@smarterplan/ngx-smarterplan-locations 0.2.44 → 0.2.45
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/esm2020/lib/components/carousel/carousel.component.mjs +28 -0
- package/esm2020/lib/components/chevron/chevron.component.mjs +18 -0
- package/esm2020/lib/components/detail-location/detail-location.component.mjs +168 -0
- package/esm2020/lib/components/form-location/form-location.component.mjs +237 -0
- package/esm2020/lib/components/images/images.component.mjs +107 -0
- package/esm2020/lib/components/locations/locations.component.mjs +145 -0
- package/esm2020/lib/components/locations/map/map-popup/map-popup.component.mjs +66 -0
- package/esm2020/lib/components/locations/map/map.component.mjs +91 -0
- package/esm2020/lib/components/plan-legend/plan-legend.component.mjs +47 -0
- package/esm2020/lib/components/plans/calibration/calibration.component.mjs +468 -0
- package/esm2020/lib/components/plans/edit-plan/edit-plan.component.mjs +324 -0
- package/esm2020/lib/components/plans/plans.component.mjs +225 -0
- package/esm2020/lib/components/tab-navigation/tab-navigation.component.mjs +41 -0
- package/esm2020/lib/components/visits/visits.component.mjs +283 -0
- package/esm2020/lib/components/zones/add-audio-zone/add-audio-zone.component.mjs +230 -0
- package/esm2020/lib/components/zones/add-zone/add-zone.component.mjs +315 -0
- package/esm2020/lib/components/zones/add-zone/selection/selection.component.mjs +77 -0
- package/esm2020/lib/components/zones/add-zone/sweep-plan-selection/sweep-plan-selection.component.mjs +502 -0
- package/esm2020/lib/components/zones/zones.component.mjs +268 -0
- package/esm2020/lib/helper.service.mjs +134 -0
- package/esm2020/lib/ngx-smarterplan-location-routing.module.mjs +49 -0
- package/esm2020/lib/ngx-smarterplan-locations.module.mjs +125 -0
- package/esm2020/lib/ngx-smarterplan-locations.service.mjs +14 -0
- package/esm2020/lib/pipes/count-audio-sweeps.pipe.mjs +27 -0
- package/esm2020/lib/radio-button/radio-button.component.mjs +26 -0
- package/esm2020/public-api.mjs +9 -0
- package/esm2020/smarterplan-ngx-smarterplan-locations.mjs +5 -0
- package/fesm2015/smarterplan-ngx-smarterplan-locations.mjs +3991 -0
- package/fesm2015/smarterplan-ngx-smarterplan-locations.mjs.map +1 -0
- package/fesm2020/smarterplan-ngx-smarterplan-locations.mjs +3828 -0
- package/fesm2020/smarterplan-ngx-smarterplan-locations.mjs.map +1 -0
- package/lib/components/carousel/carousel.component.d.ts +12 -0
- package/lib/components/chevron/chevron.component.d.ts +9 -0
- package/lib/components/detail-location/detail-location.component.d.ts +55 -0
- package/lib/components/form-location/form-location.component.d.ts +45 -0
- package/lib/components/images/images.component.d.ts +33 -0
- package/lib/components/locations/locations.component.d.ts +51 -0
- package/lib/components/locations/map/map-popup/map-popup.component.d.ts +22 -0
- package/lib/components/locations/map/map.component.d.ts +22 -0
- package/lib/components/plan-legend/plan-legend.component.d.ts +14 -0
- package/lib/components/plans/calibration/calibration.component.d.ts +140 -0
- package/lib/components/plans/edit-plan/edit-plan.component.d.ts +55 -0
- package/lib/components/plans/plans.component.d.ts +63 -0
- package/lib/components/tab-navigation/tab-navigation.component.d.ts +13 -0
- package/lib/components/visits/visits.component.d.ts +62 -0
- package/lib/components/zones/add-audio-zone/add-audio-zone.component.d.ts +63 -0
- package/lib/components/zones/add-zone/add-zone.component.d.ts +69 -0
- package/lib/components/zones/add-zone/selection/selection.component.d.ts +44 -0
- package/lib/components/zones/add-zone/sweep-plan-selection/sweep-plan-selection.component.d.ts +107 -0
- package/lib/components/zones/zones.component.d.ts +73 -0
- package/lib/helper.service.d.ts +53 -0
- package/lib/ngx-smarterplan-location-routing.module.d.ts +7 -0
- package/lib/ngx-smarterplan-locations.module.d.ts +36 -0
- package/lib/ngx-smarterplan-locations.service.d.ts +6 -0
- package/lib/pipes/count-audio-sweeps.pipe.d.ts +10 -0
- package/lib/radio-button/radio-button.component.d.ts +12 -0
- package/package.json +22 -5
- package/{src/public-api.ts → public-api.d.ts} +4 -11
- package/smarterplan-ngx-smarterplan-locations.d.ts +5 -0
- package/.browserslistrc +0 -16
- package/karma.conf.js +0 -44
- package/ng-package.json +0 -7
- package/src/lib/components/carousel/carousel.component.html +0 -13
- package/src/lib/components/carousel/carousel.component.scss +0 -0
- package/src/lib/components/carousel/carousel.component.spec.ts +0 -25
- package/src/lib/components/carousel/carousel.component.ts +0 -31
- package/src/lib/components/chevron/chevron.component.html +0 -5
- package/src/lib/components/chevron/chevron.component.scss +0 -16
- package/src/lib/components/chevron/chevron.component.spec.ts +0 -25
- package/src/lib/components/chevron/chevron.component.ts +0 -17
- package/src/lib/components/detail-location/detail-location.component.html +0 -108
- package/src/lib/components/detail-location/detail-location.component.scss +0 -0
- package/src/lib/components/detail-location/detail-location.component.spec.ts +0 -25
- package/src/lib/components/detail-location/detail-location.component.ts +0 -215
- package/src/lib/components/form-location/form-location.component.html +0 -160
- package/src/lib/components/form-location/form-location.component.scss +0 -62
- package/src/lib/components/form-location/form-location.component.spec.ts +0 -25
- package/src/lib/components/form-location/form-location.component.ts +0 -274
- package/src/lib/components/images/images.component.html +0 -27
- package/src/lib/components/images/images.component.scss +0 -0
- package/src/lib/components/images/images.component.spec.ts +0 -25
- package/src/lib/components/images/images.component.ts +0 -133
- package/src/lib/components/locations/locations.component.html +0 -63
- package/src/lib/components/locations/locations.component.scss +0 -121
- package/src/lib/components/locations/locations.component.spec.ts +0 -25
- package/src/lib/components/locations/locations.component.ts +0 -186
- package/src/lib/components/locations/map/map-popup/map-popup.component.html +0 -11
- package/src/lib/components/locations/map/map-popup/map-popup.component.scss +0 -51
- package/src/lib/components/locations/map/map-popup/map-popup.component.spec.ts +0 -25
- package/src/lib/components/locations/map/map-popup/map-popup.component.ts +0 -79
- package/src/lib/components/locations/map/map.component.html +0 -2
- package/src/lib/components/locations/map/map.component.scss +0 -0
- package/src/lib/components/locations/map/map.component.spec.ts +0 -25
- package/src/lib/components/locations/map/map.component.ts +0 -111
- package/src/lib/components/plan-legend/plan-legend.component.html +0 -9
- package/src/lib/components/plan-legend/plan-legend.component.scss +0 -38
- package/src/lib/components/plan-legend/plan-legend.component.spec.ts +0 -25
- package/src/lib/components/plan-legend/plan-legend.component.ts +0 -50
- package/src/lib/components/plans/calibration/calibration.component.html +0 -98
- package/src/lib/components/plans/calibration/calibration.component.scss +0 -136
- package/src/lib/components/plans/calibration/calibration.component.spec.ts +0 -25
- package/src/lib/components/plans/calibration/calibration.component.ts +0 -603
- package/src/lib/components/plans/edit-plan/edit-plan.component.html +0 -77
- package/src/lib/components/plans/edit-plan/edit-plan.component.scss +0 -9
- package/src/lib/components/plans/edit-plan/edit-plan.component.spec.ts +0 -25
- package/src/lib/components/plans/edit-plan/edit-plan.component.ts +0 -421
- package/src/lib/components/plans/plans.component.html +0 -102
- package/src/lib/components/plans/plans.component.scss +0 -24
- package/src/lib/components/plans/plans.component.spec.ts +0 -25
- package/src/lib/components/plans/plans.component.ts +0 -305
- package/src/lib/components/tab-navigation/tab-navigation.component.html +0 -7
- package/src/lib/components/tab-navigation/tab-navigation.component.scss +0 -27
- package/src/lib/components/tab-navigation/tab-navigation.component.spec.ts +0 -25
- package/src/lib/components/tab-navigation/tab-navigation.component.ts +0 -35
- package/src/lib/components/visits/visits.component.html +0 -134
- package/src/lib/components/visits/visits.component.scss +0 -24
- package/src/lib/components/visits/visits.component.spec.ts +0 -25
- package/src/lib/components/visits/visits.component.ts +0 -357
- package/src/lib/components/zones/add-audio-zone/add-audio-zone.component.html +0 -73
- package/src/lib/components/zones/add-audio-zone/add-audio-zone.component.scss +0 -14
- package/src/lib/components/zones/add-audio-zone/add-audio-zone.component.spec.ts +0 -25
- package/src/lib/components/zones/add-audio-zone/add-audio-zone.component.ts +0 -269
- package/src/lib/components/zones/add-zone/add-zone.component.html +0 -153
- package/src/lib/components/zones/add-zone/add-zone.component.scss +0 -44
- package/src/lib/components/zones/add-zone/add-zone.component.spec.ts +0 -25
- package/src/lib/components/zones/add-zone/add-zone.component.ts +0 -377
- package/src/lib/components/zones/add-zone/selection/selection.component.html +0 -3
- package/src/lib/components/zones/add-zone/selection/selection.component.scss +0 -16
- package/src/lib/components/zones/add-zone/selection/selection.component.spec.ts +0 -25
- package/src/lib/components/zones/add-zone/selection/selection.component.ts +0 -95
- package/src/lib/components/zones/add-zone/sweep-plan-selection/sweep-plan-selection.component.html +0 -73
- package/src/lib/components/zones/add-zone/sweep-plan-selection/sweep-plan-selection.component.scss +0 -23
- package/src/lib/components/zones/add-zone/sweep-plan-selection/sweep-plan-selection.component.spec.ts +0 -25
- package/src/lib/components/zones/add-zone/sweep-plan-selection/sweep-plan-selection.component.ts +0 -595
- package/src/lib/components/zones/zones.component.html +0 -181
- package/src/lib/components/zones/zones.component.scss +0 -36
- package/src/lib/components/zones/zones.component.spec.ts +0 -25
- package/src/lib/components/zones/zones.component.ts +0 -339
- package/src/lib/helper.service.ts +0 -161
- package/src/lib/ngx-smarterplan-location-routing.module.ts +0 -41
- package/src/lib/ngx-smarterplan-locations.module.ts +0 -74
- package/src/lib/ngx-smarterplan-locations.service.spec.ts +0 -16
- package/src/lib/ngx-smarterplan-locations.service.ts +0 -9
- package/src/lib/pipes/count-audio-sweeps.pipe.ts +0 -21
- package/src/lib/radio-button/radio-button.component.html +0 -9
- package/src/lib/radio-button/radio-button.component.scss +0 -152
- package/src/lib/radio-button/radio-button.component.spec.ts +0 -25
- package/src/lib/radio-button/radio-button.component.ts +0 -26
- package/src/test.ts +0 -27
- package/tsconfig.lib.json +0 -15
- package/tsconfig.lib.prod.json +0 -10
- package/tsconfig.spec.json +0 -17
|
@@ -0,0 +1,283 @@
|
|
|
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 { Subject, takeUntil } from 'rxjs';
|
|
6
|
+
import * as i0 from "@angular/core";
|
|
7
|
+
import * as i1 from "@angular/forms";
|
|
8
|
+
import * as i2 from "@smarterplan/ngx-smarterplan-core";
|
|
9
|
+
import * as i3 from "@angular/router";
|
|
10
|
+
import * as i4 from "@ng-bootstrap/ng-bootstrap";
|
|
11
|
+
import * as i5 from "@ngx-translate/core";
|
|
12
|
+
import * as i6 from "../tab-navigation/tab-navigation.component";
|
|
13
|
+
import * as i7 from "../chevron/chevron.component";
|
|
14
|
+
import * as i8 from "@angular/common";
|
|
15
|
+
export class VisitsComponent {
|
|
16
|
+
constructor(fb, matterportImportService, captureService, nodeService, spaceService, route, modalService, visitService, validatorsService, translate, navigatorService, router) {
|
|
17
|
+
this.fb = fb;
|
|
18
|
+
this.matterportImportService = matterportImportService;
|
|
19
|
+
this.captureService = captureService;
|
|
20
|
+
this.nodeService = nodeService;
|
|
21
|
+
this.spaceService = spaceService;
|
|
22
|
+
this.route = route;
|
|
23
|
+
this.modalService = modalService;
|
|
24
|
+
this.visitService = visitService;
|
|
25
|
+
this.validatorsService = validatorsService;
|
|
26
|
+
this.translate = translate;
|
|
27
|
+
this.navigatorService = navigatorService;
|
|
28
|
+
this.router = router;
|
|
29
|
+
this.visitIndexDetails = -1;
|
|
30
|
+
this.isEditing = false;
|
|
31
|
+
this.visitSubmitted = false;
|
|
32
|
+
this.currentSpace = { zones: [] };
|
|
33
|
+
this.visits = [];
|
|
34
|
+
this.canCancelImport = false;
|
|
35
|
+
this.imagesProcessed = 0;
|
|
36
|
+
this.totalImages = 0;
|
|
37
|
+
this.menuItems = [];
|
|
38
|
+
this.errorForm = false;
|
|
39
|
+
this.isProcessing = false;
|
|
40
|
+
this.destroy$ = new Subject();
|
|
41
|
+
this.matterportImportService.importingImages.pipe(takeUntil(this.destroy$)).subscribe(() => {
|
|
42
|
+
this.canCancelImport = true;
|
|
43
|
+
});
|
|
44
|
+
this.matterportImportService.sweepProcessedCount.pipe(takeUntil(this.destroy$)).subscribe((count) => {
|
|
45
|
+
this.imagesProcessed = count + 1;
|
|
46
|
+
});
|
|
47
|
+
this.matterportImportService.totalSweepsCount.pipe(takeUntil(this.destroy$)).subscribe((count) => {
|
|
48
|
+
this.totalImages = count;
|
|
49
|
+
});
|
|
50
|
+
this.navigatorService.locationIDChange
|
|
51
|
+
.pipe(takeUntil(this.destroy$))
|
|
52
|
+
.subscribe((spaceID) => {
|
|
53
|
+
this.router.navigate(["dashboard/localisation", spaceID, "visits"]);
|
|
54
|
+
});
|
|
55
|
+
this.route.params.subscribe((params) => {
|
|
56
|
+
this.spaceId = params.id;
|
|
57
|
+
this.resetVisits();
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
async ngOnInit() {
|
|
61
|
+
this.spaceId = this.route.snapshot.paramMap.get('id');
|
|
62
|
+
await this.resetVisits();
|
|
63
|
+
// console.log('visit in import', localStorage.getItem("visitInImport"));
|
|
64
|
+
if (localStorage.getItem("visitInImport") && localStorage.getItem("indexScanLoad")) {
|
|
65
|
+
const visitToRetake = this.visits.find((visit) => visit.model3d === localStorage.getItem("visitInImport"));
|
|
66
|
+
if (visitToRetake.spaceID === this.spaceId) {
|
|
67
|
+
console.log("retaking import");
|
|
68
|
+
this.imagesProcessed = parseInt(localStorage.getItem("indexScanLoad"));
|
|
69
|
+
this.onImport(visitToRetake);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
ngOnDestroy() {
|
|
74
|
+
this.destroy$.next(true);
|
|
75
|
+
this.destroy$.complete();
|
|
76
|
+
}
|
|
77
|
+
/*
|
|
78
|
+
Visit = {
|
|
79
|
+
captureID: string,
|
|
80
|
+
model3d: string,
|
|
81
|
+
takenAt: number,
|
|
82
|
+
spaceID: string,
|
|
83
|
+
viewer: CaptureViewer,
|
|
84
|
+
surface: number,
|
|
85
|
+
node: Node,
|
|
86
|
+
name?: string | null
|
|
87
|
+
}
|
|
88
|
+
*/
|
|
89
|
+
setupMenuItems() {
|
|
90
|
+
this.menuItems = [
|
|
91
|
+
{ label: 'Locations', url: '/localisation' },
|
|
92
|
+
{
|
|
93
|
+
label: this.currentSpace.name,
|
|
94
|
+
url: `/localisation/${this.currentSpace.id}`,
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
label: 'Virtual visits',
|
|
98
|
+
url: `/localisation/${this.currentSpace.id}/visits`,
|
|
99
|
+
},
|
|
100
|
+
];
|
|
101
|
+
}
|
|
102
|
+
onGoBack() {
|
|
103
|
+
this.onCancel();
|
|
104
|
+
}
|
|
105
|
+
async resetVisits() {
|
|
106
|
+
this.visits = [];
|
|
107
|
+
this.currentSpace = await this.spaceService.getSpace(this.spaceId);
|
|
108
|
+
this.setupMenuItems();
|
|
109
|
+
await this.visitService
|
|
110
|
+
.getVisitsForSpaceForUser(this.spaceId)
|
|
111
|
+
.then((visits) => {
|
|
112
|
+
if (visits) {
|
|
113
|
+
this.visits = visits;
|
|
114
|
+
}
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
initVisitForm(input = null) {
|
|
118
|
+
if (input) {
|
|
119
|
+
this.visitForm = this.fb.group({
|
|
120
|
+
captureID: input.captureID,
|
|
121
|
+
nodeID: input.node.id,
|
|
122
|
+
name: [input.name, [Validators.required]],
|
|
123
|
+
model3D: [input.model3d, [Validators.required]],
|
|
124
|
+
viewer: input.viewer ? input.viewer : CaptureViewer.MATTERPORT,
|
|
125
|
+
surface: input.surface ? input.surface : null,
|
|
126
|
+
});
|
|
127
|
+
this.captureDate = input.takenAt;
|
|
128
|
+
}
|
|
129
|
+
else {
|
|
130
|
+
this.visitForm = this.fb.group({
|
|
131
|
+
model3D: [null, [Validators.required]],
|
|
132
|
+
viewer: CaptureViewer.MATTERPORT,
|
|
133
|
+
surface: null,
|
|
134
|
+
name: [null, [Validators.required]],
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
onToggleDetail(index) {
|
|
139
|
+
this.visitIndexDetails = index === this.visitIndexDetails ? -1 : index;
|
|
140
|
+
}
|
|
141
|
+
onAddVisit() {
|
|
142
|
+
this.initVisitForm();
|
|
143
|
+
this.menuItems.push({ label: 'New' });
|
|
144
|
+
}
|
|
145
|
+
onEdit(visit) {
|
|
146
|
+
this.initVisitForm(visit);
|
|
147
|
+
this.isEditing = true;
|
|
148
|
+
this.menuItems.push({ label: visit.name });
|
|
149
|
+
}
|
|
150
|
+
async onSubmitVisit() {
|
|
151
|
+
this.visitSubmitted = true;
|
|
152
|
+
if (!this.visitForm.valid) {
|
|
153
|
+
this.errorForm = true;
|
|
154
|
+
return;
|
|
155
|
+
}
|
|
156
|
+
this.errorForm = false;
|
|
157
|
+
const formValue = this.visitForm.value;
|
|
158
|
+
const capture = {
|
|
159
|
+
viewer: formValue.viewer,
|
|
160
|
+
takenAt: this.captureDate,
|
|
161
|
+
surface: formValue.surface,
|
|
162
|
+
spaceID: this.currentSpace.id,
|
|
163
|
+
};
|
|
164
|
+
if (this.isEditing) {
|
|
165
|
+
capture.id = formValue.captureID;
|
|
166
|
+
await this.captureService.updateCapture(capture);
|
|
167
|
+
const node = {
|
|
168
|
+
id: formValue.nodeID,
|
|
169
|
+
model3D: formValue.model3D,
|
|
170
|
+
metadata: formValue.name,
|
|
171
|
+
};
|
|
172
|
+
await this.nodeService.updateNode(node);
|
|
173
|
+
}
|
|
174
|
+
else {
|
|
175
|
+
let createdNode;
|
|
176
|
+
await this.captureService.createCapture(capture).then(async (res) => {
|
|
177
|
+
if (res) {
|
|
178
|
+
const node = {
|
|
179
|
+
model3D: formValue.model3D,
|
|
180
|
+
captureID: res.id,
|
|
181
|
+
metadata: formValue.name,
|
|
182
|
+
};
|
|
183
|
+
createdNode = await this.nodeService.createNode(node);
|
|
184
|
+
}
|
|
185
|
+
});
|
|
186
|
+
this.launchImport(formValue.model3D, formValue.surface, createdNode, false)
|
|
187
|
+
.then((success) => {
|
|
188
|
+
this.modalReference.close('import ended with success');
|
|
189
|
+
})
|
|
190
|
+
.catch((e) => {
|
|
191
|
+
this.modalReference.close(`Error while import: ${e}`);
|
|
192
|
+
alert(`Error while import: ${e} ${JSON.stringify(e)}`);
|
|
193
|
+
this.onDelete({
|
|
194
|
+
node: createdNode,
|
|
195
|
+
captureID: createdNode.captureID,
|
|
196
|
+
}, false);
|
|
197
|
+
});
|
|
198
|
+
}
|
|
199
|
+
await this.resetVisits();
|
|
200
|
+
this.onCancel();
|
|
201
|
+
}
|
|
202
|
+
get model3D() {
|
|
203
|
+
return this.visitForm.get('model3D');
|
|
204
|
+
}
|
|
205
|
+
get name() {
|
|
206
|
+
return this.visitForm.get('name');
|
|
207
|
+
}
|
|
208
|
+
onCancel() {
|
|
209
|
+
this.visitSubmitted = false;
|
|
210
|
+
this.visitForm = null;
|
|
211
|
+
this.isEditing = false;
|
|
212
|
+
this.canCancelImport = false;
|
|
213
|
+
this.totalImages = 0;
|
|
214
|
+
this.imagesProcessed = 0;
|
|
215
|
+
this.errorForm = false;
|
|
216
|
+
this.setupMenuItems();
|
|
217
|
+
}
|
|
218
|
+
async onDelete(visit, needPermission = true) {
|
|
219
|
+
const message = this.translate.instant('confirm.deleteVisit');
|
|
220
|
+
// eslint-disable-next-line no-alert
|
|
221
|
+
if (window.confirm(message) || !needPermission) {
|
|
222
|
+
console.log(this.visitIndexDetails);
|
|
223
|
+
this.isProcessing = true;
|
|
224
|
+
await this.visitService.deleteVisit(visit, this.spaceId);
|
|
225
|
+
await this.resetVisits();
|
|
226
|
+
this.isProcessing = false;
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
getDismissReason(reason) {
|
|
230
|
+
if (reason === ModalDismissReasons.ESC) {
|
|
231
|
+
return 'by pressing ESC';
|
|
232
|
+
}
|
|
233
|
+
if (reason === ModalDismissReasons.BACKDROP_CLICK) {
|
|
234
|
+
return 'by clicking on a backdrop';
|
|
235
|
+
}
|
|
236
|
+
return `with: ${reason}`;
|
|
237
|
+
}
|
|
238
|
+
async launchImport(model3D, surface, node, imagesOnly = false) {
|
|
239
|
+
this.modalReference = this.modalService.open(this.content, {
|
|
240
|
+
ariaLabelledBy: 'modal-basic-title',
|
|
241
|
+
});
|
|
242
|
+
this.modalReference.result.then((result) => {
|
|
243
|
+
this.closeResult = `Closed with: ${result}`;
|
|
244
|
+
console.log(this.closeResult);
|
|
245
|
+
this.cancelImport();
|
|
246
|
+
}, (error) => {
|
|
247
|
+
this.closeResult = `Dismissed ${this.getDismissReason(error)}`;
|
|
248
|
+
console.log(this.closeResult);
|
|
249
|
+
this.cancelImport();
|
|
250
|
+
});
|
|
251
|
+
try {
|
|
252
|
+
await this.matterportImportService.initSdkForModel(model3D);
|
|
253
|
+
return imagesOnly
|
|
254
|
+
? this.matterportImportService.importData(this.spaceId, surface, true, node)
|
|
255
|
+
: this.matterportImportService.importData(this.spaceId, surface, false, node);
|
|
256
|
+
}
|
|
257
|
+
catch (error) {
|
|
258
|
+
console.log(error);
|
|
259
|
+
return Promise.reject(error);
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
cancelImport() {
|
|
263
|
+
this.matterportImportService.abandon();
|
|
264
|
+
this.onCancel();
|
|
265
|
+
this.resetVisits();
|
|
266
|
+
}
|
|
267
|
+
onImport(visit) {
|
|
268
|
+
this.launchImport(visit.model3d, null, visit.node.id, true);
|
|
269
|
+
}
|
|
270
|
+
isFormError(control) {
|
|
271
|
+
return control && control.invalid && this.errorForm;
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
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 }, { token: i2.ValidatorsService }, { token: i5.TranslateService }, { token: i2.NavigatorService }, { token: i3.Router }], target: i0.ɵɵFactoryTarget.Component });
|
|
275
|
+
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 <div class=\"d-flex justify-content-between align-items-center\" (click)=\"onToggleDetail(index)\">\n {{visit.name ? visit.name : visit.model3d }}\n <lib-chevron [conditionShowing]=\"index==visitIndexDetails\"></lib-chevron>\n </div>\n <div *ngIf=\"index==visitIndexDetails\">\n <ul class=\"list-group list-group-flush\">\n <li class=\"list-group-item bg-transparent\">{{'Name' | translate}} : {{ visit.name ?\n visit.name : \"Not provided\" | translate}}</li>\n <li class=\"list-group-item bg-transparent\">{{'3D Model' | translate}} : {{ visit.model3d }}\n </li>\n <li class=\"list-group-item bg-transparent\">{{'Surface' | translate}}, m<sup>2</sup>: {{\n visit.surface ?\n visit.surface : 'Not provided' | translate}}</li>\n <li class=\"list-group-item bg-transparent\">{{'Viewer' | translate}} : {{ visit.viewer }}\n </li>\n <li class=\"list-group-item bg-transparent\">{{'Date of capture' | translate}} : {{\n visit.takenAt | timeDateString | async}}\n <li class=\"list-group-item bg-transparent\">{{'Images imported' | translate}} : {{\n visit.nmbImagesImported }}\n </li>\n </ul>\n \n <lib-loader *ngIf=\"isProcessing\"></lib-loader>\n <button type=\"button\" class=\"btn btn-outline-primary rounded-pill me-2\" (click)=\"onImport(visit)\" [disabled]=\"isProcessing\">{{'Import images' |\n translate}}</button>\n <button type=\"button\" class=\"btn btn-outline-primary rounded-pill me-2\" [disabled]=\"isProcessing\"\n (click)=\"onEdit(visit)\">{{'Edit' | translate}}</button>\n <button type=\"button\" class=\"btn btn-outline-primary rounded-pill\" [disabled]=\"isProcessing\"\n (click)=\"onDelete(visit)\">{{'Delete' | translate}}</button>\n </div>\n </li>\n </ul>\n <div *ngIf=\"visitForm\">\n <form (ngSubmit)=\"onSubmitVisit()\" [formGroup]=\"visitForm\">\n <div class=\"mb-3 row\">\n <label class=\"col-sm-2 col-form-label\">{{'Name' | translate}}</label>\n <div class=\"col-sm-10\">\n <input type=\"text\" class=\"form-control\" formControlName=\"name\">\n </div>\n </div>\n <div class=\"mb-3 row\">\n <label class=\"col-sm-2 col-form-label\">{{'Reference 3D model' | translate}} *</label>\n <div class=\"col-sm-10\">\n <input type=\"text\" class=\"form-control\" [readonly]=\"isEditing\"\n [class.is-invalid]=\"model3D.invalid && visitSubmitted\" required\n formControlName=\"model3D\">\n <div class=\"invalid-feedback\">\n <ngb-alert data-testid=\"new-location-name-invalid\" [dismissible]=\"false\" type=\"danger\" \n *ngIf=\"validatorsService.isControlError(visitForm.controls['name']) \n || isFormError(visitForm.controls['name'])\">\n {{validatorsService.getError(visitForm.controls['name']) | translate}}\n </ngb-alert>\n </div>\n <div *ngIf=\"isEditing\" class=\"text-danger\">\n {{'Cannot change 3D model reference. Please add new model.' | translate}}\n </div>\n </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 <div class=\"invalid-feedback\" *ngIf=\"errorForm\">\n <ngb-alert data-testid=\"new-location-form-invalid\" [dismissible]=\"false\" type=\"danger\">\n {{'errorForm.infoBtn' |translate}}\n \n </ngb-alert>\n </div>\n </form>\n </div>\n <div *ngIf=\"!visitForm\">\n <button class=\"btn btn-outline-primary rounded-pill\" (click)=\"onAddVisit()\">{{'Add 3D visit' |\n translate}}</button>\n </div>\n </div>\n <div id=\"viewer-frame\" style=\"width: 100%; aspect-ratio: 2/1;\"></div>\n </div>\n <ng-template #content let-modal>\n <div class=\"modal-header\">\n <h4 class=\"modal-title\" id=\"modal-basic-title\">{{'Importing Data' | translate}}</h4>\n <button type=\"button\" class=\"close\" aria-label=\"Close\" (click)=\"modal.dismiss('Cross click')\">\n <span aria-hidden=\"true\">\u00D7</span>\n </button>\n </div>\n <div class=\"modal-body\">\n {{'Please do not leave or refresh this page...' | translate}}\n <div *ngIf=\"totalImages != 0\">Imported {{imagesProcessed}} out of {{totalImages}} images.</div>\n <div class=\"d-flex justify-content-center\">\n <div class=\"spinner-border\" role=\"status\">\n <span class=\"visually-hidden\">{{'Loading' | translate}}...</span>\n </div>\n </div>\n </div>\n <div class=\"modal-footer\">\n <button type=\"button\" class=\"btn btn-outline-dark\" [disabled]=\"!canCancelImport\"\n (click)=\"modal.close('Cancel click')\">{{'Cancel import of images' | translate}}</button>\n </div>\n </ng-template>\n</div>", styles: [".col-form-label{width:180px;margin-bottom:1rem}.btn-outline-primary{width:200px;margin-right:1rem}.input-group{width:83%;height:-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: i6.TabNavigationComponent, selector: "lib-tab-navigation", inputs: ["menuItems"], outputs: ["onGoBack"] }, { type: i7.ChevronComponent, selector: "lib-chevron", inputs: ["conditionShowing"] }, { type: i2.LoaderComponent, selector: "lib-loader", inputs: ["useLogo", "color"] }, { type: i4.NgbAlert, selector: "ngb-alert", inputs: ["animation", "dismissible", "type"], outputs: ["closed"], exportAs: ["ngbAlert"] }], directives: [{ type: i8.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i8.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": i5.TranslatePipe, "async": i8.AsyncPipe, "timeDateString": i2.TimeDateToLocalStringPipe } });
|
|
276
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.7", ngImport: i0, type: VisitsComponent, decorators: [{
|
|
277
|
+
type: Component,
|
|
278
|
+
args: [{ selector: 'lib-visits', template: "<div class=\"container-fluid\" class=\"dashboard-tab\">\n <div class=\"m-3\">\n <lib-tab-navigation [menuItems]='menuItems' (onGoBack)=\"onGoBack()\"></lib-tab-navigation>\n </div>\n\n <div class=\"row main-form-container\">\n <div class=\"col-md-6 form-container\">\n <ul class=\"list-group list-group-flush\" *ngIf=\"!visitForm\">\n <li class=\"list-group-item list-group-item-action\" *ngFor=\"let visit of visits; index as index\">\n <div class=\"d-flex justify-content-between align-items-center\" (click)=\"onToggleDetail(index)\">\n {{visit.name ? visit.name : visit.model3d }}\n <lib-chevron [conditionShowing]=\"index==visitIndexDetails\"></lib-chevron>\n </div>\n <div *ngIf=\"index==visitIndexDetails\">\n <ul class=\"list-group list-group-flush\">\n <li class=\"list-group-item bg-transparent\">{{'Name' | translate}} : {{ visit.name ?\n visit.name : \"Not provided\" | translate}}</li>\n <li class=\"list-group-item bg-transparent\">{{'3D Model' | translate}} : {{ visit.model3d }}\n </li>\n <li class=\"list-group-item bg-transparent\">{{'Surface' | translate}}, m<sup>2</sup>: {{\n visit.surface ?\n visit.surface : 'Not provided' | translate}}</li>\n <li class=\"list-group-item bg-transparent\">{{'Viewer' | translate}} : {{ visit.viewer }}\n </li>\n <li class=\"list-group-item bg-transparent\">{{'Date of capture' | translate}} : {{\n visit.takenAt | timeDateString | async}}\n <li class=\"list-group-item bg-transparent\">{{'Images imported' | translate}} : {{\n visit.nmbImagesImported }}\n </li>\n </ul>\n \n <lib-loader *ngIf=\"isProcessing\"></lib-loader>\n <button type=\"button\" class=\"btn btn-outline-primary rounded-pill me-2\" (click)=\"onImport(visit)\" [disabled]=\"isProcessing\">{{'Import images' |\n translate}}</button>\n <button type=\"button\" class=\"btn btn-outline-primary rounded-pill me-2\" [disabled]=\"isProcessing\"\n (click)=\"onEdit(visit)\">{{'Edit' | translate}}</button>\n <button type=\"button\" class=\"btn btn-outline-primary rounded-pill\" [disabled]=\"isProcessing\"\n (click)=\"onDelete(visit)\">{{'Delete' | translate}}</button>\n </div>\n </li>\n </ul>\n <div *ngIf=\"visitForm\">\n <form (ngSubmit)=\"onSubmitVisit()\" [formGroup]=\"visitForm\">\n <div class=\"mb-3 row\">\n <label class=\"col-sm-2 col-form-label\">{{'Name' | translate}}</label>\n <div class=\"col-sm-10\">\n <input type=\"text\" class=\"form-control\" formControlName=\"name\">\n </div>\n </div>\n <div class=\"mb-3 row\">\n <label class=\"col-sm-2 col-form-label\">{{'Reference 3D model' | translate}} *</label>\n <div class=\"col-sm-10\">\n <input type=\"text\" class=\"form-control\" [readonly]=\"isEditing\"\n [class.is-invalid]=\"model3D.invalid && visitSubmitted\" required\n formControlName=\"model3D\">\n <div class=\"invalid-feedback\">\n <ngb-alert data-testid=\"new-location-name-invalid\" [dismissible]=\"false\" type=\"danger\" \n *ngIf=\"validatorsService.isControlError(visitForm.controls['name']) \n || isFormError(visitForm.controls['name'])\">\n {{validatorsService.getError(visitForm.controls['name']) | translate}}\n </ngb-alert>\n </div>\n <div *ngIf=\"isEditing\" class=\"text-danger\">\n {{'Cannot change 3D model reference. Please add new model.' | translate}}\n </div>\n </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 <div class=\"invalid-feedback\" *ngIf=\"errorForm\">\n <ngb-alert data-testid=\"new-location-form-invalid\" [dismissible]=\"false\" type=\"danger\">\n {{'errorForm.infoBtn' |translate}}\n \n </ngb-alert>\n </div>\n </form>\n </div>\n <div *ngIf=\"!visitForm\">\n <button class=\"btn btn-outline-primary rounded-pill\" (click)=\"onAddVisit()\">{{'Add 3D visit' |\n translate}}</button>\n </div>\n </div>\n <div id=\"viewer-frame\" style=\"width: 100%; aspect-ratio: 2/1;\"></div>\n </div>\n <ng-template #content let-modal>\n <div class=\"modal-header\">\n <h4 class=\"modal-title\" id=\"modal-basic-title\">{{'Importing Data' | translate}}</h4>\n <button type=\"button\" class=\"close\" aria-label=\"Close\" (click)=\"modal.dismiss('Cross click')\">\n <span aria-hidden=\"true\">\u00D7</span>\n </button>\n </div>\n <div class=\"modal-body\">\n {{'Please do not leave or refresh this page...' | translate}}\n <div *ngIf=\"totalImages != 0\">Imported {{imagesProcessed}} out of {{totalImages}} images.</div>\n <div class=\"d-flex justify-content-center\">\n <div class=\"spinner-border\" role=\"status\">\n <span class=\"visually-hidden\">{{'Loading' | translate}}...</span>\n </div>\n </div>\n </div>\n <div class=\"modal-footer\">\n <button type=\"button\" class=\"btn btn-outline-dark\" [disabled]=\"!canCancelImport\"\n (click)=\"modal.close('Cancel click')\">{{'Cancel import of images' | translate}}</button>\n </div>\n </ng-template>\n</div>", styles: [".col-form-label{width:180px;margin-bottom:1rem}.btn-outline-primary{width:200px;margin-right:1rem}.input-group{width:83%;height:-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"] }]
|
|
279
|
+
}], 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 }, { type: i2.ValidatorsService }, { type: i5.TranslateService }, { type: i2.NavigatorService }, { type: i3.Router }]; }, propDecorators: { content: [{
|
|
280
|
+
type: ViewChild,
|
|
281
|
+
args: ['content', { static: false }]
|
|
282
|
+
}] } });
|
|
283
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmlzaXRzLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL25neC1zbWFydGVycGxhbi1sb2NhdGlvbnMvc3JjL2xpYi9jb21wb25lbnRzL3Zpc2l0cy92aXNpdHMuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvbmd4LXNtYXJ0ZXJwbGFuLWxvY2F0aW9ucy9zcmMvbGliL2NvbXBvbmVudHMvdmlzaXRzL3Zpc2l0cy5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsU0FBUyxFQUFVLFNBQVMsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUM3RCxPQUFPLEVBR0gsVUFBVSxHQUViLE1BQU0sZ0JBQWdCLENBQUM7QUFFeEIsT0FBTyxFQUFZLG1CQUFtQixFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFDM0UsT0FBTyxFQVNILGFBQWEsR0FJaEIsTUFBTSxtQ0FBbUMsQ0FBQztBQUUzQyxPQUFPLEVBQUUsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLE1BQU0sQ0FBQzs7Ozs7Ozs7OztBQU8xQyxNQUFNLE9BQU8sZUFBZTtJQXFDeEIsWUFDWSxFQUFlLEVBQ2YsdUJBQWdELEVBQ2hELGNBQThCLEVBQzlCLFdBQXdCLEVBQ3hCLFlBQTBCLEVBQzFCLEtBQXFCLEVBQ3JCLFlBQXNCLEVBQ3RCLFlBQTBCLEVBQzNCLGlCQUFvQyxFQUNuQyxTQUEyQixFQUMzQixnQkFBa0MsRUFDbEMsTUFBYztRQVhkLE9BQUUsR0FBRixFQUFFLENBQWE7UUFDZiw0QkFBdUIsR0FBdkIsdUJBQXVCLENBQXlCO1FBQ2hELG1CQUFjLEdBQWQsY0FBYyxDQUFnQjtRQUM5QixnQkFBVyxHQUFYLFdBQVcsQ0FBYTtRQUN4QixpQkFBWSxHQUFaLFlBQVksQ0FBYztRQUMxQixVQUFLLEdBQUwsS0FBSyxDQUFnQjtRQUNyQixpQkFBWSxHQUFaLFlBQVksQ0FBVTtRQUN0QixpQkFBWSxHQUFaLFlBQVksQ0FBYztRQUMzQixzQkFBaUIsR0FBakIsaUJBQWlCLENBQW1CO1FBQ25DLGNBQVMsR0FBVCxTQUFTLENBQWtCO1FBQzNCLHFCQUFnQixHQUFoQixnQkFBZ0IsQ0FBa0I7UUFDbEMsV0FBTSxHQUFOLE1BQU0sQ0FBUTtRQTlDMUIsc0JBQWlCLEdBQUcsQ0FBQyxDQUFDLENBQUM7UUFJdkIsY0FBUyxHQUFZLEtBQUssQ0FBQztRQUUzQixtQkFBYyxHQUFZLEtBQUssQ0FBQztRQUloQyxpQkFBWSxHQUFHLEVBQUUsS0FBSyxFQUFFLEVBQUUsRUFBUyxDQUFDO1FBRXBDLFdBQU0sR0FBWSxFQUFFLENBQUM7UUFRckIsb0JBQWUsR0FBRyxLQUFLLENBQUM7UUFFeEIsb0JBQWUsR0FBVyxDQUFDLENBQUM7UUFFNUIsZ0JBQVcsR0FBVyxDQUFDLENBQUM7UUFFeEIsY0FBUyxHQUFlLEVBQUUsQ0FBQztRQUUzQixjQUFTLEdBQVksS0FBSyxDQUFDO1FBRTNCLGlCQUFZLEdBQUcsS0FBSyxDQUFDO1FBRXJCLGFBQVEsR0FBRyxJQUFJLE9BQU8sRUFBRSxDQUFDO1FBZ0JyQixJQUFJLENBQUMsdUJBQXVCLENBQUMsZUFBZSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDLEdBQUcsRUFBRTtZQUN2RixJQUFJLENBQUMsZUFBZSxHQUFHLElBQUksQ0FBQztRQUNoQyxDQUFDLENBQUMsQ0FBQztRQUNILElBQUksQ0FBQyx1QkFBdUIsQ0FBQyxtQkFBbUIsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxDQUFDLEtBQUssRUFBRSxFQUFFO1lBQ2hHLElBQUksQ0FBQyxlQUFlLEdBQUcsS0FBSyxHQUFHLENBQUMsQ0FBQztRQUNyQyxDQUFDLENBQUMsQ0FBQztRQUNILElBQUksQ0FBQyx1QkFBdUIsQ0FBQyxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxDQUFDLEtBQUssRUFBRSxFQUFFO1lBQzdGLElBQUksQ0FBQyxXQUFXLEdBQUcsS0FBSyxDQUFDO1FBQzdCLENBQUMsQ0FBQyxDQUFDO1FBRUgsSUFBSSxDQUFDLGdCQUFnQixDQUFDLGdCQUFnQjthQUNqQyxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQzthQUM5QixTQUFTLENBQUMsQ0FBQyxPQUFPLEVBQUUsRUFBRTtZQUNuQixJQUFJLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxDQUFDLHdCQUF3QixFQUFFLE9BQU8sRUFBRSxRQUFRLENBQUMsQ0FBQyxDQUFDO1FBQ3hFLENBQUMsQ0FBQyxDQUFDO1FBRVAsSUFBSSxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsU0FBUyxDQUFDLENBQUMsTUFBTSxFQUFFLEVBQUU7WUFDbkMsSUFBSSxDQUFDLE9BQU8sR0FBRyxNQUFNLENBQUMsRUFBRSxDQUFDO1lBQ3pCLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQztRQUN2QixDQUFDLENBQUMsQ0FBQztJQUNQLENBQUM7SUFFRCxLQUFLLENBQUMsUUFBUTtRQUNWLElBQUksQ0FBQyxPQUFPLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUN0RCxNQUFNLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQztRQUN6Qix5RUFBeUU7UUFDekUsSUFBSSxZQUFZLENBQUMsT0FBTyxDQUFDLGVBQWUsQ0FBQyxJQUFJLFlBQVksQ0FBQyxPQUFPLENBQUMsZUFBZSxDQUFDLEVBQUU7WUFDaEYsTUFBTSxhQUFhLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUFDLEtBQUssQ0FBQyxPQUFPLEtBQUssWUFBWSxDQUFDLE9BQU8sQ0FBQyxlQUFlLENBQUMsQ0FBQyxDQUFDO1lBQzNHLElBQUksYUFBYSxDQUFDLE9BQU8sS0FBSyxJQUFJLENBQUMsT0FBTyxFQUFFO2dCQUN4QyxPQUFPLENBQUMsR0FBRyxDQUFDLGlCQUFpQixDQUFDLENBQUM7Z0JBQy9CLElBQUksQ0FBQyxlQUFlLEdBQUcsUUFBUSxDQUFDLFlBQVksQ0FBQyxPQUFPLENBQUMsZUFBZSxDQUFDLENBQUMsQ0FBQztnQkFDdkUsSUFBSSxDQUFDLFFBQVEsQ0FBQyxhQUFhLENBQUMsQ0FBQzthQUNoQztTQUNKO0lBQ0wsQ0FBQztJQUVELFdBQVc7UUFDUCxJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUN6QixJQUFJLENBQUMsUUFBUSxDQUFDLFFBQVEsRUFBRSxDQUFDO0lBQzdCLENBQUM7SUFFRDs7Ozs7Ozs7Ozs7TUFXRTtJQUNGLGNBQWM7UUFDVixJQUFJLENBQUMsU0FBUyxHQUFHO1lBQ2IsRUFBRSxLQUFLLEVBQUUsV0FBVyxFQUFFLEdBQUcsRUFBRSxlQUFlLEVBQUU7WUFDNUM7Z0JBQ0ksS0FBSyxFQUFFLElBQUksQ0FBQyxZQUFZLENBQUMsSUFBSTtnQkFDN0IsR0FBRyxFQUFFLGlCQUFpQixJQUFJLENBQUMsWUFBWSxDQUFDLEVBQUUsRUFBRTthQUMvQztZQUNEO2dCQUNJLEtBQUssRUFBRSxnQkFBZ0I7Z0JBQ3ZCLEdBQUcsRUFBRSxpQkFBaUIsSUFBSSxDQUFDLFlBQVksQ0FBQyxFQUFFLFNBQVM7YUFDdEQ7U0FDSixDQUFDO0lBQ04sQ0FBQztJQUVELFFBQVE7UUFDSixJQUFJLENBQUMsUUFBUSxFQUFFLENBQUM7SUFDcEIsQ0FBQztJQUVELEtBQUssQ0FBQyxXQUFXO1FBQ2IsSUFBSSxDQUFDLE1BQU0sR0FBRyxFQUFFLENBQUM7UUFDakIsSUFBSSxDQUFDLFlBQVksR0FBRyxNQUFNLElBQUksQ0FBQyxZQUFZLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUNuRSxJQUFJLENBQUMsY0FBYyxFQUFFLENBQUM7UUFDdEIsTUFBTSxJQUFJLENBQUMsWUFBWTthQUNsQix3QkFBd0IsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDO2FBQ3RDLElBQUksQ0FBQyxDQUFDLE1BQU0sRUFBRSxFQUFFO1lBQ2IsSUFBSSxNQUFNLEVBQUU7Z0JBQ1IsSUFBSSxDQUFDLE1BQU0sR0FBRyxNQUFNLENBQUM7YUFDeEI7UUFDTCxDQUFDLENBQUMsQ0FBQztJQUNYLENBQUM7SUFFRCxhQUFhLENBQUMsUUFBZSxJQUFJO1FBQzdCLElBQUksS0FBSyxFQUFFO1lBQ1AsSUFBSSxDQUFDLFNBQVMsR0FBRyxJQUFJLENBQUMsRUFBRSxDQUFDLEtBQUssQ0FBQztnQkFDM0IsU0FBUyxFQUFFLEtBQUssQ0FBQyxTQUFTO2dCQUMxQixNQUFNLEVBQUUsS0FBSyxDQUFDLElBQUksQ0FBQyxFQUFFO2dCQUNyQixJQUFJLEVBQUUsQ0FBQyxLQUFLLENBQUMsSUFBSSxFQUFFLENBQUMsVUFBVSxDQUFDLFFBQVEsQ0FBQyxDQUFDO2dCQUN6QyxPQUFPLEVBQUUsQ0FBQyxLQUFLLENBQUMsT0FBTyxFQUFFLENBQUMsVUFBVSxDQUFDLFFBQVEsQ0FBQyxDQUFDO2dCQUMvQyxNQUFNLEVBQUUsS0FBSyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsYUFBYSxDQUFDLFVBQVU7Z0JBQzlELE9BQU8sRUFBRSxLQUFLLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxJQUFJO2FBQ2hELENBQUMsQ0FBQztZQUNILElBQUksQ0FBQyxXQUFXLEdBQUcsS0FBSyxDQUFDLE9BQU8sQ0FBQztTQUNwQzthQUFNO1lBQ0gsSUFBSSxDQUFDLFNBQVMsR0FBRyxJQUFJLENBQUMsRUFBRSxDQUFDLEtBQUssQ0FBQztnQkFDM0IsT0FBTyxFQUFFLENBQUMsSUFBSSxFQUFFLENBQUMsVUFBVSxDQUFDLFFBQVEsQ0FBQyxDQUFDO2dCQUN0QyxNQUFNLEVBQUUsYUFBYSxDQUFDLFVBQVU7Z0JBQ2hDLE9BQU8sRUFBRSxJQUFJO2dCQUNiLElBQUksRUFBRSxDQUFDLElBQUksRUFBRSxDQUFDLFVBQVUsQ0FBQyxRQUFRLENBQUMsQ0FBQzthQUN0QyxDQUFDLENBQUM7U0FDTjtJQUNMLENBQUM7SUFFRCxjQUFjLENBQUMsS0FBSztRQUNoQixJQUFJLENBQUMsaUJBQWlCLEdBQUcsS0FBSyxLQUFLLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQztJQUMzRSxDQUFDO0lBRUQsVUFBVTtRQUNOLElBQUksQ0FBQyxhQUFhLEVBQUUsQ0FBQztRQUNyQixJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsQ0FBQyxDQUFDO0lBQzFDLENBQUM7SUFFRCxNQUFNLENBQUMsS0FBSztRQUNSLElBQUksQ0FBQyxhQUFhLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDMUIsSUFBSSxDQUFDLFNBQVMsR0FBRyxJQUFJLENBQUM7UUFDdEIsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsRUFBRSxLQUFLLEVBQUUsS0FBSyxDQUFDLElBQUksRUFBRSxDQUFDLENBQUM7SUFDL0MsQ0FBQztJQUVELEtBQUssQ0FBQyxhQUFhO1FBQ2YsSUFBSSxDQUFDLGNBQWMsR0FBRyxJQUFJLENBQUM7UUFDM0IsSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsS0FBSyxFQUFFO1lBQ3ZCLElBQUksQ0FBQyxTQUFTLEdBQUcsSUFBSSxDQUFDO1lBQ3RCLE9BQU87U0FDVjtRQUNELElBQUksQ0FBQyxTQUFTLEdBQUcsS0FBSyxDQUFDO1FBQ3ZCLE1BQU0sU0FBUyxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDO1FBQ3ZDLE1BQU0sT0FBTyxHQUFHO1lBQ1osTUFBTSxFQUFFLFNBQVMsQ0FBQyxNQUFNO1lBQ3hCLE9BQU8sRUFBRSxJQUFJLENBQUMsV0FBVztZQUN6QixPQUFPLEVBQUUsU0FBUyxDQUFDLE9BQU87WUFDMUIsT0FBTyxFQUFFLElBQUksQ0FBQyxZQUFZLENBQUMsRUFBRTtTQUNyQixDQUFDO1FBRWIsSUFBSSxJQUFJLENBQUMsU0FBUyxFQUFFO1lBQ2hCLE9BQU8sQ0FBQyxFQUFFLEdBQUcsU0FBUyxDQUFDLFNBQVMsQ0FBQztZQUNqQyxNQUFNLElBQUksQ0FBQyxjQUFjLENBQUMsYUFBYSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1lBQ2pELE1BQU0sSUFBSSxHQUFHO2dCQUNULEVBQUUsRUFBRSxTQUFTLENBQUMsTUFBTTtnQkFDcEIsT0FBTyxFQUFFLFNBQVMsQ0FBQyxPQUFPO2dCQUMxQixRQUFRLEVBQUUsU0FBUyxDQUFDLElBQUk7YUFDbkIsQ0FBQztZQUNWLE1BQU0sSUFBSSxDQUFDLFdBQVcsQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLENBQUM7U0FDM0M7YUFBTTtZQUNILElBQUksV0FBVyxDQUFDO1lBQ2hCLE1BQU0sSUFBSSxDQUFDLGNBQWMsQ0FBQyxhQUFhLENBQUMsT0FBTyxDQUFDLENBQUMsSUFBSSxDQUFDLEtBQUssRUFBRSxHQUFHLEVBQUUsRUFBRTtnQkFDaEUsSUFBSSxHQUFHLEVBQUU7b0JBQ0wsTUFBTSxJQUFJLEdBQUc7d0JBQ1QsT0FBTyxFQUFFLFNBQVMsQ0FBQyxPQUFPO3dCQUMxQixTQUFTLEVBQUUsR0FBRyxDQUFDLEVBQUU7d0JBQ2pCLFFBQVEsRUFBRSxTQUFTLENBQUMsSUFBSTtxQkFDbkIsQ0FBQztvQkFDVixXQUFXLEdBQUcsTUFBTSxJQUFJLENBQUMsV0FBVyxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsQ0FBQztpQkFDekQ7WUFDTCxDQUFDLENBQUMsQ0FBQztZQUNILElBQUksQ0FBQyxZQUFZLENBQ2IsU0FBUyxDQUFDLE9BQU8sRUFDakIsU0FBUyxDQUFDLE9BQU8sRUFDakIsV0FBVyxFQUNYLEtBQUssQ0FDUjtpQkFDSSxJQUFJLENBQUMsQ0FBQyxPQUFPLEVBQUUsRUFBRTtnQkFDZCxJQUFJLENBQUMsY0FBYyxDQUFDLEtBQUssQ0FBQywyQkFBMkIsQ0FBQyxDQUFDO1lBQzNELENBQUMsQ0FBQztpQkFDRCxLQUFLLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRTtnQkFDVCxJQUFJLENBQUMsY0FBYyxDQUFDLEtBQUssQ0FBQyx1QkFBdUIsQ0FBQyxFQUFFLENBQUMsQ0FBQztnQkFDdEQsS0FBSyxDQUFDLHVCQUF1QixDQUFDLElBQUksSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUM7Z0JBQ3ZELElBQUksQ0FBQyxRQUFRLENBQUM7b0JBQ1YsSUFBSSxFQUFFLFdBQVc7b0JBQ2pCLFNBQVMsRUFBRSxXQUFXLENBQUMsU0FBUztpQkFDMUIsRUFBRSxLQUFLLENBQUMsQ0FBQztZQUN2QixDQUFDLENBQUMsQ0FBQztTQUNWO1FBQ0QsTUFBTSxJQUFJLENBQUMsV0FBVyxFQUFFLENBQUM7UUFDekIsSUFBSSxDQUFDLFFBQVEsRUFBRSxDQUFDO0lBQ3BCLENBQUM7SUFFRCxJQUFJLE9BQU87UUFDUCxPQUFPLElBQUksQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLFNBQVMsQ0FBQyxDQUFDO0lBQ3pDLENBQUM7SUFFRCxJQUFJLElBQUk7UUFDSixPQUFPLElBQUksQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxDQUFDO0lBQ3RDLENBQUM7SUFFRCxRQUFRO1FBQ0osSUFBSSxDQUFDLGNBQWMsR0FBRyxLQUFLLENBQUM7UUFDNUIsSUFBSSxDQUFDLFNBQVMsR0FBRyxJQUFJLENBQUM7UUFDdEIsSUFBSSxDQUFDLFNBQVMsR0FBRyxLQUFLLENBQUM7UUFDdkIsSUFBSSxDQUFDLGVBQWUsR0FBRyxLQUFLLENBQUM7UUFDN0IsSUFBSSxDQUFDLFdBQVcsR0FBRyxDQUFDLENBQUM7UUFDckIsSUFBSSxDQUFDLGVBQWUsR0FBRyxDQUFDLENBQUM7UUFDekIsSUFBSSxDQUFDLFNBQVMsR0FBRyxLQUFLLENBQUM7UUFDdkIsSUFBSSxDQUFDLGNBQWMsRUFBRSxDQUFDO0lBQzFCLENBQUM7SUFFRCxLQUFLLENBQUMsUUFBUSxDQUFDLEtBQVksRUFBRSxjQUFjLEdBQUcsSUFBSTtRQUM5QyxNQUFNLE9BQU8sR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLE9BQU8sQ0FBQyxxQkFBcUIsQ0FBQyxDQUFDO1FBQzlELG9DQUFvQztRQUNwQyxJQUFJLE1BQU0sQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxjQUFjLEVBQUU7WUFDNUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsaUJBQWlCLENBQUMsQ0FBQztZQUNwQyxJQUFJLENBQUMsWUFBWSxHQUFHLElBQUksQ0FBQztZQUN6QixNQUFNLElBQUksQ0FBQyxZQUFZLENBQUMsV0FBVyxDQUFDLEtBQUssRUFBRSxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUM7WUFDekQsTUFBTSxJQUFJLENBQUMsV0FBVyxFQUFFLENBQUM7WUFDekIsSUFBSSxDQUFDLFlBQVksR0FBRyxLQUFLLENBQUM7U0FDN0I7SUFDTCxDQUFDO0lBRU8sZ0JBQWdCLENBQUMsTUFBVztRQUNoQyxJQUFJLE1BQU0sS0FBSyxtQkFBbUIsQ0FBQyxHQUFHLEVBQUU7WUFDcEMsT0FBTyxpQkFBaUIsQ0FBQztTQUM1QjtRQUNELElBQUksTUFBTSxLQUFLLG1CQUFtQixDQUFDLGNBQWMsRUFBRTtZQUMvQyxPQUFPLDJCQUEyQixDQUFDO1NBQ3RDO1FBQ0QsT0FBTyxTQUFTLE1BQU0sRUFBRSxDQUFDO0lBQzdCLENBQUM7SUFFRCxLQUFLLENBQUMsWUFBWSxDQUNkLE9BQU8sRUFDUCxPQUFPLEVBQ1AsSUFBSSxFQUNKLFVBQVUsR0FBRyxLQUFLO1FBRWxCLElBQUksQ0FBQyxjQUFjLEdBQUcsSUFBSSxDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRTtZQUN2RCxjQUFjLEVBQUUsbUJBQW1CO1NBQ3RDLENBQUMsQ0FBQztRQUNILElBQUksQ0FBQyxjQUFjLENBQUMsTUFBTSxDQUFDLElBQUksQ0FDM0IsQ0FBQyxNQUFNLEVBQUUsRUFBRTtZQUNQLElBQUksQ0FBQyxXQUFXLEdBQUcsZ0JBQWdCLE1BQU0sRUFBRSxDQUFDO1lBQzVDLE9BQU8sQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxDQUFDO1lBQzlCLElBQUksQ0FBQyxZQUFZLEVBQUUsQ0FBQztRQUN4QixDQUFDLEVBQ0QsQ0FBQyxLQUFLLEVBQUUsRUFBRTtZQUNOLElBQUksQ0FBQyxXQUFXLEdBQUcsYUFBYSxJQUFJLENBQUMsZ0JBQWdCLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQztZQUMvRCxPQUFPLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsQ0FBQztZQUM5QixJQUFJLENBQUMsWUFBWSxFQUFFLENBQUM7UUFDeEIsQ0FBQyxDQUNKLENBQUM7UUFDRixJQUFJO1lBQ0EsTUFBTSxJQUFJLENBQUMsdUJBQXVCLENBQUMsZUFBZSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1lBQzVELE9BQU8sVUFBVTtnQkFDYixDQUFDLENBQUMsSUFBSSxDQUFDLHVCQUF1QixDQUFDLFVBQVUsQ0FDckMsSUFBSSxDQUFDLE9BQU8sRUFDWixPQUFPLEVBQ1AsSUFBSSxFQUNKLElBQUksQ0FDUDtnQkFDRCxDQUFDLENBQUMsSUFBSSxDQUFDLHVCQUF1QixDQUFDLFVBQVUsQ0FDckMsSUFBSSxDQUFDLE9BQU8sRUFDWixPQUFPLEVBQ1AsS0FBSyxFQUNMLElBQUksQ0FDUCxDQUFDO1NBQ1Q7UUFBQyxPQUFPLEtBQUssRUFBRTtZQUNaLE9BQU8sQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLENBQUM7WUFDbkIsT0FBTyxPQUFPLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDO1NBQ2hDO0lBQ0wsQ0FBQztJQUVPLFlBQVk7UUFDaEIsSUFBSSxDQUFDLHVCQUF1QixDQUFDLE9BQU8sRUFBRSxDQUFDO1FBQ3ZDLElBQUksQ0FBQyxRQUFRLEVBQUUsQ0FBQztRQUNoQixJQUFJLENBQUMsV0FBVyxFQUFFLENBQUM7SUFDdkIsQ0FBQztJQUVELFFBQVEsQ0FBQyxLQUFZO1FBQ2pCLElBQUksQ0FBQyxZQUFZLENBQUMsS0FBSyxDQUFDLE9BQU8sRUFBRSxJQUFJLEVBQUUsS0FBSyxDQUFDLElBQUksQ0FBQyxFQUFFLEVBQUUsSUFBSSxDQUFDLENBQUM7SUFDaEUsQ0FBQztJQUVELFdBQVcsQ0FBQyxPQUFPO1FBQ2YsT0FBTyxPQUFPLElBQUksT0FBTyxDQUFDLE9BQU8sSUFBSSxJQUFJLENBQUMsU0FBUyxDQUFDO0lBQ3hELENBQUM7OzRHQXBVUSxlQUFlO2dHQUFmLGVBQWUsc0pDL0I1Qiwwd1FBcUlNOzJGRHRHTyxlQUFlO2tCQUwzQixTQUFTOytCQUNJLFlBQVk7NFpBdUIyQixPQUFPO3NCQUF2RCxTQUFTO3VCQUFDLFNBQVMsRUFBRSxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQUUiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb21wb25lbnQsIE9uSW5pdCwgVmlld0NoaWxkIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQge1xuICAgIEZvcm1Hcm91cCxcbiAgICBGb3JtQnVpbGRlcixcbiAgICBWYWxpZGF0b3JzLFxuICAgIEFic3RyYWN0Q29udHJvbCxcbn0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xuaW1wb3J0IHsgQWN0aXZhdGVkUm91dGUsIFJvdXRlciB9IGZyb20gJ0Bhbmd1bGFyL3JvdXRlcic7XG5pbXBvcnQgeyBOZ2JNb2RhbCwgTW9kYWxEaXNtaXNzUmVhc29ucyB9IGZyb20gJ0BuZy1ib290c3RyYXAvbmctYm9vdHN0cmFwJztcbmltcG9ydCB7XG4gICAgTm9kZSxcbiAgICBWaXNpdCxcbiAgICBNZW51SXRlbSxcbiAgICBNYXR0ZXJwb3J0SW1wb3J0U2VydmljZSxcbiAgICBDYXB0dXJlU2VydmljZSxcbiAgICBOb2RlU2VydmljZSxcbiAgICBTcGFjZVNlcnZpY2UsXG4gICAgVmlzaXRTZXJ2aWNlLFxuICAgIENhcHR1cmVWaWV3ZXIsXG4gICAgQ2FwdHVyZSxcbiAgICBWYWxpZGF0b3JzU2VydmljZSxcbiAgICBOYXZpZ2F0b3JTZXJ2aWNlLFxufSBmcm9tICdAc21hcnRlcnBsYW4vbmd4LXNtYXJ0ZXJwbGFuLWNvcmUnO1xuaW1wb3J0IHsgVHJhbnNsYXRlU2VydmljZSB9IGZyb20gJ0BuZ3gtdHJhbnNsYXRlL2NvcmUnO1xuaW1wb3J0IHsgU3ViamVjdCwgdGFrZVVudGlsIH0gZnJvbSAncnhqcyc7XG5cbkBDb21wb25lbnQoe1xuICAgIHNlbGVjdG9yOiAnbGliLXZpc2l0cycsXG4gICAgdGVtcGxhdGVVcmw6ICcuL3Zpc2l0cy5jb21wb25lbnQuaHRtbCcsXG4gICAgc3R5bGVVcmxzOiBbJy4vdmlzaXRzLmNvbXBvbmVudC5zY3NzJ10sXG59KVxuZXhwb3J0IGNsYXNzIFZpc2l0c0NvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCB7XG4gICAgc3BhY2VJZDogc3RyaW5nO1xuXG4gICAgdmlzaXRJbmRleERldGFpbHMgPSAtMTtcblxuICAgIHZpc2l0Rm9ybTogRm9ybUdyb3VwO1xuXG4gICAgaXNFZGl0aW5nOiBib29sZWFuID0gZmFsc2U7XG5cbiAgICB2aXNpdFN1Ym1pdHRlZDogYm9vbGVhbiA9IGZhbHNlO1xuXG4gICAgY2FwdHVyZURhdGU6IG51bWJlcjtcblxuICAgIGN1cnJlbnRTcGFjZSA9IHsgem9uZXM6IFtdIH0gYXMgYW55O1xuXG4gICAgdmlzaXRzOiBWaXNpdFtdID0gW107XG5cbiAgICBjbG9zZVJlc3VsdDogc3RyaW5nO1xuXG4gICAgQFZpZXdDaGlsZCgnY29udGVudCcsIHsgc3RhdGljOiBmYWxzZSB9KSBwcml2YXRlIGNvbnRlbnQ7XG5cbiAgICBtb2RhbFJlZmVyZW5jZTogYW55O1xuXG4gICAgY2FuQ2FuY2VsSW1wb3J0ID0gZmFsc2U7XG5cbiAgICBpbWFnZXNQcm9jZXNzZWQ6IG51bWJlciA9IDA7XG5cbiAgICB0b3RhbEltYWdlczogbnVtYmVyID0gMDtcblxuICAgIG1lbnVJdGVtczogTWVudUl0ZW1bXSA9IFtdO1xuXG4gICAgZXJyb3JGb3JtOiBib29sZWFuID0gZmFsc2U7XG5cbiAgICBpc1Byb2Nlc3NpbmcgPSBmYWxzZTtcblxuICAgIGRlc3Ryb3kkID0gbmV3IFN1YmplY3QoKTtcblxuICAgIGNvbnN0cnVjdG9yKFxuICAgICAgICBwcml2YXRlIGZiOiBGb3JtQnVpbGRlcixcbiAgICAgICAgcHJpdmF0ZSBtYXR0ZXJwb3J0SW1wb3J0U2VydmljZTogTWF0dGVycG9ydEltcG9ydFNlcnZpY2UsXG4gICAgICAgIHByaXZhdGUgY2FwdHVyZVNlcnZpY2U6IENhcHR1cmVTZXJ2aWNlLFxuICAgICAgICBwcml2YXRlIG5vZGVTZXJ2aWNlOiBOb2RlU2VydmljZSxcbiAgICAgICAgcHJpdmF0ZSBzcGFjZVNlcnZpY2U6IFNwYWNlU2VydmljZSxcbiAgICAgICAgcHJpdmF0ZSByb3V0ZTogQWN0aXZhdGVkUm91dGUsXG4gICAgICAgIHByaXZhdGUgbW9kYWxTZXJ2aWNlOiBOZ2JNb2RhbCxcbiAgICAgICAgcHJpdmF0ZSB2aXNpdFNlcnZpY2U6IFZpc2l0U2VydmljZSxcbiAgICAgICAgcHVibGljIHZhbGlkYXRvcnNTZXJ2aWNlOiBWYWxpZGF0b3JzU2VydmljZSxcbiAgICAgICAgcHJpdmF0ZSB0cmFuc2xhdGU6IFRyYW5zbGF0ZVNlcnZpY2UsXG4gICAgICAgIHByaXZhdGUgbmF2aWdhdG9yU2VydmljZTogTmF2aWdhdG9yU2VydmljZSxcbiAgICAgICAgcHJpdmF0ZSByb3V0ZXI6IFJvdXRlcixcbiAgICApIHtcbiAgICAgICAgdGhpcy5tYXR0ZXJwb3J0SW1wb3J0U2VydmljZS5pbXBvcnRpbmdJbWFnZXMucGlwZSh0YWtlVW50aWwodGhpcy5kZXN0cm95JCkpLnN1YnNjcmliZSgoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLmNhbkNhbmNlbEltcG9ydCA9IHRydWU7XG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLm1hdHRlcnBvcnRJbXBvcnRTZXJ2aWNlLnN3ZWVwUHJvY2Vzc2VkQ291bnQucGlwZSh0YWtlVW50aWwodGhpcy5kZXN0cm95JCkpLnN1YnNjcmliZSgoY291bnQpID0+IHtcbiAgICAgICAgICAgIHRoaXMuaW1hZ2VzUHJvY2Vzc2VkID0gY291bnQgKyAxO1xuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5tYXR0ZXJwb3J0SW1wb3J0U2VydmljZS50b3RhbFN3ZWVwc0NvdW50LnBpcGUodGFrZVVudGlsKHRoaXMuZGVzdHJveSQpKS5zdWJzY3JpYmUoKGNvdW50KSA9PiB7XG4gICAgICAgICAgICB0aGlzLnRvdGFsSW1hZ2VzID0gY291bnQ7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIHRoaXMubmF2aWdhdG9yU2VydmljZS5sb2NhdGlvbklEQ2hhbmdlXG4gICAgICAgICAgICAucGlwZSh0YWtlVW50aWwodGhpcy5kZXN0cm95JCkpXG4gICAgICAgICAgICAuc3Vic2NyaWJlKChzcGFjZUlEKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5yb3V0ZXIubmF2aWdhdGUoW1wiZGFzaGJvYXJkL2xvY2FsaXNhdGlvblwiLCBzcGFjZUlELCBcInZpc2l0c1wiXSk7XG4gICAgICAgICAgICB9KTtcblxuICAgICAgICB0aGlzLnJvdXRlLnBhcmFtcy5zdWJzY3JpYmUoKHBhcmFtcykgPT4ge1xuICAgICAgICAgICAgdGhpcy5zcGFjZUlkID0gcGFyYW1zLmlkO1xuICAgICAgICAgICAgdGhpcy5yZXNldFZpc2l0cygpO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBhc3luYyBuZ09uSW5pdCgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgdGhpcy5zcGFjZUlkID0gdGhpcy5yb3V0ZS5zbmFwc2hvdC5wYXJhbU1hcC5nZXQoJ2lkJyk7XG4gICAgICAgIGF3YWl0IHRoaXMucmVzZXRWaXNpdHMoKTtcbiAgICAgICAgLy8gY29uc29sZS5sb2coJ3Zpc2l0IGluIGltcG9ydCcsIGxvY2FsU3RvcmFnZS5nZXRJdGVtKFwidmlzaXRJbkltcG9ydFwiKSk7XG4gICAgICAgIGlmIChsb2NhbFN0b3JhZ2UuZ2V0SXRlbShcInZpc2l0SW5JbXBvcnRcIikgJiYgbG9jYWxTdG9yYWdlLmdldEl0ZW0oXCJpbmRleFNjYW5Mb2FkXCIpKSB7XG4gICAgICAgICAgICBjb25zdCB2aXNpdFRvUmV0YWtlID0gdGhpcy52aXNpdHMuZmluZCgodmlzaXQpID0+IHZpc2l0Lm1vZGVsM2QgPT09IGxvY2FsU3RvcmFnZS5nZXRJdGVtKFwidmlzaXRJbkltcG9ydFwiKSk7XG4gICAgICAgICAgICBpZiAodmlzaXRUb1JldGFrZS5zcGFjZUlEID09PSB0aGlzLnNwYWNlSWQpIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmxvZyhcInJldGFraW5nIGltcG9ydFwiKTtcbiAgICAgICAgICAgICAgICB0aGlzLmltYWdlc1Byb2Nlc3NlZCA9IHBhcnNlSW50KGxvY2FsU3RvcmFnZS5nZXRJdGVtKFwiaW5kZXhTY2FuTG9hZFwiKSk7XG4gICAgICAgICAgICAgICAgdGhpcy5vbkltcG9ydCh2aXNpdFRvUmV0YWtlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIG5nT25EZXN0cm95KCkge1xuICAgICAgICB0aGlzLmRlc3Ryb3kkLm5leHQodHJ1ZSk7XG4gICAgICAgIHRoaXMuZGVzdHJveSQuY29tcGxldGUoKTtcbiAgICB9XG5cbiAgICAvKlxuICAgIFZpc2l0ID0ge1xuICAgICAgY2FwdHVyZUlEOiBzdHJpbmcsXG4gICAgICBtb2RlbDNkOiBzdHJpbmcsXG4gICAgICB0YWtlbkF0OiBudW1iZXIsXG4gICAgICBzcGFjZUlEOiBzdHJpbmcsXG4gICAgICB2aWV3ZXI6IENhcHR1cmVWaWV3ZXIsXG4gICAgICBzdXJmYWNlOiBudW1iZXIsXG4gICAgICBub2RlOiBOb2RlLFxuICAgICAgbmFtZT86IHN0cmluZyB8IG51bGxcbiAgICB9XG4gICAgKi9cbiAgICBzZXR1cE1lbnVJdGVtcygpIHtcbiAgICAgICAgdGhpcy5tZW51SXRlbXMgPSBbXG4gICAgICAgICAgICB7IGxhYmVsOiAnTG9jYXRpb25zJywgdXJsOiAnL2xvY2FsaXNhdGlvbicgfSxcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBsYWJlbDogdGhpcy5jdXJyZW50U3BhY2UubmFtZSxcbiAgICAgICAgICAgICAgICB1cmw6IGAvbG9jYWxpc2F0aW9uLyR7dGhpcy5jdXJyZW50U3BhY2UuaWR9YCxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgbGFiZWw6ICdWaXJ0dWFsIHZpc2l0cycsXG4gICAgICAgICAgICAgICAgdXJsOiBgL2xvY2FsaXNhdGlvbi8ke3RoaXMuY3VycmVudFNwYWNlLmlkfS92aXNpdHNgLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgXTtcbiAgICB9XG5cbiAgICBvbkdvQmFjaygpIHtcbiAgICAgICAgdGhpcy5vbkNhbmNlbCgpO1xuICAgIH1cblxuICAgIGFzeW5jIHJlc2V0VmlzaXRzKCkge1xuICAgICAgICB0aGlzLnZpc2l0cyA9IFtdO1xuICAgICAgICB0aGlzLmN1cnJlbnRTcGFjZSA9IGF3YWl0IHRoaXMuc3BhY2VTZXJ2aWNlLmdldFNwYWNlKHRoaXMuc3BhY2VJZCk7XG4gICAgICAgIHRoaXMuc2V0dXBNZW51SXRlbXMoKTtcbiAgICAgICAgYXdhaXQgdGhpcy52aXNpdFNlcnZpY2VcbiAgICAgICAgICAgIC5nZXRWaXNpdHNGb3JTcGFjZUZvclVzZXIodGhpcy5zcGFjZUlkKVxuICAgICAgICAgICAgLnRoZW4oKHZpc2l0cykgPT4ge1xuICAgICAgICAgICAgICAgIGlmICh2aXNpdHMpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy52aXNpdHMgPSB2aXNpdHM7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgaW5pdFZpc2l0Rm9ybShpbnB1dDogVmlzaXQgPSBudWxsKSB7XG4gICAgICAgIGlmIChpbnB1dCkge1xuICAgICAgICAgICAgdGhpcy52aXNpdEZvcm0gPSB0aGlzLmZiLmdyb3VwKHtcbiAgICAgICAgICAgICAgICBjYXB0dXJlSUQ6IGlucHV0LmNhcHR1cmVJRCxcbiAgICAgICAgICAgICAgICBub2RlSUQ6IGlucHV0Lm5vZGUuaWQsXG4gICAgICAgICAgICAgICAgbmFtZTogW2lucHV0Lm5hbWUsIFtWYWxpZGF0b3JzLnJlcXVpcmVkXV0sXG4gICAgICAgICAgICAgICAgbW9kZWwzRDogW2lucHV0Lm1vZGVsM2QsIFtWYWxpZGF0b3JzLnJlcXVpcmVkXV0sXG4gICAgICAgICAgICAgICAgdmlld2VyOiBpbnB1dC52aWV3ZXIgPyBpbnB1dC52aWV3ZXIgOiBDYXB0dXJlVmlld2VyLk1BVFRFUlBPUlQsXG4gICAgICAgICAgICAgICAgc3VyZmFjZTogaW5wdXQuc3VyZmFjZSA/IGlucHV0LnN1cmZhY2UgOiBudWxsLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB0aGlzLmNhcHR1cmVEYXRlID0gaW5wdXQudGFrZW5BdDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMudmlzaXRGb3JtID0gdGhpcy5mYi5ncm91cCh7XG4gICAgICAgICAgICAgICAgbW9kZWwzRDogW251bGwsIFtWYWxpZGF0b3JzLnJlcXVpcmVkXV0sXG4gICAgICAgICAgICAgICAgdmlld2VyOiBDYXB0dXJlVmlld2VyLk1BVFRFUlBPUlQsXG4gICAgICAgICAgICAgICAgc3VyZmFjZTogbnVsbCxcbiAgICAgICAgICAgICAgICBuYW1lOiBbbnVsbCwgW1ZhbGlkYXRvcnMucmVxdWlyZWRdXSxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgb25Ub2dnbGVEZXRhaWwoaW5kZXgpIHtcbiAgICAgICAgdGhpcy52aXNpdEluZGV4RGV0YWlscyA9IGluZGV4ID09PSB0aGlzLnZpc2l0SW5kZXhEZXRhaWxzID8gLTEgOiBpbmRleDtcbiAgICB9XG5cbiAgICBvbkFkZFZpc2l0KCkge1xuICAgICAgICB0aGlzLmluaXRWaXNpdEZvcm0oKTtcbiAgICAgICAgdGhpcy5tZW51SXRlbXMucHVzaCh7IGxhYmVsOiAnTmV3JyB9KTtcbiAgICB9XG5cbiAgICBvbkVkaXQodmlzaXQpIHtcbiAgICAgICAgdGhpcy5pbml0VmlzaXRGb3JtKHZpc2l0KTtcbiAgICAgICAgdGhpcy5pc0VkaXRpbmcgPSB0cnVlO1xuICAgICAgICB0aGlzLm1lbnVJdGVtcy5wdXNoKHsgbGFiZWw6IHZpc2l0Lm5hbWUgfSk7XG4gICAgfVxuXG4gICAgYXN5bmMgb25TdWJtaXRWaXNpdCgpIHtcbiAgICAgICAgdGhpcy52aXNpdFN1Ym1pdHRlZCA9IHRydWU7XG4gICAgICAgIGlmICghdGhpcy52aXNpdEZvcm0udmFsaWQpIHtcbiAgICAgICAgICAgIHRoaXMuZXJyb3JGb3JtID0gdHJ1ZTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmVycm9yRm9ybSA9IGZhbHNlO1xuICAgICAgICBjb25zdCBmb3JtVmFsdWUgPSB0aGlzLnZpc2l0Rm9ybS52YWx1ZTtcbiAgICAgICAgY29uc3QgY2FwdHVyZSA9IHtcbiAgICAgICAgICAgIHZpZXdlcjogZm9ybVZhbHVlLnZpZXdlcixcbiAgICAgICAgICAgIHRha2VuQXQ6IHRoaXMuY2FwdHVyZURhdGUsXG4gICAgICAgICAgICBzdXJmYWNlOiBmb3JtVmFsdWUuc3VyZmFjZSxcbiAgICAgICAgICAgIHNwYWNlSUQ6IHRoaXMuY3VycmVudFNwYWNlLmlkLFxuICAgICAgICB9IGFzIENhcHR1cmU7XG5cbiAgICAgICAgaWYgKHRoaXMuaXNFZGl0aW5nKSB7XG4gICAgICAgICAgICBjYXB0dXJlLmlkID0gZm9ybVZhbHVlLmNhcHR1cmVJRDtcbiAgICAgICAgICAgIGF3YWl0IHRoaXMuY2FwdHVyZVNlcnZpY2UudXBkYXRlQ2FwdHVyZShjYXB0dXJlKTtcbiAgICAgICAgICAgIGNvbnN0IG5vZGUgPSB7XG4gICAgICAgICAgICAgICAgaWQ6IGZvcm1WYWx1ZS5ub2RlSUQsXG4gICAgICAgICAgICAgICAgbW9kZWwzRDogZm9ybVZhbHVlLm1vZGVsM0QsXG4gICAgICAgICAgICAgICAgbWV0YWRhdGE6IGZvcm1WYWx1ZS5uYW1lLFxuICAgICAgICAgICAgfSBhcyBOb2RlO1xuICAgICAgICAgICAgYXdhaXQgdGhpcy5ub2RlU2VydmljZS51cGRhdGVOb2RlKG5vZGUpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgbGV0IGNyZWF0ZWROb2RlO1xuICAgICAgICAgICAgYXdhaXQgdGhpcy5jYXB0dXJlU2VydmljZS5jcmVhdGVDYXB0dXJlKGNhcHR1cmUpLnRoZW4oYXN5bmMgKHJlcykgPT4ge1xuICAgICAgICAgICAgICAgIGlmIChyZXMpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgbm9kZSA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG1vZGVsM0Q6IGZvcm1WYWx1ZS5tb2RlbDNELFxuICAgICAgICAgICAgICAgICAgICAgICAgY2FwdHVyZUlEOiByZXMuaWQsXG4gICAgICAgICAgICAgICAgICAgICAgICBtZXRhZGF0YTogZm9ybVZhbHVlLm5hbWUsXG4gICAgICAgICAgICAgICAgICAgIH0gYXMgTm9kZTtcbiAgICAgICAgICAgICAgICAgICAgY3JlYXRlZE5vZGUgPSBhd2FpdCB0aGlzLm5vZGVTZXJ2aWNlLmNyZWF0ZU5vZGUobm9kZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB0aGlzLmxhdW5jaEltcG9ydChcbiAgICAgICAgICAgICAgICBmb3JtVmFsdWUubW9kZWwzRCxcbiAgICAgICAgICAgICAgICBmb3JtVmFsdWUuc3VyZmFjZSxcbiAgICAgICAgICAgICAgICBjcmVhdGVkTm9kZSxcbiAgICAgICAgICAgICAgICBmYWxzZVxuICAgICAgICAgICAgKVxuICAgICAgICAgICAgICAgIC50aGVuKChzdWNjZXNzKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMubW9kYWxSZWZlcmVuY2UuY2xvc2UoJ2ltcG9ydCBlbmRlZCB3aXRoIHN1Y2Nlc3MnKTtcbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgIC5jYXRjaCgoZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLm1vZGFsUmVmZXJlbmNlLmNsb3NlKGBFcnJvciB3aGlsZSBpbXBvcnQ6ICR7ZX1gKTtcbiAgICAgICAgICAgICAgICAgICAgYWxlcnQoYEVycm9yIHdoaWxlIGltcG9ydDogJHtlfSAke0pTT04uc3RyaW5naWZ5KGUpfWApO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLm9uRGVsZXRlKHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG5vZGU6IGNyZWF0ZWROb2RlLFxuICAgICAgICAgICAgICAgICAgICAgICAgY2FwdHVyZUlEOiBjcmVhdGVkTm9kZS5jYXB0dXJlSUQsXG4gICAgICAgICAgICAgICAgICAgIH0gYXMgVmlzaXQsIGZhbHNlKTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICBhd2FpdCB0aGlzLnJlc2V0VmlzaXRzKCk7XG4gICAgICAgIHRoaXMub25DYW5jZWwoKTtcbiAgICB9XG5cbiAgICBnZXQgbW9kZWwzRCgpOiBBYnN0cmFjdENvbnRyb2wge1xuICAgICAgICByZXR1cm4gdGhpcy52aXNpdEZvcm0uZ2V0KCdtb2RlbDNEJyk7XG4gICAgfVxuXG4gICAgZ2V0IG5hbWUoKTogQWJzdHJhY3RDb250cm9sIHtcbiAgICAgICAgcmV0dXJuIHRoaXMudmlzaXRGb3JtLmdldCgnbmFtZScpO1xuICAgIH1cblxuICAgIG9uQ2FuY2VsKCkge1xuICAgICAgICB0aGlzLnZpc2l0U3VibWl0dGVkID0gZmFsc2U7XG4gICAgICAgIHRoaXMudmlzaXRGb3JtID0gbnVsbDtcbiAgICAgICAgdGhpcy5pc0VkaXRpbmcgPSBmYWxzZTtcbiAgICAgICAgdGhpcy5jYW5DYW5jZWxJbXBvcnQgPSBmYWxzZTtcbiAgICAgICAgdGhpcy50b3RhbEltYWdlcyA9IDA7XG4gICAgICAgIHRoaXMuaW1hZ2VzUHJvY2Vzc2VkID0gMDtcbiAgICAgICAgdGhpcy5lcnJvckZvcm0gPSBmYWxzZTtcbiAgICAgICAgdGhpcy5zZXR1cE1lbnVJdGVtcygpO1xuICAgIH1cblxuICAgIGFzeW5jIG9uRGVsZXRlKHZpc2l0OiBWaXNpdCwgbmVlZFBlcm1pc3Npb24gPSB0cnVlKSB7XG4gICAgICAgIGNvbnN0IG1lc3NhZ2UgPSB0aGlzLnRyYW5zbGF0ZS5pbnN0YW50KCdjb25maXJtLmRlbGV0ZVZpc2l0Jyk7XG4gICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1hbGVydFxuICAgICAgICBpZiAod2luZG93LmNvbmZpcm0obWVzc2FnZSkgfHwgIW5lZWRQZXJtaXNzaW9uKSB7XG4gICAgICAgICAgICBjb25zb2xlLmxvZyh0aGlzLnZpc2l0SW5kZXhEZXRhaWxzKTtcbiAgICAgICAgICAgIHRoaXMuaXNQcm9jZXNzaW5nID0gdHJ1ZTtcbiAgICAgICAgICAgIGF3YWl0IHRoaXMudmlzaXRTZXJ2aWNlLmRlbGV0ZVZpc2l0KHZpc2l0LCB0aGlzLnNwYWNlSWQpO1xuICAgICAgICAgICAgYXdhaXQgdGhpcy5yZXNldFZpc2l0cygpO1xuICAgICAgICAgICAgdGhpcy5pc1Byb2Nlc3NpbmcgPSBmYWxzZTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgZ2V0RGlzbWlzc1JlYXNvbihyZWFzb246IGFueSk6IHN0cmluZyB7XG4gICAgICAgIGlmIChyZWFzb24gPT09IE1vZGFsRGlzbWlzc1JlYXNvbnMuRVNDKSB7XG4gICAgICAgICAgICByZXR1cm4gJ2J5IHByZXNzaW5nIEVTQyc7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHJlYXNvbiA9PT0gTW9kYWxEaXNtaXNzUmVhc29ucy5CQUNLRFJPUF9DTElDSykge1xuICAgICAgICAgICAgcmV0dXJuICdieSBjbGlja2luZyBvbiBhIGJhY2tkcm9wJztcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gYHdpdGg6ICR7cmVhc29ufWA7XG4gICAgfVxuXG4gICAgYXN5bmMgbGF1bmNoSW1wb3J0KFxuICAgICAgICBtb2RlbDNELFxuICAgICAgICBzdXJmYWNlLFxuICAgICAgICBub2RlLFxuICAgICAgICBpbWFnZXNPbmx5ID0gZmFsc2VcbiAgICApOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgICAgICAgdGhpcy5tb2RhbFJlZmVyZW5jZSA9IHRoaXMubW9kYWxTZXJ2aWNlLm9wZW4odGhpcy5jb250ZW50LCB7XG4gICAgICAgICAgICBhcmlhTGFiZWxsZWRCeTogJ21vZGFsLWJhc2ljLXRpdGxlJyxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMubW9kYWxSZWZlcmVuY2UucmVzdWx0LnRoZW4oXG4gICAgICAgICAgICAocmVzdWx0KSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5jbG9zZVJlc3VsdCA9IGBDbG9zZWQgd2l0aDogJHtyZXN1bHR9YDtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmxvZyh0aGlzLmNsb3NlUmVzdWx0KTtcbiAgICAgICAgICAgICAgICB0aGlzLmNhbmNlbEltcG9ydCgpO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIChlcnJvcikgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMuY2xvc2VSZXN1bHQgPSBgRGlzbWlzc2VkICR7dGhpcy5nZXREaXNtaXNzUmVhc29uKGVycm9yKX1gO1xuICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKHRoaXMuY2xvc2VSZXN1bHQpO1xuICAgICAgICAgICAgICAgIHRoaXMuY2FuY2VsSW1wb3J0KCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICk7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBhd2FpdCB0aGlzLm1hdHRlcnBvcnRJbXBvcnRTZXJ2aWNlLmluaXRTZGtGb3JNb2RlbChtb2RlbDNEKTtcbiAgICAgICAgICAgIHJldHVybiBpbWFnZXNPbmx5XG4gICAgICAgICAgICAgICAgPyB0aGlzLm1hdHRlcnBvcnRJbXBvcnRTZXJ2aWNlLmltcG9ydERhdGEoXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuc3BhY2VJZCxcbiAgICAgICAgICAgICAgICAgICAgc3VyZmFjZSxcbiAgICAgICAgICAgICAgICAgICAgdHJ1ZSxcbiAgICAgICAgICAgICAgICAgICAgbm9kZVxuICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgICA6IHRoaXMubWF0dGVycG9ydEltcG9ydFNlcnZpY2UuaW1wb3J0RGF0YShcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5zcGFjZUlkLFxuICAgICAgICAgICAgICAgICAgICBzdXJmYWNlLFxuICAgICAgICAgICAgICAgICAgICBmYWxzZSxcbiAgICAgICAgICAgICAgICAgICAgbm9kZVxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICBjb25zb2xlLmxvZyhlcnJvcik7XG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QoZXJyb3IpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBjYW5jZWxJbXBvcnQoKSB7XG4gICAgICAgIHRoaXMubWF0dGVycG9ydEltcG9ydFNlcnZpY2UuYWJhbmRvbigpO1xuICAgICAgICB0aGlzLm9uQ2FuY2VsKCk7XG4gICAgICAgIHRoaXMucmVzZXRWaXNpdHMoKTtcbiAgICB9XG5cbiAgICBvbkltcG9ydCh2aXNpdDogVmlzaXQpIHtcbiAgICAgICAgdGhpcy5sYXVuY2hJbXBvcnQodmlzaXQubW9kZWwzZCwgbnVsbCwgdmlzaXQubm9kZS5pZCwgdHJ1ZSk7XG4gICAgfVxuXG4gICAgaXNGb3JtRXJyb3IoY29udHJvbCkge1xuICAgICAgICByZXR1cm4gY29udHJvbCAmJiBjb250cm9sLmludmFsaWQgJiYgdGhpcy5lcnJvckZvcm07XG4gICAgfVxufVxuIiwiPGRpdiBjbGFzcz1cImNvbnRhaW5lci1mbHVpZFwiIGNsYXNzPVwiZGFzaGJvYXJkLXRhYlwiPlxuICAgIDxkaXYgY2xhc3M9XCJtLTNcIj5cbiAgICAgICAgPGxpYi10YWItbmF2aWdhdGlvbiBbbWVudUl0ZW1zXT0nbWVudUl0ZW1zJyAob25Hb0JhY2spPVwib25Hb0JhY2soKVwiPjwvbGliLXRhYi1uYXZpZ2F0aW9uPlxuICAgIDwvZGl2PlxuXG4gICAgPGRpdiBjbGFzcz1cInJvdyBtYWluLWZvcm0tY29udGFpbmVyXCI+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJjb2wtbWQtNiBmb3JtLWNvbnRhaW5lclwiPlxuICAgICAgICAgICAgPHVsIGNsYXNzPVwibGlzdC1ncm91cCBsaXN0LWdyb3VwLWZsdXNoXCIgKm5nSWY9XCIhdmlzaXRGb3JtXCI+XG4gICAgICAgICAgICAgICAgPGxpIGNsYXNzPVwibGlzdC1ncm91cC1pdGVtIGxpc3QtZ3JvdXAtaXRlbS1hY3Rpb25cIiAqbmdGb3I9XCJsZXQgdmlzaXQgb2YgdmlzaXRzOyBpbmRleCBhcyBpbmRleFwiPlxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZC1mbGV4IGp1c3RpZnktY29udGVudC1iZXR3ZWVuIGFsaWduLWl0ZW1zLWNlbnRlclwiIChjbGljayk9XCJvblRvZ2dsZURldGFpbChpbmRleClcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIHt7dmlzaXQubmFtZSA/IHZpc2l0Lm5hbWUgOiB2aXNpdC5tb2RlbDNkIH19XG4gICAgICAgICAgICAgICAgICAgICAgICA8bGliLWNoZXZyb24gW2NvbmRpdGlvblNob3dpbmddPVwiaW5kZXg9PXZpc2l0SW5kZXhEZXRhaWxzXCI+PC9saWItY2hldnJvbj5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgKm5nSWY9XCJpbmRleD09dmlzaXRJbmRleERldGFpbHNcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDx1bCBjbGFzcz1cImxpc3QtZ3JvdXAgbGlzdC1ncm91cC1mbHVzaFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxsaSBjbGFzcz1cImxpc3QtZ3JvdXAtaXRlbSBiZy10cmFuc3BhcmVudFwiPnt7J05hbWUnIHwgdHJhbnNsYXRlfX0gOiB7eyB2aXNpdC5uYW1lID9cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmlzaXQubmFtZSA6IFwiTm90IHByb3ZpZGVkXCIgfCB0cmFuc2xhdGV9fTwvbGk+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGxpIGNsYXNzPVwibGlzdC1ncm91cC1pdGVtIGJnLXRyYW5zcGFyZW50XCI+e3snM0QgTW9kZWwnIHwgdHJhbnNsYXRlfX0gOiB7eyB2aXNpdC5tb2RlbDNkIH19XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9saT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bGkgY2xhc3M9XCJsaXN0LWdyb3VwLWl0ZW0gYmctdHJhbnNwYXJlbnRcIj57eydTdXJmYWNlJyB8IHRyYW5zbGF0ZX19LCBtPHN1cD4yPC9zdXA+OiB7e1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2aXNpdC5zdXJmYWNlID9cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmlzaXQuc3VyZmFjZSA6ICdOb3QgcHJvdmlkZWQnIHwgdHJhbnNsYXRlfX08L2xpPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxsaSBjbGFzcz1cImxpc3QtZ3JvdXAtaXRlbSBiZy10cmFuc3BhcmVudFwiPnt7J1ZpZXdlcicgfCB0cmFuc2xhdGV9fSA6IHt7IHZpc2l0LnZpZXdlciB9fVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbGk+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGxpIGNsYXNzPVwibGlzdC1ncm91cC1pdGVtIGJnLXRyYW5zcGFyZW50XCI+e3snRGF0ZSBvZiBjYXB0dXJlJyB8IHRyYW5zbGF0ZX19IDoge3tcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmlzaXQudGFrZW5BdCB8IHRpbWVEYXRlU3RyaW5nIHwgYXN5bmN9fVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxsaSBjbGFzcz1cImxpc3QtZ3JvdXAtaXRlbSBiZy10cmFuc3BhcmVudFwiPnt7J0ltYWdlcyBpbXBvcnRlZCcgfCB0cmFuc2xhdGV9fSA6IHt7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZpc2l0Lm5tYkltYWdlc0ltcG9ydGVkIH19XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9saT5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvdWw+XG4gICAgICAgICAgICAgICAgICAgICAgICBcbiAgICAgICAgICAgICAgICAgICAgICAgIDxsaWItbG9hZGVyICpuZ0lmPVwiaXNQcm9jZXNzaW5nXCI+PC9saWItbG9hZGVyPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgY2xhc3M9XCJidG4gYnRuLW91dGxpbmUtcHJpbWFyeSByb3VuZGVkLXBpbGwgbWUtMlwiIChjbGljayk9XCJvbkltcG9ydCh2aXNpdClcIiBbZGlzYWJsZWRdPVwiaXNQcm9jZXNzaW5nXCI+e3snSW1wb3J0IGltYWdlcycgfFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyYW5zbGF0ZX19PC9idXR0b24+XG4gICAgICAgICAgICAgICAgICAgICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBjbGFzcz1cImJ0biBidG4tb3V0bGluZS1wcmltYXJ5IHJvdW5kZWQtcGlsbCBtZS0yXCIgW2Rpc2FibGVkXT1cImlzUHJvY2Vzc2luZ1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgKGNsaWNrKT1cIm9uRWRpdCh2aXNpdClcIj57eydFZGl0JyB8IHRyYW5zbGF0ZX19PC9idXR0b24+XG4gICAgICAgICAgICAgICAgICAgICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBjbGFzcz1cImJ0biBidG4tb3V0bGluZS1wcmltYXJ5IHJvdW5kZWQtcGlsbFwiIFtkaXNhYmxlZF09XCJpc1Byb2Nlc3NpbmdcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIChjbGljayk9XCJvbkRlbGV0ZSh2aXNpdClcIj57eydEZWxldGUnIHwgdHJhbnNsYXRlfX08L2J1dHRvbj5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgPC9saT5cbiAgICAgICAgICAgIDwvdWw+XG4gICAgICAgICAgICA8ZGl2ICpuZ0lmPVwidmlzaXRGb3JtXCI+XG4gICAgICAgICAgICAgICAgPGZvcm0gKG5nU3VibWl0KT1cIm9uU3VibWl0VmlzaXQoKVwiIFtmb3JtR3JvdXBdPVwidmlzaXRGb3JtXCI+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJtYi0zIHJvd1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwiY29sLXNtLTIgY29sLWZvcm0tbGFiZWxcIj57eydOYW1lJyB8IHRyYW5zbGF0ZX19PC9sYWJlbD5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjb2wtc20tMTBcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW5wdXQgdHlwZT1cInRleHRcIiBjbGFzcz1cImZvcm0tY29udHJvbFwiIGZvcm1Db250cm9sTmFtZT1cIm5hbWVcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm1iLTMgcm93XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJjb2wtc20tMiBjb2wtZm9ybS1sYWJlbFwiPnt7J1JlZmVyZW5jZSAzRCBtb2RlbCcgfCB0cmFuc2xhdGV9fSAqPC9sYWJlbD5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjb2wtc20tMTBcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW5wdXQgdHlwZT1cInRleHRcIiBjbGFzcz1cImZvcm0tY29udHJvbFwiIFtyZWFkb25seV09XCJpc0VkaXRpbmdcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbY2xhc3MuaXMtaW52YWxpZF09XCJtb2RlbDNELmludmFsaWQgJiYgdmlzaXRTdWJtaXR0ZWRcIiByZXF1aXJlZFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3JtQ29udHJvbE5hbWU9XCJtb2RlbDNEXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImludmFsaWQtZmVlZGJhY2tcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG5nYi1hbGVydCBkYXRhLXRlc3RpZD1cIm5ldy1sb2NhdGlvbi1uYW1lLWludmFsaWRcIiBbZGlzbWlzc2libGVdPVwiZmFsc2VcIiB0eXBlPVwiZGFuZ2VyXCIgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICpuZ0lmPVwidmFsaWRhdG9yc1NlcnZpY2UuaXNDb250cm9sRXJyb3IodmlzaXRGb3JtLmNvbnRyb2xzWyduYW1lJ10pIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfHwgIGlzRm9ybUVycm9yKHZpc2l0Rm9ybS5jb250cm9sc1snbmFtZSddKVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7e3ZhbGlkYXRvcnNTZXJ2aWNlLmdldEVycm9yKHZpc2l0Rm9ybS5jb250cm9sc1snbmFtZSddKSB8IHRyYW5zbGF0ZX19XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbmdiLWFsZXJ0PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgKm5nSWY9XCJpc0VkaXRpbmdcIiBjbGFzcz1cInRleHQtZGFuZ2VyXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt7J0Nhbm5vdCBjaGFuZ2UgM0QgbW9kZWwgcmVmZXJlbmNlLiBQbGVhc2UgYWRkIG5ldyBtb2RlbC4nIHwgdHJhbnNsYXRlfX1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibWItMyByb3dcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cImNvbC1zbS0yIGNvbC1mb3JtLWxhYmVsXCI+e3snVmlld2VyJyB8IHRyYW5zbGF0ZX19PC9sYWJlbD5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjb2wtc20tMTBcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW5wdXQgdHlwZT1cInRleHRcIiBjbGFzcz1cImZvcm0tY29udHJvbFwiIGZvcm1Db250cm9sTmFtZT1cInZpZXdlclwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJtYi0zIHJvd1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwiY29sLXNtLTIgY29sLWZvcm0tbGFiZWxcIj57eydTdXJmYWNlJyB8IHRyYW5zbGF0ZX19PC9sYWJlbD5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjb2wtc20tMTBcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW5wdXQgdHlwZT1cInRleHRcIiBjbGFzcz1cImZvcm0tY29udHJvbFwiIGZvcm1Db250cm9sTmFtZT1cInN1cmZhY2VcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibWItMyByb3dcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cImNvbC1zbS0yIGNvbC1mb3JtLWxhYmVsXCI+e3snQ2FwdHVyZSBEYXRlJyB8IHRyYW5zbGF0ZX19PC9sYWJlbD5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJpbnB1dC1ncm91cFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dCBjbGFzcz1cImZvcm0tY29udHJvbFwiIHBsYWNlaG9sZGVyPVwiZGQvbW0veXl5eVwiIFsobmdNb2RlbCldPVwiY2FwdHVyZURhdGVcIiBuZ2JEYXRlcGlja2VyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICNkMT1cIm5nYkRhdGVwaWNrZXJcIiBbbmdNb2RlbE9wdGlvbnNdPVwie3N0YW5kYWxvbmU6IHRydWV9XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImlucHV0LWdyb3VwLWFwcGVuZFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8YnV0dG9uIGNsYXNzPVwiYnRuIGJ0bi1vdXRsaW5lLXNlY29uZGFyeSBjYWxlbmRhclwiIChjbGljayk9XCJkMS50b2dnbGUoKVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlPVwiYnV0dG9uXCI+PC9idXR0b24+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDxidXR0b24gdHlwZT1cInN1Ym1pdFwiIGNsYXNzPVwiYnRuIGJ0bi1vdXRsaW5lLXByaW1hcnkgcm91bmRlZC1waWxsIG1lLTJcIj57eydTYXZlJyB8XG4gICAgICAgICAgICAgICAgICAgICAgICB0cmFuc2xhdGV9fTwvYnV0dG9uPlxuICAgICAgICAgICAgICAgICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiAoY2xpY2spPVwib25DYW5jZWwoKVwiIGNsYXNzPVwiYnRuIGJ0bi1vdXRsaW5lLXByaW1hcnkgcm91bmRlZC1waWxsXCI+e3snQ2FuY2VsJyB8XG4gICAgICAgICAgICAgICAgICAgICAgICB0cmFuc2xhdGV9fTwvYnV0dG9uPlxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiaW52YWxpZC1mZWVkYmFja1wiICpuZ0lmPVwiZXJyb3JGb3JtXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG5nYi1hbGVydCBkYXRhLXRlc3RpZD1cIm5ldy1sb2NhdGlvbi1mb3JtLWludmFsaWRcIiBbZGlzbWlzc2libGVdPVwiZmFsc2VcIiB0eXBlPVwiZGFuZ2VyXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7eydlcnJvckZvcm0uaW5mb0J0bicgfHRyYW5zbGF0ZX19XG4gICAgICAgICAgICAgICAgICAgICAgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9uZ2ItYWxlcnQ+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDwvZm9ybT5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPGRpdiAqbmdJZj1cIiF2aXNpdEZvcm1cIj5cbiAgICAgICAgICAgICAgICA8YnV0dG9uIGNsYXNzPVwiYnRuIGJ0bi1vdXRsaW5lLXByaW1hcnkgcm91bmRlZC1waWxsXCIgKGNsaWNrKT1cIm9uQWRkVmlzaXQoKVwiPnt7J0FkZCAzRCB2aXNpdCcgfFxuICAgICAgICAgICAgICAgICAgICB0cmFuc2xhdGV9fTwvYnV0dG9uPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuICAgICAgICA8ZGl2IGlkPVwidmlld2VyLWZyYW1lXCIgc3R5bGU9XCJ3aWR0aDogMTAwJTsgYXNwZWN0LXJhdGlvOiAyLzE7XCI+PC9kaXY+XG4gICAgPC9kaXY+XG4gICAgPG5nLXRlbXBsYXRlICNjb250ZW50IGxldC1tb2RhbD5cbiAgICAgICAgPGRpdiBjbGFzcz1cIm1vZGFsLWhlYWRlclwiPlxuICAgICAgICAgICAgPGg0IGNsYXNzPVwibW9kYWwtdGl0bGVcIiBpZD1cIm1vZGFsLWJhc2ljLXRpdGxlXCI+e3snSW1wb3J0aW5nIERhdGEnIHwgdHJhbnNsYXRlfX08L2g0PlxuICAgICAgICAgICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgY2xhc3M9XCJjbG9zZVwiIGFyaWEtbGFiZWw9XCJDbG9zZVwiIChjbGljayk9XCJtb2RhbC5kaXNtaXNzKCdDcm9zcyBjbGljaycpXCI+XG4gICAgICAgICAgICAgICAgPHNwYW4gYXJpYS1oaWRkZW49XCJ0cnVlXCI+w5c8L3NwYW4+XG4gICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgPC9kaXY+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJtb2RhbC1ib2R5XCI+XG4gICAgICAgICAgICB7eydQbGVhc2UgZG8gbm90IGxlYXZlIG9yIHJlZnJlc2ggdGhpcyBwYWdlLi4uJyB8IHRyYW5zbGF0ZX19XG4gICAgICAgICAgICA8ZGl2ICpuZ0lmPVwidG90YWxJbWFnZXMgIT0gMFwiPkltcG9ydGVkIHt7aW1hZ2VzUHJvY2Vzc2VkfX0gb3V0IG9mIHt7dG90YWxJbWFnZXN9fSBpbWFnZXMuPC9kaXY+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZC1mbGV4IGp1c3RpZnktY29udGVudC1jZW50ZXJcIj5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic3Bpbm5lci1ib3JkZXJcIiByb2xlPVwic3RhdHVzXCI+XG4gICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwidmlzdWFsbHktaGlkZGVuXCI+e3snTG9hZGluZycgfCB0cmFuc2xhdGV9fS4uLjwvc3Bhbj5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L2Rpdj5cbiAgICAgICAgPGRpdiBjbGFzcz1cIm1vZGFsLWZvb3RlclwiPlxuICAgICAgICAgICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgY2xhc3M9XCJidG4gYnRuLW91dGxpbmUtZGFya1wiIFtkaXNhYmxlZF09XCIhY2FuQ2FuY2VsSW1wb3J0XCJcbiAgICAgICAgICAgICAgICAoY2xpY2spPVwibW9kYWwuY2xvc2UoJ0NhbmNlbCBjbGljaycpXCI+e3snQ2FuY2VsIGltcG9ydCBvZiBpbWFnZXMnIHwgdHJhbnNsYXRlfX08L2J1dHRvbj5cbiAgICAgICAgPC9kaXY+XG4gICAgPC9uZy10ZW1wbGF0ZT5cbjwvZGl2PiJdfQ==
|