@smarterplan/ngx-smarterplan-locations 0.2.21 → 0.2.22

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 (59) hide show
  1. package/esm2020/lib/components/carousel/carousel.component.mjs +27 -27
  2. package/esm2020/lib/components/chevron/chevron.component.mjs +17 -17
  3. package/esm2020/lib/components/detail-location/detail-location.component.mjs +154 -154
  4. package/esm2020/lib/components/form-location/form-location.component.mjs +237 -237
  5. package/esm2020/lib/components/images/images.component.mjs +90 -90
  6. package/esm2020/lib/components/locations/locations.component.mjs +141 -141
  7. package/esm2020/lib/components/locations/map/map-popup/map-popup.component.mjs +65 -65
  8. package/esm2020/lib/components/locations/map/map.component.mjs +90 -90
  9. package/esm2020/lib/components/plan-legend/plan-legend.component.mjs +47 -0
  10. package/esm2020/lib/components/plans/calibration/calibration.component.mjs +468 -468
  11. package/esm2020/lib/components/plans/edit-plan/edit-plan.component.mjs +324 -324
  12. package/esm2020/lib/components/plans/plans.component.mjs +210 -210
  13. package/esm2020/lib/components/tab-navigation/tab-navigation.component.mjs +41 -41
  14. package/esm2020/lib/components/visits/visits.component.mjs +235 -235
  15. package/esm2020/lib/components/zones/add-audio-zone/add-audio-zone.component.mjs +230 -230
  16. package/esm2020/lib/components/zones/add-zone/add-zone.component.mjs +294 -294
  17. package/esm2020/lib/components/zones/add-zone/selection/selection.component.mjs +76 -76
  18. package/esm2020/lib/components/zones/add-zone/sweep-plan-selection/sweep-plan-selection.component.mjs +414 -413
  19. package/esm2020/lib/components/zones/zones.component.mjs +236 -232
  20. package/esm2020/lib/helper.service.mjs +134 -134
  21. package/esm2020/lib/ngx-smarterplan-location-routing.module.mjs +49 -49
  22. package/esm2020/lib/ngx-smarterplan-locations.module.mjs +125 -122
  23. package/esm2020/lib/ngx-smarterplan-locations.service.mjs +13 -13
  24. package/esm2020/lib/pipes/count-audio-sweeps.pipe.mjs +26 -26
  25. package/esm2020/lib/radio-button/radio-button.component.mjs +26 -26
  26. package/esm2020/public-api.mjs +8 -8
  27. package/esm2020/smarterplan-ngx-smarterplan-locations.mjs +4 -4
  28. package/fesm2015/smarterplan-ngx-smarterplan-locations.mjs +3676 -3624
  29. package/fesm2015/smarterplan-ngx-smarterplan-locations.mjs.map +1 -1
  30. package/fesm2020/smarterplan-ngx-smarterplan-locations.mjs +3520 -3472
  31. package/fesm2020/smarterplan-ngx-smarterplan-locations.mjs.map +1 -1
  32. package/lib/components/carousel/carousel.component.d.ts +12 -12
  33. package/lib/components/chevron/chevron.component.d.ts +9 -9
  34. package/lib/components/detail-location/detail-location.component.d.ts +51 -51
  35. package/lib/components/form-location/form-location.component.d.ts +45 -45
  36. package/lib/components/images/images.component.d.ts +28 -28
  37. package/lib/components/locations/locations.component.d.ts +50 -50
  38. package/lib/components/locations/map/map-popup/map-popup.component.d.ts +22 -22
  39. package/lib/components/locations/map/map.component.d.ts +22 -22
  40. package/lib/components/plan-legend/plan-legend.component.d.ts +14 -0
  41. package/lib/components/plans/calibration/calibration.component.d.ts +140 -140
  42. package/lib/components/plans/edit-plan/edit-plan.component.d.ts +55 -55
  43. package/lib/components/plans/plans.component.d.ts +59 -59
  44. package/lib/components/tab-navigation/tab-navigation.component.d.ts +13 -13
  45. package/lib/components/visits/visits.component.d.ts +51 -51
  46. package/lib/components/zones/add-audio-zone/add-audio-zone.component.d.ts +63 -63
  47. package/lib/components/zones/add-zone/add-zone.component.d.ts +67 -67
  48. package/lib/components/zones/add-zone/selection/selection.component.d.ts +44 -44
  49. package/lib/components/zones/add-zone/sweep-plan-selection/sweep-plan-selection.component.d.ts +96 -96
  50. package/lib/components/zones/zones.component.d.ts +67 -67
  51. package/lib/helper.service.d.ts +53 -53
  52. package/lib/ngx-smarterplan-location-routing.module.d.ts +7 -7
  53. package/lib/ngx-smarterplan-locations.module.d.ts +36 -35
  54. package/lib/ngx-smarterplan-locations.service.d.ts +6 -6
  55. package/lib/pipes/count-audio-sweeps.pipe.d.ts +10 -10
  56. package/lib/radio-button/radio-button.component.d.ts +12 -12
  57. package/package.json +1 -1
  58. package/public-api.d.ts +4 -4
  59. package/smarterplan-ngx-smarterplan-locations.d.ts +5 -5
@@ -1,235 +1,235 @@
1
- import { Component, ViewChild } from '@angular/core';
2
- import { Validators } from '@angular/forms';
3
- import { ModalDismissReasons } from '@ng-bootstrap/ng-bootstrap';
4
- import { CaptureViewer } from '@smarterplan/ngx-smarterplan-core';
5
- import * as i0 from "@angular/core";
6
- import * as i1 from "@angular/forms";
7
- import * as i2 from "@smarterplan/ngx-smarterplan-core";
8
- import * as i3 from "@angular/router";
9
- import * as i4 from "@ng-bootstrap/ng-bootstrap";
10
- import * as i5 from "../tab-navigation/tab-navigation.component";
11
- import * as i6 from "../chevron/chevron.component";
12
- import * as i7 from "@angular/common";
13
- import * as i8 from "@ngx-translate/core";
14
- export class VisitsComponent {
15
- constructor(fb, matterportImportService, captureService, nodeService, spaceService, route, modalService, visitService) {
16
- this.fb = fb;
17
- this.matterportImportService = matterportImportService;
18
- this.captureService = captureService;
19
- this.nodeService = nodeService;
20
- this.spaceService = spaceService;
21
- this.route = route;
22
- this.modalService = modalService;
23
- this.visitService = visitService;
24
- this.visitIndexDetails = -1;
25
- this.isEditing = false;
26
- this.visitSubmitted = false;
27
- this.currentSpace = { zones: [] };
28
- this.visits = [];
29
- this.canCancelImport = false;
30
- this.imagesProcessed = 0;
31
- this.totalImages = 0;
32
- this.menuItems = [];
33
- this.matterportImportService.importingImages.subscribe(() => {
34
- this.canCancelImport = true;
35
- });
36
- this.matterportImportService.sweepProcessedCount.subscribe((count) => {
37
- this.imagesProcessed = count + 1;
38
- });
39
- this.matterportImportService.totalSweepsCount.subscribe((count) => {
40
- this.totalImages = count;
41
- });
42
- }
43
- ngOnInit() {
44
- this.spaceId = this.route.snapshot.paramMap.get("id");
45
- this.resetVisits();
46
- }
47
- /*
48
- Visit = {
49
- captureID: string,
50
- model3d: string,
51
- takenAt: number,
52
- spaceID: string,
53
- viewer: CaptureViewer,
54
- surface: number,
55
- node: Node,
56
- name?: string | null
57
- }
58
- */
59
- setupMenuItems() {
60
- this.menuItems = [
61
- { label: "Locations", url: "/localisation" },
62
- {
63
- label: this.currentSpace.name,
64
- url: `/localisation/${this.currentSpace.id}`,
65
- },
66
- {
67
- label: "Virtual visits",
68
- url: `/localisation/${this.currentSpace.id}/visits`,
69
- },
70
- ];
71
- }
72
- onGoBack() {
73
- this.onCancel();
74
- }
75
- async resetVisits() {
76
- this.visits = [];
77
- this.currentSpace = await this.spaceService.getSpace(this.spaceId);
78
- this.setupMenuItems();
79
- await this.visitService
80
- .getVisitsForSpaceForUser(this.spaceId)
81
- .then((visits) => {
82
- if (visits) {
83
- this.visits = visits;
84
- }
85
- });
86
- }
87
- initVisitForm(input = null) {
88
- if (input) {
89
- this.visitForm = this.fb.group({
90
- captureID: input.captureID,
91
- nodeID: input.node.id,
92
- name: [input.name, [Validators.required]],
93
- model3D: [input.model3d, [Validators.required]],
94
- viewer: input.viewer ? input.viewer : CaptureViewer.MATTERPORT,
95
- surface: input.surface ? input.surface : null,
96
- });
97
- this.captureDate = input.takenAt;
98
- }
99
- else {
100
- this.visitForm = this.fb.group({
101
- model3D: [null, [Validators.required]],
102
- viewer: CaptureViewer.MATTERPORT,
103
- surface: null,
104
- name: [null, [Validators.required]],
105
- });
106
- }
107
- }
108
- onToggleDetail(index) {
109
- this.visitIndexDetails = index === this.visitIndexDetails ? -1 : index;
110
- }
111
- onAddVisit() {
112
- this.initVisitForm();
113
- this.menuItems.push({ label: "New" });
114
- }
115
- onEdit(visit) {
116
- this.initVisitForm(visit);
117
- this.isEditing = true;
118
- this.menuItems.push({ label: visit.name });
119
- }
120
- async onSubmitVisit() {
121
- this.visitSubmitted = true;
122
- if (!this.visitForm.valid) {
123
- return;
124
- }
125
- const formValue = this.visitForm.value;
126
- const capture = {
127
- viewer: formValue.viewer,
128
- takenAt: this.captureDate,
129
- surface: formValue.surface,
130
- spaceID: this.currentSpace.id,
131
- };
132
- if (this.isEditing) {
133
- capture.id = formValue.captureID;
134
- await this.captureService.updateCapture(capture);
135
- const node = {
136
- id: formValue.nodeID,
137
- model3D: formValue.model3D,
138
- metadata: formValue.name,
139
- };
140
- await this.nodeService.updateNode(node);
141
- }
142
- else {
143
- let createdNode;
144
- await this.captureService.createCapture(capture).then(async (res) => {
145
- if (res) {
146
- const node = {
147
- model3D: formValue.model3D,
148
- captureID: res.id,
149
- metadata: formValue.name,
150
- };
151
- createdNode = await this.nodeService.createNode(node);
152
- }
153
- });
154
- this.launchImport(formValue.model3D, formValue.surface, createdNode, false).then((success) => {
155
- this.modalReference.close("import ended with success");
156
- }).catch((e) => {
157
- this.modalReference.close(`Error while import: ${e}`);
158
- alert(`Error while import: ${e}`);
159
- this.onDelete({ node: createdNode, captureID: createdNode.captureID });
160
- });
161
- }
162
- await this.resetVisits();
163
- this.onCancel();
164
- }
165
- get model3D() {
166
- return this.visitForm.get("model3D");
167
- }
168
- get name() {
169
- return this.visitForm.get("name");
170
- }
171
- onCancel() {
172
- this.visitSubmitted = false;
173
- this.visitForm = null;
174
- this.isEditing = false;
175
- this.canCancelImport = false;
176
- this.totalImages = 0;
177
- this.imagesProcessed = 0;
178
- this.setupMenuItems();
179
- }
180
- async onDelete(visit) {
181
- await this.visitService.deleteVisit(visit, this.spaceId);
182
- this.resetVisits();
183
- }
184
- getDismissReason(reason) {
185
- if (reason === ModalDismissReasons.ESC) {
186
- return "by pressing ESC";
187
- }
188
- if (reason === ModalDismissReasons.BACKDROP_CLICK) {
189
- return "by clicking on a backdrop";
190
- }
191
- return `with: ${reason}`;
192
- }
193
- async launchImport(model3D, surface, node, imagesOnly = false) {
194
- this.modalReference = this.modalService.open(this.content, {
195
- ariaLabelledBy: "modal-basic-title",
196
- });
197
- this.modalReference.result.then((result) => {
198
- this.closeResult = `Closed with: ${result}`;
199
- console.log(this.closeResult);
200
- this.cancelImport();
201
- }, (error) => {
202
- this.closeResult = `Dismissed ${this.getDismissReason(error)}`;
203
- console.log(this.closeResult);
204
- this.cancelImport();
205
- });
206
- try {
207
- await this.matterportImportService.initSdkForModel(model3D);
208
- return imagesOnly
209
- ? this.matterportImportService.importData(this.spaceId, surface, true, node)
210
- : this.matterportImportService.importData(this.spaceId, surface, false, node);
211
- }
212
- catch (error) {
213
- console.log(error);
214
- return Promise.reject(error);
215
- }
216
- }
217
- cancelImport() {
218
- this.matterportImportService.abandon();
219
- this.onCancel();
220
- this.resetVisits();
221
- }
222
- onImport(visit) {
223
- this.launchImport(visit.model3d, null, visit.node.id, true);
224
- }
225
- }
226
- VisitsComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.7", ngImport: i0, type: VisitsComponent, deps: [{ token: i1.FormBuilder }, { token: i2.MatterportImportService }, { token: i2.CaptureService }, { token: i2.NodeService }, { token: i2.SpaceService }, { token: i3.ActivatedRoute }, { token: i4.NgbModal }, { token: i2.VisitService }], target: i0.ɵɵFactoryTarget.Component });
227
- VisitsComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.2.7", 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 (click)=\"onToggleDetail(index)\">\r\n <div class=\"d-flex justify-content-between align-items-center\">\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 visit.imagesImported }}\r\n </li>\r\n </ul>\r\n <button type=\"button\" class=\"btn btn-outline-primary rounded-pill me-2\"\r\n *ngIf=\"!visit.imagesImported\" (click)=\"onImport(visit)\">{{'Import images' |\r\n translate}}</button>\r\n <button type=\"button\" class=\"btn btn-outline-primary rounded-pill me-2\"\r\n (click)=\"onEdit(visit)\">{{'Edit' | translate}}</button>\r\n <button type=\"button\" class=\"btn btn-outline-primary rounded-pill\"\r\n (click)=\"onDelete(visit)\">{{'Delete' | translate}}</button>\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 {{'Please provide the 3D model reference' | translate}}\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 </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:-moz-fit-content;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"], components: [{ type: i5.TabNavigationComponent, selector: "lib-tab-navigation", inputs: ["menuItems"], outputs: ["onGoBack"] }, { type: i6.ChevronComponent, selector: "lib-chevron", inputs: ["conditionShowing"] }], directives: [{ type: i7.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i7.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { 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]" }, { type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { type: i1.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { type: i4.NgbInputDatepicker, selector: "input[ngbDatepicker]", inputs: ["autoClose", "datepickerClass", "dayTemplate", "dayTemplateData", "displayMonths", "firstDayOfWeek", "footerTemplate", "markDisabled", "minDate", "maxDate", "navigation", "outsideDays", "placement", "restoreFocus", "showWeekNumbers", "startDate", "container", "positionTarget", "weekdays", "disabled"], outputs: ["dateSelect", "navigate", "closed"], exportAs: ["ngbDatepicker"] }, { type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }], pipes: { "translate": i8.TranslatePipe, "async": i7.AsyncPipe, "timeDateString": i2.TimeDateToLocalStringPipe } });
228
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.7", ngImport: i0, type: VisitsComponent, decorators: [{
229
- type: Component,
230
- 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 (click)=\"onToggleDetail(index)\">\r\n <div class=\"d-flex justify-content-between align-items-center\">\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 visit.imagesImported }}\r\n </li>\r\n </ul>\r\n <button type=\"button\" class=\"btn btn-outline-primary rounded-pill me-2\"\r\n *ngIf=\"!visit.imagesImported\" (click)=\"onImport(visit)\">{{'Import images' |\r\n translate}}</button>\r\n <button type=\"button\" class=\"btn btn-outline-primary rounded-pill me-2\"\r\n (click)=\"onEdit(visit)\">{{'Edit' | translate}}</button>\r\n <button type=\"button\" class=\"btn btn-outline-primary rounded-pill\"\r\n (click)=\"onDelete(visit)\">{{'Delete' | translate}}</button>\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 {{'Please provide the 3D model reference' | translate}}\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 </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:-moz-fit-content;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"] }]
231
- }], ctorParameters: function () { return [{ type: i1.FormBuilder }, { type: i2.MatterportImportService }, { type: i2.CaptureService }, { type: i2.NodeService }, { type: i2.SpaceService }, { type: i3.ActivatedRoute }, { type: i4.NgbModal }, { type: i2.VisitService }]; }, propDecorators: { content: [{
232
- type: ViewChild,
233
- args: ["content", { static: false }]
234
- }] } });
235
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmlzaXRzLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL25neC1zbWFydGVycGxhbi1sb2NhdGlvbnMvc3JjL2xpYi9jb21wb25lbnRzL3Zpc2l0cy92aXNpdHMuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvbmd4LXNtYXJ0ZXJwbGFuLWxvY2F0aW9ucy9zcmMvbGliL2NvbXBvbmVudHMvdmlzaXRzL3Zpc2l0cy5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsU0FBUyxFQUFVLFNBQVMsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUM3RCxPQUFPLEVBQTBCLFVBQVUsRUFBbUIsTUFBTSxnQkFBZ0IsQ0FBQztBQUVyRixPQUFPLEVBQVksbUJBQW1CLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUMzRSxPQUFPLEVBQTJHLGFBQWEsRUFBVyxNQUFNLG1DQUFtQyxDQUFDOzs7Ozs7Ozs7O0FBT3BMLE1BQU0sT0FBTyxlQUFlO0lBK0J4QixZQUNZLEVBQWUsRUFDZix1QkFBZ0QsRUFDaEQsY0FBOEIsRUFDOUIsV0FBd0IsRUFDeEIsWUFBMEIsRUFDMUIsS0FBcUIsRUFDckIsWUFBc0IsRUFDdEIsWUFBMEI7UUFQMUIsT0FBRSxHQUFGLEVBQUUsQ0FBYTtRQUNmLDRCQUF1QixHQUF2Qix1QkFBdUIsQ0FBeUI7UUFDaEQsbUJBQWMsR0FBZCxjQUFjLENBQWdCO1FBQzlCLGdCQUFXLEdBQVgsV0FBVyxDQUFhO1FBQ3hCLGlCQUFZLEdBQVosWUFBWSxDQUFjO1FBQzFCLFVBQUssR0FBTCxLQUFLLENBQWdCO1FBQ3JCLGlCQUFZLEdBQVosWUFBWSxDQUFVO1FBQ3RCLGlCQUFZLEdBQVosWUFBWSxDQUFjO1FBcEN0QyxzQkFBaUIsR0FBRyxDQUFDLENBQUMsQ0FBQztRQUl2QixjQUFTLEdBQVksS0FBSyxDQUFDO1FBRTNCLG1CQUFjLEdBQVksS0FBSyxDQUFDO1FBSWhDLGlCQUFZLEdBQUcsRUFBRSxLQUFLLEVBQUUsRUFBRSxFQUFTLENBQUM7UUFFcEMsV0FBTSxHQUFZLEVBQUUsQ0FBQztRQVFyQixvQkFBZSxHQUFHLEtBQUssQ0FBQztRQUV4QixvQkFBZSxHQUFXLENBQUMsQ0FBQztRQUU1QixnQkFBVyxHQUFXLENBQUMsQ0FBQztRQUV4QixjQUFTLEdBQWUsRUFBRSxDQUFDO1FBWXZCLElBQUksQ0FBQyx1QkFBdUIsQ0FBQyxlQUFlLENBQUMsU0FBUyxDQUFDLEdBQUcsRUFBRTtZQUN4RCxJQUFJLENBQUMsZUFBZSxHQUFHLElBQUksQ0FBQztRQUNoQyxDQUFDLENBQUMsQ0FBQztRQUNILElBQUksQ0FBQyx1QkFBdUIsQ0FBQyxtQkFBbUIsQ0FBQyxTQUFTLENBQUMsQ0FBQyxLQUFLLEVBQUUsRUFBRTtZQUNqRSxJQUFJLENBQUMsZUFBZSxHQUFHLEtBQUssR0FBRyxDQUFDLENBQUM7UUFDckMsQ0FBQyxDQUFDLENBQUM7UUFDSCxJQUFJLENBQUMsdUJBQXVCLENBQUMsZ0JBQWdCLENBQUMsU0FBUyxDQUFDLENBQUMsS0FBSyxFQUFFLEVBQUU7WUFDOUQsSUFBSSxDQUFDLFdBQVcsR0FBRyxLQUFLLENBQUM7UUFDN0IsQ0FBQyxDQUFDLENBQUM7SUFDUCxDQUFDO0lBRUQsUUFBUTtRQUNKLElBQUksQ0FBQyxPQUFPLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUN0RCxJQUFJLENBQUMsV0FBVyxFQUFFLENBQUM7SUFDdkIsQ0FBQztJQUVEOzs7Ozs7Ozs7OztJQVdBO0lBQ0EsY0FBYztRQUNWLElBQUksQ0FBQyxTQUFTLEdBQUc7WUFDYixFQUFFLEtBQUssRUFBRSxXQUFXLEVBQUUsR0FBRyxFQUFFLGVBQWUsRUFBRTtZQUM1QztnQkFDSSxLQUFLLEVBQUUsSUFBSSxDQUFDLFlBQVksQ0FBQyxJQUFJO2dCQUM3QixHQUFHLEVBQUUsaUJBQWlCLElBQUksQ0FBQyxZQUFZLENBQUMsRUFBRSxFQUFFO2FBQy9DO1lBQ0Q7Z0JBQ0ksS0FBSyxFQUFFLGdCQUFnQjtnQkFDdkIsR0FBRyxFQUFFLGlCQUFpQixJQUFJLENBQUMsWUFBWSxDQUFDLEVBQUUsU0FBUzthQUN0RDtTQUNKLENBQUM7SUFDTixDQUFDO0lBRUQsUUFBUTtRQUNKLElBQUksQ0FBQyxRQUFRLEVBQUUsQ0FBQztJQUNwQixDQUFDO0lBRUQsS0FBSyxDQUFDLFdBQVc7UUFDYixJQUFJLENBQUMsTUFBTSxHQUFHLEVBQUUsQ0FBQztRQUNqQixJQUFJLENBQUMsWUFBWSxHQUFHLE1BQU0sSUFBSSxDQUFDLFlBQVksQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQ25FLElBQUksQ0FBQyxjQUFjLEVBQUUsQ0FBQztRQUN0QixNQUFNLElBQUksQ0FBQyxZQUFZO2FBQ2xCLHdCQUF3QixDQUFDLElBQUksQ0FBQyxPQUFPLENBQUM7YUFDdEMsSUFBSSxDQUFDLENBQUMsTUFBTSxFQUFFLEVBQUU7WUFDYixJQUFJLE1BQU0sRUFBRTtnQkFDUixJQUFJLENBQUMsTUFBTSxHQUFHLE1BQU0sQ0FBQzthQUN4QjtRQUNMLENBQUMsQ0FBQyxDQUFDO0lBQ1gsQ0FBQztJQUVELGFBQWEsQ0FBQyxRQUFlLElBQUk7UUFDN0IsSUFBSSxLQUFLLEVBQUU7WUFDUCxJQUFJLENBQUMsU0FBUyxHQUFHLElBQUksQ0FBQyxFQUFFLENBQUMsS0FBSyxDQUFDO2dCQUMzQixTQUFTLEVBQUUsS0FBSyxDQUFDLFNBQVM7Z0JBQzFCLE1BQU0sRUFBRSxLQUFLLENBQUMsSUFBSSxDQUFDLEVBQUU7Z0JBQ3JCLElBQUksRUFBRSxDQUFDLEtBQUssQ0FBQyxJQUFJLEVBQUUsQ0FBQyxVQUFVLENBQUMsUUFBUSxDQUFDLENBQUM7Z0JBQ3pDLE9BQU8sRUFBRSxDQUFDLEtBQUssQ0FBQyxPQUFPLEVBQUUsQ0FBQyxVQUFVLENBQUMsUUFBUSxDQUFDLENBQUM7Z0JBQy9DLE1BQU0sRUFBRSxLQUFLLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxhQUFhLENBQUMsVUFBVTtnQkFDOUQsT0FBTyxFQUFFLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLElBQUk7YUFDaEQsQ0FBQyxDQUFDO1lBQ0gsSUFBSSxDQUFDLFdBQVcsR0FBRyxLQUFLLENBQUMsT0FBTyxDQUFDO1NBQ3BDO2FBQU07WUFDSCxJQUFJLENBQUMsU0FBUyxHQUFHLElBQUksQ0FBQyxFQUFFLENBQUMsS0FBSyxDQUFDO2dCQUMzQixPQUFPLEVBQUUsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxVQUFVLENBQUMsUUFBUSxDQUFDLENBQUM7Z0JBQ3RDLE1BQU0sRUFBRSxhQUFhLENBQUMsVUFBVTtnQkFDaEMsT0FBTyxFQUFFLElBQUk7Z0JBQ2IsSUFBSSxFQUFFLENBQUMsSUFBSSxFQUFFLENBQUMsVUFBVSxDQUFDLFFBQVEsQ0FBQyxDQUFDO2FBQ3RDLENBQUMsQ0FBQztTQUNOO0lBQ0wsQ0FBQztJQUVELGNBQWMsQ0FBQyxLQUFLO1FBQ2hCLElBQUksQ0FBQyxpQkFBaUIsR0FBRyxLQUFLLEtBQUssSUFBSSxDQUFDLGlCQUFpQixDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDO0lBQzNFLENBQUM7SUFFRCxVQUFVO1FBQ04sSUFBSSxDQUFDLGFBQWEsRUFBRSxDQUFDO1FBQ3JCLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxDQUFDLENBQUM7SUFDMUMsQ0FBQztJQUVELE1BQU0sQ0FBQyxLQUFLO1FBQ1IsSUFBSSxDQUFDLGFBQWEsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUMxQixJQUFJLENBQUMsU0FBUyxHQUFHLElBQUksQ0FBQztRQUN0QixJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxFQUFFLEtBQUssRUFBRSxLQUFLLENBQUMsSUFBSSxFQUFFLENBQUMsQ0FBQztJQUMvQyxDQUFDO0lBRUQsS0FBSyxDQUFDLGFBQWE7UUFDZixJQUFJLENBQUMsY0FBYyxHQUFHLElBQUksQ0FBQztRQUMzQixJQUFJLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxLQUFLLEVBQUU7WUFDdkIsT0FBTztTQUNWO1FBQ0QsTUFBTSxTQUFTLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUM7UUFDdkMsTUFBTSxPQUFPLEdBQUc7WUFDWixNQUFNLEVBQUUsU0FBUyxDQUFDLE1BQU07WUFDeEIsT0FBTyxFQUFFLElBQUksQ0FBQyxXQUFXO1lBQ3pCLE9BQU8sRUFBRSxTQUFTLENBQUMsT0FBTztZQUMxQixPQUFPLEVBQUUsSUFBSSxDQUFDLFlBQVksQ0FBQyxFQUFFO1NBQ3JCLENBQUM7UUFFYixJQUFJLElBQUksQ0FBQyxTQUFTLEVBQUU7WUFDaEIsT0FBTyxDQUFDLEVBQUUsR0FBRyxTQUFTLENBQUMsU0FBUyxDQUFDO1lBQ2pDLE1BQU0sSUFBSSxDQUFDLGNBQWMsQ0FBQyxhQUFhLENBQUMsT0FBTyxDQUFDLENBQUM7WUFDakQsTUFBTSxJQUFJLEdBQUc7Z0JBQ1QsRUFBRSxFQUFFLFNBQVMsQ0FBQyxNQUFNO2dCQUNwQixPQUFPLEVBQUUsU0FBUyxDQUFDLE9BQU87Z0JBQzFCLFFBQVEsRUFBRSxTQUFTLENBQUMsSUFBSTthQUNuQixDQUFDO1lBQ1YsTUFBTSxJQUFJLENBQUMsV0FBVyxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsQ0FBQztTQUMzQzthQUFNO1lBQ0gsSUFBSSxXQUFXLENBQUM7WUFDaEIsTUFBTSxJQUFJLENBQUMsY0FBYyxDQUFDLGFBQWEsQ0FBQyxPQUFPLENBQUMsQ0FBQyxJQUFJLENBQUMsS0FBSyxFQUFFLEdBQUcsRUFBRSxFQUFFO2dCQUNoRSxJQUFJLEdBQUcsRUFBRTtvQkFDTCxNQUFNLElBQUksR0FBRzt3QkFDVCxPQUFPLEVBQUUsU0FBUyxDQUFDLE9BQU87d0JBQzFCLFNBQVMsRUFBRSxHQUFHLENBQUMsRUFBRTt3QkFDakIsUUFBUSxFQUFFLFNBQVMsQ0FBQyxJQUFJO3FCQUNuQixDQUFDO29CQUNWLFdBQVcsR0FBRyxNQUFNLElBQUksQ0FBQyxXQUFXLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxDQUFDO2lCQUN6RDtZQUNMLENBQUMsQ0FBQyxDQUFDO1lBQ0gsSUFBSSxDQUFDLFlBQVksQ0FDYixTQUFTLENBQUMsT0FBTyxFQUNqQixTQUFTLENBQUMsT0FBTyxFQUNqQixXQUFXLEVBQ1gsS0FBSyxDQUNSLENBQUMsSUFBSSxDQUFDLENBQUMsT0FBTyxFQUFFLEVBQUU7Z0JBQ2YsSUFBSSxDQUFDLGNBQWMsQ0FBQyxLQUFLLENBQUMsMkJBQTJCLENBQUMsQ0FBQztZQUMzRCxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRTtnQkFDWCxJQUFJLENBQUMsY0FBYyxDQUFDLEtBQUssQ0FBQyx1QkFBdUIsQ0FBQyxFQUFFLENBQUMsQ0FBQztnQkFDdEQsS0FBSyxDQUFDLHVCQUF1QixDQUFDLEVBQUUsQ0FBQyxDQUFDO2dCQUNsQyxJQUFJLENBQUMsUUFBUSxDQUFDLEVBQUUsSUFBSSxFQUFFLFdBQVcsRUFBRSxTQUFTLEVBQUUsV0FBVyxDQUFDLFNBQVMsRUFBVyxDQUFDLENBQUM7WUFDcEYsQ0FBQyxDQUFDLENBQUM7U0FFTjtRQUNELE1BQU0sSUFBSSxDQUFDLFdBQVcsRUFBRSxDQUFDO1FBQ3pCLElBQUksQ0FBQyxRQUFRLEVBQUUsQ0FBQztJQUNwQixDQUFDO0lBRUQsSUFBSSxPQUFPO1FBQ1AsT0FBTyxJQUFJLENBQUMsU0FBUyxDQUFDLEdBQUcsQ0FBQyxTQUFTLENBQUMsQ0FBQztJQUN6QyxDQUFDO0lBRUQsSUFBSSxJQUFJO1FBQ0osT0FBTyxJQUFJLENBQUMsU0FBUyxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsQ0FBQztJQUN0QyxDQUFDO0lBRUQsUUFBUTtRQUNKLElBQUksQ0FBQyxjQUFjLEdBQUcsS0FBSyxDQUFDO1FBQzVCLElBQUksQ0FBQyxTQUFTLEdBQUcsSUFBSSxDQUFDO1FBQ3RCLElBQUksQ0FBQyxTQUFTLEdBQUcsS0FBSyxDQUFDO1FBQ3ZCLElBQUksQ0FBQyxlQUFlLEdBQUcsS0FBSyxDQUFDO1FBQzdCLElBQUksQ0FBQyxXQUFXLEdBQUcsQ0FBQyxDQUFDO1FBQ3JCLElBQUksQ0FBQyxlQUFlLEdBQUcsQ0FBQyxDQUFDO1FBQ3pCLElBQUksQ0FBQyxjQUFjLEVBQUUsQ0FBQztJQUMxQixDQUFDO0lBRUQsS0FBSyxDQUFDLFFBQVEsQ0FBQyxLQUFZO1FBQ3ZCLE1BQU0sSUFBSSxDQUFDLFlBQVksQ0FBQyxXQUFXLENBQUMsS0FBSyxFQUFFLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUN6RCxJQUFJLENBQUMsV0FBVyxFQUFFLENBQUM7SUFDdkIsQ0FBQztJQUVPLGdCQUFnQixDQUFDLE1BQVc7UUFDaEMsSUFBSSxNQUFNLEtBQUssbUJBQW1CLENBQUMsR0FBRyxFQUFFO1lBQ3BDLE9BQU8saUJBQWlCLENBQUM7U0FDNUI7UUFDRCxJQUFJLE1BQU0sS0FBSyxtQkFBbUIsQ0FBQyxjQUFjLEVBQUU7WUFDL0MsT0FBTywyQkFBMkIsQ0FBQztTQUN0QztRQUNELE9BQU8sU0FBUyxNQUFNLEVBQUUsQ0FBQztJQUM3QixDQUFDO0lBRUQsS0FBSyxDQUFDLFlBQVksQ0FDZCxPQUFPLEVBQ1AsT0FBTyxFQUNQLElBQUksRUFDSixVQUFVLEdBQUcsS0FBSztRQUVsQixJQUFJLENBQUMsY0FBYyxHQUFHLElBQUksQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUU7WUFDdkQsY0FBYyxFQUFFLG1CQUFtQjtTQUN0QyxDQUFDLENBQUM7UUFDSCxJQUFJLENBQUMsY0FBYyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQzNCLENBQUMsTUFBTSxFQUFFLEVBQUU7WUFDUCxJQUFJLENBQUMsV0FBVyxHQUFHLGdCQUFnQixNQUFNLEVBQUUsQ0FBQztZQUM1QyxPQUFPLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsQ0FBQztZQUM5QixJQUFJLENBQUMsWUFBWSxFQUFFLENBQUM7UUFDeEIsQ0FBQyxFQUNELENBQUMsS0FBSyxFQUFFLEVBQUU7WUFDTixJQUFJLENBQUMsV0FBVyxHQUFHLGFBQWEsSUFBSSxDQUFDLGdCQUFnQixDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUM7WUFDL0QsT0FBTyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLENBQUM7WUFDOUIsSUFBSSxDQUFDLFlBQVksRUFBRSxDQUFDO1FBQ3hCLENBQUMsQ0FDSixDQUFDO1FBQ0YsSUFBSTtZQUNBLE1BQU0sSUFBSSxDQUFDLHVCQUF1QixDQUFDLGVBQWUsQ0FDOUMsT0FBTyxDQUNWLENBQUM7WUFDRixPQUFPLFVBQVU7Z0JBQ2IsQ0FBQyxDQUFDLElBQUksQ0FBQyx1QkFBdUIsQ0FBQyxVQUFVLENBQ3JDLElBQUksQ0FBQyxPQUFPLEVBQ1osT0FBTyxFQUNQLElBQUksRUFDSixJQUFJLENBQ1A7Z0JBQ0QsQ0FBQyxDQUFDLElBQUksQ0FBQyx1QkFBdUIsQ0FBQyxVQUFVLENBQ3JDLElBQUksQ0FBQyxPQUFPLEVBQ1osT0FBTyxFQUNQLEtBQUssRUFDTCxJQUFJLENBQ1AsQ0FBQztTQUNUO1FBQUMsT0FBTyxLQUFLLEVBQUU7WUFDWixPQUFPLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBQ25CLE9BQU8sT0FBTyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQztTQUNoQztJQUNMLENBQUM7SUFFTyxZQUFZO1FBQ2hCLElBQUksQ0FBQyx1QkFBdUIsQ0FBQyxPQUFPLEVBQUUsQ0FBQztRQUN2QyxJQUFJLENBQUMsUUFBUSxFQUFFLENBQUM7UUFDaEIsSUFBSSxDQUFDLFdBQVcsRUFBRSxDQUFDO0lBQ3ZCLENBQUM7SUFFRCxRQUFRLENBQUMsS0FBWTtRQUNqQixJQUFJLENBQUMsWUFBWSxDQUFDLEtBQUssQ0FBQyxPQUFPLEVBQUUsSUFBSSxFQUFFLEtBQUssQ0FBQyxJQUFJLENBQUMsRUFBRSxFQUFFLElBQUksQ0FBQyxDQUFDO0lBQ2hFLENBQUM7OzRHQWpSUSxlQUFlO2dHQUFmLGVBQWUsc0pDWDVCLHlyUEEySE07MkZEaEhPLGVBQWU7a0JBTDNCLFNBQVM7K0JBQ0ksWUFBWTt5U0F1QjJCLE9BQU87c0JBQXZELFNBQVM7dUJBQUMsU0FBUyxFQUFFLEVBQUUsTUFBTSxFQUFFLEtBQUssRUFBRSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbXBvbmVudCwgT25Jbml0LCBWaWV3Q2hpbGQgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuaW1wb3J0IHsgRm9ybUdyb3VwLCBGb3JtQnVpbGRlciwgVmFsaWRhdG9ycywgQWJzdHJhY3RDb250cm9sIH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xyXG5pbXBvcnQgeyBBY3RpdmF0ZWRSb3V0ZSB9IGZyb20gJ0Bhbmd1bGFyL3JvdXRlcic7XHJcbmltcG9ydCB7IE5nYk1vZGFsLCBNb2RhbERpc21pc3NSZWFzb25zIH0gZnJvbSAnQG5nLWJvb3RzdHJhcC9uZy1ib290c3RyYXAnO1xyXG5pbXBvcnQgeyBOb2RlLCBWaXNpdCwgTWVudUl0ZW0sIE1hdHRlcnBvcnRJbXBvcnRTZXJ2aWNlLCBDYXB0dXJlU2VydmljZSwgTm9kZVNlcnZpY2UsIFNwYWNlU2VydmljZSwgVmlzaXRTZXJ2aWNlLCBDYXB0dXJlVmlld2VyLCBDYXB0dXJlIH0gZnJvbSAnQHNtYXJ0ZXJwbGFuL25neC1zbWFydGVycGxhbi1jb3JlJztcclxuXHJcbkBDb21wb25lbnQoe1xyXG4gICAgc2VsZWN0b3I6ICdsaWItdmlzaXRzJyxcclxuICAgIHRlbXBsYXRlVXJsOiAnLi92aXNpdHMuY29tcG9uZW50Lmh0bWwnLFxyXG4gICAgc3R5bGVVcmxzOiBbJy4vdmlzaXRzLmNvbXBvbmVudC5zY3NzJ11cclxufSlcclxuZXhwb3J0IGNsYXNzIFZpc2l0c0NvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCB7XHJcbiAgICBzcGFjZUlkOiBzdHJpbmc7XHJcblxyXG4gICAgdmlzaXRJbmRleERldGFpbHMgPSAtMTtcclxuXHJcbiAgICB2aXNpdEZvcm06IEZvcm1Hcm91cDtcclxuXHJcbiAgICBpc0VkaXRpbmc6IGJvb2xlYW4gPSBmYWxzZTtcclxuXHJcbiAgICB2aXNpdFN1Ym1pdHRlZDogYm9vbGVhbiA9IGZhbHNlO1xyXG5cclxuICAgIGNhcHR1cmVEYXRlOiBudW1iZXI7XHJcblxyXG4gICAgY3VycmVudFNwYWNlID0geyB6b25lczogW10gfSBhcyBhbnk7XHJcblxyXG4gICAgdmlzaXRzOiBWaXNpdFtdID0gW107XHJcblxyXG4gICAgY2xvc2VSZXN1bHQ6IHN0cmluZztcclxuXHJcbiAgICBAVmlld0NoaWxkKFwiY29udGVudFwiLCB7IHN0YXRpYzogZmFsc2UgfSkgcHJpdmF0ZSBjb250ZW50O1xyXG5cclxuICAgIG1vZGFsUmVmZXJlbmNlOiBhbnk7XHJcblxyXG4gICAgY2FuQ2FuY2VsSW1wb3J0ID0gZmFsc2U7XHJcblxyXG4gICAgaW1hZ2VzUHJvY2Vzc2VkOiBudW1iZXIgPSAwO1xyXG5cclxuICAgIHRvdGFsSW1hZ2VzOiBudW1iZXIgPSAwO1xyXG5cclxuICAgIG1lbnVJdGVtczogTWVudUl0ZW1bXSA9IFtdO1xyXG5cclxuICAgIGNvbnN0cnVjdG9yKFxyXG4gICAgICAgIHByaXZhdGUgZmI6IEZvcm1CdWlsZGVyLFxyXG4gICAgICAgIHByaXZhdGUgbWF0dGVycG9ydEltcG9ydFNlcnZpY2U6IE1hdHRlcnBvcnRJbXBvcnRTZXJ2aWNlLFxyXG4gICAgICAgIHByaXZhdGUgY2FwdHVyZVNlcnZpY2U6IENhcHR1cmVTZXJ2aWNlLFxyXG4gICAgICAgIHByaXZhdGUgbm9kZVNlcnZpY2U6IE5vZGVTZXJ2aWNlLFxyXG4gICAgICAgIHByaXZhdGUgc3BhY2VTZXJ2aWNlOiBTcGFjZVNlcnZpY2UsXHJcbiAgICAgICAgcHJpdmF0ZSByb3V0ZTogQWN0aXZhdGVkUm91dGUsXHJcbiAgICAgICAgcHJpdmF0ZSBtb2RhbFNlcnZpY2U6IE5nYk1vZGFsLFxyXG4gICAgICAgIHByaXZhdGUgdmlzaXRTZXJ2aWNlOiBWaXNpdFNlcnZpY2UsXHJcbiAgICApIHtcclxuICAgICAgICB0aGlzLm1hdHRlcnBvcnRJbXBvcnRTZXJ2aWNlLmltcG9ydGluZ0ltYWdlcy5zdWJzY3JpYmUoKCkgPT4ge1xyXG4gICAgICAgICAgICB0aGlzLmNhbkNhbmNlbEltcG9ydCA9IHRydWU7XHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgdGhpcy5tYXR0ZXJwb3J0SW1wb3J0U2VydmljZS5zd2VlcFByb2Nlc3NlZENvdW50LnN1YnNjcmliZSgoY291bnQpID0+IHtcclxuICAgICAgICAgICAgdGhpcy5pbWFnZXNQcm9jZXNzZWQgPSBjb3VudCArIDE7XHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgdGhpcy5tYXR0ZXJwb3J0SW1wb3J0U2VydmljZS50b3RhbFN3ZWVwc0NvdW50LnN1YnNjcmliZSgoY291bnQpID0+IHtcclxuICAgICAgICAgICAgdGhpcy50b3RhbEltYWdlcyA9IGNvdW50O1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIG5nT25Jbml0KCk6IHZvaWQge1xyXG4gICAgICAgIHRoaXMuc3BhY2VJZCA9IHRoaXMucm91dGUuc25hcHNob3QucGFyYW1NYXAuZ2V0KFwiaWRcIik7XHJcbiAgICAgICAgdGhpcy5yZXNldFZpc2l0cygpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qXHJcbiAgVmlzaXQgPSB7XHJcbiAgICBjYXB0dXJlSUQ6IHN0cmluZyxcclxuICAgIG1vZGVsM2Q6IHN0cmluZyxcclxuICAgIHRha2VuQXQ6IG51bWJlcixcclxuICAgIHNwYWNlSUQ6IHN0cmluZyxcclxuICAgIHZpZXdlcjogQ2FwdHVyZVZpZXdlcixcclxuICAgIHN1cmZhY2U6IG51bWJlcixcclxuICAgIG5vZGU6IE5vZGUsXHJcbiAgICBuYW1lPzogc3RyaW5nIHwgbnVsbFxyXG4gIH1cclxuICAqL1xyXG4gICAgc2V0dXBNZW51SXRlbXMoKSB7XHJcbiAgICAgICAgdGhpcy5tZW51SXRlbXMgPSBbXHJcbiAgICAgICAgICAgIHsgbGFiZWw6IFwiTG9jYXRpb25zXCIsIHVybDogXCIvbG9jYWxpc2F0aW9uXCIgfSxcclxuICAgICAgICAgICAge1xyXG4gICAgICAgICAgICAgICAgbGFiZWw6IHRoaXMuY3VycmVudFNwYWNlLm5hbWUsXHJcbiAgICAgICAgICAgICAgICB1cmw6IGAvbG9jYWxpc2F0aW9uLyR7dGhpcy5jdXJyZW50U3BhY2UuaWR9YCxcclxuICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAge1xyXG4gICAgICAgICAgICAgICAgbGFiZWw6IFwiVmlydHVhbCB2aXNpdHNcIixcclxuICAgICAgICAgICAgICAgIHVybDogYC9sb2NhbGlzYXRpb24vJHt0aGlzLmN1cnJlbnRTcGFjZS5pZH0vdmlzaXRzYCxcclxuICAgICAgICAgICAgfSxcclxuICAgICAgICBdO1xyXG4gICAgfVxyXG5cclxuICAgIG9uR29CYWNrKCkge1xyXG4gICAgICAgIHRoaXMub25DYW5jZWwoKTtcclxuICAgIH1cclxuXHJcbiAgICBhc3luYyByZXNldFZpc2l0cygpIHtcclxuICAgICAgICB0aGlzLnZpc2l0cyA9IFtdO1xyXG4gICAgICAgIHRoaXMuY3VycmVudFNwYWNlID0gYXdhaXQgdGhpcy5zcGFjZVNlcnZpY2UuZ2V0U3BhY2UodGhpcy5zcGFjZUlkKTtcclxuICAgICAgICB0aGlzLnNldHVwTWVudUl0ZW1zKCk7XHJcbiAgICAgICAgYXdhaXQgdGhpcy52aXNpdFNlcnZpY2VcclxuICAgICAgICAgICAgLmdldFZpc2l0c0ZvclNwYWNlRm9yVXNlcih0aGlzLnNwYWNlSWQpXHJcbiAgICAgICAgICAgIC50aGVuKCh2aXNpdHMpID0+IHtcclxuICAgICAgICAgICAgICAgIGlmICh2aXNpdHMpIHtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLnZpc2l0cyA9IHZpc2l0cztcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgaW5pdFZpc2l0Rm9ybShpbnB1dDogVmlzaXQgPSBudWxsKSB7XHJcbiAgICAgICAgaWYgKGlucHV0KSB7XHJcbiAgICAgICAgICAgIHRoaXMudmlzaXRGb3JtID0gdGhpcy5mYi5ncm91cCh7XHJcbiAgICAgICAgICAgICAgICBjYXB0dXJlSUQ6IGlucHV0LmNhcHR1cmVJRCxcclxuICAgICAgICAgICAgICAgIG5vZGVJRDogaW5wdXQubm9kZS5pZCxcclxuICAgICAgICAgICAgICAgIG5hbWU6IFtpbnB1dC5uYW1lLCBbVmFsaWRhdG9ycy5yZXF1aXJlZF1dLFxyXG4gICAgICAgICAgICAgICAgbW9kZWwzRDogW2lucHV0Lm1vZGVsM2QsIFtWYWxpZGF0b3JzLnJlcXVpcmVkXV0sXHJcbiAgICAgICAgICAgICAgICB2aWV3ZXI6IGlucHV0LnZpZXdlciA/IGlucHV0LnZpZXdlciA6IENhcHR1cmVWaWV3ZXIuTUFUVEVSUE9SVCxcclxuICAgICAgICAgICAgICAgIHN1cmZhY2U6IGlucHV0LnN1cmZhY2UgPyBpbnB1dC5zdXJmYWNlIDogbnVsbCxcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgIHRoaXMuY2FwdHVyZURhdGUgPSBpbnB1dC50YWtlbkF0O1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIHRoaXMudmlzaXRGb3JtID0gdGhpcy5mYi5ncm91cCh7XHJcbiAgICAgICAgICAgICAgICBtb2RlbDNEOiBbbnVsbCwgW1ZhbGlkYXRvcnMucmVxdWlyZWRdXSxcclxuICAgICAgICAgICAgICAgIHZpZXdlcjogQ2FwdHVyZVZpZXdlci5NQVRURVJQT1JULFxyXG4gICAgICAgICAgICAgICAgc3VyZmFjZTogbnVsbCxcclxuICAgICAgICAgICAgICAgIG5hbWU6IFtudWxsLCBbVmFsaWRhdG9ycy5yZXF1aXJlZF1dLFxyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgb25Ub2dnbGVEZXRhaWwoaW5kZXgpIHtcclxuICAgICAgICB0aGlzLnZpc2l0SW5kZXhEZXRhaWxzID0gaW5kZXggPT09IHRoaXMudmlzaXRJbmRleERldGFpbHMgPyAtMSA6IGluZGV4O1xyXG4gICAgfVxyXG5cclxuICAgIG9uQWRkVmlzaXQoKSB7XHJcbiAgICAgICAgdGhpcy5pbml0VmlzaXRGb3JtKCk7XHJcbiAgICAgICAgdGhpcy5tZW51SXRlbXMucHVzaCh7IGxhYmVsOiBcIk5ld1wiIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIG9uRWRpdCh2aXNpdCkge1xyXG4gICAgICAgIHRoaXMuaW5pdFZpc2l0Rm9ybSh2aXNpdCk7XHJcbiAgICAgICAgdGhpcy5pc0VkaXRpbmcgPSB0cnVlO1xyXG4gICAgICAgIHRoaXMubWVudUl0ZW1zLnB1c2goeyBsYWJlbDogdmlzaXQubmFtZSB9KTtcclxuICAgIH1cclxuXHJcbiAgICBhc3luYyBvblN1Ym1pdFZpc2l0KCkge1xyXG4gICAgICAgIHRoaXMudmlzaXRTdWJtaXR0ZWQgPSB0cnVlO1xyXG4gICAgICAgIGlmICghdGhpcy52aXNpdEZvcm0udmFsaWQpIHtcclxuICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgIH1cclxuICAgICAgICBjb25zdCBmb3JtVmFsdWUgPSB0aGlzLnZpc2l0Rm9ybS52YWx1ZTtcclxuICAgICAgICBjb25zdCBjYXB0dXJlID0ge1xyXG4gICAgICAgICAgICB2aWV3ZXI6IGZvcm1WYWx1ZS52aWV3ZXIsXHJcbiAgICAgICAgICAgIHRha2VuQXQ6IHRoaXMuY2FwdHVyZURhdGUsXHJcbiAgICAgICAgICAgIHN1cmZhY2U6IGZvcm1WYWx1ZS5zdXJmYWNlLFxyXG4gICAgICAgICAgICBzcGFjZUlEOiB0aGlzLmN1cnJlbnRTcGFjZS5pZCxcclxuICAgICAgICB9IGFzIENhcHR1cmU7XHJcblxyXG4gICAgICAgIGlmICh0aGlzLmlzRWRpdGluZykge1xyXG4gICAgICAgICAgICBjYXB0dXJlLmlkID0gZm9ybVZhbHVlLmNhcHR1cmVJRDtcclxuICAgICAgICAgICAgYXdhaXQgdGhpcy5jYXB0dXJlU2VydmljZS51cGRhdGVDYXB0dXJlKGNhcHR1cmUpO1xyXG4gICAgICAgICAgICBjb25zdCBub2RlID0ge1xyXG4gICAgICAgICAgICAgICAgaWQ6IGZvcm1WYWx1ZS5ub2RlSUQsXHJcbiAgICAgICAgICAgICAgICBtb2RlbDNEOiBmb3JtVmFsdWUubW9kZWwzRCxcclxuICAgICAgICAgICAgICAgIG1ldGFkYXRhOiBmb3JtVmFsdWUubmFtZSxcclxuICAgICAgICAgICAgfSBhcyBOb2RlO1xyXG4gICAgICAgICAgICBhd2FpdCB0aGlzLm5vZGVTZXJ2aWNlLnVwZGF0ZU5vZGUobm9kZSk7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgbGV0IGNyZWF0ZWROb2RlO1xyXG4gICAgICAgICAgICBhd2FpdCB0aGlzLmNhcHR1cmVTZXJ2aWNlLmNyZWF0ZUNhcHR1cmUoY2FwdHVyZSkudGhlbihhc3luYyAocmVzKSA9PiB7XHJcbiAgICAgICAgICAgICAgICBpZiAocmVzKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgbm9kZSA9IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgbW9kZWwzRDogZm9ybVZhbHVlLm1vZGVsM0QsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNhcHR1cmVJRDogcmVzLmlkLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBtZXRhZGF0YTogZm9ybVZhbHVlLm5hbWUsXHJcbiAgICAgICAgICAgICAgICAgICAgfSBhcyBOb2RlO1xyXG4gICAgICAgICAgICAgICAgICAgIGNyZWF0ZWROb2RlID0gYXdhaXQgdGhpcy5ub2RlU2VydmljZS5jcmVhdGVOb2RlKG5vZGUpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgdGhpcy5sYXVuY2hJbXBvcnQoXHJcbiAgICAgICAgICAgICAgICBmb3JtVmFsdWUubW9kZWwzRCxcclxuICAgICAgICAgICAgICAgIGZvcm1WYWx1ZS5zdXJmYWNlLFxyXG4gICAgICAgICAgICAgICAgY3JlYXRlZE5vZGUsXHJcbiAgICAgICAgICAgICAgICBmYWxzZSxcclxuICAgICAgICAgICAgKS50aGVuKChzdWNjZXNzKSA9PiB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLm1vZGFsUmVmZXJlbmNlLmNsb3NlKFwiaW1wb3J0IGVuZGVkIHdpdGggc3VjY2Vzc1wiKTtcclxuICAgICAgICAgICAgfSkuY2F0Y2goKGUpID0+IHtcclxuICAgICAgICAgICAgICAgIHRoaXMubW9kYWxSZWZlcmVuY2UuY2xvc2UoYEVycm9yIHdoaWxlIGltcG9ydDogJHtlfWApO1xyXG4gICAgICAgICAgICAgICAgYWxlcnQoYEVycm9yIHdoaWxlIGltcG9ydDogJHtlfWApO1xyXG4gICAgICAgICAgICAgICAgdGhpcy5vbkRlbGV0ZSh7IG5vZGU6IGNyZWF0ZWROb2RlLCBjYXB0dXJlSUQ6IGNyZWF0ZWROb2RlLmNhcHR1cmVJRCB9IGFzIFZpc2l0KTtcclxuICAgICAgICAgICAgfSk7XHJcblxyXG4gICAgICAgIH1cclxuICAgICAgICBhd2FpdCB0aGlzLnJlc2V0VmlzaXRzKCk7XHJcbiAgICAgICAgdGhpcy5vbkNhbmNlbCgpO1xyXG4gICAgfVxyXG5cclxuICAgIGdldCBtb2RlbDNEKCk6IEFic3RyYWN0Q29udHJvbCB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMudmlzaXRGb3JtLmdldChcIm1vZGVsM0RcIik7XHJcbiAgICB9XHJcblxyXG4gICAgZ2V0IG5hbWUoKTogQWJzdHJhY3RDb250cm9sIHtcclxuICAgICAgICByZXR1cm4gdGhpcy52aXNpdEZvcm0uZ2V0KFwibmFtZVwiKTtcclxuICAgIH1cclxuXHJcbiAgICBvbkNhbmNlbCgpIHtcclxuICAgICAgICB0aGlzLnZpc2l0U3VibWl0dGVkID0gZmFsc2U7XHJcbiAgICAgICAgdGhpcy52aXNpdEZvcm0gPSBudWxsO1xyXG4gICAgICAgIHRoaXMuaXNFZGl0aW5nID0gZmFsc2U7XHJcbiAgICAgICAgdGhpcy5jYW5DYW5jZWxJbXBvcnQgPSBmYWxzZTtcclxuICAgICAgICB0aGlzLnRvdGFsSW1hZ2VzID0gMDtcclxuICAgICAgICB0aGlzLmltYWdlc1Byb2Nlc3NlZCA9IDA7XHJcbiAgICAgICAgdGhpcy5zZXR1cE1lbnVJdGVtcygpO1xyXG4gICAgfVxyXG5cclxuICAgIGFzeW5jIG9uRGVsZXRlKHZpc2l0OiBWaXNpdCkge1xyXG4gICAgICAgIGF3YWl0IHRoaXMudmlzaXRTZXJ2aWNlLmRlbGV0ZVZpc2l0KHZpc2l0LCB0aGlzLnNwYWNlSWQpO1xyXG4gICAgICAgIHRoaXMucmVzZXRWaXNpdHMoKTtcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIGdldERpc21pc3NSZWFzb24ocmVhc29uOiBhbnkpOiBzdHJpbmcge1xyXG4gICAgICAgIGlmIChyZWFzb24gPT09IE1vZGFsRGlzbWlzc1JlYXNvbnMuRVNDKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBcImJ5IHByZXNzaW5nIEVTQ1wiO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAocmVhc29uID09PSBNb2RhbERpc21pc3NSZWFzb25zLkJBQ0tEUk9QX0NMSUNLKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBcImJ5IGNsaWNraW5nIG9uIGEgYmFja2Ryb3BcIjtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIGB3aXRoOiAke3JlYXNvbn1gO1xyXG4gICAgfVxyXG5cclxuICAgIGFzeW5jIGxhdW5jaEltcG9ydChcclxuICAgICAgICBtb2RlbDNELFxyXG4gICAgICAgIHN1cmZhY2UsXHJcbiAgICAgICAgbm9kZSxcclxuICAgICAgICBpbWFnZXNPbmx5ID0gZmFsc2UsXHJcbiAgICApOiBQcm9taXNlPGJvb2xlYW4+IHtcclxuICAgICAgICB0aGlzLm1vZGFsUmVmZXJlbmNlID0gdGhpcy5tb2RhbFNlcnZpY2Uub3Blbih0aGlzLmNvbnRlbnQsIHtcclxuICAgICAgICAgICAgYXJpYUxhYmVsbGVkQnk6IFwibW9kYWwtYmFzaWMtdGl0bGVcIixcclxuICAgICAgICB9KTtcclxuICAgICAgICB0aGlzLm1vZGFsUmVmZXJlbmNlLnJlc3VsdC50aGVuKFxyXG4gICAgICAgICAgICAocmVzdWx0KSA9PiB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmNsb3NlUmVzdWx0ID0gYENsb3NlZCB3aXRoOiAke3Jlc3VsdH1gO1xyXG4gICAgICAgICAgICAgICAgY29uc29sZS5sb2codGhpcy5jbG9zZVJlc3VsdCk7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmNhbmNlbEltcG9ydCgpO1xyXG4gICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICAoZXJyb3IpID0+IHtcclxuICAgICAgICAgICAgICAgIHRoaXMuY2xvc2VSZXN1bHQgPSBgRGlzbWlzc2VkICR7dGhpcy5nZXREaXNtaXNzUmVhc29uKGVycm9yKX1gO1xyXG4gICAgICAgICAgICAgICAgY29uc29sZS5sb2codGhpcy5jbG9zZVJlc3VsdCk7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmNhbmNlbEltcG9ydCgpO1xyXG4gICAgICAgICAgICB9LFxyXG4gICAgICAgICk7XHJcbiAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgYXdhaXQgdGhpcy5tYXR0ZXJwb3J0SW1wb3J0U2VydmljZS5pbml0U2RrRm9yTW9kZWwoXHJcbiAgICAgICAgICAgICAgICBtb2RlbDNELFxyXG4gICAgICAgICAgICApO1xyXG4gICAgICAgICAgICByZXR1cm4gaW1hZ2VzT25seVxyXG4gICAgICAgICAgICAgICAgPyB0aGlzLm1hdHRlcnBvcnRJbXBvcnRTZXJ2aWNlLmltcG9ydERhdGEoXHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5zcGFjZUlkLFxyXG4gICAgICAgICAgICAgICAgICAgIHN1cmZhY2UsXHJcbiAgICAgICAgICAgICAgICAgICAgdHJ1ZSxcclxuICAgICAgICAgICAgICAgICAgICBub2RlLFxyXG4gICAgICAgICAgICAgICAgKVxyXG4gICAgICAgICAgICAgICAgOiB0aGlzLm1hdHRlcnBvcnRJbXBvcnRTZXJ2aWNlLmltcG9ydERhdGEoXHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5zcGFjZUlkLFxyXG4gICAgICAgICAgICAgICAgICAgIHN1cmZhY2UsXHJcbiAgICAgICAgICAgICAgICAgICAgZmFsc2UsXHJcbiAgICAgICAgICAgICAgICAgICAgbm9kZSxcclxuICAgICAgICAgICAgICAgICk7XHJcbiAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcclxuICAgICAgICAgICAgY29uc29sZS5sb2coZXJyb3IpO1xyXG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QoZXJyb3IpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIGNhbmNlbEltcG9ydCgpIHtcclxuICAgICAgICB0aGlzLm1hdHRlcnBvcnRJbXBvcnRTZXJ2aWNlLmFiYW5kb24oKTtcclxuICAgICAgICB0aGlzLm9uQ2FuY2VsKCk7XHJcbiAgICAgICAgdGhpcy5yZXNldFZpc2l0cygpO1xyXG4gICAgfVxyXG5cclxuICAgIG9uSW1wb3J0KHZpc2l0OiBWaXNpdCkge1xyXG4gICAgICAgIHRoaXMubGF1bmNoSW1wb3J0KHZpc2l0Lm1vZGVsM2QsIG51bGwsIHZpc2l0Lm5vZGUuaWQsIHRydWUpO1xyXG4gICAgfVxyXG59XHJcbiIsIjxkaXYgY2xhc3M9XCJjb250YWluZXItZmx1aWRcIiBjbGFzcz1cImRhc2hib2FyZC10YWJcIj5cclxuICAgIDxkaXYgY2xhc3M9XCJtLTNcIj5cclxuICAgICAgICA8bGliLXRhYi1uYXZpZ2F0aW9uIFttZW51SXRlbXNdPSdtZW51SXRlbXMnIChvbkdvQmFjayk9XCJvbkdvQmFjaygpXCI+PC9saWItdGFiLW5hdmlnYXRpb24+XHJcbiAgICA8L2Rpdj5cclxuXHJcbiAgICA8ZGl2IGNsYXNzPVwicm93IG1haW4tZm9ybS1jb250YWluZXJcIj5cclxuICAgICAgICA8ZGl2IGNsYXNzPVwiY29sLW1kLTYgZm9ybS1jb250YWluZXJcIj5cclxuICAgICAgICAgICAgPHVsIGNsYXNzPVwibGlzdC1ncm91cCBsaXN0LWdyb3VwLWZsdXNoXCIgKm5nSWY9XCIhdmlzaXRGb3JtXCI+XHJcbiAgICAgICAgICAgICAgICA8bGkgY2xhc3M9XCJsaXN0LWdyb3VwLWl0ZW0gbGlzdC1ncm91cC1pdGVtLWFjdGlvblwiICpuZ0Zvcj1cImxldCB2aXNpdCBvZiB2aXNpdHM7IGluZGV4IGFzIGluZGV4XCJcclxuICAgICAgICAgICAgICAgICAgICAoY2xpY2spPVwib25Ub2dnbGVEZXRhaWwoaW5kZXgpXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImQtZmxleCBqdXN0aWZ5LWNvbnRlbnQtYmV0d2VlbiBhbGlnbi1pdGVtcy1jZW50ZXJcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAge3t2aXNpdC5uYW1lID8gdmlzaXQubmFtZSA6IHZpc2l0Lm1vZGVsM2QgfX1cclxuICAgICAgICAgICAgICAgICAgICAgICAgPGxpYi1jaGV2cm9uIFtjb25kaXRpb25TaG93aW5nXT1cImluZGV4PT12aXNpdEluZGV4RGV0YWlsc1wiPjwvbGliLWNoZXZyb24+XHJcbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgPGRpdiAqbmdJZj1cImluZGV4PT12aXNpdEluZGV4RGV0YWlsc1wiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8dWwgY2xhc3M9XCJsaXN0LWdyb3VwIGxpc3QtZ3JvdXAtZmx1c2hcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxsaSBjbGFzcz1cImxpc3QtZ3JvdXAtaXRlbSBiZy10cmFuc3BhcmVudFwiPnt7J05hbWUnIHwgdHJhbnNsYXRlfX0gOiB7eyB2aXNpdC5uYW1lID9cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2aXNpdC5uYW1lIDogXCJOb3QgcHJvdmlkZWRcIiB8IHRyYW5zbGF0ZX19PC9saT5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxsaSBjbGFzcz1cImxpc3QtZ3JvdXAtaXRlbSBiZy10cmFuc3BhcmVudFwiPnt7JzNEIE1vZGVsJyB8IHRyYW5zbGF0ZX19IDoge3sgdmlzaXQubW9kZWwzZCB9fVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9saT5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxsaSBjbGFzcz1cImxpc3QtZ3JvdXAtaXRlbSBiZy10cmFuc3BhcmVudFwiPnt7J1N1cmZhY2UnIHwgdHJhbnNsYXRlfX0sIG08c3VwPjI8L3N1cD46IHt7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmlzaXQuc3VyZmFjZSA/XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmlzaXQuc3VyZmFjZSA6ICdOb3QgcHJvdmlkZWQnIHwgdHJhbnNsYXRlfX08L2xpPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGxpIGNsYXNzPVwibGlzdC1ncm91cC1pdGVtIGJnLXRyYW5zcGFyZW50XCI+e3snVmlld2VyJyB8IHRyYW5zbGF0ZX19IDoge3sgdmlzaXQudmlld2VyIH19XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2xpPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGxpIGNsYXNzPVwibGlzdC1ncm91cC1pdGVtIGJnLXRyYW5zcGFyZW50XCI+e3snRGF0ZSBvZiBjYXB0dXJlJyB8IHRyYW5zbGF0ZX19IDoge3tcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2aXNpdC50YWtlbkF0IHwgdGltZURhdGVTdHJpbmcgfCBhc3luY319XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bGkgY2xhc3M9XCJsaXN0LWdyb3VwLWl0ZW0gYmctdHJhbnNwYXJlbnRcIj57eydJbWFnZXMgYXJlIGltcG9ydGVkJyB8IHRyYW5zbGF0ZX19IDoge3tcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2aXNpdC5pbWFnZXNJbXBvcnRlZCB9fVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9saT5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPC91bD5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgY2xhc3M9XCJidG4gYnRuLW91dGxpbmUtcHJpbWFyeSByb3VuZGVkLXBpbGwgbWUtMlwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAqbmdJZj1cIiF2aXNpdC5pbWFnZXNJbXBvcnRlZFwiIChjbGljayk9XCJvbkltcG9ydCh2aXNpdClcIj57eydJbXBvcnQgaW1hZ2VzJyB8XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cmFuc2xhdGV9fTwvYnV0dG9uPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBjbGFzcz1cImJ0biBidG4tb3V0bGluZS1wcmltYXJ5IHJvdW5kZWQtcGlsbCBtZS0yXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIChjbGljayk9XCJvbkVkaXQodmlzaXQpXCI+e3snRWRpdCcgfCB0cmFuc2xhdGV9fTwvYnV0dG9uPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBjbGFzcz1cImJ0biBidG4tb3V0bGluZS1wcmltYXJ5IHJvdW5kZWQtcGlsbFwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAoY2xpY2spPVwib25EZWxldGUodmlzaXQpXCI+e3snRGVsZXRlJyB8IHRyYW5zbGF0ZX19PC9idXR0b24+XHJcbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICA8L2xpPlxyXG4gICAgICAgICAgICA8L3VsPlxyXG4gICAgICAgICAgICA8ZGl2ICpuZ0lmPVwidmlzaXRGb3JtXCI+XHJcbiAgICAgICAgICAgICAgICA8Zm9ybSAobmdTdWJtaXQpPVwib25TdWJtaXRWaXNpdCgpXCIgW2Zvcm1Hcm91cF09XCJ2aXNpdEZvcm1cIj5cclxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibWItMyByb3dcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwiY29sLXNtLTIgY29sLWZvcm0tbGFiZWxcIj57eydOYW1lJyB8IHRyYW5zbGF0ZX19PC9sYWJlbD5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNvbC1zbS0xMFwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJ0ZXh0XCIgY2xhc3M9XCJmb3JtLWNvbnRyb2xcIiBmb3JtQ29udHJvbE5hbWU9XCJuYW1lXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJtYi0zIHJvd1wiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJjb2wtc20tMiBjb2wtZm9ybS1sYWJlbFwiPnt7J1JlZmVyZW5jZSAzRCBtb2RlbCcgfCB0cmFuc2xhdGV9fSAqPC9sYWJlbD5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNvbC1zbS0xMFwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJ0ZXh0XCIgY2xhc3M9XCJmb3JtLWNvbnRyb2xcIiBbcmVhZG9ubHldPVwiaXNFZGl0aW5nXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbY2xhc3MuaXMtaW52YWxpZF09XCJtb2RlbDNELmludmFsaWQgJiYgdmlzaXRTdWJtaXR0ZWRcIiByZXF1aXJlZFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvcm1Db250cm9sTmFtZT1cIm1vZGVsM0RcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJpbnZhbGlkLWZlZWRiYWNrXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge3snUGxlYXNlIHByb3ZpZGUgdGhlIDNEIG1vZGVsIHJlZmVyZW5jZScgfCB0cmFuc2xhdGV9fVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2ICpuZ0lmPVwiaXNFZGl0aW5nXCIgY2xhc3M9XCJ0ZXh0LWRhbmdlclwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt7J0Nhbm5vdCBjaGFuZ2UgM0QgbW9kZWwgcmVmZXJlbmNlLiBQbGVhc2UgYWRkIG5ldyBtb2RlbC4nIHwgdHJhbnNsYXRlfX1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm1iLTMgcm93XCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cImNvbC1zbS0yIGNvbC1mb3JtLWxhYmVsXCI+e3snVmlld2VyJyB8IHRyYW5zbGF0ZX19PC9sYWJlbD5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNvbC1zbS0xMFwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJ0ZXh0XCIgY2xhc3M9XCJmb3JtLWNvbnRyb2xcIiBmb3JtQ29udHJvbE5hbWU9XCJ2aWV3ZXJcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJtYi0zIHJvd1wiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJjb2wtc20tMiBjb2wtZm9ybS1sYWJlbFwiPnt7J1N1cmZhY2UnIHwgdHJhbnNsYXRlfX08L2xhYmVsPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY29sLXNtLTEwXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW5wdXQgdHlwZT1cInRleHRcIiBjbGFzcz1cImZvcm0tY29udHJvbFwiIGZvcm1Db250cm9sTmFtZT1cInN1cmZhY2VcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJtYi0zIHJvd1wiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJjb2wtc20tMiBjb2wtZm9ybS1sYWJlbFwiPnt7J0NhcHR1cmUgRGF0ZScgfCB0cmFuc2xhdGV9fTwvbGFiZWw+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJpbnB1dC1ncm91cFwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0IGNsYXNzPVwiZm9ybS1jb250cm9sXCIgcGxhY2Vob2xkZXI9XCJkZC9tbS95eXl5XCIgWyhuZ01vZGVsKV09XCJjYXB0dXJlRGF0ZVwiIG5nYkRhdGVwaWNrZXJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjZDE9XCJuZ2JEYXRlcGlja2VyXCIgW25nTW9kZWxPcHRpb25zXT1cIntzdGFuZGFsb25lOiB0cnVlfVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImlucHV0LWdyb3VwLWFwcGVuZFwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxidXR0b24gY2xhc3M9XCJidG4gYnRuLW91dGxpbmUtc2Vjb25kYXJ5IGNhbGVuZGFyXCIgKGNsaWNrKT1cImQxLnRvZ2dsZSgpXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZT1cImJ1dHRvblwiPjwvYnV0dG9uPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgIDxidXR0b24gdHlwZT1cInN1Ym1pdFwiIGNsYXNzPVwiYnRuIGJ0bi1vdXRsaW5lLXByaW1hcnkgcm91bmRlZC1waWxsIG1lLTJcIj57eydTYXZlJyB8XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRyYW5zbGF0ZX19PC9idXR0b24+XHJcbiAgICAgICAgICAgICAgICAgICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgKGNsaWNrKT1cIm9uQ2FuY2VsKClcIiBjbGFzcz1cImJ0biBidG4tb3V0bGluZS1wcmltYXJ5IHJvdW5kZWQtcGlsbFwiPnt7J0NhbmNlbCcgfFxyXG4gICAgICAgICAgICAgICAgICAgICAgICB0cmFuc2xhdGV9fTwvYnV0dG9uPlxyXG4gICAgICAgICAgICAgICAgPC9mb3JtPlxyXG4gICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgPGRpdiAqbmdJZj1cIiF2aXNpdEZvcm1cIj5cclxuICAgICAgICAgICAgICAgIDxidXR0b24gY2xhc3M9XCJidG4gYnRuLW91dGxpbmUtcHJpbWFyeSByb3VuZGVkLXBpbGxcIiAoY2xpY2spPVwib25BZGRWaXNpdCgpXCI+e3snQWRkIDNEIHZpc2l0JyB8XHJcbiAgICAgICAgICAgICAgICAgICAgdHJhbnNsYXRlfX08L2J1dHRvbj5cclxuICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgPGRpdiBpZD1cInZpZXdlci1mcmFtZVwiIHN0eWxlPVwid2lkdGg6IDEwMCU7IGFzcGVjdC1yYXRpbzogMi8xO1wiPjwvZGl2PlxyXG4gICAgPC9kaXY+XHJcbiAgICA8bmctdGVtcGxhdGUgI2NvbnRlbnQgbGV0LW1vZGFsPlxyXG4gICAgICAgIDxkaXYgY2xhc3M9XCJtb2RhbC1oZWFkZXJcIj5cclxuICAgICAgICAgICAgPGg0IGNsYXNzPVwibW9kYWwtdGl0bGVcIiBpZD1cIm1vZGFsLWJhc2ljLXRpdGxlXCI+e3snSW1wb3J0aW5nIERhdGEnIHwgdHJhbnNsYXRlfX08L2g0PlxyXG4gICAgICAgICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBjbGFzcz1cImNsb3NlXCIgYXJpYS1sYWJlbD1cIkNsb3NlXCIgKGNsaWNrKT1cIm1vZGFsLmRpc21pc3MoJ0Nyb3NzIGNsaWNrJylcIj5cclxuICAgICAgICAgICAgICAgIDxzcGFuIGFyaWEtaGlkZGVuPVwidHJ1ZVwiPsOXPC9zcGFuPlxyXG4gICAgICAgICAgICA8L2J1dHRvbj5cclxuICAgICAgICA8L2Rpdj5cclxuICAgICAgICA8ZGl2IGNsYXNzPVwibW9kYWwtYm9keVwiPlxyXG4gICAgICAgICAgICB7eydQbGVhc2UgZG8gbm90IGxlYXZlIG9yIHJlZnJlc2ggdGhpcyBwYWdlLi4uJyB8IHRyYW5zbGF0ZX19XHJcbiAgICAgICAgICAgIDxkaXYgKm5nSWY9XCJ0b3RhbEltYWdlcyAhPSAwXCI+SW1wb3J0ZWQge3tpbWFnZXNQcm9jZXNzZWR9fSBvdXQgb2Yge3t0b3RhbEltYWdlc319IGltYWdlcy48L2Rpdj5cclxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImQtZmxleCBqdXN0aWZ5LWNvbnRlbnQtY2VudGVyXCI+XHJcbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic3Bpbm5lci1ib3JkZXJcIiByb2xlPVwic3RhdHVzXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJ2aXN1YWxseS1oaWRkZW5cIj57eydMb2FkaW5nJyB8IHRyYW5zbGF0ZX19Li4uPC9zcGFuPlxyXG4gICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgIDwvZGl2PlxyXG4gICAgICAgIDxkaXYgY2xhc3M9XCJtb2RhbC1mb290ZXJcIj5cclxuICAgICAgICAgICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgY2xhc3M9XCJidG4gYnRuLW91dGxpbmUtZGFya1wiIFtkaXNhYmxlZF09XCIhY2FuQ2FuY2VsSW1wb3J0XCJcclxuICAgICAgICAgICAgICAgIChjbGljayk9XCJtb2RhbC5jbG9zZSgnQ2FuY2VsIGNsaWNrJylcIj57eydDYW5jZWwgaW1wb3J0IG9mIGltYWdlcycgfCB0cmFuc2xhdGV9fTwvYnV0dG9uPlxyXG4gICAgICAgIDwvZGl2PlxyXG4gICAgPC9uZy10ZW1wbGF0ZT5cclxuPC9kaXY+Il19
1
+ import { Component, ViewChild } from '@angular/core';
2
+ import { Validators } from '@angular/forms';
3
+ import { ModalDismissReasons } from '@ng-bootstrap/ng-bootstrap';
4
+ import { CaptureViewer } from '@smarterplan/ngx-smarterplan-core';
5
+ import * as i0 from "@angular/core";
6
+ import * as i1 from "@angular/forms";
7
+ import * as i2 from "@smarterplan/ngx-smarterplan-core";
8
+ import * as i3 from "@angular/router";
9
+ import * as i4 from "@ng-bootstrap/ng-bootstrap";
10
+ import * as i5 from "../tab-navigation/tab-navigation.component";
11
+ import * as i6 from "../chevron/chevron.component";
12
+ import * as i7 from "@angular/common";
13
+ import * as i8 from "@ngx-translate/core";
14
+ export class VisitsComponent {
15
+ constructor(fb, matterportImportService, captureService, nodeService, spaceService, route, modalService, visitService) {
16
+ this.fb = fb;
17
+ this.matterportImportService = matterportImportService;
18
+ this.captureService = captureService;
19
+ this.nodeService = nodeService;
20
+ this.spaceService = spaceService;
21
+ this.route = route;
22
+ this.modalService = modalService;
23
+ this.visitService = visitService;
24
+ this.visitIndexDetails = -1;
25
+ this.isEditing = false;
26
+ this.visitSubmitted = false;
27
+ this.currentSpace = { zones: [] };
28
+ this.visits = [];
29
+ this.canCancelImport = false;
30
+ this.imagesProcessed = 0;
31
+ this.totalImages = 0;
32
+ this.menuItems = [];
33
+ this.matterportImportService.importingImages.subscribe(() => {
34
+ this.canCancelImport = true;
35
+ });
36
+ this.matterportImportService.sweepProcessedCount.subscribe((count) => {
37
+ this.imagesProcessed = count + 1;
38
+ });
39
+ this.matterportImportService.totalSweepsCount.subscribe((count) => {
40
+ this.totalImages = count;
41
+ });
42
+ }
43
+ ngOnInit() {
44
+ this.spaceId = this.route.snapshot.paramMap.get("id");
45
+ this.resetVisits();
46
+ }
47
+ /*
48
+ Visit = {
49
+ captureID: string,
50
+ model3d: string,
51
+ takenAt: number,
52
+ spaceID: string,
53
+ viewer: CaptureViewer,
54
+ surface: number,
55
+ node: Node,
56
+ name?: string | null
57
+ }
58
+ */
59
+ setupMenuItems() {
60
+ this.menuItems = [
61
+ { label: "Locations", url: "/localisation" },
62
+ {
63
+ label: this.currentSpace.name,
64
+ url: `/localisation/${this.currentSpace.id}`,
65
+ },
66
+ {
67
+ label: "Virtual visits",
68
+ url: `/localisation/${this.currentSpace.id}/visits`,
69
+ },
70
+ ];
71
+ }
72
+ onGoBack() {
73
+ this.onCancel();
74
+ }
75
+ async resetVisits() {
76
+ this.visits = [];
77
+ this.currentSpace = await this.spaceService.getSpace(this.spaceId);
78
+ this.setupMenuItems();
79
+ await this.visitService
80
+ .getVisitsForSpaceForUser(this.spaceId)
81
+ .then((visits) => {
82
+ if (visits) {
83
+ this.visits = visits;
84
+ }
85
+ });
86
+ }
87
+ initVisitForm(input = null) {
88
+ if (input) {
89
+ this.visitForm = this.fb.group({
90
+ captureID: input.captureID,
91
+ nodeID: input.node.id,
92
+ name: [input.name, [Validators.required]],
93
+ model3D: [input.model3d, [Validators.required]],
94
+ viewer: input.viewer ? input.viewer : CaptureViewer.MATTERPORT,
95
+ surface: input.surface ? input.surface : null,
96
+ });
97
+ this.captureDate = input.takenAt;
98
+ }
99
+ else {
100
+ this.visitForm = this.fb.group({
101
+ model3D: [null, [Validators.required]],
102
+ viewer: CaptureViewer.MATTERPORT,
103
+ surface: null,
104
+ name: [null, [Validators.required]],
105
+ });
106
+ }
107
+ }
108
+ onToggleDetail(index) {
109
+ this.visitIndexDetails = index === this.visitIndexDetails ? -1 : index;
110
+ }
111
+ onAddVisit() {
112
+ this.initVisitForm();
113
+ this.menuItems.push({ label: "New" });
114
+ }
115
+ onEdit(visit) {
116
+ this.initVisitForm(visit);
117
+ this.isEditing = true;
118
+ this.menuItems.push({ label: visit.name });
119
+ }
120
+ async onSubmitVisit() {
121
+ this.visitSubmitted = true;
122
+ if (!this.visitForm.valid) {
123
+ return;
124
+ }
125
+ const formValue = this.visitForm.value;
126
+ const capture = {
127
+ viewer: formValue.viewer,
128
+ takenAt: this.captureDate,
129
+ surface: formValue.surface,
130
+ spaceID: this.currentSpace.id,
131
+ };
132
+ if (this.isEditing) {
133
+ capture.id = formValue.captureID;
134
+ await this.captureService.updateCapture(capture);
135
+ const node = {
136
+ id: formValue.nodeID,
137
+ model3D: formValue.model3D,
138
+ metadata: formValue.name,
139
+ };
140
+ await this.nodeService.updateNode(node);
141
+ }
142
+ else {
143
+ let createdNode;
144
+ await this.captureService.createCapture(capture).then(async (res) => {
145
+ if (res) {
146
+ const node = {
147
+ model3D: formValue.model3D,
148
+ captureID: res.id,
149
+ metadata: formValue.name,
150
+ };
151
+ createdNode = await this.nodeService.createNode(node);
152
+ }
153
+ });
154
+ this.launchImport(formValue.model3D, formValue.surface, createdNode, false).then((success) => {
155
+ this.modalReference.close("import ended with success");
156
+ }).catch((e) => {
157
+ this.modalReference.close(`Error while import: ${e}`);
158
+ alert(`Error while import: ${e}`);
159
+ this.onDelete({ node: createdNode, captureID: createdNode.captureID });
160
+ });
161
+ }
162
+ await this.resetVisits();
163
+ this.onCancel();
164
+ }
165
+ get model3D() {
166
+ return this.visitForm.get("model3D");
167
+ }
168
+ get name() {
169
+ return this.visitForm.get("name");
170
+ }
171
+ onCancel() {
172
+ this.visitSubmitted = false;
173
+ this.visitForm = null;
174
+ this.isEditing = false;
175
+ this.canCancelImport = false;
176
+ this.totalImages = 0;
177
+ this.imagesProcessed = 0;
178
+ this.setupMenuItems();
179
+ }
180
+ async onDelete(visit) {
181
+ await this.visitService.deleteVisit(visit, this.spaceId);
182
+ this.resetVisits();
183
+ }
184
+ getDismissReason(reason) {
185
+ if (reason === ModalDismissReasons.ESC) {
186
+ return "by pressing ESC";
187
+ }
188
+ if (reason === ModalDismissReasons.BACKDROP_CLICK) {
189
+ return "by clicking on a backdrop";
190
+ }
191
+ return `with: ${reason}`;
192
+ }
193
+ async launchImport(model3D, surface, node, imagesOnly = false) {
194
+ this.modalReference = this.modalService.open(this.content, {
195
+ ariaLabelledBy: "modal-basic-title",
196
+ });
197
+ this.modalReference.result.then((result) => {
198
+ this.closeResult = `Closed with: ${result}`;
199
+ console.log(this.closeResult);
200
+ this.cancelImport();
201
+ }, (error) => {
202
+ this.closeResult = `Dismissed ${this.getDismissReason(error)}`;
203
+ console.log(this.closeResult);
204
+ this.cancelImport();
205
+ });
206
+ try {
207
+ await this.matterportImportService.initSdkForModel(model3D);
208
+ return imagesOnly
209
+ ? this.matterportImportService.importData(this.spaceId, surface, true, node)
210
+ : this.matterportImportService.importData(this.spaceId, surface, false, node);
211
+ }
212
+ catch (error) {
213
+ console.log(error);
214
+ return Promise.reject(error);
215
+ }
216
+ }
217
+ cancelImport() {
218
+ this.matterportImportService.abandon();
219
+ this.onCancel();
220
+ this.resetVisits();
221
+ }
222
+ onImport(visit) {
223
+ this.launchImport(visit.model3d, null, visit.node.id, true);
224
+ }
225
+ }
226
+ VisitsComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.7", ngImport: i0, type: VisitsComponent, deps: [{ token: i1.FormBuilder }, { token: i2.MatterportImportService }, { token: i2.CaptureService }, { token: i2.NodeService }, { token: i2.SpaceService }, { token: i3.ActivatedRoute }, { token: i4.NgbModal }, { token: i2.VisitService }], target: i0.ɵɵFactoryTarget.Component });
227
+ VisitsComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.2.7", 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 (click)=\"onToggleDetail(index)\">\n <div class=\"d-flex justify-content-between align-items-center\">\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 visit.imagesImported }}\n </li>\n </ul>\n <button type=\"button\" class=\"btn btn-outline-primary rounded-pill me-2\"\n *ngIf=\"!visit.imagesImported\" (click)=\"onImport(visit)\">{{'Import images' |\n translate}}</button>\n <button type=\"button\" class=\"btn btn-outline-primary rounded-pill me-2\"\n (click)=\"onEdit(visit)\">{{'Edit' | translate}}</button>\n <button type=\"button\" class=\"btn btn-outline-primary rounded-pill\"\n (click)=\"onDelete(visit)\">{{'Delete' | translate}}</button>\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 {{'Please provide the 3D model reference' | translate}}\n </div>\n <div *ngIf=\"isEditing\" class=\"text-danger\">\n {{'Cannot change 3D model reference. Please add new model.' | 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 <input type=\"text\" class=\"form-control\" formControlName=\"viewer\">\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 </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:-moz-fit-content;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"], components: [{ type: i5.TabNavigationComponent, selector: "lib-tab-navigation", inputs: ["menuItems"], outputs: ["onGoBack"] }, { type: i6.ChevronComponent, selector: "lib-chevron", inputs: ["conditionShowing"] }], directives: [{ type: i7.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i7.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { 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]" }, { type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { type: i1.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { type: i4.NgbInputDatepicker, selector: "input[ngbDatepicker]", inputs: ["autoClose", "datepickerClass", "dayTemplate", "dayTemplateData", "displayMonths", "firstDayOfWeek", "footerTemplate", "markDisabled", "minDate", "maxDate", "navigation", "outsideDays", "placement", "restoreFocus", "showWeekNumbers", "startDate", "container", "positionTarget", "weekdays", "disabled"], outputs: ["dateSelect", "navigate", "closed"], exportAs: ["ngbDatepicker"] }, { type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }], pipes: { "translate": i8.TranslatePipe, "async": i7.AsyncPipe, "timeDateString": i2.TimeDateToLocalStringPipe } });
228
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.7", ngImport: i0, type: VisitsComponent, decorators: [{
229
+ type: Component,
230
+ 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 (click)=\"onToggleDetail(index)\">\n <div class=\"d-flex justify-content-between align-items-center\">\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 visit.imagesImported }}\n </li>\n </ul>\n <button type=\"button\" class=\"btn btn-outline-primary rounded-pill me-2\"\n *ngIf=\"!visit.imagesImported\" (click)=\"onImport(visit)\">{{'Import images' |\n translate}}</button>\n <button type=\"button\" class=\"btn btn-outline-primary rounded-pill me-2\"\n (click)=\"onEdit(visit)\">{{'Edit' | translate}}</button>\n <button type=\"button\" class=\"btn btn-outline-primary rounded-pill\"\n (click)=\"onDelete(visit)\">{{'Delete' | translate}}</button>\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 {{'Please provide the 3D model reference' | translate}}\n </div>\n <div *ngIf=\"isEditing\" class=\"text-danger\">\n {{'Cannot change 3D model reference. Please add new model.' | 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 <input type=\"text\" class=\"form-control\" formControlName=\"viewer\">\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 </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:-moz-fit-content;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"] }]
231
+ }], ctorParameters: function () { return [{ type: i1.FormBuilder }, { type: i2.MatterportImportService }, { type: i2.CaptureService }, { type: i2.NodeService }, { type: i2.SpaceService }, { type: i3.ActivatedRoute }, { type: i4.NgbModal }, { type: i2.VisitService }]; }, propDecorators: { content: [{
232
+ type: ViewChild,
233
+ args: ["content", { static: false }]
234
+ }] } });
235
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmlzaXRzLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL25neC1zbWFydGVycGxhbi1sb2NhdGlvbnMvc3JjL2xpYi9jb21wb25lbnRzL3Zpc2l0cy92aXNpdHMuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvbmd4LXNtYXJ0ZXJwbGFuLWxvY2F0aW9ucy9zcmMvbGliL2NvbXBvbmVudHMvdmlzaXRzL3Zpc2l0cy5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsU0FBUyxFQUFVLFNBQVMsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUM3RCxPQUFPLEVBQTBCLFVBQVUsRUFBbUIsTUFBTSxnQkFBZ0IsQ0FBQztBQUVyRixPQUFPLEVBQVksbUJBQW1CLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUMzRSxPQUFPLEVBQTJHLGFBQWEsRUFBVyxNQUFNLG1DQUFtQyxDQUFDOzs7Ozs7Ozs7O0FBT3BMLE1BQU0sT0FBTyxlQUFlO0lBK0J4QixZQUNZLEVBQWUsRUFDZix1QkFBZ0QsRUFDaEQsY0FBOEIsRUFDOUIsV0FBd0IsRUFDeEIsWUFBMEIsRUFDMUIsS0FBcUIsRUFDckIsWUFBc0IsRUFDdEIsWUFBMEI7UUFQMUIsT0FBRSxHQUFGLEVBQUUsQ0FBYTtRQUNmLDRCQUF1QixHQUF2Qix1QkFBdUIsQ0FBeUI7UUFDaEQsbUJBQWMsR0FBZCxjQUFjLENBQWdCO1FBQzlCLGdCQUFXLEdBQVgsV0FBVyxDQUFhO1FBQ3hCLGlCQUFZLEdBQVosWUFBWSxDQUFjO1FBQzFCLFVBQUssR0FBTCxLQUFLLENBQWdCO1FBQ3JCLGlCQUFZLEdBQVosWUFBWSxDQUFVO1FBQ3RCLGlCQUFZLEdBQVosWUFBWSxDQUFjO1FBcEN0QyxzQkFBaUIsR0FBRyxDQUFDLENBQUMsQ0FBQztRQUl2QixjQUFTLEdBQVksS0FBSyxDQUFDO1FBRTNCLG1C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Q0FBQyxDQUFDO0lBQ2hFLENBQUM7OzRHQWpSUSxlQUFlO2dHQUFmLGVBQWUsc0pDWDVCLG04T0EySE07MkZEaEhPLGVBQWU7a0JBTDNCLFNBQVM7K0JBQ0ksWUFBWTt5U0F1QjJCLE9BQU87c0JBQXZELFNBQVM7dUJBQUMsU0FBUyxFQUFFLEVBQUUsTUFBTSxFQUFFLEtBQUssRUFBRSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbXBvbmVudCwgT25Jbml0LCBWaWV3Q2hpbGQgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IEZvcm1Hcm91cCwgRm9ybUJ1aWxkZXIsIFZhbGlkYXRvcnMsIEFic3RyYWN0Q29udHJvbCB9IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcbmltcG9ydCB7IEFjdGl2YXRlZFJvdXRlIH0gZnJvbSAnQGFuZ3VsYXIvcm91dGVyJztcbmltcG9ydCB7IE5nYk1vZGFsLCBNb2RhbERpc21pc3NSZWFzb25zIH0gZnJvbSAnQG5nLWJvb3RzdHJhcC9uZy1ib290c3RyYXAnO1xuaW1wb3J0IHsgTm9kZSwgVmlzaXQsIE1lbnVJdGVtLCBNYXR0ZXJwb3J0SW1wb3J0U2VydmljZSwgQ2FwdHVyZVNlcnZpY2UsIE5vZGVTZXJ2aWNlLCBTcGFjZVNlcnZpY2UsIFZpc2l0U2VydmljZSwgQ2FwdHVyZVZpZXdlciwgQ2FwdHVyZSB9IGZyb20gJ0BzbWFydGVycGxhbi9uZ3gtc21hcnRlcnBsYW4tY29yZSc7XG5cbkBDb21wb25lbnQoe1xuICAgIHNlbGVjdG9yOiAnbGliLXZpc2l0cycsXG4gICAgdGVtcGxhdGVVcmw6ICcuL3Zpc2l0cy5jb21wb25lbnQuaHRtbCcsXG4gICAgc3R5bGVVcmxzOiBbJy4vdmlzaXRzLmNvbXBvbmVudC5zY3NzJ11cbn0pXG5leHBvcnQgY2xhc3MgVmlzaXRzQ29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0IHtcbiAgICBzcGFjZUlkOiBzdHJpbmc7XG5cbiAgICB2aXNpdEluZGV4RGV0YWlscyA9IC0xO1xuXG4gICAgdmlzaXRGb3JtOiBGb3JtR3JvdXA7XG5cbiAgICBpc0VkaXRpbmc6IGJvb2xlYW4gPSBmYWxzZTtcblxuICAgIHZpc2l0U3VibWl0dGVkOiBib29sZWFuID0gZmFsc2U7XG5cbiAgICBjYXB0dXJlRGF0ZTogbnVtYmVyO1xuXG4gICAgY3VycmVudFNwYWNlID0geyB6b25lczogW10gfSBhcyBhbnk7XG5cbiAgICB2aXNpdHM6IFZpc2l0W10gPSBbXTtcblxuICAgIGNsb3NlUmVzdWx0OiBzdHJpbmc7XG5cbiAgICBAVmlld0NoaWxkKFwiY29udGVudFwiLCB7IHN0YXRpYzogZmFsc2UgfSkgcHJpdmF0ZSBjb250ZW50O1xuXG4gICAgbW9kYWxSZWZlcmVuY2U6IGFueTtcblxuICAgIGNhbkNhbmNlbEltcG9ydCA9IGZhbHNlO1xuXG4gICAgaW1hZ2VzUHJvY2Vzc2VkOiBudW1iZXIgPSAwO1xuXG4gICAgdG90YWxJbWFnZXM6IG51bWJlciA9IDA7XG5cbiAgICBtZW51SXRlbXM6IE1lbnVJdGVtW10gPSBbXTtcblxuICAgIGNvbnN0cnVjdG9yKFxuICAgICAgICBwcml2YXRlIGZiOiBGb3JtQnVpbGRlcixcbiAgICAgICAgcHJpdmF0ZSBtYXR0ZXJwb3J0SW1wb3J0U2VydmljZTogTWF0dGVycG9ydEltcG9ydFNlcnZpY2UsXG4gICAgICAgIHByaXZhdGUgY2FwdHVyZVNlcnZpY2U6IENhcHR1cmVTZXJ2aWNlLFxuICAgICAgICBwcml2YXRlIG5vZGVTZXJ2aWNlOiBOb2RlU2VydmljZSxcbiAgICAgICAgcHJpdmF0ZSBzcGFjZVNlcnZpY2U6IFNwYWNlU2VydmljZSxcbiAgICAgICAgcHJpdmF0ZSByb3V0ZTogQWN0aXZhdGVkUm91dGUsXG4gICAgICAgIHByaXZhdGUgbW9kYWxTZXJ2aWNlOiBOZ2JNb2RhbCxcbiAgICAgICAgcHJpdmF0ZSB2aXNpdFNlcnZpY2U6IFZpc2l0U2VydmljZSxcbiAgICApIHtcbiAgICAgICAgdGhpcy5tYXR0ZXJwb3J0SW1wb3J0U2VydmljZS5pbXBvcnRpbmdJbWFnZXMuc3Vic2NyaWJlKCgpID0+IHtcbiAgICAgICAgICAgIHRoaXMuY2FuQ2FuY2VsSW1wb3J0ID0gdHJ1ZTtcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMubWF0dGVycG9ydEltcG9ydFNlcnZpY2Uuc3dlZXBQcm9jZXNzZWRDb3VudC5zdWJzY3JpYmUoKGNvdW50KSA9PiB7XG4gICAgICAgICAgICB0aGlzLmltYWdlc1Byb2Nlc3NlZCA9IGNvdW50ICsgMTtcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMubWF0dGVycG9ydEltcG9ydFNlcnZpY2UudG90YWxTd2VlcHNDb3VudC5zdWJzY3JpYmUoKGNvdW50KSA9PiB7XG4gICAgICAgICAgICB0aGlzLnRvdGFsSW1hZ2VzID0gY291bnQ7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIG5nT25Jbml0KCk6IHZvaWQge1xuICAgICAgICB0aGlzLnNwYWNlSWQgPSB0aGlzLnJvdXRlLnNuYXBzaG90LnBhcmFtTWFwLmdldChcImlkXCIpO1xuICAgICAgICB0aGlzLnJlc2V0VmlzaXRzKCk7XG4gICAgfVxuXG4gICAgLypcbiAgVmlzaXQgPSB7XG4gICAgY2FwdHVyZUlEOiBzdHJpbmcsXG4gICAgbW9kZWwzZDogc3RyaW5nLFxuICAgIHRha2VuQXQ6IG51bWJlcixcbiAgICBzcGFjZUlEOiBzdHJpbmcsXG4gICAgdmlld2VyOiBDYXB0dXJlVmlld2VyLFxuICAgIHN1cmZhY2U6IG51bWJlcixcbiAgICBub2RlOiBOb2RlLFxuICAgIG5hbWU/OiBzdHJpbmcgfCBudWxsXG4gIH1cbiAgKi9cbiAgICBzZXR1cE1lbnVJdGVtcygpIHtcbiAgICAgICAgdGhpcy5tZW51SXRlbXMgPSBbXG4gICAgICAgICAgICB7IGxhYmVsOiBcIkxvY2F0aW9uc1wiLCB1cmw6IFwiL2xvY2FsaXNhdGlvblwiIH0sXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgbGFiZWw6IHRoaXMuY3VycmVudFNwYWNlLm5hbWUsXG4gICAgICAgICAgICAgICAgdXJsOiBgL2xvY2FsaXNhdGlvbi8ke3RoaXMuY3VycmVudFNwYWNlLmlkfWAsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIGxhYmVsOiBcIlZpcnR1YWwgdmlzaXRzXCIsXG4gICAgICAgICAgICAgICAgdXJsOiBgL2xvY2FsaXNhdGlvbi8ke3RoaXMuY3VycmVudFNwYWNlLmlkfS92aXNpdHNgLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgXTtcbiAgICB9XG5cbiAgICBvbkdvQmFjaygpIHtcbiAgICAgICAgdGhpcy5vbkNhbmNlbCgpO1xuICAgIH1cblxuICAgIGFzeW5jIHJlc2V0VmlzaXRzKCkge1xuICAgICAgICB0aGlzLnZpc2l0cyA9IFtdO1xuICAgICAgICB0aGlzLmN1cnJlbnRTcGFjZSA9IGF3YWl0IHRoaXMuc3BhY2VTZXJ2aWNlLmdldFNwYWNlKHRoaXMuc3BhY2VJZCk7XG4gICAgICAgIHRoaXMuc2V0dXBNZW51SXRlbXMoKTtcbiAgICAgICAgYXdhaXQgdGhpcy52aXNpdFNlcnZpY2VcbiAgICAgICAgICAgIC5nZXRWaXNpdHNGb3JTcGFjZUZvclVzZXIodGhpcy5zcGFjZUlkKVxuICAgICAgICAgICAgLnRoZW4oKHZpc2l0cykgPT4ge1xuICAgICAgICAgICAgICAgIGlmICh2aXNpdHMpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy52aXNpdHMgPSB2aXNpdHM7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgaW5pdFZpc2l0Rm9ybShpbnB1dDogVmlzaXQgPSBudWxsKSB7XG4gICAgICAgIGlmIChpbnB1dCkge1xuICAgICAgICAgICAgdGhpcy52aXNpdEZvcm0gPSB0aGlzLmZiLmdyb3VwKHtcbiAgICAgICAgICAgICAgICBjYXB0dXJlSUQ6IGlucHV0LmNhcHR1cmVJRCxcbiAgICAgICAgICAgICAgICBub2RlSUQ6IGlucHV0Lm5vZGUuaWQsXG4gICAgICAgICAgICAgICAgbmFtZTogW2lucHV0Lm5hbWUsIFtWYWxpZGF0b3JzLnJlcXVpcmVkXV0sXG4gICAgICAgICAgICAgICAgbW9kZWwzRDogW2lucHV0Lm1vZGVsM2QsIFtWYWxpZGF0b3JzLnJlcXVpcmVkXV0sXG4gICAgICAgICAgICAgICAgdmlld2VyOiBpbnB1dC52aWV3ZXIgPyBpbnB1dC52aWV3ZXIgOiBDYXB0dXJlVmlld2VyLk1BVFRFUlBPUlQsXG4gICAgICAgICAgICAgICAgc3VyZmFjZTogaW5wdXQuc3VyZmFjZSA/IGlucHV0LnN1cmZhY2UgOiBudWxsLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB0aGlzLmNhcHR1cmVEYXRlID0gaW5wdXQudGFrZW5BdDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMudmlzaXRGb3JtID0gdGhpcy5mYi5ncm91cCh7XG4gICAgICAgICAgICAgICAgbW9kZWwzRDogW251bGwsIFtWYWxpZGF0b3JzLnJlcXVpcmVkXV0sXG4gICAgICAgICAgICAgICAgdmlld2VyOiBDYXB0dXJlVmlld2VyLk1BVFRFUlBPUlQsXG4gICAgICAgICAgICAgICAgc3VyZmFjZTogbnVsbCxcbiAgICAgICAgICAgICAgICBuYW1lOiBbbnVsbCwgW1ZhbGlkYXRvcnMucmVxdWlyZWRdXSxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgb25Ub2dnbGVEZXRhaWwoaW5kZXgpIHtcbiAgICAgICAgdGhpcy52aXNpdEluZGV4RGV0YWlscyA9IGluZGV4ID09PSB0aGlzLnZpc2l0SW5kZXhEZXRhaWxzID8gLTEgOiBpbmRleDtcbiAgICB9XG5cbiAgICBvbkFkZFZpc2l0KCkge1xuICAgICAgICB0aGlzLmluaXRWaXNpdEZvcm0oKTtcbiAgICAgICAgdGhpcy5tZW51SXRlbXMucHVzaCh7IGxhYmVsOiBcIk5ld1wiIH0pO1xuICAgIH1cblxuICAgIG9uRWRpdCh2aXNpdCkge1xuICAgICAgICB0aGlzLmluaXRWaXNpdEZvcm0odmlzaXQpO1xuICAgICAgICB0aGlzLmlzRWRpdGluZyA9IHRydWU7XG4gICAgICAgIHRoaXMubWVudUl0ZW1zLnB1c2goeyBsYWJlbDogdmlzaXQubmFtZSB9KTtcbiAgICB9XG5cbiAgICBhc3luYyBvblN1Ym1pdFZpc2l0KCkge1xuICAgICAgICB0aGlzLnZpc2l0U3VibWl0dGVkID0gdHJ1ZTtcbiAgICAgICAgaWYgKCF0aGlzLnZpc2l0Rm9ybS52YWxpZCkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGZvcm1WYWx1ZSA9IHRoaXMudmlzaXRGb3JtLnZhbHVlO1xuICAgICAgICBjb25zdCBjYXB0dXJlID0ge1xuICAgICAgICAgICAgdmlld2VyOiBmb3JtVmFsdWUudmlld2VyLFxuICAgICAgICAgICAgdGFrZW5BdDogdGhpcy5jYXB0dXJlRGF0ZSxcbiAgICAgICAgICAgIHN1cmZhY2U6IGZvcm1WYWx1ZS5zdXJmYWNlLFxuICAgICAgICAgICAgc3BhY2VJRDogdGhpcy5jdXJyZW50U3BhY2UuaWQsXG4gICAgICAgIH0gYXMgQ2FwdHVyZTtcblxuICAgICAgICBpZiAodGhpcy5pc0VkaXRpbmcpIHtcbiAgICAgICAgICAgIGNhcHR1cmUuaWQgPSBmb3JtVmFsdWUuY2FwdHVyZUlEO1xuICAgICAgICAgICAgYXdhaXQgdGhpcy5jYXB0dXJlU2VydmljZS51cGRhdGVDYXB0dXJlKGNhcHR1cmUpO1xuICAgICAgICAgICAgY29uc3Qgbm9kZSA9IHtcbiAgICAgICAgICAgICAgICBpZDogZm9ybVZhbHVlLm5vZGVJRCxcbiAgICAgICAgICAgICAgICBtb2RlbDNEOiBmb3JtVmFsdWUubW9kZWwzRCxcbiAgICAgICAgICAgICAgICBtZXRhZGF0YTogZm9ybVZhbHVlLm5hbWUsXG4gICAgICAgICAgICB9IGFzIE5vZGU7XG4gICAgICAgICAgICBhd2FpdCB0aGlzLm5vZGVTZXJ2aWNlLnVwZGF0ZU5vZGUobm9kZSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBsZXQgY3JlYXRlZE5vZGU7XG4gICAgICAgICAgICBhd2FpdCB0aGlzLmNhcHR1cmVTZXJ2aWNlLmNyZWF0ZUNhcHR1cmUoY2FwdHVyZSkudGhlbihhc3luYyAocmVzKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKHJlcykge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBub2RlID0ge1xuICAgICAgICAgICAgICAgICAgICAgICAgbW9kZWwzRDogZm9ybVZhbHVlLm1vZGVsM0QsXG4gICAgICAgICAgICAgICAgICAgICAgICBjYXB0dXJlSUQ6IHJlcy5pZCxcbiAgICAgICAgICAgICAgICAgICAgICAgIG1ldGFkYXRhOiBmb3JtVmFsdWUubmFtZSxcbiAgICAgICAgICAgICAgICAgICAgfSBhcyBOb2RlO1xuICAgICAgICAgICAgICAgICAgICBjcmVhdGVkTm9kZSA9IGF3YWl0IHRoaXMubm9kZVNlcnZpY2UuY3JlYXRlTm9kZShub2RlKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHRoaXMubGF1bmNoSW1wb3J0KFxuICAgICAgICAgICAgICAgIGZvcm1WYWx1ZS5tb2RlbDNELFxuICAgICAgICAgICAgICAgIGZvcm1WYWx1ZS5zdXJmYWNlLFxuICAgICAgICAgICAgICAgIGNyZWF0ZWROb2RlLFxuICAgICAgICAgICAgICAgIGZhbHNlLFxuICAgICAgICAgICAgKS50aGVuKChzdWNjZXNzKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5tb2RhbFJlZmVyZW5jZS5jbG9zZShcImltcG9ydCBlbmRlZCB3aXRoIHN1Y2Nlc3NcIik7XG4gICAgICAgICAgICB9KS5jYXRjaCgoZSkgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMubW9kYWxSZWZlcmVuY2UuY2xvc2UoYEVycm9yIHdoaWxlIGltcG9ydDogJHtlfWApO1xuICAgICAgICAgICAgICAgIGFsZXJ0KGBFcnJvciB3aGlsZSBpbXBvcnQ6ICR7ZX1gKTtcbiAgICAgICAgICAgICAgICB0aGlzLm9uRGVsZXRlKHsgbm9kZTogY3JlYXRlZE5vZGUsIGNhcHR1cmVJRDogY3JlYXRlZE5vZGUuY2FwdHVyZUlEIH0gYXMgVmlzaXQpO1xuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgfVxuICAgICAgICBhd2FpdCB0aGlzLnJlc2V0VmlzaXRzKCk7XG4gICAgICAgIHRoaXMub25DYW5jZWwoKTtcbiAgICB9XG5cbiAgICBnZXQgbW9kZWwzRCgpOiBBYnN0cmFjdENvbnRyb2wge1xuICAgICAgICByZXR1cm4gdGhpcy52aXNpdEZvcm0uZ2V0KFwibW9kZWwzRFwiKTtcbiAgICB9XG5cbiAgICBnZXQgbmFtZSgpOiBBYnN0cmFjdENvbnRyb2wge1xuICAgICAgICByZXR1cm4gdGhpcy52aXNpdEZvcm0uZ2V0KFwibmFtZVwiKTtcbiAgICB9XG5cbiAgICBvbkNhbmNlbCgpIHtcbiAgICAgICAgdGhpcy52aXNpdFN1Ym1pdHRlZCA9IGZhbHNlO1xuICAgICAgICB0aGlzLnZpc2l0Rm9ybSA9IG51bGw7XG4gICAgICAgIHRoaXMuaXNFZGl0aW5nID0gZmFsc2U7XG4gICAgICAgIHRoaXMuY2FuQ2FuY2VsSW1wb3J0ID0gZmFsc2U7XG4gICAgICAgIHRoaXMudG90YWxJbWFnZXMgPSAwO1xuICAgICAgICB0aGlzLmltYWdlc1Byb2Nlc3NlZCA9IDA7XG4gICAgICAgIHRoaXMuc2V0dXBNZW51SXRlbXMoKTtcbiAgICB9XG5cbiAgICBhc3luYyBvbkRlbGV0ZSh2aXNpdDogVmlzaXQpIHtcbiAgICAgICAgYXdhaXQgdGhpcy52aXNpdFNlcnZpY2UuZGVsZXRlVmlzaXQodmlzaXQsIHRoaXMuc3BhY2VJZCk7XG4gICAgICAgIHRoaXMucmVzZXRWaXNpdHMoKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGdldERpc21pc3NSZWFzb24ocmVhc29uOiBhbnkpOiBzdHJpbmcge1xuICAgICAgICBpZiAocmVhc29uID09PSBNb2RhbERpc21pc3NSZWFzb25zLkVTQykge1xuICAgICAgICAgICAgcmV0dXJuIFwiYnkgcHJlc3NpbmcgRVNDXCI7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHJlYXNvbiA9PT0gTW9kYWxEaXNtaXNzUmVhc29ucy5CQUNLRFJPUF9DTElDSykge1xuICAgICAgICAgICAgcmV0dXJuIFwiYnkgY2xpY2tpbmcgb24gYSBiYWNrZHJvcFwiO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBgd2l0aDogJHtyZWFzb259YDtcbiAgICB9XG5cbiAgICBhc3luYyBsYXVuY2hJbXBvcnQoXG4gICAgICAgIG1vZGVsM0QsXG4gICAgICAgIHN1cmZhY2UsXG4gICAgICAgIG5vZGUsXG4gICAgICAgIGltYWdlc09ubHkgPSBmYWxzZSxcbiAgICApOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgICAgICAgdGhpcy5tb2RhbFJlZmVyZW5jZSA9IHRoaXMubW9kYWxTZXJ2aWNlLm9wZW4odGhpcy5jb250ZW50LCB7XG4gICAgICAgICAgICBhcmlhTGFiZWxsZWRCeTogXCJtb2RhbC1iYXNpYy10aXRsZVwiLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5tb2RhbFJlZmVyZW5jZS5yZXN1bHQudGhlbihcbiAgICAgICAgICAgIChyZXN1bHQpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLmNsb3NlUmVzdWx0ID0gYENsb3NlZCB3aXRoOiAke3Jlc3VsdH1gO1xuICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKHRoaXMuY2xvc2VSZXN1bHQpO1xuICAgICAgICAgICAgICAgIHRoaXMuY2FuY2VsSW1wb3J0KCk7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgKGVycm9yKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5jbG9zZVJlc3VsdCA9IGBEaXNtaXNzZWQgJHt0aGlzLmdldERpc21pc3NSZWFzb24oZXJyb3IpfWA7XG4gICAgICAgICAgICAgICAgY29uc29sZS5sb2codGhpcy5jbG9zZVJlc3VsdCk7XG4gICAgICAgICAgICAgICAgdGhpcy5jYW5jZWxJbXBvcnQoKTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICk7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBhd2FpdCB0aGlzLm1hdHRlcnBvcnRJbXBvcnRTZXJ2aWNlLmluaXRTZGtGb3JNb2RlbChcbiAgICAgICAgICAgICAgICBtb2RlbDNELFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIHJldHVybiBpbWFnZXNPbmx5XG4gICAgICAgICAgICAgICAgPyB0aGlzLm1hdHRlcnBvcnRJbXBvcnRTZXJ2aWNlLmltcG9ydERhdGEoXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuc3BhY2VJZCxcbiAgICAgICAgICAgICAgICAgICAgc3VyZmFjZSxcbiAgICAgICAgICAgICAgICAgICAgdHJ1ZSxcbiAgICAgICAgICAgICAgICAgICAgbm9kZSxcbiAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICAgICAgOiB0aGlzLm1hdHRlcnBvcnRJbXBvcnRTZXJ2aWNlLmltcG9ydERhdGEoXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuc3BhY2VJZCxcbiAgICAgICAgICAgICAgICAgICAgc3VyZmFjZSxcbiAgICAgICAgICAgICAgICAgICAgZmFsc2UsXG4gICAgICAgICAgICAgICAgICAgIG5vZGUsXG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgIGNvbnNvbGUubG9nKGVycm9yKTtcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChlcnJvcik7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIGNhbmNlbEltcG9ydCgpIHtcbiAgICAgICAgdGhpcy5tYXR0ZXJwb3J0SW1wb3J0U2VydmljZS5hYmFuZG9uKCk7XG4gICAgICAgIHRoaXMub25DYW5jZWwoKTtcbiAgICAgICAgdGhpcy5yZXNldFZpc2l0cygpO1xuICAgIH1cblxuICAgIG9uSW1wb3J0KHZpc2l0OiBWaXNpdCkge1xuICAgICAgICB0aGlzLmxhdW5jaEltcG9ydCh2aXNpdC5tb2RlbDNkLCBudWxsLCB2aXNpdC5ub2RlLmlkLCB0cnVlKTtcbiAgICB9XG59XG4iLCI8ZGl2IGNsYXNzPVwiY29udGFpbmVyLWZsdWlkXCIgY2xhc3M9XCJkYXNoYm9hcmQtdGFiXCI+XG4gICAgPGRpdiBjbGFzcz1cIm0tM1wiPlxuICAgICAgICA8bGliLXRhYi1uYXZpZ2F0aW9uIFttZW51SXRlbXNdPSdtZW51SXRlbXMnIChvbkdvQmFjayk9XCJvbkdvQmFjaygpXCI+PC9saWItdGFiLW5hdmlnYXRpb24+XG4gICAgPC9kaXY+XG5cbiAgICA8ZGl2IGNsYXNzPVwicm93IG1haW4tZm9ybS1jb250YWluZXJcIj5cbiAgICAgICAgPGRpdiBjbGFzcz1cImNvbC1tZC02IGZvcm0tY29udGFpbmVyXCI+XG4gICAgICAgICAgICA8dWwgY2xhc3M9XCJsaXN0LWdyb3VwIGxpc3QtZ3JvdXAtZmx1c2hcIiAqbmdJZj1cIiF2aXNpdEZvcm1cIj5cbiAgICAgICAgICAgICAgICA8bGkgY2xhc3M9XCJsaXN0LWdyb3VwLWl0ZW0gbGlzdC1ncm91cC1pdGVtLWFjdGlvblwiICpuZ0Zvcj1cImxldCB2aXNpdCBvZiB2aXNpdHM7IGluZGV4IGFzIGluZGV4XCJcbiAgICAgICAgICAgICAgICAgICAgKGNsaWNrKT1cIm9uVG9nZ2xlRGV0YWlsKGluZGV4KVwiPlxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZC1mbGV4IGp1c3RpZnktY29udGVudC1iZXR3ZWVuIGFsaWduLWl0ZW1zLWNlbnRlclwiPlxuICAgICAgICAgICAgICAgICAgICAgICAge3t2aXNpdC5uYW1lID8gdmlzaXQubmFtZSA6IHZpc2l0Lm1vZGVsM2QgfX1cbiAgICAgICAgICAgICAgICAgICAgICAgIDxsaWItY2hldnJvbiBbY29uZGl0aW9uU2hvd2luZ109XCJpbmRleD09dmlzaXRJbmRleERldGFpbHNcIj48L2xpYi1jaGV2cm9uPlxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiAqbmdJZj1cImluZGV4PT12aXNpdEluZGV4RGV0YWlsc1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPHVsIGNsYXNzPVwibGlzdC1ncm91cCBsaXN0LWdyb3VwLWZsdXNoXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGxpIGNsYXNzPVwibGlzdC1ncm91cC1pdGVtIGJnLXRyYW5zcGFyZW50XCI+e3snTmFtZScgfCB0cmFuc2xhdGV9fSA6IHt7IHZpc2l0Lm5hbWUgP1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2aXNpdC5uYW1lIDogXCJOb3QgcHJvdmlkZWRcIiB8IHRyYW5zbGF0ZX19PC9saT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bGkgY2xhc3M9XCJsaXN0LWdyb3VwLWl0ZW0gYmctdHJhbnNwYXJlbnRcIj57eyczRCBNb2RlbCcgfCB0cmFuc2xhdGV9fSA6IHt7IHZpc2l0Lm1vZGVsM2QgfX1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2xpPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxsaSBjbGFzcz1cImxpc3QtZ3JvdXAtaXRlbSBiZy10cmFuc3BhcmVudFwiPnt7J1N1cmZhY2UnIHwgdHJhbnNsYXRlfX0sIG08c3VwPjI8L3N1cD46IHt7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZpc2l0LnN1cmZhY2UgP1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2aXNpdC5zdXJmYWNlIDogJ05vdCBwcm92aWRlZCcgfCB0cmFuc2xhdGV9fTwvbGk+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGxpIGNsYXNzPVwibGlzdC1ncm91cC1pdGVtIGJnLXRyYW5zcGFyZW50XCI+e3snVmlld2VyJyB8IHRyYW5zbGF0ZX19IDoge3sgdmlzaXQudmlld2VyIH19XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9saT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bGkgY2xhc3M9XCJsaXN0LWdyb3VwLWl0ZW0gYmctdHJhbnNwYXJlbnRcIj57eydEYXRlIG9mIGNhcHR1cmUnIHwgdHJhbnNsYXRlfX0gOiB7e1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2aXNpdC50YWtlbkF0IHwgdGltZURhdGVTdHJpbmcgfCBhc3luY319XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGxpIGNsYXNzPVwibGlzdC1ncm91cC1pdGVtIGJnLXRyYW5zcGFyZW50XCI+e3snSW1hZ2VzIGFyZSBpbXBvcnRlZCcgfCB0cmFuc2xhdGV9fSA6IHt7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZpc2l0LmltYWdlc0ltcG9ydGVkIH19XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9saT5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvdWw+XG4gICAgICAgICAgICAgICAgICAgICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBjbGFzcz1cImJ0biBidG4tb3V0bGluZS1wcmltYXJ5IHJvdW5kZWQtcGlsbCBtZS0yXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAqbmdJZj1cIiF2aXNpdC5pbWFnZXNJbXBvcnRlZFwiIChjbGljayk9XCJvbkltcG9ydCh2aXNpdClcIj57eydJbXBvcnQgaW1hZ2VzJyB8XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJhbnNsYXRlfX08L2J1dHRvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIGNsYXNzPVwiYnRuIGJ0bi1vdXRsaW5lLXByaW1hcnkgcm91bmRlZC1waWxsIG1lLTJcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIChjbGljayk9XCJvbkVkaXQodmlzaXQpXCI+e3snRWRpdCcgfCB0cmFuc2xhdGV9fTwvYnV0dG9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgY2xhc3M9XCJidG4gYnRuLW91dGxpbmUtcHJpbWFyeSByb3VuZGVkLXBpbGxcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIChjbGljayk9XCJvbkRlbGV0ZSh2aXNpdClcIj57eydEZWxldGUnIHwgdHJhbnNsYXRlfX08L2J1dHRvbj5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgPC9saT5cbiAgICAgICAgICAgIDwvdWw+XG4gICAgICAgICAgICA8ZGl2ICpuZ0lmPVwidmlzaXRGb3JtXCI+XG4gICAgICAgICAgICAgICAgPGZvcm0gKG5nU3VibWl0KT1cIm9uU3VibWl0VmlzaXQoKVwiIFtmb3JtR3JvdXBdPVwidmlzaXRGb3JtXCI+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJtYi0zIHJvd1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwiY29sLXNtLTIgY29sLWZvcm0tbGFiZWxcIj57eydOYW1lJyB8IHRyYW5zbGF0ZX19PC9sYWJlbD5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjb2wtc20tMTBcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW5wdXQgdHlwZT1cInRleHRcIiBjbGFzcz1cImZvcm0tY29udHJvbFwiIGZvcm1Db250cm9sTmFtZT1cIm5hbWVcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm1iLTMgcm93XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJjb2wtc20tMiBjb2wtZm9ybS1sYWJlbFwiPnt7J1JlZmVyZW5jZSAzRCBtb2RlbCcgfCB0cmFuc2xhdGV9fSAqPC9sYWJlbD5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjb2wtc20tMTBcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW5wdXQgdHlwZT1cInRleHRcIiBjbGFzcz1cImZvcm0tY29udHJvbFwiIFtyZWFkb25seV09XCJpc0VkaXRpbmdcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbY2xhc3MuaXMtaW52YWxpZF09XCJtb2RlbDNELmludmFsaWQgJiYgdmlzaXRTdWJtaXR0ZWRcIiByZXF1aXJlZFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3JtQ29udHJvbE5hbWU9XCJtb2RlbDNEXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImludmFsaWQtZmVlZGJhY2tcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge3snUGxlYXNlIHByb3ZpZGUgdGhlIDNEIG1vZGVsIHJlZmVyZW5jZScgfCB0cmFuc2xhdGV9fVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgKm5nSWY9XCJpc0VkaXRpbmdcIiBjbGFzcz1cInRleHQtZGFuZ2VyXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt7J0Nhbm5vdCBjaGFuZ2UgM0QgbW9kZWwgcmVmZXJlbmNlLiBQbGVhc2UgYWRkIG5ldyBtb2RlbC4nIHwgdHJhbnNsYXRlfX1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibWItMyByb3dcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cImNvbC1zbS0yIGNvbC1mb3JtLWxhYmVsXCI+e3snVmlld2VyJyB8IHRyYW5zbGF0ZX19PC9sYWJlbD5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjb2wtc20tMTBcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW5wdXQgdHlwZT1cInRleHRcIiBjbGFzcz1cImZvcm0tY29udHJvbFwiIGZvcm1Db250cm9sTmFtZT1cInZpZXdlclwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJtYi0zIHJvd1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwiY29sLXNtLTIgY29sLWZvcm0tbGFiZWxcIj57eydTdXJmYWNlJyB8IHRyYW5zbGF0ZX19PC9sYWJlbD5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjb2wtc20tMTBcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW5wdXQgdHlwZT1cInRleHRcIiBjbGFzcz1cImZvcm0tY29udHJvbFwiIGZvcm1Db250cm9sTmFtZT1cInN1cmZhY2VcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibWItMyByb3dcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cImNvbC1zbS0yIGNvbC1mb3JtLWxhYmVsXCI+e3snQ2FwdHVyZSBEYXRlJyB8IHRyYW5zbGF0ZX19PC9sYWJlbD5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJpbnB1dC1ncm91cFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dCBjbGFzcz1cImZvcm0tY29udHJvbFwiIHBsYWNlaG9sZGVyPVwiZGQvbW0veXl5eVwiIFsobmdNb2RlbCldPVwiY2FwdHVyZURhdGVcIiBuZ2JEYXRlcGlja2VyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICNkMT1cIm5nYkRhdGVwaWNrZXJcIiBbbmdNb2RlbE9wdGlvbnNdPVwie3N0YW5kYWxvbmU6IHRydWV9XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImlucHV0LWdyb3VwLWFwcGVuZFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8YnV0dG9uIGNsYXNzPVwiYnRuIGJ0bi1vdXRsaW5lLXNlY29uZGFyeSBjYWxlbmRhclwiIChjbGljayk9XCJkMS50b2dnbGUoKVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlPVwiYnV0dG9uXCI+PC9idXR0b24+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDxidXR0b24gdHlwZT1cInN1Ym1pdFwiIGNsYXNzPVwiYnRuIGJ0bi1vdXRsaW5lLXByaW1hcnkgcm91bmRlZC1waWxsIG1lLTJcIj57eydTYXZlJyB8XG4gICAgICAgICAgICAgICAgICAgICAgICB0cmFuc2xhdGV9fTwvYnV0dG9uPlxuICAgICAgICAgICAgICAgICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiAoY2xpY2spPVwib25DYW5jZWwoKVwiIGNsYXNzPVwiYnRuIGJ0bi1vdXRsaW5lLXByaW1hcnkgcm91bmRlZC1waWxsXCI+e3snQ2FuY2VsJyB8XG4gICAgICAgICAgICAgICAgICAgICAgICB0cmFuc2xhdGV9fTwvYnV0dG9uPlxuICAgICAgICAgICAgICAgIDwvZm9ybT5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPGRpdiAqbmdJZj1cIiF2aXNpdEZvcm1cIj5cbiAgICAgICAgICAgICAgICA8YnV0dG9uIGNsYXNzPVwiYnRuIGJ0bi1vdXRsaW5lLXByaW1hcnkgcm91bmRlZC1waWxsXCIgKGNsaWNrKT1cIm9uQWRkVmlzaXQoKVwiPnt7J0FkZCAzRCB2aXNpdCcgfFxuICAgICAgICAgICAgICAgICAgICB0cmFuc2xhdGV9fTwvYnV0dG9uPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuICAgICAgICA8ZGl2IGlkPVwidmlld2VyLWZyYW1lXCIgc3R5bGU9XCJ3aWR0aDogMTAwJTsgYXNwZWN0LXJhdGlvOiAyLzE7XCI+PC9kaXY+XG4gICAgPC9kaXY+XG4gICAgPG5nLXRlbXBsYXRlICNjb250ZW50IGxldC1tb2RhbD5cbiAgICAgICAgPGRpdiBjbGFzcz1cIm1vZGFsLWhlYWRlclwiPlxuICAgICAgICAgICAgPGg0IGNsYXNzPVwibW9kYWwtdGl0bGVcIiBpZD1cIm1vZGFsLWJhc2ljLXRpdGxlXCI+e3snSW1wb3J0aW5nIERhdGEnIHwgdHJhbnNsYXRlfX08L2g0PlxuICAgICAgICAgICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgY2xhc3M9XCJjbG9zZVwiIGFyaWEtbGFiZWw9XCJDbG9zZVwiIChjbGljayk9XCJtb2RhbC5kaXNtaXNzKCdDcm9zcyBjbGljaycpXCI+XG4gICAgICAgICAgICAgICAgPHNwYW4gYXJpYS1oaWRkZW49XCJ0cnVlXCI+w5c8L3NwYW4+XG4gICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgPC9kaXY+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJtb2RhbC1ib2R5XCI+XG4gICAgICAgICAgICB7eydQbGVhc2UgZG8gbm90IGxlYXZlIG9yIHJlZnJlc2ggdGhpcyBwYWdlLi4uJyB8IHRyYW5zbGF0ZX19XG4gICAgICAgICAgICA8ZGl2ICpuZ0lmPVwidG90YWxJbWFnZXMgIT0gMFwiPkltcG9ydGVkIHt7aW1hZ2VzUHJvY2Vzc2VkfX0gb3V0IG9mIHt7dG90YWxJbWFnZXN9fSBpbWFnZXMuPC9kaXY+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZC1mbGV4IGp1c3RpZnktY29udGVudC1jZW50ZXJcIj5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic3Bpbm5lci1ib3JkZXJcIiByb2xlPVwic3RhdHVzXCI+XG4gICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwidmlzdWFsbHktaGlkZGVuXCI+e3snTG9hZGluZycgfCB0cmFuc2xhdGV9fS4uLjwvc3Bhbj5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L2Rpdj5cbiAgICAgICAgPGRpdiBjbGFzcz1cIm1vZGFsLWZvb3RlclwiPlxuICAgICAgICAgICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgY2xhc3M9XCJidG4gYnRuLW91dGxpbmUtZGFya1wiIFtkaXNhYmxlZF09XCIhY2FuQ2FuY2VsSW1wb3J0XCJcbiAgICAgICAgICAgICAgICAoY2xpY2spPVwibW9kYWwuY2xvc2UoJ0NhbmNlbCBjbGljaycpXCI+e3snQ2FuY2VsIGltcG9ydCBvZiBpbWFnZXMnIHwgdHJhbnNsYXRlfX08L2J1dHRvbj5cbiAgICAgICAgPC9kaXY+XG4gICAgPC9uZy10ZW1wbGF0ZT5cbjwvZGl2PiJdfQ==