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.
- package/esm2022/lib/action/action.mjs +73 -0
- package/{esm2020 → esm2022}/lib/audio/array_audio_buffer.mjs +163 -163
- package/{esm2020 → esm2022}/lib/audio/array_audio_buffer_input_stream.mjs +85 -85
- package/{esm2020 → esm2022}/lib/audio/array_audio_buffer_random_access_stream.mjs +15 -15
- package/esm2022/lib/audio/audio_data_holder.mjs +264 -0
- package/{esm2020 → esm2022}/lib/audio/audio_display.mjs +93 -93
- package/{esm2020 → esm2022}/lib/audio/audio_player.mjs +213 -213
- package/esm2022/lib/audio/capture/capture.mjs +855 -0
- package/esm2022/lib/audio/context.mjs +79 -0
- package/{esm2020 → esm2022}/lib/audio/dsp/level_measure.mjs +515 -515
- package/{esm2020 → esm2022}/lib/audio/format.mjs +16 -16
- package/esm2022/lib/audio/impl/wavformat.mjs +6 -0
- package/{esm2020 → esm2022}/lib/audio/impl/wavreader.mjs +133 -133
- package/esm2022/lib/audio/impl/wavwriter.mjs +105 -0
- package/esm2022/lib/audio/inddb_audio_buffer.mjs +508 -0
- package/{esm2020 → esm2022}/lib/audio/io/stream.mjs +58 -58
- package/esm2022/lib/audio/net_audio_buffer.mjs +293 -0
- package/{esm2020 → esm2022}/lib/audio/persistor.mjs +80 -80
- package/{esm2020 → esm2022}/lib/audio/playback/array_audio_buffer_source_node.mjs +125 -125
- package/esm2022/lib/audio/playback/audio_source_node.mjs +18 -0
- package/esm2022/lib/audio/playback/audio_source_worklet_module_loader.mjs +167 -0
- package/{esm2020 → esm2022}/lib/audio/playback/inddb_audio_buffer_source_node.mjs +166 -166
- package/{esm2020 → esm2022}/lib/audio/playback/net_audio_buffer_source_node.mjs +217 -217
- package/esm2022/lib/audio/playback/player.mjs +402 -0
- package/esm2022/lib/audio/ui/audio_canvas_layer_comp.mjs +347 -0
- package/{esm2020 → esm2022}/lib/audio/ui/audio_display_control.mjs +65 -65
- package/{esm2020 → esm2022}/lib/audio/ui/audio_display_scroll_pane.mjs +139 -139
- package/{esm2020 → esm2022}/lib/audio/ui/audiosignal.mjs +524 -524
- package/{esm2020 → esm2022}/lib/audio/ui/common.mjs +18 -18
- package/esm2022/lib/audio/ui/container.mjs +414 -0
- package/{esm2020 → esm2022}/lib/audio/ui/livelevel.mjs +352 -352
- package/esm2022/lib/audio/ui/scroll_pane_horizontal.mjs +11 -0
- package/esm2022/lib/audio/ui/sonagram.mjs +900 -0
- package/esm2022/lib/db/inddb.mjs +120 -0
- package/esm2022/lib/dsp/utils.mjs +48 -0
- package/{esm2020 → esm2022}/lib/io/BinaryReader.mjs +84 -84
- package/esm2022/lib/io/BinaryWriter.mjs +74 -0
- package/{esm2020 → esm2022}/lib/io/stream.mjs +258 -258
- package/{esm2020 → esm2022}/lib/math/2d/geometry.mjs +27 -27
- package/esm2022/lib/math/complex.mjs +58 -0
- package/{esm2020 → esm2022}/lib/math/dft.mjs +195 -195
- package/{esm2020 → esm2022}/lib/media/utils.mjs +13 -13
- package/esm2022/lib/net/uploader.mjs +367 -0
- package/{esm2020 → esm2022}/lib/recorder_component.mjs +64 -64
- package/esm2022/lib/speechrecorder/project/project.mjs +49 -0
- package/esm2022/lib/speechrecorder/project/project.service.mjs +64 -0
- package/{esm2020 → esm2022}/lib/speechrecorder/recording.mjs +123 -123
- package/esm2022/lib/speechrecorder/recordings/basic_recording.service.mjs +218 -0
- package/esm2022/lib/speechrecorder/recordings/recordings.service.mjs +1014 -0
- package/{esm2020 → esm2022}/lib/speechrecorder/script/script.mjs +114 -114
- package/{esm2020 → esm2022}/lib/speechrecorder/script/script.service.mjs +47 -47
- package/esm2022/lib/speechrecorder/session/audiorecorder.mjs +1179 -0
- package/esm2022/lib/speechrecorder/session/basicrecorder.mjs +668 -0
- package/esm2022/lib/speechrecorder/session/controlpanel.mjs +416 -0
- package/{esm2020 → esm2022}/lib/speechrecorder/session/item.mjs +29 -29
- package/{esm2020 → esm2022}/lib/speechrecorder/session/progress.mjs +69 -69
- package/{esm2020 → esm2022}/lib/speechrecorder/session/prompting.mjs +571 -571
- package/{esm2020 → esm2022}/lib/speechrecorder/session/recorder_combi_pane.mjs +65 -65
- package/esm2022/lib/speechrecorder/session/recording_file_cache.mjs +195 -0
- package/{esm2020 → esm2022}/lib/speechrecorder/session/recording_list.mjs +103 -103
- package/{esm2020 → esm2022}/lib/speechrecorder/session/recordingfile/recording-file-meta.component.mjs +63 -63
- package/{esm2020 → esm2022}/lib/speechrecorder/session/recordingfile/recording-file-navi.component.mjs +51 -51
- package/{esm2020 → esm2022}/lib/speechrecorder/session/recordingfile/recording-file-u-i.component.mjs +104 -104
- package/{esm2020 → esm2022}/lib/speechrecorder/session/recordingfile/recording-file-view.component.mjs +381 -381
- package/{esm2020 → esm2022}/lib/speechrecorder/session/recordingfile/recording-file.mjs +67 -67
- package/esm2022/lib/speechrecorder/session/recordingfile/recordingfile-service.mjs +288 -0
- package/{esm2020 → esm2022}/lib/speechrecorder/session/session.mjs +1 -1
- package/esm2022/lib/speechrecorder/session/session.service.mjs +69 -0
- package/{esm2020 → esm2022}/lib/speechrecorder/session/session_finished_dialog.mjs +29 -29
- package/esm2022/lib/speechrecorder/session/sessionmanager.mjs +1386 -0
- package/{esm2020 → esm2022}/lib/speechrecorder/session/warning_bar.mjs +28 -28
- package/{esm2020 → esm2022}/lib/speechrecorder/spruploader.mjs +22 -22
- package/{esm2020 → esm2022}/lib/speechrecorder/startstopsignal/startstopsignal.mjs +1 -1
- package/esm2022/lib/speechrecorder/startstopsignal/ui/simpletrafficlight.mjs +57 -0
- package/{esm2020 → esm2022}/lib/speechrecorderng.component.mjs +388 -388
- package/{esm2020 → esm2022}/lib/speechrecorderng.module.mjs +100 -100
- package/{esm2020 → esm2022}/lib/spr.config.mjs +26 -26
- package/{esm2020 → esm2022}/lib/spr.module.version.mjs +2 -2
- package/{esm2020 → esm2022}/lib/ui/canvas_layer_comp.mjs +38 -38
- package/{esm2020 → esm2022}/lib/ui/message_dialog.mjs +30 -30
- package/esm2022/lib/ui/recordingitem_display.mjs +253 -0
- package/{esm2020 → esm2022}/lib/ui/responsive_component.mjs +24 -24
- package/{esm2020 → esm2022}/lib/utils/scrollIntoViewToBottom.mjs +23 -23
- package/esm2022/lib/utils/ua-parser.mjs +190 -0
- package/esm2022/lib/utils/utils.mjs +105 -0
- package/esm2022/lib/utils/wake_lock.mjs +114 -0
- package/{esm2020 → esm2022}/lib/utils/wake_lock_media.mjs +1 -1
- package/{esm2020 → esm2022}/public-api.mjs +33 -33
- package/{esm2020 → esm2022}/speechrecorderng.mjs +4 -4
- package/{fesm2020 → fesm2022}/speechrecorderng.mjs +16518 -16454
- package/fesm2022/speechrecorderng.mjs.map +1 -0
- package/index.d.ts +5 -5
- package/lib/action/action.d.ts +27 -27
- package/lib/audio/array_audio_buffer.d.ts +31 -31
- package/lib/audio/array_audio_buffer_input_stream.d.ts +14 -14
- package/lib/audio/array_audio_buffer_random_access_stream.d.ts +9 -9
- package/lib/audio/audio_data_holder.d.ts +84 -84
- package/lib/audio/audio_display.d.ts +36 -36
- package/lib/audio/audio_player.d.ts +47 -47
- package/lib/audio/capture/capture.d.ts +67 -67
- package/lib/audio/context.d.ts +6 -6
- package/lib/audio/dsp/level_measure.d.ts +60 -60
- package/lib/audio/format.d.ts +11 -11
- package/lib/audio/impl/wavformat.d.ts +5 -5
- package/lib/audio/impl/wavreader.d.ts +16 -16
- package/lib/audio/impl/wavwriter.d.ts +13 -13
- package/lib/audio/inddb_audio_buffer.d.ts +68 -68
- package/lib/audio/io/stream.d.ts +28 -28
- package/lib/audio/net_audio_buffer.d.ts +57 -57
- package/lib/audio/persistor.d.ts +29 -29
- package/lib/audio/playback/array_audio_buffer_source_node.d.ts +18 -18
- package/lib/audio/playback/audio_source_node.d.ts +10 -10
- package/lib/audio/playback/audio_source_worklet_module_loader.d.ts +4 -4
- package/lib/audio/playback/inddb_audio_buffer_source_node.d.ts +21 -21
- package/lib/audio/playback/net_audio_buffer_source_node.d.ts +27 -27
- package/lib/audio/playback/player.d.ts +65 -65
- package/lib/audio/ui/audio_canvas_layer_comp.d.ts +68 -68
- package/lib/audio/ui/audio_display_control.d.ts +25 -25
- package/lib/audio/ui/audio_display_scroll_pane.d.ts +26 -26
- package/lib/audio/ui/audiosignal.d.ts +30 -30
- package/lib/audio/ui/common.d.ts +11 -11
- package/lib/audio/ui/container.d.ts +63 -63
- package/lib/audio/ui/livelevel.d.ts +60 -60
- package/lib/audio/ui/scroll_pane_horizontal.d.ts +5 -5
- package/lib/audio/ui/sonagram.d.ts +37 -37
- package/lib/db/inddb.d.ts +21 -21
- package/lib/dsp/utils.d.ts +19 -19
- package/lib/io/BinaryReader.d.ts +18 -18
- package/lib/io/BinaryWriter.d.ts +15 -15
- package/lib/io/stream.d.ts +59 -59
- package/lib/math/2d/geometry.d.ts +18 -18
- package/lib/math/complex.d.ts +17 -17
- package/lib/math/dft.d.ts +22 -22
- package/lib/media/utils.d.ts +3 -3
- package/lib/net/uploader.d.ts +81 -81
- package/lib/recorder_component.d.ts +16 -16
- package/lib/speechrecorder/project/project.d.ts +59 -59
- package/lib/speechrecorder/project/project.service.d.ts +21 -21
- package/lib/speechrecorder/recording.d.ts +51 -51
- package/lib/speechrecorder/recordings/basic_recording.service.d.ts +27 -27
- package/lib/speechrecorder/recordings/recordings.service.d.ts +48 -48
- package/lib/speechrecorder/script/script.d.ts +80 -79
- package/lib/speechrecorder/script/script.service.d.ts +16 -16
- package/lib/speechrecorder/session/audiorecorder.d.ts +122 -122
- package/lib/speechrecorder/session/basicrecorder.d.ts +139 -139
- package/lib/speechrecorder/session/controlpanel.d.ts +109 -107
- package/lib/speechrecorder/session/item.d.ts +12 -12
- package/lib/speechrecorder/session/progress.d.ts +17 -17
- package/lib/speechrecorder/session/prompting.d.ts +121 -121
- package/lib/speechrecorder/session/recorder_combi_pane.d.ts +32 -32
- package/lib/speechrecorder/session/recording_file_cache.d.ts +33 -33
- package/lib/speechrecorder/session/recording_list.d.ts +24 -24
- package/lib/speechrecorder/session/recordingfile/recording-file-meta.component.d.ts +15 -15
- package/lib/speechrecorder/session/recordingfile/recording-file-navi.component.d.ts +20 -20
- package/lib/speechrecorder/session/recordingfile/recording-file-u-i.component.d.ts +31 -31
- package/lib/speechrecorder/session/recordingfile/recording-file-view.component.d.ts +55 -55
- package/lib/speechrecorder/session/recordingfile/recording-file.d.ts +7 -7
- package/lib/speechrecorder/session/recordingfile/recordingfile-service.d.ts +24 -24
- package/lib/speechrecorder/session/session.d.ts +15 -15
- package/lib/speechrecorder/session/session.service.d.ts +20 -20
- package/lib/speechrecorder/session/session_finished_dialog.d.ts +10 -10
- package/lib/speechrecorder/session/sessionmanager.d.ts +129 -123
- package/lib/speechrecorder/session/warning_bar.d.ts +8 -8
- package/lib/speechrecorder/spruploader.d.ts +11 -11
- package/lib/speechrecorder/startstopsignal/startstopsignal.d.ts +10 -10
- package/lib/speechrecorder/startstopsignal/ui/simpletrafficlight.d.ts +11 -11
- package/lib/speechrecorderng.component.d.ts +61 -61
- package/lib/speechrecorderng.module.d.ts +56 -56
- package/lib/spr.config.d.ts +17 -17
- package/lib/spr.module.version.d.ts +1 -1
- package/lib/ui/canvas_layer_comp.d.ts +13 -13
- package/lib/ui/message_dialog.d.ts +10 -10
- package/lib/ui/recordingitem_display.d.ts +84 -84
- package/lib/ui/responsive_component.d.ts +9 -9
- package/lib/utils/scrollIntoViewToBottom.d.ts +9 -9
- package/lib/utils/ua-parser.d.ts +43 -43
- package/lib/utils/utils.d.ts +19 -19
- package/lib/utils/wake_lock.d.ts +23 -23
- package/lib/utils/wake_lock_media.d.ts +1 -1
- package/package.json +17 -23
- package/public-api.d.ts +33 -33
- package/esm2020/lib/action/action.mjs +0 -73
- package/esm2020/lib/audio/audio_data_holder.mjs +0 -264
- package/esm2020/lib/audio/capture/capture.mjs +0 -855
- package/esm2020/lib/audio/context.mjs +0 -79
- package/esm2020/lib/audio/impl/wavformat.mjs +0 -6
- package/esm2020/lib/audio/impl/wavwriter.mjs +0 -105
- package/esm2020/lib/audio/inddb_audio_buffer.mjs +0 -508
- package/esm2020/lib/audio/net_audio_buffer.mjs +0 -293
- package/esm2020/lib/audio/playback/audio_source_node.mjs +0 -18
- package/esm2020/lib/audio/playback/audio_source_worklet_module_loader.mjs +0 -167
- package/esm2020/lib/audio/playback/player.mjs +0 -402
- package/esm2020/lib/audio/ui/audio_canvas_layer_comp.mjs +0 -347
- package/esm2020/lib/audio/ui/container.mjs +0 -414
- package/esm2020/lib/audio/ui/scroll_pane_horizontal.mjs +0 -11
- package/esm2020/lib/audio/ui/sonagram.mjs +0 -900
- package/esm2020/lib/db/inddb.mjs +0 -120
- package/esm2020/lib/dsp/utils.mjs +0 -48
- package/esm2020/lib/io/BinaryWriter.mjs +0 -74
- package/esm2020/lib/math/complex.mjs +0 -58
- package/esm2020/lib/net/uploader.mjs +0 -367
- package/esm2020/lib/speechrecorder/project/project.mjs +0 -49
- package/esm2020/lib/speechrecorder/project/project.service.mjs +0 -64
- package/esm2020/lib/speechrecorder/recordings/basic_recording.service.mjs +0 -216
- package/esm2020/lib/speechrecorder/recordings/recordings.service.mjs +0 -1014
- package/esm2020/lib/speechrecorder/session/audiorecorder.mjs +0 -1179
- package/esm2020/lib/speechrecorder/session/basicrecorder.mjs +0 -666
- package/esm2020/lib/speechrecorder/session/controlpanel.mjs +0 -409
- package/esm2020/lib/speechrecorder/session/recording_file_cache.mjs +0 -195
- package/esm2020/lib/speechrecorder/session/recordingfile/recordingfile-service.mjs +0 -288
- package/esm2020/lib/speechrecorder/session/session.service.mjs +0 -69
- package/esm2020/lib/speechrecorder/session/sessionmanager.mjs +0 -1333
- package/esm2020/lib/speechrecorder/startstopsignal/ui/simpletrafficlight.mjs +0 -57
- package/esm2020/lib/ui/recordingitem_display.mjs +0 -253
- package/esm2020/lib/utils/ua-parser.mjs +0 -190
- package/esm2020/lib/utils/utils.mjs +0 -105
- package/esm2020/lib/utils/wake_lock.mjs +0 -114
- package/fesm2015/speechrecorderng.mjs +0 -17708
- package/fesm2015/speechrecorderng.mjs.map +0 -1
- package/fesm2020/speechrecorderng.mjs.map +0 -1
|
@@ -1,19 +1,19 @@
|
|
|
1
|
-
export class Point {
|
|
2
|
-
constructor(_x, _y) {
|
|
3
|
-
this._x = _x;
|
|
4
|
-
this._y = _y;
|
|
5
|
-
}
|
|
6
|
-
get x() {
|
|
7
|
-
return this._x;
|
|
8
|
-
}
|
|
9
|
-
get y() {
|
|
10
|
-
return this._y;
|
|
11
|
-
}
|
|
12
|
-
}
|
|
13
|
-
export class Marker {
|
|
14
|
-
constructor() {
|
|
15
|
-
this.name = null;
|
|
16
|
-
this.framePosition = null;
|
|
17
|
-
}
|
|
18
|
-
}
|
|
1
|
+
export class Point {
|
|
2
|
+
constructor(_x, _y) {
|
|
3
|
+
this._x = _x;
|
|
4
|
+
this._y = _y;
|
|
5
|
+
}
|
|
6
|
+
get x() {
|
|
7
|
+
return this._x;
|
|
8
|
+
}
|
|
9
|
+
get y() {
|
|
10
|
+
return this._y;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
export class Marker {
|
|
14
|
+
constructor() {
|
|
15
|
+
this.name = null;
|
|
16
|
+
this.framePosition = null;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
19
|
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29tbW9uLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvc3BlZWNocmVjb3JkZXJuZy9zcmMvbGliL2F1ZGlvL3VpL2NvbW1vbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFDSSxNQUFNLE9BQU8sS0FBSztJQUNkLFlBQW9CLEVBQVMsRUFBUyxFQUFTO1FBQTNCLE9BQUUsR0FBRixFQUFFLENBQU87UUFBUyxPQUFFLEdBQUYsRUFBRSxDQUFPO0lBQy9DLENBQUM7SUFDRCxJQUFJLENBQUM7UUFDRCxPQUFPLElBQUksQ0FBQyxFQUFFLENBQUM7SUFDbkIsQ0FBQztJQUNELElBQUksQ0FBQztRQUNELE9BQU8sSUFBSSxDQUFDLEVBQUUsQ0FBQztJQUNuQixDQUFDO0NBQ0o7QUFDRCxNQUFNLE9BQU8sTUFBTTtJQUFuQjtRQUNJLFNBQUksR0FBYyxJQUFJLENBQUM7UUFDdkIsa0JBQWEsR0FBYyxJQUFJLENBQUM7SUFFcEMsQ0FBQztDQUFBIiwic291cmNlc0NvbnRlbnQiOlsiXHJcbiAgICBleHBvcnQgY2xhc3MgUG9pbnQge1xyXG4gICAgICAgIGNvbnN0cnVjdG9yKHByaXZhdGUgX3g6bnVtYmVyLHByaXZhdGUgX3k6bnVtYmVyKSB7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGdldCB4KCk6bnVtYmVye1xyXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5feDtcclxuICAgICAgICB9XHJcbiAgICAgICAgZ2V0IHkoKTpudW1iZXJ7XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl95O1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIGV4cG9ydCBjbGFzcyBNYXJrZXIge1xyXG4gICAgICAgIG5hbWU6IHN0cmluZ3xudWxsPW51bGw7XHJcbiAgICAgICAgZnJhbWVQb3NpdGlvbjogbnVtYmVyfG51bGw9bnVsbDtcclxuXHJcbiAgICB9XHJcblxyXG5cclxuIl19
|
|
@@ -0,0 +1,414 @@
|
|
|
1
|
+
import { HostListener, Input, Output, EventEmitter } from '@angular/core';
|
|
2
|
+
import { AudioSignal } from './audiosignal';
|
|
3
|
+
import { Sonagram } from './sonagram';
|
|
4
|
+
import { Point } from './common';
|
|
5
|
+
import { Component, ViewChild } from '@angular/core';
|
|
6
|
+
import { Position, Dimension, Rectangle } from "../../math/2d/geometry";
|
|
7
|
+
import { BasicAudioCanvasLayerComponent } from "./audio_canvas_layer_comp";
|
|
8
|
+
import * as i0 from "@angular/core";
|
|
9
|
+
import * as i1 from "./audiosignal";
|
|
10
|
+
import * as i2 from "./sonagram";
|
|
11
|
+
/*
|
|
12
|
+
ResizeObserver not yet available in official Typescript declaration
|
|
13
|
+
Crreated declaration from IDL until its available.
|
|
14
|
+
See specs:
|
|
15
|
+
https://www.w3.org/TR/resize-observer
|
|
16
|
+
|
|
17
|
+
*/
|
|
18
|
+
// interface ResizeObserverSize {
|
|
19
|
+
// readonly inlineSize:number;
|
|
20
|
+
// readonly blockSize:number;
|
|
21
|
+
// }
|
|
22
|
+
//
|
|
23
|
+
// declare interface ResizeObserverEntry{
|
|
24
|
+
// readonly target: Element;
|
|
25
|
+
// readonly contentRect: DOMRectReadOnly ;
|
|
26
|
+
// readonly borderBoxSize: Array<ResizeObserverSize> ;
|
|
27
|
+
// readonly contentBoxSize: Array<ResizeObserverSize> ;
|
|
28
|
+
// readonly devicePixelContentBoxSize: Array<ResizeObserverSize> ;
|
|
29
|
+
// }
|
|
30
|
+
//
|
|
31
|
+
// declare interface ResizeObserverCallback {
|
|
32
|
+
// (entries: Array<ResizeObserverEntry>, observer: ResizeObserver):void;
|
|
33
|
+
// }
|
|
34
|
+
//
|
|
35
|
+
// declare enum ResizeObserverBoxOptions {
|
|
36
|
+
// "border-box", "content-box", "device-pixel-content-box"
|
|
37
|
+
// };
|
|
38
|
+
// // Declare Resizeobserver
|
|
39
|
+
// declare class ResizeObserver{
|
|
40
|
+
// constructor(callback: ResizeObserverCallback);
|
|
41
|
+
// observe: (el:Element,opts: ResizeObserverBoxOptions | null)=>void;
|
|
42
|
+
// unobserve: (el:Element)=>void;
|
|
43
|
+
// disconnect: ()=>void;
|
|
44
|
+
// }
|
|
45
|
+
/*
|
|
46
|
+
* Container component for audio display.
|
|
47
|
+
* The display elements are children of a virtual canvas. The virtual canvas makes it possible to have high zoom factors with very wide virtual audio displays.
|
|
48
|
+
* Only the visible part of the virtual canvas is implemented as a browser canvas and therefore consuming memory.
|
|
49
|
+
* The visible part has the same width as the viewport of the scroll pane parent.
|
|
50
|
+
* The virtual canvas itself is implemented as an HTML div element.
|
|
51
|
+
* The layout of the component is updated on resize of the parent or changes of the zoom factor.
|
|
52
|
+
*/
|
|
53
|
+
export class AudioClipUIContainer extends BasicAudioCanvasLayerComponent {
|
|
54
|
+
static { this.DIVIDER_PIXEL_SIZE = 10; }
|
|
55
|
+
get xZoom() {
|
|
56
|
+
return this._xZoom;
|
|
57
|
+
}
|
|
58
|
+
set xZoom(value) {
|
|
59
|
+
this.userAction = true;
|
|
60
|
+
this._xZoom = value;
|
|
61
|
+
this.layout();
|
|
62
|
+
this.userAction = false;
|
|
63
|
+
}
|
|
64
|
+
set fixFitToPanel(value) {
|
|
65
|
+
this._fixFitToPanel = value;
|
|
66
|
+
if (value) {
|
|
67
|
+
// we don't need clip bounds
|
|
68
|
+
this.bounds = null;
|
|
69
|
+
this._xZoom = null;
|
|
70
|
+
}
|
|
71
|
+
else {
|
|
72
|
+
// hold current zoom value
|
|
73
|
+
//this._xZoom=this.ce.offsetWidth/this._audioData.duration;
|
|
74
|
+
}
|
|
75
|
+
this.layout();
|
|
76
|
+
}
|
|
77
|
+
constructor(ref) {
|
|
78
|
+
super();
|
|
79
|
+
this.ref = ref;
|
|
80
|
+
this._audioClip = null;
|
|
81
|
+
this.pointer = null;
|
|
82
|
+
this.selecting = null;
|
|
83
|
+
this.selection = null;
|
|
84
|
+
this.selectionEventEmitter = new EventEmitter();
|
|
85
|
+
this._playFramePosition = null;
|
|
86
|
+
this.dragStartMouseY = null;
|
|
87
|
+
this.dragStartY = null;
|
|
88
|
+
this.dividerPosition = 0.5;
|
|
89
|
+
this.userAction = false;
|
|
90
|
+
this._xZoom = null; // pixels per second
|
|
91
|
+
// if true the complete audio file is shown, the display fits to the visible panel, the x-zoom factor is variable, this is the default
|
|
92
|
+
this._fixFitToPanel = true;
|
|
93
|
+
this.parentE = this.ref.nativeElement;
|
|
94
|
+
}
|
|
95
|
+
ngOnInit() {
|
|
96
|
+
this.ce = this.ceRef.nativeElement;
|
|
97
|
+
this.dc = this.canvasRef.nativeElement;
|
|
98
|
+
}
|
|
99
|
+
ngAfterViewInit() {
|
|
100
|
+
this.layout();
|
|
101
|
+
const heightListener = new MutationObserver((mrs, mo) => {
|
|
102
|
+
let layout = false;
|
|
103
|
+
mrs.forEach((mr) => {
|
|
104
|
+
if (!this.userAction && 'attributes' === mr.type && ('class' === mr.attributeName || 'style' === mr.attributeName)) {
|
|
105
|
+
layout = true;
|
|
106
|
+
}
|
|
107
|
+
});
|
|
108
|
+
if (layout) {
|
|
109
|
+
// re-layout required
|
|
110
|
+
this.layout(false);
|
|
111
|
+
}
|
|
112
|
+
});
|
|
113
|
+
heightListener.observe(this.ce, { attributes: true, childList: true, characterData: true });
|
|
114
|
+
heightListener.observe(this.dc, { attributes: true, childList: true, characterData: true });
|
|
115
|
+
const resizeObserver = new ResizeObserver((entries, obs) => {
|
|
116
|
+
//console.log("Resize observed:");
|
|
117
|
+
entries.forEach((e) => {
|
|
118
|
+
//console.log(e.contentRect.width+"x"+e.contentRect.height);
|
|
119
|
+
this.layout();
|
|
120
|
+
});
|
|
121
|
+
});
|
|
122
|
+
resizeObserver.observe(this.ce);
|
|
123
|
+
}
|
|
124
|
+
onResize(event) {
|
|
125
|
+
this.layout();
|
|
126
|
+
}
|
|
127
|
+
mouseover(me) {
|
|
128
|
+
this.dividerCursorPosition(me, true);
|
|
129
|
+
}
|
|
130
|
+
mouseleave(me) {
|
|
131
|
+
this.dividerCursorPosition(me, false);
|
|
132
|
+
}
|
|
133
|
+
mousedown(me) {
|
|
134
|
+
this.dragStartMouseY = me.clientY;
|
|
135
|
+
this.dragStartY = this.dc.offsetTop;
|
|
136
|
+
this.dragStartMouseY = me.clientY;
|
|
137
|
+
}
|
|
138
|
+
onMouseup(me) {
|
|
139
|
+
if (this.dragStartY != null) {
|
|
140
|
+
this.userAction = true;
|
|
141
|
+
this.dividerDrag(me);
|
|
142
|
+
this.layout(false);
|
|
143
|
+
this.dragStartY = null;
|
|
144
|
+
this.userAction = false;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
onMousemove(me) {
|
|
148
|
+
if (this.dragStartY != null) {
|
|
149
|
+
this.userAction = true;
|
|
150
|
+
this.dividerDrag(me);
|
|
151
|
+
this.layoutScaled();
|
|
152
|
+
this.userAction = true;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
pointerPositionChanged(pp) {
|
|
156
|
+
this.pointer = pp;
|
|
157
|
+
}
|
|
158
|
+
selectingChanged(s) {
|
|
159
|
+
this.selecting = s;
|
|
160
|
+
}
|
|
161
|
+
selectionChanged(s) {
|
|
162
|
+
this.selection = s;
|
|
163
|
+
if (this._audioClip) {
|
|
164
|
+
this._audioClip.selection = s;
|
|
165
|
+
}
|
|
166
|
+
this.selectionEventEmitter.emit(this.selection);
|
|
167
|
+
}
|
|
168
|
+
canvasMousePos(c, e) {
|
|
169
|
+
const cr = c.getBoundingClientRect();
|
|
170
|
+
const x = e.x - cr.left;
|
|
171
|
+
const y = e.y - cr.top;
|
|
172
|
+
return new Point(x, y);
|
|
173
|
+
}
|
|
174
|
+
dividerCursorPosition(e, show) {
|
|
175
|
+
if (this.dc) {
|
|
176
|
+
this.canvasMousePos(this.dc, e);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
dividerDrag(e) {
|
|
180
|
+
if (this.dc && this.dragStartMouseY && this.dragStartY) {
|
|
181
|
+
const dragOffset = e.clientY - this.dragStartMouseY;
|
|
182
|
+
const ceHeight = this.ce.offsetHeight;
|
|
183
|
+
let newTop = (this.dragStartY + dragOffset);
|
|
184
|
+
if (newTop < 0) {
|
|
185
|
+
newTop = 0;
|
|
186
|
+
}
|
|
187
|
+
if (newTop > ceHeight - AudioClipUIContainer.DIVIDER_PIXEL_SIZE) {
|
|
188
|
+
newTop = ceHeight - AudioClipUIContainer.DIVIDER_PIXEL_SIZE;
|
|
189
|
+
}
|
|
190
|
+
this.dc.style.top = newTop.toString() + 'px';
|
|
191
|
+
this.dividerPosition = (this.dc.offsetTop + AudioClipUIContainer.DIVIDER_PIXEL_SIZE / 2) / ceHeight;
|
|
192
|
+
if (this.dividerPosition > 1.0) {
|
|
193
|
+
this.dividerPosition = 1.0;
|
|
194
|
+
}
|
|
195
|
+
if (this.dividerPosition < 0.0) {
|
|
196
|
+
this.dividerPosition = 0.0;
|
|
197
|
+
}
|
|
198
|
+
this.drawDivider();
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
drawDivider() {
|
|
202
|
+
const w = this.dc.width;
|
|
203
|
+
const h = this.dc.height;
|
|
204
|
+
const g = this.dc.getContext('2d');
|
|
205
|
+
if (g && w > 10 && h >= 1) {
|
|
206
|
+
g.fillStyle = 'white';
|
|
207
|
+
g.fillRect(0, 0, w, h);
|
|
208
|
+
g.fillStyle = 'black';
|
|
209
|
+
g.fillRect(5, 5, w - 10, 1);
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
clipBounds(clipBounds) {
|
|
213
|
+
this.bounds = clipBounds;
|
|
214
|
+
this.layout();
|
|
215
|
+
}
|
|
216
|
+
currentXZoom() {
|
|
217
|
+
let xz = this._xZoom;
|
|
218
|
+
if (xz == null && this._audioDataHolder) {
|
|
219
|
+
let ow = this.ce.offsetWidth;
|
|
220
|
+
if (ow < 1) {
|
|
221
|
+
// at least one pixel width to avoid x-zoom zero values
|
|
222
|
+
ow = 1;
|
|
223
|
+
}
|
|
224
|
+
xz = ow / this._audioDataHolder.duration;
|
|
225
|
+
}
|
|
226
|
+
return xz;
|
|
227
|
+
}
|
|
228
|
+
_layout(clear, redraw) {
|
|
229
|
+
let ceBcr = this.ce.getBoundingClientRect();
|
|
230
|
+
const ceBcrIntW = Math.floor(ceBcr.width);
|
|
231
|
+
const ceBcrIntH = Math.floor(ceBcr.height);
|
|
232
|
+
// height available for plugins (audiosignal and sonagram)
|
|
233
|
+
let psH = ceBcrIntH - AudioClipUIContainer.DIVIDER_PIXEL_SIZE;
|
|
234
|
+
if (psH < 0) {
|
|
235
|
+
psH = 0;
|
|
236
|
+
}
|
|
237
|
+
// audio signal height
|
|
238
|
+
const asH = Math.round(psH * this.dividerPosition);
|
|
239
|
+
// sonagram height (rest: available height minus divider height minus audiosignal height)
|
|
240
|
+
let soH = ceBcrIntH - AudioClipUIContainer.DIVIDER_PIXEL_SIZE - asH;
|
|
241
|
+
if (soH < 0) {
|
|
242
|
+
soH = 0;
|
|
243
|
+
}
|
|
244
|
+
// sonagram top position
|
|
245
|
+
const soTop = asH + AudioClipUIContainer.DIVIDER_PIXEL_SIZE;
|
|
246
|
+
// Visible bounds
|
|
247
|
+
// left position
|
|
248
|
+
let vbLeft = 0;
|
|
249
|
+
// width
|
|
250
|
+
let vbWidth = ceBcrIntW;
|
|
251
|
+
if (!this._fixFitToPanel && this.bounds) {
|
|
252
|
+
vbLeft = Math.round(this.bounds.position.left);
|
|
253
|
+
vbWidth = Math.round(this.bounds.dimension.width);
|
|
254
|
+
}
|
|
255
|
+
// Divider
|
|
256
|
+
// left position
|
|
257
|
+
let vbLeftStyl = vbLeft + 'px';
|
|
258
|
+
if (this.dc.style.left != vbLeftStyl) {
|
|
259
|
+
this.dc.style.left = vbLeftStyl;
|
|
260
|
+
}
|
|
261
|
+
// top position
|
|
262
|
+
//const dTop = asH;
|
|
263
|
+
const dTopStr = asH + 'px';
|
|
264
|
+
if (this.dc.style.top != dTopStr) {
|
|
265
|
+
this.dc.style.top = dTopStr;
|
|
266
|
+
}
|
|
267
|
+
// width
|
|
268
|
+
let vbWidthStyle = vbWidth + 'px';
|
|
269
|
+
if (this.dc.style.width != vbWidthStyle) {
|
|
270
|
+
this.dc.style.width = vbWidthStyle;
|
|
271
|
+
}
|
|
272
|
+
if (this.dc.width != vbWidth) {
|
|
273
|
+
this.dc.width = vbWidth;
|
|
274
|
+
}
|
|
275
|
+
// height
|
|
276
|
+
if (this.dc.height != AudioClipUIContainer.DIVIDER_PIXEL_SIZE) {
|
|
277
|
+
this.dc.height = AudioClipUIContainer.DIVIDER_PIXEL_SIZE;
|
|
278
|
+
}
|
|
279
|
+
let divPixelSizeStyle = AudioClipUIContainer.DIVIDER_PIXEL_SIZE.toString() + 'px';
|
|
280
|
+
if (this.dc.style.height != divPixelSizeStyle) {
|
|
281
|
+
this.dc.style.height = divPixelSizeStyle;
|
|
282
|
+
}
|
|
283
|
+
this.drawDivider();
|
|
284
|
+
// Virtual dimension, only width is used
|
|
285
|
+
let virtualDim = new Dimension(ceBcrIntW, 0);
|
|
286
|
+
// Visible bounds of container
|
|
287
|
+
let br = new Rectangle(new Position(vbLeft, 0), new Dimension(vbWidth, ceBcrIntH));
|
|
288
|
+
// Set container bounds
|
|
289
|
+
this.layoutBounds(br, virtualDim, false);
|
|
290
|
+
// Visible bounds of audiosignal
|
|
291
|
+
let asR = new Rectangle(new Position(vbLeft, 0), new Dimension(vbWidth, asH));
|
|
292
|
+
// Set audiosignal bounds
|
|
293
|
+
this.as.layoutBounds(asR, virtualDim, redraw, clear);
|
|
294
|
+
// Visible bounds of sonagram
|
|
295
|
+
let soR = new Rectangle(new Position(vbLeft, soTop), new Dimension(vbWidth, soH));
|
|
296
|
+
// Set sonagram bounds
|
|
297
|
+
this.so.layoutBounds(soR, virtualDim, redraw, clear);
|
|
298
|
+
}
|
|
299
|
+
layoutScaled() {
|
|
300
|
+
this._layout(false, false);
|
|
301
|
+
}
|
|
302
|
+
layout(clear = true) {
|
|
303
|
+
if (this.ce && this.dc) {
|
|
304
|
+
const clientW = this.ce.clientWidth;
|
|
305
|
+
if (this._audioDataHolder) {
|
|
306
|
+
if (this._fixFitToPanel) {
|
|
307
|
+
// Set the virtual canvas width to the visible width
|
|
308
|
+
if (this.ce.style.width != '100%') {
|
|
309
|
+
//console.log("set width to 100%");
|
|
310
|
+
this.ce.style.width = '100%';
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
else {
|
|
314
|
+
if (this._xZoom) {
|
|
315
|
+
// Set the virtual canvas width according to the value of the user selected xZoom value
|
|
316
|
+
const newClW = Math.round(this._xZoom * this._audioDataHolder?.duration);
|
|
317
|
+
this.ce.style.width = newClW + 'px';
|
|
318
|
+
}
|
|
319
|
+
else {
|
|
320
|
+
// Set the virtual canvas width to the visible width only
|
|
321
|
+
this.ce.style.width = clientW + 'px';
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
this._layout(clear, true);
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
set audioData(audioDataHolder) {
|
|
329
|
+
this._audioClip = null;
|
|
330
|
+
this._audioDataHolder = audioDataHolder;
|
|
331
|
+
this.as.setData(audioDataHolder);
|
|
332
|
+
this.so.setData(audioDataHolder);
|
|
333
|
+
this.layout();
|
|
334
|
+
}
|
|
335
|
+
get audioData() {
|
|
336
|
+
return this._audioDataHolder;
|
|
337
|
+
}
|
|
338
|
+
set audioClip(audioClip) {
|
|
339
|
+
this._audioClip = audioClip;
|
|
340
|
+
let audioData = null;
|
|
341
|
+
let sel = null;
|
|
342
|
+
if (audioClip) {
|
|
343
|
+
audioData = audioClip.audioDataHolder;
|
|
344
|
+
if (this._audioClip) {
|
|
345
|
+
this._audioClip.addSelectionObserver((clip) => {
|
|
346
|
+
this.selection = clip.selection;
|
|
347
|
+
});
|
|
348
|
+
}
|
|
349
|
+
sel = audioClip.selection;
|
|
350
|
+
}
|
|
351
|
+
this._audioDataHolder = audioData;
|
|
352
|
+
this.as.setData(this._audioDataHolder);
|
|
353
|
+
this.so.setData(this._audioDataHolder);
|
|
354
|
+
this.selecting = null;
|
|
355
|
+
this.selection = sel;
|
|
356
|
+
this.layout();
|
|
357
|
+
}
|
|
358
|
+
get playFramePosition() {
|
|
359
|
+
return this._playFramePosition;
|
|
360
|
+
}
|
|
361
|
+
set playFramePosition(playFramePosition) {
|
|
362
|
+
this._playFramePosition = playFramePosition;
|
|
363
|
+
this.as.playFramePosition = playFramePosition;
|
|
364
|
+
this.so.playFramePosition = playFramePosition;
|
|
365
|
+
}
|
|
366
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.6", ngImport: i0, type: AudioClipUIContainer, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
367
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.0.6", type: AudioClipUIContainer, selector: "app-audio", inputs: { audioData: "audioData", audioClip: "audioClip" }, outputs: { selectionEventEmitter: "selectionEventEmitter" }, host: { listeners: { "window:resize": "onResize($event)", "document:mouseup": "onMouseup($event)", "document:mousemove": "onMousemove($event)" } }, viewQueries: [{ propertyName: "canvasRef", first: true, predicate: ["divider"], descendants: true, static: true }, { propertyName: "ceRef", first: true, predicate: ["virtualCanvas"], descendants: true, static: true }, { propertyName: "as", first: true, predicate: AudioSignal, descendants: true, static: true }, { propertyName: "so", first: true, predicate: Sonagram, descendants: true, static: true }], usesInheritance: true, ngImport: i0, template: `
|
|
368
|
+
<div #virtualCanvas>
|
|
369
|
+
<canvas #divider (mousedown)="mousedown($event)" (mouseover)="mouseover($event)"
|
|
370
|
+
(mouseleave)="mouseleave($event)" height="10"></canvas>
|
|
371
|
+
<audio-signal [pointerPosition]="pointer" [selecting]="selecting" [selection]="selection" (pointerPositionEventEmitter)="pointerPositionChanged($event)" (selectingEventEmitter)="selectingChanged($event)" (selectedEventEmitter)="selectionChanged($event)"></audio-signal>
|
|
372
|
+
<audio-sonagram [pointerPosition]="pointer" [selecting]="selecting" [selection]="selection" (pointerPositionEventEmitter)="pointerPositionChanged($event)" (selectingEventEmitter)="selectingChanged($event)" (selectedEventEmitter)="selectionChanged($event)"></audio-sonagram>
|
|
373
|
+
</div>
|
|
374
|
+
`, isInline: true, styles: ["div{margin:0;padding:0;top:0;left:0;width:100%;height:100%;position:relative;box-sizing:border-box;transform:none;overflow:hidden}\n", "canvas{top:0;left:0;width:0;height:0;cursor:ns-resize;position:absolute;z-index:1;transform:none}\n", "audio-signal{top:0;left:0;position:absolute;z-index:1;transform:none}\n", "audio-sonagram{top:0;left:0;position:absolute;z-index:1;transform:none}\n"], dependencies: [{ kind: "component", type: i1.AudioSignal, selector: "audio-signal" }, { kind: "component", type: i2.Sonagram, selector: "audio-sonagram" }] }); }
|
|
375
|
+
}
|
|
376
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.6", ngImport: i0, type: AudioClipUIContainer, decorators: [{
|
|
377
|
+
type: Component,
|
|
378
|
+
args: [{ selector: 'app-audio', template: `
|
|
379
|
+
<div #virtualCanvas>
|
|
380
|
+
<canvas #divider (mousedown)="mousedown($event)" (mouseover)="mouseover($event)"
|
|
381
|
+
(mouseleave)="mouseleave($event)" height="10"></canvas>
|
|
382
|
+
<audio-signal [pointerPosition]="pointer" [selecting]="selecting" [selection]="selection" (pointerPositionEventEmitter)="pointerPositionChanged($event)" (selectingEventEmitter)="selectingChanged($event)" (selectedEventEmitter)="selectionChanged($event)"></audio-signal>
|
|
383
|
+
<audio-sonagram [pointerPosition]="pointer" [selecting]="selecting" [selection]="selection" (pointerPositionEventEmitter)="pointerPositionChanged($event)" (selectingEventEmitter)="selectingChanged($event)" (selectedEventEmitter)="selectionChanged($event)"></audio-sonagram>
|
|
384
|
+
</div>
|
|
385
|
+
`, styles: ["div{margin:0;padding:0;top:0;left:0;width:100%;height:100%;position:relative;box-sizing:border-box;transform:none;overflow:hidden}\n", "canvas{top:0;left:0;width:0;height:0;cursor:ns-resize;position:absolute;z-index:1;transform:none}\n", "audio-signal{top:0;left:0;position:absolute;z-index:1;transform:none}\n", "audio-sonagram{top:0;left:0;position:absolute;z-index:1;transform:none}\n"] }]
|
|
386
|
+
}], ctorParameters: () => [{ type: i0.ElementRef }], propDecorators: { canvasRef: [{
|
|
387
|
+
type: ViewChild,
|
|
388
|
+
args: ['divider', { static: true }]
|
|
389
|
+
}], ceRef: [{
|
|
390
|
+
type: ViewChild,
|
|
391
|
+
args: ['virtualCanvas', { static: true }]
|
|
392
|
+
}], as: [{
|
|
393
|
+
type: ViewChild,
|
|
394
|
+
args: [AudioSignal, { static: true }]
|
|
395
|
+
}], so: [{
|
|
396
|
+
type: ViewChild,
|
|
397
|
+
args: [Sonagram, { static: true }]
|
|
398
|
+
}], selectionEventEmitter: [{
|
|
399
|
+
type: Output
|
|
400
|
+
}], onResize: [{
|
|
401
|
+
type: HostListener,
|
|
402
|
+
args: ['window:resize', ['$event']]
|
|
403
|
+
}], onMouseup: [{
|
|
404
|
+
type: HostListener,
|
|
405
|
+
args: ['document:mouseup', ['$event']]
|
|
406
|
+
}], onMousemove: [{
|
|
407
|
+
type: HostListener,
|
|
408
|
+
args: ['document:mousemove', ['$event']]
|
|
409
|
+
}], audioData: [{
|
|
410
|
+
type: Input
|
|
411
|
+
}], audioClip: [{
|
|
412
|
+
type: Input
|
|
413
|
+
}] } });
|
|
414
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29udGFpbmVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvc3BlZWNocmVjb3JkZXJuZy9zcmMvbGliL2F1ZGlvL3VpL2NvbnRhaW5lci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQ3NCLFlBQVksRUFBRSxLQUFLLEVBQVUsTUFBTSxFQUFFLFlBQVksRUFDN0UsTUFBTSxlQUFlLENBQUE7QUFDdEIsT0FBTyxFQUFDLFdBQVcsRUFBQyxNQUFNLGVBQWUsQ0FBQTtBQUN6QyxPQUFPLEVBQUMsUUFBUSxFQUFDLE1BQU0sWUFBWSxDQUFBO0FBQ25DLE9BQU8sRUFBUyxLQUFLLEVBQUMsTUFBTSxVQUFVLENBQUE7QUFFdEMsT0FBTyxFQUFDLFNBQVMsRUFBRSxTQUFTLEVBQUMsTUFBTSxlQUFlLENBQUM7QUFDbkQsT0FBTyxFQUFDLFFBQVEsRUFBQyxTQUFTLEVBQUUsU0FBUyxFQUFDLE1BQU0sd0JBQXdCLENBQUM7QUFFckUsT0FBTyxFQUFDLDhCQUE4QixFQUFDLE1BQU0sMkJBQTJCLENBQUM7Ozs7QUFHekU7Ozs7OztHQU1HO0FBRUgsaUNBQWlDO0FBQ2pDLGdDQUFnQztBQUNoQywrQkFBK0I7QUFDL0IsSUFBSTtBQUNKLEVBQUU7QUFDRix5Q0FBeUM7QUFDekMsOEJBQThCO0FBQzlCLDRDQUE0QztBQUM1Qyx3REFBd0Q7QUFDeEQseURBQXlEO0FBQ3pELG9FQUFvRTtBQUNwRSxJQUFJO0FBQ0osRUFBRTtBQUNGLDZDQUE2QztBQUM3QywwRUFBMEU7QUFDMUUsSUFBSTtBQUNKLEVBQUU7QUFDRiwwQ0FBMEM7QUFDMUMsNERBQTREO0FBQzVELEtBQUs7QUFFTCw0QkFBNEI7QUFDNUIsZ0NBQWdDO0FBQ2hDLG1EQUFtRDtBQUNuRCx1RUFBdUU7QUFDdkUsbUNBQW1DO0FBQ25DLDBCQUEwQjtBQUMxQixJQUFJO0FBRUo7Ozs7Ozs7R0FPRztBQStDSCxNQUFNLE9BQU8sb0JBQXFC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QVEsQ0FBQztnQkFZNUMsV0FBVztzQkFEVixZQUFZO3VCQUFDLG9CQUFvQixFQUFFLENBQUMsUUFBUSxDQUFDO2dCQXNOMUMsU0FBUztzQkFEWixLQUFLO2dCQWVGLFNBQVM7c0JBRFosS0FBSyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XHJcbiAgRWxlbWVudFJlZiwgQWZ0ZXJWaWV3SW5pdCwgSG9zdExpc3RlbmVyLCBJbnB1dCwgT25Jbml0LCBPdXRwdXQsIEV2ZW50RW1pdHRlclxyXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnXHJcbmltcG9ydCB7QXVkaW9TaWduYWx9IGZyb20gJy4vYXVkaW9zaWduYWwnXHJcbmltcG9ydCB7U29uYWdyYW19IGZyb20gJy4vc29uYWdyYW0nXHJcbmltcG9ydCB7TWFya2VyLCBQb2ludH0gZnJvbSAnLi9jb21tb24nXHJcblxyXG5pbXBvcnQge0NvbXBvbmVudCwgVmlld0NoaWxkfSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuaW1wb3J0IHtQb3NpdGlvbixEaW1lbnNpb24sIFJlY3RhbmdsZX0gZnJvbSBcIi4uLy4uL21hdGgvMmQvZ2VvbWV0cnlcIjtcclxuaW1wb3J0IHtBdWRpb0NsaXAsU2VsZWN0aW9ufSBmcm9tIFwiLi4vcGVyc2lzdG9yXCI7XHJcbmltcG9ydCB7QmFzaWNBdWRpb0NhbnZhc0xheWVyQ29tcG9uZW50fSBmcm9tIFwiLi9hdWRpb19jYW52YXNfbGF5ZXJfY29tcFwiO1xyXG5pbXBvcnQge0F1ZGlvRGF0YUhvbGRlcn0gZnJvbSBcIi4uL2F1ZGlvX2RhdGFfaG9sZGVyXCI7XHJcblxyXG4vKlxyXG4gIFJlc2l6ZU9ic2VydmVyIG5vdCB5ZXQgYXZhaWxhYmxlIGluIG9mZmljaWFsIFR5cGVzY3JpcHQgZGVjbGFyYXRpb25cclxuICBDcnJlYXRlZCBkZWNsYXJhdGlvbiBmcm9tIElETCB1bnRpbCBpdHMgYXZhaWxhYmxlLlxyXG4gIFNlZSBzcGVjczpcclxuICBodHRwczovL3d3dy53My5vcmcvVFIvcmVzaXplLW9ic2VydmVyXHJcblxyXG4gKi9cclxuXHJcbi8vIGludGVyZmFjZSBSZXNpemVPYnNlcnZlclNpemUge1xyXG4vLyAgIHJlYWRvbmx5IGlubGluZVNpemU6bnVtYmVyO1xyXG4vLyAgIHJlYWRvbmx5IGJsb2NrU2l6ZTpudW1iZXI7XHJcbi8vIH1cclxuLy9cclxuLy8gZGVjbGFyZSBpbnRlcmZhY2UgUmVzaXplT2JzZXJ2ZXJFbnRyeXtcclxuLy8gICByZWFkb25seSB0YXJnZXQ6IEVsZW1lbnQ7XHJcbi8vICAgcmVhZG9ubHkgY29udGVudFJlY3Q6IERPTVJlY3RSZWFkT25seSA7XHJcbi8vICAgcmVhZG9ubHkgYm9yZGVyQm94U2l6ZTogQXJyYXk8UmVzaXplT2JzZXJ2ZXJTaXplPiA7XHJcbi8vICAgcmVhZG9ubHkgY29udGVudEJveFNpemU6IEFycmF5PFJlc2l6ZU9ic2VydmVyU2l6ZT4gO1xyXG4vLyAgIHJlYWRvbmx5IGRldmljZVBpeGVsQ29udGVudEJveFNpemU6IEFycmF5PFJlc2l6ZU9ic2VydmVyU2l6ZT4gO1xyXG4vLyB9XHJcbi8vXHJcbi8vIGRlY2xhcmUgaW50ZXJmYWNlIFJlc2l6ZU9ic2VydmVyQ2FsbGJhY2sge1xyXG4vLyAgIChlbnRyaWVzOiBBcnJheTxSZXNpemVPYnNlcnZlckVudHJ5Piwgb2JzZXJ2ZXI6IFJlc2l6ZU9ic2VydmVyKTp2b2lkO1xyXG4vLyB9XHJcbi8vXHJcbi8vIGRlY2xhcmUgZW51bSBSZXNpemVPYnNlcnZlckJveE9wdGlvbnMge1xyXG4vLyAgIFwiYm9yZGVyLWJveFwiLCBcImNvbnRlbnQtYm94XCIsIFwiZGV2aWNlLXBpeGVsLWNvbnRlbnQtYm94XCJcclxuLy8gfTtcclxuXHJcbi8vIC8vIERlY2xhcmUgUmVzaXplb2JzZXJ2ZXJcclxuLy8gZGVjbGFyZSBjbGFzcyBSZXNpemVPYnNlcnZlcntcclxuLy8gICBjb25zdHJ1Y3RvcihjYWxsYmFjazogUmVzaXplT2JzZXJ2ZXJDYWxsYmFjayk7XHJcbi8vICAgb2JzZXJ2ZTogKGVsOkVsZW1lbnQsb3B0czogUmVzaXplT2JzZXJ2ZXJCb3hPcHRpb25zIHwgbnVsbCk9PnZvaWQ7XHJcbi8vICAgdW5vYnNlcnZlOiAoZWw6RWxlbWVudCk9PnZvaWQ7XHJcbi8vICAgZGlzY29ubmVjdDogKCk9PnZvaWQ7XHJcbi8vIH1cclxuXHJcbi8qXHJcbiAqIENvbnRhaW5lciBjb21wb25lbnQgZm9yIGF1ZGlvIGRpc3BsYXkuXHJcbiAqIFRoZSBkaXNwbGF5IGVsZW1lbnRzIGFyZSBjaGlsZHJlbiBvZiBhIHZpcnR1YWwgY2FudmFzLiBUaGUgdmlydHVhbCBjYW52YXMgbWFrZXMgaXQgcG9zc2libGUgdG8gaGF2ZSBoaWdoIHpvb20gZmFjdG9ycyB3aXRoIHZlcnkgd2lkZSB2aXJ0dWFsIGF1ZGlvIGRpc3BsYXlzLlxyXG4gKiBPbmx5IHRoZSB2aXNpYmxlIHBhcnQgb2YgdGhlIHZpcnR1YWwgY2FudmFzIGlzIGltcGxlbWVudGVkIGFzIGEgYnJvd3NlciBjYW52YXMgYW5kIHRoZXJlZm9yZSBjb25zdW1pbmcgbWVtb3J5LlxyXG4gKiBUaGUgdmlzaWJsZSBwYXJ0IGhhcyB0aGUgc2FtZSB3aWR0aCBhcyB0aGUgdmlld3BvcnQgb2YgdGhlIHNjcm9sbCBwYW5lIHBhcmVudC5cclxuICogVGhlIHZpcnR1YWwgY2FudmFzIGl0c2VsZiBpcyBpbXBsZW1lbnRlZCBhcyBhbiBIVE1MIGRpdiBlbGVtZW50LlxyXG4gKiBUaGUgbGF5b3V0IG9mIHRoZSBjb21wb25lbnQgaXMgdXBkYXRlZCBvbiByZXNpemUgb2YgdGhlIHBhcmVudCBvciBjaGFuZ2VzIG9mIHRoZSB6b29tIGZhY3Rvci5cclxuICovXHJcbkBDb21wb25lbnQoe1xyXG5cclxuICBzZWxlY3RvcjogJ2FwcC1hdWRpbycsXHJcbiAgdGVtcGxhdGU6IGBcclxuICAgIDxkaXYgI3ZpcnR1YWxDYW52YXM+XHJcbiAgICA8Y2FudmFzICNkaXZpZGVyIChtb3VzZWRvd24pPVwibW91c2Vkb3duKCRldmVudClcIiAobW91c2VvdmVyKT1cIm1vdXNlb3ZlcigkZXZlbnQpXCJcclxuICAgICAgICAgICAgKG1vdXNlbGVhdmUpPVwibW91c2VsZWF2ZSgkZXZlbnQpXCIgaGVpZ2h0PVwiMTBcIj48L2NhbnZhcz5cclxuICAgIDxhdWRpby1zaWduYWwgW3BvaW50ZXJQb3NpdGlvbl09XCJwb2ludGVyXCIgW3NlbGVjdGluZ109XCJzZWxlY3RpbmdcIiBbc2VsZWN0aW9uXT1cInNlbGVjdGlvblwiIChwb2ludGVyUG9zaXRpb25FdmVudEVtaXR0ZXIpPVwicG9pbnRlclBvc2l0aW9uQ2hhbmdlZCgkZXZlbnQpXCIgKHNlbGVjdGluZ0V2ZW50RW1pdHRlcik9XCJzZWxlY3RpbmdDaGFuZ2VkKCRldmVudClcIiAoc2VsZWN0ZWRFdmVudEVtaXR0ZXIpPVwic2VsZWN0aW9uQ2hhbmdlZCgkZXZlbnQpXCI+PC9hdWRpby1zaWduYWw+XHJcbiAgICA8YXVkaW8tc29uYWdyYW0gW3BvaW50ZXJQb3NpdGlvbl09XCJwb2ludGVyXCIgW3NlbGVjdGluZ109XCJzZWxlY3RpbmdcIiBbc2VsZWN0aW9uXT1cInNlbGVjdGlvblwiIChwb2ludGVyUG9zaXRpb25FdmVudEVtaXR0ZXIpPVwicG9pbnRlclBvc2l0aW9uQ2hhbmdlZCgkZXZlbnQpXCIgKHNlbGVjdGluZ0V2ZW50RW1pdHRlcik9XCJzZWxlY3RpbmdDaGFuZ2VkKCRldmVudClcIiAoc2VsZWN0ZWRFdmVudEVtaXR0ZXIpPVwic2VsZWN0aW9uQ2hhbmdlZCgkZXZlbnQpXCI+PC9hdWRpby1zb25hZ3JhbT5cclxuICAgIDwvZGl2PlxyXG4gIGAsXHJcbiAgc3R5bGVzOiBbYGRpdiB7XHJcbiAgICBtYXJnaW46IDA7XHJcbiAgICBwYWRkaW5nOiAwO1xyXG4gICAgdG9wOiAwO1xyXG4gICAgbGVmdDogMDtcclxuICAgIHdpZHRoOiAxMDAlO1xyXG4gICAgaGVpZ2h0OiAxMDAlO1xyXG4gICAgcG9zaXRpb246IHJlbGF0aXZlOyAvKiBUT0RPIGNvbnRhaW5lciBkaXYgcG9zaXRpb24gbXVzdCBub3QgYmUgJ3N0YXRpYycgKGRlZmF1bHQpIHRvIGFjdCBhcyByZWZlcmVuY2UgZm9yIHRoZSBjYW52YXNlcyAqL1xyXG4gICAgYm94LXNpemluZzogYm9yZGVyLWJveDtcclxuICAgIHRyYW5zZm9ybTogbm9uZTtcclxuICAgIG92ZXJmbG93OiBoaWRkZW47XHJcbiAgfWAsIGBjYW52YXN7XHJcbiAgICB0b3A6IDA7XHJcbiAgICBsZWZ0OiAwO1xyXG4gICAgd2lkdGg6IDA7XHJcbiAgICBoZWlnaHQ6IDA7XHJcbiAgICBjdXJzb3I6IG5zLXJlc2l6ZTtcclxuICAgIHBvc2l0aW9uOiBhYnNvbHV0ZTtcclxuICAgIHotaW5kZXg6IDE7XHJcbiAgICB0cmFuc2Zvcm06IG5vbmU7XHJcbiAgfWAsIGBhdWRpby1zaWduYWwge1xyXG4gICAgdG9wOiAwO1xyXG4gICAgbGVmdDogMDtcclxuICAgIHBvc2l0aW9uOiBhYnNvbHV0ZTtcclxuICAgIHotaW5kZXg6IDE7XHJcbiAgICB0cmFuc2Zvcm06IG5vbmU7XHJcbiAgfWAsIGBhdWRpby1zb25hZ3JhbSB7XHJcbiAgICB0b3A6IDA7XHJcbiAgICBsZWZ0OiAwO1xyXG4gICAgcG9zaXRpb246IGFic29sdXRlO1xyXG4gICAgei1pbmRleDogMTtcclxuICAgIHRyYW5zZm9ybTogbm9uZTtcclxuICB9YF1cclxuXHJcbn0pXHJcbmV4cG9ydCBjbGFzcyBBdWRpb0NsaXBVSUNvbnRhaW5lciBleHRlbmRzIEJhc2ljQXVkaW9DYW52YXNMYXllckNvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCxBZnRlclZpZXdJbml0e1xyXG5cclxuICBwcml2YXRlIHN0YXRpYyBESVZJREVSX1BJWEVMX1NJWkUgPSAxMDtcclxuXHJcbiAgcGFyZW50RTogSFRNTEVsZW1lbnQ7XHJcblxyXG4gIC8vIERpdmlkZXIgY2FudmFzXHJcbiAgQFZpZXdDaGlsZCgnZGl2aWRlcicsIHsgc3RhdGljOiB0cnVlIH0pIGNhbnZhc1JlZiE6IEVsZW1lbnRSZWY7XHJcbiAgZGMhOiBIVE1MQ2FudmFzRWxlbWVudDtcclxuXHJcbiAgLy8gVmlydHVhbCBjb250YWluZXJcclxuICBAVmlld0NoaWxkKCd2aXJ0dWFsQ2FudmFzJywgeyBzdGF0aWM6IHRydWUgfSkgY2VSZWYhOiBFbGVtZW50UmVmO1xyXG4gIGNlITogSFRNTERpdkVsZW1lbnQ7XHJcblxyXG4gIEBWaWV3Q2hpbGQoQXVkaW9TaWduYWwsIHsgc3RhdGljOiB0cnVlIH0pIGFzITogQXVkaW9TaWduYWw7XHJcbiAgQFZpZXdDaGlsZChTb25hZ3JhbSwgeyBzdGF0aWM6IHRydWUgfSkgc28hOiBTb25hZ3JhbTtcclxuXHJcbiAgcHJpdmF0ZSBfYXVkaW9DbGlwOkF1ZGlvQ2xpcCB8IG51bGw9bnVsbDtcclxuICBwb2ludGVyOiBNYXJrZXJ8bnVsbD1udWxsO1xyXG4gIHNlbGVjdGluZzogU2VsZWN0aW9ufG51bGw9bnVsbDtcclxuICBzZWxlY3Rpb246IFNlbGVjdGlvbnxudWxsPW51bGw7XHJcbiAgQE91dHB1dCgpIHNlbGVjdGlvbkV2ZW50RW1pdHRlciA9IG5ldyBFdmVudEVtaXR0ZXI8U2VsZWN0aW9uPigpO1xyXG4gIHByaXZhdGUgX3BsYXlGcmFtZVBvc2l0aW9uOiBudW1iZXJ8bnVsbD1udWxsO1xyXG4gIHByaXZhdGUgZHJhZ1N0YXJ0TW91c2VZOiBudW1iZXIgfCBudWxsID0gbnVsbDtcclxuICBwcml2YXRlIGRyYWdTdGFydFk6IG51bWJlciB8IG51bGwgPSBudWxsO1xyXG4gIHByaXZhdGUgZGl2aWRlclBvc2l0aW9uID0gMC41O1xyXG5cclxuICB1c2VyQWN0aW9uPWZhbHNlO1xyXG5cclxuICBwcml2YXRlIF94Wm9vbTogbnVtYmVyIHwgbnVsbCA9IG51bGw7IC8vIHBpeGVscyBwZXIgc2Vjb25kXHJcblxyXG4gIGdldCB4Wm9vbSgpOiBudW1iZXIgfCBudWxsIHtcclxuICAgIHJldHVybiB0aGlzLl94Wm9vbTtcclxuICB9XHJcblxyXG4gIHNldCB4Wm9vbSh2YWx1ZTogbnVtYmVyIHwgbnVsbCkge1xyXG4gICAgdGhpcy51c2VyQWN0aW9uPXRydWU7XHJcbiAgICB0aGlzLl94Wm9vbSA9IHZhbHVlO1xyXG4gICAgdGhpcy5sYXlvdXQoKVxyXG4gICAgdGhpcy51c2VyQWN0aW9uPWZhbHNlO1xyXG4gIH1cclxuXHJcbiAgLy8gaWYgdHJ1ZSB0aGUgY29tcGxldGUgYXVkaW8gZmlsZSBpcyBzaG93biwgdGhlIGRpc3BsYXkgZml0cyB0byB0aGUgdmlzaWJsZSBwYW5lbCwgdGhlIHgtem9vbSBmYWN0b3IgaXMgdmFyaWFibGUsIHRoaXMgaXMgdGhlIGRlZmF1bHRcclxuICBwcml2YXRlIF9maXhGaXRUb1BhbmVsID0gdHJ1ZTtcclxuXHJcbiAgc2V0IGZpeEZpdFRvUGFuZWwodmFsdWU6IGJvb2xlYW4pIHtcclxuICAgIHRoaXMuX2ZpeEZpdFRvUGFuZWwgPSB2YWx1ZTtcclxuICAgIGlmICh2YWx1ZSkge1xyXG4gICAgICAvLyB3ZSBkb24ndCBuZWVkICBjbGlwIGJvdW5kc1xyXG4gICAgICB0aGlzLmJvdW5kcz1udWxsO1xyXG4gICAgICB0aGlzLl94Wm9vbSA9IG51bGw7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICAvLyBob2xkIGN1cnJlbnQgem9vbSB2YWx1ZVxyXG4gICAgICAvL3RoaXMuX3hab29tPXRoaXMuY2Uub2Zmc2V0V2lkdGgvdGhpcy5fYXVkaW9EYXRhLmR1cmF0aW9uO1xyXG4gICAgfVxyXG4gICAgdGhpcy5sYXlvdXQoKVxyXG4gIH1cclxuXHJcbiAgY29uc3RydWN0b3IocHJpdmF0ZSByZWY6IEVsZW1lbnRSZWYpIHtcclxuICAgIHN1cGVyKClcclxuICAgIHRoaXMucGFyZW50RSA9IHRoaXMucmVmLm5hdGl2ZUVsZW1lbnQ7XHJcbiAgfVxyXG5cclxuICBuZ09uSW5pdCgpIHtcclxuICAgIHRoaXMuY2UgPSB0aGlzLmNlUmVmLm5hdGl2ZUVsZW1lbnQ7XHJcbiAgICB0aGlzLmRjID0gdGhpcy5jYW52YXNSZWYubmF0aXZlRWxlbWVudDtcclxuICB9XHJcblxyXG4gIG5nQWZ0ZXJWaWV3SW5pdCgpIHtcclxuICAgIHRoaXMubGF5b3V0KCk7XHJcbiAgICBjb25zdCBoZWlnaHRMaXN0ZW5lciA9IG5ldyBNdXRhdGlvbk9ic2VydmVyKChtcnM6IEFycmF5PE11dGF0aW9uUmVjb3JkPiwgbW86IE11dGF0aW9uT2JzZXJ2ZXIpID0+IHtcclxuXHJcbiAgICAgIGxldCBsYXlvdXQ9ZmFsc2U7XHJcbiAgICAgIG1ycy5mb3JFYWNoKChtcjogTXV0YXRpb25SZWNvcmQpID0+IHtcclxuICAgICAgICBpZiAoIXRoaXMudXNlckFjdGlvbiAmJiAnYXR0cmlidXRlcycgPT09IG1yLnR5cGUgJiYgKCdjbGFzcycgPT09IG1yLmF0dHJpYnV0ZU5hbWUgfHwgJ3N0eWxlJyA9PT0gbXIuYXR0cmlidXRlTmFtZSkpIHtcclxuICAgICAgICAgIGxheW91dD10cnVlO1xyXG4gICAgICAgIH1cclxuICAgICAgfSk7XHJcbiAgICAgIGlmKGxheW91dCl7XHJcbiAgICAgICAgLy8gcmUtbGF5b3V0IHJlcXVpcmVkXHJcbiAgICAgICAgdGhpcy5sYXlvdXQoZmFsc2UpO1xyXG4gICAgICB9XHJcbiAgICB9KTtcclxuXHJcbiAgICBoZWlnaHRMaXN0ZW5lci5vYnNlcnZlKHRoaXMuY2UsIHthdHRyaWJ1dGVzOiB0cnVlLCBjaGlsZExpc3Q6IHRydWUsIGNoYXJhY3RlckRhdGE6IHRydWV9KTtcclxuICAgIGhlaWdodExpc3RlbmVyLm9ic2VydmUodGhpcy5kYywge2F0dHJpYnV0ZXM6IHRydWUsIGNoaWxkTGlzdDogdHJ1ZSwgY2hhcmFjdGVyRGF0YTogdHJ1ZX0pO1xyXG5cclxuICAgIGNvbnN0IHJlc2l6ZU9ic2VydmVyID0gbmV3IFJlc2l6ZU9ic2VydmVyKChlbnRyaWVzLG9icykgPT4ge1xyXG4gICAgICAvL2NvbnNvbGUubG9nKFwiUmVzaXplIG9ic2VydmVkOlwiKTtcclxuICAgICAgZW50cmllcy5mb3JFYWNoKChlKT0+e1xyXG4gICAgICAgIC8vY29uc29sZS5sb2coZS5jb250ZW50UmVjdC53aWR0aCtcInhcIitlLmNvbnRlbnRSZWN0LmhlaWdodCk7XHJcbiAgICAgICAgdGhpcy5sYXlvdXQoKTtcclxuICAgICAgfSlcclxuICAgIH0pO1xyXG5cclxuICAgIHJlc2l6ZU9ic2VydmVyLm9ic2VydmUodGhpcy5jZSk7XHJcblxyXG4gIH1cclxuXHJcbiAgQEhvc3RMaXN0ZW5lcignd2luZG93OnJlc2l6ZScsIFsnJGV2ZW50J10pXHJcbiAgb25SZXNpemUoZXZlbnQ6IEV2ZW50KTogdm9pZCB7XHJcbiAgICB0aGlzLmxheW91dCgpO1xyXG4gIH1cclxuXHJcbiAgbW91c2VvdmVyKG1lOiBNb3VzZUV2ZW50KSB7XHJcbiAgICB0aGlzLmRpdmlkZXJDdXJzb3JQb3NpdGlvbihtZSwgdHJ1ZSk7XHJcbiAgfVxyXG5cclxuICBtb3VzZWxlYXZlKG1lOiBNb3VzZUV2ZW50KSB7XHJcbiAgICB0aGlzLmRpdmlkZXJDdXJzb3JQb3NpdGlvbihtZSwgZmFsc2UpO1xyXG4gIH1cclxuXHJcbiAgbW91c2Vkb3duKG1lOiBNb3VzZUV2ZW50KSB7XHJcbiAgICB0aGlzLmRyYWdTdGFydE1vdXNlWSA9IG1lLmNsaWVudFk7XHJcbiAgICB0aGlzLmRyYWdTdGFydFkgPSB0aGlzLmRjLm9mZnNldFRvcDtcclxuICAgIHRoaXMuZHJhZ1N0YXJ0TW91c2VZID0gbWUuY2xpZW50WTtcclxuICB9XHJcblxyXG4gIEBIb3N0TGlzdGVuZXIoJ2RvY3VtZW50Om1vdXNldXAnLCBbJyRldmVudCddKVxyXG4gIG9uTW91c2V1cChtZTogTW91c2VFdmVudCkge1xyXG4gICAgaWYgKHRoaXMuZHJhZ1N0YXJ0WSAhPSBudWxsKSB7XHJcbiAgICAgIHRoaXMudXNlckFjdGlvbj10cnVlO1xyXG4gICAgICB0aGlzLmRpdmlkZXJEcmFnKG1lKTtcclxuICAgICAgdGhpcy5sYXlvdXQoZmFsc2UpO1xyXG4gICAgICB0aGlzLmRyYWdTdGFydFkgPSBudWxsO1xyXG4gICAgICB0aGlzLnVzZXJBY3Rpb249ZmFsc2U7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBASG9zdExpc3RlbmVyKCdkb2N1bWVudDptb3VzZW1vdmUnLCBbJyRldmVudCddKVxyXG4gIG9uTW91c2Vtb3ZlKG1lOiBNb3VzZUV2ZW50KSB7XHJcbiAgICBpZiAodGhpcy5kcmFnU3RhcnRZICE9IG51bGwpIHtcclxuICAgICAgdGhpcy51c2VyQWN0aW9uPXRydWU7XHJcbiAgICAgIHRoaXMuZGl2aWRlckRyYWcobWUpO1xyXG4gICAgICB0aGlzLmxheW91dFNjYWxlZCgpO1xyXG4gICAgICB0aGlzLnVzZXJBY3Rpb249dHJ1ZTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIHBvaW50ZXJQb3NpdGlvbkNoYW5nZWQocHA6TWFya2VyKXtcclxuICAgIHRoaXMucG9pbnRlcj1wcFxyXG4gIH1cclxuXHJcbiAgc2VsZWN0aW5nQ2hhbmdlZChzOlNlbGVjdGlvbnwgbnVsbCl7XHJcbiAgICB0aGlzLnNlbGVjdGluZz1zXHJcbiAgfVxyXG5cclxuICBzZWxlY3Rpb25DaGFuZ2VkKHM6U2VsZWN0aW9uKXtcclxuICAgIHRoaXMuc2VsZWN0aW9uPXNcclxuICAgIGlmKHRoaXMuX2F1ZGlvQ2xpcCl7XHJcbiAgICAgIHRoaXMuX2F1ZGlvQ2xpcC5zZWxlY3Rpb249c1xyXG4gICAgfVxyXG4gICAgdGhpcy5zZWxlY3Rpb25FdmVudEVtaXR0ZXIuZW1pdCh0aGlzLnNlbGVjdGlvbilcclxuICB9XHJcblxyXG4gIHByaXZhdGUgY2FudmFzTW91c2VQb3MoYzogSFRNTENhbnZhc0VsZW1lbnQsIGU6IE1vdXNlRXZlbnQpOiBQb2ludCB7XHJcbiAgICBjb25zdCBjciA9IGMuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XHJcbiAgICBjb25zdCB4ID0gZS54IC0gY3IubGVmdDtcclxuICAgIGNvbnN0IHkgPSBlLnkgLSBjci50b3A7XHJcbiAgICByZXR1cm4gbmV3IFBvaW50KHgseSk7XHJcbiAgfVxyXG5cclxuICBkaXZpZGVyQ3Vyc29yUG9zaXRpb24oZTogTW91c2VFdmVudCwgc2hvdzogYm9vbGVhbikge1xyXG4gICAgaWYgKHRoaXMuZGMpIHtcclxuICAgICAgdGhpcy5jYW52YXNNb3VzZVBvcyh0aGlzLmRjLCBlKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIGRpdmlkZXJEcmFnKGU6IE1vdXNlRXZlbnQpIHtcclxuICAgIGlmICh0aGlzLmRjICYmIHRoaXMuZHJhZ1N0YXJ0TW91c2VZICYmIHRoaXMuZHJhZ1N0YXJ0WSkge1xyXG5cclxuICAgICAgY29uc3QgZHJhZ09mZnNldCA9IGUuY2xpZW50WSAtIHRoaXMuZHJhZ1N0YXJ0TW91c2VZO1xyXG4gICAgICBjb25zdCBjZUhlaWdodCA9IHRoaXMuY2Uub2Zmc2V0SGVpZ2h0O1xyXG5cclxuICAgICAgbGV0IG5ld1RvcCA9ICh0aGlzLmRyYWdTdGFydFkgKyBkcmFnT2Zmc2V0KTtcclxuICAgICAgaWYgKG5ld1RvcCA8IDApIHtcclxuICAgICAgICBuZXdUb3AgPSAwO1xyXG4gICAgICB9XHJcbiAgICAgIGlmIChuZXdUb3AgPiBjZUhlaWdodCAtIEF1ZGlvQ2xpcFVJQ29udGFpbmVyLkRJVklERVJfUElYRUxfU0laRSkge1xyXG4gICAgICAgIG5ld1RvcCA9IGNlSGVpZ2h0IC0gQXVkaW9DbGlwVUlDb250YWluZXIuRElWSURFUl9QSVhFTF9TSVpFO1xyXG4gICAgICB9XHJcbiAgICAgIHRoaXMuZGMuc3R5bGUudG9wID0gbmV3VG9wLnRvU3RyaW5nKCkgKyAncHgnO1xyXG4gICAgICB0aGlzLmRpdmlkZXJQb3NpdGlvbiA9ICh0aGlzLmRjLm9mZnNldFRvcCArIEF1ZGlvQ2xpcFVJQ29udGFpbmVyLkRJVklERVJfUElYRUxfU0laRSAvIDIpIC8gY2VIZWlnaHQ7XHJcbiAgICAgIGlmICh0aGlzLmRpdmlkZXJQb3NpdGlvbiA+IDEuMCkge1xyXG4gICAgICAgIHRoaXMuZGl2aWRlclBvc2l0aW9uID0gMS4wO1xyXG4gICAgICB9XHJcbiAgICAgIGlmICh0aGlzLmRpdmlkZXJQb3NpdGlvbiA8IDAuMCkge1xyXG4gICAgICAgIHRoaXMuZGl2aWRlclBvc2l0aW9uID0gMC4wO1xyXG4gICAgICB9XHJcbiAgICAgIHRoaXMuZHJhd0RpdmlkZXIoKTtcclxuICAgIH1cclxuICB9XHJcblxyXG5cclxuICBkcmF3RGl2aWRlcigpIHtcclxuICAgIGNvbnN0IHcgPSB0aGlzLmRjLndpZHRoO1xyXG4gICAgY29uc3QgaCA9IHRoaXMuZGMuaGVpZ2h0O1xyXG4gICAgY29uc3QgZyA9IHRoaXMuZGMuZ2V0Q29udGV4dCgnMmQnKTtcclxuICAgIGlmIChnICYmIHc+MTAgJiYgaD49MSkge1xyXG4gICAgICBnLmZpbGxTdHlsZSA9ICd3aGl0ZSc7XHJcbiAgICAgIGcuZmlsbFJlY3QoMCwgMCwgdywgaCk7XHJcbiAgICAgIGcuZmlsbFN0eWxlID0gJ2JsYWNrJztcclxuICAgICAgZy5maWxsUmVjdCg1LCA1LCB3IC0gMTAsIDEpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgY2xpcEJvdW5kcyhjbGlwQm91bmRzOiBSZWN0YW5nbGUpIHtcclxuICAgIHRoaXMuYm91bmRzID0gY2xpcEJvdW5kcztcclxuICAgIHRoaXMubGF5b3V0KCk7XHJcbiAgfVxyXG5cclxuICBjdXJyZW50WFpvb20oKTogbnVtYmVyIHwgbnVsbCB7XHJcbiAgICBsZXQgeHogPSB0aGlzLl94Wm9vbTtcclxuICAgIGlmICh4ej09bnVsbCAmJiB0aGlzLl9hdWRpb0RhdGFIb2xkZXIpIHtcclxuICAgICAgbGV0IG93ID0gdGhpcy5jZS5vZmZzZXRXaWR0aDtcclxuICAgICAgaWYgKG93IDwgMSkge1xyXG4gICAgICAgIC8vIGF0IGxlYXN0IG9uZSBwaXhlbCB3aWR0aCB0byBhdm9pZCB4LXpvb20gemVybyB2YWx1ZXNcclxuICAgICAgICBvdyA9IDE7XHJcbiAgICAgIH1cclxuICAgICAgeHogPSBvdyAvIHRoaXMuX2F1ZGlvRGF0YUhvbGRlci5kdXJhdGlvbjtcclxuICAgIH1cclxuICAgIHJldHVybiB4ejtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgX2xheW91dChjbGVhcjogYm9vbGVhbiwgcmVkcmF3OiBib29sZWFuKSB7XHJcbiAgICBsZXQgY2VCY3IgPSB0aGlzLmNlLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xyXG5cclxuICAgIGNvbnN0IGNlQmNySW50VyA9IE1hdGguZmxvb3IoY2VCY3Iud2lkdGgpO1xyXG4gICAgY29uc3QgY2VCY3JJbnRIID0gTWF0aC5mbG9vcihjZUJjci5oZWlnaHQpO1xyXG5cclxuICAgIC8vIGhlaWdodCBhdmFpbGFibGUgZm9yIHBsdWdpbnMgKGF1ZGlvc2lnbmFsIGFuZCBzb25hZ3JhbSlcclxuICAgIGxldCBwc0ggPSBjZUJjckludEggLSBBdWRpb0NsaXBVSUNvbnRhaW5lci5ESVZJREVSX1BJWEVMX1NJWkU7XHJcbiAgICBpZiAocHNIIDwgMCkge1xyXG4gICAgICBwc0ggPSAwO1xyXG4gICAgfVxyXG4gICAgLy8gYXVkaW8gc2lnbmFsIGhlaWdodFxyXG4gICAgY29uc3QgYXNIID0gTWF0aC5yb3VuZChwc0ggKiB0aGlzLmRpdmlkZXJQb3NpdGlvbik7XHJcblxyXG4gICAgLy8gc29uYWdyYW0gaGVpZ2h0IChyZXN0OiBhdmFpbGFibGUgaGVpZ2h0IG1pbnVzIGRpdmlkZXIgaGVpZ2h0IG1pbnVzIGF1ZGlvc2lnbmFsIGhlaWdodClcclxuICAgIGxldCBzb0ggPSBjZUJjckludEggLSBBdWRpb0NsaXBVSUNvbnRhaW5lci5ESVZJREVSX1BJWEVMX1NJWkUgLSBhc0g7XHJcbiAgICBpZiAoc29IIDwgMCkge1xyXG4gICAgICBzb0ggPSAwO1xyXG4gICAgfVxyXG5cclxuICAvLyBzb25hZ3JhbSB0b3AgcG9zaXRpb25cclxuICAgIGNvbnN0IHNvVG9wID0gYXNIICsgQXVkaW9DbGlwVUlDb250YWluZXIuRElWSURFUl9QSVhFTF9TSVpFO1xyXG5cclxuICAgIC8vIFZpc2libGUgYm91bmRzXHJcbiAgICAvLyBsZWZ0IHBvc2l0aW9uXHJcbiAgICBsZXQgdmJMZWZ0ID0gMDtcclxuICAgIC8vIHdpZHRoXHJcbiAgICBsZXQgdmJXaWR0aCA9IGNlQmNySW50VztcclxuICAgIGlmICghdGhpcy5fZml4Rml0VG9QYW5lbCAmJiB0aGlzLmJvdW5kcykge1xyXG4gICAgICB2YkxlZnQgPSBNYXRoLnJvdW5kKHRoaXMuYm91bmRzLnBvc2l0aW9uLmxlZnQpO1xyXG4gICAgICB2YldpZHRoID0gTWF0aC5yb3VuZCh0aGlzLmJvdW5kcy5kaW1lbnNpb24ud2lkdGgpO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIERpdmlkZXJcclxuICAgIC8vIGxlZnQgcG9zaXRpb25cclxuICAgIGxldCB2YkxlZnRTdHlsID0gdmJMZWZ0ICsgJ3B4JztcclxuICAgIGlmICh0aGlzLmRjLnN0eWxlLmxlZnQgIT0gdmJMZWZ0U3R5bCkge1xyXG4gICAgICB0aGlzLmRjLnN0eWxlLmxlZnQgPSB2YkxlZnRTdHlsO1xyXG4gICAgfVxyXG4gICAgLy8gdG9wIHBvc2l0aW9uXHJcbiAgICAvL2NvbnN0IGRUb3AgPSBhc0g7XHJcbiAgICBjb25zdCBkVG9wU3RyID0gYXNIICsgJ3B4JztcclxuICAgIGlmICh0aGlzLmRjLnN0eWxlLnRvcCAhPSBkVG9wU3RyKSB7XHJcbiAgICAgIHRoaXMuZGMuc3R5bGUudG9wID0gZFRvcFN0cjtcclxuICAgIH1cclxuICAgIC8vIHdpZHRoXHJcbiAgICBsZXQgdmJXaWR0aFN0eWxlID0gdmJXaWR0aCArICdweCc7XHJcbiAgICBpZiAodGhpcy5kYy5zdHlsZS53aWR0aCAhPSB2YldpZHRoU3R5bGUpIHtcclxuICAgICAgdGhpcy5kYy5zdHlsZS53aWR0aCA9IHZiV2lkdGhTdHlsZTtcclxuICAgIH1cclxuICAgIGlmICh0aGlzLmRjLndpZHRoICE9IHZiV2lkdGgpIHtcclxuICAgICAgdGhpcy5kYy53aWR0aCA9IHZiV2lkdGg7XHJcbiAgICB9XHJcbiAgICAvLyBoZWlnaHRcclxuICAgIGlmKHRoaXMuZGMuaGVpZ2h0IT1BdWRpb0NsaXBVSUNvbnRhaW5lci5ESVZJREVSX1BJWEVMX1NJWkUpIHtcclxuICAgICAgdGhpcy5kYy5oZWlnaHQgPSBBdWRpb0NsaXBVSUNvbnRhaW5lci5ESVZJREVSX1BJWEVMX1NJWkU7XHJcblxyXG4gICAgfVxyXG4gICAgbGV0IGRpdlBpeGVsU2l6ZVN0eWxlPUF1ZGlvQ2xpcFVJQ29udGFpbmVyLkRJVklERVJfUElYRUxfU0laRS50b1N0cmluZygpICsgJ3B4JztcclxuICAgIGlmKHRoaXMuZGMuc3R5bGUuaGVpZ2h0IT1kaXZQaXhlbFNpemVTdHlsZSkge1xyXG4gICAgICB0aGlzLmRjLnN0eWxlLmhlaWdodCA9IGRpdlBpeGVsU2l6ZVN0eWxlO1xyXG4gICAgfVxyXG5cclxuICAgIHRoaXMuZHJhd0RpdmlkZXIoKTtcclxuXHJcblxyXG4gICAgLy8gVmlydHVhbCBkaW1lbnNpb24sIG9ubHkgd2lkdGggaXMgdXNlZFxyXG4gICAgbGV0IHZpcnR1YWxEaW0gPSBuZXcgRGltZW5zaW9uKGNlQmNySW50VywgMClcclxuXHJcbiAgICAvLyBWaXNpYmxlIGJvdW5kcyBvZiBjb250YWluZXJcclxuICAgIGxldCBiciA9IG5ldyBSZWN0YW5nbGUobmV3IFBvc2l0aW9uKHZiTGVmdCwgMCksIG5ldyBEaW1lbnNpb24odmJXaWR0aCwgY2VCY3JJbnRIKSk7XHJcblxyXG4gICAgLy8gU2V0IGNvbnRhaW5lciBib3VuZHNcclxuICAgIHRoaXMubGF5b3V0Qm91bmRzKGJyLCB2aXJ0dWFsRGltLCBmYWxzZSk7XHJcblxyXG4gICAgLy8gVmlzaWJsZSBib3VuZHMgb2YgYXVkaW9zaWduYWxcclxuICAgIGxldCBhc1IgPSBuZXcgUmVjdGFuZ2xlKG5ldyBQb3NpdGlvbih2YkxlZnQsIDApLCBuZXcgRGltZW5zaW9uKHZiV2lkdGgsIGFzSCkpO1xyXG5cclxuICAgIC8vIFNldCBhdWRpb3NpZ25hbCBib3VuZHNcclxuICAgIHRoaXMuYXMubGF5b3V0Qm91bmRzKGFzUiwgdmlydHVhbERpbSwgcmVkcmF3LCBjbGVhcik7XHJcblxyXG4gICAgLy8gVmlzaWJsZSBib3VuZHMgb2Ygc29uYWdyYW1cclxuICAgIGxldCBzb1IgPSBuZXcgUmVjdGFuZ2xlKG5ldyBQb3NpdGlvbih2YkxlZnQsIHNvVG9wKSwgbmV3IERpbWVuc2lvbih2YldpZHRoLCBzb0gpKTtcclxuXHJcbiAgICAvLyBTZXQgc29uYWdyYW0gYm91bmRzXHJcbiAgICB0aGlzLnNvLmxheW91dEJvdW5kcyhzb1IsIHZpcnR1YWxEaW0sIHJlZHJhdywgY2xlYXIpO1xyXG4gIH1cclxuXHJcbiAgbGF5b3V0U2NhbGVkKCkge1xyXG4gICAgdGhpcy5fbGF5b3V0KGZhbHNlLCBmYWxzZSk7XHJcbiAgfVxyXG5cclxuICBsYXlvdXQoY2xlYXI9dHJ1ZSkge1xyXG5cclxuICAgIGlmKHRoaXMuY2UgJiYgdGhpcy5kYykge1xyXG4gICAgICBjb25zdCBjbGllbnRXPXRoaXMuY2UuY2xpZW50V2lkdGg7XHJcbiAgICAgIGlmKHRoaXMuX2F1ZGlvRGF0YUhvbGRlcil7XHJcbiAgICAgICAgaWYodGhpcy5fZml4Rml0VG9QYW5lbCkge1xyXG4gICAgICAgICAgLy8gU2V0IHRoZSB2aXJ0dWFsIGNhbnZhcyB3aWR0aCB0byB0aGUgdmlzaWJsZSB3aWR0aFxyXG4gICAgICAgICAgaWYodGhpcy5jZS5zdHlsZS53aWR0aCE9JzEwMCUnKSB7XHJcbiAgICAgICAgICAgIC8vY29uc29sZS5sb2coXCJzZXQgd2lkdGggdG8gMTAwJVwiKTtcclxuICAgICAgICAgICAgdGhpcy5jZS5zdHlsZS53aWR0aCA9ICcxMDAlJztcclxuICAgICAgICAgIH1cclxuICAgICAgICB9ZWxzZXtcclxuICAgICAgICAgIGlmICh0aGlzLl94Wm9vbSkge1xyXG4gICAgICAgICAgICAvLyBTZXQgdGhlIHZpcnR1YWwgY2FudmFzIHdpZHRoIGFjY29yZGluZyB0byB0aGUgdmFsdWUgb2YgdGhlIHVzZXIgc2VsZWN0ZWQgeFpvb20gdmFsdWVcclxuICAgICAgICAgICAgY29uc3QgbmV3Q2xXID0gTWF0aC5yb3VuZCggdGhpcy5feFpvb20qdGhpcy5fYXVkaW9EYXRhSG9sZGVyPy5kdXJhdGlvbiApO1xyXG4gICAgICAgICAgICB0aGlzLmNlLnN0eWxlLndpZHRoID0gbmV3Q2xXICsgJ3B4JztcclxuICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIC8vIFNldCB0aGUgdmlydHVhbCBjYW52YXMgd2lkdGggdG8gdGhlIHZpc2libGUgd2lkdGggb25seVxyXG4gICAgICAgICAgICB0aGlzLmNlLnN0eWxlLndpZHRoID0gY2xpZW50VyArICdweCc7XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcbiAgICAgIHRoaXMuX2xheW91dChjbGVhcix0cnVlKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIEBJbnB1dCgpXHJcbiAgc2V0IGF1ZGlvRGF0YShhdWRpb0RhdGFIb2xkZXI6IEF1ZGlvRGF0YUhvbGRlciB8IG51bGwpIHtcclxuICAgIHRoaXMuX2F1ZGlvQ2xpcD1udWxsXHJcbiAgICB0aGlzLl9hdWRpb0RhdGFIb2xkZXI9YXVkaW9EYXRhSG9sZGVyO1xyXG4gICAgdGhpcy5hcy5zZXREYXRhKGF1ZGlvRGF0YUhvbGRlcik7XHJcbiAgICB0aGlzLnNvLnNldERhdGEoYXVkaW9EYXRhSG9sZGVyKTtcclxuICAgIHRoaXMubGF5b3V0KCk7XHJcbiAgfVxyXG5cclxuICBnZXQgYXVkaW9EYXRhKCk6QXVkaW9EYXRhSG9sZGVyfG51bGx7XHJcbiAgICByZXR1cm4gdGhpcy5fYXVkaW9EYXRhSG9sZGVyXHJcbiAgfVxyXG5cclxuXHJcbiAgQElucHV0KClcclxuICBzZXQgYXVkaW9DbGlwKGF1ZGlvQ2xpcDogQXVkaW9DbGlwIHwgbnVsbCkge1xyXG4gICAgdGhpcy5fYXVkaW9DbGlwPWF1ZGlvQ2xpcFxyXG4gICAgICBsZXQgYXVkaW9EYXRhOkF1ZGlvRGF0YUhvbGRlcnxudWxsPW51bGw7XHJcbiAgICBsZXQgc2VsOlNlbGVjdGlvbnxudWxsPW51bGw7XHJcbiAgICAgIGlmKGF1ZGlvQ2xpcCkge1xyXG4gICAgICAgIGF1ZGlvRGF0YSA9IGF1ZGlvQ2xpcC5hdWRpb0RhdGFIb2xkZXI7XHJcbiAgICAgICAgaWYgKHRoaXMuX2F1ZGlvQ2xpcCkge1xyXG4gICAgICAgICAgdGhpcy5fYXVkaW9DbGlwLmFkZFNlbGVjdGlvbk9ic2VydmVyKChjbGlwKSA9PiB7XHJcbiAgICAgICAgICAgIHRoaXMuc2VsZWN0aW9uID0gY2xpcC5zZWxlY3Rpb25cclxuICAgICAgICAgIH0pO1xyXG4gICAgICAgIH1cclxuICAgICAgICBzZWw9YXVkaW9DbGlwLnNlbGVjdGlvbjtcclxuICAgICAgfVxyXG4gICAgICB0aGlzLl9hdWRpb0RhdGFIb2xkZXIgPSBhdWRpb0RhdGE7XHJcbiAgICAgIHRoaXMuYXMuc2V0RGF0YSh0aGlzLl9hdWRpb0RhdGFIb2xkZXIpO1xyXG4gICAgICB0aGlzLnNvLnNldERhdGEodGhpcy5fYXVkaW9EYXRhSG9sZGVyKTtcclxuICAgICAgdGhpcy5zZWxlY3Rpbmc9bnVsbFxyXG4gICAgICB0aGlzLnNlbGVjdGlvbj1zZWxcclxuICAgIHRoaXMubGF5b3V0KCk7XHJcbiAgfVxyXG5cclxuICBnZXQgcGxheUZyYW1lUG9zaXRpb24oKTogbnVtYmVyIHxudWxsIHtcclxuICAgIHJldHVybiB0aGlzLl9wbGF5RnJhbWVQb3NpdGlvbjtcclxuICB9XHJcblxyXG4gIHNldCBwbGF5RnJhbWVQb3NpdGlvbihwbGF5RnJhbWVQb3NpdGlvbjogbnVtYmVyfG51bGwpIHtcclxuICAgIHRoaXMuX3BsYXlGcmFtZVBvc2l0aW9uID0gcGxheUZyYW1lUG9zaXRpb247XHJcbiAgICB0aGlzLmFzLnBsYXlGcmFtZVBvc2l0aW9uID0gcGxheUZyYW1lUG9zaXRpb247XHJcbiAgICB0aGlzLnNvLnBsYXlGcmFtZVBvc2l0aW9uID0gcGxheUZyYW1lUG9zaXRpb247XHJcbiAgfVxyXG59XHJcblxyXG4iXX0=
|