ngx-scandoc 1.0.1 → 1.0.3

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 (45) hide show
  1. package/core/components/base.component.d.ts +6 -0
  2. package/core/components/camera-switch/camera-switch.component.d.ts +11 -0
  3. package/core/components/components.module.d.ts +10 -3
  4. package/core/components/scan/scan.component.d.ts +119 -0
  5. package/core/components/scan-results/scan-results.component.d.ts +20 -0
  6. package/core/components/webcam/webcam/webcam.component.d.ts +5 -2
  7. package/core/interfaces/config.d.ts +16 -0
  8. package/dialogs/components/blank/blank.component.d.ts +2 -3
  9. package/dialogs/components/scan-profile/scan-profile.component.d.ts +10 -116
  10. package/dialogs/components/turn-document/turn-document.component.d.ts +12 -0
  11. package/dialogs/dialogs.core.provider.d.ts +1 -1
  12. package/dialogs/dialogs.module.d.ts +2 -2
  13. package/esm2020/core/components/base.component.mjs +15 -0
  14. package/esm2020/core/components/camera-switch/camera-switch.component.mjs +22 -0
  15. package/esm2020/core/components/components.module.mjs +34 -6
  16. package/esm2020/core/components/scan/scan.component.mjs +582 -0
  17. package/esm2020/core/components/scan-results/scan-results.component.mjs +38 -0
  18. package/esm2020/core/components/webcam/webcam/webcam.component.mjs +23 -12
  19. package/esm2020/core/interfaces/config.mjs +2 -0
  20. package/esm2020/dialogs/components/blank/blank.component.mjs +6 -7
  21. package/esm2020/dialogs/components/scan-profile/scan-profile.component.mjs +33 -741
  22. package/esm2020/dialogs/components/scan-selfie/scan-selfie.component.mjs +2 -2
  23. package/esm2020/dialogs/components/turn-document/turn-document.component.mjs +32 -0
  24. package/esm2020/dialogs/dialogs.core.provider.mjs +18 -9
  25. package/esm2020/dialogs/dialogs.module.mjs +7 -7
  26. package/esm2020/lib/ngx-scandoc.module.mjs +1 -1
  27. package/esm2020/providers/auth.provider.mjs +3 -2
  28. package/esm2020/providers/camera.provider.mjs +40 -0
  29. package/esm2020/providers/interceptor.provider.mjs +2 -2
  30. package/esm2020/providers/layout.provider.mjs +28 -0
  31. package/esm2020/providers/scan.provider.mjs +4 -6
  32. package/esm2020/public-api.mjs +4 -2
  33. package/fesm2015/ngx-scandoc.mjs +1765 -1752
  34. package/fesm2015/ngx-scandoc.mjs.map +1 -1
  35. package/fesm2020/ngx-scandoc.mjs +1962 -1949
  36. package/fesm2020/ngx-scandoc.mjs.map +1 -1
  37. package/lib/ngx-scandoc.module.d.ts +1 -15
  38. package/package.json +1 -1
  39. package/providers/auth.provider.d.ts +1 -1
  40. package/providers/camera.provider.d.ts +17 -0
  41. package/providers/layout.provider.d.ts +11 -0
  42. package/providers/scan.provider.d.ts +3 -5
  43. package/public-api.d.ts +3 -1
  44. package/dialogs/components/scan-mobile/scan-mobile.component.d.ts +0 -16
  45. package/esm2020/dialogs/components/scan-mobile/scan-mobile.component.mjs +0 -43
@@ -0,0 +1,582 @@
1
+ import { Component, ViewChild, EventEmitter, Output, HostListener, ChangeDetectionStrategy, Input, HostBinding, } from '@angular/core';
2
+ import { Subject } from 'rxjs';
3
+ import { v4 as uuidv4 } from 'uuid';
4
+ import { FormGroup } from '@angular/forms';
5
+ import { ScanProvider } from '../../../providers/scan.provider';
6
+ import { BaseComponent } from '../base.component';
7
+ import * as i0 from "@angular/core";
8
+ import * as i1 from "@ngx-translate/core";
9
+ import * as i2 from "../../../providers/camera.provider";
10
+ import * as i3 from "../../../providers/layout.provider";
11
+ import * as i4 from "../../../providers/auth.provider";
12
+ import * as i5 from "@angular/common";
13
+ import * as i6 from "../webcam/webcam/webcam.component";
14
+ import * as i7 from "@angular/material/icon";
15
+ import * as i8 from "@angular/material/button";
16
+ import * as i9 from "@angular/material/progress-bar";
17
+ import * as i10 from "../scan-results/scan-results.component";
18
+ export class ScanComponent extends BaseComponent {
19
+ constructor(cd, zone, translate, cameraProvider, injector, layoutProvider, auth // private api: ServerProvider
20
+ ) {
21
+ super();
22
+ this.cd = cd;
23
+ this.zone = zone;
24
+ this.translate = translate;
25
+ this.cameraProvider = cameraProvider;
26
+ this.injector = injector;
27
+ this.layoutProvider = layoutProvider;
28
+ this.auth = auth;
29
+ this.scanBlastData = [
30
+ {
31
+ title: 'pms.dialogs.components.scanProfile.front',
32
+ description: 'pms.dialogs.components.scanProfile.frontDescription',
33
+ side: 'FRONT',
34
+ },
35
+ {
36
+ title: 'pms.dialogs.components.scanProfile.back',
37
+ description: 'pms.dialogs.components.scanProfile.backDescription',
38
+ disabled: true,
39
+ side: 'BACK',
40
+ },
41
+ ];
42
+ this.type = 'desktop';
43
+ this.actions = new EventEmitter();
44
+ this.mediaDevices = [];
45
+ this.videoOptions = {
46
+ width: 1920,
47
+ height: 1080,
48
+ facingMode: 'environment',
49
+ };
50
+ this.startTime = 0;
51
+ this.isDebug = false;
52
+ this.multipleWebcamsAvailable = false;
53
+ this.scanInProgress = false;
54
+ // webcam snapshot trigger
55
+ this.documentTypeSelected = false;
56
+ this.preview = null;
57
+ this.errorCode = '1000';
58
+ this.displayInfo = 'Position document inside rectange and hold steady.';
59
+ this.allowCameraSwitch = true;
60
+ this.verificationErrorSent = false;
61
+ this.error = false;
62
+ this.cameraReady = false;
63
+ this.scaning = false;
64
+ this.imageHandler = new Subject();
65
+ this.logData = {
66
+ AcceptTermsAndConditions: true,
67
+ Request: null,
68
+ Response: null,
69
+ ExpectedOutput: null,
70
+ };
71
+ this.scanDatas = [];
72
+ this.idScan = null;
73
+ this.validation = false;
74
+ this.scannedImages = [];
75
+ this.scanDelay = 0;
76
+ this.trigger = new Subject();
77
+ // switch to next / previous / specific webcam; true/false: forward/backwards, string: deviceId
78
+ this.nextWebcam = new Subject();
79
+ this.imageVerified = false;
80
+ this.form = new FormGroup({});
81
+ this.isMobile = false;
82
+ this.showDialog = false;
83
+ this.scanImageTimestamps = {
84
+ time: 0,
85
+ load: 0,
86
+ };
87
+ this.scanProvider = this.injector.get(ScanProvider);
88
+ }
89
+ get class() {
90
+ return this.isMobile;
91
+ }
92
+ onResize() {
93
+ if (this.wraper) {
94
+ this.width = this.wraper.nativeElement.clientWidth;
95
+ this.height = this.wraper.nativeElement.clientHeight;
96
+ setTimeout(() => {
97
+ const video = this.wraper?.nativeElement.querySelector('video');
98
+ if (video) {
99
+ // console.log(video.clientWidth, video.clientHeight);
100
+ this.videoWidth = video.clientWidth;
101
+ this.videoHeight = video.clientHeight;
102
+ }
103
+ this.cd.detectChanges();
104
+ }, 100);
105
+ this.cd.detectChanges();
106
+ }
107
+ }
108
+ resetLogData() {
109
+ this.logData = {
110
+ Request: null,
111
+ Response: null,
112
+ ExpectedOutput: null,
113
+ AcceptTermsAndConditions: true,
114
+ };
115
+ }
116
+ ngOnDestroy() {
117
+ if (this.scanTimeout) {
118
+ clearTimeout(this.scanTimeout);
119
+ }
120
+ if (this.imageHandlerSubscription) {
121
+ this.imageHandlerSubscription.unsubscribe();
122
+ }
123
+ console.log('DESTROXY');
124
+ this.__destroy();
125
+ }
126
+ init() {
127
+ this.auth.accesToken.subscribe();
128
+ this.resetLogData();
129
+ // this.result=true;
130
+ // this.result ={};
131
+ console.log('INIT SCAN');
132
+ }
133
+ cameraOff(ev) {
134
+ this.cameraReady = false;
135
+ this.cd.detectChanges();
136
+ }
137
+ continue() {
138
+ this.documentTypeSelected = false;
139
+ setTimeout(() => {
140
+ this.selectedSide.image = this.webcamImage;
141
+ if (this.selectedSide.side === 'FRONT') {
142
+ this.scanBlastData[1].disabled = false;
143
+ }
144
+ this.cd.detectChanges();
145
+ }, 200);
146
+ }
147
+ scan() {
148
+ // this.triggerSnapshot();
149
+ // this.scanDatas[0] = true;
150
+ // if (this.scanTimeout) {
151
+ // clearTimeout(this.scanTimeout);
152
+ // }
153
+ // this.scanTimeout = setTimeout(() => {
154
+ // this.scan();
155
+ // }, 1);
156
+ }
157
+ handleImage(webcamImage) {
158
+ // console.log('[received webcam image]', webcamImage);
159
+ this.zone.runOutsideAngular(() => {
160
+ const time = new Date().getTime();
161
+ if (this.scanImageTimestamps.load > 0) {
162
+ const { load } = this.scanImageTimestamps;
163
+ const diff = time - load;
164
+ // console.log('time:', diff);
165
+ this.scanDelay = diff;
166
+ }
167
+ this.scanImageTimestamps.load = time;
168
+ if (webcamImage.imageData) {
169
+ this.scannedImages.push(webcamImage);
170
+ }
171
+ this.cd.detectChanges();
172
+ if (this.scannedImages.length > 4 && !this.validation) {
173
+ console.timeEnd('scan');
174
+ console.time('scan');
175
+ // get last 10
176
+ console.log('CAPTURED:', this.scannedImages.length);
177
+ const images = this.scannedImages.slice(-5);
178
+ // set images to 0
179
+ this.scannedImages = [];
180
+ const imagesArray = images.map((m) => m.imageResized.split(',')[1]);
181
+ this.validation = true;
182
+ this.handleBurstData(imagesArray, images);
183
+ }
184
+ if (this.cameraReady) {
185
+ this.trigger.next(new Date().getTime());
186
+ }
187
+ });
188
+ }
189
+ handleBurstData(imagesArray, images, type = 'plain') {
190
+ this.__subs(this.scanProvider.burst(imagesArray)).subscribe((resp) => {
191
+ this.displayInfo = resp.Info;
192
+ console.timeEnd('validationPOST');
193
+ console.log('AnalysisTime', resp.AnalysisTime);
194
+ const { DocType, Series, Side, InfoCode } = resp;
195
+ // if (InfoCode === '1006' && this.idScan) {
196
+ // this.handleLongValidationError(image);
197
+ // }
198
+ if (resp.Validated) {
199
+ console.log('[SCANNED INDEX]', resp.Index);
200
+ const selectedImage = images[resp.Index];
201
+ // this.preview = this.webcamImage.imageAsDataUrl;
202
+ this.cd.detectChanges();
203
+ let image = selectedImage;
204
+ if (type == 'worker') {
205
+ const dataUrl = this.handleBitmapImage(selectedImage.bitmap);
206
+ image = { dataUrl };
207
+ }
208
+ if (InfoCode === '1007') {
209
+ // For ID ask for other side
210
+ if (Side === 'FRONT') {
211
+ this.scanBlastData[0].image = image;
212
+ }
213
+ else {
214
+ this.scanBlastData[1].image = image;
215
+ }
216
+ if (this.scanBlastData[0].image && this.scanBlastData[1].image) {
217
+ console.warn('UPLOAD');
218
+ if (type == 'worker') {
219
+ this.imageHandler.next({ type: 'stop' });
220
+ }
221
+ this.scanBlastFinish();
222
+ }
223
+ else {
224
+ const num = Side === 'FRONT' ? 1 : 0;
225
+ this.singleScan(this.scanBlastData[num]);
226
+ this.scan();
227
+ this.idScan = this.scanBlastData[num].side;
228
+ if (!this.showDialog) {
229
+ this.showDialog = true;
230
+ this.zone.run(() => {
231
+ this.dialogs.turnDocument(this.idScan).subscribe(() => {
232
+ this.showDialog = false;
233
+ this.validation = false;
234
+ });
235
+ });
236
+ }
237
+ console.log('ID SIDE', this.idScan);
238
+ this.displayInfo = 'Please turn the document over!';
239
+ }
240
+ }
241
+ else {
242
+ this.scanBlastData[0].image = image;
243
+ console.warn('UPLOAD');
244
+ if (type == 'worker') {
245
+ this.imageHandler.next({ type: 'stop' });
246
+ }
247
+ this.scanBlastFinish();
248
+ }
249
+ this.scannedImages = [];
250
+ // this.scanBlastData[0].image = selectedImage;
251
+ //this.scanBlastFinish();
252
+ }
253
+ else {
254
+ this.validation = false;
255
+ }
256
+ });
257
+ }
258
+ handleInitError(error) {
259
+ console.log(error);
260
+ }
261
+ get scanBlastCanUpload() {
262
+ return this.scanBlastData[0].image ? true : false;
263
+ }
264
+ cameraWasSwitched(deviceId) {
265
+ console.log('[active device]', deviceId);
266
+ this.deviceId = deviceId;
267
+ this.cameraReady = true;
268
+ this.defaultDevice = deviceId;
269
+ setTimeout(() => {
270
+ this.onResize();
271
+ this.scan();
272
+ }, 300);
273
+ }
274
+ get nextWebcamObservable() {
275
+ return this.nextWebcam.asObservable();
276
+ }
277
+ handleLongValidationError(img) {
278
+ // save current image after 10sec
279
+ const diff = (Date.now() - this.startTime) / 1000;
280
+ if (diff > 15 &&
281
+ !this.verificationErrorSent &&
282
+ this.scanProvider.config.development) {
283
+ this.verificationErrorSent = true;
284
+ const dataUrl = this.handleBitmapImage(img.bitmap);
285
+ console.warn('SENT');
286
+ // this.displayInfo = 'Cant detect document!';
287
+ this.logData.Request = this.__subs(this.scanProvider.sendLog({
288
+ AcceptTermsAndConditions: true,
289
+ ExpectedOutput: {},
290
+ Request: {
291
+ verification: dataUrl.split(',')[1],
292
+ },
293
+ Response: {
294
+ TransactionID: uuidv4(),
295
+ },
296
+ })).subscribe();
297
+ }
298
+ }
299
+ ngAfterViewInit() {
300
+ this.cd.detectChanges();
301
+ this.autoScan();
302
+ this.__subs(this.layoutProvider.breakpoint$).subscribe((v) => {
303
+ this.isMobile = !v.matches;
304
+ console.log('MNOBILE', this.isMobile);
305
+ });
306
+ this.imageHandlerSubscription = this.imageHandler.subscribe((webcamImage) => {
307
+ // return;
308
+ if (this.startTime === 0) {
309
+ this.startTime = Date.now();
310
+ }
311
+ this.zone.runOutsideAngular(() => {
312
+ if (webcamImage.base64) {
313
+ const time = new Date().getTime();
314
+ if (this.scanImageTimestamps.load > 0) {
315
+ const { load } = this.scanImageTimestamps;
316
+ const diff = time - load;
317
+ // console.warn('TIME', diff);
318
+ this.scanDelay = diff;
319
+ }
320
+ this.scanImageTimestamps.load = time;
321
+ this.scannedImages.push(webcamImage);
322
+ this.handleLongValidationError(webcamImage);
323
+ }
324
+ // this.cd.detectChanges();
325
+ if (this.scannedImages.length > 4 && !this.validation) {
326
+ // get last 10
327
+ console.timeEnd('validationTOTAL_UI');
328
+ console.time('validationTOTAL_UI');
329
+ const images = this.scannedImages.slice(-5);
330
+ // set images to 0
331
+ this.scannedImages = [];
332
+ console.log(images);
333
+ const imagesArray = images.map((m) => m.base64.split(',')[1]);
334
+ this.validation = true;
335
+ this.handleBurstData(imagesArray, images, 'worker');
336
+ console.time('validationPOST');
337
+ }
338
+ this.cd.detectChanges();
339
+ });
340
+ });
341
+ }
342
+ handleBitmapImage(bitmap) {
343
+ const { width, height } = bitmap;
344
+ const offscreenSmall = document.createElement('canvas');
345
+ offscreenSmall.width = width;
346
+ offscreenSmall.height = height;
347
+ const ctx = offscreenSmall.getContext('bitmaprenderer');
348
+ if (ctx) {
349
+ ctx.imageSmoothingEnabled = false;
350
+ ctx.transferFromImageBitmap(bitmap);
351
+ bitmap.close();
352
+ const data = ctx.canvas.toDataURL('image/jpeg');
353
+ return data;
354
+ }
355
+ return null;
356
+ }
357
+ autoScan() {
358
+ const side = this.scanBlastData[0];
359
+ this.idScan = null;
360
+ this.singleScan(side);
361
+ }
362
+ singleScan(side) {
363
+ this.scanType = side.side;
364
+ this.preview = null;
365
+ this.selectedSide = side;
366
+ this.selectedSide.image = null;
367
+ this.documentTypeSelected = true;
368
+ this.scanBlastData[1].disabled = false;
369
+ this.cd.detectChanges();
370
+ setTimeout(() => {
371
+ this.onResize();
372
+ }, 10);
373
+ }
374
+ getImgBase64(num) {
375
+ console.log('GET 64');
376
+ return this.scanBlastData[num].image.dataUrl.split(',')[1];
377
+ }
378
+ scanBlastFinish() {
379
+ console.time('upload');
380
+ if (this.type === 'mobile') {
381
+ this.actions.emit({ data: this.scanBlastData });
382
+ this.retake();
383
+ return;
384
+ }
385
+ this.idScan = null;
386
+ // const loading = this.dialogs.loading();
387
+ this.scaning = true;
388
+ this.cd.detectChanges();
389
+ console.time('payload');
390
+ const payload = {
391
+ AcceptTermsAndConditions: true,
392
+ DataFields: {
393
+ FrontImageType: 'base64',
394
+ FrontImageCropped: false,
395
+ BackImageType: 'base64',
396
+ BackImageCropped: false,
397
+ FrontImage: this.getImgBase64(0),
398
+ BackImage: this.scanBlastData[1].image ? this.getImgBase64(1) : null,
399
+ },
400
+ Settings: {
401
+ ShouldValidate: true,
402
+ ShouldReturnDocumentImage: true,
403
+ ShouldReturnFaceIfDetected: true,
404
+ SkipImageSizeCheck: true,
405
+ CanStoreImages: this.scanProvider.canStoreImages,
406
+ },
407
+ // CallBackUrl: 'http://demo:5000/report/extracted/',
408
+ };
409
+ if (!this.scanBlastData[1].image) {
410
+ payload.Settings.IgnoreBackImage = true;
411
+ }
412
+ this.logData.Request = JSON.parse(JSON.stringify(payload));
413
+ console.timeEnd('payload');
414
+ this.__subs(this.scanProvider.blastPost(payload)).subscribe((data) => {
415
+ //console.log(data);
416
+ const results = data.Data;
417
+ console.timeEnd('upload');
418
+ console.time('parse');
419
+ // data.InfoCode = '1001';
420
+ this.logData.Response = JSON.parse(JSON.stringify(data));
421
+ //loading.close();
422
+ this.documentTypeSelected = true;
423
+ this.scaning = false;
424
+ if (data.InfoCode === '1001') {
425
+ this.error = true;
426
+ console.log('[ERROR] 1001');
427
+ this.errorCode = '1001';
428
+ // this.scanSide = 0;
429
+ this.preview = true;
430
+ this.cd.detectChanges();
431
+ return;
432
+ }
433
+ if (data.InfoCode === '1002') {
434
+ this.error = true;
435
+ console.log('[ERROR] 1002');
436
+ this.errorCode = '1002';
437
+ // this.scanSide = 0;
438
+ this.preview = true;
439
+ this.cd.detectChanges();
440
+ return;
441
+ }
442
+ if (results && data.Metadata.length > 0 && data.InfoCode === '1000') {
443
+ console.log('Extraction time', data.AnalysisTime);
444
+ this.zone.run(() => {
445
+ if (data.ImageData?.Documents) {
446
+ const { Documents } = data.ImageData;
447
+ this.images = Documents.map((image, i) => {
448
+ return { data: 'data:image/jpeg;base64,' + Documents[i] };
449
+ });
450
+ }
451
+ this.result = this.scanProvider.parseBlast(results);
452
+ console.log('RES', this.result);
453
+ this.cd.detectChanges();
454
+ this.model = this.result.model;
455
+ if (data.ImageData?.FaceImage) {
456
+ this.model._avatar =
457
+ 'data:image/jpeg;base64,' + data.ImageData?.FaceImage;
458
+ }
459
+ console.log('MODEL', this.model);
460
+ this.cd.detectChanges();
461
+ });
462
+ }
463
+ else {
464
+ console.log('ERROR');
465
+ // this.scanSide = 0;
466
+ this.error = true;
467
+ this.preview = true;
468
+ this.cd.detectChanges();
469
+ // this.documentTypeSelected = false;
470
+ // this.retry();
471
+ }
472
+ this.cd.detectChanges();
473
+ console.timeEnd('parse');
474
+ }, (err) => {
475
+ // loading.close();
476
+ // this.scanSide = 0;
477
+ this.error = true;
478
+ this.preview = true;
479
+ this.documentTypeSelected = true;
480
+ this.scaning = false;
481
+ });
482
+ }
483
+ retry() {
484
+ this.preview = false;
485
+ this.validation = false;
486
+ this.errorCode = '1000';
487
+ this.result = false;
488
+ if (this.error) {
489
+ this.documentTypeSelected = false;
490
+ this.scanBlastData.forEach((element) => {
491
+ element.image = null;
492
+ });
493
+ }
494
+ this.error = false;
495
+ this.autoScan();
496
+ this.cd.detectChanges();
497
+ }
498
+ triggerSnapshot() {
499
+ this.trigger.next(0);
500
+ }
501
+ retake() {
502
+ this.validation = false;
503
+ this.preview = false;
504
+ this.error = false;
505
+ this.result = false;
506
+ this.scanSide = 0;
507
+ this.imageVerified = false;
508
+ this.scanDatas = [];
509
+ this.scaning = false;
510
+ this.images = [];
511
+ this.scanInProgress = false;
512
+ this.documentTypeSelected = false;
513
+ this.scanBlastData.forEach((m) => {
514
+ m.image = null;
515
+ });
516
+ this.autoScan();
517
+ this.cd.detectChanges();
518
+ }
519
+ use() {
520
+ // save images??
521
+ if (this.scanProvider.canStoreImages) {
522
+ this.logData.ExpectedOutput = JSON.parse(JSON.stringify(this.model));
523
+ if (this.logData.ExpectedOutput?._avatar) {
524
+ delete this.logData.ExpectedOutput._avatar;
525
+ }
526
+ this.__subs(this.scanProvider.sendLog(this.logData)).subscribe();
527
+ console.log(this.logData);
528
+ }
529
+ this.dialogRef?.close({
530
+ model: this.model,
531
+ images: this.images,
532
+ });
533
+ }
534
+ selfie() {
535
+ this.dialogs
536
+ .scanSelfie({ avatar: this.model._avatar })
537
+ .afterClosed()
538
+ .subscribe((resp) => {
539
+ if (resp) {
540
+ console.log(resp);
541
+ if (this.scanProvider.enableVerification) {
542
+ this.imageVerified = true;
543
+ }
544
+ this.model._avatar = resp.imageAsDataUrl;
545
+ this.cd.detectChanges();
546
+ }
547
+ });
548
+ }
549
+ videoReady(event) {
550
+ this.cameraReady = event;
551
+ if (this.cameraReady && !this.scanInProgress) {
552
+ this.scanInProgress = true;
553
+ setTimeout(() => {
554
+ this.trigger.next(new Date().getTime());
555
+ }, 1000);
556
+ }
557
+ }
558
+ }
559
+ ScanComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: ScanComponent, deps: [{ token: i0.ChangeDetectorRef }, { token: i0.NgZone }, { token: i1.TranslateService }, { token: i2.NgxScandocCameraProvider }, { token: i0.Injector }, { token: i3.LayoutProvider }, { token: i4.AuthProvider }], target: i0.ɵɵFactoryTarget.Component });
560
+ ScanComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: ScanComponent, selector: "ngx-scan", inputs: { type: "type", dialogs: "dialogs", showDialog: "showDialog" }, outputs: { actions: "actions" }, host: { listeners: { "window:resize": "onResize($event)" }, properties: { "class.mobile": "this.class" } }, viewQueries: [{ propertyName: "wraper", first: true, predicate: ["wraper"], descendants: true }], usesInheritance: true, ngImport: i0, template: "<section *ngIf=\"result\">\n <ngx-scan-results\n (action)=\"selfie()\"\n [form]=\"form\"\n [model]=\"model\"\n [images]=\"images\"\n ></ngx-scan-results>\n\n <footer>\n <div class=\"actions\">\n <button fxFlex class=\"mr-4\" mat-raised-button (click)=\"retake()\">\n {{ \"pms.dialogs.components.scanProfile.reTake\" | translate }}\n </button>\n <button\n [disabled]=\"error || form.invalid\"\n fxFlex\n class=\"ml-4\"\n mat-raised-button\n (click)=\"use()\"\n >\n {{ \"pms.dialogs.components.scanProfile.useData\" | translate }}\n </button>\n </div>\n </footer>\n</section>\n\n<section *ngIf=\"!result && documentTypeSelected\">\n <div #wraper class=\"wraper\">\n <div class=\"loading\" *ngIf=\"!cameraReady && !preview\">\n <mat-progress-bar mode=\"indeterminate\"></mat-progress-bar>\n </div>\n\n <ng-container *ngIf=\"!error\">\n <app-webcam\n *ngIf=\"!preview && !scaning\"\n class=\"main\"\n [imageQuality]=\"1\"\n #webcam\n fxFlex\n type=\"document\"\n [trigger]=\"trigger\"\n [imageHandler]=\"imageHandler\"\n (imageCapture)=\"handleImage($event)\"\n [allowCameraSwitch]=\"allowCameraSwitch\"\n [videoOptions]=\"videoOptions\"\n [switchCamera]=\"cameraProvider.nextWebcamObservable\"\n (cameraSwitched)=\"cameraWasSwitched($event)\"\n (initError)=\"handleInitError($event)\"\n [width]=\"width\"\n [height]=\"height\"\n (destroyed)=\"cameraOff($event)\"\n (videoReady)=\"videoReady($event)\"\n >\n </app-webcam>\n </ng-container>\n <div\n fxLayout=\"row\"\n fxFlex\n class=\"previewData\"\n *ngIf=\"preview\"\n style=\"z-index: 20; position: absolute; width: 100%; height: 100%\"\n >\n <div class=\"p-16 error\" *ngIf=\"error\">\n <div>\n <div class=\"title\" fxLayout=\"row\" fxLayoutAlign=\"start center\">\n <mat-icon>error_outline</mat-icon\n ><span class=\"ml-8\">{{\n \"pms.dialogs.components.scanProfile.unableToDetectId\" | translate\n }}</span>\n </div>\n\n <ng-container *ngIf=\"errorCode === '1001'\">\n <div>\n Could not classify the given object as a supported document.\n </div>\n </ng-container>\n <ng-container *ngIf=\"errorCode === '1002'\">\n <div>\n Something is wrong with extraction data. Please try again.\n </div>\n </ng-container>\n\n <ul *ngIf=\"errorCode === '1000'\">\n <li>\n {{\n \"pms.dialogs.components.scanProfile.placeIdCloseToDevice\"\n | translate\n }}\n </li>\n <li>\n {{\n \"pms.dialogs.components.scanProfile.ensureSufficientLight\"\n | translate\n }}\n </li>\n <li>\n {{\n \"pms.dialogs.components.scanProfile.holdDocumentSteady\"\n | translate\n }}\n </li>\n <li>\n {{\n \"pms.dialogs.components.scanProfile.makeSureAllEdgesOfTheIdAreVisible\"\n | translate\n }}\n </li>\n <li>\n {{\n \"pms.dialogs.components.scanProfile.makeSureThereAreNoGlareAndShadowsOnTheId\"\n | translate\n }}\n </li>\n </ul>\n </div>\n </div>\n\n <div\n class=\"scanPreview\"\n fxFlex\n fxLayout=\"column\"\n *ngIf=\"!error && !scaning\"\n >\n <!-- <div class=\"py-16\" style=\"font-size: 16px\">\n {{\n \"pms.dialogs.components.scanProfile.ensureAllTextsAreVisible\"\n | translate\n }}\n </div> -->\n <div\n fxFlex\n class=\"image\"\n [style.background-image]=\"'url(' + preview + ')'\"\n ></div>\n </div>\n </div>\n </div>\n\n <footer>\n <div\n class=\"displayInfo\"\n ngClass.lt-sm=\"mobile\"\n *ngIf=\"!preview && cameraReady\"\n >\n {{ displayInfo }}\n </div>\n <!-- <div style=\"height: 26px\">\n <div\n style=\"text-align: center; font-size: 18px\"\n *ngIf=\"idScan && !preview && cameraReady\"\n >\n <ng-container *ngIf=\"idScan === 'BACK'\">\n Turn document and:\n {{ \"pms.dialogs.components.scanProfile.captureBack\" | translate }}\n </ng-container>\n <ng-container *ngIf=\"idScan === 'FRONT'\">\n Turn document and:\n {{ \"pms.dialogs.components.scanProfile.captureFront\" | translate }}\n </ng-container>\n </div>\n </div> -->\n\n <div class=\"actions\" *ngIf=\"preview\">\n <button fxFlex class=\"mr-4\" mat-raised-button (click)=\"retry()\">\n {{ \"pms.dialogs.components.scanProfile.retry\" | translate }}\n </button>\n\n <button\n [disabled]=\"error\"\n fxFlex\n class=\"ml-4\"\n mat-raised-button\n (click)=\"continue()\"\n >\n {{\n \"pms.dialogs.components.scanProfile.continueWithSelectedImage\"\n | translate\n }}\n </button>\n </div>\n </footer>\n</section>\n", styles: [":host{display:flex;flex-direction:column!important;flex:1;background-color:#f5f5f5;overflow:hidden}section{flex:1;display:flex;flex-direction:column;position:relative;overflow:hidden}.wraper{position:relative;overflow:hidden;display:flex;flex-direction:column;flex:1}.wraper .loading{position:absolute;inset:0;z-index:20;background-color:#f5f5f5}.documentTurnOver{position:absolute;width:100%;height:100%;top:0;left:0;display:flex;flex-direction:column;align-items:center;justify-content:center}.documentTurnOver mat-icon{width:200px;color:#fff;height:200px;font-size:100px}.displayInfo{text-align:center;flex:1;width:100%;background-color:#000;height:50px;line-height:50px;color:#fff;z-index:200}.displayInfo.mobile{font-size:12px}.preview{width:100%;border-radius:1%}footer button{box-shadow:none!important;height:45px;min-height:45px;text-transform:uppercase}footer .actions{display:flex;flex-direction:row;align-items:center;padding:8px}footer .actions button{flex:1}.error{display:flex;align-items:center;justify-content:center;flex:1}.error .title{font-size:20px;margin-bottom:8px}.error .title mat-icon{margin-right:8px}.error ul{font-size:18px;list-style-type:none}mat-card{box-shadow:none!important}.mr-4{margin-right:4px}.ml-4{margin-left:4px}.p-16{padding:16px}.p-8{padding:8px}.py-16{padding:16px 0}.w-100-p{width:100%}.scanPreview{padding:16px}.scanPreview .image{background-position:center;background-repeat:no-repeat;background-size:contain}.empty{flex:1;display:flex;flex-direction:column;align-items:center;justify-content:center}\n"], dependencies: [{ kind: "directive", type: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i6.WebcamComponent, selector: "app-webcam", inputs: ["imageHandler", "id", "type", "width", "height", "videoOptions", "allowCameraSwitch", "mirrorImage", "captureImageData", "imageType", "imageQuality", "trigger", "switchCamera"], outputs: ["imageCapture", "initError", "imageClick", "cameraSwitched", "videoReady", "destroyed"] }, { kind: "component", type: i7.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i8.MatButton, selector: "button[mat-button], button[mat-raised-button], button[mat-icon-button], button[mat-fab], button[mat-mini-fab], button[mat-stroked-button], button[mat-flat-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { kind: "component", type: i9.MatProgressBar, selector: "mat-progress-bar", inputs: ["color", "value", "bufferValue", "mode"], outputs: ["animationEnd"], exportAs: ["matProgressBar"] }, { kind: "component", type: i10.ScanResultsComponent, selector: "ngx-scan-results", inputs: ["model", "images", "form"], outputs: ["action"] }, { kind: "pipe", type: i1.TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
561
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: ScanComponent, decorators: [{
562
+ type: Component,
563
+ args: [{ selector: 'ngx-scan', changeDetection: ChangeDetectionStrategy.OnPush, template: "<section *ngIf=\"result\">\n <ngx-scan-results\n (action)=\"selfie()\"\n [form]=\"form\"\n [model]=\"model\"\n [images]=\"images\"\n ></ngx-scan-results>\n\n <footer>\n <div class=\"actions\">\n <button fxFlex class=\"mr-4\" mat-raised-button (click)=\"retake()\">\n {{ \"pms.dialogs.components.scanProfile.reTake\" | translate }}\n </button>\n <button\n [disabled]=\"error || form.invalid\"\n fxFlex\n class=\"ml-4\"\n mat-raised-button\n (click)=\"use()\"\n >\n {{ \"pms.dialogs.components.scanProfile.useData\" | translate }}\n </button>\n </div>\n </footer>\n</section>\n\n<section *ngIf=\"!result && documentTypeSelected\">\n <div #wraper class=\"wraper\">\n <div class=\"loading\" *ngIf=\"!cameraReady && !preview\">\n <mat-progress-bar mode=\"indeterminate\"></mat-progress-bar>\n </div>\n\n <ng-container *ngIf=\"!error\">\n <app-webcam\n *ngIf=\"!preview && !scaning\"\n class=\"main\"\n [imageQuality]=\"1\"\n #webcam\n fxFlex\n type=\"document\"\n [trigger]=\"trigger\"\n [imageHandler]=\"imageHandler\"\n (imageCapture)=\"handleImage($event)\"\n [allowCameraSwitch]=\"allowCameraSwitch\"\n [videoOptions]=\"videoOptions\"\n [switchCamera]=\"cameraProvider.nextWebcamObservable\"\n (cameraSwitched)=\"cameraWasSwitched($event)\"\n (initError)=\"handleInitError($event)\"\n [width]=\"width\"\n [height]=\"height\"\n (destroyed)=\"cameraOff($event)\"\n (videoReady)=\"videoReady($event)\"\n >\n </app-webcam>\n </ng-container>\n <div\n fxLayout=\"row\"\n fxFlex\n class=\"previewData\"\n *ngIf=\"preview\"\n style=\"z-index: 20; position: absolute; width: 100%; height: 100%\"\n >\n <div class=\"p-16 error\" *ngIf=\"error\">\n <div>\n <div class=\"title\" fxLayout=\"row\" fxLayoutAlign=\"start center\">\n <mat-icon>error_outline</mat-icon\n ><span class=\"ml-8\">{{\n \"pms.dialogs.components.scanProfile.unableToDetectId\" | translate\n }}</span>\n </div>\n\n <ng-container *ngIf=\"errorCode === '1001'\">\n <div>\n Could not classify the given object as a supported document.\n </div>\n </ng-container>\n <ng-container *ngIf=\"errorCode === '1002'\">\n <div>\n Something is wrong with extraction data. Please try again.\n </div>\n </ng-container>\n\n <ul *ngIf=\"errorCode === '1000'\">\n <li>\n {{\n \"pms.dialogs.components.scanProfile.placeIdCloseToDevice\"\n | translate\n }}\n </li>\n <li>\n {{\n \"pms.dialogs.components.scanProfile.ensureSufficientLight\"\n | translate\n }}\n </li>\n <li>\n {{\n \"pms.dialogs.components.scanProfile.holdDocumentSteady\"\n | translate\n }}\n </li>\n <li>\n {{\n \"pms.dialogs.components.scanProfile.makeSureAllEdgesOfTheIdAreVisible\"\n | translate\n }}\n </li>\n <li>\n {{\n \"pms.dialogs.components.scanProfile.makeSureThereAreNoGlareAndShadowsOnTheId\"\n | translate\n }}\n </li>\n </ul>\n </div>\n </div>\n\n <div\n class=\"scanPreview\"\n fxFlex\n fxLayout=\"column\"\n *ngIf=\"!error && !scaning\"\n >\n <!-- <div class=\"py-16\" style=\"font-size: 16px\">\n {{\n \"pms.dialogs.components.scanProfile.ensureAllTextsAreVisible\"\n | translate\n }}\n </div> -->\n <div\n fxFlex\n class=\"image\"\n [style.background-image]=\"'url(' + preview + ')'\"\n ></div>\n </div>\n </div>\n </div>\n\n <footer>\n <div\n class=\"displayInfo\"\n ngClass.lt-sm=\"mobile\"\n *ngIf=\"!preview && cameraReady\"\n >\n {{ displayInfo }}\n </div>\n <!-- <div style=\"height: 26px\">\n <div\n style=\"text-align: center; font-size: 18px\"\n *ngIf=\"idScan && !preview && cameraReady\"\n >\n <ng-container *ngIf=\"idScan === 'BACK'\">\n Turn document and:\n {{ \"pms.dialogs.components.scanProfile.captureBack\" | translate }}\n </ng-container>\n <ng-container *ngIf=\"idScan === 'FRONT'\">\n Turn document and:\n {{ \"pms.dialogs.components.scanProfile.captureFront\" | translate }}\n </ng-container>\n </div>\n </div> -->\n\n <div class=\"actions\" *ngIf=\"preview\">\n <button fxFlex class=\"mr-4\" mat-raised-button (click)=\"retry()\">\n {{ \"pms.dialogs.components.scanProfile.retry\" | translate }}\n </button>\n\n <button\n [disabled]=\"error\"\n fxFlex\n class=\"ml-4\"\n mat-raised-button\n (click)=\"continue()\"\n >\n {{\n \"pms.dialogs.components.scanProfile.continueWithSelectedImage\"\n | translate\n }}\n </button>\n </div>\n </footer>\n</section>\n", styles: [":host{display:flex;flex-direction:column!important;flex:1;background-color:#f5f5f5;overflow:hidden}section{flex:1;display:flex;flex-direction:column;position:relative;overflow:hidden}.wraper{position:relative;overflow:hidden;display:flex;flex-direction:column;flex:1}.wraper .loading{position:absolute;inset:0;z-index:20;background-color:#f5f5f5}.documentTurnOver{position:absolute;width:100%;height:100%;top:0;left:0;display:flex;flex-direction:column;align-items:center;justify-content:center}.documentTurnOver mat-icon{width:200px;color:#fff;height:200px;font-size:100px}.displayInfo{text-align:center;flex:1;width:100%;background-color:#000;height:50px;line-height:50px;color:#fff;z-index:200}.displayInfo.mobile{font-size:12px}.preview{width:100%;border-radius:1%}footer button{box-shadow:none!important;height:45px;min-height:45px;text-transform:uppercase}footer .actions{display:flex;flex-direction:row;align-items:center;padding:8px}footer .actions button{flex:1}.error{display:flex;align-items:center;justify-content:center;flex:1}.error .title{font-size:20px;margin-bottom:8px}.error .title mat-icon{margin-right:8px}.error ul{font-size:18px;list-style-type:none}mat-card{box-shadow:none!important}.mr-4{margin-right:4px}.ml-4{margin-left:4px}.p-16{padding:16px}.p-8{padding:8px}.py-16{padding:16px 0}.w-100-p{width:100%}.scanPreview{padding:16px}.scanPreview .image{background-position:center;background-repeat:no-repeat;background-size:contain}.empty{flex:1;display:flex;flex-direction:column;align-items:center;justify-content:center}\n"] }]
564
+ }], ctorParameters: function () { return [{ type: i0.ChangeDetectorRef }, { type: i0.NgZone }, { type: i1.TranslateService }, { type: i2.NgxScandocCameraProvider }, { type: i0.Injector }, { type: i3.LayoutProvider }, { type: i4.AuthProvider }]; }, propDecorators: { type: [{
565
+ type: Input
566
+ }], dialogs: [{
567
+ type: Input
568
+ }], actions: [{
569
+ type: Output
570
+ }], showDialog: [{
571
+ type: Input
572
+ }], wraper: [{
573
+ type: ViewChild,
574
+ args: ['wraper']
575
+ }], class: [{
576
+ type: HostBinding,
577
+ args: ['class.mobile']
578
+ }], onResize: [{
579
+ type: HostListener,
580
+ args: ['window:resize', ['$event']]
581
+ }] } });
582
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2Nhbi5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9uZ3gtc2NhbmRvYy9zcmMvY29yZS9jb21wb25lbnRzL3NjYW4vc2Nhbi5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9uZ3gtc2NhbmRvYy9zcmMvY29yZS9jb21wb25lbnRzL3NjYW4vc2Nhbi5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQ0wsU0FBUyxFQUNULFNBQVMsRUFDVCxZQUFZLEVBQ1osTUFBTSxFQUNOLFlBQVksRUFJWix1QkFBdUIsRUFDdkIsS0FBSyxFQUlMLFdBQVcsR0FDWixNQUFNLGVBQWUsQ0FBQztBQUV2QixPQUFPLEVBQUUsT0FBTyxFQUFnRCxNQUFNLE1BQU0sQ0FBQztBQUM3RSxPQUFPLEVBQUUsRUFBRSxJQUFJLE1BQU0sRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUVwQyxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFLM0MsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLGtDQUFrQyxDQUFDO0FBTWhFLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQzs7Ozs7Ozs7Ozs7O0FBd0JsRCxNQUFNLE9BQU8sYUFDWCxTQUFRLGFBQWE7SUFnSHJCLFlBQ1MsRUFBcUIsRUFFcEIsSUFBWSxFQUNaLFNBQTJCLEVBQzVCLGNBQXdDLEVBQ3ZDLFFBQWtCLEVBQ2xCLGNBQThCLEVBRTlCLElBQWtCLENBQUMsOEJBQThCOztRQUV6RCxLQUFLLEVBQUUsQ0FBQztRQVZELE9BQUUsR0FBRixFQUFFLENBQW1CO1FBRXBCLFNBQUksR0FBSixJQUFJLENBQVE7UUFDWixjQUFTLEdBQVQsU0FBUyxDQUFrQjtRQUM1QixtQkFBYyxHQUFkLGNBQWMsQ0FBMEI7UUFDdkMsYUFBUSxHQUFSLFFBQVEsQ0FBVTtRQUNsQixt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RkFBYixhQUFhLDhYQ3ZEMUIsMjJLQXNMQTsyRkQvSGEsYUFBYTtrQkFOekIsU0FBUzsrQkFDRSxVQUFVLG1CQUdILHVCQUF1QixDQUFDLE1BQU07a1JBbUJ0QyxJQUFJO3NCQUFaLEtBQUs7Z0JBQ0csT0FBTztzQkFBZixLQUFLO2dCQUNJLE9BQU87c0JBQWhCLE1BQU07Z0JBOERFLFVBQVU7c0JBQWxCLEtBQUs7Z0JBS2UsTUFBTTtzQkFBMUIsU0FBUzt1QkFBQyxRQUFRO2dCQUVjLEtBQUs7c0JBQXJDLFdBQVc7dUJBQUMsY0FBYztnQkFLM0IsUUFBUTtzQkFEUCxZQUFZO3VCQUFDLGVBQWUsRUFBRSxDQUFDLFFBQVEsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gIENvbXBvbmVudCxcbiAgVmlld0NoaWxkLFxuICBFdmVudEVtaXR0ZXIsXG4gIE91dHB1dCxcbiAgSG9zdExpc3RlbmVyLFxuICBFbGVtZW50UmVmLFxuICBDaGFuZ2VEZXRlY3RvclJlZixcbiAgQWZ0ZXJWaWV3SW5pdCxcbiAgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksXG4gIElucHV0LFxuICBPbkRlc3Ryb3ksXG4gIE5nWm9uZSxcbiAgSW5qZWN0b3IsXG4gIEhvc3RCaW5kaW5nLFxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IE1hdERpYWxvZ1JlZiB9IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsL2RpYWxvZyc7XG5pbXBvcnQgeyBTdWJqZWN0LCBPYnNlcnZhYmxlLCBvZiwgZm9ya0pvaW4sIGZyb20sIFN1YnNjcmlwdGlvbiB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgdjQgYXMgdXVpZHY0IH0gZnJvbSAndXVpZCc7XG5cbmltcG9ydCB7IEZvcm1Hcm91cCB9IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcblxuaW1wb3J0IHsgc3dpdGNoTWFwLCBtYXAsIGRlbGF5IH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuXG5pbXBvcnQgeyBUcmFuc2xhdGVTZXJ2aWNlIH0gZnJvbSAnQG5neC10cmFuc2xhdGUvY29yZSc7XG5pbXBvcnQgeyBTY2FuUHJvdmlkZXIgfSBmcm9tICcuLi8uLi8uLi9wcm92aWRlcnMvc2Nhbi5wcm92aWRlcic7XG5pbXBvcnQgeyBXZWJjYW1JbWFnZSB9IGZyb20gJy4uLy4uLy4uL2NvcmUvY29tcG9uZW50cy93ZWJjYW0vZG9tYWluL3dlYmNhbS1pbWFnZSc7XG5pbXBvcnQgeyBXZWJjYW1Jbml0RXJyb3IgfSBmcm9tICcuLi8uLi8uLi9jb3JlL2NvbXBvbmVudHMvd2ViY2FtL2RvbWFpbi93ZWJjYW0taW5pdC1lcnJvcic7XG5pbXBvcnQgeyBBdXRoUHJvdmlkZXIgfSBmcm9tICcuLi8uLi8uLi9wcm92aWRlcnMvYXV0aC5wcm92aWRlcic7XG5pbXBvcnQgeyBOZ3hTY2FuZG9jQ2FtZXJhUHJvdmlkZXIgfSBmcm9tICcuLi8uLi8uLi9wcm92aWRlcnMvY2FtZXJhLnByb3ZpZGVyJztcbmltcG9ydCB7IExheW91dFByb3ZpZGVyIH0gZnJvbSAnLi4vLi4vLi4vcHJvdmlkZXJzL2xheW91dC5wcm92aWRlcic7XG5pbXBvcnQgeyBCYXNlQ29tcG9uZW50IH0gZnJvbSAnLi4vYmFzZS5jb21wb25lbnQnO1xuXG5leHBvcnQgaW50ZXJmYWNlIElXaW5kb3cgZXh0ZW5kcyBXaW5kb3cge1xuICBUZXh0RGV0ZWN0b3I6IGFueTtcbn1cblxuaW50ZXJmYWNlIFRyb3VibGVzaG9vdGluZyB7XG4gIFJlcXVlc3Q6IGFueTtcbiAgUmVzcG9uc2U6IGFueTtcbiAgRXhwZWN0ZWRPdXRwdXQ6IGFueTtcbiAgQWNjZXB0VGVybXNBbmRDb25kaXRpb25zOiBib29sZWFuO1xufVxuXG5pbnRlcmZhY2UgVGltZXN0YW1wcyB7XG4gIHRpbWU6IG51bWJlcjtcbiAgbG9hZDogbnVtYmVyO1xufVxuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICduZ3gtc2NhbicsXG4gIHRlbXBsYXRlVXJsOiAnLi9zY2FuLmNvbXBvbmVudC5odG1sJyxcbiAgc3R5bGVVcmxzOiBbJy4vc2Nhbi5jb21wb25lbnQuc2NzcyddLFxuICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaCxcbn0pXG5leHBvcnQgY2xhc3MgU2NhbkNvbXBvbmVudFxuICBleHRlbmRzIEJhc2VDb21wb25lbnRcbiAgaW1wbGVtZW50cyBBZnRlclZpZXdJbml0LCBPbkRlc3Ryb3lcbntcbiAgc2NhbkJsYXN0RGF0YTogYW55ID0gW1xuICAgIHtcbiAgICAgIHRpdGxlOiAncG1zLmRpYWxvZ3MuY29tcG9uZW50cy5zY2FuUHJvZmlsZS5mcm9udCcsXG4gICAgICBkZXNjcmlwdGlvbjogJ3Btcy5kaWFsb2dzLmNvbXBvbmVudHMuc2NhblByb2ZpbGUuZnJvbnREZXNjcmlwdGlvbicsXG4gICAgICBzaWRlOiAnRlJPTlQnLFxuICAgIH0sXG4gICAge1xuICAgICAgdGl0bGU6ICdwbXMuZGlhbG9ncy5jb21wb25lbnRzLnNjYW5Qcm9maWxlLmJhY2snLFxuICAgICAgZGVzY3JpcHRpb246ICdwbXMuZGlhbG9ncy5jb21wb25lbnRzLnNjYW5Qcm9maWxlLmJhY2tEZXNjcmlwdGlvbicsXG4gICAgICBkaXNhYmxlZDogdHJ1ZSxcbiAgICAgIHNpZGU6ICdCQUNLJyxcbiAgICB9LFxuICBdO1xuICBASW5wdXQoKSB0eXBlID0gJ2Rlc2t0b3AnO1xuICBASW5wdXQoKSBkaWFsb2dzOiBhbnk7XG4gIEBPdXRwdXQoKSBhY3Rpb25zID0gbmV3IEV2ZW50RW1pdHRlcigpO1xuICBtZWRpYURldmljZXM6IGFueSA9IFtdO1xuICBwdWJsaWMgZGV2aWNlSWQ/OiBzdHJpbmc7XG4gIHB1YmxpYyB2aWRlb09wdGlvbnM6IE1lZGlhVHJhY2tDb25zdHJhaW50cyA9IHtcbiAgICB3aWR0aDogMTkyMCxcbiAgICBoZWlnaHQ6IDEwODAsXG4gICAgZmFjaW5nTW9kZTogJ2Vudmlyb25tZW50JyxcbiAgfTtcbiAgZGlhbG9nUmVmPzogTWF0RGlhbG9nUmVmPGFueT47XG4gIGRhdGE6IGFueTtcbiAgc3RhcnRUaW1lOiBudW1iZXIgPSAwO1xuICBpc0RlYnVnID0gZmFsc2U7XG4gIG11bHRpcGxlV2ViY2Ftc0F2YWlsYWJsZSA9IGZhbHNlO1xuICBzY2FuSW5Qcm9ncmVzcyA9IGZhbHNlO1xuICBmaWVsZHM6IGFueTtcbiAgLy8gd2ViY2FtIHNuYXBzaG90IHRyaWdnZXJcbiAgZG9jdW1lbnRUeXBlU2VsZWN0ZWQgPSBmYWxzZTtcbiAgaW1hZ2VIYW5kbGVyU3Vic2NyaXB0aW9uITogU3Vic2NyaXB0aW9uO1xuICBzZWxlY3RlZFNpZGU6IGFueTtcbiAgaW1hZ2VzOiBhbnk7XG4gIHNjYW5UaW1lb3V0OiBhbnk7XG4gIHByZXZpZXc6IGFueSA9IG51bGw7XG4gIHNjYW5UeXBlOiBhbnk7XG4gIHdpZHRoOiBhbnk7XG4gIGhlaWdodDogYW55O1xuICB2aWRlb1dpZHRoOiBhbnk7XG4gIHZpZGVvSGVpZ2h0OiBhbnk7XG4gIGVycm9yQ29kZSA9ICcxMDAwJztcbiAgZGlzcGxheUluZm86IGFueSA9ICdQb3NpdGlvbiBkb2N1bWVudCBpbnNpZGUgcmVjdGFuZ2UgYW5kIGhvbGQgc3RlYWR5Lic7XG4gIGFsbG93Q2FtZXJhU3dpdGNoID0gdHJ1ZTtcbiAgdmVyaWZpY2F0aW9uRXJyb3JTZW50ID0gZmFsc2U7XG4gIGVycm9yID0gZmFsc2U7XG4gIGNhbWVyYVJlYWR5ID0gZmFsc2U7XG4gIHJlc3VsdDogYW55O1xuICBzY2FuaW5nID0gZmFsc2U7XG5cbiAgaW1hZ2VIYW5kbGVyID0gbmV3IFN1YmplY3QoKTtcblxuICBsb2dEYXRhOiBUcm91Ymxlc2hvb3RpbmcgPSB7XG4gICAgQWNjZXB0VGVybXNBbmRDb25kaXRpb25zOiB0cnVlLFxuICAgIFJlcXVlc3Q6IG51bGwsXG4gICAgUmVzcG9uc2U6IG51bGwsXG4gICAgRXhwZWN0ZWRPdXRwdXQ6IG51bGwsXG4gIH07XG4gIGRlZmF1bHREZXZpY2U6IGFueTtcbiAgc2NhbkRhdGFzOiBhbnkgPSBbXTtcbiAgc2NhblNpZGU6IGFueTtcbiAgaWRTY2FuOiBhbnkgPSBudWxsO1xuICB3ZWJjYW1JbWFnZT86IFdlYmNhbUltYWdlO1xuICBtb2RlbDogYW55O1xuICB2YWxpZGF0aW9uID0gZmFsc2U7XG4gIHNjYW5uZWRJbWFnZXM6IGFueVtdID0gW107XG4gIHNjYW5EZWxheTogYW55ID0gMDtcbiAgcHVibGljIHRyaWdnZXI6IFN1YmplY3Q8bnVtYmVyPiA9IG5ldyBTdWJqZWN0PG51bWJlcj4oKTtcbiAgLy8gc3dpdGNoIHRvIG5leHQgLyBwcmV2aW91cyAvIHNwZWNpZmljIHdlYmNhbTsgdHJ1ZS9mYWxzZTogZm9yd2FyZC9iYWNrd2FyZHMsIHN0cmluZzogZGV2aWNlSWRcbiAgcHVibGljIG5leHRXZWJjYW06IFN1YmplY3Q8Ym9vbGVhbiB8IHN0cmluZz4gPSBuZXcgU3ViamVjdDxcbiAgICBib29sZWFuIHwgc3RyaW5nXG4gID4oKTtcbiAgaW1hZ2VWZXJpZmllZCA9IGZhbHNlO1xuICBmb3JtID0gbmV3IEZvcm1Hcm91cCh7fSk7XG5cbiAgaXNNb2JpbGUgPSBmYWxzZTtcbiAgQElucHV0KCkgc2hvd0RpYWxvZyA9IGZhbHNlO1xuICBzY2FuSW1hZ2VUaW1lc3RhbXBzOiBUaW1lc3RhbXBzID0ge1xuICAgIHRpbWU6IDAsXG4gICAgbG9hZDogMCxcbiAgfTtcbiAgQFZpZXdDaGlsZCgnd3JhcGVyJykgd3JhcGVyPzogRWxlbWVudFJlZjtcblxuICBASG9zdEJpbmRpbmcoJ2NsYXNzLm1vYmlsZScpIGdldCBjbGFzcygpIHtcbiAgICByZXR1cm4gdGhpcy5pc01vYmlsZTtcbiAgfVxuXG4gIEBIb3N0TGlzdGVuZXIoJ3dpbmRvdzpyZXNpemUnLCBbJyRldmVudCddKVxuICBvblJlc2l6ZSgpIHtcbiAgICBpZiAodGhpcy53cmFwZXIpIHtcbiAgICAgIHRoaXMud2lkdGggPSB0aGlzLndyYXBlci5uYXRpdmVFbGVtZW50LmNsaWVudFdpZHRoO1xuICAgICAgdGhpcy5oZWlnaHQgPSB0aGlzLndyYXBlci5uYXRpdmVFbGVtZW50LmNsaWVudEhlaWdodDtcblxuICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgIGNvbnN0IHZpZGVvID0gdGhpcy53cmFwZXI/Lm5hdGl2ZUVsZW1lbnQucXVlcnlTZWxlY3RvcigndmlkZW8nKTtcbiAgICAgICAgaWYgKHZpZGVvKSB7XG4gICAgICAgICAgLy8gICBjb25zb2xlLmxvZyh2aWRlby5jbGllbnRXaWR0aCwgdmlkZW8uY2xpZW50SGVpZ2h0KTtcbiAgICAgICAgICB0aGlzLnZpZGVvV2lkdGggPSB2aWRlby5jbGllbnRXaWR0aDtcbiAgICAgICAgICB0aGlzLnZpZGVvSGVpZ2h0ID0gdmlkZW8uY2xpZW50SGVpZ2h0O1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuY2QuZGV0ZWN0Q2hhbmdlcygpO1xuICAgICAgfSwgMTAwKTtcbiAgICAgIHRoaXMuY2QuZGV0ZWN0Q2hhbmdlcygpO1xuICAgIH1cbiAgfVxuXG4gIHNjYW5Qcm92aWRlciE6IFNjYW5Qcm92aWRlcjtcblxuICBjb25zdHJ1Y3RvcihcbiAgICBwdWJsaWMgY2Q6IENoYW5nZURldGVjdG9yUmVmLFxuXG4gICAgcHJpdmF0ZSB6b25lOiBOZ1pvbmUsXG4gICAgcHJpdmF0ZSB0cmFuc2xhdGU6IFRyYW5zbGF0ZVNlcnZpY2UsXG4gICAgcHVibGljIGNhbWVyYVByb3ZpZGVyOiBOZ3hTY2FuZG9jQ2FtZXJhUHJvdmlkZXIsXG4gICAgcHJpdmF0ZSBpbmplY3RvcjogSW5qZWN0b3IsXG4gICAgcHJpdmF0ZSBsYXlvdXRQcm92aWRlcjogTGF5b3V0UHJvdmlkZXIsXG5cbiAgICBwcml2YXRlIGF1dGg6IEF1dGhQcm92aWRlciAvLyBwcml2YXRlIGFwaTogU2VydmVyUHJvdmlkZXJcbiAgKSB7XG4gICAgc3VwZXIoKTtcbiAgICB0aGlzLnNjYW5Qcm92aWRlciA9IHRoaXMuaW5qZWN0b3IuZ2V0KFNjYW5Qcm92aWRlcik7XG4gIH1cblxuICBwcml2YXRlIHJlc2V0TG9nRGF0YSgpIHtcbiAgICB0aGlzLmxvZ0RhdGEgPSB7XG4gICAgICBSZXF1ZXN0OiBudWxsLFxuICAgICAgUmVzcG9uc2U6IG51bGwsXG4gICAgICBFeHBlY3RlZE91dHB1dDogbnVsbCxcbiAgICAgIEFjY2VwdFRlcm1zQW5kQ29uZGl0aW9uczogdHJ1ZSxcbiAgICB9O1xuICB9XG4gIG5nT25EZXN0cm95KCk6IHZvaWQge1xuICAgIGlmICh0aGlzLnNjYW5UaW1lb3V0KSB7XG4gICAgICBjbGVhclRpbWVvdXQodGhpcy5zY2FuVGltZW91dCk7XG4gICAgfVxuICAgIGlmICh0aGlzLmltYWdlSGFuZGxlclN1YnNjcmlwdGlvbikge1xuICAgICAgdGhpcy5pbWFnZUhhbmRsZXJTdWJzY3JpcHRpb24udW5zdWJzY3JpYmUoKTtcbiAgICB9XG5cbiAgICBjb25zb2xlLmxvZygnREVTVFJPWFknKTtcblxuICAgIHRoaXMuX19kZXN0cm95KCk7XG4gIH1cbiAgaW5pdCgpIHtcbiAgICB0aGlzLmF1dGguYWNjZXNUb2tlbi5zdWJzY3JpYmUoKTtcbiAgICB0aGlzLnJlc2V0TG9nRGF0YSgpO1xuICAgIC8vIHRoaXMucmVzdWx0PXRydWU7XG4gICAgLy8gdGhpcy5yZXN1bHQgPXt9O1xuXG4gICAgY29uc29sZS5sb2coJ0lOSVQgU0NBTicpO1xuICB9XG5cbiAgY2FtZXJhT2ZmKGV2OiBhbnkpIHtcbiAgICB0aGlzLmNhbWVyYVJlYWR5ID0gZmFsc2U7XG4gICAgdGhpcy5jZC5kZXRlY3RDaGFuZ2VzKCk7XG4gIH1cblxuICBjb250aW51ZSgpIHtcbiAgICB0aGlzLmRvY3VtZW50VHlwZVNlbGVjdGVkID0gZmFsc2U7XG5cbiAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgIHRoaXMuc2VsZWN0ZWRTaWRlLmltYWdlID0gdGhpcy53ZWJjYW1JbWFnZTtcbiAgICAgIGlmICh0aGlzLnNlbGVjdGVkU2lkZS5zaWRlID09PSAnRlJPTlQnKSB7XG4gICAgICAgIHRoaXMuc2NhbkJsYXN0RGF0YVsxXS5kaXNhYmxlZCA9IGZhbHNlO1xuICAgICAgfVxuICAgICAgdGhpcy5jZC5kZXRlY3RDaGFuZ2VzKCk7XG4gICAgfSwgMjAwKTtcbiAgfVxuXG4gIHNjYW4oKSB7XG4gICAgLy8gdGhpcy50cmlnZ2VyU25hcHNob3QoKTtcbiAgICAvLyAgIHRoaXMuc2NhbkRhdGFzWzBdID0gdHJ1ZTtcbiAgICAvLyBpZiAodGhpcy5zY2FuVGltZW91dCkge1xuICAgIC8vICAgY2xlYXJUaW1lb3V0KHRoaXMuc2NhblRpbWVvdXQpO1xuICAgIC8vIH1cbiAgICAvLyB0aGlzLnNjYW5UaW1lb3V0ID0gc2V0VGltZW91dCgoKSA9PiB7XG4gICAgLy8gICB0aGlzLnNjYW4oKTtcbiAgICAvLyB9LCAxKTtcbiAgfVxuXG4gIHB1YmxpYyBoYW5kbGVJbWFnZSh3ZWJjYW1JbWFnZTogV2ViY2FtSW1hZ2UpOiB2b2lkIHtcbiAgICAvLyBjb25zb2xlLmxvZygnW3JlY2VpdmVkIHdlYmNhbSBpbWFnZV0nLCB3ZWJjYW1JbWFnZSk7XG4gICAgdGhpcy56b25lLnJ1bk91dHNpZGVBbmd1bGFyKCgpID0+IHtcbiAgICAgIGNvbnN0IHRpbWUgPSBuZXcgRGF0ZSgpLmdldFRpbWUoKTtcblxuICAgICAgaWYgKHRoaXMuc2NhbkltYWdlVGltZXN0YW1wcy5sb2FkID4gMCkge1xuICAgICAgICBjb25zdCB7IGxvYWQgfSA9IHRoaXMuc2NhbkltYWdlVGltZXN0YW1wcztcbiAgICAgICAgY29uc3QgZGlmZiA9IHRpbWUgLSBsb2FkO1xuICAgICAgICAvLyAgIGNvbnNvbGUubG9nKCd0aW1lOicsIGRpZmYpO1xuICAgICAgICB0aGlzLnNjYW5EZWxheSA9IGRpZmY7XG4gICAgICB9XG5cbiAgICAgIHRoaXMuc2NhbkltYWdlVGltZXN0YW1wcy5sb2FkID0gdGltZTtcblxuICAgICAgaWYgKHdlYmNhbUltYWdlLmltYWdlRGF0YSkge1xuICAgICAgICB0aGlzLnNjYW5uZWRJbWFnZXMucHVzaCh3ZWJjYW1JbWFnZSk7XG4gICAgICB9XG5cbiAgICAgIHRoaXMuY2QuZGV0ZWN0Q2hhbmdlcygpO1xuICAgICAgaWYgKHRoaXMuc2Nhbm5lZEltYWdlcy5sZW5ndGggPiA0ICYmICF0aGlzLnZhbGlkYXRpb24pIHtcbiAgICAgICAgY29uc29sZS50aW1lRW5kKCdzY2FuJyk7XG4gICAgICAgIGNvbnNvbGUudGltZSgnc2NhbicpO1xuICAgICAgICAvLyBnZXQgbGFzdCAxMFxuICAgICAgICBjb25zb2xlLmxvZygnQ0FQVFVSRUQ6JywgdGhpcy5zY2FubmVkSW1hZ2VzLmxlbmd0aCk7XG4gICAgICAgIGNvbnN0IGltYWdlcyA9IHRoaXMuc2Nhbm5lZEltYWdlcy5zbGljZSgtNSk7XG4gICAgICAgIC8vIHNldCBpbWFnZXMgdG8gMFxuICAgICAgICB0aGlzLnNjYW5uZWRJbWFnZXMgPSBbXTtcbiAgICAgICAgY29uc3QgaW1hZ2VzQXJyYXkgPSBpbWFnZXMubWFwKChtKSA9PiBtLmltYWdlUmVzaXplZC5zcGxpdCgnLCcpWzFdKTtcbiAgICAgICAgdGhpcy52YWxpZGF0aW9uID0gdHJ1ZTtcblxuICAgICAgICB0aGlzLmhhbmRsZUJ1cnN0RGF0YShpbWFnZXNBcnJheSwgaW1hZ2VzKTtcbiAgICAgIH1cblxuICAgICAgaWYgKHRoaXMuY2FtZXJhUmVhZHkpIHtcbiAgICAgICAgdGhpcy50cmlnZ2VyLm5leHQobmV3IERhdGUoKS5nZXRUaW1lKCkpO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBoYW5kbGVCdXJzdERhdGEoXG4gICAgaW1hZ2VzQXJyYXk6IGFueSxcbiAgICBpbWFnZXM6IGFueSxcbiAgICB0eXBlOiAnd29ya2VyJyB8ICdwbGFpbicgPSAncGxhaW4nXG4gICkge1xuICAgIHRoaXMuX19zdWJzKHRoaXMuc2NhblByb3ZpZGVyLmJ1cnN0KGltYWdlc0FycmF5KSkuc3Vic2NyaWJlKChyZXNwOiBhbnkpID0+IHtcbiAgICAgIHRoaXMuZGlzcGxheUluZm8gPSByZXNwLkluZm87XG4gICAgICBjb25zb2xlLnRpbWVFbmQoJ3ZhbGlkYXRpb25QT1NUJyk7XG4gICAgICBjb25zb2xlLmxvZygnQW5hbHlzaXNUaW1lJywgcmVzcC5BbmFseXNpc1RpbWUpO1xuICAgICAgY29uc3QgeyBEb2NUeXBlLCBTZXJpZXMsIFNpZGUsIEluZm9Db2RlIH0gPSByZXNwO1xuXG4gICAgICAvLyBpZiAoSW5mb0NvZGUgPT09ICcxMDA2JyAmJiB0aGlzLmlkU2Nhbikge1xuICAgICAgLy8gICB0aGlzLmhhbmRsZUxvbmdWYWxpZGF0aW9uRXJyb3IoaW1hZ2UpO1xuICAgICAgLy8gfVxuXG4gICAgICBpZiAocmVzcC5WYWxpZGF0ZWQpIHtcbiAgICAgICAgY29uc29sZS5sb2coJ1tTQ0FOTkVEIElOREVYXScsIHJlc3AuSW5kZXgpO1xuICAgICAgICBjb25zdCBzZWxlY3RlZEltYWdlID0gaW1hZ2VzW3Jlc3AuSW5kZXhdO1xuXG4gICAgICAgIC8vIHRoaXMucHJldmlldyA9IHRoaXMud2ViY2FtSW1hZ2UuaW1hZ2VBc0RhdGFVcmw7XG4gICAgICAgIHRoaXMuY2QuZGV0ZWN0Q2hhbmdlcygpO1xuXG4gICAgICAgIGxldCBpbWFnZSA9IHNlbGVjdGVkSW1hZ2U7XG4gICAgICAgIGlmICh0eXBlID09ICd3b3JrZXInKSB7XG4gICAgICAgICAgY29uc3QgZGF0YVVybCA9IHRoaXMuaGFuZGxlQml0bWFwSW1hZ2Uoc2VsZWN0ZWRJbWFnZS5iaXRtYXApO1xuICAgICAgICAgIGltYWdlID0geyBkYXRhVXJsIH07XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoSW5mb0NvZGUgPT09ICcxMDA3Jykge1xuICAgICAgICAgIC8vIEZvciBJRCBhc2sgZm9yIG90aGVyIHNpZGVcbiAgICAgICAgICBpZiAoU2lkZSA9PT0gJ0ZST05UJykge1xuICAgICAgICAgICAgdGhpcy5zY2FuQmxhc3REYXRhWzBdLmltYWdlID0gaW1hZ2U7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuc2NhbkJsYXN0RGF0YVsxXS5pbWFnZSA9IGltYWdlO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGlmICh0aGlzLnNjYW5CbGFzdERhdGFbMF0uaW1hZ2UgJiYgdGhpcy5zY2FuQmxhc3REYXRhWzFdLmltYWdlKSB7XG4gICAgICAgICAgICBjb25zb2xlLndhcm4oJ1VQTE9BRCcpO1xuICAgICAgICAgICAgaWYgKHR5cGUgPT0gJ3dvcmtlcicpIHtcbiAgICAgICAgICAgICAgdGhpcy5pbWFnZUhhbmRsZXIubmV4dCh7IHR5cGU6ICdzdG9wJyB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMuc2NhbkJsYXN0RmluaXNoKCk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGNvbnN0IG51bSA9IFNpZGUgPT09ICdGUk9OVCcgPyAxIDogMDtcblxuICAgICAgICAgICAgdGhpcy5zaW5nbGVTY2FuKHRoaXMuc2NhbkJsYXN0RGF0YVtudW1dKTtcbiAgICAgICAgICAgIHRoaXMuc2NhbigpO1xuICAgICAgICAgICAgdGhpcy5pZFNjYW4gPSB0aGlzLnNjYW5CbGFzdERhdGFbbnVtXS5zaWRlO1xuXG4gICAgICAgICAgICBpZiAoIXRoaXMuc2hvd0RpYWxvZykge1xuICAgICAgICAgICAgICB0aGlzLnNob3dEaWFsb2cgPSB0cnVlO1xuXG4gICAgICAgICAgICAgIHRoaXMuem9uZS5ydW4oKCkgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMuZGlhbG9ncy50dXJuRG9jdW1lbnQodGhpcy5pZFNjYW4pLnN1YnNjcmliZSgoKSA9PiB7XG4gICAgICAgICAgICAgICAgICB0aGlzLnNob3dEaWFsb2cgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICAgIHRoaXMudmFsaWRhdGlvbiA9IGZhbHNlO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBjb25zb2xlLmxvZygnSUQgU0lERScsIHRoaXMuaWRTY2FuKTtcblxuICAgICAgICAgICAgdGhpcy5kaXNwbGF5SW5mbyA9ICdQbGVhc2UgdHVybiB0aGUgZG9jdW1lbnQgb3ZlciEnO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aGlzLnNjYW5CbGFzdERhdGFbMF0uaW1hZ2UgPSBpbWFnZTtcbiAgICAgICAgICBjb25zb2xlLndhcm4oJ1VQTE9BRCcpO1xuICAgICAgICAgIGlmICh0eXBlID09ICd3b3JrZXInKSB7XG4gICAgICAgICAgICB0aGlzLmltYWdlSGFuZGxlci5uZXh0KHsgdHlwZTogJ3N0b3AnIH0pO1xuICAgICAgICAgIH1cbiAgICAgICAgICB0aGlzLnNjYW5CbGFzdEZpbmlzaCgpO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5zY2FubmVkSW1hZ2VzID0gW107XG5cbiAgICAgICAgLy8gdGhpcy5zY2FuQmxhc3REYXRhWzBdLmltYWdlID0gc2VsZWN0ZWRJbWFnZTtcblxuICAgICAgICAvL3RoaXMuc2NhbkJsYXN0RmluaXNoKCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLnZhbGlkYXRpb24gPSBmYWxzZTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIHB1YmxpYyBoYW5kbGVJbml0RXJyb3IoZXJyb3I6IFdlYmNhbUluaXRFcnJvcik6IHZvaWQge1xuICAgIGNvbnNvbGUubG9nKGVycm9yKTtcbiAgfVxuXG4gIGdldCBzY2FuQmxhc3RDYW5VcGxvYWQoKSB7XG4gICAgcmV0dXJuIHRoaXMuc2NhbkJsYXN0RGF0YVswXS5pbWFnZSA/IHRydWUgOiBmYWxzZTtcbiAgfVxuICBwdWJsaWMgY2FtZXJhV2FzU3dpdGNoZWQoZGV2aWNlSWQ6IHN0cmluZyk6IHZvaWQge1xuICAgIGNvbnNvbGUubG9nKCdbYWN0aXZlIGRldmljZV0nLCBkZXZpY2VJZCk7XG4gICAgdGhpcy5kZXZpY2VJZCA9IGRldmljZUlkO1xuICAgIHRoaXMuY2FtZXJhUmVhZHkgPSB0cnVlO1xuICAgIHRoaXMuZGVmYXVsdERldmljZSA9IGRldmljZUlkO1xuXG4gICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICB0aGlzLm9uUmVzaXplKCk7XG4gICAgICB0aGlzLnNjYW4oKTtcbiAgICB9LCAzMDApO1xuICB9XG5cbiAgcHVibGljIGdldCBuZXh0V2ViY2FtT2JzZXJ2YWJsZSgpOiBPYnNlcnZhYmxlPGJvb2xlYW4gfCBzdHJpbmc+IHtcbiAgICByZXR1cm4gdGhpcy5uZXh0V2ViY2FtLmFzT2JzZXJ2YWJsZSgpO1xuICB9XG5cbiAgcHJpdmF0ZSBoYW5kbGVMb25nVmFsaWRhdGlvbkVycm9yKGltZzogYW55KSB7XG4gICAgLy8gc2F2ZSBjdXJyZW50IGltYWdlIGFmdGVyIDEwc2VjXG5cbiAgICBjb25zdCBkaWZmID0gKERhdGUubm93KCkgLSB0aGlzLnN0YXJ0VGltZSkgLyAxMDAwO1xuXG4gICAgaWYgKFxuICAgICAgZGlmZiA+IDE1ICYmXG4gICAgICAhdGhpcy52ZXJpZmljYXRpb25FcnJvclNlbnQgJiZcbiAgICAgIHRoaXMuc2NhblByb3ZpZGVyLmNvbmZpZy5kZXZlbG9wbWVudFxuICAgICkge1xuICAgICAgdGhpcy52ZXJpZmljYXRpb25FcnJvclNlbnQgPSB0cnVlO1xuICAgICAgY29uc3QgZGF0YVVybCA9IHRoaXMuaGFuZGxlQml0bWFwSW1hZ2UoaW1nLmJpdG1hcCk7XG5cbiAgICAgIGNvbnNvbGUud2FybignU0VOVCcpO1xuICAgICAgLy8gIHRoaXMuZGlzcGxheUluZm8gPSAnQ2FudCBkZXRlY3QgZG9jdW1lbnQhJztcbiAgICAgIHRoaXMubG9nRGF0YS5SZXF1ZXN0ID0gdGhpcy5fX3N1YnMoXG4gICAgICAgIHRoaXMuc2NhblByb3ZpZGVyLnNlbmRMb2coe1xuICAgICAgICAgIEFjY2VwdFRlcm1zQW5kQ29uZGl0aW9uczogdHJ1ZSxcbiAgICAgICAgICBFeHBlY3RlZE91dHB1dDoge30sXG4gICAgICAgICAgUmVxdWVzdDoge1xuICAgICAgICAgICAgdmVyaWZpY2F0aW9uOiBkYXRhVXJsLnNwbGl0KCcsJylbMV0sXG4gICAgICAgICAgfSxcbiAgICAgICAgICBSZXNwb25zZToge1xuICAgICAgICAgICAgVHJhbnNhY3Rpb25JRDogdXVpZHY0KCksXG4gICAgICAgICAgfSxcbiAgICAgICAgfSlcbiAgICAgICkuc3Vic2NyaWJlKCk7XG4gICAgfVxuICB9XG4gIG5nQWZ0ZXJWaWV3SW5pdCgpIHtcbiAgICB0aGlzLmNkLmRldGVjdENoYW5nZXMoKTtcbiAgICB0aGlzLmF1dG9TY2FuKCk7XG5cbiAgICB0aGlzLl9fc3Vicyh0aGlzLmxheW91dFByb3ZpZGVyLmJyZWFrcG9pbnQkKS5zdWJzY3JpYmUoKHY6IGFueSkgPT4ge1xuICAgICAgdGhpcy5pc01vYmlsZSA9ICF2Lm1hdGNoZXM7XG4gICAgICBjb25zb2xlLmxvZygnTU5PQklMRScsIHRoaXMuaXNNb2JpbGUpO1xuICAgIH0pO1xuXG4gICAgdGhpcy5pbWFnZUhhbmRsZXJTdWJzY3JpcHRpb24gPSB0aGlzLmltYWdlSGFuZGxlci5zdWJzY3JpYmUoXG4gICAgICAod2ViY2FtSW1hZ2U6IGFueSkgPT4ge1xuICAgICAgICAvLyByZXR1cm47XG4gICAgICAgIGlmICh0aGlzLnN0YXJ0VGltZSA9PT0gMCkge1xuICAgICAgICAgIHRoaXMuc3RhcnRUaW1lID0gRGF0ZS5ub3coKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuem9uZS5ydW5PdXRzaWRlQW5ndWxhcigoKSA9PiB7XG4gICAgICAgICAgaWYgKHdlYmNhbUltYWdlLmJhc2U2NCkge1xuICAgICAgICAgICAgY29uc3QgdGltZSA9IG5ldyBEYXRlKCkuZ2V0VGltZSgpO1xuXG4gICAgICAgICAgICBpZiAodGhpcy5zY2FuSW1hZ2VUaW1lc3RhbXBzLmxvYWQgPiAwKSB7XG4gICAgICAgICAgICAgIGNvbnN0IHsgbG9hZCB9ID0gdGhpcy5zY2FuSW1hZ2VUaW1lc3RhbXBzO1xuICAgICAgICAgICAgICBjb25zdCBkaWZmID0gdGltZSAtIGxvYWQ7XG4gICAgICAgICAgICAgIC8vIGNvbnNvbGUud2FybignVElNRScsIGRpZmYpO1xuICAgICAgICAgICAgICB0aGlzLnNjYW5EZWxheSA9IGRpZmY7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHRoaXMuc2NhbkltYWdlVGltZXN0YW1wcy5sb2FkID0gdGltZTtcblxuICAgICAgICAgICAgdGhpcy5zY2FubmVkSW1hZ2VzLnB1c2god2ViY2FtSW1hZ2UpO1xuICAgICAgICAgICAgdGhpcy5oYW5kbGVMb25nVmFsaWRhdGlvbkVycm9yKHdlYmNhbUltYWdlKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICAvLyB0aGlzLmNkLmRldGVjdENoYW5nZXMoKTtcbiAgICAgICAgICBpZiAodGhpcy5zY2FubmVkSW1hZ2VzLmxlbmd0aCA+IDQgJiYgIXRoaXMudmFsaWRhdGlvbikge1xuICAgICAgICAgICAgLy8gZ2V0IGxhc3QgMTBcbiAgICAgICAgICAgIGNvbnNvbGUudGltZUVuZCgndmFsaWRhdGlvblRPVEFMX1VJJyk7XG4gICAgICAgICAgICBjb25zb2xlLnRpbWUoJ3ZhbGlkYXRpb25UT1RBTF9VSScpO1xuICAgICAgICAgICAgY29uc3QgaW1hZ2VzID0gdGhpcy5zY2FubmVkSW1hZ2VzLnNsaWNlKC01KTtcbiAgICAgICAgICAgIC8vIHNldCBpbWFnZXMgdG8gMFxuICAgICAgICAgICAgdGhpcy5zY2FubmVkSW1hZ2VzID0gW107XG4gICAgICAgICAgICBjb25zb2xlLmxvZyhpbWFnZXMpO1xuXG4gICAgICAgICAgICBjb25zdCBpbWFnZXNBcnJheSA9IGltYWdlcy5tYXAoKG0pID0+IG0uYmFzZTY0LnNwbGl0KCcsJylbMV0pO1xuICAgICAgICAgICAgdGhpcy52YWxpZGF0aW9uID0gdHJ1ZTtcblxuICAgICAgICAgICAgdGhpcy5oYW5kbGVCdXJzdERhdGEoaW1hZ2VzQXJyYXksIGltYWdlcywgJ3dvcmtlcicpO1xuXG4gICAgICAgICAgICBjb25zb2xlLnRpbWUoJ3ZhbGlkYXRpb25QT1NUJyk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHRoaXMuY2QuZGV0ZWN0Q2hhbmdlcygpO1xuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICApO1xuICB9XG5cbiAgaGFuZGxlQml0bWFwSW1hZ2UoYml0bWFwOiBhbnkpIHtcbiAgICBjb25zdCB7IHdpZHRoLCBoZWlnaHQgfSA9IGJpdG1hcDtcblxuICAgIGNvbnN0IG9mZnNjcmVlblNtYWxsID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnY2FudmFzJyk7XG4gICAgb2Zmc2NyZWVuU21hbGwud2lkdGggPSB3aWR0aDtcbiAgICBvZmZzY3JlZW5TbWFsbC5oZWlnaHQgPSBoZWlnaHQ7XG4gICAgY29uc3QgY3R4OiBhbnkgPSBvZmZzY3JlZW5TbWFsbC5nZXRDb250ZXh0KCdiaXRtYXByZW5kZXJlcicpO1xuXG4gICAgaWYgKGN0eCkge1xuICAgICAgY3R4LmltYWdlU21vb3RoaW5nRW5hYmxlZCA9IGZhbHNlO1xuICAgICAgY3R4LnRyYW5zZmVyRnJvbUltYWdlQml0bWFwKGJpdG1hcCk7XG4gICAgICBiaXRtYXAuY2xvc2UoKTtcbiAgICAgIGNvbnN0IGRhdGEgPSBjdHguY2FudmFzLnRvRGF0YVVSTCgnaW1hZ2UvanBlZycpO1xuICAgICAgcmV0dXJuIGRhdGE7XG4gICAgfVxuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgYXV0b1NjYW4oKSB7XG4gICAgY29uc3Qgc2lkZSA9IHRoaXMuc2NhbkJsYXN0RGF0YVswXTtcbiAgICB0aGlzLmlkU2NhbiA9IG51bGw7XG4gICAgdGhpcy5zaW5nbGVTY2FuKHNpZGUpO1xuICB9XG5cbiAgc2luZ2xlU2NhbihzaWRlOiBhbnkpIHtcbiAgICB0aGlzLnNjYW5UeXBlID0gc2lkZS5zaWRlO1xuICAgIHRoaXMucHJldmlldyA9IG51bGw7XG4gICAgdGhpcy5zZWxlY3RlZFNpZGUgPSBzaWRlO1xuXG4gICAgdGhpcy5zZWxlY3RlZFNpZGUuaW1hZ2UgPSBudWxsO1xuICAgIHRoaXMuZG9jdW1lbnRUeXBlU2VsZWN0ZWQgPSB0cnVlO1xuICAgIHRoaXMuc2NhbkJsYXN0RGF0YVsxXS5kaXNhYmxlZCA9IGZhbHNlO1xuICAgIHRoaXMuY2QuZGV0ZWN0Q2hhbmdlcygpO1xuICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgdGhpcy5vblJlc2l6ZSgpO1xuICAgIH0sIDEwKTtcbiAgfVxuXG4gIHByaXZhdGUgZ2V0SW1nQmFzZTY0KG51bTogYW55KSB7XG4gICAgY29uc29sZS5sb2coJ0dFVCA2NCcpO1xuICAgIHJldHVybiB0aGlzLnNjYW5CbGFzdERhdGFbbnVtXS5pbWFnZS5kYXRhVXJsLnNwbGl0KCcsJylbMV07XG4gIH1cbiAgc2NhbkJsYXN0RmluaXNoKCkge1xuICAgIGNvbnNvbGUudGltZSgndXBsb2FkJyk7XG4gICAgaWYgKHRoaXMudHlwZSA9PT0gJ21vYmlsZScpIHtcbiAgICAgIHRoaXMuYWN0aW9ucy5lbWl0KHsgZGF0YTogdGhpcy5zY2FuQmxhc3REYXRhIH0pO1xuICAgICAgdGhpcy5yZXRha2UoKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhpcy5pZFNjYW4gPSBudWxsO1xuICAgIC8vIGNvbnN0IGxvYWRpbmcgPSB0aGlzLmRpYWxvZ3MubG9hZGluZygpO1xuICAgIHRoaXMuc2NhbmluZyA9IHRydWU7XG4gICAgdGhpcy5jZC5kZXRlY3RDaGFuZ2VzKCk7XG4gICAgY29uc29sZS50aW1lKCdwYXlsb2FkJyk7XG4gICAgY29uc3QgcGF5bG9hZDogYW55ID0ge1xuICAgICAgQWNjZXB0VGVybXNBbmRDb25kaXRpb25zOiB0cnVlLFxuICAgICAgRGF0YUZpZWxkczoge1xuICAgICAgICBGcm9udEltYWdlVHlwZTogJ2Jhc2U2NCcsXG4gICAgICAgIEZyb250SW1hZ2VDcm9wcGVkOiBmYWxzZSxcbiAgICAgICAgQmFja0ltYWdlVHlwZTogJ2Jhc2U2NCcsXG4gICAgICAgIEJhY2tJbWFnZUNyb3BwZWQ6IGZhbHNlLFxuICAgICAgICBGcm9udEltYWdlOiB0aGlzLmdldEltZ0Jhc2U2NCgwKSxcbiAgICAgICAgQmFja0ltYWdlOiB0aGlzLnNjYW5CbGFzdERhdGFbMV0uaW1hZ2UgPyB0aGlzLmdldEltZ0Jhc2U2NCgxKSA6IG51bGwsXG4gICAgICB9LFxuICAgICAgU2V0dGluZ3M6IHtcbiAgICAgICAgU2hvdWxkVmFsaWRhdGU6IHRydWUsXG4gICAgICAgIFNob3VsZFJldHVybkRvY3VtZW50SW1hZ2U6IHRydWUsXG4gICAgICAgIFNob3VsZFJldHVybkZhY2VJZkRldGVjdGVkOiB0cnVlLFxuICAgICAgICBTa2lwSW1hZ2VTaXplQ2hlY2s6IHRydWUsXG4gICAgICAgIENhblN0b3JlSW1hZ2VzOiB0aGlzLnNjYW5Qcm92aWRlci5jYW5TdG9yZUltYWdlcyxcbiAgICAgIH0sXG4gICAgICAvLyBDYWxsQmFja1VybDogJ2h0dHA6Ly9kZW1vOjUwMDAvcmVwb3J0L2V4dHJhY3RlZC8nLFxuICAgIH07XG4gICAgaWYgKCF0aGlzLnNjYW5CbGFzdERhdGFbMV0uaW1hZ2UpIHtcbiAgICAgIHBheWxvYWQuU2V0dGluZ3MuSWdub3JlQmFja0ltYWdlID0gdHJ1ZTtcbiAgICB9XG4gICAgdGhpcy5sb2dEYXRhLlJlcXVlc3QgPSBKU09OLnBhcnNlKEpTT04uc3RyaW5naWZ5KHBheWxvYWQpKTtcblxuICAgIGNvbnNvbGUudGltZUVuZCgncGF5bG9hZCcpO1xuICAgIHRoaXMuX19zdWJzKHRoaXMuc2NhblByb3ZpZGVyLmJsYXN0UG9zdChwYXlsb2FkKSkuc3Vic2NyaWJlKFxuICAgICAgKGRhdGE6IGFueSkgPT4ge1xuICAgICAgICAvL2NvbnNvbGUubG9nKGRhdGEpO1xuICAgICAgICBjb25zdCByZXN1bHRzID0gZGF0YS5EYXRhO1xuICAgICAgICBjb25zb2xlLnRpbWVFbmQoJ3VwbG9hZCcpO1xuICAgICAgICBjb25zb2xlLnRpbWUoJ3BhcnNlJyk7XG4gICAgICAgIC8vIGRhdGEuSW5mb0NvZGUgPSAnMTAwMSc7XG4gICAgICAgIHRoaXMubG9nRGF0YS5SZXNwb25zZSA9IEpTT04ucGFyc2UoSlNPTi5zdHJpbmdpZnkoZGF0YSkpO1xuICAgICAgICAvL2xvYWRpbmcuY2xvc2UoKTtcbiAgICAgICAgdGhpcy5kb2N1bWVudFR5cGVTZWxlY3RlZCA9IHRydWU7XG4gICAgICAgIHRoaXMuc2NhbmluZyA9IGZhbHNlO1xuXG4gICAgICAgIGlmIChkYXRhLkluZm9Db2RlID09PSAnMTAwMScpIHtcbiAgICAgICAgICB0aGlzLmVycm9yID0gdHJ1ZTtcbiAgICAgICAgICBjb25zb2xlLmxvZygnW0VSUk9SXSAxMDAxJyk7XG4gICAgICAgICAgdGhpcy5lcnJvckNvZGUgPSAnMTAwMSc7XG4gICAgICAgICAgLy8gdGhpcy5zY2FuU2lkZSA9IDA7XG5cbiAgICAgICAgICB0aGlzLnByZXZpZXcgPSB0cnVlO1xuICAgICAgICAgIHRoaXMuY2QuZGV0ZWN0Q2hhbmdlcygpO1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBpZiAoZGF0YS5JbmZvQ29kZSA9PT0gJzEwMDInKSB7XG4gICAgICAgICAgdGhpcy5lcnJvciA9IHRydWU7XG4gICAgICAgICAgY29uc29sZS5sb2coJ1tFUlJPUl0gMTAwMicpO1xuICAgICAgICAgIHRoaXMuZXJyb3JDb2RlID0gJzEwMDInO1xuICAgICAgICAgIC8vIHRoaXMuc2NhblNpZGUgPSAwO1xuXG4gICAgICAgICAgdGhpcy5wcmV2aWV3ID0gdHJ1ZTtcbiAgICAgICAgICB0aGlzLmNkLmRldGVjdENoYW5nZXMoKTtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHJlc3VsdHMgJiYgZGF0YS5NZXRhZGF0YS5sZW5ndGggPiAwICYmIGRhdGEuSW5mb0NvZGUgPT09ICcxMDAwJykge1xuICAgICAgICAgIGNvbnNvbGUubG9nKCdFeHRyYWN0aW9uIHRpbWUnLCBkYXRhLkFuYWx5c2lzVGltZSk7XG4gICAgICAgICAgdGhpcy56b25lLnJ1bigoKSA9PiB7XG4gICAgICAgICAgICBpZiAoZGF0YS5JbWFnZURhdGE/LkRvY3VtZW50cykge1xuICAgICAgICAgICAgICBjb25zdCB7IERvY3VtZW50cyB9ID0gZGF0YS5JbWFnZURhdGE7XG4gICAgICAgICAgICAgIHRoaXMuaW1hZ2VzID0gRG9jdW1lbnRzLm1hcCgoaW1hZ2U6IGFueSwgaTogbnVtYmVyKSA9PiB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHsgZGF0YTogJ2RhdGE6aW1hZ2UvanBlZztiYXNlNjQsJyArIERvY3VtZW50c1tpXSB9O1xuICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdGhpcy5yZXN1bHQgPSB0aGlzLnNjYW5Qcm92aWRlci5wYXJzZUJsYXN0KHJlc3VsdHMpO1xuICAgICAgICAgICAgY29uc29sZS5sb2coJ1JFUycsIHRoaXMucmVzdWx0KTtcbiAgICAgICAgICAgIHRoaXMuY2QuZGV0ZWN0Q2hhbmdlcygpO1xuXG4gICAgICAgICAgICB0aGlzLm1vZGVsID0gdGhpcy5yZXN1bHQubW9kZWw7XG4gICAgICAgICAgICBpZiAoZGF0YS5JbWFnZURhdGE/LkZhY2VJbWFnZSkge1xuICAgICAgICAgICAgICB0aGlzLm1vZGVsLl9hdmF0YXIgPVxuICAgICAgICAgICAgICAgICdkYXRhOmltYWdlL2pwZWc7YmFzZTY0LCcgKyBkYXRhLkltYWdlRGF0YT8uRmFjZUltYWdlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29uc29sZS5sb2coJ01PREVMJywgdGhpcy5tb2RlbCk7XG4gICAgICAgICAgICB0aGlzLmNkLmRldGVjdENoYW5nZXMoKTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBjb25zb2xlLmxvZygnRVJST1InKTtcbiAgICAgICAgICAvLyB0aGlzLnNjYW5TaWRlID0gMDtcbiAgICAgICAgICB0aGlzLmVycm9yID0gdHJ1ZTtcbiAgICAgICAgICB0aGlzLnByZXZpZXcgPSB0cnVlO1xuICAgICAgICAgIHRoaXMuY2QuZGV0ZWN0Q2hhbmdlcygpO1xuICAgICAgICAgIC8vIHRoaXMuZG9jdW1lbnRUeXBlU2VsZWN0ZWQgPSBmYWxzZTtcblxuICAgICAgICAgIC8vIHRoaXMucmV0cnkoKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuY2QuZGV0ZWN0Q2hhbmdlcygpO1xuICAgICAgICBjb25zb2xlLnRpbWVFbmQoJ3BhcnNlJyk7XG4gICAgICB9LFxuICAgICAgKGVycikgPT4ge1xuICAgICAgICAvLyBsb2FkaW5nLmNsb3NlKCk7XG4gICAgICAgIC8vIHRoaXMuc2NhblNpZGUgPSAwO1xuICAgICAgICB0aGlzLmVycm9yID0gdHJ1ZTtcbiAgICAgICAgdGhpcy5wcmV2aWV3ID0gdHJ1ZTtcbiAgICAgICAgdGhpcy5kb2N1bWVudFR5cGVTZWxlY3RlZCA9IHRydWU7XG4gICAgICAgIHRoaXMuc2NhbmluZyA9IGZhbHNlO1xuICAgICAgfVxuICAgICk7XG4gIH1cblxuICByZXRyeSgpIHtcbiAgICB0aGlzLnByZXZpZXcgPSBmYWxzZTtcbiAgICB0aGlzLnZhbGlkYXRpb24gPSBmYWxzZTtcbiAgICB0aGlzLmVycm9yQ29kZSA9ICcxMDAwJztcbiAgICB0aGlzLnJlc3VsdCA9IGZhbHNlO1xuICAgIGlmICh0aGlzLmVycm9yKSB7XG4gICAgICB0aGlzLmRvY3VtZW50VHlwZVNlbGVjdGVkID0gZmFsc2U7XG4gICAgICB0aGlzLnNjYW5CbGFzdERhdGEuZm9yRWFjaCgoZWxlbWVudDogYW55KSA9PiB7XG4gICAgICAgIGVsZW1lbnQuaW1hZ2UgPSBudWxsO1xuICAgICAgfSk7XG4gICAgfVxuICAgIHRoaXMuZXJyb3IgPSBmYWxzZTtcbiAgICB0aGlzLmF1dG9TY2FuKCk7XG4gICAgdGhpcy5jZC5kZXRlY3RDaGFuZ2VzKCk7XG4gIH1cbiAgcHVibGljIHRyaWdnZXJTbmFwc2hvdCgpOiB2b2lkIHtcbiAgICB0aGlzLnRyaWdnZXIubmV4dCgwKTtcbiAgfVxuXG4gIHB1YmxpYyByZXRha2UoKSB7XG4gICAgdGhpcy52YWxpZGF0aW9uID0gZmFsc2U7XG4gICAgdGhpcy5wcmV2aWV3ID0gZmFsc2U7XG4gICAgdGhpcy5lcnJvciA9IGZhbHNlO1xuICAgIHRoaXMucmVzdWx0ID0gZmFsc2U7XG4gICAgdGhpcy5zY2FuU2lkZSA9IDA7XG5cbiAgICB0aGlzLmltYWdlVmVyaWZpZWQgPSBmYWxzZTtcbiAgICB0aGlzLnNjYW5EYXRhcyA9IFtdO1xuICAgIHRoaXMuc2NhbmluZyA9IGZhbHNlO1xuICAgIHRoaXMuaW1hZ2VzID0gW107XG4gICAgdGhpcy5zY2FuSW5Qcm9ncmVzcyA9IGZhbHNlO1xuXG4gICAgdGhpcy5kb2N1bWVudFR5cGVTZWxlY3RlZCA9IGZhbHNlO1xuICAgIHRoaXMuc2NhbkJsYXN0RGF0YS5mb3JFYWNoKChtOiBhbnkpID0+IHtcbiAgICAgIG0uaW1hZ2UgPSBudWxsO1xuICAgIH0pO1xuXG4gICAgdGhpcy5hdXRvU2NhbigpO1xuXG4gICAgdGhpcy5jZC5kZXRlY3RDaGFuZ2VzKCk7XG4gIH1cblxuICB1c2UoKSB7XG4gICAgLy8gc2F2ZSBpbWFnZXM/P1xuXG4gICAgaWYgKHRoaXMuc2NhblByb3ZpZGVyLmNhblN0b3JlSW1hZ2VzKSB7XG4gICAgICB0aGlzLmxvZ0RhdGEuRXhwZWN0ZWRPdXRwdXQgPSBKU09OLnBhcnNlKEpTT04uc3RyaW5naWZ5KHRoaXMubW9kZWwpKTtcbiAgICAgIGlmICh0aGlzLmxvZ0RhdGEuRXhwZWN0ZWRPdXRwdXQ/Ll9hdmF0YXIpIHtcbiAgICAgICAgZGVsZXRlIHRoaXMubG9nRGF0YS5FeHBlY3RlZE91dHB1dC5fYXZhdGFyO1xuICAgICAgfVxuICAgICAgdGhpcy5fX3N1YnModGhpcy5zY2FuUHJvdmlkZXIuc2VuZExvZyh0aGlzLmxvZ0RhdGEpKS5zdWJzY3JpYmUoKTtcbiAgICAgIGNvbnNvbGUubG9nKHRoaXMubG9nRGF0YSk7XG4gICAgfVxuICAgIHRoaXMuZGlhbG9nUmVmPy5jbG9zZSh7XG4gICAgICBtb2RlbDogdGhpcy5tb2RlbCxcbiAgICAgIGltYWdlczogdGhpcy5pbWFnZXMsXG4gICAgfSk7XG4gIH1cbiAgc2VsZmllKCkge1xuICAgIHRoaXMuZGlhbG9nc1xuICAgICAgLnNjYW5TZWxmaWUoeyBhdmF0YXI6IHRoaXMubW9kZWwuX2F2YXRhciB9KVxuICAgICAgLmFmdGVyQ2xvc2VkKClcbiAgICAgIC5zdWJzY3JpYmUoKHJlc3A6IGFueSkgPT4ge1xuICAgICAgICBpZiAocmVzcCkge1xuICAgICAgICAgIGNvbnNvbGUubG9nKHJlc3ApO1xuICAgICAgICAgIGlmICh0aGlzLnNjYW5Qcm92aWRlci5lbmFibGVWZXJpZmljYXRpb24pIHtcbiAgICAgICAgICAgIHRoaXMuaW1hZ2VWZXJpZmllZCA9IHRydWU7XG4gICAgICAgICAgfVxuICAgICAgICAgIHRoaXMubW9kZWwuX2F2YXRhciA9IHJlc3AuaW1hZ2VBc0RhdGFVcmw7XG4gICAgICAgICAgdGhpcy5jZC5kZXRlY3RDaGFuZ2VzKCk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICB9XG5cbiAgdmlkZW9SZWFkeShldmVudDogYm9vbGVhbikge1xuICAgIHRoaXMuY2FtZXJhUmVhZHkgPSBldmVudDtcbiAgICBpZiAodGhpcy5jYW1lcmFSZWFkeSAmJiAhdGhpcy5zY2FuSW5Qcm9ncmVzcykge1xuICAgICAgdGhpcy5zY2FuSW5Qcm9ncmVzcyA9IHRydWU7XG5cbiAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICB0aGlzLnRyaWdnZXIubmV4dChuZXcgRGF0ZSgpLmdldFRpbWUoKSk7XG4gICAgICB9LCAxMDAwKTtcbiAgICB9XG4gIH1cbn1cbiIsIjxzZWN0aW9uICpuZ0lmPVwicmVzdWx0XCI+XG4gIDxuZ3gtc2Nhbi1yZXN1bHRzXG4gICAgKGFjdGlvbik9XCJzZWxmaWUoKVwiXG4gICAgW2Zvcm1dPVwiZm9ybVwiXG4gICAgW21vZGVsXT1cIm1vZGVsXCJcbiAgICBbaW1hZ2VzXT1cImltYWdlc1wiXG4gID48L25neC1zY2FuLXJlc3VsdHM+XG5cbiAgPGZvb3Rlcj5cbiAgICA8ZGl2IGNsYXNzPVwiYWN0aW9uc1wiPlxuICAgICAgPGJ1dHRvbiBmeEZsZXggY2xhc3M9XCJtci00XCIgbWF0LXJhaXNlZC1idXR0b24gKGNsaWNrKT1cInJldGFrZSgpXCI+XG4gICAgICAgIHt7IFwicG1zLmRpYWxvZ3MuY29tcG9uZW50cy5zY2FuUHJvZmlsZS5yZVRha2VcIiB8IHRyYW5zbGF0ZSB9fVxuICAgICAgPC9idXR0b24+XG4gICAgICA8YnV0dG9uXG4gICAgICAgIFtkaXNhYmxlZF09XCJlcnJvciB8fCBmb3JtLmludmFsaWRcIlxuICAgICAgICBmeEZsZXhcbiAgICAgICAgY2xhc3M9XCJtbC00XCJcbiAgICAgICAgbWF0LXJhaXNlZC1idXR0b25cbiAgICAgICAgKGNsaWNrKT1cInVzZSgpXCJcbiAgICAgID5cbiAgICAgICAge3sgXCJwbXMuZGlhbG9ncy5jb21wb25lbnRzLnNjYW5Qcm9maWxlLnVzZURhdGFcIiB8IHRyYW5zbGF0ZSB9fVxuICAgICAgPC9idXR0b24+XG4gICAgPC9kaXY+XG4gIDwvZm9vdGVyPlxuPC9zZWN0aW9uPlxuXG48c2VjdGlvbiAqbmdJZj1cIiFyZXN1bHQgJiYgZG9jdW1lbnRUeXBlU2VsZWN0ZWRcIj5cbiAgPGRpdiAjd3JhcGVyIGNsYXNzPVwid3JhcGVyXCI+XG4gICAgPGRpdiBjbGFzcz1cImxvYWRpbmdcIiAqbmdJZj1cIiFjYW1lcmFSZWFkeSAmJiAhcHJldmlld1wiPlxuICAgICAgPG1hdC1wcm9ncmVzcy1iYXIgbW9kZT1cImluZGV0ZXJtaW5hdGVcIj48L21hdC1wcm9ncmVzcy1iYXI+XG4gICAgPC9kaXY+XG5cbiAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiIWVycm9yXCI+XG4gICAgICA8YXBwLXdlYmNhbVxuICAgICAgICAqbmdJZj1cIiFwcmV2aWV3ICYmICFzY2FuaW5nXCJcbiAgICAgICAgY2xhc3M9XCJtYWluXCJcbiAgICAgICAgW2ltYWdlUXVhbGl0eV09XCIxXCJcbiAgICAgICAgI3dlYmNhbVxuICAgICAgICBmeEZsZXhcbiAgICAgICAgdHlwZT1cImRvY3VtZW50XCJcbiAgICAgICAgW3RyaWdnZXJdPVwidHJpZ2dlclwiXG4gICAgICAgIFtpbWFnZUhhbmRsZXJdPVwiaW1hZ2VIYW5kbGVyXCJcbiAgICAgICAgKGltYWdlQ2FwdHVyZSk9XCJoYW5kbGVJbWFnZSgkZXZlbnQpXCJcbiAgICAgICAgW2FsbG93Q2FtZXJhU3dpdGNoXT1cImFsbG93Q2FtZXJhU3dpdGNoXCJcbiAgICAgICAgW3ZpZGVvT3B0aW9uc109XCJ2aWRlb09wdGlvbnNcIlxuICAgICAgICBbc3dpdGNoQ2FtZXJhXT1cImNhbWVyYVByb3ZpZGVyLm5leHRXZWJjYW1PYnNlcnZhYmxlXCJcbiAgICAgICAgKGNhbWVyYVN3aXRjaGVkKT1cImNhbWVyYVdhc1N3aXRjaGVkKCRldmVudClcIlxuICAgICAgICAoaW5pdEVycm9yKT1cImhhbmRsZUluaXRFcnJvcigkZXZlbnQpXCJcbiAgICAgICAgW3dpZHRoXT1cIndpZHRoXCJcbiAgICAgICAgW2hlaWdodF09XCJoZWlnaHRcIlxuICAgICAgICAoZGVzdHJveWVkKT1cImNhbWVyYU9mZigkZXZlbnQpXCJcbiAgICAgICAgKHZpZGVvUmVhZHkpPVwidmlkZW9SZWFkeSgkZXZlbnQpXCJcbiAgICAgID5cbiAgICAgIDwvYXBwLXdlYmNhbT5cbiAgICA8L25nLWNvbnRhaW5lcj5cbiAgICA8ZGl2XG4gICAgICBmeExheW91dD1cInJvd1wiXG4gICAgICBmeEZsZXhcbiAgICAgIGNsYXNzPVwicHJldmlld0RhdGFcIlxuICAgICAgKm5nSWY9XCJwcmV2aWV3XCJcbiAgICAgIHN0eWxlPVwiei1pbmRleDogMjA7IHBvc2l0aW9uOiBhYnNvbHV0ZTsgd2lkdGg6IDEwMCU7IGhlaWdodDogMTAwJVwiXG4gICAgPlxuICAgICAgPGRpdiBjbGFzcz1cInAtMTYgZXJyb3JcIiAqbmdJZj1cImVycm9yXCI+XG4gICAgICAgIDxkaXY+XG4gICAgICAgICAgPGRpdiBjbGFzcz1cInRpdGxlXCIgZnhMYXlvdXQ9XCJyb3dcIiBmeExheW91dEFsaWduPVwic3RhcnQgY2VudGVyXCI+XG4gICAgICAgICAgICA8bWF0LWljb24+ZXJyb3Jfb3V0bGluZTwvbWF0LWljb25cbiAgICAgICAgICAgID48c3BhbiBjbGFzcz1cIm1sLThcIj57e1xuICAgICAgICAgICAgICBcInBtcy5kaWFsb2dzLmNvbXBvbmVudHMuc2NhblByb2ZpbGUudW5hYmxlVG9EZXRlY3RJZFwiIHwgdHJhbnNsYXRlXG4gICAgICAgICAgICB9fTwvc3Bhbj5cbiAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJlcnJvckNvZGUgPT09ICcxMDAxJ1wiPlxuICAgICAgICAgICAgPGRpdj5cbiAgICAgICAgICAgICAgQ291bGQgbm90IGNsYXNzaWZ5IHRoZSBnaXZlbiBvYmplY3QgYXMgYSBzdXBwb3J0ZWQgZG9jdW1lbnQuXG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiZXJyb3JDb2RlID09PSAnMTAwMidcIj5cbiAgICAgICAgICAgIDxkaXY+XG4gICAgICAgICAgICAgIFNvbWV0aGluZyBpcyB3cm9uZyB3aXRoIGV4dHJhY3Rpb24gZGF0YS4gUGxlYXNlIHRyeSBhZ2Fpbi5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuXG4gICAgICAgICAgPHVsICpuZ0lmPVwiZXJyb3JDb2RlID09PSAnMTAwMCdcIj5cbiAgICAgICAgICAgIDxsaT5cbiAgICAgICAgICAgICAge3tcbiAgICAgICAgICAgICAgICBcInBtcy5kaWFsb2dzLmNvbXBvbmVudHMuc2NhblByb2ZpbGUucGxhY2VJZENsb3NlVG9EZXZpY2VcIlxuICAgICAgICAgICAgICAgICAgfCB0cmFuc2xhdGVcbiAgICAgICAgICAgICAgfX1cbiAgICAgICAgICAgIDwvbGk+XG4gICAgICAgICAgICA8bGk+XG4gICAgICAgICAgICAgIHt7XG4gICAgICAgICAgICAgICAgXCJwbXMuZGlhbG9ncy5jb21wb25lbnRzLnNjYW5Qcm9maWxlLmVuc3VyZVN1ZmZpY2llbnRMaWdodFwiXG4gICAgICAgICAgICAgICAgICB8IHRyYW5zbGF0ZVxuICAgICAgICAgICAgICB9fVxuICAgICAgICAgICAgPC9saT5cbiAgICAgICAgICAgIDxsaT5cbiAgICAgICAgICAgICAge3tcbiAgICAgICAgICAgICAgICBcInBtcy5kaWFsb2dzLmNvbXBvbmVudHMuc2NhblByb2ZpbGUuaG9sZERvY3VtZW50U3RlYWR5XCJcbiAgICAgICAgICAgICAgICAgIHwgdHJhbnNsYXRlXG4gICAgICAgICAgICAgIH19XG4gICAgICAgICAgICA8L2xpPlxuICAgICAgICAgICAgPGxpPlxuICAgICAgICAgICAgICB7e1xuICAgICAgICAgICAgICAgIFwicG1zLmRpYWxvZ3MuY29tcG9uZW50cy5zY2FuUHJvZmlsZS5tYWtlU3VyZUFsbEVkZ2VzT2ZUaGVJZEFyZVZpc2libGVcIlxuICAgICAgICAgICAgICAgICAgfCB0cmFuc2xhdGVcbiAgICAgICAgICAgICAgfX1cbiAgICAgICAgICAgIDwvbGk+XG4gICAgICAgICAgICA8bGk+XG4gICAgICAgICAgICAgIHt7XG4gICAgICAgICAgICAgICAgXCJwbXMuZGlhbG9ncy5jb21wb25lbnRzLnNjYW5Qcm9maWxlLm1ha2VTdXJlVGhlcmVBcmVOb0dsYXJlQW5kU2hhZG93c09uVGhlSWRcIlxuICAgICAgICAgICAgICAgICAgfCB0cmFuc2xhdGVcbiAgICAgICAgICAgICAgfX1cbiAgICAgICAgICAgIDwvbGk+XG4gICAgICAgICAgPC91bD5cbiAgICAgICAgPC9kaXY+XG4gICAgICA8L2Rpdj5cblxuICAgICAgPGRpdlxuICAgICAgICBjbGFzcz1cInNjYW5QcmV2aWV3XCJcbiAgICAgICAgZnhGbGV4XG4gICAgICAgIGZ4TGF5b3V0PVwiY29sdW1uXCJcbiAgICAgICAgKm5nSWY9XCIhZXJyb3IgJiYgIXNjYW5pbmdcIlxuICAgICAgPlxuICAgICAgICA8IS0tIDxkaXYgY2xhc3M9XCJweS0xNlwiIHN0eWxlPVwiZm9udC1zaXplOiAxNnB4XCI+XG4gICAgICAgICAge3tcbiAgICAgICAgICAgIFwicG1zLmRpYWxvZ3MuY29tcG9uZW50cy5zY2FuUHJvZmlsZS5lbnN1cmVBbGxUZXh0c0FyZVZpc2libGVcIlxuICAgICAgICAgICAgICB8IHRyYW5zbGF0ZVxuICAgICAgICAgIH19XG4gICAgICAgIDwvZGl2PiAtLT5cbiAgICAgICAgPGRpdlxuICAgICAgICAgIGZ4RmxleFxuICAgICAgICAgIGNsYXNzPVwiaW1hZ2VcIlxuICAgICAgICAgIFtzdHlsZS5iYWNrZ3JvdW5kLWltYWdlXT1cIid1cmwoJyArIHByZXZpZXcgKyAnKSdcIlxuICAgICAgICA+PC9kaXY+XG4gICAgICA8L2Rpdj5cbiAgICA8L2Rpdj5cbiAgPC9kaXY+XG5cbiAgPGZvb3Rlcj5cbiAgICA8ZGl2XG4gICAgICBjbGFzcz1cImRpc3BsYXlJbmZvXCJcbiAgICAgIG5nQ2xhc3MubHQtc209XCJtb2JpbGVcIlxuICAgICAgKm5nSWY9XCIhcHJldmlldyAmJiBjYW1lcmFSZWFkeVwiXG4gICAgPlxuICAgICAge3sgZGlzcGxheUluZm8gfX1cbiAgICA8L2Rpdj5cbiAgICA8IS0tIDxkaXYgc3R5bGU9XCJoZWlnaHQ6IDI2cHhcIj5cbiAgICAgIDxkaXZcbiAgICAgICAgc3R5bGU9XCJ0ZXh0LWFsaWduOiBjZW50ZXI7IGZvbnQtc2l6ZTogMThweFwiXG4gICAgICAgICpuZ0lmPVwiaWRTY2FuICYmICFwcmV2aWV3ICYmIGNhbWVyYVJlYWR5XCJcbiAgICAgID5cbiAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImlkU2NhbiA9PT0gJ0JBQ0snXCI+XG4gICAgICAgICAgVHVybiBkb2N1bWVudCBhbmQ6XG4gICAgICAgICAge3sgXCJwbXMuZGlhbG9ncy5jb21wb25lbnRzLnNjYW5Qcm9maWxlLmNhcHR1cmVCYWNrXCIgfCB0cmFuc2xhdGUgfX1cbiAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJpZFNjYW4gPT09ICdGUk9OVCdcIj5cbiAgICAgICAgICBUdXJuIGRvY3VtZW50IGFuZDpcbiAgICAgICAgICB7eyBcInBtcy5kaWFsb2dzLmNvbXBvbmVudHMuc2NhblByb2ZpbGUuY2FwdHVyZUZyb250XCIgfCB0cmFuc2xhdGUgfX1cbiAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICA8L2Rpdj5cbiAgICA8L2Rpdj4gLS0+XG5cbiAgICA8ZGl2IGNsYXNzPVwiYWN0aW9uc1wiICpuZ0lmPVwicHJldmlld1wiPlxuICAgICAgPGJ1dHRvbiBmeEZsZXggY2xhc3M9XCJtci00XCIgbWF0LXJhaXNlZC1idXR0b24gKGNsaWNrKT1cInJldHJ5KClcIj5cbiAgICAgICAge3sgXCJwbXMuZGlhbG9ncy5jb21wb25lbnRzLnNjYW5Qcm9maWxlLnJldHJ5XCIgfCB0cmFuc2xhdGUgfX1cbiAgICAgIDwvYnV0dG9uPlxuXG4gICAgICA8YnV0dG9uXG4gICAgICAgIFtkaXNhYmxlZF09XCJlcnJvclwiXG4gICAgICAgIGZ4RmxleFxuICAgICAgICBjbGFzcz1cIm1sLTRcIlxuICAgICAgICBtYXQtcmFpc2VkLWJ1dHRvblxuICAgICAgICAoY2xpY2spPVwiY29udGludWUoKVwiXG4gICAgICA+XG4gICAgICAgIHt7XG4gICAgICAgICAgXCJwbXMuZGlhbG9ncy5jb21wb25lbnRzLnNjYW5Qcm9maWxlLmNvbnRpbnVlV2l0aFNlbGVjdGVkSW1hZ2VcIlxuICAgICAgICAgICAgfCB0cmFuc2xhdGVcbiAgICAgICAgfX1cbiAgICAgIDwvYnV0dG9uPlxuICAgIDwvZGl2PlxuICA8L2Zvb3Rlcj5cbjwvc2VjdGlvbj5cbiJdfQ==