speechrecorderng 3.10.13 → 3.11.1

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 (99) hide show
  1. package/README.md +1 -1
  2. package/fesm2022/speechrecorderng.mjs +204 -201
  3. package/fesm2022/speechrecorderng.mjs.map +1 -1
  4. package/lib/audio/ui/audio_canvas_layer_comp.d.ts +2 -2
  5. package/lib/spr.module.version.d.ts +1 -1
  6. package/lib/ui/canvas_layer_comp.d.ts +1 -1
  7. package/lib/ui/responsive_component.d.ts +1 -1
  8. package/package.json +13 -15
  9. package/esm2022/lib/action/action.mjs +0 -73
  10. package/esm2022/lib/audio/array_audio_buffer.mjs +0 -164
  11. package/esm2022/lib/audio/array_audio_buffer_input_stream.mjs +0 -86
  12. package/esm2022/lib/audio/array_audio_buffer_random_access_stream.mjs +0 -16
  13. package/esm2022/lib/audio/audio_data_holder.mjs +0 -264
  14. package/esm2022/lib/audio/audio_display.mjs +0 -118
  15. package/esm2022/lib/audio/audio_player.mjs +0 -238
  16. package/esm2022/lib/audio/capture/capture.mjs +0 -855
  17. package/esm2022/lib/audio/context.mjs +0 -79
  18. package/esm2022/lib/audio/dsp/level_measure.mjs +0 -517
  19. package/esm2022/lib/audio/format.mjs +0 -20
  20. package/esm2022/lib/audio/impl/wavformat.mjs +0 -7
  21. package/esm2022/lib/audio/impl/wavreader.mjs +0 -144
  22. package/esm2022/lib/audio/impl/wavwriter.mjs +0 -191
  23. package/esm2022/lib/audio/inddb_audio_buffer.mjs +0 -508
  24. package/esm2022/lib/audio/io/stream.mjs +0 -59
  25. package/esm2022/lib/audio/net_audio_buffer.mjs +0 -293
  26. package/esm2022/lib/audio/persistor.mjs +0 -81
  27. package/esm2022/lib/audio/playback/array_audio_buffer_source_node.mjs +0 -126
  28. package/esm2022/lib/audio/playback/audio_source_node.mjs +0 -18
  29. package/esm2022/lib/audio/playback/audio_source_worklet_module_loader.mjs +0 -167
  30. package/esm2022/lib/audio/playback/inddb_audio_buffer_source_node.mjs +0 -167
  31. package/esm2022/lib/audio/playback/net_audio_buffer_source_node.mjs +0 -218
  32. package/esm2022/lib/audio/playback/player.mjs +0 -402
  33. package/esm2022/lib/audio/ui/audio_canvas_layer_comp.mjs +0 -347
  34. package/esm2022/lib/audio/ui/audio_display_control.mjs +0 -150
  35. package/esm2022/lib/audio/ui/audio_display_scroll_pane.mjs +0 -146
  36. package/esm2022/lib/audio/ui/audiosignal.mjs +0 -533
  37. package/esm2022/lib/audio/ui/common.mjs +0 -19
  38. package/esm2022/lib/audio/ui/container.mjs +0 -414
  39. package/esm2022/lib/audio/ui/livelevel.mjs +0 -361
  40. package/esm2022/lib/audio/ui/scroll_pane_horizontal.mjs +0 -11
  41. package/esm2022/lib/audio/ui/sonagram.mjs +0 -900
  42. package/esm2022/lib/db/inddb.mjs +0 -120
  43. package/esm2022/lib/dsp/utils.mjs +0 -48
  44. package/esm2022/lib/environment/environment.defaults.mjs +0 -9
  45. package/esm2022/lib/io/BinaryReader.mjs +0 -93
  46. package/esm2022/lib/io/BinaryWriter.mjs +0 -80
  47. package/esm2022/lib/io/stream.mjs +0 -259
  48. package/esm2022/lib/math/2d/geometry.mjs +0 -28
  49. package/esm2022/lib/math/complex.mjs +0 -58
  50. package/esm2022/lib/math/dft.mjs +0 -196
  51. package/esm2022/lib/media/utils.mjs +0 -14
  52. package/esm2022/lib/net/uploader.mjs +0 -367
  53. package/esm2022/lib/recorder_component.mjs +0 -65
  54. package/esm2022/lib/speechrecorder/project/project.mjs +0 -54
  55. package/esm2022/lib/speechrecorder/project/project.service.mjs +0 -64
  56. package/esm2022/lib/speechrecorder/recording.mjs +0 -124
  57. package/esm2022/lib/speechrecorder/recordings/basic_recording.service.mjs +0 -221
  58. package/esm2022/lib/speechrecorder/recordings/recordings.service.mjs +0 -1014
  59. package/esm2022/lib/speechrecorder/script/script.mjs +0 -114
  60. package/esm2022/lib/speechrecorder/script/script.service.mjs +0 -47
  61. package/esm2022/lib/speechrecorder/session/audiorecorder.mjs +0 -1179
  62. package/esm2022/lib/speechrecorder/session/basicrecorder.mjs +0 -676
  63. package/esm2022/lib/speechrecorder/session/controlpanel.mjs +0 -416
  64. package/esm2022/lib/speechrecorder/session/item.mjs +0 -30
  65. package/esm2022/lib/speechrecorder/session/progress.mjs +0 -135
  66. package/esm2022/lib/speechrecorder/session/prompting.mjs +0 -639
  67. package/esm2022/lib/speechrecorder/session/recorder_combi_pane.mjs +0 -88
  68. package/esm2022/lib/speechrecorder/session/recording_file_cache.mjs +0 -195
  69. package/esm2022/lib/speechrecorder/session/recording_list.mjs +0 -188
  70. package/esm2022/lib/speechrecorder/session/recordingfile/recording-file-meta.component.mjs +0 -128
  71. package/esm2022/lib/speechrecorder/session/recordingfile/recording-file-navi.component.mjs +0 -114
  72. package/esm2022/lib/speechrecorder/session/recordingfile/recording-file-u-i.component.mjs +0 -146
  73. package/esm2022/lib/speechrecorder/session/recordingfile/recording-file-view.component.mjs +0 -424
  74. package/esm2022/lib/speechrecorder/session/recordingfile/recording-file.mjs +0 -68
  75. package/esm2022/lib/speechrecorder/session/recordingfile/recordingfile-service.mjs +0 -288
  76. package/esm2022/lib/speechrecorder/session/session.mjs +0 -2
  77. package/esm2022/lib/speechrecorder/session/session.service.mjs +0 -69
  78. package/esm2022/lib/speechrecorder/session/session_finished_dialog.mjs +0 -46
  79. package/esm2022/lib/speechrecorder/session/sessionmanager.mjs +0 -1385
  80. package/esm2022/lib/speechrecorder/session/warning_bar.mjs +0 -33
  81. package/esm2022/lib/speechrecorder/spruploader.mjs +0 -22
  82. package/esm2022/lib/speechrecorder/startstopsignal/startstopsignal.mjs +0 -2
  83. package/esm2022/lib/speechrecorder/startstopsignal/ui/simpletrafficlight.mjs +0 -57
  84. package/esm2022/lib/speechrecorderng.component.mjs +0 -392
  85. package/esm2022/lib/speechrecorderng.module.mjs +0 -97
  86. package/esm2022/lib/spr.config.mjs +0 -27
  87. package/esm2022/lib/spr.module.version.mjs +0 -2
  88. package/esm2022/lib/ui/canvas_layer_comp.mjs +0 -38
  89. package/esm2022/lib/ui/intersection-observer.directive.mjs +0 -32
  90. package/esm2022/lib/ui/message_dialog.mjs +0 -51
  91. package/esm2022/lib/ui/recordingitem_display.mjs +0 -253
  92. package/esm2022/lib/ui/responsive_component.mjs +0 -24
  93. package/esm2022/lib/utils/scrollIntoViewToBottom.mjs +0 -23
  94. package/esm2022/lib/utils/ua-parser.mjs +0 -190
  95. package/esm2022/lib/utils/utils.mjs +0 -132
  96. package/esm2022/lib/utils/wake_lock.mjs +0 -114
  97. package/esm2022/lib/utils/wake_lock_media.mjs +0 -2
  98. package/esm2022/public-api.mjs +0 -35
  99. package/esm2022/speechrecorderng.mjs +0 -5
@@ -1,639 +0,0 @@
1
- import { Component, ViewChild, Input, Output, EventEmitter, HostListener, HostBinding } from "@angular/core";
2
- import { SimpleTrafficLight } from "../startstopsignal/ui/simpletrafficlight";
3
- import { AudioDisplay } from "../../audio/audio_display";
4
- import { ResponsiveComponent } from "../../ui/responsive_component";
5
- import * as i0 from "@angular/core";
6
- import * as i1 from "../project/project.service";
7
- import * as i2 from "@angular/cdk/layout";
8
- import * as i3 from "@angular/common";
9
- import * as i4 from "../../audio/audio_display";
10
- import * as i5 from "./progress";
11
- import * as i6 from "../startstopsignal/ui/simpletrafficlight";
12
- export class Recinstructions {
13
- displayText() {
14
- let riTxt = '';
15
- if (this.itemCount && this.selectedItemIdx) {
16
- riTxt = riTxt + this.selectedItemIdx + '/' + (this.itemCount - 1);
17
- }
18
- if (this.recinstructions) {
19
- riTxt = riTxt + ': ' + this.recinstructions;
20
- }
21
- return riTxt;
22
- }
23
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.12", ngImport: i0, type: Recinstructions, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
24
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.12", type: Recinstructions, selector: "spr-recinstructions", inputs: { recinstructions: "recinstructions", selectedItemIdx: "selectedItemIdx", itemCount: "itemCount" }, ngImport: i0, template: `
25
-
26
- {{displayText()}}
27
- `, isInline: true, styles: [":host{justify-content:left;align-items:flex-start;background:#fff;text-align:left;font-size:1em;flex:0;width:100%}\n"] }); }
28
- }
29
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.12", ngImport: i0, type: Recinstructions, decorators: [{
30
- type: Component,
31
- args: [{ selector: 'spr-recinstructions', template: `
32
-
33
- {{displayText()}}
34
- `, styles: [":host{justify-content:left;align-items:flex-start;background:#fff;text-align:left;font-size:1em;flex:0;width:100%}\n"] }]
35
- }], propDecorators: { recinstructions: [{
36
- type: Input
37
- }], selectedItemIdx: [{
38
- type: Input
39
- }], itemCount: [{
40
- type: Input
41
- }] } });
42
- export class Prompter {
43
- constructor(elRef, renderer, projectService) {
44
- this.elRef = elRef;
45
- this.renderer = renderer;
46
- this.projectService = projectService;
47
- this._promptMediaItems = null;
48
- this.prompterHeight = 0;
49
- this._text = null;
50
- this._src = null;
51
- this.currPromptChild = null;
52
- this.prompterStyleFill = false;
53
- }
54
- get text() {
55
- return this._text;
56
- }
57
- get src() {
58
- return this._src;
59
- }
60
- srcUrl() {
61
- if (this.projectName && this._src) {
62
- return this.projectService.projectResourceUrl(this.projectName, this._src);
63
- }
64
- return null;
65
- }
66
- width() {
67
- if (this.elRef) {
68
- if (this.elRef.nativeElement) {
69
- return this.elRef.nativeElement.clientWidth;
70
- }
71
- }
72
- return null;
73
- }
74
- height() {
75
- if (this.elRef) {
76
- if (this.elRef.nativeElement) {
77
- return this.elRef.nativeElement.clientHeight;
78
- }
79
- }
80
- return null;
81
- }
82
- appendTextElement(parentEl, txt) {
83
- let t = txt.text;
84
- let txtNd = this.renderer.createText(t);
85
- if (txt.decoration || txt.color) {
86
- let spEl = this.renderer.createElement('span');
87
- let styleStr = '';
88
- if (txt.decoration) {
89
- styleStr = styleStr + 'text-decoration: ' + txt.decoration + ';';
90
- }
91
- if (txt.color) {
92
- styleStr = styleStr + 'color: ' + txt.color + ';';
93
- }
94
- spEl.style = styleStr;
95
- this.renderer.appendChild(parentEl, spEl);
96
- this.renderer.appendChild(spEl, txtNd);
97
- }
98
- else {
99
- this.renderer.appendChild(parentEl, txtNd);
100
- }
101
- }
102
- set promptMediaItems(pMis) {
103
- this._promptMediaItems = pMis;
104
- if (this.currPromptChild != null) {
105
- this.renderer.removeChild(this.elRef.nativeElement, this.currPromptChild);
106
- }
107
- if (this._promptMediaItems && this._promptMediaItems.length == 1) {
108
- let mi = this._promptMediaItems[0];
109
- this.mimetype = 'text/plain';
110
- if (mi.mimetype) {
111
- this.mimetype = mi.mimetype.trim();
112
- }
113
- if (this.mimetype === 'text/plain') {
114
- this._text = mi.text;
115
- this._src = null;
116
- let prTxt = '';
117
- if (this._text) {
118
- prTxt = this._text;
119
- }
120
- this.currPromptChild = this.renderer.createText(prTxt);
121
- this.prompterStyleFill = false;
122
- this.renderer.appendChild(this.elRef.nativeElement, this.currPromptChild);
123
- }
124
- else if (this.mimetype === 'text/x-prompt') {
125
- //this.rendering=true
126
- this._text = null;
127
- this._src = null;
128
- this._blocks = new Array();
129
- let pd = mi.promptDoc;
130
- if (pd) {
131
- let pdBody = pd.body;
132
- if (pdBody) {
133
- this._blocks = pdBody.blocks;
134
- }
135
- }
136
- this.prompterStyleFill = false;
137
- this.currPromptChild = this.renderer.createElement('div');
138
- if (this._blocks) {
139
- for (let bi = 0; bi < this._blocks.length; bi++) {
140
- let bl = this._blocks[bi];
141
- if ('p' === bl.type) {
142
- let pBlEl = this.renderer.createElement('p');
143
- this.renderer.appendChild(this.currPromptChild, pBlEl);
144
- for (let ti = 0; ti < bl.texts.length; ti++) {
145
- let txt = bl.texts[ti];
146
- if (txt) {
147
- if ('text' === txt.type) {
148
- this.appendTextElement(pBlEl, txt);
149
- }
150
- else if ('font' === txt.type) {
151
- let spEl = this.renderer.createElement('span');
152
- let styleStr = '';
153
- if (txt.style) {
154
- styleStr = styleStr + 'font-style: ' + txt.style + ';';
155
- }
156
- if (txt.size) {
157
- styleStr = styleStr + 'font-size: ' + txt.size + ';';
158
- }
159
- if (txt.weight) {
160
- styleStr = styleStr + 'font-weight: ' + txt.weight + ';';
161
- }
162
- spEl.style = styleStr;
163
- this.renderer.appendChild(pBlEl, spEl);
164
- this.appendTextElement(spEl, txt.text);
165
- }
166
- else if ('linebreak' === txt.type) {
167
- let brEl = this.renderer.createElement('br');
168
- this.renderer.appendChild(pBlEl, brEl);
169
- }
170
- }
171
- }
172
- }
173
- }
174
- }
175
- this.renderer.appendChild(this.elRef.nativeElement, this.currPromptChild);
176
- //this.rendering=false
177
- }
178
- else if (this.mimetype.startsWith('image')) {
179
- this._text = null;
180
- this._src = mi.src;
181
- let promptImage = new Image();
182
- this.currPromptChild = promptImage;
183
- this.renderer.appendChild(this.elRef.nativeElement, this.currPromptChild);
184
- this.renderer.setStyle(this.currPromptChild, "max-width", "100%");
185
- this.renderer.setStyle(this.currPromptChild, "max-height", "100%");
186
- this.prompterStyleFill = true;
187
- // TODO vertical alignment
188
- // https://stackoverflow.com/questions/7273338/how-to-vertically-align-an-image-inside-a-div
189
- //console.log(promptImage.naturalWidth + "x"+promptImage.naturalHeight);
190
- promptImage.onload = (ev) => { };
191
- let srcUrl = this.srcUrl();
192
- if (srcUrl) {
193
- promptImage.src = srcUrl;
194
- }
195
- }
196
- }
197
- else {
198
- this._text = null;
199
- this._src = null;
200
- }
201
- }
202
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.12", ngImport: i0, type: Prompter, deps: [{ token: i0.ElementRef }, { token: i0.Renderer2 }, { token: i1.ProjectService }], target: i0.ɵɵFactoryTarget.Component }); }
203
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.12", type: Prompter, selector: "app-sprprompter", inputs: { projectName: "projectName", prompterHeight: "prompterHeight", promptMediaItems: "promptMediaItems" }, host: { properties: { "class.fill": "this.prompterStyleFill" } }, ngImport: i0, template: `
204
-
205
- <!--<ng-template [ngIf]="text">{{text}}</ng-template>-->
206
- <!-- <img *ngIf="src" #promptImage [src]="srcUrl()" [height]="prompterHeight-20" /> -->
207
- `, isInline: true, styles: [":host{justify-content:center;align-items:center;background:#fff;text-align:center;line-height:1.2em;font-weight:700;flex:0 1}\n", ":host(.fill){flex:3;width:100%;height:100%;max-height:100%;max-width:100%;vertical-align:middle}\n"] }); }
208
- }
209
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.12", ngImport: i0, type: Prompter, decorators: [{
210
- type: Component,
211
- args: [{ selector: 'app-sprprompter', template: `
212
-
213
- <!--<ng-template [ngIf]="text">{{text}}</ng-template>-->
214
- <!-- <img *ngIf="src" #promptImage [src]="srcUrl()" [height]="prompterHeight-20" /> -->
215
- `, styles: [":host{justify-content:center;align-items:center;background:#fff;text-align:center;line-height:1.2em;font-weight:700;flex:0 1}\n", ":host(.fill){flex:3;width:100%;height:100%;max-height:100%;max-width:100%;vertical-align:middle}\n"] }]
216
- }], ctorParameters: () => [{ type: i0.ElementRef }, { type: i0.Renderer2 }, { type: i1.ProjectService }], propDecorators: { projectName: [{
217
- type: Input
218
- }], prompterHeight: [{
219
- type: Input
220
- }], prompterStyleFill: [{
221
- type: HostBinding,
222
- args: ['class.fill']
223
- }], promptMediaItems: [{
224
- type: Input
225
- }] } });
226
- export const VIRTUAL_HEIGHT = 600;
227
- export const DEFAULT_PROMPT_FONTSIZE = 48;
228
- export const MIN_FONT_SIZE = 6;
229
- export const FALLBACK_DEF_USER_AGENT_FONT_SIZE = 14;
230
- export class PromptContainer {
231
- constructor(elRef) {
232
- this.elRef = elRef;
233
- this._mediaitems = null;
234
- this.prompterHeight = VIRTUAL_HEIGHT;
235
- this.fontSizeChange = false;
236
- this.contentChecked = false;
237
- this.prDisplay = 'hidden';
238
- this.autoFontSize = false;
239
- }
240
- ngOnInit() {
241
- // fallback
242
- this.defaultFontSizePx = FALLBACK_DEF_USER_AGENT_FONT_SIZE;
243
- // try to parse default user agent font size (no comment about DOM API design ;) )
244
- this.defaultStyle = window.getComputedStyle(this.elRef.nativeElement);
245
- let defFontSizeStr = this.defaultStyle.fontSize;
246
- if (defFontSizeStr) {
247
- defFontSizeStr = defFontSizeStr.trim();
248
- if (defFontSizeStr.endsWith('px')) {
249
- // parseFloat ignores non number characters at the end (again no comment ;) )
250
- this.defaultFontSizePx = parseFloat(defFontSizeStr);
251
- //console.info("Default font size: "+this.defaultFontSizePx)
252
- }
253
- }
254
- this.contentChecked = false;
255
- }
256
- ngAfterContentChecked() {
257
- if (this.autoFontSize) {
258
- if (this.fontSizeChange) {
259
- //console.log("ngaftercontentchecked, call fontSizeToFit ");
260
- // check prompter size again
261
- this.fontSizeToFit();
262
- }
263
- else {
264
- // font size was checked, but we need to check again after angular content check
265
- if (!this.contentChecked) {
266
- this.contentChecked = true;
267
- //console.log("ngaftercontentchecked, not font size changed, call ");
268
- this.fontSizeToFit();
269
- }
270
- }
271
- }
272
- }
273
- set mediaitems(mediaitems) {
274
- this._mediaitems = mediaitems;
275
- let mimetype = null;
276
- if (this._mediaitems && this._mediaitems.length == 1) {
277
- let mi = this._mediaitems[0];
278
- mimetype = 'text/plain';
279
- if (mi.mimetype) {
280
- mimetype = mi.mimetype.trim();
281
- }
282
- if (mi.defaultVirtualViewBox) {
283
- this.prompterHeight = mi.defaultVirtualViewBox.height;
284
- }
285
- }
286
- else {
287
- this.prompterHeight = VIRTUAL_HEIGHT;
288
- }
289
- this.prompter.promptMediaItems = this._mediaitems;
290
- this.autoFontSize = (mimetype != null && mimetype.startsWith('text/'));
291
- this.layout();
292
- }
293
- get mediaitems() {
294
- return this._mediaitems;
295
- }
296
- onResize(event) {
297
- //console.debug("onresize, call fontSizeToFit hook ");
298
- this.layout();
299
- }
300
- layout() {
301
- if (this.autoFontSize && this.elRef) {
302
- this.fontSizeChange = true;
303
- this.contentChecked = false;
304
- this.prDisplay = 'hidden';
305
- let elH = this.elRef.nativeElement.offsetHeight;
306
- // prompt text font size should scale according to prompt container height
307
- let scaledSize = Math.round((elH / this.prompterHeight) * DEFAULT_PROMPT_FONTSIZE);
308
- // min prompt font size is default user agent size
309
- let newSize = Math.max(scaledSize, this.defaultFontSizePx);
310
- if (this.fontSize !== newSize) {
311
- this.fontSize = newSize;
312
- }
313
- //console.log("layout, call fontSizeToFit hook ");
314
- window.setTimeout(() => this.fontSizeToFit());
315
- }
316
- else {
317
- this.contentChecked = true;
318
- this.prDisplay = 'visible';
319
- }
320
- }
321
- fontSizeToFit() {
322
- if (this.prompter) {
323
- let pW = this.prompter.width();
324
- let pH = this.prompter.height();
325
- if (this._mediaitems && this.elRef && pW && pH) {
326
- let nEl = this.elRef.nativeElement;
327
- //console.log("prompter: " + this.prompter.width() + "x" + this.prompter.height()+ " font size: "+this.fontSize)
328
- if (this.fontSize >= MIN_FONT_SIZE && (pW > nEl.offsetWidth || pH > nEl.offsetHeight)) {
329
- // prompter oversizes prompter container. Decrease font size.
330
- // set invisible during font size checks
331
- this.prDisplay = 'hidden';
332
- // decrease font size
333
- this.fontSize = this.fontSize - 1;
334
- // console.log("Decreased font size: "+this.fontSize )
335
- // Set flags
336
- this.fontSizeChange = true;
337
- this.contentChecked = false;
338
- // hook the next check
339
- window.setTimeout(() => this.fontSizeToFit());
340
- }
341
- else {
342
- // prompter fits in prompter container, font size should be fine
343
- //console.log("prDisplay: "+this.prDisplay)
344
- //if(this.contentChecked && ! this.fontSizeChange) {
345
- //console.log("Display!")
346
- // set prompter visible now
347
- this.prDisplay = 'visible';
348
- //}
349
- this.fontSizeChange = false;
350
- }
351
- //console.log("Prompt text width: "+textSize.width+" "+this.elRef.nativeElement.offsetWidth+"x"+this.elRef.nativeElement.offsetHeight)
352
- }
353
- }
354
- }
355
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.12", ngImport: i0, type: PromptContainer, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component }); }
356
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.12", type: PromptContainer, selector: "app-sprpromptcontainer", inputs: { projectName: "projectName", mediaitems: "mediaitems" }, host: { listeners: { "window:resize": "onResize($event)" } }, viewQueries: [{ propertyName: "prompter", first: true, predicate: Prompter, descendants: true, static: true }], ngImport: i0, template: `
357
- <app-sprprompter #prompter [projectName]="projectName" [promptMediaItems]="mediaitems" [style.font-size]="fontSize+'px'" [style.visibility]="prDisplay" [prompterHeight]="prompterHeight"></app-sprprompter>
358
- `, isInline: true, styles: [":host{flex:3;padding:10pt;height:100%;max-height:100%;justify-content:center;align-items:center;background:#fff;text-align:center;display:flex;flex-direction:column;min-height:0px;width:100%}\n"], dependencies: [{ kind: "component", type: Prompter, selector: "app-sprprompter", inputs: ["projectName", "prompterHeight", "promptMediaItems"] }] }); }
359
- }
360
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.12", ngImport: i0, type: PromptContainer, decorators: [{
361
- type: Component,
362
- args: [{ selector: 'app-sprpromptcontainer', template: `
363
- <app-sprprompter #prompter [projectName]="projectName" [promptMediaItems]="mediaitems" [style.font-size]="fontSize+'px'" [style.visibility]="prDisplay" [prompterHeight]="prompterHeight"></app-sprprompter>
364
- `, styles: [":host{flex:3;padding:10pt;height:100%;max-height:100%;justify-content:center;align-items:center;background:#fff;text-align:center;display:flex;flex-direction:column;min-height:0px;width:100%}\n"] }]
365
- }], ctorParameters: () => [{ type: i0.ElementRef }], propDecorators: { projectName: [{
366
- type: Input
367
- }], prompter: [{
368
- type: ViewChild,
369
- args: [Prompter, { static: true }]
370
- }], mediaitems: [{
371
- type: Input
372
- }], onResize: [{
373
- type: HostListener,
374
- args: ['window:resize', ['$event']]
375
- }] } });
376
- export class PromptingContainer {
377
- constructor(ref) {
378
- this.ref = ref;
379
- this.promptItem = null;
380
- this.showPrompt = false;
381
- this.startX = null;
382
- this.touchStartTimeStamp = null;
383
- }
384
- ngOnInit() {
385
- this.e = this.ref.nativeElement;
386
- }
387
- onTouchstart(ev) {
388
- //console.log("Touch start! ")
389
- if (!(this.transportActions.fwdAction.disabled &&
390
- this.transportActions.bwdAction.disabled &&
391
- this.transportActions.nextAction.disabled)) {
392
- let targetTouchesLen = ev.targetTouches.length;
393
- //for(let ti=0;ti<ev.targetTouches.length;ti++){
394
- //let t=ev.targetTouches.item(ti);
395
- // All x values are the same ??
396
- //console.log("Touch #"+ti+": pageX: "+t.pageX+" clientX: "+t.clientX+" screenX: "+t.screenX)
397
- //}
398
- if (targetTouchesLen == 1) {
399
- // single touch
400
- let t = ev.targetTouches.item(0);
401
- if (t) {
402
- this.startX = Math.round(t.screenX);
403
- this.touchStartTimeStamp = ev.timeStamp;
404
- this.e.style.transition = 'none';
405
- //console.log("Touch start x: "+this.startX)
406
- //ev.preventDefault();
407
- }
408
- }
409
- }
410
- }
411
- onTouchEnd(ev) {
412
- //console.log("Touch end!")
413
- // Reset offset shift
414
- if (!(this.transportActions.fwdAction.disabled && this.transportActions.bwdAction.disabled &&
415
- this.transportActions.nextAction.disabled)) {
416
- let changedTouchesLen = ev.changedTouches.length;
417
- //console.log(changedTouchesLen+" "+this.startX)
418
- if (changedTouchesLen == 1 && this.startX) {
419
- // single touch
420
- let t = ev.changedTouches.item(0);
421
- if (t) {
422
- let deltaX = Math.round(t.clientX - this.startX);
423
- let touchMoveSpeed = 0;
424
- if (this.touchStartTimeStamp) {
425
- touchMoveSpeed = deltaX / (ev.timeStamp - this.touchStartTimeStamp);
426
- }
427
- let futureDeltaX = deltaX + (800 * touchMoveSpeed);
428
- //console.log("DeltaX: " + deltaX + " Future deltaX: " + futureDeltaX + " width: " + this.e.offsetWidth)
429
- if (futureDeltaX > this.e.offsetWidth / 2) {
430
- //console.log("Swipe right detected!!")
431
- //this.swipedRight.emit()
432
- if (!this.transportActions.bwdAction.disabled) {
433
- this.transportActions.bwdAction.perform();
434
- }
435
- this.e.style.left = -this.e.offsetLeft + "px";
436
- }
437
- if (-futureDeltaX > this.e.offsetWidth / 2) {
438
- //console.log("Swipe left detected!!")
439
- this.e.style.left = -this.e.offsetLeft + "px";
440
- //this.swipedLeft.emit()
441
- if (!this.transportActions.nextAction.disabled) {
442
- this.transportActions.nextAction.perform();
443
- }
444
- else if (!this.transportActions.fwdAction.disabled) {
445
- this.transportActions.fwdAction.perform();
446
- }
447
- }
448
- else {
449
- }
450
- ev.preventDefault();
451
- }
452
- }
453
- // reset animated
454
- this.e.style.transition = "left 0.8s";
455
- }
456
- this.startX = null;
457
- this.touchStartTimeStamp = null;
458
- this.e.style.left = "0px";
459
- }
460
- onTouchMove(ev) {
461
- //console.log("Touch move!")
462
- if (!(this.transportActions.fwdAction.disabled && this.transportActions.bwdAction.disabled &&
463
- this.transportActions.nextAction.disabled)) {
464
- let targetTouchesLen = ev.targetTouches.length;
465
- if (targetTouchesLen == 1 && this.startX) {
466
- // single touch
467
- let t = ev.targetTouches.item(0);
468
- if (t) {
469
- let deltaX = Math.round(t.screenX - this.startX);
470
- this.e.style.left = deltaX + "px";
471
- // console.log("Touch move delta x: "+deltaX)
472
- }
473
- ev.preventDefault();
474
- }
475
- }
476
- }
477
- onTouchCancel(ev) {
478
- //console.log("Touch cancel!")
479
- this.e.style.left = "0px";
480
- //ev.preventDefault();
481
- }
482
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.12", ngImport: i0, type: PromptingContainer, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component }); }
483
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.12", type: PromptingContainer, selector: "app-sprpromptingcontainer", inputs: { projectName: "projectName", promptItem: "promptItem", showPrompt: "showPrompt", selectedItemIdx: "selectedItemIdx", itemCount: "itemCount", transportActions: "transportActions" }, host: { listeners: { "touchstart": "onTouchstart($event)", "touchend": "onTouchEnd($event)", "touchmove": "onTouchMove($event)", "touchcancel": "onTouchCancel($event)" } }, ngImport: i0, template: `
484
- <spr-recinstructions [selectedItemIdx]="selectedItemIdx" [itemCount]="itemCount"
485
- [recinstructions]="promptItem?.recinstructions?.recinstructions"></spr-recinstructions>
486
- <app-sprpromptcontainer [projectName]="projectName"
487
- [mediaitems]="showPrompt?(promptItem?promptItem.mediaitems:null):null"></app-sprpromptcontainer>
488
-
489
- `, isInline: true, styles: [":host{position:relative;flex:3;padding:10pt;justify-content:center;align-items:center;background:#fff;text-align:center;display:flex;flex-direction:column;min-height:0px}\n"], dependencies: [{ kind: "component", type: Recinstructions, selector: "spr-recinstructions", inputs: ["recinstructions", "selectedItemIdx", "itemCount"] }, { kind: "component", type: PromptContainer, selector: "app-sprpromptcontainer", inputs: ["projectName", "mediaitems"] }] }); }
490
- }
491
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.12", ngImport: i0, type: PromptingContainer, decorators: [{
492
- type: Component,
493
- args: [{ selector: 'app-sprpromptingcontainer', template: `
494
- <spr-recinstructions [selectedItemIdx]="selectedItemIdx" [itemCount]="itemCount"
495
- [recinstructions]="promptItem?.recinstructions?.recinstructions"></spr-recinstructions>
496
- <app-sprpromptcontainer [projectName]="projectName"
497
- [mediaitems]="showPrompt?(promptItem?promptItem.mediaitems:null):null"></app-sprpromptcontainer>
498
-
499
- `, styles: [":host{position:relative;flex:3;padding:10pt;justify-content:center;align-items:center;background:#fff;text-align:center;display:flex;flex-direction:column;min-height:0px}\n"] }]
500
- }], ctorParameters: () => [{ type: i0.ElementRef }], propDecorators: { projectName: [{
501
- type: Input
502
- }], promptItem: [{
503
- type: Input
504
- }], showPrompt: [{
505
- type: Input
506
- }], selectedItemIdx: [{
507
- type: Input
508
- }], itemCount: [{
509
- type: Input
510
- }], transportActions: [{
511
- type: Input
512
- }], onTouchstart: [{
513
- type: HostListener,
514
- args: ['touchstart', ['$event']]
515
- }], onTouchEnd: [{
516
- type: HostListener,
517
- args: ['touchend', ['$event']]
518
- }], onTouchMove: [{
519
- type: HostListener,
520
- args: ['touchmove', ['$event']]
521
- }], onTouchCancel: [{
522
- type: HostListener,
523
- args: ['touchcancel', ['$event']]
524
- }] } });
525
- export class Prompting extends ResponsiveComponent {
526
- constructor(bpo) {
527
- super(bpo);
528
- this.bpo = bpo;
529
- this.promptItem = null;
530
- this.showPrompt = false;
531
- this.items = undefined;
532
- this.enableDownload = false;
533
- this.audioSignalCollapsed = true;
534
- this.displayAudioClip = null;
535
- this.onItemSelect = new EventEmitter();
536
- this.onNextItem = new EventEmitter();
537
- this.onPrevItem = new EventEmitter();
538
- }
539
- itemSelect(rowIdx) {
540
- this.onItemSelect.emit(rowIdx);
541
- }
542
- nextItem() {
543
- this.onNextItem.emit();
544
- }
545
- prevItem() {
546
- this.onPrevItem.emit();
547
- }
548
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.12", ngImport: i0, type: Prompting, deps: [{ token: i2.BreakpointObserver }], target: i0.ɵɵFactoryTarget.Component }); }
549
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.12", type: Prompting, selector: "app-sprprompting", inputs: { projectName: "projectName", startStopSignalState: "startStopSignalState", promptItem: "promptItem", showPrompt: "showPrompt", items: "items", selectedItemIdx: "selectedItemIdx", transportActions: "transportActions", enableDownload: "enableDownload", audioSignalCollapsed: "audioSignalCollapsed", displayAudioClip: "displayAudioClip", playStartAction: "playStartAction", playSelectionAction: "playSelectionAction", autoPlayOnSelectToggleAction: "autoPlayOnSelectToggleAction", playStopAction: "playStopAction" }, outputs: { onItemSelect: "onItemSelect", onNextItem: "onNextItem", onPrevItem: "onPrevItem" }, viewQueries: [{ propertyName: "simpleTrafficLight", first: true, predicate: SimpleTrafficLight, descendants: true, static: true }, { propertyName: "audioDisplay", first: true, predicate: AudioDisplay, descendants: true, static: true }], usesInheritance: true, ngImport: i0, template: `
550
-
551
- <app-simpletrafficlight [status]="startStopSignalState"></app-simpletrafficlight>
552
- <app-sprpromptingcontainer [projectName]="projectName" [promptItem]="promptItem" [showPrompt]="showPrompt"
553
- [itemCount]="items?.length" [selectedItemIdx]="selectedItemIdx"
554
- [transportActions]="transportActions"></app-sprpromptingcontainer>
555
- <app-sprprogress *ngIf="!screenXs" [items]="items" [selectedItemIdx]="selectedItemIdx"
556
- (onRowSelect)="itemSelect($event)"></app-sprprogress>
557
- <div #asCt [class.active]="!audioSignalCollapsed && !screenXs">
558
-
559
- <app-audiodisplay #audioSignalContainer [class.active]="!audioSignalCollapsed"
560
- [audioClip]="displayAudioClip"
561
- [playStartAction]="playStartAction"
562
- [playSelectionAction]="playSelectionAction"
563
- [autoPlayOnSelectToggleAction]="autoPlayOnSelectToggleAction"
564
- [playStopAction]="playStopAction"></app-audiodisplay>
565
-
566
-
567
- </div>
568
-
569
-
570
-
571
- `, isInline: true, styles: [":host{position:relative;margin:0;padding:0;background:#d3d3d3;width:100%;flex:1;min-height:0px;display:flex;flex-direction:row;flex-wrap:nowrap}\n", "app-simpletrafficlight{margin:10px;min-height:0px;z-index:3}\n", "app-sprprogress{z-index:3}\n", "div{display:none;position:absolute;z-index:5}\n", "div.active{display:flex;position:absolute;bottom:0;height:90%;width:100%;overflow:hidden;padding:0;z-index:5;box-sizing:border-box;background-color:#0000}\n"], dependencies: [{ kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i4.AudioDisplay, selector: "app-audiodisplay", inputs: ["playStartAction", "playStopAction", "playSelectionAction", "autoPlayOnSelectToggleAction", "audioData", "audioClip"] }, { kind: "component", type: i5.Progress, selector: "app-sprprogress", inputs: ["items", "selectedItemIdx", "enableDownload"], outputs: ["onRowSelect", "rowSelect", "onShowDoneAction", "clickDone", "onDownloadDoneAction", "clickDownloadDone"] }, { kind: "component", type: i6.SimpleTrafficLight, selector: "app-simpletrafficlight", inputs: ["status"] }, { kind: "component", type: PromptingContainer, selector: "app-sprpromptingcontainer", inputs: ["projectName", "promptItem", "showPrompt", "selectedItemIdx", "itemCount", "transportActions"] }] }); }
572
- }
573
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.12", ngImport: i0, type: Prompting, decorators: [{
574
- type: Component,
575
- args: [{ selector: 'app-sprprompting', template: `
576
-
577
- <app-simpletrafficlight [status]="startStopSignalState"></app-simpletrafficlight>
578
- <app-sprpromptingcontainer [projectName]="projectName" [promptItem]="promptItem" [showPrompt]="showPrompt"
579
- [itemCount]="items?.length" [selectedItemIdx]="selectedItemIdx"
580
- [transportActions]="transportActions"></app-sprpromptingcontainer>
581
- <app-sprprogress *ngIf="!screenXs" [items]="items" [selectedItemIdx]="selectedItemIdx"
582
- (onRowSelect)="itemSelect($event)"></app-sprprogress>
583
- <div #asCt [class.active]="!audioSignalCollapsed && !screenXs">
584
-
585
- <app-audiodisplay #audioSignalContainer [class.active]="!audioSignalCollapsed"
586
- [audioClip]="displayAudioClip"
587
- [playStartAction]="playStartAction"
588
- [playSelectionAction]="playSelectionAction"
589
- [autoPlayOnSelectToggleAction]="autoPlayOnSelectToggleAction"
590
- [playStopAction]="playStopAction"></app-audiodisplay>
591
-
592
-
593
- </div>
594
-
595
-
596
-
597
- `, styles: [":host{position:relative;margin:0;padding:0;background:#d3d3d3;width:100%;flex:1;min-height:0px;display:flex;flex-direction:row;flex-wrap:nowrap}\n", "app-simpletrafficlight{margin:10px;min-height:0px;z-index:3}\n", "app-sprprogress{z-index:3}\n", "div{display:none;position:absolute;z-index:5}\n", "div.active{display:flex;position:absolute;bottom:0;height:90%;width:100%;overflow:hidden;padding:0;z-index:5;box-sizing:border-box;background-color:#0000}\n"] }]
598
- }], ctorParameters: () => [{ type: i2.BreakpointObserver }], propDecorators: { simpleTrafficLight: [{
599
- type: ViewChild,
600
- args: [SimpleTrafficLight, { static: true }]
601
- }], audioDisplay: [{
602
- type: ViewChild,
603
- args: [AudioDisplay, { static: true }]
604
- }], projectName: [{
605
- type: Input
606
- }], startStopSignalState: [{
607
- type: Input
608
- }], promptItem: [{
609
- type: Input
610
- }], showPrompt: [{
611
- type: Input
612
- }], items: [{
613
- type: Input
614
- }], selectedItemIdx: [{
615
- type: Input
616
- }], transportActions: [{
617
- type: Input
618
- }], enableDownload: [{
619
- type: Input
620
- }], audioSignalCollapsed: [{
621
- type: Input
622
- }], displayAudioClip: [{
623
- type: Input
624
- }], playStartAction: [{
625
- type: Input
626
- }], playSelectionAction: [{
627
- type: Input
628
- }], autoPlayOnSelectToggleAction: [{
629
- type: Input
630
- }], playStopAction: [{
631
- type: Input
632
- }], onItemSelect: [{
633
- type: Output
634
- }], onNextItem: [{
635
- type: Output
636
- }], onPrevItem: [{
637
- type: Output
638
- }] } });
639
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJvbXB0aW5nLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvc3BlZWNocmVjb3JkZXJuZy9zcmMvbGliL3NwZWVjaHJlY29yZGVyL3Nlc3Npb24vcHJvbXB0aW5nLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFDTCxTQUFTLEVBQ1QsU0FBUyxFQUNULEtBQUssRUFDTCxNQUFNLEVBQ04sWUFBWSxFQUNaLFlBQVksRUFJWixXQUFXLEVBRVosTUFBTSxlQUFlLENBQUM7QUFFdkIsT0FBTyxFQUFDLGtCQUFrQixFQUFDLE1BQU0sMENBQTBDLENBQUM7QUFNNUUsT0FBTyxFQUFDLFlBQVksRUFBQyxNQUFNLDJCQUEyQixDQUFDO0FBR3ZELE9BQU8sRUFBQyxtQkFBbUIsRUFBQyxNQUFNLCtCQUErQixDQUFDOzs7Ozs7OztBQXdCbEUsTUFBTSxPQUFPLGVBQWU7SUFLMUIsV0FBVztRQUNULElBQUksS0FBSyxHQUFRLEVBQUUsQ0FBQztRQUNwQixJQUFHLElBQUksQ0FBQyxTQUFTLElBQUksSUFBSSxDQUFDLGVBQWUsRUFBQyxDQUFDO1lBQ3pDLEtBQUssR0FBQyxLQUFLLEdBQUMsSUFBSSxDQUFDLGVBQWUsR0FBQyxHQUFHLEdBQUMsQ0FBQyxJQUFJLENBQUMsU0FBUyxHQUFDLENBQUMsQ0FBQyxDQUFDO1FBQzFELENBQUM7UUFDRCxJQUFHLElBQUksQ0FBQyxlQUFlLEVBQUMsQ0FBQztZQUN2QixLQUFLLEdBQUMsS0FBSyxHQUFDLElBQUksR0FBQyxJQUFJLENBQUMsZUFBZSxDQUFDO1FBQ3hDLENBQUM7UUFDRCxPQUFPLEtBQUssQ0FBQztJQUNmLENBQUM7K0dBZFUsZUFBZTttR0FBZixlQUFlLHVLQWhCaEI7OztHQUdUOzs0RkFhVSxlQUFlO2tCQXBCM0IsU0FBUzsrQkFFRSxxQkFBcUIsWUFFckI7OztHQUdUOzhCQWNRLGVBQWU7c0JBQXZCLEtBQUs7Z0JBQ0csZUFBZTtzQkFB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QW1CO3NCQUEzQixLQUFLO2dCQUNHLDRCQUE0QjtzQkFBcEMsS0FBSztnQkFDRyxjQUFjO3NCQUF0QixLQUFLO2dCQUNJLFlBQVk7c0JBQXJCLE1BQU07Z0JBQ0csVUFBVTtzQkFBbkIsTUFBTTtnQkFDRyxVQUFVO3NCQUFuQixNQUFNIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcclxuICBDb21wb25lbnQsXHJcbiAgVmlld0NoaWxkLFxyXG4gIElucHV0LFxyXG4gIE91dHB1dCxcclxuICBFdmVudEVtaXR0ZXIsXHJcbiAgSG9zdExpc3RlbmVyLFxyXG4gIEVsZW1lbnRSZWYsXHJcbiAgT25Jbml0LFxyXG4gIFJlbmRlcmVyMixcclxuICBIb3N0QmluZGluZyxcclxuICBBZnRlckNvbnRlbnRDaGVja2VkXHJcbn0gZnJvbSBcIkBhbmd1bGFyL2NvcmVcIjtcclxuXHJcbmltcG9ydCB7U2ltcGxlVHJhZmZpY0xpZ2h0fSBmcm9tIFwiLi4vc3RhcnRzdG9wc2lnbmFsL3VpL3NpbXBsZXRyYWZmaWNsaWdodFwiO1xyXG5pbXBvcnQge1N0YXRlIGFzIFN0YXJ0U3RvcFNpZ25hbFN0YXRlfSBmcm9tIFwiLi4vc3RhcnRzdG9wc2lnbmFsL3N0YXJ0c3RvcHNpZ25hbFwiO1xyXG5pbXBvcnQge0l0ZW19IGZyb20gXCIuL2l0ZW1cIjtcclxuaW1wb3J0IHtCbG9jaywgVGV4dCwgTWVkaWFpdGVtLCBQcm9tcHRJdGVtfSBmcm9tIFwiLi4vc2NyaXB0L3NjcmlwdFwiO1xyXG5pbXBvcnQge1RyYW5zcG9ydEFjdGlvbnN9IGZyb20gXCIuL2NvbnRyb2xwYW5lbFwiO1xyXG5pbXBvcnQge0FjdGlvbn0gZnJvbSBcIi4uLy4uL2FjdGlvbi9hY3Rpb25cIjtcclxuaW1wb3J0IHtBdWRpb0Rpc3BsYXl9IGZyb20gXCIuLi8uLi9hdWRpby9hdWRpb19kaXNwbGF5XCI7XHJcbmltcG9ydCB7UHJvamVjdFNlcnZpY2V9IGZyb20gXCIuLi9wcm9qZWN0L3Byb2plY3Quc2VydmljZVwiO1xyXG5pbXBvcnQge0F1ZGlvQ2xpcH0gZnJvbSBcIi4uLy4uL2F1ZGlvL3BlcnNpc3RvclwiO1xyXG5pbXBvcnQge1Jlc3BvbnNpdmVDb21wb25lbnR9IGZyb20gXCIuLi8uLi91aS9yZXNwb25zaXZlX2NvbXBvbmVudFwiO1xyXG5pbXBvcnQge0JyZWFrcG9pbnRPYnNlcnZlcn0gZnJvbSBcIkBhbmd1bGFyL2Nkay9sYXlvdXRcIjtcclxuXHJcblxyXG5AQ29tcG9uZW50KHtcclxuXHJcbiAgc2VsZWN0b3I6ICdzcHItcmVjaW5zdHJ1Y3Rpb25zJyxcclxuXHJcbiAgdGVtcGxhdGU6IGBcclxuXHJcbiAgICB7e2Rpc3BsYXlUZXh0KCl9fVxyXG4gIGAsXHJcbiAgc3R5bGVzOiBbYDpob3N0IHtcclxuXHJcbiAgICBqdXN0aWZ5LWNvbnRlbnQ6IGxlZnQ7IC8qIGFsaWduIGhvcml6b250YWwgY2VudGVyICovXHJcbiAgICBhbGlnbi1pdGVtczogZmxleC1zdGFydDsgLyogYWxpZ24gdmVydGljYWwgIGNlbnRlciAqL1xyXG4gICAgYmFja2dyb3VuZDogd2hpdGU7XHJcbiAgICB0ZXh0LWFsaWduOiBsZWZ0O1xyXG4gICAgZm9udC1zaXplOiAxZW07XHJcbiAgICBmbGV4OiAwO1xyXG4gICAgd2lkdGg6IDEwMCU7XHJcbiAgfVxyXG4gIGBdXHJcbn0pXHJcbmV4cG9ydCBjbGFzcyBSZWNpbnN0cnVjdGlvbnMge1xyXG4gIEBJbnB1dCgpIHJlY2luc3RydWN0aW9uczogc3RyaW5nfG51bGx8IHVuZGVmaW5lZDtcclxuICBASW5wdXQoKSBzZWxlY3RlZEl0ZW1JZHg6IG51bWJlcnxudWxsfHVuZGVmaW5lZDtcclxuICBASW5wdXQoKSBpdGVtQ291bnQ6IG51bWJlcnx1bmRlZmluZWQ7XHJcblxyXG4gIGRpc3BsYXlUZXh0KCk6c3RyaW5ne1xyXG4gICAgbGV0IHJpVHh0OnN0cmluZz0nJztcclxuICAgIGlmKHRoaXMuaXRlbUNvdW50ICYmIHRoaXMuc2VsZWN0ZWRJdGVtSWR4KXtcclxuICAgICAgcmlUeHQ9cmlUeHQrdGhpcy5zZWxlY3RlZEl0ZW1JZHgrJy8nKyh0aGlzLml0ZW1Db3VudC0xKTtcclxuICAgIH1cclxuICAgIGlmKHRoaXMucmVjaW5zdHJ1Y3Rpb25zKXtcclxuICAgICAgcmlUeHQ9cmlUeHQrJzogJyt0aGlzLnJlY2luc3RydWN0aW9ucztcclxuICAgIH1cclxuICAgIHJldHVybiByaVR4dDtcclxuICB9XHJcbn1cclxuXHJcbkBDb21wb25lbnQoe1xyXG5cclxuICBzZWxlY3RvcjogJ2FwcC1zcHJwcm9tcHRlcicsXHJcblxyXG4gIHRlbXBsYXRlOiBgXHJcblxyXG4gICAgPCEtLTxuZy10ZW1wbGF0ZSBbbmdJZl09XCJ0ZXh0XCI+e3t0ZXh0fX08L25nLXRlbXBsYXRlPi0tPlxyXG4gICAgPCEtLSA8aW1nICpuZ0lmPVwic3JjXCIgI3Byb21wdEltYWdlIFtzcmNdPVwic3JjVXJsKClcIiBbaGVpZ2h0XT1cInByb21wdGVySGVpZ2h0LTIwXCIgLz4gLS0+XHJcbiAgYCxcclxuICBzdHlsZXM6IFtgOmhvc3Qge1xyXG5cclxuICAgIGp1c3RpZnktY29udGVudDogY2VudGVyOyAvKiBhbGlnbiBob3Jpem9udGFsIGNlbnRlciAqL1xyXG4gICAgYWxpZ24taXRlbXM6IGNlbnRlcjsgLyogYWxpZ24gdmVydGljYWwgIGNlbnRlciAqL1xyXG4gICAgYmFja2dyb3VuZDogd2hpdGU7XHJcbiAgICB0ZXh0LWFsaWduOiBjZW50ZXI7XHJcbiAgICAvKiBmb250LXNpemU6IDJlbTsgKi9cclxuICAgIGxpbmUtaGVpZ2h0OiAxLjJlbTtcclxuICAgIGZvbnQtd2VpZ2h0OiBib2xkO1xyXG4gICAgLyogVXNlIG9ubHkgbmF0dXJhbCBzaXplIG9mIHRoZSBwcm9tcHQgKi9cclxuICAgIC8qIFRoZSBwcm9tcHRlciBjb21wbmVudCB0aGVuIGV0cyBhbGlnbmVkIHZlcnRpY2FsbHkgY2VudGVyZWQgKi9cclxuICAgIGZsZXg6IDAgMTtcclxuXHJcbiAgfWAsIGA6aG9zdCguZmlsbCkge1xyXG4gICAgLyogVXNlIGFsbCBzcGFjZSB0byBzY2FsZSBpbWFnZXMgKi9cclxuICAgIGZsZXg6IDM7XHJcbiAgICB3aWR0aDogMTAwJTtcclxuICAgIGhlaWdodDogMTAwJTtcclxuICAgIG1heC1oZWlnaHQ6IDEwMCU7XHJcbiAgICBtYXgtd2lkdGg6IDEwMCU7XHJcbiAgICAvKiBBIHNlcGFyYXRlIGZsZXggY29udGFpbmVyIG1pZ2h0IGJlIG5lY2Vzc2F5ciB0byBhbGlnaG4gY2VudGVyZWQgKi9cclxuICAgIHZlcnRpY2FsLWFsaWduOiBtaWRkbGU7IC8qIFRPRE8gZG9lcyBub3Qgd29yaywgaW1hZ2UgaXMgbm90IHZlcnRpY2FsbHkgY2VudGVyZWQgKi9cclxuICB9YF1cclxufSlcclxuZXhwb3J0IGNsYXNzIFByb21wdGVyIHtcclxuICBASW5wdXQoKSBwcm9qZWN0TmFtZTogc3RyaW5nIHwgdW5kZWZpbmVkO1xyXG4gIHByaXZhdGUgX3Byb21wdE1lZGlhSXRlbXM6IEFycmF5PE1lZGlhaXRlbT58bnVsbHx1bmRlZmluZWQ9bnVsbFxyXG5cclxuICBASW5wdXQoKSBwcm9tcHRlckhlaWdodDogbnVtYmVyPTA7XHJcbiAgcHJpdmF0ZSBfdGV4dDogc3RyaW5nfHVuZGVmaW5lZHxudWxsID0gbnVsbDtcclxuICBwcml2YXRlIF9zcmM6IHN0cmluZ3x1bmRlZmluZWR8bnVsbCA9IG51bGw7XHJcbiAgcHJpdmF0ZSBfYmxvY2tzOiBBcnJheTxCbG9jaz58dW5kZWZpbmVkO1xyXG4gIG1pbWV0eXBlITogc3RyaW5nO1xyXG4gIHByaXZhdGUgY3VyclByb21wdENoaWxkOiBIVE1MRWxlbWVudHxudWxsID0gbnVsbDtcclxuXHJcbiAgQEhvc3RCaW5kaW5nKCdjbGFzcy5maWxsJykgcHVibGljIHByb21wdGVyU3R5bGVGaWxsID0gZmFsc2U7XHJcblxyXG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgZWxSZWY6IEVsZW1lbnRSZWYsIHByaXZhdGUgcmVuZGVyZXI6IFJlbmRlcmVyMiwgcHJpdmF0ZSBwcm9qZWN0U2VydmljZTogUHJvamVjdFNlcnZpY2UpIHtcclxuXHJcbiAgfVxyXG5cclxuICBnZXQgdGV4dCgpIHtcclxuICAgIHJldHVybiB0aGlzLl90ZXh0O1xyXG4gIH1cclxuXHJcbiAgZ2V0IHNyYygpIHtcclxuICAgIHJldHVybiB0aGlzLl9zcmM7XHJcbiAgfVxyXG5cclxuICBzcmNVcmwoKTogc3RyaW5nfG51bGx7XHJcbiAgICBpZiAodGhpcy5wcm9qZWN0TmFtZSAmJiB0aGlzLl9zcmMpIHtcclxuICAgICAgcmV0dXJuIHRoaXMucHJvamVjdFNlcnZpY2UucHJvamVjdFJlc291cmNlVXJsKHRoaXMucHJvamVjdE5hbWUsIHRoaXMuX3NyYyk7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gbnVsbDtcclxuICB9XHJcblxyXG4gICAgd2lkdGgoKTpudW1iZXJ8bnVsbHtcclxuICAgICAgaWYodGhpcy5lbFJlZil7XHJcbiAgICAgICAgaWYodGhpcy5lbFJlZi5uYXRpdmVFbGVtZW50KXtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuZWxSZWYubmF0aXZlRWxlbWVudC5jbGllbnRXaWR0aFxyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG4gICAgICByZXR1cm4gbnVsbDtcclxuICAgIH1cclxuICAgIGhlaWdodCgpOm51bWJlcnxudWxse1xyXG4gICAgICAgIGlmKHRoaXMuZWxSZWYpe1xyXG4gICAgICAgICAgICBpZih0aGlzLmVsUmVmLm5hdGl2ZUVsZW1lbnQpe1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZWxSZWYubmF0aXZlRWxlbWVudC5jbGllbnRIZWlnaHRcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gbnVsbDtcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIGFwcGVuZFRleHRFbGVtZW50KHBhcmVudEVsOkhUTUxFbGVtZW50LHR4dDpUZXh0KXtcclxuICAgICAgbGV0IHQ6IHN0cmluZyA9IDxzdHJpbmc+dHh0LnRleHRcclxuICAgICAgbGV0IHR4dE5kID0gdGhpcy5yZW5kZXJlci5jcmVhdGVUZXh0KHQpXHJcbiAgICAgIGlmKHR4dC5kZWNvcmF0aW9uIHx8IHR4dC5jb2xvcil7XHJcbiAgICAgICAgbGV0IHNwRWwgPSB0aGlzLnJlbmRlcmVyLmNyZWF0ZUVsZW1lbnQoJ3NwYW4nKVxyXG4gICAgICAgIGxldCBzdHlsZVN0cj0nJ1xyXG4gICAgICAgIGlmKHR4dC5kZWNvcmF0aW9uKSB7XHJcbiAgICAgICAgICBzdHlsZVN0ciA9IHN0eWxlU3RyICsndGV4dC1kZWNvcmF0aW9uOiAnICsgdHh0LmRlY29yYXRpb24rJzsnXHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmKHR4dC5jb2xvcil7XHJcbiAgICAgICAgICBzdHlsZVN0ciA9IHN0eWxlU3RyICsnY29sb3I6ICcgKyB0eHQuY29sb3IrJzsnXHJcbiAgICAgICAgfVxyXG4gICAgICAgIHNwRWwuc3R5bGU9c3R5bGVTdHJcclxuICAgICAgICB0aGlzLnJlbmRlcmVyLmFwcGVuZENoaWxkKHBhcmVudEVsLCBzcEVsKVxyXG4gICAgICAgIHRoaXMucmVuZGVyZXIuYXBwZW5kQ2hpbGQoc3BFbCwgdHh0TmQpXHJcbiAgICAgIH1lbHNlIHtcclxuICAgICAgICB0aGlzLnJlbmRlcmVyLmFwcGVuZENoaWxkKHBhcmVudEVsLCB0eHROZClcclxuICAgICAgfVxyXG4gICAgfVxyXG5cclxuICBASW5wdXQoKSBzZXQgcHJvbXB0TWVkaWFJdGVtcyhwTWlzOiBBcnJheTxNZWRpYWl0ZW0+fG51bGwpIHtcclxuICAgIHRoaXMuX3Byb21wdE1lZGlhSXRlbXMgPSBwTWlzXHJcbiAgICBpZiAodGhpcy5jdXJyUHJvbXB0Q2hpbGQgIT0gbnVsbCkge1xyXG4gICAgICB0aGlzLnJlbmRlcmVyLnJlbW92ZUNoaWxkKHRoaXMuZWxSZWYubmF0aXZlRWxlbWVudCwgdGhpcy5jdXJyUHJvbXB0Q2hpbGQpXHJcbiAgICB9XHJcbiAgICBpZiAodGhpcy5fcHJvbXB0TWVkaWFJdGVtcyAmJiB0aGlzLl9wcm9tcHRNZWRpYUl0ZW1zLmxlbmd0aCA9PSAxKSB7XHJcbiAgICAgIGxldCBtaSA9IHRoaXMuX3Byb21wdE1lZGlhSXRlbXNbMF1cclxuICAgICAgdGhpcy5taW1ldHlwZSA9ICd0ZXh0L3BsYWluJ1xyXG4gICAgICBpZiAobWkubWltZXR5cGUpIHtcclxuICAgICAgICB0aGlzLm1pbWV0eXBlID0gbWkubWltZXR5cGUudHJpbSgpO1xyXG4gICAgICB9XHJcbiAgICAgIGlmICh0aGlzLm1pbWV0eXBlID09PSAndGV4dC9wbGFpbicpIHtcclxuICAgICAgICB0aGlzLl90ZXh0ID0gbWkudGV4dFxyXG4gICAgICAgIHRoaXMuX3NyYyA9IG51bGw7XHJcbiAgICAgICAgbGV0IHByVHh0PScnO1xyXG4gICAgICAgIGlmKHRoaXMuX3RleHQpe1xyXG4gICAgICAgICAgcHJUeHQ9dGhpcy5fdGV4dDtcclxuICAgICAgICB9XHJcbiAgICAgICAgdGhpcy5jdXJyUHJvbXB0Q2hpbGQgPSB0aGlzLnJlbmRlcmVyLmNyZWF0ZVRleHQocHJUeHQpO1xyXG4gICAgICAgIHRoaXMucHJvbXB0ZXJTdHlsZUZpbGwgPSBmYWxzZTtcclxuICAgICAgICB0aGlzLnJlbmRlcmVyLmFwcGVuZENoaWxkKHRoaXMuZWxSZWYubmF0aXZlRWxlbWVudCwgdGhpcy5jdXJyUHJvbXB0Q2hpbGQpO1xyXG4gICAgICB9IGVsc2UgaWYgKHRoaXMubWltZXR5cGUgPT09ICd0ZXh0L3gtcHJvbXB0Jykge1xyXG4gICAgICAgIC8vdGhpcy5yZW5kZXJpbmc9dHJ1ZVxyXG4gICAgICAgIHRoaXMuX3RleHQ9bnVsbDtcclxuICAgICAgICB0aGlzLl9zcmM9bnVsbDtcclxuICAgICAgICB0aGlzLl9ibG9ja3M9bmV3IEFycmF5PEJsb2NrPigpO1xyXG4gICAgICAgIGxldCBwZD1taS5wcm9tcHREb2NcclxuICAgICAgICBpZihwZCl7XHJcbiAgICAgICAgICBsZXQgcGRCb2R5PXBkLmJvZHlcclxuICAgICAgICAgIGlmKHBkQm9keSl7XHJcbiAgICAgICAgICAgIHRoaXMuX2Jsb2Nrcz1wZEJvZHkuYmxvY2tzO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgdGhpcy5wcm9tcHRlclN0eWxlRmlsbCA9IGZhbHNlXHJcbiAgICAgICAgdGhpcy5jdXJyUHJvbXB0Q2hpbGQgPSB0aGlzLnJlbmRlcmVyLmNyZWF0ZUVsZW1lbnQoJ2RpdicpXHJcbiAgICAgICAgaWYodGhpcy5fYmxvY2tzKSB7XHJcbiAgICAgICAgICBmb3IgKGxldCBiaSA9IDA7IGJpIDwgdGhpcy5fYmxvY2tzLmxlbmd0aDsgYmkrKykge1xyXG4gICAgICAgICAgICBsZXQgYmwgPSB0aGlzLl9ibG9ja3NbYmldXHJcbiAgICAgICAgICAgIGlmICgncCcgPT09IGJsLnR5cGUpIHtcclxuICAgICAgICAgICAgICBsZXQgcEJsRWwgPSB0aGlzLnJlbmRlcmVyLmNyZWF0ZUVsZW1lbnQoJ3AnKVxyXG4gICAgICAgICAgICAgIHRoaXMucmVuZGVyZXIuYXBwZW5kQ2hpbGQodGhpcy5jdXJyUHJvbXB0Q2hpbGQsIHBCbEVsKVxyXG4gICAgICAgICAgICAgIGZvciAobGV0IHRpID0gMDsgdGkgPCBibC50ZXh0cy5sZW5ndGg7IHRpKyspIHtcclxuICAgICAgICAgICAgICAgIGxldCB0eHQgPSBibC50ZXh0c1t0aV1cclxuICAgICAgICAgICAgICAgIGlmICh0eHQpIHtcclxuICAgICAgICAgICAgICAgICAgaWYgKCd0ZXh0JyA9PT0gdHh0LnR5cGUpIHtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLmFwcGVuZFRleHRFbGVtZW50KHBCbEVsLCB0eHQpXHJcbiAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoJ2ZvbnQnID09PSB0eHQudHlwZSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGxldCBzcEVsID0gdGhpcy5yZW5kZXJlci5jcmVhdGVFbGVtZW50KCdzcGFuJylcclxuICAgICAgICAgICAgICAgICAgICBsZXQgc3R5bGVTdHIgPSAnJ1xyXG4gICAgICAgICAgICAgICAgICAgIGlmICh0eHQuc3R5bGUpIHtcclxuICAgICAgICAgICAgICAgICAgICAgIHN0eWxlU3RyID0gc3R5bGVTdHIgKyAnZm9udC1zdHlsZTogJyArIHR4dC5zdHlsZSArICc7J1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBpZiAodHh0LnNpemUpIHtcclxuICAgICAgICAgICAgICAgICAgICAgIHN0eWxlU3RyID0gc3R5bGVTdHIgKyAnZm9udC1zaXplOiAnICsgdHh0LnNpemUgKyAnOydcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHR4dC53ZWlnaHQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgIHN0eWxlU3RyID0gc3R5bGVTdHIgKyAnZm9udC13ZWlnaHQ6ICcgKyB0eHQud2VpZ2h0ICsgJzsnXHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIHNwRWwuc3R5bGUgPSBzdHlsZVN0clxyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMucmVuZGVyZXIuYXBwZW5kQ2hpbGQocEJsRWwsIHNwRWwpXHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5hcHBlbmRUZXh0RWxlbWVudChzcEVsLCA8VGV4dD50eHQudGV4dClcclxuICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmICgnbGluZWJyZWFrJyA9PT0gdHh0LnR5cGUpIHtcclxuICAgICAgICAgICAgICAgICAgICBsZXQgYnJFbCA9IHRoaXMucmVuZGVyZXIuY3JlYXRlRWxlbWVudCgnYnInKVxyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMucmVuZGVyZXIuYXBwZW5kQ2hpbGQocEJsRWwsIGJyRWwpXHJcbiAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgdGhpcy5yZW5kZXJlci5hcHBlbmRDaGlsZCh0aGlzLmVsUmVmLm5hdGl2ZUVsZW1lbnQsIHRoaXMuY3VyclByb21wdENoaWxkKVxyXG4gICAgICAgIC8vdGhpcy5yZW5kZXJpbmc9ZmFsc2VcclxuICAgICAgfSBlbHNlIGlmICh0aGlzLm1pbWV0eXBlLnN0YXJ0c1dpdGgoJ2ltYWdlJykpIHtcclxuICAgICAgICB0aGlzLl90ZXh0ID0gbnVsbDtcclxuICAgICAgICB0aGlzLl9zcmMgPSBtaS5zcmNcclxuICAgICAgICBsZXQgcHJvbXB0SW1hZ2UgPSBuZXcgSW1hZ2UoKVxyXG5cclxuICAgICAgICB0aGlzLmN1cnJQcm9tcHRDaGlsZCA9IHByb21wdEltYWdlXHJcbiAgICAgICAgdGhpcy5yZW5kZXJlci5hcHBlbmRDaGlsZCh0aGlzLmVsUmVmLm5hdGl2ZUVsZW1lbnQsIHRoaXMuY3VyclByb21wdENoaWxkKVxyXG4gICAgICAgIHRoaXMucmVuZGVyZXIuc2V0U3R5bGUodGhpcy5jdXJyUHJvbXB0Q2hpbGQsIFwibWF4LXdpZHRoXCIsIFwiMTAwJVwiKVxyXG4gICAgICAgIHRoaXMucmVuZGVyZXIuc2V0U3R5bGUodGhpcy5jdXJyUHJvbXB0Q2hpbGQsIFwibWF4LWhlaWdodFwiLCBcIjEwMCVcIilcclxuICAgICAgICB0aGlzLnByb21wdGVyU3R5bGVGaWxsID0gdHJ1ZVxyXG4gICAgICAgIC8vIFRPRE8gdmVydGljYWwgYWxpZ25tZW50XHJcbiAgICAgICAgLy8gaHR0cHM6Ly9zdGFja292ZXJmbG93LmNvbS9xdWVzdGlvbnMvNzI3MzMzOC9ob3ctdG8tdmVydGljYWxseS1hbGlnbi1hbi1pbWFnZS1pbnNpZGUtYS1kaXZcclxuXHJcbiAgICAgICAgLy9jb25zb2xlLmxvZyhwcm9tcHRJbWFnZS5uYXR1cmFsV2lkdGggKyBcInhcIitwcm9tcHRJbWFnZS5uYXR1cmFsSGVpZ2h0KTtcclxuICAgICAgICBwcm9tcHRJbWFnZS5vbmxvYWQgPSAoZXY6IEV2ZW50KSA9PiB7fVxyXG4gICAgICAgIGxldCBzcmNVcmw9dGhpcy5zcmNVcmwoKTtcclxuICAgICAgICBpZihzcmNVcmwpIHtcclxuICAgICAgICAgIHByb21wdEltYWdlLnNyYyA9IHNyY1VybDtcclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuXHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICB0aGlzLl90ZXh0ID0gbnVsbFxyXG4gICAgICB0aGlzLl9zcmMgPSBudWxsXHJcbiAgICB9XHJcbiAgfVxyXG59XHJcblxyXG5leHBvcnQgY29uc3QgVklSVFVBTF9IRUlHSFQgPSA2MDA7XHJcbmV4cG9ydCBjb25zdCBERUZBVUxUX1BST01QVF9GT05UU0laRSA9IDQ4O1xyXG5leHBvcnQgY29uc3QgTUlOX0ZPTlRfU0laRT02O1xyXG5leHBvcnQgY29uc3QgRkFMTEJBQ0tfREVGX1VTRVJfQUdFTlRfRk9OVF9TSVpFID0gMTQ7XHJcblxyXG5AQ29tcG9uZW50KHtcclxuXHJcbiAgc2VsZWN0b3I6ICdhcHAtc3BycHJvbXB0Y29udGFpbmVyJyxcclxuXHJcbiAgdGVtcGxhdGU6IGBcclxuICAgIDxhcHAtc3BycHJvbXB0ZXIgI3Byb21wdGVyIFtwcm9qZWN0TmFtZV09XCJwcm9qZWN0TmFtZVwiIFtwcm9tcHRNZWRpYUl0ZW1zXT1cIm1lZGlhaXRlbXNcIiBbc3R5bGUuZm9udC1zaXplXT1cImZvbnRTaXplKydweCdcIiBbc3R5bGUudmlzaWJpbGl0eV09XCJwckRpc3BsYXlcIiBbcHJvbXB0ZXJIZWlnaHRdPVwicHJvbXB0ZXJIZWlnaHRcIj48L2FwcC1zcHJwcm9tcHRlcj5cclxuICBgXHJcbiAgLFxyXG4gIHN0eWxlczogW2A6aG9zdCB7XHJcblxyXG4gICAgZmxleDogMzsgLyogdGhlIGNvbnRhaW5lciBjb25zdW1lcyBhbGwgYXZhaWxhYmxlIHNwYWNlICovXHJcbiAgICBwYWRkaW5nOiAxMHB0O1xyXG4gICAgaGVpZ2h0OiAxMDAlO1xyXG4gICAgbWF4LWhlaWdodDogMTAwJTtcclxuXHJcbiAgICBqdXN0aWZ5LWNvbnRlbnQ6IGNlbnRlcjsgLyogYWxpZ24gaG9yaXpvbnRhbCBjZW50ZXIqL1xyXG4gICAgYWxpZ24taXRlbXM6IGNlbnRlcjsgLyogYWxpZ24gdmVydGljYWwgY2VudGVyICovXHJcbiAgICBiYWNrZ3JvdW5kOiB3aGl0ZTtcclxuICAgIHRleHQtYWxpZ246IGNlbnRlcjtcclxuICAgIGRpc3BsYXk6IGZsZXg7XHJcbiAgICBmbGV4LWRpcmVjdGlvbjogY29sdW1uO1xyXG4gICAgbWluLWhlaWdodDogMHB4O1xyXG4gICAgd2lkdGg6IDEwMCU7XHJcbiAgfVxyXG4gIGBdXHJcbn0pXHJcbmV4cG9ydCBjbGFzcyBQcm9tcHRDb250YWluZXIgaW1wbGVtZW50cyBPbkluaXQsQWZ0ZXJDb250ZW50Q2hlY2tlZCB7XHJcbiAgQElucHV0KCkgcHJvamVjdE5hbWU6IHN0cmluZyB8IHVuZGVmaW5lZDtcclxuICBwcml2YXRlIF9tZWRpYWl0ZW1zOiBBcnJheTxNZWRpYWl0ZW0+fG51bGw9bnVsbDtcclxuXHJcbiAgcHJvbXB0ZXJIZWlnaHQ6IG51bWJlciA9IFZJUlRVQUxfSEVJR0hUXHJcbiAgZm9udFNpemUhOiBudW1iZXI7XHJcbiAgZm9udFNpemVDaGFuZ2U9ZmFsc2VcclxuICBjb250ZW50Q2hlY2tlZD1mYWxzZTtcclxuICBwckRpc3BsYXk9J2hpZGRlbic7XHJcbiAgZGVmYXVsdFN0eWxlITogQ1NTU3R5bGVEZWNsYXJhdGlvbjtcclxuICBkZWZhdWx0Rm9udFNpemVQeCE6IG51bWJlcjtcclxuXHJcbiAgYXV0b0ZvbnRTaXplPWZhbHNlO1xyXG4gIEBWaWV3Q2hpbGQoUHJvbXB0ZXIsIHsgc3RhdGljOiB0cnVlIH0pIHByb21wdGVyITogUHJvbXB0ZXI7XHJcblxyXG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgZWxSZWY6RWxlbWVudFJlZil7fVxyXG5cclxuICBuZ09uSW5pdCgpIHtcclxuXHJcbiAgICAvLyBmYWxsYmFja1xyXG4gICAgdGhpcy5kZWZhdWx0Rm9udFNpemVQeCA9IEZBTExCQUNLX0RFRl9VU0VSX0FHRU5UX0ZPTlRfU0laRTtcclxuICAgIC8vIHRyeSB0byBwYXJzZSBkZWZhdWx0IHVzZXIgYWdlbnQgZm9udCBzaXplIChubyBjb21tZW50IGFib3V0IERPTSBBUEkgZGVzaWduIDspIClcclxuICAgIHRoaXMuZGVmYXVsdFN0eWxlID0gd2luZG93LmdldENvbXB1dGVkU3R5bGUodGhpcy5lbFJlZi5uYXRpdmVFbGVtZW50KTtcclxuICAgIGxldCBkZWZGb250U2l6ZVN0ciA9IHRoaXMuZGVmYXVsdFN0eWxlLmZvbnRTaXplO1xyXG4gICAgaWYgKGRlZkZvbnRTaXplU3RyKSB7XHJcbiAgICAgIGRlZkZvbnRTaXplU3RyID0gZGVmRm9udFNpemVTdHIudHJpbSgpO1xyXG4gICAgICBpZiAoZGVmRm9udFNpemVTdHIuZW5kc1dpdGgoJ3B4JykpIHtcclxuICAgICAgICAvLyBwYXJzZUZsb2F0IGlnbm9yZXMgbm9uIG51bWJlciBjaGFyYWN0ZXJzIGF0IHRoZSBlbmQgKGFnYWluIG5vIGNvbW1lbnQgOykgKVxyXG4gICAgICAgIHRoaXMuZGVmYXVsdEZvbnRTaXplUHggPSBwYXJzZUZsb2F0KGRlZkZvbnRTaXplU3RyKTtcclxuICAgICAgICAgIC8vY29uc29sZS5pbmZvKFwiRGVmYXVsdCBmb250IHNpemU6IFwiK3RoaXMuZGVmYXVsdEZvbnRTaXplUHgpXHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcbiAgICAgIHRoaXMuY29udGVudENoZWNrZWQgPSBmYWxzZTtcclxuICB9XHJcblxyXG4gIG5nQWZ0ZXJDb250ZW50Q2hlY2tlZCgpOiB2b2lkIHtcclxuICAgIGlmKHRoaXMuYXV0b0ZvbnRTaXplKSB7XHJcbiAgICAgIGlmICh0aGlzLmZvbnRTaXplQ2hhbmdlKSB7XHJcbiAgICAgICAgLy9jb25zb2xlLmxvZyhcIm5nYWZ0ZXJjb250ZW50Y2hlY2tlZCwgY2FsbCBmb250U2l6ZVRvRml0IFwiKTtcclxuICAgICAgICAvLyBjaGVjayBwcm9tcHRlciBzaXplIGFnYWluXHJcbiAgICAgICAgdGhpcy5mb250U2l6ZVRvRml0KClcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICAvLyBmb250IHNpemUgd2FzIGNoZWNrZWQsIGJ1dCB3ZSBuZWVkIHRvIGNoZWNrIGFnYWluIGFmdGVyIGFuZ3VsYXIgY29udGVudCBjaGVja1xyXG4gICAgICAgIGlmICghdGhpcy5jb250ZW50Q2hlY2tlZCkge1xyXG4gICAgICAgICAgdGhpcy5jb250ZW50Q2hlY2tlZCA9IHRydWU7XHJcbiAgICAgICAgICAvL2NvbnNvbGUubG9nKFwibmdhZnRlcmNvbnRlbnRjaGVja2VkLCBub3QgZm9udCBzaXplIGNoYW5nZWQsIGNhbGwgXCIpO1xyXG4gICAgICAgICAgdGhpcy5mb250U2l6ZVRvRml0KClcclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuICAgIH1cclxuICB9XHJcblxyXG5cclxuICBASW5wdXQoKSBzZXQgbWVkaWFpdGVtcyhtZWRpYWl0ZW1zOkFycmF5PE1lZGlhaXRlbT58bnVsbCl7XHJcblxyXG4gICAgdGhpcy5fbWVkaWFpdGVtcyA9IG1lZGlhaXRlbXNcclxuXHJcbiAgICBsZXQgbWltZXR5cGU6c3RyaW5nfG51bGw9bnVsbDtcclxuICAgIGlmICh0aGlzLl9tZWRpYWl0ZW1zICYmIHRoaXMuX21lZGlhaXRlbXMubGVuZ3RoID09IDEpIHtcclxuICAgICAgbGV0IG1pID0gdGhpcy5fbWVkaWFpdGVtc1swXVxyXG4gICAgICBtaW1ldHlwZSA9ICd0ZXh0L3BsYWluJ1xyXG4gICAgICBpZiAobWkubWltZXR5cGUpIHtcclxuICAgICAgICBtaW1ldHlwZSA9IG1pLm1pbWV0eXBlLnRyaW0oKTtcclxuICAgICAgfVxyXG4gICAgICBpZihtaS5kZWZhdWx0VmlydHVhbFZpZXdCb3gpe1xyXG4gICAgICAgIHRoaXMucHJvbXB0ZXJIZWlnaHQ9bWkuZGVmYXVsdFZpcnR1YWxWaWV3Qm94LmhlaWdodFxyXG4gICAgICB9XHJcbiAgICB9ZWxzZXtcclxuICAgICAgdGhpcy5wcm9tcHRlckhlaWdodD1WSVJUVUFMX0hFSUdIVFxyXG4gICAgfVxyXG4gICAgdGhpcy5wcm9tcHRlci5wcm9tcHRNZWRpYUl0ZW1zPXRoaXMuX21lZGlhaXRlbXNcclxuICAgIHRoaXMuYXV0b0ZvbnRTaXplPShtaW1ldHlwZSE9bnVsbCAmJiBtaW1ldHlwZS5zdGFydHNXaXRoKCd0ZXh0LycpKTtcclxuXHJcbiAgICB0aGlzLmxheW91dCgpO1xyXG5cclxuICB9XHJcblxyXG4gIGdldCBtZWRpYWl0ZW1zKCk6QXJyYXk8TWVkaWFpdGVtPnxudWxse1xyXG4gICAgICByZXR1cm4gdGhpcy5fbWVkaWFpdGVtcztcclxuICB9XHJcblxyXG5cclxuXHJcbiAgQEhvc3RMaXN0ZW5lcignd2luZG93OnJlc2l6ZScsIFsnJGV2ZW50J10pXHJcbiAgb25SZXNpemUoZXZlbnQ6IEV2ZW50KTogdm9pZCB7XHJcbiAgICAvL2NvbnNvbGUuZGVidWcoXCJvbnJlc2l6ZSwgY2FsbCBmb250U2l6ZVRvRml0IGhvb2sgXCIpO1xyXG4gICAgdGhpcy5sYXlvdXQoKTtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgbGF5b3V0KCkge1xyXG4gICAgaWYodGhpcy5hdXRvRm9udFNpemUgJiYgdGhpcy5lbFJlZikge1xyXG5cclxuICAgICAgdGhpcy5mb250U2l6ZUNoYW5nZT10cnVlO1xyXG4gICAgICB0aGlzLmNvbnRlbnRDaGVja2VkID0gZmFsc2VcclxuICAgICAgdGhpcy5wckRpc3BsYXkgPSAnaGlkZGVuJ1xyXG4gICAgICBsZXQgZWxIID0gdGhpcy5lbFJlZi5uYXRpdmVFbGVtZW50Lm9mZnNldEhlaWdodDtcclxuICAgICAgLy8gcHJvbXB0IHRleHQgZm9udCBzaXplIHNob3VsZCBzY2FsZSBhY2NvcmRpbmcgdG8gcHJvbXB0IGNvbnRhaW5lciBoZWlnaHRcclxuICAgICAgbGV0IHNjYWxlZFNpemUgPSBNYXRoLnJvdW5kKChlbEggLyB0aGlzLnByb21wdGVySGVpZ2h0KSAqIERFRkFVTFRfUFJPTVBUX0ZPTlRTSVpFKTtcclxuXHJcbiAgICAgIC8vIG1pbiBwcm9tcHQgZm9udCBzaXplIGlzIGRlZmF1bHQgdXNlciBhZ2VudCBzaXplXHJcbiAgICAgIGxldCBuZXdTaXplID0gTWF0aC5tYXgoc2NhbGVkU2l6ZSwgdGhpcy5kZWZhdWx0Rm9udFNpemVQeCk7XHJcbiAgICAgIGlmICh0aGlzLmZvbnRTaXplICE9PSBuZXdTaXplKSB7XHJcbiAgICAgICAgdGhpcy5mb250U2l6ZSA9IG5ld1NpemU7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIC8vY29uc29sZS5sb2coXCJsYXlvdXQsIGNhbGwgZm9udFNpemVUb0ZpdCBob29rIFwiKTtcclxuICAgICAgd2luZG93LnNldFRpbWVvdXQoKCkgPT4gdGhpcy5mb250U2l6ZVRvRml0KCkpXHJcblxyXG4gICAgfWVsc2V7XHJcbiAgICAgIHRoaXMuY29udGVudENoZWNrZWQgPSB0cnVlO1xyXG4gICAgICB0aGlzLnByRGlzcGxheSA9ICd2aXNpYmxlJztcclxuICAgIH1cclxuICB9XHJcblxyXG5cclxuICBwcml2YXRlIGZvbnRTaXplVG9GaXQoKXtcclxuICAgICAgaWYodGhpcy5wcm9tcHRlcikge1xyXG4gICAgICAgIGxldCBwVz10aGlzLnByb21wdGVyLndpZHRoKCk7XHJcbiAgICAgICAgbGV0IHBIPXRoaXMucHJvbXB0ZXIuaGVpZ2h0KCk7XHJcbiAgICAgICAgaWYgKHRoaXMuX21lZGlhaXRlbXMgJiYgdGhpcy5lbFJlZiAmJiBwVyAmJiBwSCkge1xyXG4gICAgICAgICAgbGV0IG5FbCA9IHRoaXMuZWxSZWYubmF0aXZlRWxlbWVudFxyXG4gICAgICAgICAgLy9jb25zb2xlLmxvZyhcInByb21wdGVyOiBcIiArIHRoaXMucHJvbXB0ZXIud2lkdGgoKSArIFwieFwiICsgdGhpcy5wcm9tcHRlci5oZWlnaHQoKSsgXCIgZm9udCBzaXplOiBcIit0aGlzLmZvbnRTaXplKVxyXG4gICAgICAgICAgaWYgKHRoaXMuZm9udFNpemUgPj0gTUlOX0ZPTlRfU0laRSAmJiAocFcgPiBuRWwub2Zmc2V0V2lkdGggfHwgcEggPiBuRWwub2Zmc2V0SGVpZ2h0KSkge1xyXG4gICAgICAgICAgICAvLyBwcm9tcHRlciBvdmVyc2l6ZXMgcHJvbXB0ZXIgY29udGFpbmVyLiBEZWNyZWFzZSBmb250IHNpemUuXHJcbiAgICAgICAgICAgIC8vIHNldCBpbnZpc2libGUgZHVyaW5nIGZvbnQgc2l6ZSBjaGVja3NcclxuICAgICAgICAgICAgdGhpcy5wckRpc3BsYXkgPSAnaGlkZGVuJ1xyXG4gICAgICAgICAgICAvLyBkZWNyZWFzZSBmb250IHNpemVcclxuICAgICAgICAgICAgdGhpcy5mb250U2l6ZSA9IHRoaXMuZm9udFNpemUgLSAxXHJcbiAgICAgICAgICAgIC8vIGNvbnNvbGUubG9nKFwiRGVjcmVhc2VkIGZvbnQgc2l6ZTogXCIrdGhpcy5mb250U2l6ZSApXHJcbiAgICAgICAgICAgIC8vIFNldCBmbGFnc1xyXG4gICAgICAgICAgICB0aGlzLmZvbnRTaXplQ2hhbmdlID0gdHJ1ZVxyXG4gICAgICAgICAgICB0aGlzLmNvbnRlbnRDaGVja2VkID0gZmFsc2VcclxuICAgICAgICAgICAgLy8gaG9vayB0aGUgbmV4dCBjaGVja1xyXG4gICAgICAgICAgICB3aW5kb3cuc2V0VGltZW91dCgoKSA9PiB0aGlzLmZvbnRTaXplVG9GaXQoKSlcclxuICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIC8vIHByb21wdGVyIGZpdHMgaW4gIHByb21wdGVyIGNvbnRhaW5lciwgZm9udCBzaXplIHNob3VsZCBiZSBmaW5lXHJcblxyXG4gICAgICAgICAgICAvL2NvbnNvbGUubG9nKFwicHJEaXNwbGF5OiBcIit0aGlzLnByRGlzcGxheSlcclxuXHJcbiAgICAgICAgICAgIC8vaWYodGhpcy5jb250ZW50Q2hlY2tlZCAmJiAhIHRoaXMuZm9udFNpemVDaGFuZ2UpIHtcclxuICAgICAgICAgICAgLy9jb25zb2xlLmxvZyhcIkRpc3BsYXkhXCIpXHJcbiAgICAgICAgICAgIC8vIHNldCBwcm9tcHRlciB2aXNpYmxlIG5vd1xyXG4gICAgICAgICAgICB0aGlzLnByRGlzcGxheSA9ICd2aXNpYmxlJ1xyXG4gICAgICAgICAgICAvL31cclxuICAgICAgICAgICAgdGhpcy5mb250U2l6ZUNoYW5nZSA9IGZhbHNlXHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgICAvL2NvbnNvbGUubG9nKFwiUHJvbXB0IHRleHQgd2lkdGg6IFwiK3RleHRTaXplLndpZHRoK1wiIFwiK3RoaXMuZWxSZWYubmF0aXZlRWxlbWVudC5vZmZzZXRXaWR0aCtcInhcIit0aGlzLmVsUmVmLm5hdGl2ZUVsZW1lbnQub2Zmc2V0SGVpZ2h0KVxyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG4gIH1cclxuXHJcbn1cclxuXHJcblxyXG5cclxuQENvbXBvbmVudCh7XHJcblxyXG4gIHNlbGVjdG9yOiAnYXBwLXNwcnByb21wdGluZ2NvbnRhaW5lcicsXHJcblxyXG4gIHRlbXBsYXRlOiBgXHJcbiAgICA8c3ByLXJlY2luc3RydWN0aW9ucyBbc2VsZWN0ZWRJdGVtSWR4XT1cInNlbGVjdGVkSXRlbUlkeFwiIFtpdGVtQ291bnRdPVwiaXRlbUNvdW50XCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgIFtyZWNpbnN0cnVjdGlvbnNdPVwicHJvbXB0SXRlbT8ucmVjaW5zdHJ1Y3Rpb25zPy5yZWNpbnN0cnVjdGlvbnNcIj48L3Nwci1yZWNpbnN0cnVjdGlvbnM+XHJcbiAgICA8YXBwLXNwcnByb21wdGNvbnRhaW5lciBbcHJvamVjdE5hbWVdPVwicHJvamVjdE5hbWVcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgW21lZGlhaXRlbXNdPVwic2hvd1Byb21wdD8ocHJvbXB0SXRlbT9wcm9tcHRJdGVtLm1lZGlhaXRlbXM6bnVsbCk6bnVsbFwiPjwvYXBwLXNwcnByb21wdGNvbnRhaW5lcj5cclxuXHJcbiAgYFxyXG4gICxcclxuICBzdHlsZXM6IFtgOmhvc3Qge1xyXG4gICAgcG9zaXRpb246IHJlbGF0aXZlO1xyXG4gICAgZmxleDogMzsgLyogdGhlIGNvbnRhaW5lciBjb25zdW1lcyBhbGwgYXZhaWxhYmxlIHNwYWNlICovXHJcbiAgICBwYWRkaW5nOiAxMHB0O1xyXG4gICAganVzdGlmeS1jb250ZW50OiBjZW50ZXI7IC8qIGFsaWduIGhvcml6b250YWwgY2VudGVyKi9cclxuICAgIGFsaWduLWl0ZW1zOiBjZW50ZXI7IC8qIGFsaWduIHZlcnRpY2FsIGNlbnRlciAqL1xyXG4gICAgYmFja2dyb3VuZDogd2hpdGU7XHJcbiAgICB0ZXh0LWFsaWduOiBjZW50ZXI7XHJcbiAgICBkaXNwbGF5OiBmbGV4O1xyXG4gICAgZmxleC1kaXJlY3Rpb246IGNvbHVtbjtcclxuICAgIG1pbi1oZWlnaHQ6IDBweDtcclxuICB9XHJcbiAgYF1cclxufSlcclxuZXhwb3J0IGNsYXNzIFByb21wdGluZ0NvbnRhaW5lciB7XHJcbiAgQElucHV0KCkgcHJvamVjdE5hbWU6IHN0cmluZyB8IHVuZGVmaW5lZDtcclxuICBASW5wdXQoKSBwcm9tcHRJdGVtOiBQcm9tcHRJdGVtfG51bGw9bnVsbDtcclxuICBASW5wdXQoKSBzaG93UHJvbXB0OiBib29sZWFuPWZhbHNlO1xyXG4gIEBJbnB1dCgpIHNlbGVjdGVkSXRlbUlkeCE6IG51bWJlcjtcclxuICBASW5wdXQoKSBpdGVtQ291bnQ6IG51bWJlcnx1bmRlZmluZWQ7XHJcblxyXG4gIEBJbnB1dCgpIHRyYW5zcG9ydEFjdGlvbnMhOiBUcmFuc3BvcnRBY3Rpb25zO1xyXG5cclxuICBwcml2YXRlIGUhOiBIVE1MRGl2RWxlbWVudDtcclxuICBwcml2YXRlIHN0YXJ0WDogbnVtYmVyIHwgbnVsbCA9IG51bGxcclxuICBwcml2YXRlIHRvdWNoU3RhcnRUaW1lU3RhbXA6IG51bWJlciB8IG51bGw9bnVsbDtcclxuXHJcbiAgY29uc3RydWN0b3IocHJpdmF0ZSByZWY6IEVsZW1lbnRSZWYpIHtcclxuICAgIHR5cGUgVG91Y2hTdGFydCA9IHt9XHJcbiAgfVxyXG5cclxuICBuZ09uSW5pdCgpIHtcclxuICAgIHRoaXMuZSA9IHRoaXMucmVmLm5hdGl2ZUVsZW1lbnQ7XHJcbiAgfVxyXG5cclxuICBASG9zdExpc3RlbmVyKCd0b3VjaHN0YXJ0JywgWyckZXZlbnQnXSlcclxuICBvblRvdWNoc3RhcnQoZXY6IFRvdWNoRXZlbnQgfCBhbnkpIHtcclxuICAgIC8vY29uc29sZS5sb2coXCJUb3VjaCBzdGFydCEgXCIpXHJcbiAgICBpZiAoISh0aGlzLnRyYW5zcG9ydEFjdGlvbnMuZndkQWN0aW9uLmRpc2FibGVkICYmXHJcbiAgICAgIHRoaXMudHJhbnNwb3J0QWN0aW9ucy5id2RBY3Rpb24uZGlzYWJsZWQgJiZcclxuICAgICAgdGhpcy50cmFuc3BvcnRBY3Rpb25zLm5leHRBY3Rpb24uZGlzYWJsZWQpKSB7XHJcbiAgICAgIGxldCB0YXJnZXRUb3VjaGVzTGVuID0gZXYudGFyZ2V0VG91Y2hlcy5sZW5ndGg7XHJcbiAgICAgIC8vZm9yKGxldCB0aT0wO3RpPGV2LnRhcmdldFRvdWNoZXMubGVuZ3RoO3RpKyspe1xyXG4gICAgICAvL2xldCB0PWV2LnRhcmdldFRvdWNoZXMuaXRlbSh0aSk7XHJcbiAgICAgIC8vIEFsbCB4IHZhbHVlcyBhcmUgdGhlIHNhbWUgPz9cclxuICAgICAgLy9jb25zb2xlLmxvZyhcIlRvdWNoICNcIit0aStcIjogcGFnZVg6IFwiK3QucGFnZVgrXCIgY2xpZW50WDogXCIrdC5jbGllbnRYK1wiIHNjcmVlblg6IFwiK3Quc2NyZWVuWClcclxuICAgICAgLy99XHJcbiAgICAgIGlmICh0YXJnZXRUb3VjaGVzTGVuID09IDEpIHtcclxuICAgICAgICAvLyBzaW5nbGUgdG91Y2hcclxuICAgICAgICBsZXQgdCA9IGV2LnRhcmdldFRvdWNoZXMuaXRlbSgwKTtcclxuICAgICAgICBpZiAodCkge1xyXG4gICAgICAgICAgdGhpcy5zdGFydFggPSBNYXRoLnJvdW5kKHQuc2NyZWVuWCk7XHJcbiAgICAgICAgICB0aGlzLnRvdWNoU3RhcnRUaW1lU3RhbXAgPSBldi50aW1lU3RhbXA7XHJcbiAgICAgICAgICB0aGlzLmUuc3R5bGUudHJhbnNpdGlvbiA9ICdub25lJztcclxuICAgICAgICAgIC8vY29uc29sZS5sb2coXCJUb3VjaCBzdGFydCB4OiBcIit0aGlzLnN0YXJ0WClcclxuICAgICAgICAgIC8vZXYucHJldmVudERlZmF1bHQoKTtcclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgfVxyXG5cclxuICBASG9zdExpc3RlbmVyKCd0b3VjaGVuZCcsIFsnJGV2ZW50J10pXHJcbiAgb25Ub3VjaEVuZChldjogVG91Y2hFdmVudCB8IGFueSkge1xyXG4gICAgLy9jb25zb2xlLmxvZyhcIlRvdWNoIGVuZCFcIilcclxuICAgIC8vIFJlc2V0IG9mZnNldCBzaGlmdFxyXG4gICAgaWYgKCEodGhpcy50cmFuc3BvcnRBY3Rpb25zLmZ3ZEFjdGlvbi5kaXNhYmxlZCAmJiB0aGlzLnRyYW5zcG9ydEFjdGlvbnMuYndkQWN0aW9uLmRpc2FibGVkICYmXHJcbiAgICAgIHRoaXMudHJhbnNwb3J0QWN0aW9ucy5uZXh0QWN0aW9uLmRpc2FibGVkKSkge1xyXG5cclxuICAgICAgbGV0IGNoYW5nZWRUb3VjaGVzTGVuID0gZXYuY2hhbmdlZFRvdWNoZXMubGVuZ3RoO1xyXG4gICAgICAvL2NvbnNvbGUubG9nKGNoYW5nZWRUb3VjaGVzTGVuK1wiIFwiK3RoaXMuc3RhcnRYKVxyXG4gICAgICBpZiAoY2hhbmdlZFRvdWNoZXNMZW4gPT0gMSAmJiB0aGlzLnN0YXJ0WCkge1xyXG4gICAgICAgIC8vIHNpbmdsZSB0b3VjaFxyXG4gICAgICAgIGxldCB0ID0gZXYuY2hhbmdlZFRvdWNoZXMuaXRlbSgwKTtcclxuICAgICAgICBpZiAodCkge1xyXG4gICAgICAgICAgbGV0IGRlbHRhWCA9IE1hdGgucm91bmQodC5jbGllbnRYIC0gdGhpcy5zdGFydFgpO1xyXG4gICAgICAgICAgbGV0IHRvdWNoTW92ZVNwZWVkID0gMDtcclxuICAgICAgICAgIGlmICh0aGlzLnRvdWNoU3RhcnRUaW1lU3RhbXApIHtcclxuICAgICAgICAgICAgdG91Y2hNb3ZlU3BlZWQgPSBkZWx0YVggLyAoZXYudGltZVN0YW1wIC0gdGhpcy50b3VjaFN0YXJ0VGltZVN0YW1wKTtcclxuICAgICAgICAgIH1cclxuICAgICAgICAgIGxldCBmdXR1cmVEZWx0YVggPSBkZWx0YVggKyAoODAwICogdG91Y2hNb3ZlU3BlZWQpO1xyXG4gICAgICAgICAgLy9jb25zb2xlLmxvZyhcIkRlbHRhWDogXCIgKyBkZWx0YVggKyBcIiBGdXR1cmUgZGVsdGFYOiBcIiArIGZ1dHVyZURlbHRhWCArIFwiICB3aWR0aDogXCIgKyB0aGlzLmUub2Zmc2V0V2lkdGgpXHJcbiAgICAgICAgICBpZiAoZnV0dXJlRGVsdGFYID4gdGhpcy5lLm9mZnNldFdpZHRoIC8gMikge1xyXG4gICAgICAgICAgICAvL2NvbnNvbGUubG9nKFwiU3dpcGUgcmlnaHQgZGV0ZWN0ZWQhIVwiKVxyXG4gICAgICAgICAgICAvL3RoaXMuc3dpcGVkUmlnaHQuZW1pdCgpXHJcbiAgICAgICAgICAgIGlmICghdGhpcy50cmFuc3BvcnRBY3Rpb25zLmJ3ZEFjdGlvbi5kaXNhYmxlZCkge1xyXG4gICAgICAgICAgICAgIHRoaXMudHJhbnNwb3J0QWN0aW9ucy5id2RBY3Rpb24ucGVyZm9ybSgpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHRoaXMuZS5zdHlsZS5sZWZ0ID0gLXRoaXMuZS5vZmZzZXRMZWZ0ICsgXCJweFwiO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgICAgaWYgKC1mdXR1cmVEZWx0YVggPiB0aGlzLmUub2Zmc2V0V2lkdGggLyAyKSB7XHJcbiAgICAgICAgICAgIC8vY29uc29sZS5sb2coXCJTd2lwZSBsZWZ0IGRldGVjdGVkISFcIilcclxuICAgICAgICAgICAgdGhpcy5lLnN0eWxlLmxlZnQgPSAtdGhpcy5lLm9mZnNldExlZnQgKyBcInB4XCI7XHJcbiAgICAgICAgICAgIC8vdGhpcy5zd2lwZWRMZWZ0LmVtaXQoKVxyXG4gICAgICAgICAgICBpZiAoIXRoaXMudHJhbnNwb3J0QWN0aW9ucy5uZXh0QWN0aW9uLmRpc2FibGVkKSB7XHJcbiAgICAgICAgICAgICAgdGhpcy50cmFuc3BvcnRBY3Rpb25zLm5leHRBY3Rpb24ucGVyZm9ybSgpO1xyXG4gICAgICAgICAgICB9IGVsc2UgaWYgKCF0aGlzLnRyYW5zcG9ydEFjdGlvbnMuZndkQWN0aW9uLmRpc2FibGVkKSB7XHJcbiAgICAgICAgICAgICAgdGhpcy50cmFuc3BvcnRBY3Rpb25zLmZ3ZEFjdGlvbi5wZXJmb3JtKCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgICBldi5wcmV2ZW50RGVmYXVsdCgpO1xyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG5cclxuICAgICAgLy8gcmVzZXQgYW5pbWF0ZWRcclxuICAgICAgdGhpcy5lLnN0eWxlLnRyYW5zaXRpb24gPSBcImxlZnQgMC44c1wiO1xyXG4gICAgfVxyXG4gICAgdGhpcy5zdGFydFggPSBudWxsO1xyXG4gICAgdGhpcy50b3VjaFN0YXJ0VGltZVN0YW1wID0gbnVsbDtcclxuICAgIHRoaXMuZS5zdHlsZS5sZWZ0ID0gXCIwcHhcIjtcclxuICB9XHJcblxyXG4gIEBIb3N0TGlzdGVuZXIoJ3RvdWNobW92ZScsIFsnJGV2ZW50J10pXHJcbiAgb25Ub3VjaE1vdmUoZXY6IFRvdWNoRXZlbnQgfCBhbnkpIHtcclxuICAgIC8vY29uc29sZS5sb2coXCJUb3VjaCBtb3ZlIVwiKVxyXG4gICAgaWYgKCEodGhpcy50cmFuc3BvcnRBY3Rpb25zLmZ3ZEFjdGlvbi5kaXNhYmxlZCAmJiB0aGlzLnRyYW5zcG9ydEFjdGlvbnMuYndkQWN0aW9uLmRpc2FibGVkICYmXHJcbiAgICAgIHRoaXMudHJhbnNwb3J0QWN0aW9ucy5uZXh0QWN0aW9uLmRpc2FibGVkKSkge1xyXG4gICAgICBsZXQgdGFyZ2V0VG91Y2hlc0xlbiA9IGV2LnRhcmdldFRvdWNoZXMubGVuZ3RoO1xyXG4gICAgICBpZiAodGFyZ2V0VG91Y2hlc0xlbiA9PSAxICYmIHRoaXMuc3RhcnRYKSB7XHJcbiAgICAgICAgLy8gc2luZ2xlIHRvdWNoXHJcbiAgICAgICAgbGV0IHQgPSBldi50YXJnZXRUb3VjaGVzLml0ZW0oMCk7XHJcbiAgICAgICAgaWYgKHQpIHtcclxuICAgICAgICAgIGxldCBkZWx0YVggPSBNYXRoLnJvdW5kKHQuc2NyZWVuWCAtIHRoaXMuc3RhcnRYKTtcclxuICAgICAgICAgIHRoaXMuZS5zdHlsZS5sZWZ0ID0gZGVsdGFYICsgXCJweFwiO1xyXG4gICAgICAgICAgLy8gY29uc29sZS5sb2coXCJUb3VjaCBtb3ZlIGRlbHRhIHg6IFwiK2RlbHRhWClcclxuICAgICAgICB9XHJcbiAgICAgICAgZXYucHJldmVudERlZmF1bHQoKTtcclxuICAgICAgfVxyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgQEhvc3RMaXN0ZW5lcigndG91Y2hjYW5jZWwnLCBbJyRldmVudCddKVxyXG4gIG9uVG91Y2hDYW5jZWwoZXY6IFRvdWNoRXZlbnQgfCBhbnkpIHtcclxuICAgIC8vY29uc29sZS5sb2coXCJUb3VjaCBjYW5jZWwhXCIpXHJcbiAgICB0aGlzLmUuc3R5bGUubGVmdCA9IFwiMHB4XCI7XHJcbiAgICAvL2V2LnByZXZlbnREZWZhdWx0KCk7XHJcbiAgfVxyXG5cclxufVxyXG5cclxuXHJcbkBDb21wb25lbnQoe1xyXG5cclxuICBzZWxlY3RvcjogJ2FwcC1zcHJwcm9tcHRpbmcnLFxyXG5cclxuICB0ZW1wbGF0ZTogYFxyXG5cclxuICAgIDxhcHAtc2ltcGxldHJhZmZpY2xpZ2h0IFtzdGF0dXNdPVwic3RhcnRTdG9wU2lnbmFsU3RhdGVcIj48L2FwcC1zaW1wbGV0cmFmZmljbGlnaHQ+XHJcbiAgICA8YXBwLXNwcnByb21wdGluZ2NvbnRhaW5lciBbcHJvamVjdE5hbWVdPVwicHJvamVjdE5hbWVcIiBbcHJvbXB0SXRlbV09XCJwcm9tcHRJdGVtXCIgW3Nob3dQcm9tcHRdPVwic2hvd1Byb21wdFwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbaXRlbUNvdW50XT1cIml0ZW1zPy5sZW5ndGhcIiBbc2VsZWN0ZWRJdGVtSWR4XT1cInNlbGVjdGVkSXRlbUlkeFwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbdHJhbnNwb3J0QWN0aW9uc109XCJ0cmFuc3BvcnRBY3Rpb25zXCI+PC9hcHAtc3BycHJvbXB0aW5nY29udGFpbmVyPlxyXG4gICAgPGFwcC1zcHJwcm9ncmVzcyAqbmdJZj1cIiFzY3JlZW5Yc1wiIFtpdGVtc109XCJpdGVtc1wiIFtzZWxlY3RlZEl0ZW1JZHhdPVwic2VsZWN0ZWRJdGVtSWR4XCJcclxuICAgICAgICAgICAgICAgICAgICAgKG9uUm93U2VsZWN0KT1cIml0ZW1TZWxlY3QoJGV2ZW50KVwiPjwvYXBwLXNwcnByb2dyZXNzPlxyXG4gICAgPGRpdiAjYXNDdCBbY2xhc3MuYWN0aXZlXT1cIiFhdWRpb1NpZ25hbENvbGxhcHNlZCAmJiAhc2NyZWVuWHNcIj5cclxuXHJcbiAgICAgIDxhcHAtYXVkaW9kaXNwbGF5ICNhdWRpb1NpZ25hbENvbnRhaW5lciBbY2xhc3MuYWN0aXZlXT1cIiFhdWRpb1NpZ25hbENvbGxhcHNlZFwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIFthdWRpb0NsaXBdPVwiZGlzcGxheUF1ZGlvQ2xpcFwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIFtwbGF5U3RhcnRBY3Rpb25dPVwicGxheVN0YXJ0QWN0aW9uXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgW3BsYXlTZWxlY3Rpb25BY3Rpb25dPVwicGxheVNlbGVjdGlvbkFjdGlvblwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIFthdXRvUGxheU9uU2VsZWN0VG9nZ2xlQWN0aW9uXT1cImF1dG9QbGF5T25TZWxlY3RUb2dnbGVBY3Rpb25cIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBbcGxheVN0b3BBY3Rpb25dPVwicGxheVN0b3BBY3Rpb25cIj48L2FwcC1hdWRpb2Rpc3BsYXk+XHJcblxyXG5cclxuICAgIDwvZGl2PlxyXG5cclxuXHJcblxyXG4gIGAsXHJcbiAgc3R5bGVzOiBbYDpob3N0IHtcclxuICAgIHBvc2l0aW9uOiByZWxhdGl2ZTtcclxuICAgIG1hcmdpbjogMDtcclxuICAgIHBhZGRpbmc6IDA7XHJcbiAgICBiYWNrZ3JvdW5kOiBsaWdodGdyZXk7XHJcbiAgICB3aWR0aDogMTAwJTsgLyogdXNlIGFsbCBob3Jpem9udGFsIGF2YWlsYWJsZSBzcGFjZSAqL1xyXG4gICAgZmxleDogMTsgLyogLi4uIGFuZCBmaWxsIHJlc3Qgb2YgdmVydGljYWwgYXZhaWxhYmxlIHNwYWNlIChvdGhlciBjb21wb25lbnRzIGhhdmUgZmxleCAwKSAqL1xyXG5cclxuICAgIC8qIFdvcmthcm91bmQgZm9yIEZpcmVmb3hcclxuICAgIElmIHRoZSBwcm9ncmVzcyB0YWJsZSBnZXRzIGxvbmcgKHNjcmlwdCB3aXRoIG1hbnkgaXRlbXMpIEZGIGluY3JlYXNlcyB0aGUgaGVpZ2h0IG9mIHRoZSBvdmVyZmxvdyBwcm9ncmVzc0NvbnRhaW5lciBhbmRcclxuICAgIHRoZSB3aG9sZSBhcHAgZG9lcyBub3QgZml0IGludG8gdGhlIHBhZ2UgYW55bW9yZS4gVGhlIGFwcCBvdmVyZmxvd3MgYW5kIHNob3dzIGEgdmVydGljYWwgc2Nyb2xsYmFyIGZvciB0aGUgd2hvbGUgYXBwLlxyXG4gICAgU2VlIGh0dHBzOi8vc3RhY2tvdmVyZmxvdy5jb20vcXVlc3Rpb25zLzI4NjM2ODMyL2ZpcmVmb3gtb3ZlcmZsb3cteS1ub3Qtd29ya2luZy13aXRoLW5lc3RlZC1mbGV4Ym94XHJcbiAgICAqL1xyXG4gICAgbWluLWhlaWdodDogMHB4O1xyXG5cclxuICAgIGRpc3BsYXk6IGZsZXg7IC8qIGZsZXggY29udGFpbmVyOiBsZWZ0IHRyYWZmaWMgbGlnaHQsIHJpZ2h0IHByb21wdGVyIChjb250YWluZXIpICovXHJcbiAgICBmbGV4LWRpcmVjdGlvbjogcm93O1xyXG4gICAgZmxleC13cmFwOiBub3dyYXA7IC8qIHdyYXAgY291bGQgY29tcGxldGVseSBkZXN0cm95IHRoZSBsYXlvdXQgKi9cclxuICB9YCwgYFxyXG4gICAgYXBwLXNpbXBsZXRyYWZmaWNsaWdodCB7XHJcbiAgICAgIG1hcmdpbjogMTBweDtcclxuICAgICAgbWluLWhlaWdodDogMHB4O1xyXG4gICAgICB6LWluZGV4OiAzO1xyXG4gICAgfVxyXG4gIGAsIGBcclxuICAgIGFwcC1zcHJwcm9ncmVzcyB7XHJcbiAgICAgIHotaW5kZXg6IDM7XHJcbiAgICB9XHJcbiAgYCwgYFxyXG4gICAgZGl2IHtcclxuICAgICAgZGlzcGxheTogbm9uZTtcclxuICAgICAgcG9zaXRpb246IGFic29sdXRlO1xyXG5cclxuXHJcbiAgICAgIC8qIGhlaWdodDogNTAlOyAqL1xyXG4gICAgICAvKiB3aWR0aDogMTAwJTsgKi9cclxuXHJcbiAgICAgIC8qIG92ZXJmbG93OiBoaWRkZW47ICovXHJcblxyXG4gICAgICAvKiBtYXJnaW46IDIwcHg7ICovXHJcbiAgICAgIC8qIGJvcmRlcjogMjBweDsgKi9cclxuICAgICAgei1pbmRleDogNTtcclxuICAgICAgLypiYWNrZ3JvdW5kLWNvbG9yOiByZWQ7ICovXHJcbiAgICB9YCwgYFxyXG4gICAgZGl2LmFjdGl2ZSB7XHJcbiAgICAgIGRpc3BsYXk6IGZsZXg7XHJcbiAgICAgIHBvc2l0aW9uOiBhYnNvbHV0ZTtcclxuICAgICAgYm90dG9tOiAwcHg7XHJcbiAgICAgIC8qbGVmdDogMHB4OyAqL1xyXG5cclxuICAgICAgaGVpZ2h0OiA5MCU7XHJcbiAgICAgIHdpZHRoOiAxMDAlO1xyXG5cclxuICAgICAgb3ZlcmZsb3c6IGhpZGRlbjtcclxuXHJcbiAgICAgIHBhZGRpbmc6IDBweDtcclxuICAgICAgLyogbWFyZ2luOiAyMHB4OyAqL1xyXG4gICAgICAvKiBib3JkZXI6IDIwcHg7ICovXHJcbiAgICAgIHotaW5kZXg6IDU7XHJcbiAgICAgIGJveC1zaXppbmc6IGJvcmRlci1ib3g7XHJcbiAgICAgIGJhY2tncm91bmQtY29sb3I6IHJnYmEoMCwgMCwgMCwgMClcclxuXHJcbiAgICB9YFxyXG4gIF1cclxuXHJcbn0pXHJcbmV4cG9ydCBjbGFzcyBQcm9tcHRpbmcgZXh0ZW5kcyBSZXNwb25zaXZlQ29tcG9uZW50e1xyXG5cclxuICBjb25zdHJ1Y3Rvcihwcm90ZWN0ZWQgYnBvOkJyZWFrcG9pbnRPYnNlcnZlcikge1xyXG4gICAgc3VwZXIoYnBvKTtcclxuICB9XHJcblxyXG4gIEBWaWV3Q2hpbGQoU2ltcGxlVHJhZmZpY0xpZ2h0LCB7IHN0YXRpYzogdHJ1ZSB9KSBzaW1wbGVUcmFmZmljTGlnaHQhOiBTaW1wbGVUcmFmZmljTGlnaHQ7XHJcbiAgQFZpZXdDaGlsZChBdWRpb0Rpc3BsYXksIHsgc3RhdGljOiB0cnVlIH0pIGF1ZGlvRGlzcGxheSE6IEF1ZGlvRGlzcGxheTtcclxuICBASW5wdXQoKSBwcm9qZWN0TmFtZTogc3RyaW5nIHwgdW5kZWZpbmVkO1xyXG4gIEBJbnB1dCgpIHN0YXJ0U3RvcFNpZ25hbFN0YXRlITogU3RhcnRTdG9wU2lnbmFsU3RhdGU7XHJcbiAgQElucHV0KCkgcHJvbXB0SXRlbTogUHJvbXB0SXRlbSB8IG51bGw9bnVsbDtcclxuICBASW5wdXQoKSBzaG93UHJvbXB0OiBib29sZWFuPWZhbHNlO1xyXG4gIEBJbnB1dCgpIGl0ZW1zOiBBcnJheTxJdGVtPnx1bmRlZmluZWQ9dW5kZWZpbmVkO1xyXG4gIEBJbnB1dCgpIHNlbGVjdGVkSXRlbUlkeCE6IG51bWJlcjtcclxuICBASW5wdXQoKSB0cmFuc3BvcnRBY3Rpb25zITogVHJhbnNwb3J0QWN0aW9ucztcclxuICBASW5wdXQoKSBlbmFibGVEb3dubG9hZDogYm9vbGVhbj1mYWxzZTtcclxuXHJcbiAgQElucHV0KCkgYXVkaW9TaWduYWxDb2xsYXBzZWQ6IGJvb2xlYW49dHJ1ZTtcclxuICBASW5wdXQoKSBkaXNwbGF5QXVkaW9DbGlwOiBBdWRpb0NsaXAgfCBudWxsPW51bGw7XHJcbiAgQElucHV0KCkgcGxheVN0YXJ0QWN0aW9uOiBBY3Rpb248dm9pZD58dW5kZWZpbmVkO1xyXG4gIEBJbnB1dCgpIHBsYXlTZWxlY3Rpb25BY3Rpb246IEFjdGlvbjx2b2lkPnx1bmRlZmluZWQ7XHJcbiAgQElucHV0KCkgYXV0b1BsYXlPblNlbGVjdFRvZ2dsZUFjdGlvbjpBY3Rpb248Ym9vbGVhbj58dW5kZWZpbmVkO1xyXG4gIEBJbnB1dCgpIHBsYXlTdG9wQWN0aW9uOiBBY3Rpb248dm9pZD58dW5kZWZpbmVkO1xyXG4gIEBPdXRwdXQoKSBvbkl0ZW1TZWxlY3QgPSBuZXcgRXZlbnRFbWl0dGVyPG51bWJlcj4oKTtcclxuICBAT3V0cHV0KCkgb25OZXh0SXRlbSA9IG5ldyBFdmVudEVtaXR0ZXIoKTtcclxuICBAT3V0cHV0KCkgb25QcmV2SXRlbSA9IG5ldyBFdmVudEVtaXR0ZXIoKTtcclxuXHJcbiAgaXRlbVNlbGVjdChyb3dJZHg6IG51bWJlcikge1xyXG4gICAgdGhpcy5vbkl0ZW1TZWxlY3QuZW1pdChyb3dJZHgpO1xyXG4gIH1cclxuXHJcbiAgbmV4dEl0ZW0oKSB7XHJcbiAgICB0aGlzLm9uTmV4dEl0ZW0uZW1pdCgpO1xyXG4gIH1cclxuXHJcbiAgcHJldkl0ZW0oKSB7XHJcbiAgICB0aGlzLm9uUHJldkl0ZW0uZW1pdCgpO1xyXG4gIH1cclxufVxyXG5cclxuIl19