@smarterplan/ngx-smarterplan-locations 0.4.19 → 0.4.21

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 (39) hide show
  1. package/README.md +24 -24
  2. package/esm2022/lib/components/carousel/carousel.component.mjs +3 -3
  3. package/esm2022/lib/components/chevron/chevron.component.mjs +3 -3
  4. package/esm2022/lib/components/detail-location/detail-location.component.mjs +40 -4
  5. package/esm2022/lib/components/form-location/form-location.component.mjs +3 -3
  6. package/esm2022/lib/components/images/images.component.mjs +3 -3
  7. package/esm2022/lib/components/landmark-picker/landmark-picker.component.mjs +3 -3
  8. package/esm2022/lib/components/locations/locations.component.mjs +19 -4
  9. package/esm2022/lib/components/locations/map/map-popup/map-popup.component.mjs +3 -3
  10. package/esm2022/lib/components/locations/map/map.component.mjs +3 -3
  11. package/esm2022/lib/components/models3d/models3d.component.mjs +295 -0
  12. package/esm2022/lib/components/plan-legend/plan-legend.component.mjs +3 -3
  13. package/esm2022/lib/components/plans/calibration/calibration.component.mjs +3 -3
  14. package/esm2022/lib/components/plans/edit-plan/edit-plan.component.mjs +3 -3
  15. package/esm2022/lib/components/plans/plans.component.mjs +3 -3
  16. package/esm2022/lib/components/tab-navigation/tab-navigation.component.mjs +3 -3
  17. package/esm2022/lib/components/visits/visits.component.mjs +45 -12
  18. package/esm2022/lib/components/zones/add-audio-zone/add-audio-zone.component.mjs +3 -3
  19. package/esm2022/lib/components/zones/add-zone/add-zone.component.mjs +3 -3
  20. package/esm2022/lib/components/zones/add-zone/selection/selection.component.mjs +3 -3
  21. package/esm2022/lib/components/zones/add-zone/sweep-plan-selection/sweep-plan-selection.component.mjs +3 -3
  22. package/esm2022/lib/components/zones/zones.component.mjs +3 -3
  23. package/esm2022/lib/helper.service.mjs +1 -1
  24. package/esm2022/lib/ngx-smarterplan-location-routing.module.mjs +3 -1
  25. package/esm2022/lib/ngx-smarterplan-locations.module.mjs +4 -1
  26. package/esm2022/lib/ngx-smarterplan-locations.service.mjs +1 -1
  27. package/esm2022/lib/pipes/count-audio-sweeps.pipe.mjs +1 -1
  28. package/esm2022/lib/radio-button/radio-button.component.mjs +3 -3
  29. package/esm2022/public-api.mjs +1 -1
  30. package/fesm2022/smarterplan-ngx-smarterplan-locations.mjs +424 -56
  31. package/fesm2022/smarterplan-ngx-smarterplan-locations.mjs.map +1 -1
  32. package/lib/components/detail-location/detail-location.component.d.ts +13 -0
  33. package/lib/components/locations/locations.component.d.ts +10 -0
  34. package/lib/components/locations/map/map.component.d.ts +2 -2
  35. package/lib/components/models3d/models3d.component.d.ts +84 -0
  36. package/lib/components/visits/visits.component.d.ts +8 -3
  37. package/lib/components/zones/add-zone/sweep-plan-selection/sweep-plan-selection.component.d.ts +0 -1
  38. package/lib/ngx-smarterplan-locations.module.d.ts +27 -26
  39. package/package.json +2 -2
@@ -15,6 +15,7 @@ import * as i8 from "../chevron/chevron.component";
15
15
  export class VisitsComponent {
16
16
  fb;
17
17
  matterportImportService;
18
+ threejsImportService;
18
19
  captureService;
19
20
  nodeService;
20
21
  spaceService;
@@ -44,9 +45,10 @@ export class VisitsComponent {
44
45
  errorForm = false;
45
46
  isProcessing = false;
46
47
  destroy$ = new Subject();
47
- constructor(fb, matterportImportService, captureService, nodeService, spaceService, route, modalService, visitService, validatorsService, translate, navigatorService, router) {
48
+ constructor(fb, matterportImportService, threejsImportService, captureService, nodeService, spaceService, route, modalService, visitService, validatorsService, translate, navigatorService, router) {
48
49
  this.fb = fb;
49
50
  this.matterportImportService = matterportImportService;
51
+ this.threejsImportService = threejsImportService;
50
52
  this.captureService = captureService;
51
53
  this.nodeService = nodeService;
52
54
  this.spaceService = spaceService;
@@ -120,7 +122,10 @@ export class VisitsComponent {
120
122
  .getVisitsForSpaceForUser(this.spaceId)
121
123
  .then((visits) => {
122
124
  if (visits) {
123
- this.visits = visits;
125
+ // 3D models share this storage but have their own screen, so listing them here
126
+ // too showed every model twice. They can still be created from this form; they
127
+ // just belong to the other tab once they exist.
128
+ this.visits = visits.filter((visit) => visit.viewer !== CaptureViewer.THREEJS);
124
129
  }
125
130
  });
126
131
  }
@@ -133,6 +138,7 @@ export class VisitsComponent {
133
138
  model3D: [input.model3d, [Validators.required]],
134
139
  viewer: input.viewer ? input.viewer : CaptureViewer.MATTERPORT,
135
140
  surface: input.surface ? input.surface : null,
141
+ threeJsPlacement: input.captureMetadata ?? null,
136
142
  });
137
143
  this.captureDate = input.takenAt;
138
144
  }
@@ -142,9 +148,21 @@ export class VisitsComponent {
142
148
  viewer: CaptureViewer.MATTERPORT,
143
149
  surface: null,
144
150
  name: [null, [Validators.required]],
151
+ threeJsPlacement: null,
145
152
  });
146
153
  }
147
154
  }
155
+ /** True while the form is set to create a Three.js visit, which asks for different fields. */
156
+ get isThreeJsVisit() {
157
+ return this.visitForm?.value.viewer === CaptureViewer.THREEJS;
158
+ }
159
+ /** Validation error for the 3D model field, or null. Only meaningful for Three.js visits. */
160
+ get modelKeyError() {
161
+ if (!this.isThreeJsVisit) {
162
+ return null;
163
+ }
164
+ return this.threejsImportService.validateModelKey(this.visitForm.value.model3D);
165
+ }
148
166
  async onToggleDetail(index) {
149
167
  this.visitIndexDetails = index === this.visitIndexDetails ? -1 : index;
150
168
  this.imagesUploaded = await this.matterportImportService.getUploadedImageCount(this.visits[index].model3d);
@@ -164,6 +182,13 @@ export class VisitsComponent {
164
182
  this.errorForm = true;
165
183
  return;
166
184
  }
185
+ // A Three.js visit points at a file rather than a Matterport model, so the reference is
186
+ // checked before anything is written - otherwise a typo creates zones and navigation for a
187
+ // model that 404s the first time someone opens the visit.
188
+ if (this.modelKeyError) {
189
+ this.errorForm = true;
190
+ return;
191
+ }
167
192
  this.errorForm = false;
168
193
  const formValue = this.visitForm.value;
169
194
  const capture = {
@@ -171,6 +196,7 @@ export class VisitsComponent {
171
196
  takenAt: this.captureDate,
172
197
  surface: formValue.surface,
173
198
  spaceID: this.currentSpace.id,
199
+ metadata: this.isThreeJsVisit ? formValue.threeJsPlacement : null,
174
200
  };
175
201
  if (this.isEditing) {
176
202
  capture.id = formValue.captureID;
@@ -194,7 +220,7 @@ export class VisitsComponent {
194
220
  createdNode = await this.nodeService.createNode(node);
195
221
  }
196
222
  });
197
- this.launchImport(formValue.model3D, formValue.surface, createdNode, false)
223
+ this.launchImport(formValue.model3D, formValue.surface, createdNode, formValue.viewer, false, false, formValue.threeJsPlacement)
198
224
  .then((success) => {
199
225
  this.modalReference.close('import ended with success');
200
226
  })
@@ -246,7 +272,7 @@ export class VisitsComponent {
246
272
  }
247
273
  return `with: ${reason}`;
248
274
  }
249
- async launchImport(model3D, surface, node, imagesOnly = false, overrideExisting = false) {
275
+ async launchImport(model3D, surface, node, viewerType, imagesOnly = false, overrideExisting = false, placementMetadata = null) {
250
276
  this.modalReference = this.modalService.open(this.content, {
251
277
  ariaLabelledBy: "modal-basic-title",
252
278
  });
@@ -260,8 +286,15 @@ export class VisitsComponent {
260
286
  this.cancelImport();
261
287
  });
262
288
  try {
263
- await this.matterportImportService.initSdkForModel(model3D);
264
- await this.matterportImportService.importData(this.spaceId, surface, imagesOnly, node, overrideExisting);
289
+ if (viewerType === CaptureViewer.THREEJS) {
290
+ // Route the import to the new Three.js Import Service
291
+ await this.threejsImportService.importData(this.spaceId, surface, imagesOnly, node, overrideExisting, placementMetadata);
292
+ }
293
+ else {
294
+ // Route the import to the existing Matterport Import Service
295
+ await this.matterportImportService.initSdkForModel(model3D);
296
+ await this.matterportImportService.importData(this.spaceId, surface, imagesOnly, node, overrideExisting);
297
+ }
265
298
  this.modalReference.close();
266
299
  }
267
300
  catch (error) {
@@ -275,19 +308,19 @@ export class VisitsComponent {
275
308
  this.resetVisits();
276
309
  }
277
310
  onImportImages(visit, overrideExisting) {
278
- this.launchImport(visit.model3d, null, visit.node.id, true, overrideExisting);
311
+ this.launchImport(visit.model3d, null, visit.node.id, visit.viewer, true, overrideExisting, visit.captureMetadata);
279
312
  }
280
313
  isFormError(control) {
281
314
  return control && control.invalid && this.errorForm;
282
315
  }
283
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: VisitsComponent, deps: [{ token: i1.UntypedFormBuilder }, { token: i2.MatterportImportService }, { token: i2.CaptureService }, { token: i2.NodeService }, { token: i2.SpaceService }, { token: i3.ActivatedRoute }, { token: i4.NgbModal }, { token: i2.VisitService }, { token: i2.ValidatorsService }, { token: i5.TranslateService }, { token: i2.NavigatorService }, { token: i3.Router }], target: i0.ɵɵFactoryTarget.Component });
284
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: VisitsComponent, selector: "lib-visits", viewQueries: [{ propertyName: "content", first: true, predicate: ["content"], descendants: true }], ngImport: i0, template: "<div class=\"container-fluid\" class=\"dashboard-tab\">\r\n <div class=\"m-3\">\r\n <lib-tab-navigation [menuItems]='menuItems' (onGoBack)=\"onGoBack()\"></lib-tab-navigation>\r\n </div>\r\n\r\n <div class=\"row main-form-container\">\r\n <div class=\"col-md-6 form-container\">\r\n <ul class=\"list-group list-group-flush\" *ngIf=\"!visitForm\">\r\n <li class=\"list-group-item list-group-item-action\" *ngFor=\"let visit of visits; index as index\">\r\n <div class=\"d-flex justify-content-between align-items-center\" (click)=\"onToggleDetail(index)\">\r\n {{visit.name ? visit.name : visit.model3d }}\r\n <lib-chevron [conditionShowing]=\"index==visitIndexDetails\"></lib-chevron>\r\n </div>\r\n <div *ngIf=\"index==visitIndexDetails\">\r\n <ul class=\"list-group list-group-flush\">\r\n <li class=\"list-group-item bg-transparent\">{{'Name' | translate}} : {{ visit.name ?\r\n visit.name : \"Not provided\" | translate}}</li>\r\n <li class=\"list-group-item bg-transparent\">{{'3D Model' | translate}} : {{ visit.model3d }}\r\n </li>\r\n <li class=\"list-group-item bg-transparent\">{{'Surface' | translate}}, m<sup>2</sup>: {{\r\n visit.surface ?\r\n visit.surface : 'Not provided' | translate}}</li>\r\n <li class=\"list-group-item bg-transparent\">{{'Viewer' | translate}} : {{ visit.viewer }}\r\n </li>\r\n <li class=\"list-group-item bg-transparent\">{{'Date of capture' | translate}} : {{\r\n visit.takenAt | timeDateString | async}}\r\n <li class=\"list-group-item bg-transparent\">{{'Images are imported' | translate}} : {{\r\n imagesUploaded }}\r\n </li>\r\n </ul>\r\n \r\n <lib-loader *ngIf=\"isProcessing\"></lib-loader>\r\n\r\n <div class=\"action-button-container mt-3\">\r\n <button type=\"button\" class=\"btn btn-outline-primary rounded-pill me-2\" (click)=\"onImportImages(visit, true)\" [disabled]=\"isProcessing\">{{'Import all images' |\r\n translate}}</button>\r\n <button type=\"button\" *ngIf=\"imagesUploaded > 0\" class=\"btn btn-outline-primary rounded-pill me-2\" (click)=\"onImportImages(visit, false)\" [disabled]=\"isProcessing\">{{'Import from image' |\r\n translate}} {{imagesUploaded}}</button>\r\n <button type=\"button\" class=\"btn btn-outline-primary rounded-pill me-2\" [disabled]=\"isProcessing\"\r\n (click)=\"onEdit(visit)\">{{'Edit' | translate}}</button>\r\n <button type=\"button\" class=\"btn btn-outline-primary rounded-pill\" [disabled]=\"isProcessing\"\r\n (click)=\"onDelete(visit)\">{{'Delete' | translate}}</button>\r\n </div>\r\n </div>\r\n </li>\r\n </ul>\r\n <div *ngIf=\"visitForm\">\r\n <form (ngSubmit)=\"onSubmitVisit()\" [formGroup]=\"visitForm\">\r\n <div class=\"mb-3 row\">\r\n <label class=\"col-sm-2 col-form-label\">{{'Name' | translate}}</label>\r\n <div class=\"col-sm-10\">\r\n <input type=\"text\" class=\"form-control\" formControlName=\"name\">\r\n </div>\r\n </div>\r\n <div class=\"mb-3 row\">\r\n <label class=\"col-sm-2 col-form-label\">{{'Reference 3D model' | translate}} *</label>\r\n <div class=\"col-sm-10\">\r\n <input type=\"text\" class=\"form-control\" [readonly]=\"isEditing\"\r\n [class.is-invalid]=\"model3D.invalid && visitSubmitted\" required\r\n formControlName=\"model3D\">\r\n <div class=\"invalid-feedback\">\r\n <ngb-alert data-testid=\"new-location-name-invalid\" [dismissible]=\"false\" type=\"danger\" \r\n *ngIf=\"validatorsService.isControlError(visitForm.controls['name']) \r\n || isFormError(visitForm.controls['name'])\">\r\n {{validatorsService.getError(visitForm.controls['name']) | translate}}\r\n </ngb-alert>\r\n </div>\r\n <div *ngIf=\"isEditing\" class=\"text-danger\">\r\n {{'Cannot change 3D model reference. Please add new model.' | translate}}\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"mb-3 row\">\r\n <label class=\"col-sm-2 col-form-label\">{{'Viewer' | translate}}</label>\r\n <div class=\"col-sm-10\">\r\n <input type=\"text\" class=\"form-control\" formControlName=\"viewer\">\r\n </div>\r\n </div>\r\n\r\n <div class=\"mb-3 row\">\r\n <label class=\"col-sm-2 col-form-label\">{{'Surface' | translate}}</label>\r\n <div class=\"col-sm-10\">\r\n <input type=\"text\" class=\"form-control\" formControlName=\"surface\">\r\n </div>\r\n </div>\r\n\r\n <div class=\"mb-3 row\">\r\n <label class=\"col-sm-2 col-form-label\">{{'Capture Date' | translate}}</label>\r\n <div class=\"input-group\">\r\n <input class=\"form-control\" placeholder=\"dd/mm/yyyy\" [(ngModel)]=\"captureDate\" ngbDatepicker\r\n #d1=\"ngbDatepicker\" [ngModelOptions]=\"{standalone: true}\">\r\n <div class=\"input-group-append\">\r\n <button class=\"btn btn-outline-secondary calendar\" (click)=\"d1.toggle()\"\r\n type=\"button\"></button>\r\n </div>\r\n </div>\r\n </div>\r\n <button type=\"submit\" class=\"btn btn-outline-primary rounded-pill me-2\">{{'Save' |\r\n translate}}</button>\r\n <button type=\"button\" (click)=\"onCancel()\" class=\"btn btn-outline-primary rounded-pill\">{{'Cancel' |\r\n translate}}</button>\r\n <div class=\"invalid-feedback\" *ngIf=\"errorForm\">\r\n <ngb-alert data-testid=\"new-location-form-invalid\" [dismissible]=\"false\" type=\"danger\">\r\n {{'errorForm.infoBtn' |translate}}\r\n \r\n </ngb-alert>\r\n </div>\r\n </form>\r\n </div>\r\n <div *ngIf=\"!visitForm\">\r\n <button class=\"btn btn-outline-primary rounded-pill\" (click)=\"onAddVisit()\">{{'Add 3D visit' |\r\n translate}}</button>\r\n </div>\r\n </div>\r\n <div id=\"viewer-frame\" style=\"width: 100%; aspect-ratio: 2/1;\"></div>\r\n </div>\r\n <ng-template #content let-modal>\r\n <div class=\"modal-header\">\r\n <h4 class=\"modal-title\" id=\"modal-basic-title\">{{'Importing Data' | translate}}</h4>\r\n <button type=\"button\" class=\"close\" aria-label=\"Close\" (click)=\"modal.dismiss('Cross click')\">\r\n <span aria-hidden=\"true\">\u00D7</span>\r\n </button>\r\n </div>\r\n <div class=\"modal-body\">\r\n {{'Please do not leave or refresh this page...' | translate}}\r\n <div *ngIf=\"totalImages != 0\">Imported {{imagesProcessed}} out of {{totalImages}} images.</div>\r\n <div class=\"d-flex justify-content-center\">\r\n <div class=\"spinner-border\" role=\"status\">\r\n <span class=\"visually-hidden\">{{'Loading' | translate}}...</span>\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"modal-footer\">\r\n <button type=\"button\" class=\"btn btn-outline-dark\" [disabled]=\"!canCancelImport\"\r\n (click)=\"modal.close('Cancel click')\">{{'Cancel import of images' | translate}}</button>\r\n </div>\r\n </ng-template>\r\n</div>", styles: [".col-form-label{width:180px;margin-bottom:1rem}.btn-outline-primary{width:200px;margin-right:1rem}.input-group{width:83%;height:fit-content}.main-form-container{width:60vw;display:flex;flex-direction:column}@media screen and (max-width: 765px){.main-form-container{width:90vw}}.main-form-container .form-container{width:100%}\n"], dependencies: [{ kind: "component", type: i4.NgbAlert, selector: "ngb-alert", inputs: ["animation", "dismissible", "type"], outputs: ["closed"], exportAs: ["ngbAlert"] }, { kind: "directive", type: i4.NgbInputDatepicker, selector: "input[ngbDatepicker]", inputs: ["autoClose", "contentTemplate", "datepickerClass", "dayTemplate", "dayTemplateData", "displayMonths", "firstDayOfWeek", "footerTemplate", "markDisabled", "minDate", "maxDate", "navigation", "outsideDays", "placement", "popperOptions", "restoreFocus", "showWeekNumbers", "startDate", "container", "positionTarget", "weekdays", "disabled"], outputs: ["dateSelect", "navigate", "closed"], exportAs: ["ngbDatepicker"] }, { kind: "directive", type: i6.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i6.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: i2.LoaderComponent, selector: "lib-loader", inputs: ["useLogo", "color"] }, { kind: "component", type: i7.TabNavigationComponent, selector: "lib-tab-navigation", inputs: ["menuItems"], outputs: ["onGoBack"] }, { kind: "component", type: i8.ChevronComponent, selector: "lib-chevron", inputs: ["conditionShowing"] }, { kind: "pipe", type: i6.AsyncPipe, name: "async" }, { kind: "pipe", type: i5.TranslatePipe, name: "translate" }, { kind: "pipe", type: i2.TimeDateToLocalStringPipe, name: "timeDateString" }] });
316
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: VisitsComponent, deps: [{ token: i1.UntypedFormBuilder }, { token: i2.MatterportImportService }, { token: i2.ThreeJsImportService }, { token: i2.CaptureService }, { token: i2.NodeService }, { token: i2.SpaceService }, { token: i3.ActivatedRoute }, { token: i4.NgbModal }, { token: i2.VisitService }, { token: i2.ValidatorsService }, { token: i5.TranslateService }, { token: i2.NavigatorService }, { token: i3.Router }], target: i0.ɵɵFactoryTarget.Component });
317
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: VisitsComponent, selector: "lib-visits", viewQueries: [{ propertyName: "content", first: true, predicate: ["content"], descendants: true }], ngImport: i0, template: "<div class=\"container-fluid\" class=\"dashboard-tab\">\n <div class=\"m-3\">\n <lib-tab-navigation [menuItems]='menuItems' (onGoBack)=\"onGoBack()\"></lib-tab-navigation>\n </div>\n\n <div class=\"row main-form-container\">\n <div class=\"col-md-6 form-container\">\n <ul class=\"list-group list-group-flush\" *ngIf=\"!visitForm\">\n <li class=\"list-group-item list-group-item-action\" *ngFor=\"let visit of visits; index as index\">\n <div class=\"d-flex justify-content-between align-items-center\" (click)=\"onToggleDetail(index)\">\n {{visit.name ? visit.name : visit.model3d }}\n <lib-chevron [conditionShowing]=\"index==visitIndexDetails\"></lib-chevron>\n </div>\n <div *ngIf=\"index==visitIndexDetails\">\n <ul class=\"list-group list-group-flush\">\n <li class=\"list-group-item bg-transparent\">{{'Name' | translate}} : {{ visit.name ?\n visit.name : \"Not provided\" | translate}}</li>\n <li class=\"list-group-item bg-transparent\">{{'3D Model' | translate}} : {{ visit.model3d }}\n </li>\n <li class=\"list-group-item bg-transparent\">{{'Surface' | translate}}, m<sup>2</sup>: {{\n visit.surface ?\n visit.surface : 'Not provided' | translate}}</li>\n <li class=\"list-group-item bg-transparent\">{{'Viewer' | translate}} : {{ visit.viewer }}\n </li>\n <li class=\"list-group-item bg-transparent\">{{'Date of capture' | translate}} : {{\n visit.takenAt | timeDateString | async}}\n <li class=\"list-group-item bg-transparent\">{{'Images are imported' | translate}} : {{\n imagesUploaded }}\n </li>\n </ul>\n \n <lib-loader *ngIf=\"isProcessing\"></lib-loader>\n\n <div class=\"action-button-container mt-3\">\n <button type=\"button\" class=\"btn btn-outline-primary rounded-pill me-2\" (click)=\"onImportImages(visit, true)\" [disabled]=\"isProcessing\">{{'Import all images' |\n translate}}</button>\n <button type=\"button\" *ngIf=\"imagesUploaded > 0\" class=\"btn btn-outline-primary rounded-pill me-2\" (click)=\"onImportImages(visit, false)\" [disabled]=\"isProcessing\">{{'Import from image' |\n translate}} {{imagesUploaded}}</button>\n <button type=\"button\" class=\"btn btn-outline-primary rounded-pill me-2\" [disabled]=\"isProcessing\"\n (click)=\"onEdit(visit)\">{{'Edit' | translate}}</button>\n <button type=\"button\" class=\"btn btn-outline-primary rounded-pill\" [disabled]=\"isProcessing\"\n (click)=\"onDelete(visit)\">{{'Delete' | translate}}</button>\n </div>\n </div>\n </li>\n </ul>\n <div *ngIf=\"visitForm\">\n <form (ngSubmit)=\"onSubmitVisit()\" [formGroup]=\"visitForm\">\n <div class=\"mb-3 row\">\n <label class=\"col-sm-2 col-form-label\">{{'Name' | translate}}</label>\n <div class=\"col-sm-10\">\n <input type=\"text\" class=\"form-control\" formControlName=\"name\">\n </div>\n </div>\n <div class=\"mb-3 row\">\n <label class=\"col-sm-2 col-form-label\">{{'Reference 3D model' | translate}} *</label>\n <div class=\"col-sm-10\">\n <input type=\"text\" class=\"form-control\" [readonly]=\"isEditing\"\n [class.is-invalid]=\"model3D.invalid && visitSubmitted\" required\n formControlName=\"model3D\">\n <div class=\"invalid-feedback\">\n <ngb-alert data-testid=\"new-location-name-invalid\" [dismissible]=\"false\" type=\"danger\" \n *ngIf=\"validatorsService.isControlError(visitForm.controls['name']) \n || isFormError(visitForm.controls['name'])\">\n {{validatorsService.getError(visitForm.controls['name']) | translate}}\n </ngb-alert>\n </div>\n <div *ngIf=\"isEditing\" class=\"text-danger\">\n {{'Cannot change 3D model reference. Please add new model.' | translate}}\n </div>\n <!-- A Three.js visit stores an S3 key here instead of a Matterport model ID,\n so the field means something different depending on the viewer above. -->\n <div *ngIf=\"isThreeJsVisit\" class=\"form-text\">\n {{'S3 key of the .glb file, for example visits/my-model.glb' | translate}}\n </div>\n <div *ngIf=\"modelKeyError && visitSubmitted\" class=\"text-danger\">\n {{modelKeyError | translate}}\n </div>\n </div>\n </div>\n\n <div class=\"mb-3 row\">\n <label class=\"col-sm-2 col-form-label\">{{'Viewer' | translate}}</label>\n <div class=\"col-sm-10\">\n <select class=\"form-select\" formControlName=\"viewer\">\n <option value=\"MATTERPORT\">Matterport</option>\n <option value=\"THREEJS\">Mod\u00E8le 3D (Three.js)</option>\n <option value=\"CUPIX\">Cupix</option>\n </select>\n </div>\n </div>\n\n <div class=\"mb-3 row\" *ngIf=\"isThreeJsVisit\">\n <label class=\"col-sm-2 col-form-label\">{{'Initial placement' | translate}}</label>\n <div class=\"col-sm-10\">\n <textarea class=\"form-control\" rows=\"3\" formControlName=\"threeJsPlacement\"\n placeholder='{\"cameraPosition\": {\"x\": 0, \"y\": 5, \"z\": 15}, \"rotation\": {\"x\": 0, \"y\": 0, \"z\": 0}}'></textarea>\n <div class=\"form-text\">\n {{'Optional. Leave empty to frame the model automatically.' | translate}}\n </div>\n </div>\n </div>\n\n <div class=\"mb-3 row\">\n <label class=\"col-sm-2 col-form-label\">{{'Surface' | translate}}</label>\n <div class=\"col-sm-10\">\n <input type=\"text\" class=\"form-control\" formControlName=\"surface\">\n </div>\n </div>\n\n <div class=\"mb-3 row\">\n <label class=\"col-sm-2 col-form-label\">{{'Capture Date' | translate}}</label>\n <div class=\"input-group\">\n <input class=\"form-control\" placeholder=\"dd/mm/yyyy\" [(ngModel)]=\"captureDate\" ngbDatepicker\n #d1=\"ngbDatepicker\" [ngModelOptions]=\"{standalone: true}\">\n <div class=\"input-group-append\">\n <button class=\"btn btn-outline-secondary calendar\" (click)=\"d1.toggle()\"\n type=\"button\"></button>\n </div>\n </div>\n </div>\n <button type=\"submit\" class=\"btn btn-outline-primary rounded-pill me-2\">{{'Save' |\n translate}}</button>\n <button type=\"button\" (click)=\"onCancel()\" class=\"btn btn-outline-primary rounded-pill\">{{'Cancel' |\n translate}}</button>\n <div class=\"invalid-feedback\" *ngIf=\"errorForm\">\n <ngb-alert data-testid=\"new-location-form-invalid\" [dismissible]=\"false\" type=\"danger\">\n {{'errorForm.infoBtn' |translate}}\n \n </ngb-alert>\n </div>\n </form>\n </div>\n <div *ngIf=\"!visitForm\">\n <button class=\"btn btn-outline-primary rounded-pill\" (click)=\"onAddVisit()\">{{'Add 3D visit' |\n translate}}</button>\n </div>\n </div>\n <div id=\"viewer-frame\" style=\"width: 100%; aspect-ratio: 2/1;\"></div>\n </div>\n <ng-template #content let-modal>\n <div class=\"modal-header\">\n <h4 class=\"modal-title\" id=\"modal-basic-title\">{{'Importing Data' | translate}}</h4>\n <button type=\"button\" class=\"close\" aria-label=\"Close\" (click)=\"modal.dismiss('Cross click')\">\n <span aria-hidden=\"true\">\u00D7</span>\n </button>\n </div>\n <div class=\"modal-body\">\n {{'Please do not leave or refresh this page...' | translate}}\n <div *ngIf=\"totalImages != 0\">Imported {{imagesProcessed}} out of {{totalImages}} images.</div>\n <div class=\"d-flex justify-content-center\">\n <div class=\"spinner-border\" role=\"status\">\n <span class=\"visually-hidden\">{{'Loading' | translate}}...</span>\n </div>\n </div>\n </div>\n <div class=\"modal-footer\">\n <button type=\"button\" class=\"btn btn-outline-dark\" [disabled]=\"!canCancelImport\"\n (click)=\"modal.close('Cancel click')\">{{'Cancel import of images' | translate}}</button>\n </div>\n </ng-template>\n</div>", styles: [".col-form-label{width:180px;margin-bottom:1rem}.btn-outline-primary{width:200px;margin-right:1rem}.input-group{width:83%;height:fit-content}.main-form-container{width:60vw;display:flex;flex-direction:column}@media screen and (max-width: 765px){.main-form-container{width:90vw}}.main-form-container .form-container{width:100%}\n"], dependencies: [{ kind: "component", type: i4.NgbAlert, selector: "ngb-alert", inputs: ["animation", "dismissible", "type"], outputs: ["closed"], exportAs: ["ngbAlert"] }, { kind: "directive", type: i4.NgbInputDatepicker, selector: "input[ngbDatepicker]", inputs: ["autoClose", "contentTemplate", "datepickerClass", "dayTemplate", "dayTemplateData", "displayMonths", "firstDayOfWeek", "footerTemplate", "markDisabled", "minDate", "maxDate", "navigation", "outsideDays", "placement", "popperOptions", "restoreFocus", "showWeekNumbers", "startDate", "container", "positionTarget", "weekdays", "disabled"], outputs: ["dateSelect", "navigate", "closed"], exportAs: ["ngbDatepicker"] }, { kind: "directive", type: i6.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i6.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: i2.LoaderComponent, selector: "lib-loader", inputs: ["useLogo", "color"] }, { kind: "component", type: i7.TabNavigationComponent, selector: "lib-tab-navigation", inputs: ["menuItems"], outputs: ["onGoBack"] }, { kind: "component", type: i8.ChevronComponent, selector: "lib-chevron", inputs: ["conditionShowing"] }, { kind: "pipe", type: i6.AsyncPipe, name: "async" }, { kind: "pipe", type: i5.TranslatePipe, name: "translate" }, { kind: "pipe", type: i2.TimeDateToLocalStringPipe, name: "timeDateString" }] });
285
318
  }
286
319
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: VisitsComponent, decorators: [{
287
320
  type: Component,
288
- args: [{ selector: 'lib-visits', template: "<div class=\"container-fluid\" class=\"dashboard-tab\">\r\n <div class=\"m-3\">\r\n <lib-tab-navigation [menuItems]='menuItems' (onGoBack)=\"onGoBack()\"></lib-tab-navigation>\r\n </div>\r\n\r\n <div class=\"row main-form-container\">\r\n <div class=\"col-md-6 form-container\">\r\n <ul class=\"list-group list-group-flush\" *ngIf=\"!visitForm\">\r\n <li class=\"list-group-item list-group-item-action\" *ngFor=\"let visit of visits; index as index\">\r\n <div class=\"d-flex justify-content-between align-items-center\" (click)=\"onToggleDetail(index)\">\r\n {{visit.name ? visit.name : visit.model3d }}\r\n <lib-chevron [conditionShowing]=\"index==visitIndexDetails\"></lib-chevron>\r\n </div>\r\n <div *ngIf=\"index==visitIndexDetails\">\r\n <ul class=\"list-group list-group-flush\">\r\n <li class=\"list-group-item bg-transparent\">{{'Name' | translate}} : {{ visit.name ?\r\n visit.name : \"Not provided\" | translate}}</li>\r\n <li class=\"list-group-item bg-transparent\">{{'3D Model' | translate}} : {{ visit.model3d }}\r\n </li>\r\n <li class=\"list-group-item bg-transparent\">{{'Surface' | translate}}, m<sup>2</sup>: {{\r\n visit.surface ?\r\n visit.surface : 'Not provided' | translate}}</li>\r\n <li class=\"list-group-item bg-transparent\">{{'Viewer' | translate}} : {{ visit.viewer }}\r\n </li>\r\n <li class=\"list-group-item bg-transparent\">{{'Date of capture' | translate}} : {{\r\n visit.takenAt | timeDateString | async}}\r\n <li class=\"list-group-item bg-transparent\">{{'Images are imported' | translate}} : {{\r\n imagesUploaded }}\r\n </li>\r\n </ul>\r\n \r\n <lib-loader *ngIf=\"isProcessing\"></lib-loader>\r\n\r\n <div class=\"action-button-container mt-3\">\r\n <button type=\"button\" class=\"btn btn-outline-primary rounded-pill me-2\" (click)=\"onImportImages(visit, true)\" [disabled]=\"isProcessing\">{{'Import all images' |\r\n translate}}</button>\r\n <button type=\"button\" *ngIf=\"imagesUploaded > 0\" class=\"btn btn-outline-primary rounded-pill me-2\" (click)=\"onImportImages(visit, false)\" [disabled]=\"isProcessing\">{{'Import from image' |\r\n translate}} {{imagesUploaded}}</button>\r\n <button type=\"button\" class=\"btn btn-outline-primary rounded-pill me-2\" [disabled]=\"isProcessing\"\r\n (click)=\"onEdit(visit)\">{{'Edit' | translate}}</button>\r\n <button type=\"button\" class=\"btn btn-outline-primary rounded-pill\" [disabled]=\"isProcessing\"\r\n (click)=\"onDelete(visit)\">{{'Delete' | translate}}</button>\r\n </div>\r\n </div>\r\n </li>\r\n </ul>\r\n <div *ngIf=\"visitForm\">\r\n <form (ngSubmit)=\"onSubmitVisit()\" [formGroup]=\"visitForm\">\r\n <div class=\"mb-3 row\">\r\n <label class=\"col-sm-2 col-form-label\">{{'Name' | translate}}</label>\r\n <div class=\"col-sm-10\">\r\n <input type=\"text\" class=\"form-control\" formControlName=\"name\">\r\n </div>\r\n </div>\r\n <div class=\"mb-3 row\">\r\n <label class=\"col-sm-2 col-form-label\">{{'Reference 3D model' | translate}} *</label>\r\n <div class=\"col-sm-10\">\r\n <input type=\"text\" class=\"form-control\" [readonly]=\"isEditing\"\r\n [class.is-invalid]=\"model3D.invalid && visitSubmitted\" required\r\n formControlName=\"model3D\">\r\n <div class=\"invalid-feedback\">\r\n <ngb-alert data-testid=\"new-location-name-invalid\" [dismissible]=\"false\" type=\"danger\" \r\n *ngIf=\"validatorsService.isControlError(visitForm.controls['name']) \r\n || isFormError(visitForm.controls['name'])\">\r\n {{validatorsService.getError(visitForm.controls['name']) | translate}}\r\n </ngb-alert>\r\n </div>\r\n <div *ngIf=\"isEditing\" class=\"text-danger\">\r\n {{'Cannot change 3D model reference. Please add new model.' | translate}}\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"mb-3 row\">\r\n <label class=\"col-sm-2 col-form-label\">{{'Viewer' | translate}}</label>\r\n <div class=\"col-sm-10\">\r\n <input type=\"text\" class=\"form-control\" formControlName=\"viewer\">\r\n </div>\r\n </div>\r\n\r\n <div class=\"mb-3 row\">\r\n <label class=\"col-sm-2 col-form-label\">{{'Surface' | translate}}</label>\r\n <div class=\"col-sm-10\">\r\n <input type=\"text\" class=\"form-control\" formControlName=\"surface\">\r\n </div>\r\n </div>\r\n\r\n <div class=\"mb-3 row\">\r\n <label class=\"col-sm-2 col-form-label\">{{'Capture Date' | translate}}</label>\r\n <div class=\"input-group\">\r\n <input class=\"form-control\" placeholder=\"dd/mm/yyyy\" [(ngModel)]=\"captureDate\" ngbDatepicker\r\n #d1=\"ngbDatepicker\" [ngModelOptions]=\"{standalone: true}\">\r\n <div class=\"input-group-append\">\r\n <button class=\"btn btn-outline-secondary calendar\" (click)=\"d1.toggle()\"\r\n type=\"button\"></button>\r\n </div>\r\n </div>\r\n </div>\r\n <button type=\"submit\" class=\"btn btn-outline-primary rounded-pill me-2\">{{'Save' |\r\n translate}}</button>\r\n <button type=\"button\" (click)=\"onCancel()\" class=\"btn btn-outline-primary rounded-pill\">{{'Cancel' |\r\n translate}}</button>\r\n <div class=\"invalid-feedback\" *ngIf=\"errorForm\">\r\n <ngb-alert data-testid=\"new-location-form-invalid\" [dismissible]=\"false\" type=\"danger\">\r\n {{'errorForm.infoBtn' |translate}}\r\n \r\n </ngb-alert>\r\n </div>\r\n </form>\r\n </div>\r\n <div *ngIf=\"!visitForm\">\r\n <button class=\"btn btn-outline-primary rounded-pill\" (click)=\"onAddVisit()\">{{'Add 3D visit' |\r\n translate}}</button>\r\n </div>\r\n </div>\r\n <div id=\"viewer-frame\" style=\"width: 100%; aspect-ratio: 2/1;\"></div>\r\n </div>\r\n <ng-template #content let-modal>\r\n <div class=\"modal-header\">\r\n <h4 class=\"modal-title\" id=\"modal-basic-title\">{{'Importing Data' | translate}}</h4>\r\n <button type=\"button\" class=\"close\" aria-label=\"Close\" (click)=\"modal.dismiss('Cross click')\">\r\n <span aria-hidden=\"true\">\u00D7</span>\r\n </button>\r\n </div>\r\n <div class=\"modal-body\">\r\n {{'Please do not leave or refresh this page...' | translate}}\r\n <div *ngIf=\"totalImages != 0\">Imported {{imagesProcessed}} out of {{totalImages}} images.</div>\r\n <div class=\"d-flex justify-content-center\">\r\n <div class=\"spinner-border\" role=\"status\">\r\n <span class=\"visually-hidden\">{{'Loading' | translate}}...</span>\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"modal-footer\">\r\n <button type=\"button\" class=\"btn btn-outline-dark\" [disabled]=\"!canCancelImport\"\r\n (click)=\"modal.close('Cancel click')\">{{'Cancel import of images' | translate}}</button>\r\n </div>\r\n </ng-template>\r\n</div>", styles: [".col-form-label{width:180px;margin-bottom:1rem}.btn-outline-primary{width:200px;margin-right:1rem}.input-group{width:83%;height:fit-content}.main-form-container{width:60vw;display:flex;flex-direction:column}@media screen and (max-width: 765px){.main-form-container{width:90vw}}.main-form-container .form-container{width:100%}\n"] }]
289
- }], ctorParameters: () => [{ type: i1.UntypedFormBuilder }, { type: i2.MatterportImportService }, { type: i2.CaptureService }, { type: i2.NodeService }, { type: i2.SpaceService }, { type: i3.ActivatedRoute }, { type: i4.NgbModal }, { type: i2.VisitService }, { type: i2.ValidatorsService }, { type: i5.TranslateService }, { type: i2.NavigatorService }, { type: i3.Router }], propDecorators: { content: [{
321
+ args: [{ selector: 'lib-visits', template: "<div class=\"container-fluid\" class=\"dashboard-tab\">\n <div class=\"m-3\">\n <lib-tab-navigation [menuItems]='menuItems' (onGoBack)=\"onGoBack()\"></lib-tab-navigation>\n </div>\n\n <div class=\"row main-form-container\">\n <div class=\"col-md-6 form-container\">\n <ul class=\"list-group list-group-flush\" *ngIf=\"!visitForm\">\n <li class=\"list-group-item list-group-item-action\" *ngFor=\"let visit of visits; index as index\">\n <div class=\"d-flex justify-content-between align-items-center\" (click)=\"onToggleDetail(index)\">\n {{visit.name ? visit.name : visit.model3d }}\n <lib-chevron [conditionShowing]=\"index==visitIndexDetails\"></lib-chevron>\n </div>\n <div *ngIf=\"index==visitIndexDetails\">\n <ul class=\"list-group list-group-flush\">\n <li class=\"list-group-item bg-transparent\">{{'Name' | translate}} : {{ visit.name ?\n visit.name : \"Not provided\" | translate}}</li>\n <li class=\"list-group-item bg-transparent\">{{'3D Model' | translate}} : {{ visit.model3d }}\n </li>\n <li class=\"list-group-item bg-transparent\">{{'Surface' | translate}}, m<sup>2</sup>: {{\n visit.surface ?\n visit.surface : 'Not provided' | translate}}</li>\n <li class=\"list-group-item bg-transparent\">{{'Viewer' | translate}} : {{ visit.viewer }}\n </li>\n <li class=\"list-group-item bg-transparent\">{{'Date of capture' | translate}} : {{\n visit.takenAt | timeDateString | async}}\n <li class=\"list-group-item bg-transparent\">{{'Images are imported' | translate}} : {{\n imagesUploaded }}\n </li>\n </ul>\n \n <lib-loader *ngIf=\"isProcessing\"></lib-loader>\n\n <div class=\"action-button-container mt-3\">\n <button type=\"button\" class=\"btn btn-outline-primary rounded-pill me-2\" (click)=\"onImportImages(visit, true)\" [disabled]=\"isProcessing\">{{'Import all images' |\n translate}}</button>\n <button type=\"button\" *ngIf=\"imagesUploaded > 0\" class=\"btn btn-outline-primary rounded-pill me-2\" (click)=\"onImportImages(visit, false)\" [disabled]=\"isProcessing\">{{'Import from image' |\n translate}} {{imagesUploaded}}</button>\n <button type=\"button\" class=\"btn btn-outline-primary rounded-pill me-2\" [disabled]=\"isProcessing\"\n (click)=\"onEdit(visit)\">{{'Edit' | translate}}</button>\n <button type=\"button\" class=\"btn btn-outline-primary rounded-pill\" [disabled]=\"isProcessing\"\n (click)=\"onDelete(visit)\">{{'Delete' | translate}}</button>\n </div>\n </div>\n </li>\n </ul>\n <div *ngIf=\"visitForm\">\n <form (ngSubmit)=\"onSubmitVisit()\" [formGroup]=\"visitForm\">\n <div class=\"mb-3 row\">\n <label class=\"col-sm-2 col-form-label\">{{'Name' | translate}}</label>\n <div class=\"col-sm-10\">\n <input type=\"text\" class=\"form-control\" formControlName=\"name\">\n </div>\n </div>\n <div class=\"mb-3 row\">\n <label class=\"col-sm-2 col-form-label\">{{'Reference 3D model' | translate}} *</label>\n <div class=\"col-sm-10\">\n <input type=\"text\" class=\"form-control\" [readonly]=\"isEditing\"\n [class.is-invalid]=\"model3D.invalid && visitSubmitted\" required\n formControlName=\"model3D\">\n <div class=\"invalid-feedback\">\n <ngb-alert data-testid=\"new-location-name-invalid\" [dismissible]=\"false\" type=\"danger\" \n *ngIf=\"validatorsService.isControlError(visitForm.controls['name']) \n || isFormError(visitForm.controls['name'])\">\n {{validatorsService.getError(visitForm.controls['name']) | translate}}\n </ngb-alert>\n </div>\n <div *ngIf=\"isEditing\" class=\"text-danger\">\n {{'Cannot change 3D model reference. Please add new model.' | translate}}\n </div>\n <!-- A Three.js visit stores an S3 key here instead of a Matterport model ID,\n so the field means something different depending on the viewer above. -->\n <div *ngIf=\"isThreeJsVisit\" class=\"form-text\">\n {{'S3 key of the .glb file, for example visits/my-model.glb' | translate}}\n </div>\n <div *ngIf=\"modelKeyError && visitSubmitted\" class=\"text-danger\">\n {{modelKeyError | translate}}\n </div>\n </div>\n </div>\n\n <div class=\"mb-3 row\">\n <label class=\"col-sm-2 col-form-label\">{{'Viewer' | translate}}</label>\n <div class=\"col-sm-10\">\n <select class=\"form-select\" formControlName=\"viewer\">\n <option value=\"MATTERPORT\">Matterport</option>\n <option value=\"THREEJS\">Mod\u00E8le 3D (Three.js)</option>\n <option value=\"CUPIX\">Cupix</option>\n </select>\n </div>\n </div>\n\n <div class=\"mb-3 row\" *ngIf=\"isThreeJsVisit\">\n <label class=\"col-sm-2 col-form-label\">{{'Initial placement' | translate}}</label>\n <div class=\"col-sm-10\">\n <textarea class=\"form-control\" rows=\"3\" formControlName=\"threeJsPlacement\"\n placeholder='{\"cameraPosition\": {\"x\": 0, \"y\": 5, \"z\": 15}, \"rotation\": {\"x\": 0, \"y\": 0, \"z\": 0}}'></textarea>\n <div class=\"form-text\">\n {{'Optional. Leave empty to frame the model automatically.' | translate}}\n </div>\n </div>\n </div>\n\n <div class=\"mb-3 row\">\n <label class=\"col-sm-2 col-form-label\">{{'Surface' | translate}}</label>\n <div class=\"col-sm-10\">\n <input type=\"text\" class=\"form-control\" formControlName=\"surface\">\n </div>\n </div>\n\n <div class=\"mb-3 row\">\n <label class=\"col-sm-2 col-form-label\">{{'Capture Date' | translate}}</label>\n <div class=\"input-group\">\n <input class=\"form-control\" placeholder=\"dd/mm/yyyy\" [(ngModel)]=\"captureDate\" ngbDatepicker\n #d1=\"ngbDatepicker\" [ngModelOptions]=\"{standalone: true}\">\n <div class=\"input-group-append\">\n <button class=\"btn btn-outline-secondary calendar\" (click)=\"d1.toggle()\"\n type=\"button\"></button>\n </div>\n </div>\n </div>\n <button type=\"submit\" class=\"btn btn-outline-primary rounded-pill me-2\">{{'Save' |\n translate}}</button>\n <button type=\"button\" (click)=\"onCancel()\" class=\"btn btn-outline-primary rounded-pill\">{{'Cancel' |\n translate}}</button>\n <div class=\"invalid-feedback\" *ngIf=\"errorForm\">\n <ngb-alert data-testid=\"new-location-form-invalid\" [dismissible]=\"false\" type=\"danger\">\n {{'errorForm.infoBtn' |translate}}\n \n </ngb-alert>\n </div>\n </form>\n </div>\n <div *ngIf=\"!visitForm\">\n <button class=\"btn btn-outline-primary rounded-pill\" (click)=\"onAddVisit()\">{{'Add 3D visit' |\n translate}}</button>\n </div>\n </div>\n <div id=\"viewer-frame\" style=\"width: 100%; aspect-ratio: 2/1;\"></div>\n </div>\n <ng-template #content let-modal>\n <div class=\"modal-header\">\n <h4 class=\"modal-title\" id=\"modal-basic-title\">{{'Importing Data' | translate}}</h4>\n <button type=\"button\" class=\"close\" aria-label=\"Close\" (click)=\"modal.dismiss('Cross click')\">\n <span aria-hidden=\"true\">\u00D7</span>\n </button>\n </div>\n <div class=\"modal-body\">\n {{'Please do not leave or refresh this page...' | translate}}\n <div *ngIf=\"totalImages != 0\">Imported {{imagesProcessed}} out of {{totalImages}} images.</div>\n <div class=\"d-flex justify-content-center\">\n <div class=\"spinner-border\" role=\"status\">\n <span class=\"visually-hidden\">{{'Loading' | translate}}...</span>\n </div>\n </div>\n </div>\n <div class=\"modal-footer\">\n <button type=\"button\" class=\"btn btn-outline-dark\" [disabled]=\"!canCancelImport\"\n (click)=\"modal.close('Cancel click')\">{{'Cancel import of images' | translate}}</button>\n </div>\n </ng-template>\n</div>", styles: [".col-form-label{width:180px;margin-bottom:1rem}.btn-outline-primary{width:200px;margin-right:1rem}.input-group{width:83%;height:fit-content}.main-form-container{width:60vw;display:flex;flex-direction:column}@media screen and (max-width: 765px){.main-form-container{width:90vw}}.main-form-container .form-container{width:100%}\n"] }]
322
+ }], ctorParameters: () => [{ type: i1.UntypedFormBuilder }, { type: i2.MatterportImportService }, { type: i2.ThreeJsImportService }, { type: i2.CaptureService }, { type: i2.NodeService }, { type: i2.SpaceService }, { type: i3.ActivatedRoute }, { type: i4.NgbModal }, { type: i2.VisitService }, { type: i2.ValidatorsService }, { type: i5.TranslateService }, { type: i2.NavigatorService }, { type: i3.Router }], propDecorators: { content: [{
290
323
  type: ViewChild,
291
324
  args: ['content', { static: false }]
292
325
  }] } });
293
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmlzaXRzLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL25neC1zbWFydGVycGxhbi1sb2NhdGlvbnMvc3JjL2xpYi9jb21wb25lbnRzL3Zpc2l0cy92aXNpdHMuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvbmd4LXNtYXJ0ZXJwbGFuLWxvY2F0aW9ucy9zcmMvbGliL2NvbXBvbmVudHMvdmlzaXRzL3Zpc2l0cy5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsU0FBUyxFQUFVLFNBQVMsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUM3RCxPQUFPLEVBR0gsVUFBVSxHQUViLE1BQU0sZ0JBQWdCLENBQUM7QUFFeEIsT0FBTyxFQUFZLG1CQUFtQixFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFDM0UsT0FBTyxFQVNILGFBQWEsR0FJaEIsTUFBTSxtQ0FBbUMsQ0FBQztBQUUzQyxPQUFPLEVBQUUsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLE1BQU0sQ0FBQzs7Ozs7Ozs7OztBQU8xQyxNQUFNLE9BQU8sZUFBZTtJQXdDWjtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0Q7SUFDQztJQUNBO0lBQ0E7SUFsRFosT0FBTyxDQUFTO0lBRWhCLGlCQUFpQixHQUFHLENBQUMsQ0FBQyxDQUFDO0lBRXZCLFNBQVMsQ0FBbUI7SUFFNUIsU0FBUyxHQUFZLEtBQUssQ0FBQztJQUUzQixjQUFjLEdBQVksS0FBSyxDQUFDO0lBRWhDLFdBQVcsQ0FBUztJQUVwQixZQUFZLEdBQUcsRUFBRSxLQUFLLEVBQUUsRUFBRSxFQUFTLENBQUM7SUFFcEMsTUFBTSxHQUFZLEVBQUUsQ0FBQztJQUVyQixXQUFXLENBQVM7SUFFNkIsT0FBTyxDQUFDO0lBRXpELGNBQWMsQ0FBTTtJQUVwQixlQUFlLEdBQUcsS0FBSyxDQUFD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QUFFLEVBQUUsSUFBSSxFQUFFLGdCQUFnQixDQUFDLENBQUM7SUFDbEYsQ0FBQztJQUVELFdBQVcsQ0FBQyxPQUFPO1FBQ2YsT0FBTyxPQUFPLElBQUksT0FBTyxDQUFDLE9BQU8sSUFBSSxJQUFJLENBQUMsU0FBUyxDQUFDO0lBQ3hELENBQUM7d0dBN1RRLGVBQWU7NEZBQWYsZUFBZSxzSkMvQjVCLHE4UkEwSU07OzRGRDNHTyxlQUFlO2tCQUwzQixTQUFTOytCQUNJLFlBQVk7aVpBdUIyQixPQUFPO3NCQUF2RCxTQUFTO3VCQUFDLFNBQVMsRUFBRSxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQUUiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb21wb25lbnQsIE9uSW5pdCwgVmlld0NoaWxkIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcbmltcG9ydCB7XHJcbiAgICBVbnR5cGVkRm9ybUdyb3VwLFxyXG4gICAgVW50eXBlZEZvcm1CdWlsZGVyLFxyXG4gICAgVmFsaWRhdG9ycyxcclxuICAgIEFic3RyYWN0Q29udHJvbCxcclxufSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XHJcbmltcG9ydCB7IEFjdGl2YXRlZFJvdXRlLCBSb3V0ZXIgfSBmcm9tICdAYW5ndWxhci9yb3V0ZXInO1xyXG5pbXBvcnQgeyBOZ2JNb2RhbCwgTW9kYWxEaXNtaXNzUmVhc29ucyB9IGZyb20gJ0BuZy1ib290c3RyYXAvbmctYm9vdHN0cmFwJztcclxuaW1wb3J0IHtcclxuICAgIE5vZGUsXHJcbiAgICBWaXNpdCxcclxuICAgIE1lbnVJdGVtLFxyXG4gICAgTWF0dGVycG9ydEltcG9ydFNlcnZpY2UsXHJcbiAgICBDYXB0dXJlU2VydmljZSxcclxuICAgIE5vZGVTZXJ2aWNlLFxyXG4gICAgU3BhY2VTZXJ2aWNlLFxyXG4gICAgVmlzaXRTZXJ2aWNlLFxyXG4gICAgQ2FwdHVyZVZpZXdlcixcclxuICAgIENhcHR1cmUsXHJcbiAgICBWYWxpZGF0b3JzU2VydmljZSxcclxuICAgIE5hdmlnYXRvclNlcnZpY2UsXHJcbn0gZnJvbSAnQHNtYXJ0ZXJwbGFuL25neC1zbWFydGVycGxhbi1jb3JlJztcclxuaW1wb3J0IHsgVHJhbnNsYXRlU2VydmljZSB9IGZyb20gJ0BuZ3gtdHJhbnNsYXRlL2NvcmUnO1xyXG5pbXBvcnQgeyBTdWJqZWN0LCB0YWtlVW50aWwgfSBmcm9tICdyeGpzJztcclxuXHJcbkBDb21wb25lbnQoe1xyXG4gICAgc2VsZWN0b3I6ICdsaWItdmlzaXRzJyxcclxuICAgIHRlbXBsYXRlVXJsOiAnLi92aXNpdHMuY29tcG9uZW50Lmh0bWwnLFxyXG4gICAgc3R5bGVVcmxzOiBbJy4vdmlzaXRzLmNvbXBvbmVudC5zY3NzJ10sXHJcbn0pXHJcbmV4cG9ydCBjbGFzcyBWaXNpdHNDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQge1xyXG4gICAgc3BhY2VJZDogc3RyaW5nO1xyXG5cclxuICAgIHZpc2l0SW5kZXhEZXRhaWxzID0gLTE7XHJcblxyXG4gICAgdmlzaXRGb3JtOiBVbnR5cGVkRm9ybUdyb3VwO1xyXG5cclxuICAgIGlzRWRpdGluZzogYm9vbGVhbiA9IGZhbHNlO1xyXG5cclxuICAgIHZpc2l0U3VibWl0dGVkOiBib29sZWFuID0gZmFsc2U7XHJcblxyXG4gICAgY2FwdHVyZURhdGU6IG51bWJlcjtcclxuXHJcbiAgICBjdXJyZW50U3BhY2UgPSB7IHpvbmVzOiBbXSB9IGFzIGFueTtcclxuXHJcbiAgICB2aXNpdHM6IFZpc2l0W10gPSBbXTtcclxuXHJcbiAgICBjbG9zZVJlc3VsdDogc3RyaW5nO1xyXG5cclxuICAgIEBWaWV3Q2hpbGQoJ2NvbnRlbnQnLCB7IHN0YXRpYzogZmFsc2UgfSkgcHJpdmF0ZSBjb250ZW50O1xyXG5cclxuICAgIG1vZGFsUmVmZXJlbmNlOiBhbnk7XHJcblxyXG4gICAgY2FuQ2FuY2VsSW1wb3J0ID0gZmFsc2U7XHJcblxyXG4gICAgaW1hZ2VzUHJvY2Vzc2VkOiBudW1iZXIgPSAwO1xyXG5cclxuICAgIHRvdGFsSW1hZ2VzOiBudW1iZXIgPSAwO1xyXG5cclxuICAgIGltYWdlc1VwbG9hZGVkOiBudW1iZXIgPSAwO1xyXG5cclxuICAgIG1lbnVJdGVtczogTWVudUl0ZW1bXSA9IFtdO1xyXG5cclxuICAgIGVycm9yRm9ybTogYm9vbGVhbiA9IGZhbHNlO1xyXG5cclxuICAgIGlzUHJvY2Vzc2luZyA9IGZhbHNlO1xyXG5cclxuICAgIGRlc3Ryb3kkID0gbmV3IFN1YmplY3QoKTtcclxuXHJcbiAgICBjb25zdHJ1Y3RvcihcclxuICAgICAgICBwcml2YXRlIGZiOiBVbnR5cGVkRm9ybUJ1aWxkZXIsXHJcbiAgICAgICAgcHJpdmF0ZSBtYXR0ZXJwb3J0SW1wb3J0U2VydmljZTogTWF0dGVycG9ydEltcG9ydFNlcnZpY2UsXHJcbiAgICAgICAgcHJpdmF0ZSBjYXB0dXJlU2VydmljZTogQ2FwdHVyZVNlcnZpY2UsXHJcbiAgICAgICAgcHJpdmF0ZSBub2RlU2VydmljZTogTm9kZVNlcnZpY2UsXHJcbiAgICAgICAgcHJpdmF0ZSBzcGFjZVNlcnZpY2U6IFNwYWNlU2VydmljZSxcclxuICAgICAgICBwcml2YXRlIHJvdXRlOiBBY3RpdmF0ZWRSb3V0ZSxcclxuICAgICAgICBwcml2YXRlIG1vZGFsU2VydmljZTogTmdiTW9kYWwsXHJcbiAgICAgICAgcHJpdmF0ZSB2aXNpdFNlcnZpY2U6IFZpc2l0U2VydmljZSxcclxuICAgICAgICBwdWJsaWMgdmFsaWRhdG9yc1NlcnZpY2U6IFZhbGlkYXRvcnNTZXJ2aWNlLFxyXG4gICAgICAgIHByaXZhdGUgdHJhbnNsYXRlOiBUcmFuc2xhdGVTZXJ2aWNlLFxyXG4gICAgICAgIHByaXZhdGUgbmF2aWdhdG9yU2VydmljZTogTmF2aWdhdG9yU2VydmljZSxcclxuICAgICAgICBwcml2YXRlIHJvdXRlcjogUm91dGVyLFxyXG4gICAgKSB7XHJcbiAgICAgICAgdGhpcy5tYXR0ZXJwb3J0SW1wb3J0U2VydmljZS5pbXBvcnRpbmdJbWFnZXMucGlwZSh0YWtlVW50aWwodGhpcy5kZXN0cm95JCkpLnN1YnNjcmliZSgoKSA9PiB7XHJcbiAgICAgICAgICAgIHRoaXMuY2FuQ2FuY2VsSW1wb3J0ID0gdHJ1ZTtcclxuICAgICAgICB9KTtcclxuICAgICAgICB0aGlzLm1hdHRlcnBvcnRJbXBvcnRTZXJ2aWNlLnN3ZWVwUHJvY2Vzc2VkQ291bnQucGlwZSh0YWtlVW50aWwodGhpcy5kZXN0cm95JCkpLnN1YnNjcmliZSgoY291bnQpID0+IHtcclxuICAgICAgICAgICAgdGhpcy5pbWFnZXNQcm9jZXNzZWQgPSBjb3VudCArIDE7XHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgdGhpcy5tYXR0ZXJwb3J0SW1wb3J0U2VydmljZS50b3RhbFN3ZWVwc0NvdW50LnBpcGUodGFrZVVudGlsKHRoaXMuZGVzdHJveSQpKS5zdWJzY3JpYmUoKGNvdW50KSA9PiB7XHJcbiAgICAgICAgICAgIHRoaXMudG90YWxJbWFnZXMgPSBjb3VudDtcclxuICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgdGhpcy5uYXZpZ2F0b3JTZXJ2aWNlLmxvY2F0aW9uSURDaGFuZ2VcclxuICAgICAgICAgICAgLnBpcGUodGFrZVVudGlsKHRoaXMuZGVzdHJveSQpKVxyXG4gICAgICAgICAgICAuc3Vic2NyaWJlKChzcGFjZUlEKSA9PiB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLnJvdXRlci5uYXZpZ2F0ZShbXCJkYXNoYm9hcmQvbG9jYWxpc2F0aW9uXCIsIHNwYWNlSUQsIFwidmlzaXRzXCJdKTtcclxuICAgICAgICAgICAgfSk7XHJcblxyXG4gICAgICAgIHRoaXMucm91dGUucGFyYW1zLnN1YnNjcmliZSgocGFyYW1zKSA9PiB7XHJcbiAgICAgICAgICAgIHRoaXMuc3BhY2VJZCA9IHBhcmFtcy5pZDtcclxuICAgICAgICAgICAgdGhpcy5yZXNldFZpc2l0cygpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIGFzeW5jIG5nT25Jbml0KCk6IFByb21pc2U8dm9pZD4ge1xyXG4gICAgICAgIHRoaXMuc3BhY2VJZCA9IHRoaXMucm91dGUuc25hcHNob3QucGFyYW1NYXAuZ2V0KCdpZCcpO1xyXG4gICAgICAgIGF3YWl0IHRoaXMucmVzZXRWaXNpdHMoKTtcclxuICAgIH1cclxuXHJcbiAgICBuZ09uRGVzdHJveSgpIHtcclxuICAgICAgICB0aGlzLmRlc3Ryb3kkLm5leHQodHJ1ZSk7XHJcbiAgICAgICAgdGhpcy5kZXN0cm95JC5jb21wbGV0ZSgpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qXHJcbiAgICBWaXNpdCA9IHtcclxuICAgICAgY2FwdHVyZUlEOiBzdHJpbmcsXHJcbiAgICAgIG1vZGVsM2Q6IHN0cmluZyxcclxuICAgICAgdGFrZW5BdDogbnVtYmVyLFxyXG4gICAgICBzcGFjZUlEOiBzdHJpbmcsXHJcbiAgICAgIHZpZXdlcjogQ2FwdHVyZVZpZXdlcixcclxuICAgICAgc3VyZmFjZTogbnVtYmVyLFxyXG4gICAgICBub2RlOiBOb2RlLFxyXG4gICAgICBuYW1lPzogc3RyaW5nIHwgbnVsbFxyXG4gICAgfVxyXG4gICAgKi9cclxuICAgIHNldHVwTWVudUl0ZW1zKCkge1xyXG4gICAgICAgIHRoaXMubWVudUl0ZW1zID0gW1xyXG4gICAgICAgICAgICB7IGxhYmVsOiAnTG9jYXRpb25zJywgdXJsOiAnL2xvY2FsaXNhdGlvbicgfSxcclxuICAgICAgICAgICAge1xyXG4gICAgICAgICAgICAgICAgbGFiZWw6IHRoaXMuY3VycmVudFNwYWNlLm5hbWUsXHJcbiAgICAgICAgICAgICAgICB1cmw6IGAvbG9jYWxpc2F0aW9uLyR7dGhpcy5jdXJyZW50U3BhY2UuaWR9YCxcclxuICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAge1xyXG4gICAgICAgICAgICAgICAgbGFiZWw6ICdWaXJ0dWFsIHZpc2l0cycsXHJcbiAgICAgICAgICAgICAgICB1cmw6IGAvbG9jYWxpc2F0aW9uLyR7dGhpcy5jdXJyZW50U3BhY2UuaWR9L3Zpc2l0c2AsXHJcbiAgICAgICAgICAgIH0sXHJcbiAgICAgICAgXTtcclxuICAgIH1cclxuXHJcbiAgICBvbkdvQmFjaygpIHtcclxuICAgICAgICB0aGlzLm9uQ2FuY2VsKCk7XHJcbiAgICB9XHJcblxyXG4gICAgYXN5bmMgcmVzZXRWaXNpdHMoKSB7XHJcbiAgICAgICAgdGhpcy52aXNpdHMgPSBbXTtcclxuICAgICAgICB0aGlzLmN1cnJlbnRTcGFjZSA9IGF3YWl0IHRoaXMuc3BhY2VTZXJ2aWNlLmdldFNwYWNlKHRoaXMuc3BhY2VJZCk7XHJcbiAgICAgICAgdGhpcy5zZXR1cE1lbnVJdGVtcygpO1xyXG4gICAgICAgIGF3YWl0IHRoaXMudmlzaXRTZXJ2aWNlXHJcbiAgICAgICAgICAgIC5nZXRWaXNpdHNGb3JTcGFjZUZvclVzZXIodGhpcy5zcGFjZUlkKVxyXG4gICAgICAgICAgICAudGhlbigodmlzaXRzKSA9PiB7XHJcbiAgICAgICAgICAgICAgICBpZiAodmlzaXRzKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy52aXNpdHMgPSB2aXNpdHM7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIGluaXRWaXNpdEZvcm0oaW5wdXQ6IFZpc2l0ID0gbnVsbCkge1xyXG4gICAgICAgIGlmIChpbnB1dCkge1xyXG4gICAgICAgICAgICB0aGlzLnZpc2l0Rm9ybSA9IHRoaXMuZmIuZ3JvdXAoe1xyXG4gICAgICAgICAgICAgICAgY2FwdHVyZUlEOiBpbnB1dC5jYXB0dXJlSUQsXHJcbiAgICAgICAgICAgICAgICBub2RlSUQ6IGlucHV0Lm5vZGUuaWQsXHJcbiAgICAgICAgICAgICAgICBuYW1lOiBbaW5wdXQubmFtZSwgW1ZhbGlkYXRvcnMucmVxdWlyZWRdXSxcclxuICAgICAgICAgICAgICAgIG1vZGVsM0Q6IFtpbnB1dC5tb2RlbDNkLCBbVmFsaWRhdG9ycy5yZXF1aXJlZF1dLFxyXG4gICAgICAgICAgICAgICAgdmlld2VyOiBpbnB1dC52aWV3ZXIgPyBpbnB1dC52aWV3ZXIgOiBDYXB0dXJlVmlld2VyLk1BVFRFUlBPUlQsXHJcbiAgICAgICAgICAgICAgICBzdXJmYWNlOiBpbnB1dC5zdXJmYWNlID8gaW5wdXQuc3VyZmFjZSA6IG51bGwsXHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICB0aGlzLmNhcHR1cmVEYXRlID0gaW5wdXQudGFrZW5BdDtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICB0aGlzLnZpc2l0Rm9ybSA9IHRoaXMuZmIuZ3JvdXAoe1xyXG4gICAgICAgICAgICAgICAgbW9kZWwzRDogW251bGwsIFtWYWxpZGF0b3JzLnJlcXVpcmVkXV0sXHJcbiAgICAgICAgICAgICAgICB2aWV3ZXI6IENhcHR1cmVWaWV3ZXIuTUFUVEVSUE9SVCxcclxuICAgICAgICAgICAgICAgIHN1cmZhY2U6IG51bGwsXHJcbiAgICAgICAgICAgICAgICBuYW1lOiBbbnVsbCwgW1ZhbGlkYXRvcnMucmVxdWlyZWRdXSxcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIGFzeW5jIG9uVG9nZ2xlRGV0YWlsKGluZGV4KSB7XHJcbiAgICAgICAgdGhpcy52aXNpdEluZGV4RGV0YWlscyA9IGluZGV4ID09PSB0aGlzLnZpc2l0SW5kZXhEZXRhaWxzID8gLTEgOiBpbmRleDtcclxuICAgICAgICB0aGlzLmltYWdlc1VwbG9hZGVkID0gYXdhaXQgdGhpcy5tYXR0ZXJwb3J0SW1wb3J0U2VydmljZS5nZXRVcGxvYWRlZEltYWdlQ291bnQodGhpcy52aXNpdHNbaW5kZXhdLm1vZGVsM2QpO1xyXG4gICAgfVxyXG5cclxuICAgIG9uQWRkVmlzaXQoKSB7XHJcbiAgICAgICAgdGhpcy5pbml0VmlzaXRGb3JtKCk7XHJcbiAgICAgICAgdGhpcy5tZW51SXRlbXMucHVzaCh7IGxhYmVsOiAnTmV3JyB9KTtcclxuICAgIH1cclxuXHJcbiAgICBvbkVkaXQodmlzaXQpIHtcclxuICAgICAgICB0aGlzLmluaXRWaXNpdEZvcm0odmlzaXQpO1xyXG4gICAgICAgIHRoaXMuaXNFZGl0aW5nID0gdHJ1ZTtcclxuICAgICAgICB0aGlzLm1lbnVJdGVtcy5wdXNoKHsgbGFiZWw6IHZpc2l0Lm5hbWUgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgYXN5bmMgb25TdWJtaXRWaXNpdCgpIHtcclxuICAgICAgICB0aGlzLnZpc2l0U3VibWl0dGVkID0gdHJ1ZTtcclxuICAgICAgICBpZiAoIXRoaXMudmlzaXRGb3JtLnZhbGlkKSB7XHJcbiAgICAgICAgICAgIHRoaXMuZXJyb3JGb3JtID0gdHJ1ZTtcclxuICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgIH1cclxuICAgICAgICB0aGlzLmVycm9yRm9ybSA9IGZhbHNlO1xyXG4gICAgICAgIGNvbnN0IGZvcm1WYWx1ZSA9IHRoaXMudmlzaXRGb3JtLnZhbHVlO1xyXG4gICAgICAgIGNvbnN0IGNhcHR1cmUgPSB7XHJcbiAgICAgICAgICAgIHZpZXdlcjogZm9ybVZhbHVlLnZpZXdlcixcclxuICAgICAgICAgICAgdGFrZW5BdDogdGhpcy5jYXB0dXJlRGF0ZSxcclxuICAgICAgICAgICAgc3VyZmFjZTogZm9ybVZhbHVlLnN1cmZhY2UsXHJcbiAgICAgICAgICAgIHNwYWNlSUQ6IHRoaXMuY3VycmVudFNwYWNlLmlkLFxyXG4gICAgICAgIH0gYXMgQ2FwdHVyZTtcclxuXHJcbiAgICAgICAgaWYgKHRoaXMuaXNFZGl0aW5nKSB7XHJcbiAgICAgICAgICAgIGNhcHR1cmUuaWQgPSBmb3JtVmFsdWUuY2FwdHVyZUlEO1xyXG4gICAgICAgICAgICBhd2FpdCB0aGlzLmNhcHR1cmVTZXJ2aWNlLnVwZGF0ZUNhcHR1cmUoY2FwdHVyZSk7XHJcbiAgICAgICAgICAgIGNvbnN0IG5vZGUgPSB7XHJcbiAgICAgICAgICAgICAgICBpZDogZm9ybVZhbHVlLm5vZGVJRCxcclxuICAgICAgICAgICAgICAgIG1vZGVsM0Q6IGZvcm1WYWx1ZS5tb2RlbDNELFxyXG4gICAgICAgICAgICAgICAgbWV0YWRhdGE6IGZvcm1WYWx1ZS5uYW1lLFxyXG4gICAgICAgICAgICB9IGFzIE5vZGU7XHJcbiAgICAgICAgICAgIGF3YWl0IHRoaXMubm9kZVNlcnZpY2UudXBkYXRlTm9kZShub2RlKTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICBsZXQgY3JlYXRlZE5vZGU7XHJcbiAgICAgICAgICAgIGF3YWl0IHRoaXMuY2FwdHVyZVNlcnZpY2UuY3JlYXRlQ2FwdHVyZShjYXB0dXJlKS50aGVuKGFzeW5jIChyZXMpID0+IHtcclxuICAgICAgICAgICAgICAgIGlmIChyZXMpIHtcclxuICAgICAgICAgICAgICAgICAgICBjb25zdCBub2RlID0ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBtb2RlbDNEOiBmb3JtVmFsdWUubW9kZWwzRCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgY2FwdHVyZUlEOiByZXMuaWQsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIG1ldGFkYXRhOiBmb3JtVmFsdWUubmFtZSxcclxuICAgICAgICAgICAgICAgICAgICB9IGFzIE5vZGU7XHJcbiAgICAgICAgICAgICAgICAgICAgY3JlYXRlZE5vZGUgPSBhd2FpdCB0aGlzLm5vZGVTZXJ2aWNlLmNyZWF0ZU5vZGUobm9kZSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICB0aGlzLmxhdW5jaEltcG9ydChcclxuICAgICAgICAgICAgICAgIGZvcm1WYWx1ZS5tb2RlbDNELFxyXG4gICAgICAgICAgICAgICAgZm9ybVZhbHVlLnN1cmZhY2UsXHJcbiAgICAgICAgICAgICAgICBjcmVhdGVkTm9kZSxcclxuICAgICAgICAgICAgICAgIGZhbHNlXHJcbiAgICAgICAgICAgIClcclxuICAgICAgICAgICAgICAgIC50aGVuKChzdWNjZXNzKSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5tb2RhbFJlZmVyZW5jZS5jbG9zZSgnaW1wb3J0IGVuZGVkIHdpdGggc3VjY2VzcycpO1xyXG4gICAgICAgICAgICAgICAgfSlcclxuICAgICAgICAgICAgICAgIC5jYXRjaCgoZSkgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMubW9kYWxSZWZlcmVuY2UuY2xvc2UoYEVycm9yIHdoaWxlIGltcG9ydDogJHtlfWApO1xyXG4gICAgICAgICAgICAgICAgICAgIGFsZXJ0KGBFcnJvciB3aGlsZSBpbXBvcnQ6ICR7ZX0gJHtKU09OLnN0cmluZ2lmeShlKX1gKTtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLm9uRGVsZXRlKHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgbm9kZTogY3JlYXRlZE5vZGUsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNhcHR1cmVJRDogY3JlYXRlZE5vZGUuY2FwdHVyZUlELFxyXG4gICAgICAgICAgICAgICAgICAgIH0gYXMgVmlzaXQsIGZhbHNlKTtcclxuICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIH1cclxuICAgICAgICBhd2FpdCB0aGlzLnJlc2V0VmlzaXRzKCk7XHJcbiAgICAgICAgdGhpcy5vbkNhbmNlbCgpO1xyXG4gICAgfVxyXG5cclxuICAgIGdldCBtb2RlbDNEKCk6IEFic3RyYWN0Q29udHJvbCB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMudmlzaXRGb3JtLmdldCgnbW9kZWwzRCcpO1xyXG4gICAgfVxyXG5cclxuICAgIGdldCBuYW1lKCk6IEFic3RyYWN0Q29udHJvbCB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMudmlzaXRGb3JtLmdldCgnbmFtZScpO1xyXG4gICAgfVxyXG5cclxuICAgIG9uQ2FuY2VsKCkge1xyXG4gICAgICAgIHRoaXMudmlzaXRTdWJtaXR0ZWQgPSBmYWxzZTtcclxuICAgICAgICB0aGlzLnZpc2l0Rm9ybSA9IG51bGw7XHJcbiAgICAgICAgdGhpcy5pc0VkaXRpbmcgPSBmYWxzZTtcclxuICAgICAgICB0aGlzLmNhbkNhbmNlbEltcG9ydCA9IGZhbHNlO1xyXG4gICAgICAgIHRoaXMudG90YWxJbWFnZXMgPSAwO1xyXG4gICAgICAgIHRoaXMuaW1hZ2VzUHJvY2Vzc2VkID0gMDtcclxuICAgICAgICB0aGlzLmVycm9yRm9ybSA9IGZhbHNlO1xyXG4gICAgICAgIHRoaXMuc2V0dXBNZW51SXRlbXMoKTtcclxuICAgIH1cclxuXHJcbiAgICBhc3luYyBvbkRlbGV0ZSh2aXNpdDogVmlzaXQsIG5lZWRQZXJtaXNzaW9uID0gdHJ1ZSkge1xyXG4gICAgICAgIGNvbnN0IG1lc3NhZ2UgPSB0aGlzLnRyYW5zbGF0ZS5pbnN0YW50KCdjb25maXJtLmRlbGV0ZVZpc2l0Jyk7XHJcbiAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWFsZXJ0XHJcbiAgICAgICAgaWYgKHdpbmRvdy5jb25maXJtKG1lc3NhZ2UpIHx8ICFuZWVkUGVybWlzc2lvbikge1xyXG4gICAgICAgICAgICBjb25zb2xlLmxvZyh0aGlzLnZpc2l0SW5kZXhEZXRhaWxzKTtcclxuICAgICAgICAgICAgdGhpcy5pc1Byb2Nlc3NpbmcgPSB0cnVlO1xyXG4gICAgICAgICAgICBhd2FpdCB0aGlzLnZpc2l0U2VydmljZS5kZWxldGVWaXNpdCh2aXNpdCwgdGhpcy5zcGFjZUlkKTtcclxuICAgICAgICAgICAgYXdhaXQgdGhpcy5yZXNldFZpc2l0cygpO1xyXG4gICAgICAgICAgICB0aGlzLmlzUHJvY2Vzc2luZyA9IGZhbHNlO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIGdldERpc21pc3NSZWFzb24ocmVhc29uOiBhbnkpOiBzdHJpbmcge1xyXG4gICAgICAgIGlmIChyZWFzb24gPT09IE1vZGFsRGlzbWlzc1JlYXNvbnMuRVNDKSB7XHJcbiAgICAgICAgICAgIHJldHVybiAnYnkgcHJlc3NpbmcgRVNDJztcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKHJlYXNvbiA9PT0gTW9kYWxEaXNtaXNzUmVhc29ucy5CQUNLRFJPUF9DTElDSykge1xyXG4gICAgICAgICAgICByZXR1cm4gJ2J5IGNsaWNraW5nIG9uIGEgYmFja2Ryb3AnO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gYHdpdGg6ICR7cmVhc29ufWA7XHJcbiAgICB9XHJcblxyXG4gICAgYXN5bmMgbGF1bmNoSW1wb3J0KFxyXG4gICAgICAgIG1vZGVsM0QsXHJcbiAgICAgICAgc3VyZmFjZSxcclxuICAgICAgICBub2RlLFxyXG4gICAgICAgIGltYWdlc09ubHkgPSBmYWxzZSxcclxuICAgICAgICBvdmVycmlkZUV4aXN0aW5nID0gZmFsc2UsXHJcbiAgICApIHtcclxuICAgICAgICB0aGlzLm1vZGFsUmVmZXJlbmNlID0gdGhpcy5tb2RhbFNlcnZpY2Uub3Blbih0aGlzLmNvbnRlbnQsIHtcclxuICAgICAgICAgICAgYXJpYUxhYmVsbGVkQnk6IFwibW9kYWwtYmFzaWMtdGl0bGVcIixcclxuICAgICAgICB9KTtcclxuICAgICAgICB0aGlzLm1vZGFsUmVmZXJlbmNlLnJlc3VsdC50aGVuKFxyXG4gICAgICAgICAgICAocmVzdWx0KSA9PiB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmNsb3NlUmVzdWx0ID0gYENsb3NlZCB3aXRoOiAke3Jlc3VsdH1gO1xyXG4gICAgICAgICAgICAgICAgY29uc29sZS5sb2codGhpcy5jbG9zZVJlc3VsdCk7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmNhbmNlbEltcG9ydCgpO1xyXG4gICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICAoZXJyb3IpID0+IHtcclxuICAgICAgICAgICAgICAgIHRoaXMuY2xvc2VSZXN1bHQgPSBgRGlzbWlzc2VkICR7dGhpcy5nZXREaXNtaXNzUmVhc29uKGVycm9yKX1gO1xyXG4gICAgICAgICAgICAgICAgY29uc29sZS5sb2codGhpcy5jbG9zZVJlc3VsdCk7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmNhbmNlbEltcG9ydCgpO1xyXG4gICAgICAgICAgICB9LFxyXG4gICAgICAgICk7XHJcbiAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgYXdhaXQgdGhpcy5tYXR0ZXJwb3J0SW1wb3J0U2VydmljZS5pbml0U2RrRm9yTW9kZWwobW9kZWwzRCk7XHJcblxyXG4gICAgICAgICAgICBhd2FpdCB0aGlzLm1hdHRlcnBvcnRJbXBvcnRTZXJ2aWNlLmltcG9ydERhdGEoXHJcbiAgICAgICAgICAgICAgICB0aGlzLnNwYWNlSWQsXHJcbiAgICAgICAgICAgICAgICBzdXJmYWNlLFxyXG4gICAgICAgICAgICAgICAgaW1hZ2VzT25seSxcclxuICAgICAgICAgICAgICAgIG5vZGUsXHJcbiAgICAgICAgICAgICAgICBvdmVycmlkZUV4aXN0aW5nXHJcbiAgICAgICAgICAgICk7XHJcblxyXG4gICAgICAgICAgICB0aGlzLm1vZGFsUmVmZXJlbmNlLmNsb3NlKCk7XHJcblxyXG4gICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XHJcbiAgICAgICAgICAgIGNvbnNvbGUubG9nKGVycm9yKTtcclxuICAgICAgICAgICAgUHJvbWlzZS5yZWplY3QoZXJyb3IpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIGNhbmNlbEltcG9ydCgpIHtcclxuICAgICAgICB0aGlzLm1hdHRlcnBvcnRJbXBvcnRTZXJ2aWNlLmFiYW5kb24oKTtcclxuICAgICAgICB0aGlzLm9uQ2FuY2VsKCk7XHJcbiAgICAgICAgdGhpcy5yZXNldFZpc2l0cygpO1xyXG4gICAgfVxyXG5cclxuICAgIG9uSW1wb3J0SW1hZ2VzKHZpc2l0OiBWaXNpdCwgb3ZlcnJpZGVFeGlzdGluZykge1xyXG4gICAgICAgIHRoaXMubGF1bmNoSW1wb3J0KHZpc2l0Lm1vZGVsM2QsIG51bGwsIHZpc2l0Lm5vZGUuaWQsIHRydWUsIG92ZXJyaWRlRXhpc3RpbmcpO1xyXG4gICAgfVxyXG5cclxuICAgIGlzRm9ybUVycm9yKGNvbnRyb2wpIHtcclxuICAgICAgICByZXR1cm4gY29udHJvbCAmJiBjb250cm9sLmludmFsaWQgJiYgdGhpcy5lcnJvckZvcm07XHJcbiAgICB9XHJcbn1cclxuIiwiPGRpdiBjbGFzcz1cImNvbnRhaW5lci1mbHVpZFwiIGNsYXNzPVwiZGFzaGJvYXJkLXRhYlwiPlxyXG4gICAgPGRpdiBjbGFzcz1cIm0tM1wiPlxyXG4gICAgICAgIDxsaWItdGFiLW5hdmlnYXRpb24gW21lbnVJdGVtc109J21lbnVJdGVtcycgKG9uR29CYWNrKT1cIm9uR29CYWNrKClcIj48L2xpYi10YWItbmF2aWdhdGlvbj5cclxuICAgIDwvZGl2PlxyXG5cclxuICAgIDxkaXYgY2xhc3M9XCJyb3cgbWFpbi1mb3JtLWNvbnRhaW5lclwiPlxyXG4gICAgICAgIDxkaXYgY2xhc3M9XCJjb2wtbWQtNiBmb3JtLWNvbnRhaW5lclwiPlxyXG4gICAgICAgICAgICA8dWwgY2xhc3M9XCJsaXN0LWdyb3VwIGxpc3QtZ3JvdXAtZmx1c2hcIiAqbmdJZj1cIiF2aXNpdEZvcm1cIj5cclxuICAgICAgICAgICAgICAgIDxsaSBjbGFzcz1cImxpc3QtZ3JvdXAtaXRlbSBsaXN0LWdyb3VwLWl0ZW0tYWN0aW9uXCIgKm5nRm9yPVwibGV0IHZpc2l0IG9mIHZpc2l0czsgaW5kZXggYXMgaW5kZXhcIj5cclxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZC1mbGV4IGp1c3RpZnktY29udGVudC1iZXR3ZWVuIGFsaWduLWl0ZW1zLWNlbnRlclwiIChjbGljayk9XCJvblRvZ2dsZURldGFpbChpbmRleClcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAge3t2aXNpdC5uYW1lID8gdmlzaXQubmFtZSA6IHZpc2l0Lm1vZGVsM2QgfX1cclxuICAgICAgICAgICAgICAgICAgICAgICAgPGxpYi1jaGV2cm9uIFtjb25kaXRpb25TaG93aW5nXT1cImluZGV4PT12aXNpdEluZGV4RGV0YWlsc1wiPjwvbGliLWNoZXZyb24+XHJcbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgPGRpdiAqbmdJZj1cImluZGV4PT12aXNpdEluZGV4RGV0YWlsc1wiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8dWwgY2xhc3M9XCJsaXN0LWdyb3VwIGxpc3QtZ3JvdXAtZmx1c2hcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxsaSBjbGFzcz1cImxpc3QtZ3JvdXAtaXRlbSBiZy10cmFuc3BhcmVudFwiPnt7J05hbWUnIHwgdHJhbnNsYXRlfX0gOiB7eyB2aXNpdC5uYW1lID9cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2aXNpdC5uYW1lIDogXCJOb3QgcHJvdmlkZWRcIiB8IHRyYW5zbGF0ZX19PC9saT5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxsaSBjbGFzcz1cImxpc3QtZ3JvdXAtaXRlbSBiZy10cmFuc3BhcmVudFwiPnt7JzNEIE1vZGVsJyB8IHRyYW5zbGF0ZX19IDoge3sgdmlzaXQubW9kZWwzZCB9fVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9saT5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxsaSBjbGFzcz1cImxpc3QtZ3JvdXAtaXRlbSBiZy10cmFuc3BhcmVudFwiPnt7J1N1cmZhY2UnIHwgdHJhbnNsYXRlfX0sIG08c3VwPjI8L3N1cD46IHt7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmlzaXQuc3VyZmFjZSA/XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmlzaXQuc3VyZmFjZSA6ICdOb3QgcHJvdmlkZWQnIHwgdHJhbnNsYXRlfX08L2xpPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGxpIGNsYXNzPVwibGlzdC1ncm91cC1pdGVtIGJnLXRyYW5zcGFyZW50XCI+e3snVmlld2VyJyB8IHRyYW5zbGF0ZX19IDoge3sgdmlzaXQudmlld2VyIH19XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2xpPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGxpIGNsYXNzPVwibGlzdC1ncm91cC1pdGVtIGJnLXRyYW5zcGFyZW50XCI+e3snRGF0ZSBvZiBjYXB0dXJlJyB8IHRyYW5zbGF0ZX19IDoge3tcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2aXNpdC50YWtlbkF0IHwgdGltZURhdGVTdHJpbmcgfCBhc3luY319XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGxpIGNsYXNzPVwibGlzdC1ncm91cC1pdGVtIGJnLXRyYW5zcGFyZW50XCI+e3snSW1hZ2VzIGFyZSBpbXBvcnRlZCcgfCB0cmFuc2xhdGV9fSA6IHt7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGltYWdlc1VwbG9hZGVkIH19XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9saT5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPC91bD5cclxuICAgICAgICAgICAgICAgICAgICAgICAgXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDxsaWItbG9hZGVyICpuZ0lmPVwiaXNQcm9jZXNzaW5nXCI+PC9saWItbG9hZGVyPlxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImFjdGlvbi1idXR0b24tY29udGFpbmVyIG10LTNcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgY2xhc3M9XCJidG4gYnRuLW91dGxpbmUtcHJpbWFyeSByb3VuZGVkLXBpbGwgbWUtMlwiIChjbGljayk9XCJvbkltcG9ydEltYWdlcyh2aXNpdCwgdHJ1ZSlcIiBbZGlzYWJsZWRdPVwiaXNQcm9jZXNzaW5nXCI+e3snSW1wb3J0IGFsbCBpbWFnZXMnIHxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyYW5zbGF0ZX19PC9idXR0b24+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiAqbmdJZj1cImltYWdlc1VwbG9hZGVkID4gMFwiIGNsYXNzPVwiYnRuIGJ0bi1vdXRsaW5lLXByaW1hcnkgcm91bmRlZC1waWxsIG1lLTJcIiAoY2xpY2spPVwib25JbXBvcnRJbWFnZXModmlzaXQsIGZhbHNlKVwiIFtkaXNhYmxlZF09XCJpc1Byb2Nlc3NpbmdcIj57eydJbXBvcnQgZnJvbSBpbWFnZScgfFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyYW5zbGF0ZX19IHt7aW1hZ2VzVXBsb2FkZWR9fTwvYnV0dG9uPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBjbGFzcz1cImJ0biBidG4tb3V0bGluZS1wcmltYXJ5IHJvdW5kZWQtcGlsbCBtZS0yXCIgW2Rpc2FibGVkXT1cImlzUHJvY2Vzc2luZ1wiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAoY2xpY2spPVwib25FZGl0KHZpc2l0KVwiPnt7J0VkaXQnIHwgdHJhbnNsYXRlfX08L2J1dHRvbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgY2xhc3M9XCJidG4gYnRuLW91dGxpbmUtcHJpbWFyeSByb3VuZGVkLXBpbGxcIiBbZGlzYWJsZWRdPVwiaXNQcm9jZXNzaW5nXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIChjbGljayk9XCJvbkRlbGV0ZSh2aXNpdClcIj57eydEZWxldGUnIHwgdHJhbnNsYXRlfX08L2J1dHRvbj5cclxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgIDwvbGk+XHJcbiAgICAgICAgICAgIDwvdWw+XHJcbiAgICAgICAgICAgIDxkaXYgKm5nSWY9XCJ2aXNpdEZvcm1cIj5cclxuICAgICAgICAgICAgICAgIDxmb3JtIChuZ1N1Ym1pdCk9XCJvblN1Ym1pdFZpc2l0KClcIiBbZm9ybUdyb3VwXT1cInZpc2l0Rm9ybVwiPlxyXG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJtYi0zIHJvd1wiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJjb2wtc20tMiBjb2wtZm9ybS1sYWJlbFwiPnt7J05hbWUnIHwgdHJhbnNsYXRlfX08L2xhYmVsPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY29sLXNtLTEwXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW5wdXQgdHlwZT1cInRleHRcIiBjbGFzcz1cImZvcm0tY29udHJvbFwiIGZvcm1Db250cm9sTmFtZT1cIm5hbWVcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm1iLTMgcm93XCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cImNvbC1zbS0yIGNvbC1mb3JtLWxhYmVsXCI+e3snUmVmZXJlbmNlIDNEIG1vZGVsJyB8IHRyYW5zbGF0ZX19ICo8L2xhYmVsPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY29sLXNtLTEwXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW5wdXQgdHlwZT1cInRleHRcIiBjbGFzcz1cImZvcm0tY29udHJvbFwiIFtyZWFkb25seV09XCJpc0VkaXRpbmdcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtjbGFzcy5pcy1pbnZhbGlkXT1cIm1vZGVsM0QuaW52YWxpZCAmJiB2aXNpdFN1Ym1pdHRlZFwiIHJlcXVpcmVkXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9ybUNvbnRyb2xOYW1lPVwibW9kZWwzRFwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImludmFsaWQtZmVlZGJhY2tcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bmdiLWFsZXJ0IGRhdGEtdGVzdGlkPVwibmV3LWxvY2F0aW9uLW5hbWUtaW52YWxpZFwiIFtkaXNtaXNzaWJsZV09XCJmYWxzZVwiIHR5cGU9XCJkYW5nZXJcIiBcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqbmdJZj1cInZhbGlkYXRvcnNTZXJ2aWNlLmlzQ29udHJvbEVycm9yKHZpc2l0Rm9ybS5jb250cm9sc1snbmFtZSddKSBcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfHwgIGlzRm9ybUVycm9yKHZpc2l0Rm9ybS5jb250cm9sc1snbmFtZSddKVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt7dmFsaWRhdG9yc1NlcnZpY2UuZ2V0RXJyb3IodmlzaXRGb3JtLmNvbnRyb2xzWyduYW1lJ10pIHwgdHJhbnNsYXRlfX1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L25nYi1hbGVydD5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiAqbmdJZj1cImlzRWRpdGluZ1wiIGNsYXNzPVwidGV4dC1kYW5nZXJcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7eydDYW5ub3QgY2hhbmdlIDNEIG1vZGVsIHJlZmVyZW5jZS4gUGxlYXNlIGFkZCBuZXcgbW9kZWwuJyB8IHRyYW5zbGF0ZX19XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJtYi0zIHJvd1wiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJjb2wtc20tMiBjb2wtZm9ybS1sYWJlbFwiPnt7J1ZpZXdlcicgfCB0cmFuc2xhdGV9fTwvbGFiZWw+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjb2wtc20tMTBcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dCB0eXBlPVwidGV4dFwiIGNsYXNzPVwiZm9ybS1jb250cm9sXCIgZm9ybUNvbnRyb2xOYW1lPVwidmlld2VyXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG5cclxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibWItMyByb3dcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwiY29sLXNtLTIgY29sLWZvcm0tbGFiZWxcIj57eydTdXJmYWNlJyB8IHRyYW5zbGF0ZX19PC9sYWJlbD5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNvbC1zbS0xMFwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJ0ZXh0XCIgY2xhc3M9XCJmb3JtLWNvbnRyb2xcIiBmb3JtQ29udHJvbE5hbWU9XCJzdXJmYWNlXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG5cclxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibWItMyByb3dcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwiY29sLXNtLTIgY29sLWZvcm0tbGFiZWxcIj57eydDYXB0dXJlIERhdGUnIHwgdHJhbnNsYXRlfX08L2xhYmVsPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiaW5wdXQtZ3JvdXBcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dCBjbGFzcz1cImZvcm0tY29udHJvbFwiIHBsYWNlaG9sZGVyPVwiZGQvbW0veXl5eVwiIFsobmdNb2RlbCldPVwiY2FwdHVyZURhdGVcIiBuZ2JEYXRlcGlja2VyXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgI2QxPVwibmdiRGF0ZXBpY2tlclwiIFtuZ01vZGVsT3B0aW9uc109XCJ7c3RhbmRhbG9uZTogdHJ1ZX1cIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJpbnB1dC1ncm91cC1hcHBlbmRcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8YnV0dG9uIGNsYXNzPVwiYnRuIGJ0bi1vdXRsaW5lLXNlY29uZGFyeSBjYWxlbmRhclwiIChjbGljayk9XCJkMS50b2dnbGUoKVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGU9XCJidXR0b25cIj48L2J1dHRvbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICA8YnV0dG9uIHR5cGU9XCJzdWJtaXRcIiBjbGFzcz1cImJ0biBidG4tb3V0bGluZS1wcmltYXJ5IHJvdW5kZWQtcGlsbCBtZS0yXCI+e3snU2F2ZScgfFxyXG4gICAgICAgICAgICAgICAgICAgICAgICB0cmFuc2xhdGV9fTwvYnV0dG9uPlxyXG4gICAgICAgICAgICAgICAgICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIChjbGljayk9XCJvbkNhbmNlbCgpXCIgY2xhc3M9XCJidG4gYnRuLW91dGxpbmUtcHJpbWFyeSByb3VuZGVkLXBpbGxcIj57eydDYW5jZWwnIHxcclxuICAgICAgICAgICAgICAgICAgICAgICAgdHJhbnNsYXRlfX08L2J1dHRvbj5cclxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiaW52YWxpZC1mZWVkYmFja1wiICpuZ0lmPVwiZXJyb3JGb3JtXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bmdiLWFsZXJ0IGRhdGEtdGVzdGlkPVwibmV3LWxvY2F0aW9uLWZvcm0taW52YWxpZFwiIFtkaXNtaXNzaWJsZV09XCJmYWxzZVwiIHR5cGU9XCJkYW5nZXJcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge3snZXJyb3JGb3JtLmluZm9CdG4nIHx0cmFuc2xhdGV9fVxyXG4gICAgICAgICAgICAgICAgICAgICAgXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L25nYi1hbGVydD5cclxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgIDwvZm9ybT5cclxuICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgIDxkaXYgKm5nSWY9XCIhdmlzaXRGb3JtXCI+XHJcbiAgICAgICAgICAgICAgICA8YnV0dG9uIGNsYXNzPVwiYnRuIGJ0bi1vdXRsaW5lLXByaW1hcnkgcm91bmRlZC1waWxsXCIgKGNsaWNrKT1cIm9uQWRkVmlzaXQoKVwiPnt7J0FkZCAzRCB2aXNpdCcgfFxyXG4gICAgICAgICAgICAgICAgICAgIHRyYW5zbGF0ZX19PC9idXR0b24+XHJcbiAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgIDwvZGl2PlxyXG4gICAgICAgIDxkaXYgaWQ9XCJ2aWV3ZXItZnJhbWVcIiBzdHlsZT1cIndpZHRoOiAxMDAlOyBhc3BlY3QtcmF0aW86IDIvMTtcIj48L2Rpdj5cclxuICAgIDwvZGl2PlxyXG4gICAgPG5nLXRlbXBsYXRlICNjb250ZW50IGxldC1tb2RhbD5cclxuICAgICAgICA8ZGl2IGNsYXNzPVwibW9kYWwtaGVhZGVyXCI+XHJcbiAgICAgICAgICAgIDxoNCBjbGFzcz1cIm1vZGFsLXRpdGxlXCIgaWQ9XCJtb2RhbC1iYXNpYy10aXRsZVwiPnt7J0ltcG9ydGluZyBEYXRhJyB8IHRyYW5zbGF0ZX19PC9oND5cclxuICAgICAgICAgICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgY2xhc3M9XCJjbG9zZVwiIGFyaWEtbGFiZWw9XCJDbG9zZVwiIChjbGljayk9XCJtb2RhbC5kaXNtaXNzKCdDcm9zcyBjbGljaycpXCI+XHJcbiAgICAgICAgICAgICAgICA8c3BhbiBhcmlhLWhpZGRlbj1cInRydWVcIj7Dlzwvc3Bhbj5cclxuICAgICAgICAgICAgPC9idXR0b24+XHJcbiAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgPGRpdiBjbGFzcz1cIm1vZGFsLWJvZHlcIj5cclxuICAgICAgICAgICAge3snUGxlYXNlIGRvIG5vdCBsZWF2ZSBvciByZWZyZXNoIHRoaXMgcGFnZS4uLicgfCB0cmFuc2xhdGV9fVxyXG4gICAgICAgICAgICA8ZGl2ICpuZ0lmPVwidG90YWxJbWFnZXMgIT0gMFwiPkltcG9ydGVkIHt7aW1hZ2VzUHJvY2Vzc2VkfX0gb3V0IG9mIHt7dG90YWxJbWFnZXN9fSBpbWFnZXMuPC9kaXY+XHJcbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJkLWZsZXgganVzdGlmeS1jb250ZW50LWNlbnRlclwiPlxyXG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInNwaW5uZXItYm9yZGVyXCIgcm9sZT1cInN0YXR1c1wiPlxyXG4gICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwidmlzdWFsbHktaGlkZGVuXCI+e3snTG9hZGluZycgfCB0cmFuc2xhdGV9fS4uLjwvc3Bhbj5cclxuICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICA8L2Rpdj5cclxuICAgICAgICA8ZGl2IGNsYXNzPVwibW9kYWwtZm9vdGVyXCI+XHJcbiAgICAgICAgICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIGNsYXNzPVwiYnRuIGJ0bi1vdXRsaW5lLWRhcmtcIiBbZGlzYWJsZWRdPVwiIWNhbkNhbmNlbEltcG9ydFwiXHJcbiAgICAgICAgICAgICAgICAoY2xpY2spPVwibW9kYWwuY2xvc2UoJ0NhbmNlbCBjbGljaycpXCI+e3snQ2FuY2VsIGltcG9ydCBvZiBpbWFnZXMnIHwgdHJhbnNsYXRlfX08L2J1dHRvbj5cclxuICAgICAgICA8L2Rpdj5cclxuICAgIDwvbmctdGVtcGxhdGU+XHJcbjwvZGl2PiJdfQ==
326
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmlzaXRzLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL25neC1zbWFydGVycGxhbi1sb2NhdGlvbnMvc3JjL2xpYi9jb21wb25lbnRzL3Zpc2l0cy92aXNpdHMuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvbmd4LXNtYXJ0ZXJwbGFuLWxvY2F0aW9ucy9zcmMvbGliL2NvbXBvbmVudHMvdmlzaXRzL3Zpc2l0cy5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsU0FBUyxFQUFVLFNBQVMsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUM3RCxPQUFPLEVBR0gsVUFBVSxHQUViLE1BQU0sZ0JBQWdCLENBQUM7QUFFeEIsT0FBTyxFQUFZLG1CQUFtQixFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFDM0UsT0FBTyxFQVVILGFBQWEsR0FJaEIsTUFBTSxtQ0FBbUMsQ0FBQztBQUUzQyxPQUFPLEVBQUUsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLE1BQU0sQ0FBQzs7Ozs7Ozs7OztBQU8xQyxNQUFNLE9BQU8sZUFBZTtJQXdDWjtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDRDtJQUNDO0lBQ0E7SUFDQTtJQW5EWixPQUFPLENBQVM7SUFFaEIsaUJBQWlCLEdBQUcsQ0FBQyxDQUFDLENBQUM7SUFFdkIsU0FBUyxDQUFtQjtJQUU1QixTQUFTLEdBQVksS0FBSyxDQUFDO0lBRTNCLGNBQWMsR0FBWSxLQUFLLENBQUM7SUFFaEMsV0FBVyxDQUFTO0lBRXBCLFlBQVksR0FBRyxFQUFFLEtBQUssRUFBRSxFQUFFLEVBQVMsQ0FBQztJQUVwQyxNQUFNLEdBQVksRUFBRSxDQUFDO0lBRXJCLFdBQVcsQ0FBUztJQUU2QixPQUFPLENBQUM7SUFFekQsY0FBYyxDQUFNO0lBRXBCLGVBQWUsR0FBRyxLQUFL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Q3ZDLElBQUksQ0FBQyxRQUFRLEVBQUUsQ0FBQztRQUNoQixJQUFJLENBQUMsV0FBVyxFQUFFLENBQUM7SUFDdkIsQ0FBQztJQUVELGNBQWMsQ0FBQyxLQUFZLEVBQUUsZ0JBQWdCO1FBQ3pDLElBQUksQ0FBQyxZQUFZLENBQUMsS0FBSyxDQUFDLE9BQU8sRUFBRSxJQUFJLEVBQUUsS0FBSyxDQUFDLElBQUksQ0FBQyxFQUFFLEVBQUUsS0FBSyxDQUFDLE1BQU0sRUFBRSxJQUFJLEVBQUUsZ0JBQWdCLEVBQUUsS0FBSyxDQUFDLGVBQWUsQ0FBQyxDQUFDO0lBQ3ZILENBQUM7SUFFRCxXQUFXLENBQUMsT0FBTztRQUNmLE9BQU8sT0FBTyxJQUFJLE9BQU8sQ0FBQyxPQUFPLElBQUksSUFBSSxDQUFDLFNBQVMsQ0FBQztJQUN4RCxDQUFDO3dHQTVXUSxlQUFlOzRGQUFmLGVBQWUsc0pDaEM1Qix3elVBaUtNOzs0RkRqSU8sZUFBZTtrQkFMM0IsU0FBUzsrQkFDSSxZQUFZO29iQXVCMkIsT0FBTztzQkFBdkQsU0FBUzt1QkFBQyxTQUFTLEVBQUUsRUFBRSxNQUFNLEVBQUUsS0FBSyxFQUFFIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29tcG9uZW50LCBPbkluaXQsIFZpZXdDaGlsZCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHtcbiAgICBVbnR5cGVkRm9ybUdyb3VwLFxuICAgIFVudHlwZWRGb3JtQnVpbGRlcixcbiAgICBWYWxpZGF0b3JzLFxuICAgIEFic3RyYWN0Q29udHJvbCxcbn0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xuaW1wb3J0IHsgQWN0aXZhdGVkUm91dGUsIFJvdXRlciB9IGZyb20gJ0Bhbmd1bGFyL3JvdXRlcic7XG5pbXBvcnQgeyBOZ2JNb2RhbCwgTW9kYWxEaXNtaXNzUmVhc29ucyB9IGZyb20gJ0BuZy1ib290c3RyYXAvbmctYm9vdHN0cmFwJztcbmltcG9ydCB7XG4gICAgTm9kZSxcbiAgICBWaXNpdCxcbiAgICBNZW51SXRlbSxcbiAgICBNYXR0ZXJwb3J0SW1wb3J0U2VydmljZSxcbiAgICBUaHJlZUpzSW1wb3J0U2VydmljZSxcbiAgICBDYXB0dXJlU2VydmljZSxcbiAgICBOb2RlU2VydmljZSxcbiAgICBTcGFjZVNlcnZpY2UsXG4gICAgVmlzaXRTZXJ2aWNlLFxuICAgIENhcHR1cmVWaWV3ZXIsXG4gICAgQ2FwdHVyZSxcbiAgICBWYWxpZGF0b3JzU2VydmljZSxcbiAgICBOYXZpZ2F0b3JTZXJ2aWNlLFxufSBmcm9tICdAc21hcnRlcnBsYW4vbmd4LXNtYXJ0ZXJwbGFuLWNvcmUnO1xuaW1wb3J0IHsgVHJhbnNsYXRlU2VydmljZSB9IGZyb20gJ0BuZ3gtdHJhbnNsYXRlL2NvcmUnO1xuaW1wb3J0IHsgU3ViamVjdCwgdGFrZVVudGlsIH0gZnJvbSAncnhqcyc7XG5cbkBDb21wb25lbnQoe1xuICAgIHNlbGVjdG9yOiAnbGliLXZpc2l0cycsXG4gICAgdGVtcGxhdGVVcmw6ICcuL3Zpc2l0cy5jb21wb25lbnQuaHRtbCcsXG4gICAgc3R5bGVVcmxzOiBbJy4vdmlzaXRzLmNvbXBvbmVudC5zY3NzJ10sXG59KVxuZXhwb3J0IGNsYXNzIFZpc2l0c0NvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCB7XG4gICAgc3BhY2VJZDogc3RyaW5nO1xuXG4gICAgdmlzaXRJbmRleERldGFpbHMgPSAtMTtcblxuICAgIHZpc2l0Rm9ybTogVW50eXBlZEZvcm1Hcm91cDtcblxuICAgIGlzRWRpdGluZzogYm9vbGVhbiA9IGZhbHNlO1xuXG4gICAgdmlzaXRTdWJtaXR0ZWQ6IGJvb2xlYW4gPSBmYWxzZTtcblxuICAgIGNhcHR1cmVEYXRlOiBudW1iZXI7XG5cbiAgICBjdXJyZW50U3BhY2UgPSB7IHpvbmVzOiBbXSB9IGFzIGFueTtcblxuICAgIHZpc2l0czogVmlzaXRbXSA9IFtdO1xuXG4gICAgY2xvc2VSZXN1bHQ6IHN0cmluZztcblxuICAgIEBWaWV3Q2hpbGQoJ2NvbnRlbnQnLCB7IHN0YXRpYzogZmFsc2UgfSkgcHJpdmF0ZSBjb250ZW50O1xuXG4gICAgbW9kYWxSZWZlcmVuY2U6IGFueTtcblxuICAgIGNhbkNhbmNlbEltcG9ydCA9IGZhbHNlO1xuXG4gICAgaW1hZ2VzUHJvY2Vzc2VkOiBudW1iZXIgPSAwO1xuXG4gICAgdG90YWxJbWFnZXM6IG51bWJlciA9IDA7XG5cbiAgICBpbWFnZXNVcGxvYWRlZDogbnVtYmVyID0gMDtcblxuICAgIG1lbnVJdGVtczogTWVudUl0ZW1bXSA9IFtdO1xuXG4gICAgZXJyb3JGb3JtOiBib29sZWFuID0gZmFsc2U7XG5cbiAgICBpc1Byb2Nlc3NpbmcgPSBmYWxzZTtcblxuICAgIGRlc3Ryb3kkID0gbmV3IFN1YmplY3QoKTtcblxuICAgIGNvbnN0cnVjdG9yKFxuICAgICAgICBwcml2YXRlIGZiOiBVbnR5cGVkRm9ybUJ1aWxkZXIsXG4gICAgICAgIHByaXZhdGUgbWF0dGVycG9ydEltcG9ydFNlcnZpY2U6IE1hdHRlcnBvcnRJbXBvcnRTZXJ2aWNlLFxuICAgICAgICBwcml2YXRlIHRocmVlanNJbXBvcnRTZXJ2aWNlOiBUaHJlZUpzSW1wb3J0U2VydmljZSxcbiAgICAgICAgcHJpdmF0ZSBjYXB0dXJlU2VydmljZTogQ2FwdHVyZVNlcnZpY2UsXG4gICAgICAgIHByaXZhdGUgbm9kZVNlcnZpY2U6IE5vZGVTZXJ2aWNlLFxuICAgICAgICBwcml2YXRlIHNwYWNlU2VydmljZTogU3BhY2VTZXJ2aWNlLFxuICAgICAgICBwcml2YXRlIHJvdXRlOiBBY3RpdmF0ZWRSb3V0ZSxcbiAgICAgICAgcHJpdmF0ZSBtb2RhbFNlcnZpY2U6IE5nYk1vZGFsLFxuICAgICAgICBwcml2YXRlIHZpc2l0U2VydmljZTogVmlzaXRTZXJ2aWNlLFxuICAgICAgICBwdWJsaWMgdmFsaWRhdG9yc1NlcnZpY2U6IFZhbGlkYXRvcnNTZXJ2aWNlLFxuICAgICAgICBwcml2YXRlIHRyYW5zbGF0ZTogVHJhbnNsYXRlU2VydmljZSxcbiAgICAgICAgcHJpdmF0ZSBuYXZpZ2F0b3JTZXJ2aWNlOiBOYXZpZ2F0b3JTZXJ2aWNlLFxuICAgICAgICBwcml2YXRlIHJvdXRlcjogUm91dGVyLFxuICAgICkge1xuICAgICAgICB0aGlzLm1hdHRlcnBvcnRJbXBvcnRTZXJ2aWNlLmltcG9ydGluZ0ltYWdlcy5waXBlKHRha2VVbnRpbCh0aGlzLmRlc3Ryb3kkKSkuc3Vic2NyaWJlKCgpID0+IHtcbiAgICAgICAgICAgIHRoaXMuY2FuQ2FuY2VsSW1wb3J0ID0gdHJ1ZTtcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMubWF0dGVycG9ydEltcG9ydFNlcnZpY2Uuc3dlZXBQcm9jZXNzZWRDb3VudC5waXBlKHRha2VVbnRpbCh0aGlzLmRlc3Ryb3kkKSkuc3Vic2NyaWJlKChjb3VudCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5pbWFnZXNQcm9jZXNzZWQgPSBjb3VudCArIDE7XG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLm1hdHRlcnBvcnRJbXBvcnRTZXJ2aWNlLnRvdGFsU3dlZXBzQ291bnQucGlwZSh0YWtlVW50aWwodGhpcy5kZXN0cm95JCkpLnN1YnNjcmliZSgoY291bnQpID0+IHtcbiAgICAgICAgICAgIHRoaXMudG90YWxJbWFnZXMgPSBjb3VudDtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgdGhpcy5uYXZpZ2F0b3JTZXJ2aWNlLmxvY2F0aW9uSURDaGFuZ2VcbiAgICAgICAgICAgIC5waXBlKHRha2VVbnRpbCh0aGlzLmRlc3Ryb3kkKSlcbiAgICAgICAgICAgIC5zdWJzY3JpYmUoKHNwYWNlSUQpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLnJvdXRlci5uYXZpZ2F0ZShbXCJkYXNoYm9hcmQvbG9jYWxpc2F0aW9uXCIsIHNwYWNlSUQsIFwidmlzaXRzXCJdKTtcbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgIHRoaXMucm91dGUucGFyYW1zLnN1YnNjcmliZSgocGFyYW1zKSA9PiB7XG4gICAgICAgICAgICB0aGlzLnNwYWNlSWQgPSBwYXJhbXMuaWQ7XG4gICAgICAgICAgICB0aGlzLnJlc2V0VmlzaXRzKCk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIGFzeW5jIG5nT25Jbml0KCk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICB0aGlzLnNwYWNlSWQgPSB0aGlzLnJvdXRlLnNuYXBzaG90LnBhcmFtTWFwLmdldCgnaWQnKTtcbiAgICAgICAgYXdhaXQgdGhpcy5yZXNldFZpc2l0cygpO1xuICAgIH1cblxuICAgIG5nT25EZXN0cm95KCkge1xuICAgICAgICB0aGlzLmRlc3Ryb3kkLm5leHQodHJ1ZSk7XG4gICAgICAgIHRoaXMuZGVzdHJveSQuY29tcGxldGUoKTtcbiAgICB9XG5cbiAgICAvKlxuICAgIFZpc2l0ID0ge1xuICAgICAgY2FwdHVyZUlEOiBzdHJpbmcsXG4gICAgICBtb2RlbDNkOiBzdHJpbmcsXG4gICAgICB0YWtlbkF0OiBudW1iZXIsXG4gICAgICBzcGFjZUlEOiBzdHJpbmcsXG4gICAgICB2aWV3ZXI6IENhcHR1cmVWaWV3ZXIsXG4gICAgICBzdXJmYWNlOiBudW1iZXIsXG4gICAgICBub2RlOiBOb2RlLFxuICAgICAgbmFtZT86IHN0cmluZyB8IG51bGxcbiAgICB9XG4gICAgKi9cbiAgICBzZXR1cE1lbnVJdGVtcygpIHtcbiAgICAgICAgdGhpcy5tZW51SXRlbXMgPSBbXG4gICAgICAgICAgICB7IGxhYmVsOiAnTG9jYXRpb25zJywgdXJsOiAnL2xvY2FsaXNhdGlvbicgfSxcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBsYWJlbDogdGhpcy5jdXJyZW50U3BhY2UubmFtZSxcbiAgICAgICAgICAgICAgICB1cmw6IGAvbG9jYWxpc2F0aW9uLyR7dGhpcy5jdXJyZW50U3BhY2UuaWR9YCxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgbGFiZWw6ICdWaXJ0dWFsIHZpc2l0cycsXG4gICAgICAgICAgICAgICAgdXJsOiBgL2xvY2FsaXNhdGlvbi8ke3RoaXMuY3VycmVudFNwYWNlLmlkfS92aXNpdHNgLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgXTtcbiAgICB9XG5cbiAgICBvbkdvQmFjaygpIHtcbiAgICAgICAgdGhpcy5vbkNhbmNlbCgpO1xuICAgIH1cblxuICAgIGFzeW5jIHJlc2V0VmlzaXRzKCkge1xuICAgICAgICB0aGlzLnZpc2l0cyA9IFtdO1xuICAgICAgICB0aGlzLmN1cnJlbnRTcGFjZSA9IGF3YWl0IHRoaXMuc3BhY2VTZXJ2aWNlLmdldFNwYWNlKHRoaXMuc3BhY2VJZCk7XG4gICAgICAgIHRoaXMuc2V0dXBNZW51SXRlbXMoKTtcbiAgICAgICAgYXdhaXQgdGhpcy52aXNpdFNlcnZpY2VcbiAgICAgICAgICAgIC5nZXRWaXNpdHNGb3JTcGFjZUZvclVzZXIodGhpcy5zcGFjZUlkKVxuICAgICAgICAgICAgLnRoZW4oKHZpc2l0cykgPT4ge1xuICAgICAgICAgICAgICAgIGlmICh2aXNpdHMpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gM0QgbW9kZWxzIHNoYXJlIHRoaXMgc3RvcmFnZSBidXQgaGF2ZSB0aGVpciBvd24gc2NyZWVuLCBzbyBsaXN0aW5nIHRoZW0gaGVyZVxuICAgICAgICAgICAgICAgICAgICAvLyB0b28gc2hvd2VkIGV2ZXJ5IG1vZGVsIHR3aWNlLiBUaGV5IGNhbiBzdGlsbCBiZSBjcmVhdGVkIGZyb20gdGhpcyBmb3JtOyB0aGV5XG4gICAgICAgICAgICAgICAgICAgIC8vIGp1c3QgYmVsb25nIHRvIHRoZSBvdGhlciB0YWIgb25jZSB0aGV5IGV4aXN0LlxuICAgICAgICAgICAgICAgICAgICB0aGlzLnZpc2l0cyA9IHZpc2l0cy5maWx0ZXIoXG4gICAgICAgICAgICAgICAgICAgICAgICAodmlzaXQpID0+IHZpc2l0LnZpZXdlciAhPT0gQ2FwdHVyZVZpZXdlci5USFJFRUpTLFxuICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgIH1cblxuICAgIGluaXRWaXNpdEZvcm0oaW5wdXQ6IFZpc2l0ID0gbnVsbCkge1xuICAgICAgICBpZiAoaW5wdXQpIHtcbiAgICAgICAgICAgIHRoaXMudmlzaXRGb3JtID0gdGhpcy5mYi5ncm91cCh7XG4gICAgICAgICAgICAgICAgY2FwdHVyZUlEOiBpbnB1dC5jYXB0dXJlSUQsXG4gICAgICAgICAgICAgICAgbm9kZUlEOiBpbnB1dC5ub2RlLmlkLFxuICAgICAgICAgICAgICAgIG5hbWU6IFtpbnB1dC5uYW1lLCBbVmFsaWRhdG9ycy5yZXF1aXJlZF1dLFxuICAgICAgICAgICAgICAgIG1vZGVsM0Q6IFtpbnB1dC5tb2RlbDNkLCBbVmFsaWRhdG9ycy5yZXF1aXJlZF1dLFxuICAgICAgICAgICAgICAgIHZpZXdlcjogaW5wdXQudmlld2VyID8gaW5wdXQudmlld2VyIDogQ2FwdHVyZVZpZXdlci5NQVRURVJQT1JULFxuICAgICAgICAgICAgICAgIHN1cmZhY2U6IGlucHV0LnN1cmZhY2UgPyBpbnB1dC5zdXJmYWNlIDogbnVsbCxcbiAgICAgICAgICAgICAgICB0aHJlZUpzUGxhY2VtZW50OiBpbnB1dC5jYXB0dXJlTWV0YWRhdGEgPz8gbnVsbCxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgdGhpcy5jYXB0dXJlRGF0ZSA9IGlucHV0LnRha2VuQXQ7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLnZpc2l0Rm9ybSA9IHRoaXMuZmIuZ3JvdXAoe1xuICAgICAgICAgICAgICAgIG1vZGVsM0Q6IFtudWxsLCBbVmFsaWRhdG9ycy5yZXF1aXJlZF1dLFxuICAgICAgICAgICAgICAgIHZpZXdlcjogQ2FwdHVyZVZpZXdlci5NQVRURVJQT1JULFxuICAgICAgICAgICAgICAgIHN1cmZhY2U6IG51bGwsXG4gICAgICAgICAgICAgICAgbmFtZTogW251bGwsIFtWYWxpZGF0b3JzLnJlcXVpcmVkXV0sXG4gICAgICAgICAgICAgICAgdGhyZWVKc1BsYWNlbWVudDogbnVsbCxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqIFRydWUgd2hpbGUgdGhlIGZvcm0gaXMgc2V0IHRvIGNyZWF0ZSBhIFRocmVlLmpzIHZpc2l0LCB3aGljaCBhc2tzIGZvciBkaWZmZXJlbnQgZmllbGRzLiAqL1xuICAgIGdldCBpc1RocmVlSnNWaXNpdCgpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIHRoaXMudmlzaXRGb3JtPy52YWx1ZS52aWV3ZXIgPT09IENhcHR1cmVWaWV3ZXIuVEhSRUVKUztcbiAgICB9XG5cbiAgICAvKiogVmFsaWRhdGlvbiBlcnJvciBmb3IgdGhlIDNEIG1vZGVsIGZpZWxkLCBvciBudWxsLiBPbmx5IG1lYW5pbmdmdWwgZm9yIFRocmVlLmpzIHZpc2l0cy4gKi9cbiAgICBnZXQgbW9kZWxLZXlFcnJvcigpOiBzdHJpbmcgfCBudWxsIHtcbiAgICAgICAgaWYgKCF0aGlzLmlzVGhyZWVKc1Zpc2l0KSB7XG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcy50aHJlZWpzSW1wb3J0U2VydmljZS52YWxpZGF0ZU1vZGVsS2V5KHRoaXMudmlzaXRGb3JtLnZhbHVlLm1vZGVsM0QpO1xuICAgIH1cblxuICAgIGFzeW5jIG9uVG9nZ2xlRGV0YWlsKGluZGV4KSB7XG4gICAgICAgIHRoaXMudmlzaXRJbmRleERldGFpbHMgPSBpbmRleCA9PT0gdGhpcy52aXNpdEluZGV4RGV0YWlscyA/IC0xIDogaW5kZXg7XG4gICAgICAgIHRoaXMuaW1hZ2VzVXBsb2FkZWQgPSBhd2FpdCB0aGlzLm1hdHRlcnBvcnRJbXBvcnRTZXJ2aWNlLmdldFVwbG9hZGVkSW1hZ2VDb3VudCh0aGlzLnZpc2l0c1tpbmRleF0ubW9kZWwzZCk7XG4gICAgfVxuXG4gICAgb25BZGRWaXNpdCgpIHtcbiAgICAgICAgdGhpcy5pbml0VmlzaXRGb3JtKCk7XG4gICAgICAgIHRoaXMubWVudUl0ZW1zLnB1c2goeyBsYWJlbDogJ05ldycgfSk7XG4gICAgfVxuXG4gICAgb25FZGl0KHZpc2l0KSB7XG4gICAgICAgIHRoaXMuaW5pdFZpc2l0Rm9ybSh2aXNpdCk7XG4gICAgICAgIHRoaXMuaXNFZGl0aW5nID0gdHJ1ZTtcbiAgICAgICAgdGhpcy5tZW51SXRlbXMucHVzaCh7IGxhYmVsOiB2aXNpdC5uYW1lIH0pO1xuICAgIH1cblxuICAgIGFzeW5jIG9uU3VibWl0VmlzaXQoKSB7XG4gICAgICAgIHRoaXMudmlzaXRTdWJtaXR0ZWQgPSB0cnVlO1xuICAgICAgICBpZiAoIXRoaXMudmlzaXRGb3JtLnZhbGlkKSB7XG4gICAgICAgICAgICB0aGlzLmVycm9yRm9ybSA9IHRydWU7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgLy8gQSBUaHJlZS5qcyB2aXNpdCBwb2ludHMgYXQgYSBmaWxlIHJhdGhlciB0aGFuIGEgTWF0dGVycG9ydCBtb2RlbCwgc28gdGhlIHJlZmVyZW5jZSBpc1xuICAgICAgICAvLyBjaGVja2VkIGJlZm9yZSBhbnl0aGluZyBpcyB3cml0dGVuIC0gb3RoZXJ3aXNlIGEgdHlwbyBjcmVhdGVzIHpvbmVzIGFuZCBuYXZpZ2F0aW9uIGZvciBhXG4gICAgICAgIC8vIG1vZGVsIHRoYXQgNDA0cyB0aGUgZmlyc3QgdGltZSBzb21lb25lIG9wZW5zIHRoZSB2aXNpdC5cbiAgICAgICAgaWYgKHRoaXMubW9kZWxLZXlFcnJvcikge1xuICAgICAgICAgICAgdGhpcy5lcnJvckZvcm0gPSB0cnVlO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuZXJyb3JGb3JtID0gZmFsc2U7XG4gICAgICAgIGNvbnN0IGZvcm1WYWx1ZSA9IHRoaXMudmlzaXRGb3JtLnZhbHVlO1xuICAgICAgICBjb25zdCBjYXB0dXJlID0ge1xuICAgICAgICAgICAgdmlld2VyOiBmb3JtVmFsdWUudmlld2VyLFxuICAgICAgICAgICAgdGFrZW5BdDogdGhpcy5jYXB0dXJlRGF0ZSxcbiAgICAgICAgICAgIHN1cmZhY2U6IGZvcm1WYWx1ZS5zdXJmYWNlLFxuICAgICAgICAgICAgc3BhY2VJRDogdGhpcy5jdXJyZW50U3BhY2UuaWQsXG4gICAgICAgICAgICBtZXRhZGF0YTogdGhpcy5pc1RocmVlSnNWaXNpdCA/IGZvcm1WYWx1ZS50aHJlZUpzUGxhY2VtZW50IDogbnVsbCxcbiAgICAgICAgfSBhcyBDYXB0dXJlO1xuXG4gICAgICAgIGlmICh0aGlzLmlzRWRpdGluZykge1xuICAgICAgICAgICAgY2FwdHVyZS5pZCA9IGZvcm1WYWx1ZS5jYXB0dXJlSUQ7XG4gICAgICAgICAgICBhd2FpdCB0aGlzLmNhcHR1cmVTZXJ2aWNlLnVwZGF0ZUNhcHR1cmUoY2FwdHVyZSk7XG4gICAgICAgICAgICBjb25zdCBub2RlID0ge1xuICAgICAgICAgICAgICAgIGlkOiBmb3JtVmFsdWUubm9kZUlELFxuICAgICAgICAgICAgICAgIG1vZGVsM0Q6IGZvcm1WYWx1ZS5tb2RlbDNELFxuICAgICAgICAgICAgICAgIG1ldGFkYXRhOiBmb3JtVmFsdWUubmFtZSxcbiAgICAgICAgICAgIH0gYXMgTm9kZTtcbiAgICAgICAgICAgIGF3YWl0IHRoaXMubm9kZVNlcnZpY2UudXBkYXRlTm9kZShub2RlKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGxldCBjcmVhdGVkTm9kZTtcbiAgICAgICAgICAgIGF3YWl0IHRoaXMuY2FwdHVyZVNlcnZpY2UuY3JlYXRlQ2FwdHVyZShjYXB0dXJlKS50aGVuKGFzeW5jIChyZXMpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAocmVzKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IG5vZGUgPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBtb2RlbDNEOiBmb3JtVmFsdWUubW9kZWwzRCxcbiAgICAgICAgICAgICAgICAgICAgICAgIGNhcHR1cmVJRDogcmVzLmlkLFxuICAgICAgICAgICAgICAgICAgICAgICAgbWV0YWRhdGE6IGZvcm1WYWx1ZS5uYW1lLFxuICAgICAgICAgICAgICAgICAgICB9IGFzIE5vZGU7XG4gICAgICAgICAgICAgICAgICAgIGNyZWF0ZWROb2RlID0gYXdhaXQgdGhpcy5ub2RlU2VydmljZS5jcmVhdGVOb2RlKG5vZGUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgdGhpcy5sYXVuY2hJbXBvcnQoXG4gICAgICAgICAgICAgICAgZm9ybVZhbHVlLm1vZGVsM0QsXG4gICAgICAgICAgICAgICAgZm9ybVZhbHVlLnN1cmZhY2UsXG4gICAgICAgICAgICAgICAgY3JlYXRlZE5vZGUsXG4gICAgICAgICAgICAgICAgZm9ybVZhbHVlLnZpZXdlcixcbiAgICAgICAgICAgICAgICBmYWxzZSxcbiAgICAgICAgICAgICAgICBmYWxzZSxcbiAgICAgICAgICAgICAgICBmb3JtVmFsdWUudGhyZWVKc1BsYWNlbWVudFxuICAgICAgICAgICAgKVxuICAgICAgICAgICAgICAgIC50aGVuKChzdWNjZXNzKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMubW9kYWxSZWZlcmVuY2UuY2xvc2UoJ2ltcG9ydCBlbmRlZCB3aXRoIHN1Y2Nlc3MnKTtcbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgIC5jYXRjaCgoZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLm1vZGFsUmVmZXJlbmNlLmNsb3NlKGBFcnJvciB3aGlsZSBpbXBvcnQ6ICR7ZX1gKTtcbiAgICAgICAgICAgICAgICAgICAgYWxlcnQoYEVycm9yIHdoaWxlIGltcG9ydDogJHtlfSAke0pTT04uc3RyaW5naWZ5KGUpfWApO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLm9uRGVsZXRlKHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG5vZGU6IGNyZWF0ZWROb2RlLFxuICAgICAgICAgICAgICAgICAgICAgICAgY2FwdHVyZUlEOiBjcmVhdGVkTm9kZS5jYXB0dXJlSUQsXG4gICAgICAgICAgICAgICAgICAgIH0gYXMgVmlzaXQsIGZhbHNlKTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICBhd2FpdCB0aGlzLnJlc2V0VmlzaXRzKCk7XG4gICAgICAgIHRoaXMub25DYW5jZWwoKTtcbiAgICB9XG5cbiAgICBnZXQgbW9kZWwzRCgpOiBBYnN0cmFjdENvbnRyb2wge1xuICAgICAgICByZXR1cm4gdGhpcy52aXNpdEZvcm0uZ2V0KCdtb2RlbDNEJyk7XG4gICAgfVxuXG4gICAgZ2V0IG5hbWUoKTogQWJzdHJhY3RDb250cm9sIHtcbiAgICAgICAgcmV0dXJuIHRoaXMudmlzaXRGb3JtLmdldCgnbmFtZScpO1xuICAgIH1cblxuICAgIG9uQ2FuY2VsKCkge1xuICAgICAgICB0aGlzLnZpc2l0U3VibWl0dGVkID0gZmFsc2U7XG4gICAgICAgIHRoaXMudmlzaXRGb3JtID0gbnVsbDtcbiAgICAgICAgdGhpcy5pc0VkaXRpbmcgPSBmYWxzZTtcbiAgICAgICAgdGhpcy5jYW5DYW5jZWxJbXBvcnQgPSBmYWxzZTtcbiAgICAgICAgdGhpcy50b3RhbEltYWdlcyA9IDA7XG4gICAgICAgIHRoaXMuaW1hZ2VzUHJvY2Vzc2VkID0gMDtcbiAgICAgICAgdGhpcy5lcnJvckZvcm0gPSBmYWxzZTtcbiAgICAgICAgdGhpcy5zZXR1cE1lbnVJdGVtcygpO1xuICAgIH1cblxuICAgIGFzeW5jIG9uRGVsZXRlKHZpc2l0OiBWaXNpdCwgbmVlZFBlcm1pc3Npb24gPSB0cnVlKSB7XG4gICAgICAgIGNvbnN0IG1lc3NhZ2UgPSB0aGlzLnRyYW5zbGF0ZS5pbnN0YW50KCdjb25maXJtLmRlbGV0ZVZpc2l0Jyk7XG4gICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1hbGVydFxuICAgICAgICBpZiAod2luZG93LmNvbmZpcm0obWVzc2FnZSkgfHwgIW5lZWRQZXJtaXNzaW9uKSB7XG4gICAgICAgICAgICBjb25zb2xlLmxvZyh0aGlzLnZpc2l0SW5kZXhEZXRhaWxzKTtcbiAgICAgICAgICAgIHRoaXMuaXNQcm9jZXNzaW5nID0gdHJ1ZTtcbiAgICAgICAgICAgIGF3YWl0IHRoaXMudmlzaXRTZXJ2aWNlLmRlbGV0ZVZpc2l0KHZpc2l0LCB0aGlzLnNwYWNlSWQpO1xuICAgICAgICAgICAgYXdhaXQgdGhpcy5yZXNldFZpc2l0cygpO1xuICAgICAgICAgICAgdGhpcy5pc1Byb2Nlc3NpbmcgPSBmYWxzZTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgZ2V0RGlzbWlzc1JlYXNvbihyZWFzb246IGFueSk6IHN0cmluZyB7XG4gICAgICAgIGlmIChyZWFzb24gPT09IE1vZGFsRGlzbWlzc1JlYXNvbnMuRVNDKSB7XG4gICAgICAgICAgICByZXR1cm4gJ2J5IHByZXNzaW5nIEVTQyc7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHJlYXNvbiA9PT0gTW9kYWxEaXNtaXNzUmVhc29ucy5CQUNLRFJPUF9DTElDSykge1xuICAgICAgICAgICAgcmV0dXJuICdieSBjbGlja2luZyBvbiBhIGJhY2tkcm9wJztcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gYHdpdGg6ICR7cmVhc29ufWA7XG4gICAgfVxuXG4gICAgYXN5bmMgbGF1bmNoSW1wb3J0KFxuICAgICAgICBtb2RlbDNELFxuICAgICAgICBzdXJmYWNlLFxuICAgICAgICBub2RlLFxuICAgICAgICB2aWV3ZXJUeXBlOiBDYXB0dXJlVmlld2VyLFxuICAgICAgICBpbWFnZXNPbmx5ID0gZmFsc2UsXG4gICAgICAgIG92ZXJyaWRlRXhpc3RpbmcgPSBmYWxzZSxcbiAgICAgICAgcGxhY2VtZW50TWV0YWRhdGE6IHN0cmluZyA9IG51bGwsXG4gICAgKSB7XG4gICAgICAgIHRoaXMubW9kYWxSZWZlcmVuY2UgPSB0aGlzLm1vZGFsU2VydmljZS5vcGVuKHRoaXMuY29udGVudCwge1xuICAgICAgICAgICAgYXJpYUxhYmVsbGVkQnk6IFwibW9kYWwtYmFzaWMtdGl0bGVcIixcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMubW9kYWxSZWZlcmVuY2UucmVzdWx0LnRoZW4oXG4gICAgICAgICAgICAocmVzdWx0KSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5jbG9zZVJlc3VsdCA9IGBDbG9zZWQgd2l0aDogJHtyZXN1bHR9YDtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmxvZyh0aGlzLmNsb3NlUmVzdWx0KTtcbiAgICAgICAgICAgICAgICB0aGlzLmNhbmNlbEltcG9ydCgpO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIChlcnJvcikgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMuY2xvc2VSZXN1bHQgPSBgRGlzbWlzc2VkICR7dGhpcy5nZXREaXNtaXNzUmVhc29uKGVycm9yKX1gO1xuICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKHRoaXMuY2xvc2VSZXN1bHQpO1xuICAgICAgICAgICAgICAgIHRoaXMuY2FuY2VsSW1wb3J0KCk7XG4gICAgICAgICAgICB9LFxuICAgICAgICApO1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgaWYgKHZpZXdlclR5cGUgPT09IENhcHR1cmVWaWV3ZXIuVEhSRUVKUykge1xuICAgICAgICAgICAgICAgIC8vIFJvdXRlIHRoZSBpbXBvcnQgdG8gdGhlIG5ldyBUaHJlZS5qcyBJbXBvcnQgU2VydmljZVxuICAgICAgICAgICAgICAgIGF3YWl0IHRoaXMudGhyZWVqc0ltcG9ydFNlcnZpY2UuaW1wb3J0RGF0YShcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5zcGFjZUlkLFxuICAgICAgICAgICAgICAgICAgICBzdXJmYWNlLFxuICAgICAgICAgICAgICAgICAgICBpbWFnZXNPbmx5LFxuICAgICAgICAgICAgICAgICAgICBub2RlLFxuICAgICAgICAgICAgICAgICAgICBvdmVycmlkZUV4aXN0aW5nLFxuICAgICAgICAgICAgICAgICAgICBwbGFjZW1lbnRNZXRhZGF0YVxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIC8vIFJvdXRlIHRoZSBpbXBvcnQgdG8gdGhlIGV4aXN0aW5nIE1hdHRlcnBvcnQgSW1wb3J0IFNlcnZpY2VcbiAgICAgICAgICAgICAgICBhd2FpdCB0aGlzLm1hdHRlcnBvcnRJbXBvcnRTZXJ2aWNlLmluaXRTZGtGb3JNb2RlbChtb2RlbDNEKTtcblxuICAgICAgICAgICAgICAgIGF3YWl0IHRoaXMubWF0dGVycG9ydEltcG9ydFNlcnZpY2UuaW1wb3J0RGF0YShcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5zcGFjZUlkLFxuICAgICAgICAgICAgICAgICAgICBzdXJmYWNlLFxuICAgICAgICAgICAgICAgICAgICBpbWFnZXNPbmx5LFxuICAgICAgICAgICAgICAgICAgICBub2RlLFxuICAgICAgICAgICAgICAgICAgICBvdmVycmlkZUV4aXN0aW5nXG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdGhpcy5tb2RhbFJlZmVyZW5jZS5jbG9zZSgpO1xuXG4gICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICBjb25zb2xlLmxvZyhlcnJvcik7XG4gICAgICAgICAgICBQcm9taXNlLnJlamVjdChlcnJvcik7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIGNhbmNlbEltcG9ydCgpIHtcbiAgICAgICAgdGhpcy5tYXR0ZXJwb3J0SW1wb3J0U2VydmljZS5hYmFuZG9uKCk7XG4gICAgICAgIHRoaXMub25DYW5jZWwoKTtcbiAgICAgICAgdGhpcy5yZXNldFZpc2l0cygpO1xuICAgIH1cblxuICAgIG9uSW1wb3J0SW1hZ2VzKHZpc2l0OiBWaXNpdCwgb3ZlcnJpZGVFeGlzdGluZykge1xuICAgICAgICB0aGlzLmxhdW5jaEltcG9ydCh2aXNpdC5tb2RlbDNkLCBudWxsLCB2aXNpdC5ub2RlLmlkLCB2aXNpdC52aWV3ZXIsIHRydWUsIG92ZXJyaWRlRXhpc3RpbmcsIHZpc2l0LmNhcHR1cmVNZXRhZGF0YSk7XG4gICAgfVxuXG4gICAgaXNGb3JtRXJyb3IoY29udHJvbCkge1xuICAgICAgICByZXR1cm4gY29udHJvbCAmJiBjb250cm9sLmludmFsaWQgJiYgdGhpcy5lcnJvckZvcm07XG4gICAgfVxufVxuIiwiPGRpdiBjbGFzcz1cImNvbnRhaW5lci1mbHVpZFwiIGNsYXNzPVwiZGFzaGJvYXJkLXRhYlwiPlxuICAgIDxkaXYgY2xhc3M9XCJtLTNcIj5cbiAgICAgICAgPGxpYi10YWItbmF2aWdhdGlvbiBbbWVudUl0ZW1zXT0nbWVudUl0ZW1zJyAob25Hb0JhY2spPVwib25Hb0JhY2soKVwiPjwvbGliLXRhYi1uYXZpZ2F0aW9uPlxuICAgIDwvZGl2PlxuXG4gICAgPGRpdiBjbGFzcz1cInJvdyBtYWluLWZvcm0tY29udGFpbmVyXCI+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJjb2wtbWQtNiBmb3JtLWNvbnRhaW5lclwiPlxuICAgICAgICAgICAgPHVsIGNsYXNzPVwibGlzdC1ncm91cCBsaXN0LWdyb3VwLWZsdXNoXCIgKm5nSWY9XCIhdmlzaXRGb3JtXCI+XG4gICAgICAgICAgICAgICAgPGxpIGNsYXNzPVwibGlzdC1ncm91cC1pdGVtIGxpc3QtZ3JvdXAtaXRlbS1hY3Rpb25cIiAqbmdGb3I9XCJsZXQgdmlzaXQgb2YgdmlzaXRzOyBpbmRleCBhcyBpbmRleFwiPlxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZC1mbGV4IGp1c3RpZnktY29udGVudC1iZXR3ZWVuIGFsaWduLWl0ZW1zLWNlbnRlclwiIChjbGljayk9XCJvblRvZ2dsZURldGFpbChpbmRleClcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIHt7dmlzaXQubmFtZSA/IHZpc2l0Lm5hbWUgOiB2aXNpdC5tb2RlbDNkIH19XG4gICAgICAgICAgICAgICAgICAgICAgICA8bGliLWNoZXZyb24gW2NvbmRpdGlvblNob3dpbmddPVwiaW5kZXg9PXZpc2l0SW5kZXhEZXRhaWxzXCI+PC9saWItY2hldnJvbj5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgKm5nSWY9XCJpbmRleD09dmlzaXRJbmRleERldGFpbHNcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDx1bCBjbGFzcz1cImxpc3QtZ3JvdXAgbGlzdC1ncm91cC1mbHVzaFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxsaSBjbGFzcz1cImxpc3QtZ3JvdXAtaXRlbSBiZy10cmFuc3BhcmVudFwiPnt7J05hbWUnIHwgdHJhbnNsYXRlfX0gOiB7eyB2aXNpdC5uYW1lID9cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmlzaXQubmFtZSA6IFwiTm90IHByb3ZpZGVkXCIgfCB0cmFuc2xhdGV9fTwvbGk+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGxpIGNsYXNzPVwibGlzdC1ncm91cC1pdGVtIGJnLXRyYW5zcGFyZW50XCI+e3snM0QgTW9kZWwnIHwgdHJhbnNsYXRlfX0gOiB7eyB2aXNpdC5tb2RlbDNkIH19XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9saT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bGkgY2xhc3M9XCJsaXN0LWdyb3VwLWl0ZW0gYmctdHJhbnNwYXJlbnRcIj57eydTdXJmYWNlJyB8IHRyYW5zbGF0ZX19LCBtPHN1cD4yPC9zdXA+OiB7e1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2aXNpdC5zdXJmYWNlID9cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmlzaXQuc3VyZmFjZSA6ICdOb3QgcHJvdmlkZWQnIHwgdHJhbnNsYXRlfX08L2xpPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxsaSBjbGFzcz1cImxpc3QtZ3JvdXAtaXRlbSBiZy10cmFuc3BhcmVudFwiPnt7J1ZpZXdlcicgfCB0cmFuc2xhdGV9fSA6IHt7IHZpc2l0LnZpZXdlciB9fVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbGk+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGxpIGNsYXNzPVwibGlzdC1ncm91cC1pdGVtIGJnLXRyYW5zcGFyZW50XCI+e3snRGF0ZSBvZiBjYXB0dXJlJyB8IHRyYW5zbGF0ZX19IDoge3tcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmlzaXQudGFrZW5BdCB8IHRpbWVEYXRlU3RyaW5nIHwgYXN5bmN9fVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bGkgY2xhc3M9XCJsaXN0LWdyb3VwLWl0ZW0gYmctdHJhbnNwYXJlbnRcIj57eydJbWFnZXMgYXJlIGltcG9ydGVkJyB8IHRyYW5zbGF0ZX19IDoge3tcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGltYWdlc1VwbG9hZGVkIH19XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbGk+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L3VsPlxuICAgICAgICAgICAgICAgICAgICAgICAgXG4gICAgICAgICAgICAgICAgICAgICAgICA8bGliLWxvYWRlciAqbmdJZj1cImlzUHJvY2Vzc2luZ1wiPjwvbGliLWxvYWRlcj5cblxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImFjdGlvbi1idXR0b24tY29udGFpbmVyIG10LTNcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIGNsYXNzPVwiYnRuIGJ0bi1vdXRsaW5lLXByaW1hcnkgcm91bmRlZC1waWxsIG1lLTJcIiAoY2xpY2spPVwib25JbXBvcnRJbWFnZXModmlzaXQsIHRydWUpXCIgW2Rpc2FibGVkXT1cImlzUHJvY2Vzc2luZ1wiPnt7J0ltcG9ydCBhbGwgaW1hZ2VzJyB8XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJhbnNsYXRlfX08L2J1dHRvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiAqbmdJZj1cImltYWdlc1VwbG9hZGVkID4gMFwiIGNsYXNzPVwiYnRuIGJ0bi1vdXRsaW5lLXByaW1hcnkgcm91bmRlZC1waWxsIG1lLTJcIiAoY2xpY2spPVwib25JbXBvcnRJbWFnZXModmlzaXQsIGZhbHNlKVwiIFtkaXNhYmxlZF09XCJpc1Byb2Nlc3NpbmdcIj57eydJbXBvcnQgZnJvbSBpbWFnZScgfFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cmFuc2xhdGV9fSB7e2ltYWdlc1VwbG9hZGVkfX08L2J1dHRvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIGNsYXNzPVwiYnRuIGJ0bi1vdXRsaW5lLXByaW1hcnkgcm91bmRlZC1waWxsIG1lLTJcIiBbZGlzYWJsZWRdPVwiaXNQcm9jZXNzaW5nXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAoY2xpY2spPVwib25FZGl0KHZpc2l0KVwiPnt7J0VkaXQnIHwgdHJhbnNsYXRlfX08L2J1dHRvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIGNsYXNzPVwiYnRuIGJ0bi1vdXRsaW5lLXByaW1hcnkgcm91bmRlZC1waWxsXCIgW2Rpc2FibGVkXT1cImlzUHJvY2Vzc2luZ1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgKGNsaWNrKT1cIm9uRGVsZXRlKHZpc2l0KVwiPnt7J0RlbGV0ZScgfCB0cmFuc2xhdGV9fTwvYnV0dG9uPlxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgPC9saT5cbiAgICAgICAgICAgIDwvdWw+XG4gICAgICAgICAgICA8ZGl2ICpuZ0lmPVwidmlzaXRGb3JtXCI+XG4gICAgICAgICAgICAgICAgPGZvcm0gKG5nU3VibWl0KT1cIm9uU3VibWl0VmlzaXQoKVwiIFtmb3JtR3JvdXBdPVwidmlzaXRGb3JtXCI+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJtYi0zIHJvd1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwiY29sLXNtLTIgY29sLWZvcm0tbGFiZWxcIj57eydOYW1lJyB8IHRyYW5zbGF0ZX19PC9sYWJlbD5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjb2wtc20tMTBcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW5wdXQgdHlwZT1cInRleHRcIiBjbGFzcz1cImZvcm0tY29udHJvbFwiIGZvcm1Db250cm9sTmFtZT1cIm5hbWVcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm1iLTMgcm93XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJjb2wtc20tMiBjb2wtZm9ybS1sYWJlbFwiPnt7J1JlZmVyZW5jZSAzRCBtb2RlbCcgfCB0cmFuc2xhdGV9fSAqPC9sYWJlbD5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjb2wtc20tMTBcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW5wdXQgdHlwZT1cInRleHRcIiBjbGFzcz1cImZvcm0tY29udHJvbFwiIFtyZWFkb25seV09XCJpc0VkaXRpbmdcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbY2xhc3MuaXMtaW52YWxpZF09XCJtb2RlbDNELmludmFsaWQgJiYgdmlzaXRTdWJtaXR0ZWRcIiByZXF1aXJlZFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3JtQ29udHJvbE5hbWU9XCJtb2RlbDNEXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImludmFsaWQtZmVlZGJhY2tcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG5nYi1hbGVydCBkYXRhLXRlc3RpZD1cIm5ldy1sb2NhdGlvbi1uYW1lLWludmFsaWRcIiBbZGlzbWlzc2libGVdPVwiZmFsc2VcIiB0eXBlPVwiZGFuZ2VyXCIgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICpuZ0lmPVwidmFsaWRhdG9yc1NlcnZpY2UuaXNDb250cm9sRXJyb3IodmlzaXRGb3JtLmNvbnRyb2xzWyduYW1lJ10pIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfHwgIGlzRm9ybUVycm9yKHZpc2l0Rm9ybS5jb250cm9sc1snbmFtZSddKVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7e3ZhbGlkYXRvcnNTZXJ2aWNlLmdldEVycm9yKHZpc2l0Rm9ybS5jb250cm9sc1snbmFtZSddKSB8IHRyYW5zbGF0ZX19XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbmdiLWFsZXJ0PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgKm5nSWY9XCJpc0VkaXRpbmdcIiBjbGFzcz1cInRleHQtZGFuZ2VyXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt7J0Nhbm5vdCBjaGFuZ2UgM0QgbW9kZWwgcmVmZXJlbmNlLiBQbGVhc2UgYWRkIG5ldyBtb2RlbC4nIHwgdHJhbnNsYXRlfX1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8IS0tIEEgVGhyZWUuanMgdmlzaXQgc3RvcmVzIGFuIFMzIGtleSBoZXJlIGluc3RlYWQgb2YgYSBNYXR0ZXJwb3J0IG1vZGVsIElELFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc28gdGhlIGZpZWxkIG1lYW5zIHNvbWV0aGluZyBkaWZmZXJlbnQgZGVwZW5kaW5nIG9uIHRoZSB2aWV3ZXIgYWJvdmUuIC0tPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgKm5nSWY9XCJpc1RocmVlSnNWaXNpdFwiIGNsYXNzPVwiZm9ybS10ZXh0XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt7J1MzIGtleSBvZiB0aGUgLmdsYiBmaWxlLCBmb3IgZXhhbXBsZSB2aXNpdHMvbXktbW9kZWwuZ2xiJyB8IHRyYW5zbGF0ZX19XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiAqbmdJZj1cIm1vZGVsS2V5RXJyb3IgJiYgdmlzaXRTdWJtaXR0ZWRcIiBjbGFzcz1cInRleHQtZGFuZ2VyXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt7bW9kZWxLZXlFcnJvciB8IHRyYW5zbGF0ZX19XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm1iLTMgcm93XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJjb2wtc20tMiBjb2wtZm9ybS1sYWJlbFwiPnt7J1ZpZXdlcicgfCB0cmFuc2xhdGV9fTwvbGFiZWw+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY29sLXNtLTEwXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNlbGVjdCBjbGFzcz1cImZvcm0tc2VsZWN0XCIgZm9ybUNvbnRyb2xOYW1lPVwidmlld2VyXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9XCJNQVRURVJQT1JUXCI+TWF0dGVycG9ydDwvb3B0aW9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8b3B0aW9uIHZhbHVlPVwiVEhSRUVKU1wiPk1vZMOobGUgM0QgKFRocmVlLmpzKTwvb3B0aW9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8b3B0aW9uIHZhbHVlPVwiQ1VQSVhcIj5DdXBpeDwvb3B0aW9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvc2VsZWN0PlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJtYi0zIHJvd1wiICpuZ0lmPVwiaXNUaHJlZUpzVmlzaXRcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cImNvbC1zbS0yIGNvbC1mb3JtLWxhYmVsXCI+e3snSW5pdGlhbCBwbGFjZW1lbnQnIHwgdHJhbnNsYXRlfX08L2xhYmVsPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNvbC1zbS0xMFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx0ZXh0YXJlYSBjbGFzcz1cImZvcm0tY29udHJvbFwiIHJvd3M9XCIzXCIgZm9ybUNvbnRyb2xOYW1lPVwidGhyZWVKc1BsYWNlbWVudFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBsYWNlaG9sZGVyPSd7XCJjYW1lcmFQb3NpdGlvblwiOiB7XCJ4XCI6IDAsIFwieVwiOiA1LCBcInpcIjogMTV9LCBcInJvdGF0aW9uXCI6IHtcInhcIjogMCwgXCJ5XCI6IDAsIFwielwiOiAwfX0nPjwvdGV4dGFyZWE+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZvcm0tdGV4dFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7eydPcHRpb25hbC4gTGVhdmUgZW1wdHkgdG8gZnJhbWUgdGhlIG1vZGVsIGF1dG9tYXRpY2FsbHkuJyB8IHRyYW5zbGF0ZX19XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm1iLTMgcm93XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJjb2wtc20tMiBjb2wtZm9ybS1sYWJlbFwiPnt7J1N1cmZhY2UnIHwgdHJhbnNsYXRlfX08L2xhYmVsPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNvbC1zbS0xMFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dCB0eXBlPVwidGV4dFwiIGNsYXNzPVwiZm9ybS1jb250cm9sXCIgZm9ybUNvbnRyb2xOYW1lPVwic3VyZmFjZVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJtYi0zIHJvd1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwiY29sLXNtLTIgY29sLWZvcm0tbGFiZWxcIj57eydDYXB0dXJlIERhdGUnIHwgdHJhbnNsYXRlfX08L2xhYmVsPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImlucHV0LWdyb3VwXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0IGNsYXNzPVwiZm9ybS1jb250cm9sXCIgcGxhY2Vob2xkZXI9XCJkZC9tbS95eXl5XCIgWyhuZ01vZGVsKV09XCJjYXB0dXJlRGF0ZVwiIG5nYkRhdGVwaWNrZXJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgI2QxPVwibmdiRGF0ZXBpY2tlclwiIFtuZ01vZGVsT3B0aW9uc109XCJ7c3RhbmRhbG9uZTogdHJ1ZX1cIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiaW5wdXQtZ3JvdXAtYXBwZW5kXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxidXR0b24gY2xhc3M9XCJidG4gYnRuLW91dGxpbmUtc2Vjb25kYXJ5IGNhbGVuZGFyXCIgKGNsaWNrKT1cImQxLnRvZ2dsZSgpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGU9XCJidXR0b25cIj48L2J1dHRvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPGJ1dHRvbiB0eXBlPVwic3VibWl0XCIgY2xhc3M9XCJidG4gYnRuLW91dGxpbmUtcHJpbWFyeSByb3VuZGVkLXBpbGwgbWUtMlwiPnt7J1NhdmUnIHxcbiAgICAgICAgICAgICAgICAgICAgICAgIHRyYW5zbGF0ZX19PC9idXR0b24+XG4gICAgICAgICAgICAgICAgICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIChjbGljayk9XCJvbkNhbmNlbCgpXCIgY2xhc3M9XCJidG4gYnRuLW91dGxpbmUtcHJpbWFyeSByb3VuZGVkLXBpbGxcIj57eydDYW5jZWwnIHxcbiAgICAgICAgICAgICAgICAgICAgICAgIHRyYW5zbGF0ZX19PC9idXR0b24+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJpbnZhbGlkLWZlZWRiYWNrXCIgKm5nSWY9XCJlcnJvckZvcm1cIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bmdiLWFsZXJ0IGRhdGEtdGVzdGlkPVwibmV3LWxvY2F0aW9uLWZvcm0taW52YWxpZFwiIFtkaXNtaXNzaWJsZV09XCJmYWxzZVwiIHR5cGU9XCJkYW5nZXJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt7J2Vycm9yRm9ybS5pbmZvQnRuJyB8dHJhbnNsYXRlfX1cbiAgICAgICAgICAgICAgICAgICAgICBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L25nYi1hbGVydD5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgPC9mb3JtPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8ZGl2ICpuZ0lmPVwiIXZpc2l0Rm9ybVwiPlxuICAgICAgICAgICAgICAgIDxidXR0b24gY2xhc3M9XCJidG4gYnRuLW91dGxpbmUtcHJpbWFyeSByb3VuZGVkLXBpbGxcIiAoY2xpY2spPVwib25BZGRWaXNpdCgpXCI+e3snQWRkIDNEIHZpc2l0JyB8XG4gICAgICAgICAgICAgICAgICAgIHRyYW5zbGF0ZX19PC9idXR0b24+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9kaXY+XG4gICAgICAgIDxkaXYgaWQ9XCJ2aWV3ZXItZnJhbWVcIiBzdHlsZT1cIndpZHRoOiAxMDAlOyBhc3BlY3QtcmF0aW86IDIvMTtcIj48L2Rpdj5cbiAgICA8L2Rpdj5cbiAgICA8bmctdGVtcGxhdGUgI2NvbnRlbnQgbGV0LW1vZGFsPlxuICAgICAgICA8ZGl2IGNsYXNzPVwibW9kYWwtaGVhZGVyXCI+XG4gICAgICAgICAgICA8aDQgY2xhc3M9XCJtb2RhbC10aXRsZVwiIGlkPVwibW9kYWwtYmFzaWMtdGl0bGVcIj57eydJbXBvcnRpbmcgRGF0YScgfCB0cmFuc2xhdGV9fTwvaDQ+XG4gICAgICAgICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBjbGFzcz1cImNsb3NlXCIgYXJpYS1sYWJlbD1cIkNsb3NlXCIgKGNsaWNrKT1cIm1vZGFsLmRpc21pc3MoJ0Nyb3NzIGNsaWNrJylcIj5cbiAgICAgICAgICAgICAgICA8c3BhbiBhcmlhLWhpZGRlbj1cInRydWVcIj7Dlzwvc3Bhbj5cbiAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICA8L2Rpdj5cbiAgICAgICAgPGRpdiBjbGFzcz1cIm1vZGFsLWJvZHlcIj5cbiAgICAgICAgICAgIHt7J1BsZWFzZSBkbyBub3QgbGVhdmUgb3IgcmVmcmVzaCB0aGlzIHBhZ2UuLi4nIHwgdHJhbnNsYXRlfX1cbiAgICAgICAgICAgIDxkaXYgKm5nSWY9XCJ0b3RhbEltYWdlcyAhPSAwXCI+SW1wb3J0ZWQge3tpbWFnZXNQcm9jZXNzZWR9fSBvdXQgb2Yge3t0b3RhbEltYWdlc319IGltYWdlcy48L2Rpdj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJkLWZsZXgganVzdGlmeS1jb250ZW50LWNlbnRlclwiPlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzcGlubmVyLWJvcmRlclwiIHJvbGU9XCJzdGF0dXNcIj5cbiAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJ2aXN1YWxseS1oaWRkZW5cIj57eydMb2FkaW5nJyB8IHRyYW5zbGF0ZX19Li4uPC9zcGFuPlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuICAgICAgICA8ZGl2IGNsYXNzPVwibW9kYWwtZm9vdGVyXCI+XG4gICAgICAgICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBjbGFzcz1cImJ0biBidG4tb3V0bGluZS1kYXJrXCIgW2Rpc2FibGVkXT1cIiFjYW5DYW5jZWxJbXBvcnRcIlxuICAgICAgICAgICAgICAgIChjbGljayk9XCJtb2RhbC5jbG9zZSgnQ2FuY2VsIGNsaWNrJylcIj57eydDYW5jZWwgaW1wb3J0IG9mIGltYWdlcycgfCB0cmFuc2xhdGV9fTwvYnV0dG9uPlxuICAgICAgICA8L2Rpdj5cbiAgICA8L25nLXRlbXBsYXRlPlxuPC9kaXY+Il19