@smarterplan/ngx-smarterplan-locations 0.3.4 → 0.4.2
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/esm2022/lib/components/carousel/carousel.component.mjs +30 -0
- package/esm2022/lib/components/chevron/chevron.component.mjs +18 -0
- package/esm2022/lib/components/detail-location/detail-location.component.mjs +183 -0
- package/{esm2020 → esm2022}/lib/components/form-location/form-location.component.mjs +254 -237
- package/esm2022/lib/components/images/images.component.mjs +120 -0
- package/esm2022/lib/components/locations/locations.component.mjs +157 -0
- package/esm2022/lib/components/locations/map/map-popup/map-popup.component.mjs +72 -0
- package/esm2022/lib/components/locations/map/map.component.mjs +92 -0
- package/esm2022/lib/components/plan-legend/plan-legend.component.mjs +49 -0
- package/esm2022/lib/components/plans/calibration/calibration.component.mjs +494 -0
- package/esm2022/lib/components/plans/edit-plan/edit-plan.component.mjs +350 -0
- package/{esm2020 → esm2022}/lib/components/plans/plans.component.mjs +243 -225
- package/esm2022/lib/components/tab-navigation/tab-navigation.component.mjs +43 -0
- package/esm2022/lib/components/visits/visits.component.mjs +294 -0
- package/esm2022/lib/components/zones/add-audio-zone/add-audio-zone.component.mjs +250 -0
- package/esm2022/lib/components/zones/add-zone/add-zone.component.mjs +333 -0
- package/esm2022/lib/components/zones/add-zone/selection/selection.component.mjs +81 -0
- package/esm2022/lib/components/zones/add-zone/sweep-plan-selection/sweep-plan-selection.component.mjs +518 -0
- package/esm2022/lib/components/zones/zones.component.mjs +291 -0
- package/{esm2020 → esm2022}/lib/helper.service.mjs +133 -133
- package/esm2022/lib/ngx-smarterplan-location-routing.module.mjs +50 -0
- package/esm2022/lib/ngx-smarterplan-locations.module.mjs +124 -0
- package/esm2022/lib/ngx-smarterplan-locations.service.mjs +15 -0
- package/esm2022/lib/pipes/count-audio-sweeps.pipe.mjs +29 -0
- package/esm2022/lib/radio-button/radio-button.component.mjs +28 -0
- package/{esm2020 → esm2022}/public-api.mjs +8 -8
- package/{esm2020 → esm2022}/smarterplan-ngx-smarterplan-locations.mjs +4 -4
- package/{fesm2020 → fesm2022}/smarterplan-ngx-smarterplan-locations.mjs +3959 -3738
- package/fesm2022/smarterplan-ngx-smarterplan-locations.mjs.map +1 -0
- package/index.d.ts +5 -5
- package/lib/components/carousel/carousel.component.d.ts +12 -12
- package/lib/components/chevron/chevron.component.d.ts +9 -9
- package/lib/components/detail-location/detail-location.component.d.ts +55 -55
- package/lib/components/form-location/form-location.component.d.ts +45 -45
- package/lib/components/images/images.component.d.ts +33 -33
- package/lib/components/locations/locations.component.d.ts +51 -51
- package/lib/components/locations/map/map-popup/map-popup.component.d.ts +22 -22
- package/lib/components/locations/map/map.component.d.ts +21 -22
- package/lib/components/plan-legend/plan-legend.component.d.ts +14 -14
- package/lib/components/plans/calibration/calibration.component.d.ts +140 -140
- package/lib/components/plans/edit-plan/edit-plan.component.d.ts +55 -55
- package/lib/components/plans/plans.component.d.ts +63 -63
- package/lib/components/tab-navigation/tab-navigation.component.d.ts +13 -13
- package/lib/components/visits/visits.component.d.ts +63 -63
- package/lib/components/zones/add-audio-zone/add-audio-zone.component.d.ts +63 -63
- package/lib/components/zones/add-zone/add-zone.component.d.ts +69 -69
- package/lib/components/zones/add-zone/selection/selection.component.d.ts +44 -44
- package/lib/components/zones/add-zone/sweep-plan-selection/sweep-plan-selection.component.d.ts +107 -107
- package/lib/components/zones/zones.component.d.ts +73 -73
- package/lib/helper.service.d.ts +53 -53
- package/lib/ngx-smarterplan-location-routing.module.d.ts +7 -7
- package/lib/ngx-smarterplan-locations.module.d.ts +36 -36
- package/lib/ngx-smarterplan-locations.service.d.ts +6 -6
- package/lib/pipes/count-audio-sweeps.pipe.d.ts +10 -10
- package/lib/radio-button/radio-button.component.d.ts +12 -12
- package/package.json +13 -19
- package/public-api.d.ts +4 -4
- package/esm2020/lib/components/carousel/carousel.component.mjs +0 -28
- package/esm2020/lib/components/chevron/chevron.component.mjs +0 -18
- package/esm2020/lib/components/detail-location/detail-location.component.mjs +0 -168
- package/esm2020/lib/components/images/images.component.mjs +0 -107
- package/esm2020/lib/components/locations/locations.component.mjs +0 -145
- package/esm2020/lib/components/locations/map/map-popup/map-popup.component.mjs +0 -66
- package/esm2020/lib/components/locations/map/map.component.mjs +0 -91
- package/esm2020/lib/components/plan-legend/plan-legend.component.mjs +0 -47
- package/esm2020/lib/components/plans/calibration/calibration.component.mjs +0 -468
- package/esm2020/lib/components/plans/edit-plan/edit-plan.component.mjs +0 -324
- package/esm2020/lib/components/tab-navigation/tab-navigation.component.mjs +0 -41
- package/esm2020/lib/components/visits/visits.component.mjs +0 -275
- package/esm2020/lib/components/zones/add-audio-zone/add-audio-zone.component.mjs +0 -230
- package/esm2020/lib/components/zones/add-zone/add-zone.component.mjs +0 -315
- package/esm2020/lib/components/zones/add-zone/selection/selection.component.mjs +0 -77
- package/esm2020/lib/components/zones/add-zone/sweep-plan-selection/sweep-plan-selection.component.mjs +0 -502
- package/esm2020/lib/components/zones/zones.component.mjs +0 -268
- package/esm2020/lib/ngx-smarterplan-location-routing.module.mjs +0 -49
- package/esm2020/lib/ngx-smarterplan-locations.module.mjs +0 -123
- package/esm2020/lib/ngx-smarterplan-locations.service.mjs +0 -14
- package/esm2020/lib/pipes/count-audio-sweeps.pipe.mjs +0 -27
- package/esm2020/lib/radio-button/radio-button.component.mjs +0 -26
- package/fesm2015/smarterplan-ngx-smarterplan-locations.mjs +0 -3983
- package/fesm2015/smarterplan-ngx-smarterplan-locations.mjs.map +0 -1
- package/fesm2020/smarterplan-ngx-smarterplan-locations.mjs.map +0 -1
|
@@ -0,0 +1,494 @@
|
|
|
1
|
+
import { Component, ViewChild } from '@angular/core';
|
|
2
|
+
import { getDocument } from 'pdfjs-dist';
|
|
3
|
+
// import { PDFDocumentProxy } from 'ng2-pdf-viewer';
|
|
4
|
+
import { getMetaForImage, } from '@smarterplan/ngx-smarterplan-core';
|
|
5
|
+
import panzoom from 'panzoom';
|
|
6
|
+
import * as i0 from "@angular/core";
|
|
7
|
+
import * as i1 from "@smarterplan/ngx-smarterplan-core";
|
|
8
|
+
import * as i2 from "@angular/router";
|
|
9
|
+
import * as i3 from "@ngx-translate/core";
|
|
10
|
+
import * as i4 from "@ng-bootstrap/ng-bootstrap";
|
|
11
|
+
import * as i5 from "@angular/common";
|
|
12
|
+
import * as i6 from "@angular/forms";
|
|
13
|
+
import * as i7 from "../../tab-navigation/tab-navigation.component";
|
|
14
|
+
class CalibrationComponent {
|
|
15
|
+
matterportImportService;
|
|
16
|
+
planService;
|
|
17
|
+
route;
|
|
18
|
+
router;
|
|
19
|
+
zoneService;
|
|
20
|
+
spaceService;
|
|
21
|
+
navigationService;
|
|
22
|
+
translate;
|
|
23
|
+
/** Item to display for the navbar */
|
|
24
|
+
menuItems = [];
|
|
25
|
+
/** Canvas (Plan) */
|
|
26
|
+
canvas;
|
|
27
|
+
/** CanvasDiv (Div that contain the canvas + matterport iframe) */
|
|
28
|
+
canvasDiv;
|
|
29
|
+
/** Size of the canvas & matterport iframe */
|
|
30
|
+
canvasSize;
|
|
31
|
+
/** Zoom ratio of the canvas/plan */
|
|
32
|
+
canvasZoom = 0;
|
|
33
|
+
/** Opacity for matterport iframe */
|
|
34
|
+
opacity = 50;
|
|
35
|
+
/** Current rotation for matterport, [0-360], matterport rotation is bind to input range */
|
|
36
|
+
rotation = 180;
|
|
37
|
+
/** Previous rotation, use to calculate the deltaRotation to rotate, when user change rotation value using range input */
|
|
38
|
+
prevRotation = 180;
|
|
39
|
+
/** Current Camera Pose */
|
|
40
|
+
cameraPose;
|
|
41
|
+
/** True when the user is currently rotating with the input range, the matterport rotation events will be ignored */
|
|
42
|
+
isRotatingRange = false;
|
|
43
|
+
/** Rotating queue event to send to matterport */
|
|
44
|
+
rotatingQueueEvent = [];
|
|
45
|
+
/** True when Vertical symmetry is enabled */
|
|
46
|
+
reflectV = false;
|
|
47
|
+
/** True when Horizontal symmetry is enabled */
|
|
48
|
+
reflectH = false;
|
|
49
|
+
chosenPlan;
|
|
50
|
+
spaceID;
|
|
51
|
+
currentSpace;
|
|
52
|
+
currentZone;
|
|
53
|
+
chosenPlanIsPdf = false;
|
|
54
|
+
/** First Point in visit, used to determine the calibration */
|
|
55
|
+
firstMarkVisit = { x: 0, y: 0 };
|
|
56
|
+
/** Second Point in visit, used to determine the calibration */
|
|
57
|
+
secondMarkVisit = { x: 0.5, y: 0.5 };
|
|
58
|
+
/** Equivalent of 'firstMarkVisit' in canvas */
|
|
59
|
+
firstMarkPlan = { x: 0, y: 0 };
|
|
60
|
+
/** Equivalent of 'secondMarkVisit' in canvas */
|
|
61
|
+
secondMarkPlan = { x: 0, y: 0 };
|
|
62
|
+
/** Calibration result, (offsetX, offsetY, x, y) */
|
|
63
|
+
calibrage = {};
|
|
64
|
+
/** Is in preview mode (see scan result) */
|
|
65
|
+
preview = false;
|
|
66
|
+
/** Matterport is loading */
|
|
67
|
+
loading = true;
|
|
68
|
+
/* for pan and zoom of canvas */
|
|
69
|
+
panzoom;
|
|
70
|
+
currentNavigations;
|
|
71
|
+
positions = [];
|
|
72
|
+
floors = [];
|
|
73
|
+
currentFloor;
|
|
74
|
+
zoomCanBeChanged = false;
|
|
75
|
+
constructor(matterportImportService, planService, route, router, zoneService, spaceService, navigationService, translate) {
|
|
76
|
+
this.matterportImportService = matterportImportService;
|
|
77
|
+
this.planService = planService;
|
|
78
|
+
this.route = route;
|
|
79
|
+
this.router = router;
|
|
80
|
+
this.zoneService = zoneService;
|
|
81
|
+
this.spaceService = spaceService;
|
|
82
|
+
this.navigationService = navigationService;
|
|
83
|
+
this.translate = translate;
|
|
84
|
+
}
|
|
85
|
+
ngOnDestroy() {
|
|
86
|
+
if (!this.loading) {
|
|
87
|
+
this.matterportImportService.removeFrame();
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
async ngOnInit() {
|
|
91
|
+
this.spaceID = this.route.snapshot.queryParams.spaceID;
|
|
92
|
+
this.currentSpace = await this.spaceService.getSpace(this.spaceID);
|
|
93
|
+
/** Menu nav bar */
|
|
94
|
+
this.setupMenuItems();
|
|
95
|
+
this.chosenPlan = this.planService.getChosenPlan();
|
|
96
|
+
if (this.chosenPlan) {
|
|
97
|
+
this.chosenPlanIsPdf = this.chosenPlan.annexe.includes('pdf');
|
|
98
|
+
this.launchViewer();
|
|
99
|
+
setTimeout(() => {
|
|
100
|
+
this.configureCanvas().then(() => {
|
|
101
|
+
this.panzoom = panzoom(this.canvas, {
|
|
102
|
+
bounds: true,
|
|
103
|
+
boundsPadding: 0,
|
|
104
|
+
maxZoom: 2.5,
|
|
105
|
+
minZoom: 0.1,
|
|
106
|
+
initialZoom: 1,
|
|
107
|
+
zoomSpeed: 0.02,
|
|
108
|
+
});
|
|
109
|
+
});
|
|
110
|
+
}, 500);
|
|
111
|
+
}
|
|
112
|
+
else {
|
|
113
|
+
this.router.navigate(['/dashboard/localisation', this.spaceID, 'plans']);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
/** **********************************************************************************************
|
|
117
|
+
* MENU NAV BAR
|
|
118
|
+
*********************************************************************************************** */
|
|
119
|
+
setupMenuItems() {
|
|
120
|
+
this.menuItems = [
|
|
121
|
+
{ label: 'Locations', url: '/localisation' },
|
|
122
|
+
{
|
|
123
|
+
label: this.currentSpace.name,
|
|
124
|
+
url: `/localisation/${this.spaceID}`,
|
|
125
|
+
},
|
|
126
|
+
{
|
|
127
|
+
label: 'Plans',
|
|
128
|
+
url: `/localisation/${this.currentSpace.id}/plans`,
|
|
129
|
+
},
|
|
130
|
+
{
|
|
131
|
+
label: 'Calibration',
|
|
132
|
+
url: `/localisation/${this.currentSpace.id}/plan-calibration?spaceID=${this.currentSpace.id}`,
|
|
133
|
+
},
|
|
134
|
+
];
|
|
135
|
+
}
|
|
136
|
+
/** **********************************************************************************************
|
|
137
|
+
* CANVAS
|
|
138
|
+
*********************************************************************************************** */
|
|
139
|
+
/** Display the plan */
|
|
140
|
+
async configureCanvas() {
|
|
141
|
+
/** Get canvas */
|
|
142
|
+
if (!this.canvas) {
|
|
143
|
+
const canvas = document.querySelector('#canvas');
|
|
144
|
+
this.canvas = canvas;
|
|
145
|
+
}
|
|
146
|
+
if (!this.chosenPlanIsPdf) {
|
|
147
|
+
const image = await getMetaForImage(this.chosenPlan.filepath);
|
|
148
|
+
/** Compute the new size for the canvas/matterport, base on the dimension of the plan, keeping the ratio */
|
|
149
|
+
const size = this.getSizeForCanvas(image.width, image.height);
|
|
150
|
+
/** Compute the plan zoom ratio (use for the calibration later) */
|
|
151
|
+
this.canvasZoom = size.w / image.width;
|
|
152
|
+
this.resizeView(size);
|
|
153
|
+
/** Draw Plan on the canvas */
|
|
154
|
+
this.drawImage(this.chosenPlan.filepath);
|
|
155
|
+
}
|
|
156
|
+
else {
|
|
157
|
+
// TODO
|
|
158
|
+
this.pdfToCanvas();
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
/** Update size of the canvas/matterport */
|
|
162
|
+
resizeView(size) {
|
|
163
|
+
this.canvasDiv.nativeElement.style.width = `${size.w}px`;
|
|
164
|
+
this.canvasDiv.nativeElement.style.height = `${size.h}px`;
|
|
165
|
+
this.canvas.style.width = `${size.w}px`;
|
|
166
|
+
this.canvas.style.height = `${size.h}px`;
|
|
167
|
+
this.canvas.width = size.w;
|
|
168
|
+
this.canvas.height = size.h;
|
|
169
|
+
this.canvasSize = size;
|
|
170
|
+
}
|
|
171
|
+
/** Draw something on the canvas */
|
|
172
|
+
drawImage(url, x = 0, y = 0, icone = false) {
|
|
173
|
+
const image = new Image();
|
|
174
|
+
const size = this.canvasSize;
|
|
175
|
+
const context = this.canvas.getContext('2d');
|
|
176
|
+
/** Flip the context, for symmetry */
|
|
177
|
+
// if (this.reflectV) {
|
|
178
|
+
// context.translate(size.w, 0);
|
|
179
|
+
// context.scale(-1, 1);
|
|
180
|
+
// }
|
|
181
|
+
// if (this.reflectH) {
|
|
182
|
+
// context.translate(0, size.h);
|
|
183
|
+
// context.scale(1, -1);
|
|
184
|
+
// }
|
|
185
|
+
let imageWidth = size.w;
|
|
186
|
+
let imageHeight = size.h;
|
|
187
|
+
image.addEventListener('load', () => {
|
|
188
|
+
if (icone) {
|
|
189
|
+
imageWidth = image.width;
|
|
190
|
+
imageHeight = image.height;
|
|
191
|
+
}
|
|
192
|
+
context.drawImage(image, 0, 0, image.width, image.height, x, y, imageWidth, imageHeight);
|
|
193
|
+
});
|
|
194
|
+
image.src = url;
|
|
195
|
+
}
|
|
196
|
+
/** Get the size for the canvas, based on the plan size, keeping the ratio */
|
|
197
|
+
getSizeForCanvas(w, h) {
|
|
198
|
+
let canvasW = this.canvasDiv.nativeElement.offsetWidth;
|
|
199
|
+
let canvasH = this.canvasDiv.nativeElement.offsetHeight;
|
|
200
|
+
const imageRatio = w / h;
|
|
201
|
+
const canvasRatio = canvasW / canvasH;
|
|
202
|
+
if (imageRatio > canvasRatio) {
|
|
203
|
+
canvasH = canvasW / imageRatio;
|
|
204
|
+
}
|
|
205
|
+
else {
|
|
206
|
+
canvasW = canvasH * imageRatio;
|
|
207
|
+
}
|
|
208
|
+
return { w: canvasW, h: canvasH };
|
|
209
|
+
}
|
|
210
|
+
/** [TODO] Convert a PDF to a Canvas */
|
|
211
|
+
async pdfToCanvas() {
|
|
212
|
+
const pdfjs = await import('pdfjs-dist/build/pdf');
|
|
213
|
+
const pdfjsWorker = await import('pdfjs-dist/build/pdf.worker.entry');
|
|
214
|
+
pdfjs.GlobalWorkerOptions.workerSrc = pdfjsWorker;
|
|
215
|
+
const pdf = await getDocument(this.chosenPlan.filepath)
|
|
216
|
+
.promise;
|
|
217
|
+
const page = await pdf.getPage(1);
|
|
218
|
+
const viewPortParameters = { scale: 1 };
|
|
219
|
+
const viewport = page.getViewport(viewPortParameters);
|
|
220
|
+
this.canvas.height = viewport.height;
|
|
221
|
+
this.canvas.width = viewport.width;
|
|
222
|
+
const size = this.getSizeForCanvas(viewport.width, viewport.height);
|
|
223
|
+
console.log(size);
|
|
224
|
+
this.canvasSize = size;
|
|
225
|
+
this.canvasZoom = size.w / viewport.width;
|
|
226
|
+
const context = this.canvas.getContext('2d');
|
|
227
|
+
const renderContext = {
|
|
228
|
+
canvasContext: context,
|
|
229
|
+
viewport,
|
|
230
|
+
};
|
|
231
|
+
const renderTask = page.render(renderContext).promise;
|
|
232
|
+
renderTask.then(() => console.log('Page rendered'));
|
|
233
|
+
// const res = canvas.toDataURL();
|
|
234
|
+
// if (pdf != null) pdf.destroy();
|
|
235
|
+
// return res;
|
|
236
|
+
}
|
|
237
|
+
/** User click to user Symmetry Vertical */
|
|
238
|
+
onReflectV() {
|
|
239
|
+
this.reflectV = !this.reflectV;
|
|
240
|
+
this.configureCanvas();
|
|
241
|
+
}
|
|
242
|
+
/** User click to user Symmetry Horizontal */
|
|
243
|
+
onReflectH() {
|
|
244
|
+
this.reflectH = !this.reflectH;
|
|
245
|
+
this.configureCanvas();
|
|
246
|
+
}
|
|
247
|
+
/** **********************************************************************************************
|
|
248
|
+
* MATTERPORT
|
|
249
|
+
*********************************************************************************************** */
|
|
250
|
+
/** Launch matterport */
|
|
251
|
+
async launchViewer() {
|
|
252
|
+
await this.matterportImportService.initSdkForModel(this.chosenPlan.model3d);
|
|
253
|
+
const { sdk } = this.matterportImportService;
|
|
254
|
+
this.floors = Object.values(this.matterportImportService.floors);
|
|
255
|
+
// console.log(this.floors);
|
|
256
|
+
setTimeout(async () => {
|
|
257
|
+
/** Move Floor mode */
|
|
258
|
+
sdk.Mode.moveTo(sdk.Mode.Mode.FLOORPLAN).then(async (nextMode) => {
|
|
259
|
+
/** Display the correct floor for the plan */
|
|
260
|
+
try {
|
|
261
|
+
const matterportFloor = this.chosenPlan.zone.metadata ?
|
|
262
|
+
JSON.parse(this.chosenPlan.zone.metadata).matterportFloorSequence : null;
|
|
263
|
+
await this.matterportImportService.moveToFloor(this.chosenPlan.zone.name, matterportFloor);
|
|
264
|
+
/** When the user try to change the view mode we set it back to floorpan */
|
|
265
|
+
sdk.on(sdk.Mode.Event.CHANGE_END, (oldMode, newMode) => {
|
|
266
|
+
if (newMode !== sdk.Mode.Mode.FLOORPLAN) {
|
|
267
|
+
sdk.Mode.moveTo(sdk.Mode.Mode.FLOORPLAN, {
|
|
268
|
+
transition: 'transition.instant',
|
|
269
|
+
});
|
|
270
|
+
}
|
|
271
|
+
});
|
|
272
|
+
}
|
|
273
|
+
catch {
|
|
274
|
+
console.log('couldnot move to floor');
|
|
275
|
+
}
|
|
276
|
+
});
|
|
277
|
+
/** We can display the matterport view now */
|
|
278
|
+
this.loading = false;
|
|
279
|
+
}, 1000);
|
|
280
|
+
/** Update current camera pose and rotation */
|
|
281
|
+
sdk.Camera.pose.subscribe((event) => {
|
|
282
|
+
/** We update only if the user is not changing the rotation with the <input> range, to not override the <input> value */
|
|
283
|
+
if (!this.isRotatingRange) {
|
|
284
|
+
this.rotation = event.rotation.y + 180;
|
|
285
|
+
this.prevRotation = this.rotation;
|
|
286
|
+
this.cameraPose = event;
|
|
287
|
+
}
|
|
288
|
+
});
|
|
289
|
+
}
|
|
290
|
+
/** When the <input> range, for rotation, change */
|
|
291
|
+
async onRotationChange() {
|
|
292
|
+
const rotationDelta = this.rotation - this.prevRotation;
|
|
293
|
+
this.prevRotation = this.rotation;
|
|
294
|
+
/** Send the rotationDelta to th queue event in order to be send to matterport */
|
|
295
|
+
this.rotatingQueueEvent.push(rotationDelta);
|
|
296
|
+
/** Start to process the queue, if it's the first event */
|
|
297
|
+
if (!this.isRotatingRange) {
|
|
298
|
+
this.isRotatingRange = true;
|
|
299
|
+
this.processRotatingQueueEvent();
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
/** Process the rotating event queue, send event one by one to matterport */
|
|
303
|
+
async processRotatingQueueEvent() {
|
|
304
|
+
const { sdk } = this.matterportImportService;
|
|
305
|
+
/** While the queue is not empty */
|
|
306
|
+
while (this.rotatingQueueEvent.length > 0) {
|
|
307
|
+
/** Rotate matterport by deltaRotation and remove event from queue */
|
|
308
|
+
await sdk.Camera.rotate(this.rotatingQueueEvent.shift(), 0, {
|
|
309
|
+
speed: 360,
|
|
310
|
+
});
|
|
311
|
+
}
|
|
312
|
+
/** When the queue is empty, then the user is not rotating with the <input> range anymore */
|
|
313
|
+
this.isRotatingRange = false;
|
|
314
|
+
}
|
|
315
|
+
/** **********************************************************************************************
|
|
316
|
+
* USER ACTIONS
|
|
317
|
+
*********************************************************************************************** */
|
|
318
|
+
/** Preview calibration */
|
|
319
|
+
async onPreview() {
|
|
320
|
+
this.preview = true;
|
|
321
|
+
/** Place sweeps */
|
|
322
|
+
this.onPlaceSweeps();
|
|
323
|
+
}
|
|
324
|
+
async calibrate() {
|
|
325
|
+
const [navigation] = this.currentNavigations;
|
|
326
|
+
const position = JSON.parse(navigation.position);
|
|
327
|
+
this.firstMarkPlan =
|
|
328
|
+
await this.matterportImportService.sdk.Renderer.getScreenPosition({
|
|
329
|
+
x: position.x,
|
|
330
|
+
y: position.y,
|
|
331
|
+
z: position.z,
|
|
332
|
+
});
|
|
333
|
+
this.secondMarkPlan =
|
|
334
|
+
await this.matterportImportService.sdk.Renderer.getScreenPosition({
|
|
335
|
+
x: position.x,
|
|
336
|
+
y: 0,
|
|
337
|
+
z: 0,
|
|
338
|
+
});
|
|
339
|
+
const deltaZVisit = 0 - position.z;
|
|
340
|
+
let deltaXPlan = this.secondMarkPlan.x - this.firstMarkPlan.x;
|
|
341
|
+
if (deltaXPlan === 0) {
|
|
342
|
+
// console.log("we moved along Y axis on Plan");
|
|
343
|
+
const deltaYPlan = this.secondMarkPlan.y - this.firstMarkPlan.y;
|
|
344
|
+
this.calibrage.nameYAxis = 'z';
|
|
345
|
+
this.calibrage.nameXAxis = 'x';
|
|
346
|
+
this.calibrage.offsetY = this.secondMarkPlan.y;
|
|
347
|
+
this.calibrage.scaleY = deltaYPlan / deltaZVisit;
|
|
348
|
+
}
|
|
349
|
+
else {
|
|
350
|
+
// console.log(" we moved along X axis on Plan");
|
|
351
|
+
this.calibrage.nameYAxis = 'x';
|
|
352
|
+
this.calibrage.nameXAxis = 'z';
|
|
353
|
+
this.calibrage.offsetX = this.secondMarkPlan.x;
|
|
354
|
+
this.calibrage.scaleX = deltaXPlan / deltaZVisit;
|
|
355
|
+
}
|
|
356
|
+
const thirdMarkPlan = await this.matterportImportService.sdk.Renderer.getScreenPosition({
|
|
357
|
+
x: 0,
|
|
358
|
+
y: 0,
|
|
359
|
+
z: position.z,
|
|
360
|
+
});
|
|
361
|
+
const deltaXVisit = 0 - position.x;
|
|
362
|
+
if (deltaXPlan === 0) {
|
|
363
|
+
// console.log(" we moved along X axis on Plan");
|
|
364
|
+
deltaXPlan = thirdMarkPlan.x - this.firstMarkPlan.x;
|
|
365
|
+
this.calibrage.offsetX = thirdMarkPlan.x;
|
|
366
|
+
this.calibrage.scaleX = deltaXPlan / deltaXVisit;
|
|
367
|
+
}
|
|
368
|
+
else {
|
|
369
|
+
const deltaYPlan = thirdMarkPlan.y - this.firstMarkPlan.y;
|
|
370
|
+
this.calibrage.offsetY = thirdMarkPlan.y;
|
|
371
|
+
this.calibrage.scaleY = deltaYPlan / deltaXVisit;
|
|
372
|
+
}
|
|
373
|
+
/** Take considiration of pan and zoom of plan on canvas */
|
|
374
|
+
const transformInfo = this.panzoom.getTransform();
|
|
375
|
+
const { scale, x, y } = transformInfo;
|
|
376
|
+
// console.log(transformInfo);
|
|
377
|
+
this.calibrage.offsetXPlan = x;
|
|
378
|
+
this.calibrage.offsetYPlan = y;
|
|
379
|
+
this.calibrage.scalePlan = scale;
|
|
380
|
+
console.log(this.calibrage);
|
|
381
|
+
}
|
|
382
|
+
/** Place sweeps */
|
|
383
|
+
async onPlaceSweeps() {
|
|
384
|
+
/** Display all scan */
|
|
385
|
+
const zone = await this.zoneService.getZone(this.chosenPlan.zoneID);
|
|
386
|
+
if (zone) {
|
|
387
|
+
this.currentZone = zone;
|
|
388
|
+
const navigations = await this.navigationService.getNavigationsForZone(this.currentZone);
|
|
389
|
+
this.currentNavigations = navigations;
|
|
390
|
+
await this.calibrate();
|
|
391
|
+
if (navigations.length > 0) {
|
|
392
|
+
for (const navigation of navigations) {
|
|
393
|
+
const testPosition = JSON.parse(navigation.position);
|
|
394
|
+
const positionX = this.calibrage.nameXAxis === 'x' ? testPosition.x : testPosition.z;
|
|
395
|
+
const positionY = this.calibrage.nameYAxis === 'x' ? testPosition.x : testPosition.z;
|
|
396
|
+
const testX = positionX * this.calibrage.scaleX + this.calibrage.offsetX;
|
|
397
|
+
const testY = positionY * this.calibrage.scaleY + this.calibrage.offsetY;
|
|
398
|
+
// console.log("test position GREEN", testX, testY);
|
|
399
|
+
const transformedX = (testX - this.calibrage.offsetXPlan) / this.calibrage.scalePlan; // we are undoing the pan and zoom
|
|
400
|
+
const transformedY = (testY - this.calibrage.offsetYPlan) / this.calibrage.scalePlan;
|
|
401
|
+
this.positions.push({
|
|
402
|
+
navID: navigation.id,
|
|
403
|
+
planID: this.chosenPlan.id,
|
|
404
|
+
x: transformedX,
|
|
405
|
+
y: transformedY,
|
|
406
|
+
});
|
|
407
|
+
const iconSize = 30 * this.calibrage.scalePlan;
|
|
408
|
+
const shift = iconSize / 2;
|
|
409
|
+
this.drawImage('https://api.iconify.design/mdi:adjust.svg?color=green&height=30&width=30', transformedX - shift, transformedY - shift, true);
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
/** Save calibration */
|
|
415
|
+
async onSave() {
|
|
416
|
+
if (this.currentZone) {
|
|
417
|
+
/** Normalize with the zoom */
|
|
418
|
+
// this.calibrage.offsetX /= this.canvasZoom;
|
|
419
|
+
// this.calibrage.offsetY /= this.canvasZoom;
|
|
420
|
+
// this.calibrage.x /= this.canvasZoom;
|
|
421
|
+
// this.calibrage.y /= this.canvasZoom;
|
|
422
|
+
this.calibrage.new = true;
|
|
423
|
+
this.calibrage.imgWidth = this.canvasSize.w;
|
|
424
|
+
this.calibrage.imgHeight = this.canvasSize.h;
|
|
425
|
+
await this.planService.updatePlan({
|
|
426
|
+
id: this.chosenPlan.id,
|
|
427
|
+
calibration: JSON.stringify(this.calibrage),
|
|
428
|
+
});
|
|
429
|
+
await Promise.all(this.positions.map(async (position) => {
|
|
430
|
+
const { navID } = position;
|
|
431
|
+
delete position.navID;
|
|
432
|
+
const nav = this.currentNavigations.find((_nav) => _nav.id === navID);
|
|
433
|
+
let positionsDataToUpdate;
|
|
434
|
+
if (nav.positionOnPlan) {
|
|
435
|
+
const positionOnPlan = nav.positionOnPlan.map((entry) => JSON.parse(entry));
|
|
436
|
+
const positionForCurrentPlan = positionOnPlan.find((entry) => entry.planID === this.chosenPlan.id);
|
|
437
|
+
if (positionForCurrentPlan) {
|
|
438
|
+
positionOnPlan.splice(positionOnPlan.indexOf(positionForCurrentPlan), 1, position);
|
|
439
|
+
}
|
|
440
|
+
else {
|
|
441
|
+
positionOnPlan.push(position);
|
|
442
|
+
}
|
|
443
|
+
positionsDataToUpdate = [...positionOnPlan];
|
|
444
|
+
}
|
|
445
|
+
else {
|
|
446
|
+
positionsDataToUpdate = [position];
|
|
447
|
+
}
|
|
448
|
+
// console.log(positionsDataToUpdate);
|
|
449
|
+
await this.navigationService.updateNavigation({
|
|
450
|
+
id: navID,
|
|
451
|
+
positionOnPlan: positionsDataToUpdate.map((entry) => JSON.stringify(entry)),
|
|
452
|
+
});
|
|
453
|
+
}));
|
|
454
|
+
}
|
|
455
|
+
this.matterportImportService.removeFrame();
|
|
456
|
+
this.router.navigate(['/dashboard/localisation', this.spaceID, 'plans']);
|
|
457
|
+
alert(this.translate.instant('calibration.success'));
|
|
458
|
+
}
|
|
459
|
+
/** Reset the canvas */
|
|
460
|
+
onReset() {
|
|
461
|
+
this.reflectH = false;
|
|
462
|
+
this.reflectV = false;
|
|
463
|
+
this.preview = false;
|
|
464
|
+
this.configureCanvas();
|
|
465
|
+
}
|
|
466
|
+
/** Cancel, leave */
|
|
467
|
+
onCancel() {
|
|
468
|
+
this.matterportImportService.removeFrame();
|
|
469
|
+
this.router.navigate(['/dashboard/localisation', this.spaceID, 'plans']);
|
|
470
|
+
alert(this.translate.instant('calibration.canceled'));
|
|
471
|
+
}
|
|
472
|
+
async onFloorClick(floor) {
|
|
473
|
+
this.currentFloor = floor;
|
|
474
|
+
await this.matterportImportService.moveToFloor(floor.id);
|
|
475
|
+
}
|
|
476
|
+
onActivateZoomChange() {
|
|
477
|
+
this.zoomCanBeChanged = !this.zoomCanBeChanged;
|
|
478
|
+
const iframe = document.querySelector('#viewer-frame');
|
|
479
|
+
if (iframe) {
|
|
480
|
+
iframe.style.zIndex = this.zoomCanBeChanged ? '1' : '0';
|
|
481
|
+
}
|
|
482
|
+
}
|
|
483
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: CalibrationComponent, deps: [{ token: i1.MatterportImportService }, { token: i1.PlanService }, { token: i2.ActivatedRoute }, { token: i2.Router }, { token: i1.ZoneService }, { token: i1.SpaceService }, { token: i1.NavigationService }, { token: i3.TranslateService }], target: i0.ɵɵFactoryTarget.Component });
|
|
484
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: CalibrationComponent, selector: "lib-calibration", viewQueries: [{ propertyName: "canvasDiv", first: true, predicate: ["canvasDiv"], descendants: true }], ngImport: i0, template: "<div class=\"row mt-3\">\r\n <div class=\"col\">\r\n <div class=\"m-3\">\r\n <lib-tab-navigation [menuItems]='menuItems'></lib-tab-navigation>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<div id=\"rowCanvas\">\r\n <div #canvasDiv id=\"canvasDiv\">\r\n\r\n <div id=\"viewer-frame\" [style.pointer-events]=\"zoomCanBeChanged?'auto':'none'\">\r\n <!-- <div class=\"blur\"></div> -->\r\n </div>\r\n <canvas id=\"canvas\" [ngStyle]=\"{'opacity': (preview||loading) ? '1' : 'calc(' + opacity + '/ 100)'}\"></canvas>\r\n </div>\r\n\r\n <div class=\"calibration-tools container-fluid\" *ngIf=\"!(preview || loading)\">\r\n <h1>{{'Calibration tool' | translate}}</h1>\r\n <div class=\"tool\">\r\n <div class=\"row ms-0 me-0 legend\">\r\n <div class=\"legend-bar-indicator\" [ngStyle]=\"{'opacity': 'calc(' + (-(opacity-100)+10) + '/ 100)'}\">\r\n {{'Less' | translate}}</div>\r\n <div class=\"legend-title\">{{'Plan Opacity' | translate }}</div>\r\n <div class=\"legend-bar-indicator\" [ngStyle]=\"{'opacity': 'calc(' + (opacity+10) + '/ 100)'}\">{{'More' |\r\n translate}}</div>\r\n </div>\r\n <div class=\"row ms-0 me-0 \">\r\n <input [disabled]=\"false\" [ngModelOptions]=\"{standalone: true}\" [(ngModel)]=\"opacity\" type=\"range\"\r\n class=\"form-range\" min=\"0\" max=\"100\" value=\"50\" id=\"opacity\">\r\n </div>\r\n </div>\r\n <div class=\"tool\">\r\n <div class=\"row ms-0 me-0 \">\r\n <div class=\"label-legend\">{{'Change Visit Floor' | translate}}</div>\r\n <div ngbDropdown class=\"d-inline-block ms-3\">\r\n <button class=\"btn btn-label-file rounded-pill\" id=\"dropdownBasic1\" ngbDropdownToggle>\r\n {{currentFloor ? currentFloor.id : ('Floor' | translate) }}</button>\r\n <div ngbDropdownMenu aria-labelledby=\"dropdownBasic1\">\r\n <button ngbDropdownItem *ngFor=\"let floor of floors\" (click)=\"onFloorClick(floor)\">\r\n {{ floor.name.length > 0 ? floor.name : ('Floor ' + floor.id) }}\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n </div>\r\n <div class=\"tool\">\r\n <div class=\"row ms-0 me-0 \">\r\n <div class=\"tool-checkbox-container\">\r\n <div class=\"tool-checkbox-subcontainer\">\r\n <div class=\"label-legend me-3\">{{'Pan/Zoom Visit' | translate}} {{zoomCanBeChanged ? \"ON\" :\r\n \"OFF\"}}\r\n </div>\r\n <input type=\"checkbox\" (change)=\"onActivateZoomChange()\" style=\"margin-top: 5px;\">\r\n </div>\r\n <div class=\"card border-warning mb-3 mt-3\" *ngIf=\"zoomCanBeChanged\">\r\n <div class=\"card-body text-warning\">\r\n <h5 class=\"card-title\">{{\"calibration.wait-message\" | translate}}</h5>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"action\">\r\n <button type=\"button\" class=\"btn btn-outline-primary rounded-pill\" (click)=\"onPreview()\"\r\n [disabled]=\"zoomCanBeChanged\">{{'Preview' | translate}}</button>\r\n <button type=\"button\" class=\"btn btn-outline-primary rounded-pill\" (click)=\"onCancel()\">{{'Cancel' |\r\n translate}}</button>\r\n\r\n </div>\r\n\r\n </div>\r\n <div class=\"calibration-tools container-fluid\" *ngIf=\"preview\">\r\n <h1>{{'Validation' | translate}}</h1>\r\n <div class=\"action\">\r\n <button type=\"button\" class=\"btn btn-outline-primary rounded-pill\" (click)=\"onSave()\">{{'Validate' |\r\n translate}}</button>\r\n <button type=\"button\" class=\"btn btn-outline-primary rounded-pill\" (click)=\"onReset()\">{{'Reset' |\r\n translate}}</button>\r\n <button type=\"button\" class=\"btn btn-outline-primary rounded-pill\" (click)=\"onCancel()\">{{'Cancel' |\r\n translate}}</button>\r\n\r\n </div>\r\n </div>\r\n\r\n\r\n <div class=\"calibration-tools container-fluid\" *ngIf=\"loading\">\r\n <h3>{{\"Waiting for Matterport\" | translate}}...</h3>\r\n <div class=\"d-flex justify-content-center\">\r\n <div class=\"spinner-border\" role=\"status\">\r\n <span class=\"visually-hidden\">Loading...</span>\r\n </div>\r\n </div>\r\n\r\n </div>\r\n</div>", styles: [".button-visit{display:none;height:30px;width:30px;position:absolute;background:url(https://api.iconify.design/mdi:map-marker-check.svg?color=red&height=30) no-repeat scroll 0 0 transparent;border:none}#button-visit-left{left:350px;top:550px}#button-visit-right{left:500px;top:600px}#rowCanvas{display:flex}#canvasDiv{height:100%;width:100%;position:relative}#canvas{width:100%;height:100%;opacity:.5}#viewer-frame{top:0;position:absolute;width:100%;height:100%}.calibration-tools{margin-left:20px;width:400px;background-color:#fff;z-index:11;border:1px solid var(--smarterplan-primary);padding:7px}.form-range{width:100%}.tool{margin-top:20px}.tool .legend{justify-content:space-between;position:relative;margin-bottom:5px}.tool .legend-title{font-size:1.2rem;color:var(--smarterplan-primary);margin:auto;width:100%;font-weight:700;display:flex;justify-content:center}.tool .legend-bar-indicator{width:15%!important}.tool .label-legend{color:var(--smarterplan-primary);font-size:1.1rem;max-width:55%}.tool .tool-checkbox-container{display:flex;flex-direction:column}.tool .tool-checkbox-container .tool-checkbox-subcontainer{display:flex}.blur{width:150px;height:52px;position:absolute;background-color:#1e2023;bottom:0}.symmetry{padding:5px;border:solid 2px;border-radius:10px;color:var(--smarterplan-primary);margin:25px 10px;cursor:pointer}.symmetry:hover{color:var(--smarterplan-primary)}.symmetry-row{justify-content:center}.action{margin-top:30px;display:flex;justify-content:space-evenly}h1{color:var(--smarterplan-primary);text-align:center;margin-bottom:20px}h3{color:var(--smarterplan-primary);text-align:center;margin-bottom:10px}.btn-outline-primary.disabled{background-color:var(--smarterplan-orange)!important}\n"], dependencies: [{ kind: "directive", type: i4.NgbDropdown, selector: "[ngbDropdown]", inputs: ["autoClose", "dropdownClass", "open", "placement", "popperOptions", "container", "display"], outputs: ["openChange"], exportAs: ["ngbDropdown"] }, { kind: "directive", type: i4.NgbDropdownToggle, selector: "[ngbDropdownToggle]" }, { kind: "directive", type: i4.NgbDropdownMenu, selector: "[ngbDropdownMenu]" }, { kind: "directive", type: i4.NgbDropdownItem, selector: "[ngbDropdownItem]", inputs: ["disabled"] }, { kind: "directive", type: i5.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i5.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: i6.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i6.RangeValueAccessor, selector: "input[type=range][formControlName],input[type=range][formControl],input[type=range][ngModel]" }, { kind: "directive", type: i6.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i6.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i7.TabNavigationComponent, selector: "lib-tab-navigation", inputs: ["menuItems"], outputs: ["onGoBack"] }, { kind: "pipe", type: i3.TranslatePipe, name: "translate" }] });
|
|
485
|
+
}
|
|
486
|
+
export { CalibrationComponent };
|
|
487
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: CalibrationComponent, decorators: [{
|
|
488
|
+
type: Component,
|
|
489
|
+
args: [{ selector: 'lib-calibration', template: "<div class=\"row mt-3\">\r\n <div class=\"col\">\r\n <div class=\"m-3\">\r\n <lib-tab-navigation [menuItems]='menuItems'></lib-tab-navigation>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<div id=\"rowCanvas\">\r\n <div #canvasDiv id=\"canvasDiv\">\r\n\r\n <div id=\"viewer-frame\" [style.pointer-events]=\"zoomCanBeChanged?'auto':'none'\">\r\n <!-- <div class=\"blur\"></div> -->\r\n </div>\r\n <canvas id=\"canvas\" [ngStyle]=\"{'opacity': (preview||loading) ? '1' : 'calc(' + opacity + '/ 100)'}\"></canvas>\r\n </div>\r\n\r\n <div class=\"calibration-tools container-fluid\" *ngIf=\"!(preview || loading)\">\r\n <h1>{{'Calibration tool' | translate}}</h1>\r\n <div class=\"tool\">\r\n <div class=\"row ms-0 me-0 legend\">\r\n <div class=\"legend-bar-indicator\" [ngStyle]=\"{'opacity': 'calc(' + (-(opacity-100)+10) + '/ 100)'}\">\r\n {{'Less' | translate}}</div>\r\n <div class=\"legend-title\">{{'Plan Opacity' | translate }}</div>\r\n <div class=\"legend-bar-indicator\" [ngStyle]=\"{'opacity': 'calc(' + (opacity+10) + '/ 100)'}\">{{'More' |\r\n translate}}</div>\r\n </div>\r\n <div class=\"row ms-0 me-0 \">\r\n <input [disabled]=\"false\" [ngModelOptions]=\"{standalone: true}\" [(ngModel)]=\"opacity\" type=\"range\"\r\n class=\"form-range\" min=\"0\" max=\"100\" value=\"50\" id=\"opacity\">\r\n </div>\r\n </div>\r\n <div class=\"tool\">\r\n <div class=\"row ms-0 me-0 \">\r\n <div class=\"label-legend\">{{'Change Visit Floor' | translate}}</div>\r\n <div ngbDropdown class=\"d-inline-block ms-3\">\r\n <button class=\"btn btn-label-file rounded-pill\" id=\"dropdownBasic1\" ngbDropdownToggle>\r\n {{currentFloor ? currentFloor.id : ('Floor' | translate) }}</button>\r\n <div ngbDropdownMenu aria-labelledby=\"dropdownBasic1\">\r\n <button ngbDropdownItem *ngFor=\"let floor of floors\" (click)=\"onFloorClick(floor)\">\r\n {{ floor.name.length > 0 ? floor.name : ('Floor ' + floor.id) }}\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n </div>\r\n <div class=\"tool\">\r\n <div class=\"row ms-0 me-0 \">\r\n <div class=\"tool-checkbox-container\">\r\n <div class=\"tool-checkbox-subcontainer\">\r\n <div class=\"label-legend me-3\">{{'Pan/Zoom Visit' | translate}} {{zoomCanBeChanged ? \"ON\" :\r\n \"OFF\"}}\r\n </div>\r\n <input type=\"checkbox\" (change)=\"onActivateZoomChange()\" style=\"margin-top: 5px;\">\r\n </div>\r\n <div class=\"card border-warning mb-3 mt-3\" *ngIf=\"zoomCanBeChanged\">\r\n <div class=\"card-body text-warning\">\r\n <h5 class=\"card-title\">{{\"calibration.wait-message\" | translate}}</h5>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"action\">\r\n <button type=\"button\" class=\"btn btn-outline-primary rounded-pill\" (click)=\"onPreview()\"\r\n [disabled]=\"zoomCanBeChanged\">{{'Preview' | translate}}</button>\r\n <button type=\"button\" class=\"btn btn-outline-primary rounded-pill\" (click)=\"onCancel()\">{{'Cancel' |\r\n translate}}</button>\r\n\r\n </div>\r\n\r\n </div>\r\n <div class=\"calibration-tools container-fluid\" *ngIf=\"preview\">\r\n <h1>{{'Validation' | translate}}</h1>\r\n <div class=\"action\">\r\n <button type=\"button\" class=\"btn btn-outline-primary rounded-pill\" (click)=\"onSave()\">{{'Validate' |\r\n translate}}</button>\r\n <button type=\"button\" class=\"btn btn-outline-primary rounded-pill\" (click)=\"onReset()\">{{'Reset' |\r\n translate}}</button>\r\n <button type=\"button\" class=\"btn btn-outline-primary rounded-pill\" (click)=\"onCancel()\">{{'Cancel' |\r\n translate}}</button>\r\n\r\n </div>\r\n </div>\r\n\r\n\r\n <div class=\"calibration-tools container-fluid\" *ngIf=\"loading\">\r\n <h3>{{\"Waiting for Matterport\" | translate}}...</h3>\r\n <div class=\"d-flex justify-content-center\">\r\n <div class=\"spinner-border\" role=\"status\">\r\n <span class=\"visually-hidden\">Loading...</span>\r\n </div>\r\n </div>\r\n\r\n </div>\r\n</div>", styles: [".button-visit{display:none;height:30px;width:30px;position:absolute;background:url(https://api.iconify.design/mdi:map-marker-check.svg?color=red&height=30) no-repeat scroll 0 0 transparent;border:none}#button-visit-left{left:350px;top:550px}#button-visit-right{left:500px;top:600px}#rowCanvas{display:flex}#canvasDiv{height:100%;width:100%;position:relative}#canvas{width:100%;height:100%;opacity:.5}#viewer-frame{top:0;position:absolute;width:100%;height:100%}.calibration-tools{margin-left:20px;width:400px;background-color:#fff;z-index:11;border:1px solid var(--smarterplan-primary);padding:7px}.form-range{width:100%}.tool{margin-top:20px}.tool .legend{justify-content:space-between;position:relative;margin-bottom:5px}.tool .legend-title{font-size:1.2rem;color:var(--smarterplan-primary);margin:auto;width:100%;font-weight:700;display:flex;justify-content:center}.tool .legend-bar-indicator{width:15%!important}.tool .label-legend{color:var(--smarterplan-primary);font-size:1.1rem;max-width:55%}.tool .tool-checkbox-container{display:flex;flex-direction:column}.tool .tool-checkbox-container .tool-checkbox-subcontainer{display:flex}.blur{width:150px;height:52px;position:absolute;background-color:#1e2023;bottom:0}.symmetry{padding:5px;border:solid 2px;border-radius:10px;color:var(--smarterplan-primary);margin:25px 10px;cursor:pointer}.symmetry:hover{color:var(--smarterplan-primary)}.symmetry-row{justify-content:center}.action{margin-top:30px;display:flex;justify-content:space-evenly}h1{color:var(--smarterplan-primary);text-align:center;margin-bottom:20px}h3{color:var(--smarterplan-primary);text-align:center;margin-bottom:10px}.btn-outline-primary.disabled{background-color:var(--smarterplan-orange)!important}\n"] }]
|
|
490
|
+
}], ctorParameters: function () { return [{ type: i1.MatterportImportService }, { type: i1.PlanService }, { type: i2.ActivatedRoute }, { type: i2.Router }, { type: i1.ZoneService }, { type: i1.SpaceService }, { type: i1.NavigationService }, { type: i3.TranslateService }]; }, propDecorators: { canvasDiv: [{
|
|
491
|
+
type: ViewChild,
|
|
492
|
+
args: ['canvasDiv']
|
|
493
|
+
}] } });
|
|
494
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2FsaWJyYXRpb24uY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvbmd4LXNtYXJ0ZXJwbGFuLWxvY2F0aW9ucy9zcmMvbGliL2NvbXBvbmVudHMvcGxhbnMvY2FsaWJyYXRpb24vY2FsaWJyYXRpb24uY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvbmd4LXNtYXJ0ZXJwbGFuLWxvY2F0aW9ucy9zcmMvbGliL2NvbXBvbmVudHMvcGxhbnMvY2FsaWJyYXRpb24vY2FsaWJyYXRpb24uY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFNBQVMsRUFBc0IsU0FBUyxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBR3pFLE9BQU8sRUFBRSxXQUFXLEVBQW9CLE1BQU0sWUFBWSxDQUFDO0FBQzNELHFEQUFxRDtBQUNyRCxPQUFPLEVBVUgsZUFBZSxHQUVsQixNQUFNLG1DQUFtQyxDQUFDO0FBQzNDLE9BQU8sT0FBTyxNQUFNLFNBQVMsQ0FBQzs7Ozs7Ozs7O0FBRTlCLE1BS2Esb0JBQW9CO0lBcUZqQjtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBM0ZaLHFDQUFxQztJQUNyQyxTQUFTLEdBQWUsRUFBRSxDQUFDO0lBRTNCLG9CQUFvQjtJQUNwQixNQUFNLENBQUM7SUFFUCxrRUFBa0U7SUFDMUMsU0FBUyxDQUFhO0lBRTlDLDZDQUE2QztJQUM3QyxVQUFVLENBQTRCO0lBRXRDLHFDQUFxQztJQUNyQyxVQUFVLEdBQUcsQ0FBQyxDQUFDO0lBRWYsb0NBQW9DO0lBQ3BDLE9BQU8sR0FBVyxFQUFFLENBQUM7SUFFckIsNEZBQTRGO0lBQzVGLFFBQVEsR0FBVyxHQUFHLENBQUM7SUFFdkIseUhBQXlIO0lBQ3pILFlBQVksR0FBVyxHQUFHLENBQUM7SUFFM0IsMEJBQTBCO0lBQzFCLFVBQVUsQ0FBTTtJ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QzNDLElBQUksQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLENBQUMseUJBQXlCLEVBQUUsSUFBSSxDQUFDLE9BQU8sRUFBRSxPQUFPLENBQUMsQ0FBQyxDQUFDO1FBQ3pFLEtBQUssQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLE9BQU8sQ0FBQyxzQkFBc0IsQ0FBQyxDQUFDLENBQUM7SUFDMUQsQ0FBQztJQUVELEtBQUssQ0FBQyxZQUFZLENBQUMsS0FBSztRQUNwQixJQUFJLENBQUMsWUFBWSxHQUFHLEtBQUssQ0FBQztRQUMxQixNQUFNLElBQUksQ0FBQyx1QkFBdUIsQ0FBQyxXQUFXLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQyxDQUFDO0lBQzdELENBQUM7SUFFRCxvQkFBb0I7UUFDaEIsSUFBSSxDQUFDLGdCQUFnQixHQUFHLENBQUMsSUFBSSxDQUFDLGdCQUFnQixDQUFDO1FBQy9DLE1BQU0sTUFBTSxHQUFHLFFBQVEsQ0FBQyxhQUFhLENBQUMsZUFBZSxDQUFnQixDQUFDO1FBQ3RFLElBQUksTUFBTSxFQUFFO1lBQ1IsTUFBTSxDQUFDLEtBQUssQ0FBQyxNQUFNLEdBQUcsSUFBSSxDQUFDLGdCQUFnQixDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQztTQUMzRDtJQUNMLENBQUM7d0dBaGtCUSxvQkFBb0I7NEZBQXBCLG9CQUFvQiwrSkN6QmpDLGl6SkFpR007O1NEeEVPLG9CQUFvQjs0RkFBcEIsb0JBQW9CO2tCQUxoQyxTQUFTOytCQUNJLGlCQUFpQjs4U0FZSCxTQUFTO3NCQUFoQyxTQUFTO3VCQUFDLFdBQVciLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb21wb25lbnQsIEVsZW1lbnRSZWYsIE9uSW5pdCwgVmlld0NoaWxkIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcbmltcG9ydCB7IEFjdGl2YXRlZFJvdXRlLCBSb3V0ZXIgfSBmcm9tICdAYW5ndWxhci9yb3V0ZXInO1xyXG5pbXBvcnQgeyBUcmFuc2xhdGVTZXJ2aWNlIH0gZnJvbSAnQG5neC10cmFuc2xhdGUvY29yZSc7XHJcbmltcG9ydCB7IGdldERvY3VtZW50LCBQREZEb2N1bWVudFByb3h5IH0gZnJvbSAncGRmanMtZGlzdCc7XHJcbi8vIGltcG9ydCB7IFBERkRvY3VtZW50UHJveHkgfSBmcm9tICduZzItcGRmLXZpZXdlcic7XHJcbmltcG9ydCB7XHJcbiAgICBab25lLFxyXG4gICAgTWVudUl0ZW0sXHJcbiAgICBQbGFuLFxyXG4gICAgU3BhY2UsXHJcbiAgICBOYXZpZ2F0aW9uLFxyXG4gICAgUGxhblNlcnZpY2UsXHJcbiAgICBab25lU2VydmljZSxcclxuICAgIFNwYWNlU2VydmljZSxcclxuICAgIE5hdmlnYXRpb25TZXJ2aWNlLFxyXG4gICAgZ2V0TWV0YUZvckltYWdlLFxyXG4gICAgTWF0dGVycG9ydEltcG9ydFNlcnZpY2UsXHJcbn0gZnJvbSAnQHNtYXJ0ZXJwbGFuL25neC1zbWFydGVycGxhbi1jb3JlJztcclxuaW1wb3J0IHBhbnpvb20gZnJvbSAncGFuem9vbSc7XHJcblxyXG5AQ29tcG9uZW50KHtcclxuICAgIHNlbGVjdG9yOiAnbGliLWNhbGlicmF0aW9uJyxcclxuICAgIHRlbXBsYXRlVXJsOiAnLi9jYWxpYnJhdGlvbi5jb21wb25lbnQuaHRtbCcsXHJcbiAgICBzdHlsZVVybHM6IFsnLi9jYWxpYnJhdGlvbi5jb21wb25lbnQuc2NzcyddLFxyXG59KVxyXG5leHBvcnQgY2xhc3MgQ2FsaWJyYXRpb25Db21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQge1xyXG4gICAgLyoqIEl0ZW0gdG8gZGlzcGxheSBmb3IgdGhlIG5hdmJhciAqL1xyXG4gICAgbWVudUl0ZW1zOiBNZW51SXRlbVtdID0gW107XHJcblxyXG4gICAgLyoqIENhbnZhcyAoUGxhbikgKi9cclxuICAgIGNhbnZhcztcclxuXHJcbiAgICAvKiogQ2FudmFzRGl2IChEaXYgdGhhdCBjb250YWluIHRoZSBjYW52YXMgKyBtYXR0ZXJwb3J0IGlmcmFtZSkgKi9cclxuICAgIEBWaWV3Q2hpbGQoJ2NhbnZhc0RpdicpIGNhbnZhc0RpdjogRWxlbWVudFJlZjtcclxuXHJcbiAgICAvKiogU2l6ZSBvZiB0aGUgY2FudmFzICYgbWF0dGVycG9ydCBpZnJhbWUgKi9cclxuICAgIGNhbnZhc1NpemU6IHsgdzogbnVtYmVyOyBoOiBudW1iZXI7IH07XHJcblxyXG4gICAgLyoqIFpvb20gcmF0aW8gb2YgdGhlIGNhbnZhcy9wbGFuICAqL1xyXG4gICAgY2FudmFzWm9vbSA9IDA7XHJcblxyXG4gICAgLyoqIE9wYWNpdHkgZm9yIG1hdHRlcnBvcnQgaWZyYW1lICovXHJcbiAgICBvcGFjaXR5OiBudW1iZXIgPSA1MDtcclxuXHJcbiAgICAvKiogQ3VycmVudCByb3RhdGlvbiBmb3IgbWF0dGVycG9ydCwgWzAtMzYwXSwgIG1hdHRlcnBvcnQgcm90YXRpb24gaXMgYmluZCB0byBpbnB1dCByYW5nZSAqL1xyXG4gICAgcm90YXRpb246IG51bWJlciA9IDE4MDtcclxuXHJcbiAgICAvKiogUHJldmlvdXMgcm90YXRpb24sIHVzZSB0byBjYWxjdWxhdGUgdGhlIGRlbHRhUm90YXRpb24gdG8gcm90YXRlLCB3aGVuIHVzZXIgY2hhbmdlIHJvdGF0aW9uIHZhbHVlIHVzaW5nIHJhbmdlIGlucHV0ICovXHJcbiAgICBwcmV2Um90YXRpb246IG51bWJlciA9IDE4MDtcclxuXHJcbiAgICAvKiogQ3VycmVudCBDYW1lcmEgUG9zZSAqL1xyXG4gICAgY2FtZXJhUG9zZTogYW55O1xyXG5cclxuICAgIC8qKiBUcnVlIHdoZW4gdGhlIHVzZXIgaXMgY3VycmVudGx5IHJvdGF0aW5nIHdpdGggdGhlIGlucHV0IHJhbmdlLCB0aGUgbWF0dGVycG9ydCByb3RhdGlvbiBldmVudHMgd2lsbCBiZSBpZ25vcmVkICovXHJcbiAgICBpc1JvdGF0aW5nUmFuZ2U6IGJvb2xlYW4gPSBmYWxzZTtcclxuXHJcbiAgICAvKiogUm90YXRpbmcgcXVldWUgZXZlbnQgdG8gc2VuZCB0byBtYXR0ZXJwb3J0ICovXHJcbiAgICByb3RhdGluZ1F1ZXVlRXZlbnQ6IG51bWJlcltdID0gW107XHJcblxyXG4gICAgLyoqIFRydWUgd2hlbiBWZXJ0aWNhbCBzeW1tZXRyeSBpcyBlbmFibGVkICovXHJcbiAgICByZWZsZWN0ViA9IGZhbHNlO1xyXG5cclxuICAgIC8qKiBUcnVlIHdoZW4gSG9yaXpvbnRhbCBzeW1tZXRyeSBpcyBlbmFibGVkICovXHJcbiAgICByZWZsZWN0SCA9IGZhbHNlO1xyXG5cclxuICAgIGNob3NlblBsYW46IFBsYW47XHJcblxyXG4gICAgc3BhY2VJRDogc3RyaW5nO1xyXG5cclxuICAgIGN1cnJlbnRTcGFjZTogU3BhY2U7XHJcblxyXG4gICAgY3VycmVudFpvbmU6IFpvbmU7XHJcblxyXG4gICAgY2hvc2VuUGxhbklzUGRmID0gZmFsc2U7XHJcblxyXG4gICAgLyoqIEZpcnN0IFBvaW50IGluIHZpc2l0LCB1c2VkIHRvIGRldGVybWluZSB0aGUgY2FsaWJyYXRpb24gICovXHJcbiAgICBmaXJzdE1hcmtWaXNpdCA9IHsgeDogMCwgeTogMCB9O1xyXG5cclxuICAgIC8qKiBTZWNvbmQgUG9pbnQgaW4gdmlzaXQsIHVzZWQgdG8gZGV0ZXJtaW5lIHRoZSBjYWxpYnJhdGlvbiAgKi9cclxuICAgIHNlY29uZE1hcmtWaXNpdCA9IHsgeDogMC41LCB5OiAwLjUgfTtcclxuXHJcbiAgICAvKiogRXF1aXZhbGVudCBvZiAnZmlyc3RNYXJrVmlzaXQnIGluIGNhbnZhcyAgKi9cclxuICAgIGZpcnN0TWFya1BsYW46IHsgeDogbnVtYmVyOyB5OiBudW1iZXI7IH0gPSB7IHg6IDAsIHk6IDAgfTtcclxuXHJcbiAgICAvKiogRXF1aXZhbGVudCBvZiAnc2Vjb25kTWFya1Zpc2l0JyBpbiBjYW52YXMgICovXHJcbiAgICBzZWNvbmRNYXJrUGxhbjogeyB4OiBudW1iZXI7IHk6IG51bWJlcjsgfSA9IHsgeDogMCwgeTogMCB9O1xyXG5cclxuICAgIC8qKiBDYWxpYnJhdGlvbiByZXN1bHQsIChvZmZzZXRYLCBvZmZzZXRZLCB4LCB5KSAqL1xyXG4gICAgY2FsaWJyYWdlOiBhbnkgPSB7fTtcclxuXHJcbiAgICAvKiogSXMgaW4gcHJldmlldyBtb2RlIChzZWUgc2NhbiByZXN1bHQpICovXHJcbiAgICBwcmV2aWV3ID0gZmFsc2U7XHJcblxyXG4gICAgLyoqIE1hdHRlcnBvcnQgaXMgbG9hZGluZyAqL1xyXG4gICAgbG9hZGluZyA9IHRydWU7XHJcblxyXG4gICAgLyogZm9yIHBhbiBhbmQgem9vbSBvZiBjYW52YXMgKi9cclxuICAgIHBhbnpvb206IGFueTtcclxuXHJcbiAgICBjdXJyZW50TmF2aWdhdGlvbnM6IE5hdmlnYXRpb25bXTtcclxuXHJcbiAgICBwb3NpdGlvbnM6IHsgbmF2SUQ6IHN0cmluZzsgcGxhbklEOiBzdHJpbmc7IHg6IG51bWJlcjsgeTogbnVtYmVyOyB9W10gPSBbXTtcclxuXHJcbiAgICBmbG9vcnM6IGFueVtdID0gW107XHJcblxyXG4gICAgY3VycmVudEZsb29yO1xyXG5cclxuICAgIHpvb21DYW5CZUNoYW5nZWQ6IGJvb2xlYW4gPSBmYWxzZTtcclxuXHJcbiAgICBjb25zdHJ1Y3RvcihcclxuICAgICAgICBwcml2YXRlIG1hdHRlcnBvcnRJbXBvcnRTZXJ2aWNlOiBNYXR0ZXJwb3J0SW1wb3J0U2VydmljZSxcclxuICAgICAgICBwcml2YXRlIHBsYW5TZXJ2aWNlOiBQbGFuU2VydmljZSxcclxuICAgICAgICBwcml2YXRlIHJvdXRlOiBBY3RpdmF0ZWRSb3V0ZSxcclxuICAgICAgICBwcml2YXRlIHJvdXRlcjogUm91dGVyLFxyXG4gICAgICAgIHByaXZhdGUgem9uZVNlcnZpY2U6IFpvbmVTZXJ2aWNlLFxyXG4gICAgICAgIHByaXZhdGUgc3BhY2VTZXJ2aWNlOiBTcGFjZVNlcnZpY2UsXHJcbiAgICAgICAgcHJpdmF0ZSBuYXZpZ2F0aW9uU2VydmljZTogTmF2aWdhdGlvblNlcnZpY2UsXHJcbiAgICAgICAgcHJpdmF0ZSB0cmFuc2xhdGU6IFRyYW5zbGF0ZVNlcnZpY2VcclxuICAgICkgeyB9XHJcblxyXG4gICAgbmdPbkRlc3Ryb3koKTogdm9pZCB7XHJcbiAgICAgICAgaWYgKCF0aGlzLmxvYWRpbmcpIHtcclxuICAgICAgICAgICAgdGhpcy5tYXR0ZXJwb3J0SW1wb3J0U2VydmljZS5yZW1vdmVGcmFtZSgpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBhc3luYyBuZ09uSW5pdCgpOiBQcm9taXNlPHZvaWQ+IHtcclxuICAgICAgICB0aGlzLnNwYWNlSUQgPSB0aGlzLnJvdXRlLnNuYXBzaG90LnF1ZXJ5UGFyYW1zLnNwYWNlSUQ7XHJcbiAgICAgICAgdGhpcy5jdXJyZW50U3BhY2UgPSBhd2FpdCB0aGlzLnNwYWNlU2VydmljZS5nZXRTcGFjZSh0aGlzLnNwYWNlSUQpO1xyXG5cclxuICAgICAgICAvKiogTWVudSBuYXYgYmFyICovXHJcbiAgICAgICAgdGhpcy5zZXR1cE1lbnVJdGVtcygpO1xyXG5cclxuICAgICAgICB0aGlzLmNob3NlblBsYW4gPSB0aGlzLnBsYW5TZXJ2aWNlLmdldENob3NlblBsYW4oKTtcclxuXHJcbiAgICAgICAgaWYgKHRoaXMuY2hvc2VuUGxhbikge1xyXG4gICAgICAgICAgICB0aGlzLmNob3NlblBsYW5Jc1BkZiA9IHRoaXMuY2hvc2VuUGxhbi5hbm5leGUuaW5jbHVkZXMoJ3BkZicpO1xyXG4gICAgICAgICAgICB0aGlzLmxhdW5jaFZpZXdlcigpO1xyXG4gICAgICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHtcclxuICAgICAgICAgICAgICAgIHRoaXMuY29uZmlndXJlQ2FudmFzKCkudGhlbigoKSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5wYW56b29tID0gcGFuem9vbSh0aGlzLmNhbnZhcywge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBib3VuZHM6IHRydWUsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGJvdW5kc1BhZGRpbmc6IDAsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIG1heFpvb206IDIuNSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgbWluWm9vbTogMC4xLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBpbml0aWFsWm9vbTogMSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgem9vbVNwZWVkOiAwLjAyLFxyXG4gICAgICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgIH0sIDUwMCk7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgdGhpcy5yb3V0ZXIubmF2aWdhdGUoWycvZGFzaGJvYXJkL2xvY2FsaXNhdGlvbicsIHRoaXMuc3BhY2VJRCwgJ3BsYW5zJ10pO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICAvKiogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKlxyXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1FTlUgTkFWIEJBUlxyXG4gICAgICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqICovXHJcbiAgICBzZXR1cE1lbnVJdGVtcygpIHtcclxuICAgICAgICB0aGlzLm1lbnVJdGVtcyA9IFtcclxuICAgICAgICAgICAgeyBsYWJlbDogJ0xvY2F0aW9ucycsIHVybDogJy9sb2NhbGlzYXRpb24nIH0sXHJcbiAgICAgICAgICAgIHtcclxuICAgICAgICAgICAgICAgIGxhYmVsOiB0aGlzLmN1cnJlbnRTcGFjZS5uYW1lLFxyXG4gICAgICAgICAgICAgICAgdXJsOiBgL2xvY2FsaXNhdGlvbi8ke3RoaXMuc3BhY2VJRH1gLFxyXG4gICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICB7XHJcbiAgICAgICAgICAgICAgICBsYWJlbDogJ1BsYW5zJyxcclxuICAgICAgICAgICAgICAgIHVybDogYC9sb2NhbGlzYXRpb24vJHt0aGlzLmN1cnJlbnRTcGFjZS5pZH0vcGxhbnNgLFxyXG4gICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICB7XHJcbiAgICAgICAgICAgICAgICBsYWJlbDogJ0NhbGlicmF0aW9uJyxcclxuICAgICAgICAgICAgICAgIHVybDogYC9sb2NhbGlzYXRpb24vJHt0aGlzLmN1cnJlbnRTcGFjZS5pZH0vcGxhbi1jYWxpYnJhdGlvbj9zcGFjZUlEPSR7dGhpcy5jdXJyZW50U3BhY2UuaWR9YCxcclxuICAgICAgICAgICAgfSxcclxuICAgICAgICBdO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqXHJcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDQU5WQVNcclxuICAgICAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiAqL1xyXG5cclxuICAgIC8qKiBEaXNwbGF5IHRoZSBwbGFuICovXHJcbiAgICBhc3luYyBjb25maWd1cmVDYW52YXMoKSB7XHJcbiAgICAgICAgLyoqIEdldCBjYW52YXMgKi9cclxuICAgICAgICBpZiAoIXRoaXMuY2FudmFzKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IGNhbnZhcyA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyNjYW52YXMnKSBhcyBIVE1MQ2FudmFzRWxlbWVudDtcclxuICAgICAgICAgICAgdGhpcy5jYW52YXMgPSBjYW52YXM7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAoIXRoaXMuY2hvc2VuUGxhbklzUGRmKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IGltYWdlID0gYXdhaXQgZ2V0TWV0YUZvckltYWdlKHRoaXMuY2hvc2VuUGxhbi5maWxlcGF0aCk7XHJcbiAgICAgICAgICAgIC8qKiBDb21wdXRlIHRoZSBuZXcgc2l6ZSBmb3IgdGhlIGNhbnZhcy9tYXR0ZXJwb3J0LCBiYXNlIG9uIHRoZSBkaW1lbnNpb24gb2YgdGhlIHBsYW4sIGtlZXBpbmcgdGhlIHJhdGlvICovXHJcbiAgICAgICAgICAgIGNvbnN0IHNpemUgPSB0aGlzLmdldFNpemVGb3JDYW52YXMoaW1hZ2Uud2lkdGgsIGltYWdlLmhlaWdodCk7XHJcblxyXG4gICAgICAgICAgICAvKiogQ29tcHV0ZSB0aGUgcGxhbiB6b29tIHJhdGlvICh1c2UgZm9yIHRoZSBjYWxpYnJhdGlvbiBsYXRlcikgKi9cclxuICAgICAgICAgICAgdGhpcy5jYW52YXNab29tID0gc2l6ZS53IC8gaW1hZ2Uud2lkdGg7XHJcblxyXG4gICAgICAgICAgICB0aGlzLnJlc2l6ZVZpZXcoc2l6ZSk7XHJcblxyXG4gICAgICAgICAgICAvKiogRHJhdyBQbGFuIG9uIHRoZSBjYW52YXMgKi9cclxuICAgICAgICAgICAgdGhpcy5kcmF3SW1hZ2UodGhpcy5jaG9zZW5QbGFuLmZpbGVwYXRoKTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAvLyBUT0RPXHJcbiAgICAgICAgICAgIHRoaXMucGRmVG9DYW52YXMoKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgLyoqIFVwZGF0ZSBzaXplIG9mIHRoZSBjYW52YXMvbWF0dGVycG9ydCAqL1xyXG4gICAgcmVzaXplVmlldyhzaXplKSB7XHJcbiAgICAgICAgdGhpcy5jYW52YXNEaXYubmF0aXZlRWxlbWVudC5zdHlsZS53aWR0aCA9IGAke3NpemUud31weGA7XHJcbiAgICAgICAgdGhpcy5jYW52YXNEaXYubmF0aXZlRWxlbWVudC5zdHlsZS5oZWlnaHQgPSBgJHtzaXplLmh9cHhgO1xyXG4gICAgICAgIHRoaXMuY2FudmFzLnN0eWxlLndpZHRoID0gYCR7c2l6ZS53fXB4YDtcclxuICAgICAgICB0aGlzLmNhbnZhcy5zdHlsZS5oZWlnaHQgPSBgJHtzaXplLmh9cHhgO1xyXG4gICAgICAgIHRoaXMuY2FudmFzLndpZHRoID0gc2l6ZS53O1xyXG4gICAgICAgIHRoaXMuY2FudmFzLmhlaWdodCA9IHNpemUuaDtcclxuICAgICAgICB0aGlzLmNhbnZhc1NpemUgPSBzaXplO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKiBEcmF3IHNvbWV0aGluZyBvbiB0aGUgY2FudmFzICovXHJcbiAgICBkcmF3SW1hZ2UodXJsOiBzdHJpbmcsIHggPSAwLCB5ID0gMCwgaWNvbmUgPSBmYWxzZSkge1xyXG4gICAgICAgIGNvbnN0IGltYWdlID0gbmV3IEltYWdlKCk7XHJcbiAgICAgICAgY29uc3Qgc2l6ZSA9IHRoaXMuY2FudmFzU2l6ZTtcclxuICAgICAgICBjb25zdCBjb250ZXh0ID0gdGhpcy5jYW52YXMuZ2V0Q29udGV4dCgnMmQnKTtcclxuXHJcbiAgICAgICAgLyoqIEZsaXAgdGhlIGNvbnRleHQsIGZvciBzeW1tZXRyeSAqL1xyXG4gICAgICAgIC8vIGlmICh0aGlzLnJlZmxlY3RWKSB7XHJcbiAgICAgICAgLy8gICAgIGNvbnRleHQudHJhbnNsYXRlKHNpemUudywgMCk7XHJcbiAgICAgICAgLy8gICAgIGNvbnRleHQuc2NhbGUoLTEsIDEpO1xyXG4gICAgICAgIC8vIH1cclxuICAgICAgICAvLyBpZiAodGhpcy5yZWZsZWN0SCkge1xyXG4gICAgICAgIC8vICAgICBjb250ZXh0LnRyYW5zbGF0ZSgwLCBzaXplLmgpO1xyXG4gICAgICAgIC8vICAgICBjb250ZXh0LnNjYWxlKDEsIC0xKTtcclxuICAgICAgICAvLyB9XHJcblxyXG4gICAgICAgIGxldCBpbWFnZVdpZHRoID0gc2l6ZS53O1xyXG4gICAgICAgIGxldCBpbWFnZUhlaWdodCA9IHNpemUuaDtcclxuICAgICAgICBpbWFnZS5hZGRFdmVudExpc3RlbmVyKCdsb2FkJywgKCkgPT4ge1xyXG4gICAgICAgICAgICBpZiAoaWNvbmUpIHtcclxuICAgICAgICAgICAgICAgIGltYWdlV2lkdGggPSBpbWFnZS53aWR0aDtcclxuICAgICAgICAgICAgICAgIGltYWdlSGVpZ2h0ID0gaW1hZ2UuaGVpZ2h0O1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGNvbnRleHQuZHJhd0ltYWdlKFxyXG4gICAgICAgICAgICAgICAgaW1hZ2UsXHJcbiAgICAgICAgICAgICAgICAwLFxyXG4gICAgICAgICAgICAgICAgMCxcclxuICAgICAgICAgICAgICAgIGltYWdlLndpZHRoLFxyXG4gICAgICAgICAgICAgICAgaW1hZ2UuaGVpZ2h0LFxyXG4gICAgICAgICAgICAgICAgeCxcclxuICAgICAgICAgICAgICAgIHksXHJcbiAgICAgICAgICAgICAgICBpbWFnZVdpZHRoLFxyXG4gICAgICAgICAgICAgICAgaW1hZ2VIZWlnaHRcclxuICAgICAgICAgICAgKTtcclxuICAgICAgICB9KTtcclxuICAgICAgICBpbWFnZS5zcmMgPSB1cmw7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqIEdldCB0aGUgc2l6ZSBmb3IgdGhlIGNhbnZhcywgYmFzZWQgb24gdGhlIHBsYW4gc2l6ZSwga2VlcGluZyB0aGUgcmF0aW8gKi9cclxuICAgIGdldFNpemVGb3JDYW52YXModywgaCkge1xyXG4gICAgICAgIGxldCBjYW52YXNXID0gdGhpcy5jYW52YXNEaXYubmF0aXZlRWxlbWVudC5vZmZzZXRXaWR0aDtcclxuICAgICAgICBsZXQgY2FudmFzSCA9IHRoaXMuY2FudmFzRGl2Lm5hdGl2ZUVsZW1lbnQub2Zmc2V0SGVpZ2h0O1xyXG5cclxuICAgICAgICBjb25zdCBpbWFnZVJhdGlvID0gdyAvIGg7XHJcbiAgICAgICAgY29uc3QgY2FudmFzUmF0aW8gPSBjYW52YXNXIC8gY2FudmFzSDtcclxuXHJcbiAgICAgICAgaWYgKGltYWdlUmF0aW8gPiBjYW52YXNSYXRpbykge1xyXG4gICAgICAgICAgICBjYW52YXNIID0gY2FudmFzVyAvIGltYWdlUmF0aW87XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgY2FudmFzVyA9IGNhbnZhc0ggKiBpbWFnZVJhdGlvO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4geyB3OiBjYW52YXNXLCBoOiBjYW52YXNIIH07XHJcbiAgICB9XHJcblxyXG4gICAgLyoqIFtUT0RPXSBDb252ZXJ0IGEgUERGIHRvIGEgQ2FudmFzICovXHJcbiAgICBhc3luYyBwZGZUb0NhbnZhcygpIHtcclxuICAgICAgICBjb25zdCBwZGZqcyA9IGF3YWl0IGltcG9ydCgncGRmanMtZGlzdC9idWlsZC9wZGYnKTtcclxuICAgICAgICBjb25zdCBwZGZqc1dvcmtlciA9IGF3YWl0IGltcG9ydCgncGRmanMtZGlzdC9idWlsZC9wZGYud29ya2VyLmVudHJ5Jyk7XHJcblxyXG4gICAgICAgIHBkZmpzLkdsb2JhbFdvcmtlck9wdGlvbnMud29ya2VyU3JjID0gcGRmanNXb3JrZXI7XHJcblxyXG4gICAgICAgIGNvbnN0IHBkZjogUERGRG9jdW1lbnRQcm94eSA9IGF3YWl0IGdldERvY3VtZW50KHRoaXMuY2hvc2VuUGxhbi5maWxlcGF0aClcclxuICAgICAgICAgICAgLnByb21pc2U7XHJcbiAgICAgICAgY29uc3QgcGFnZSA9IGF3YWl0IHBkZi5nZXRQYWdlKDEpO1xyXG5cclxuICAgICAgICBjb25zdCB2aWV3UG9ydFBhcmFtZXRlcnMgPSB7IHNjYWxlOiAxIH07XHJcbiAgICAgICAgY29uc3Qgdmlld3BvcnQgPSBwYWdlLmdldFZpZXdwb3J0KHZpZXdQb3J0UGFyYW1ldGVycyk7XHJcblxyXG4gICAgICAgIHRoaXMuY2FudmFzLmhlaWdodCA9IHZpZXdwb3J0LmhlaWdodDtcclxuICAgICAgICB0aGlzLmNhbnZhcy53aWR0aCA9IHZpZXdwb3J0LndpZHRoO1xyXG5cclxuICAgICAgICBjb25zdCBzaXplID0gdGhpcy5nZXRTaXplRm9yQ2FudmFzKHZpZXdwb3J0LndpZHRoLCB2aWV3cG9ydC5oZWlnaHQpO1xyXG4gICAgICAgIGNvbnNvbGUubG9nKHNpemUpO1xyXG4gICAgICAgIHRoaXMuY2FudmFzU2l6ZSA9IHNpemU7XHJcblxyXG4gICAgICAgIHRoaXMuY2FudmFzWm9vbSA9IHNpemUudyAvIHZpZXdwb3J0LndpZHRoO1xyXG5cclxuICAgICAgICBjb25zdCBjb250ZXh0ID0gdGhpcy5jYW52YXMuZ2V0Q29udGV4dCgnMmQnKSBhcyBDYW52YXNSZW5kZXJpbmdDb250ZXh0MkQ7XHJcbiAgICAgICAgY29uc3QgcmVuZGVyQ29udGV4dCA9IHtcclxuICAgICAgICAgICAgY2FudmFzQ29udGV4dDogY29udGV4dCxcclxuICAgICAgICAgICAgdmlld3BvcnQsXHJcbiAgICAgICAgfTtcclxuICAgICAgICBjb25zdCByZW5kZXJUYXNrID0gcGFnZS5yZW5kZXIocmVuZGVyQ29udGV4dCkucHJvbWlzZTtcclxuXHJcbiAgICAgICAgcmVuZGVyVGFzay50aGVuKCgpID0+IGNvbnNvbGUubG9nKCdQYWdlIHJlbmRlcmVkJykpO1xyXG5cclxuICAgICAgICAvLyBjb25zdCByZXMgPSBjYW52YXMudG9EYXRhVVJMKCk7XHJcbiAgICAgICAgLy8gaWYgKHBkZiAhPSBudWxsKSBwZGYuZGVzdHJveSgpO1xyXG4gICAgICAgIC8vIHJldHVybiByZXM7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqIFVzZXIgY2xpY2sgdG8gdXNlciBTeW1tZXRyeSBWZXJ0aWNhbCAqL1xyXG4gICAgb25SZWZsZWN0VigpIHtcclxuICAgICAgICB0aGlzLnJlZmxlY3RWID0gIXRoaXMucmVmbGVjdFY7XHJcbiAgICAgICAgdGhpcy5jb25maWd1cmVDYW52YXMoKTtcclxuICAgIH1cclxuXHJcbiAgICAvKiogVXNlciBjbGljayB0byB1c2VyIFN5bW1ldHJ5IEhvcml6b250YWwgKi9cclxuICAgIG9uUmVmbGVjdEgoKSB7XHJcbiAgICAgICAgdGhpcy5yZWZsZWN0SCA9ICF0aGlzLnJlZmxlY3RIO1xyXG4gICAgICAgIHRoaXMuY29uZmlndXJlQ2FudmFzKCk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKipcclxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1BVFRFUlBPUlRcclxuICAgICAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiAqL1xyXG5cclxuICAgIC8qKiBMYXVuY2ggbWF0dGVycG9ydCAqL1xyXG4gICAgYXN5bmMgbGF1bmNoVmlld2VyKCkge1xyXG4gICAgICAgIGF3YWl0IHRoaXMubWF0dGVycG9ydEltcG9ydFNlcnZpY2UuaW5pdFNka0Zvck1vZGVsKHRoaXMuY2hvc2VuUGxhbi5tb2RlbDNkKTtcclxuXHJcbiAgICAgICAgY29uc3QgeyBzZGsgfSA9IHRoaXMubWF0dGVycG9ydEltcG9ydFNlcnZpY2U7XHJcbiAgICAgICAgdGhpcy5mbG9vcnMgPSBPYmplY3QudmFsdWVzKHRoaXMubWF0dGVycG9ydEltcG9ydFNlcnZpY2UuZmxvb3JzKTtcclxuICAgICAgICAvLyBjb25zb2xlLmxvZyh0aGlzLmZsb29ycyk7XHJcbiAgICAgICAgc2V0VGltZW91dChhc3luYyAoKSA9PiB7XHJcbiAgICAgICAgICAgIC8qKiBNb3ZlIEZsb29yIG1vZGUgKi9cclxuICAgICAgICAgICAgc2RrLk1vZGUubW92ZVRvKHNkay5Nb2RlLk1vZGUuRkxPT1JQTEFOKS50aGVuKGFzeW5jIChuZXh0TW9kZSkgPT4ge1xyXG4gICAgICAgICAgICAgICAgLyoqIERpc3BsYXkgdGhlIGNvcnJlY3QgZmxvb3IgZm9yIHRoZSBwbGFuICovXHJcbiAgICAgICAgICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IG1hdHRlcnBvcnRGbG9vciA9IHRoaXMuY2hvc2VuUGxhbi56b25lLm1ldGFkYXRhID9cclxuICAgICAgICAgICAgICAgICAgICAgICAgSlNPTi5wYXJzZSh0aGlzLmNob3NlblBsYW4uem9uZS5tZXRhZGF0YSkubWF0dGVycG9ydEZsb29yU2VxdWVuY2UgOiBudWxsO1xyXG4gICAgICAgICAgICAgICAgICAgIGF3YWl0IHRoaXMubWF0dGVycG9ydEltcG9ydFNlcnZpY2UubW92ZVRvRmxvb3IodGhpcy5jaG9zZW5QbGFuLnpvbmUubmFtZSwgbWF0dGVycG9ydEZsb29yKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgLyoqIFdoZW4gdGhlIHVzZXIgdHJ5IHRvIGNoYW5nZSB0aGUgdmlldyBtb2RlIHdlIHNldCBpdCBiYWNrIHRvIGZsb29ycGFuICovXHJcbiAgICAgICAgICAgICAgICAgICAgc2RrLm9uKHNkay5Nb2RlLkV2ZW50LkNIQU5HRV9FTkQsIChvbGRNb2RlLCBuZXdNb2RlKSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChuZXdNb2RlICE9PSBzZGsuTW9kZS5Nb2RlLkZMT09SUExBTikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc2RrLk1vZGUubW92ZVRvKHNkay5Nb2RlLk1vZGUuRkxPT1JQTEFOLCB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJhbnNpdGlvbjogJ3RyYW5zaXRpb24uaW5zdGFudCcsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgfSBjYXRjaCB7XHJcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS5sb2coJ2NvdWxkbm90IG1vdmUgdG8gZmxvb3InKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfSk7XHJcblxyXG4gICAgICAgICAgICAvKiogV2UgY2FuIGRpc3BsYXkgdGhlIG1hdHRlcnBvcnQgdmlldyBub3cgKi9cclxuICAgICAgICAgICAgdGhpcy5sb2FkaW5nID0gZmFsc2U7XHJcbiAgICAgICAgfSwgMTAwMCk7XHJcblxyXG4gICAgICAgIC8qKiBVcGRhdGUgY3VycmVudCBjYW1lcmEgcG9zZSBhbmQgcm90YXRpb24gKi9cclxuICAgICAgICBzZGsuQ2FtZXJhLnBvc2Uuc3Vic2NyaWJlKChldmVudCkgPT4ge1xyXG4gICAgICAgICAgICAvKiogV2UgdXBkYXRlIG9ubHkgaWYgdGhlIHVzZXIgaXMgbm90IGNoYW5naW5nIHRoZSByb3RhdGlvbiB3aXRoIHRoZSA8aW5wdXQ+IHJhbmdlLCB0byBub3Qgb3ZlcnJpZGUgdGhlIDxpbnB1dD4gdmFsdWUgKi9cclxuICAgICAgICAgICAgaWYgKCF0aGlzLmlzUm90YXRpbmdSYW5nZSkge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5yb3RhdGlvbiA9IGV2ZW50LnJvdGF0aW9uLnkgKyAxODA7XHJcbiAgICAgICAgICAgICAgICB0aGlzLnByZXZSb3RhdGlvbiA9IHRoaXMucm90YXRpb247XHJcbiAgICAgICAgICAgICAgICB0aGlzLmNhbWVyYVBvc2UgPSBldmVudDtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKiBXaGVuIHRoZSA8aW5wdXQ+IHJhbmdlLCBmb3Igcm90YXRpb24sIGNoYW5nZSAqL1xyXG4gICAgYXN5bmMgb25Sb3RhdGlvbkNoYW5nZSgpIHtcclxuICAgICAgICBjb25zdCByb3RhdGlvbkRlbHRhID0gdGhpcy5yb3RhdGlvbiAtIHRoaXMucHJldlJvdGF0aW9uO1xyXG4gICAgICAgIHRoaXMucHJldlJvdGF0aW9uID0gdGhpcy5yb3RhdGlvbjtcclxuXHJcbiAgICAgICAgLyoqIFNlbmQgdGhlIHJvdGF0aW9uRGVsdGEgdG8gdGggcXVldWUgZXZlbnQgaW4gb3JkZXIgdG8gYmUgc2VuZCB0byBtYXR0ZXJwb3J0ICovXHJcbiAgICAgICAgdGhpcy5yb3RhdGluZ1F1ZXVlRXZlbnQucHVzaChyb3RhdGlvbkRlbHRhKTtcclxuXHJcbiAgICAgICAgLyoqIFN0YXJ0IHRvIHByb2Nlc3MgdGhlIHF1ZXVlLCBpZiBpdCdzIHRoZSBmaXJzdCBldmVudCAqL1xyXG4gICAgICAgIGlmICghdGhpcy5pc1JvdGF0aW5nUmFuZ2UpIHtcclxuICAgICAgICAgICAgdGhpcy5pc1JvdGF0aW5nUmFuZ2UgPSB0cnVlO1xyXG4gICAgICAgICAgICB0aGlzLnByb2Nlc3NSb3RhdGluZ1F1ZXVlRXZlbnQoKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgLyoqIFByb2Nlc3MgdGhlIHJvdGF0aW5nIGV2ZW50IHF1ZXVlLCBzZW5kIGV2ZW50IG9uZSBieSBvbmUgdG8gbWF0dGVycG9ydCAgKi9cclxuICAgIGFzeW5jIHByb2Nlc3NSb3RhdGluZ1F1ZXVlRXZlbnQoKSB7XHJcbiAgICAgICAgY29uc3QgeyBzZGsgfSA9IHRoaXMubWF0dGVycG9ydEltcG9ydFNlcnZpY2U7XHJcblxyXG4gICAgICAgIC8qKiBXaGlsZSB0aGUgcXVldWUgaXMgbm90IGVtcHR5ICovXHJcbiAgICAgICAgd2hpbGUgKHRoaXMucm90YXRpbmdRdWV1ZUV2ZW50Lmxlbmd0aCA+IDApIHtcclxuICAgICAgICAgICAgLyoqIFJvdGF0ZSBtYXR0ZXJwb3J0IGJ5IGRlbHRhUm90YXRpb24gYW5kIHJlbW92ZSBldmVudCBmcm9tIHF1ZXVlICovXHJcbiAgICAgICAgICAgIGF3YWl0IHNkay5DYW1lcmEucm90YXRlKHRoaXMucm90YXRpbmdRdWV1ZUV2ZW50LnNoaWZ0KCksIDAsIHtcclxuICAgICAgICAgICAgICAgIHNwZWVkOiAzNjAsXHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLyoqIFdoZW4gdGhlIHF1ZXVlIGlzIGVtcHR5LCB0aGVuIHRoZSB1c2VyIGlzIG5vdCByb3RhdGluZyB3aXRoIHRoZSA8aW5wdXQ+IHJhbmdlIGFueW1vcmUgKi9cclxuICAgICAgICB0aGlzLmlzUm90YXRpbmdSYW5nZSA9IGZhbHNlO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqXHJcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVU0VSIEFDVElPTlNcclxuICAgICAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiAqL1xyXG5cclxuICAgIC8qKiBQcmV2aWV3IGNhbGlicmF0aW9uICovXHJcbiAgICBhc3luYyBvblByZXZpZXcoKSB7XHJcbiAgICAgICAgdGhpcy5wcmV2aWV3ID0gdHJ1ZTtcclxuICAgICAgICAvKiogUGxhY2Ugc3dlZXBzICovXHJcbiAgICAgICAgdGhpcy5vblBsYWNlU3dlZXBzKCk7XHJcbiAgICB9XHJcblxyXG4gICAgYXN5bmMgY2FsaWJyYXRlKCkge1xyXG4gICAgICAgIGNvbnN0IFtuYXZpZ2F0aW9uXSA9IHRoaXMuY3VycmVudE5hdmlnYXRpb25zO1xyXG4gICAgICAgIGNvbnN0IHBvc2l0aW9uID0gSlNPTi5wYXJzZShuYXZpZ2F0aW9uLnBvc2l0aW9uKTtcclxuICAgICAgICB0aGlzLmZpcnN0TWFya1BsYW4gPVxyXG4gICAgICAgICAgICBhd2FpdCB0aGlzLm1hdHRlcnBvcnRJbXBvcnRTZXJ2aWNlLnNkay5SZW5kZXJlci5nZXRTY3JlZW5Qb3NpdGlvbih7XHJcbiAgICAgICAgICAgICAgICB4OiBwb3NpdGlvbi54LFxyXG4gICAgICAgICAgICAgICAgeTogcG9zaXRpb24ueSxcclxuICAgICAgICAgICAgICAgIHo6IHBvc2l0aW9uLnosXHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIHRoaXMuc2Vjb25kTWFya1BsYW4gPVxyXG4gICAgICAgICAgICBhd2FpdCB0aGlzLm1hdHRlcnBvcnRJbXBvcnRTZXJ2aWNlLnNkay5SZW5kZXJlci5nZXRTY3JlZW5Qb3NpdGlvbih7XHJcbiAgICAgICAgICAgICAgICB4OiBwb3NpdGlvbi54LFxyXG4gICAgICAgICAgICAgICAgeTogMCxcclxuICAgICAgICAgICAgICAgIHo6IDAsXHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIGNvbnN0IGRlbHRhWlZpc2l0ID0gMCAtIHBvc2l0aW9uLno7XHJcbiAgICAgICAgbGV0IGRlbHRhWFBsYW4gPSB0aGlzLnNlY29uZE1hcmtQbGFuLnggLSB0aGlzLmZpcnN0TWFya1BsYW4ueDtcclxuICAgICAgICBpZiAoZGVsdGFYUGxhbiA9PT0gMCkge1xyXG4gICAgICAgICAgICAvLyBjb25zb2xlLmxvZyhcIndlIG1vdmVkIGFsb25nIFkgYXhpcyBvbiBQbGFuXCIpO1xyXG4gICAgICAgICAgICBjb25zdCBkZWx0YVlQbGFuID0gdGhpcy5zZWNvbmRNYXJrUGxhbi55IC0gdGhpcy5maXJzdE1hcmtQbGFuLnk7XHJcbiAgICAgICAgICAgIHRoaXMuY2FsaWJyYWdlLm5hbWVZQXhpcyA9ICd6JztcclxuICAgICAgICAgICAgdGhpcy5jYWxpYnJhZ2UubmFtZVhBeGlzID0gJ3gnO1xyXG4gICAgICAgICAgICB0aGlzLmNhbGlicmFnZS5vZmZzZXRZID0gdGhpcy5zZWNvbmRNYXJrUGxhbi55O1xyXG4gICAgICAgICAgICB0aGlzLmNhbGlicmFnZS5zY2FsZVkgPSBkZWx0YVlQbGFuIC8gZGVsdGFaVmlzaXQ7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgLy8gY29uc29sZS5sb2coXCIgd2UgbW92ZWQgYWxvbmcgWCBheGlzIG9uIFBsYW5cIik7XHJcbiAgICAgICAgICAgIHRoaXMuY2FsaWJyYWdlLm5hbWVZQXhpcyA9ICd4JztcclxuICAgICAgICAgICAgdGhpcy5jYWxpYnJhZ2UubmFtZVhBeGlzID0gJ3onO1xyXG4gICAgICAgICAgICB0aGlzLmNhbGlicmFnZS5vZmZzZXRYID0gdGhpcy5zZWNvbmRNYXJrUGxhbi54O1xyXG4gICAgICAgICAgICB0aGlzLmNhbGlicmFnZS5zY2FsZVggPSBkZWx0YVhQbGFuIC8gZGVsdGFaVmlzaXQ7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGNvbnN0IHRoaXJkTWFya1BsYW4gPVxyXG4gICAgICAgICAgICBhd2FpdCB0aGlzLm1hdHRlcnBvcnRJbXBvcnRTZXJ2aWNlLnNkay5SZW5kZXJlci5nZXRTY3JlZW5Qb3NpdGlvbih7XHJcbiAgICAgICAgICAgICAgICB4OiAwLFxyXG4gICAgICAgICAgICAgICAgeTogMCxcclxuICAgICAgICAgICAgICAgIHo6IHBvc2l0aW9uLnosXHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIGNvbnN0IGRlbHRhWFZpc2l0ID0gMCAtIHBvc2l0aW9uLng7XHJcbiAgICAgICAgaWYgKGRlbHRhWFBsYW4gPT09IDApIHtcclxuICAgICAgICAgICAgLy8gY29uc29sZS5sb2coXCIgd2UgbW92ZWQgYWxvbmcgWCBheGlzIG9uIFBsYW5cIik7XHJcbiAgICAgICAgICAgIGRlbHRhWFBsYW4gPSB0aGlyZE1hcmtQbGFuLnggLSB0aGlzLmZpcnN0TWFya1BsYW4ueDtcclxuICAgICAgICAgICAgdGhpcy5jYWxpYnJhZ2Uub2Zmc2V0WCA9IHRoaXJkTWFya1BsYW4ueDtcclxuICAgICAgICAgICAgdGhpcy5jYWxpYnJhZ2Uuc2NhbGVYID0gZGVsdGFYUGxhbiAvIGRlbHRhWFZpc2l0O1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIGNvbnN0IGRlbHRhWVBsYW4gPSB0aGlyZE1hcmtQbGFuLnkgLSB0aGlzLmZpcnN0TWFya1BsYW4ueTtcclxuICAgICAgICAgICAgdGhpcy5jYWxpYnJhZ2Uub2Zmc2V0WSA9IHRoaXJkTWFya1BsYW4ueTtcclxuICAgICAgICAgICAgdGhpcy5jYWxpYnJhZ2Uuc2NhbGVZID0gZGVsdGFZUGxhbiAvIGRlbHRhWFZpc2l0O1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLyoqIFRha2UgY29uc2lkaXJhdGlvbiBvZiBwYW4gYW5kIHpvb20gb2YgcGxhbiBvbiBjYW52YXMgKi9cclxuICAgICAgICBjb25zdCB0cmFuc2Zvcm1JbmZvID0gdGhpcy5wYW56b29tLmdldFRyYW5zZm9ybSgpO1xyXG4gICAgICAgIGNvbnN0IHsgc2NhbGUsIHgsIHkgfSA9IHRyYW5zZm9ybUluZm87XHJcbiAgICAgICAgLy8gY29uc29sZS5sb2codHJhbnNmb3JtSW5mbyk7XHJcbiAgICAgICAgdGhpcy5jYWxpYnJhZ2Uub2Zmc2V0WFBsYW4gPSB4O1xyXG4gICAgICAgIHRoaXMuY2FsaWJyYWdlLm9mZnNldFlQbGFuID0geTtcclxuICAgICAgICB0aGlzLmNhbGlicmFnZS5zY2FsZVBsYW4gPSBzY2FsZTtcclxuICAgICAgICBjb25zb2xlLmxvZyh0aGlzLmNhbGlicmFnZSk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqIFBsYWNlIHN3ZWVwcyAqL1xyXG4gICAgYXN5bmMgb25QbGFjZVN3ZWVwcygpIHtcclxuICAgICAgICAvKiogRGlzcGxheSBhbGwgc2NhbiAqL1xyXG4gICAgICAgIGNvbnN0IHpvbmUgPSBhd2FpdCB0aGlzLnpvbmVTZXJ2aWNlLmdldFpvbmUodGhpcy5jaG9zZW5QbGFuLnpvbmVJRCk7XHJcblxyXG4gICAgICAgIGlmICh6b25lKSB7XHJcbiAgICAgICAgICAgIHRoaXMuY3VycmVudFpvbmUgPSB6b25lO1xyXG4gICAgICAgICAgICBjb25zdCBuYXZpZ2F0aW9ucyA9IGF3YWl0IHRoaXMubmF2aWdhdGlvblNlcnZpY2UuZ2V0TmF2aWdhdGlvbnNGb3Jab25lKFxyXG4gICAgICAgICAgICAgICAgdGhpcy5jdXJyZW50Wm9uZVxyXG4gICAgICAgICAgICApO1xyXG4gICAgICAgICAgICB0aGlzLmN1cnJlbnROYXZpZ2F0aW9ucyA9IG5hdmlnYXRpb25zO1xyXG4gICAgICAgICAgICBhd2FpdCB0aGlzLmNhbGlicmF0ZSgpO1xyXG4gICAgICAgICAgICBpZiAobmF2aWdhdGlvbnMubGVuZ3RoID4gMCkge1xyXG4gICAgICAgICAgICAgICAgZm9yIChjb25zdCBuYXZpZ2F0aW9uIG9mIG5hdmlnYXRpb25zKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgdGVzdFBvc2l0aW9uID0gSlNPTi5wYXJzZShuYXZpZ2F0aW9uLnBvc2l0aW9uKTtcclxuICAgICAgICAgICAgICAgICAgICBjb25zdCBwb3NpdGlvblggPVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmNhbGlicmFnZS5uYW1lWEF4aXMgPT09ICd4JyA/IHRlc3RQb3NpdGlvbi54IDogdGVzdFBvc2l0aW9uLno7XHJcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgcG9zaXRpb25ZID1cclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5jYWxpYnJhZ2UubmFtZVlBeGlzID09PSAneCcgPyB0ZXN0UG9zaXRpb24ueCA6IHRlc3RQb3NpdGlvbi56O1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHRlc3RYID1cclxuICAgICAgICAgICAgICAgICAgICAgICAgcG9zaXRpb25YICogdGhpcy5jYWxpYnJhZ2Uuc2NhbGVYICsgdGhpcy5jYWxpYnJhZ2Uub2Zmc2V0WDtcclxuICAgICAgICAgICAgICAgICAgICBjb25zdCB0ZXN0WSA9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHBvc2l0aW9uWSAqIHRoaXMuY2FsaWJyYWdlLnNjYWxlWSArIHRoaXMuY2FsaWJyYWdlLm9mZnNldFk7XHJcbiAgICAgICAgICAgICAgICAgICAgLy8gY29uc29sZS5sb2coXCJ0ZXN0IHBvc2l0aW9uIEdSRUVOXCIsIHRlc3RYLCB0ZXN0WSk7XHJcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgdHJhbnNmb3JtZWRYID1cclxuICAgICAgICAgICAgICAgICAgICAgICAgKHRlc3RYIC0gdGhpcy5jYWxpYnJhZ2Uub2Zmc2V0WFBsYW4pIC8gdGhpcy5jYWxpYnJhZ2Uuc2NhbGVQbGFuOyAvLyB3ZSBhcmUgdW5kb2luZyB0aGUgcGFuIGFuZCB6b29tXHJcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgdHJhbnNmb3JtZWRZID1cclxuICAgICAgICAgICAgICAgICAgICAgICAgKHRlc3RZIC0gdGhpcy5jYWxpYnJhZ2Uub2Zmc2V0WVBsYW4pIC8gdGhpcy5jYWxpYnJhZ2Uuc2NhbGVQbGFuO1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMucG9zaXRpb25zLnB1c2goe1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBuYXZJRDogbmF2aWdhdGlvbi5pZCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgcGxhbklEOiB0aGlzLmNob3NlblBsYW4uaWQsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHg6IHRyYW5zZm9ybWVkWCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgeTogdHJhbnNmb3JtZWRZLFxyXG4gICAgICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGljb25TaXplID0gMzAgKiB0aGlzLmNhbGlicmFnZS5zY2FsZVBsYW47XHJcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgc2hpZnQgPSBpY29uU2l6ZSAvIDI7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5kcmF3SW1hZ2UoXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICdodHRwczovL2FwaS5pY29uaWZ5LmRlc2lnbi9tZGk6YWRqdXN0LnN2Zz9jb2xvcj1ncmVlbiZoZWlnaHQ9MzAmd2lkdGg9MzAnLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICB0cmFuc2Zvcm1lZFggLSBzaGlmdCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgdHJhbnNmb3JtZWRZIC0gc2hpZnQsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRydWVcclxuICAgICAgICAgICAgICAgICAgICApO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIC8qKiBTYXZlIGNhbGlicmF0aW9uICovXHJcbiAgICBhc3luYyBvblNhdmUoKSB7XHJcbiAgICAgICAgaWYgKHRoaXMuY3VycmVudFpvbmUpIHtcclxuICAgICAgICAgICAgLyoqIE5vcm1hbGl6ZSB3aXRoIHRoZSB6b29tICovXHJcbiAgICAgICAgICAgIC8vIHRoaXMuY2FsaWJyYWdlLm9mZnNldFggLz0gdGhpcy5jYW52YXNab29tO1xyXG4gICAgICAgICAgICAvLyB0aGlzLmNhbGlicmFnZS5vZmZzZXRZIC89IHRoaXMuY2FudmFzWm9vbTtcclxuICAgICAgICAgICAgLy8gdGhpcy5jYWxpYnJhZ2UueCAvPSB0aGlzLmNhbnZhc1pvb207XHJcbiAgICAgICAgICAgIC8vIHRoaXMuY2FsaWJyYWdlLnkgLz0gdGhpcy5jYW52YXNab29tO1xyXG4gICAgICAgICAgICB0aGlzLmNhbGlicmFnZS5uZXcgPSB0cnVlO1xyXG4gICAgICAgICAgICB0aGlzLmNhbGlicmFnZS5pbWdXaWR0aCA9IHRoaXMuY2FudmFzU2l6ZS53O1xyXG4gICAgICAgICAgICB0aGlzLmNhbGlicmFnZS5pbWdIZWlnaHQgPSB0aGlzLmNhbnZhc1NpemUuaDtcclxuXHJcbiAgICAgICAgICAgIGF3YWl0IHRoaXMucGxhblNlcnZpY2UudXBkYXRlUGxhbih7XHJcbiAgICAgICAgICAgICAgICBpZDogdGhpcy5jaG9zZW5QbGFuLmlkLFxyXG4gICAgICAgICAgICAgICAgY2FsaWJyYXRpb246IEpTT04uc3RyaW5naWZ5KHRoaXMuY2FsaWJyYWdlKSxcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgIGF3YWl0IFByb21pc2UuYWxsKFxyXG4gICAgICAgICAgICAgICAgdGhpcy5wb3NpdGlvbnMubWFwKGFzeW5jIChwb3NpdGlvbikgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHsgbmF2SUQgfSA9IHBvc2l0aW9uO1xyXG4gICAgICAgICAgICAgICAgICAgIGRlbGV0ZSBwb3NpdGlvbi5uYXZJRDtcclxuICAgICAgICAgICAgICAgICAgICBjb25zdCBuYXYgPSB0aGlzLmN1cnJlbnROYXZpZ2F0aW9ucy5maW5kKChfbmF2KSA9PiBfbmF2LmlkID09PSBuYXZJRCk7XHJcbiAgICAgICAgICAgICAgICAgICAgbGV0IHBvc2l0aW9uc0RhdGFUb1VwZGF0ZTtcclxuICAgICAgICAgICAgICAgICAgICBpZiAobmF2LnBvc2l0aW9uT25QbGFuKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHBvc2l0aW9uT25QbGFuID0gbmF2LnBvc2l0aW9uT25QbGFuLm1hcCgoZW50cnkpID0+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBKU09OLnBhcnNlKGVudHJ5KVxyXG4gICAgICAgICAgICAgICAgICAgICAgICApO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBwb3NpdGlvbkZvckN1cnJlbnRQbGFuID0gcG9zaXRpb25PblBsYW4uZmluZChcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIChlbnRyeSkgPT4gZW50cnkucGxhbklEID09PSB0aGlzLmNob3NlblBsYW4uaWRcclxuICAgICAgICAgICAgICAgICAgICAgICAgKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHBvc2l0aW9uRm9yQ3VycmVudFBsYW4pIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBvc2l0aW9uT25QbGFuLnNwbGljZShcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwb3NpdGlvbk9uUGxhbi5pbmRleE9mKHBvc2l0aW9uRm9yQ3VycmVudFBsYW4pLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDEsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcG9zaXRpb25cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwb3NpdGlvbk9uUGxhbi5wdXNoKHBvc2l0aW9uKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBwb3NpdGlvbnNEYXRhVG9VcGRhdGUgPSBbLi4ucG9zaXRpb25PblBsYW5dO1xyXG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHBvc2l0aW9uc0RhdGFUb1VwZGF0ZSA9IFtwb3NpdGlvbl07XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIC8vIGNvbnNvbGUubG9nKHBvc2l0aW9uc0RhdGFUb1VwZGF0ZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgYXdhaXQgdGhpcy5uYXZpZ2F0aW9uU2VydmljZS51cGRhdGVOYXZpZ2F0aW9uKHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWQ6IG5hdklELFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBwb3NpdGlvbk9uUGxhbjogcG9zaXRpb25zRGF0YVRvVXBkYXRlLm1hcCgoZW50cnkpID0+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBKU09OLnN0cmluZ2lmeShlbnRyeSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgKSxcclxuICAgICAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgICAgIH0pXHJcbiAgICAgICAgICAgICk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHRoaXMubWF0dGVycG9ydEltcG9ydFNlcnZpY2UucmVtb3ZlRnJhbWUoKTtcclxuXHJcbiAgICAgICAgdGhpcy5yb3V0ZXIubmF2aWdhdGUoWycvZGFzaGJvYXJkL2xvY2FsaXNhdGlvbicsIHRoaXMuc3BhY2VJRCwgJ3BsYW5zJ10pO1xyXG4gICAgICAgIGFsZXJ0KHRoaXMudHJhbnNsYXRlLmluc3RhbnQoJ2NhbGlicmF0aW9uLnN1Y2Nlc3MnKSk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqIFJlc2V0IHRoZSBjYW52YXMgKi9cclxuICAgIG9uUmVzZXQoKSB7XHJcbiAgICAgICAgdGhpcy5yZWZsZWN0SCA9IGZhbHNlO1xyXG4gICAgICAgIHRoaXMucmVmbGVjdFYgPSBmYWxzZTtcclxuICAgICAgICB0aGlzLnByZXZpZXcgPSBmYWxzZTtcclxuXHJcbiAgICAgICAgdGhpcy5jb25maWd1cmVDYW52YXMoKTtcclxuICAgIH1cclxuXHJcbiAgICAvKiogQ2FuY2VsLCBsZWF2ZSAqL1xyXG4gICAgb25DYW5jZWwoKSB7XHJcbiAgICAgICAgdGhpcy5tYXR0ZXJwb3J0SW1wb3J0U2VydmljZS5yZW1vdmVGcmFtZSgpO1xyXG4gICAgICAgIHRoaXMucm91dGVyLm5hdmlnYXRlKFsnL2Rhc2hib2FyZC9sb2NhbGlzYXRpb24nLCB0aGlzLnNwYWNlSUQsICdwbGFucyddKTtcclxuICAgICAgICBhbGVydCh0aGlzLnRyYW5zbGF0ZS5pbnN0YW50KCdjYWxpYnJhdGlvbi5jYW5jZWxlZCcpKTtcclxuICAgIH1cclxuXHJcbiAgICBhc3luYyBvbkZsb29yQ2xpY2soZmxvb3IpIHtcclxuICAgICAgICB0aGlzLmN1cnJlbnRGbG9vciA9IGZsb29yO1xyXG4gICAgICAgIGF3YWl0IHRoaXMubWF0dGVycG9ydEltcG9ydFNlcnZpY2UubW92ZVRvRmxvb3IoZmxvb3IuaWQpO1xyXG4gICAgfVxyXG5cclxuICAgIG9uQWN0aXZhdGVab29tQ2hhbmdlKCkge1xyXG4gICAgICAgIHRoaXMuem9vbUNhbkJlQ2hhbmdlZCA9ICF0aGlzLnpvb21DYW5CZUNoYW5nZWQ7XHJcbiAgICAgICAgY29uc3QgaWZyYW1lID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI3ZpZXdlci1mcmFtZScpIGFzIEhUTUxFbGVtZW50O1xyXG4gICAgICAgIGlmIChpZnJhbWUpIHtcclxuICAgICAgICAgICAgaWZyYW1lLnN0eWxlLnpJbmRleCA9IHRoaXMuem9vbUNhbkJlQ2hhbmdlZCA/ICcxJyA6ICcwJztcclxuICAgICAgICB9XHJcbiAgICB9XHJcbn1cclxuIiwiPGRpdiBjbGFzcz1cInJvdyBtdC0zXCI+XHJcbiAgICA8ZGl2IGNsYXNzPVwiY29sXCI+XHJcbiAgICAgICAgPGRpdiBjbGFzcz1cIm0tM1wiPlxyXG4gICAgICAgICAgICA8bGliLXRhYi1uYXZpZ2F0aW9uIFttZW51SXRlbXNdPSdtZW51SXRlbXMnPjwvbGliLXRhYi1uYXZpZ2F0aW9uPlxyXG4gICAgICAgIDwvZGl2PlxyXG4gICAgPC9kaXY+XHJcbjwvZGl2PlxyXG5cclxuPGRpdiBpZD1cInJvd0NhbnZhc1wiPlxyXG4gICAgPGRpdiAjY2FudmFzRGl2IGlkPVwiY2FudmFzRGl2XCI+XHJcblxyXG4gICAgICAgIDxkaXYgaWQ9XCJ2aWV3ZXItZnJhbWVcIiBbc3R5bGUucG9pbnRlci1ldmVudHNdPVwiem9vbUNhbkJlQ2hhbmdlZD8nYXV0byc6J25vbmUnXCI+XHJcbiAgICAgICAgICAgIDwhLS0gPGRpdiBjbGFzcz1cImJsdXJcIj48L2Rpdj4gLS0+XHJcbiAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgPGNhbnZhcyBpZD1cImNhbnZhc1wiIFtuZ1N0eWxlXT1cInsnb3BhY2l0eSc6IChwcmV2aWV3fHxsb2FkaW5nKSA/ICcxJyA6ICdjYWxjKCcgKyBvcGFjaXR5ICsgJy8gMTAwKSd9XCI+PC9jYW52YXM+XHJcbiAgICA8L2Rpdj5cclxuXHJcbiAgICA8ZGl2IGNsYXNzPVwiY2FsaWJyYXRpb24tdG9vbHMgY29udGFpbmVyLWZsdWlkXCIgKm5nSWY9XCIhKHByZXZpZXcgfHwgbG9hZGluZylcIj5cclxuICAgICAgICA8aDE+e3snQ2FsaWJyYXRpb24gdG9vbCcgfCB0cmFuc2xhdGV9fTwvaDE+XHJcbiAgICAgICAgPGRpdiBjbGFzcz1cInRvb2xcIj5cclxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cInJvdyBtcy0wIG1lLTAgbGVnZW5kXCI+XHJcbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibGVnZW5kLWJhci1pbmRpY2F0b3JcIiBbbmdTdHlsZV09XCJ7J29wYWNpdHknOiAnY2FsYygnICsgKC0ob3BhY2l0eS0xMDApKzEwKSArICcvIDEwMCknfVwiPlxyXG4gICAgICAgICAgICAgICAgICAgIHt7J0xlc3MnIHwgdHJhbnNsYXRlfX08L2Rpdj5cclxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJsZWdlbmQtdGl0bGVcIj57eydQbGFuIE9wYWNpdHknIHwgdHJhbnNsYXRlIH19PC9kaXY+XHJcbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibGVnZW5kLWJhci1pbmRpY2F0b3JcIiBbbmdTdHlsZV09XCJ7J29wYWNpdHknOiAnY2FsYygnICsgKG9wYWNpdHkrMTApICsgJy8gMTAwKSd9XCI+e3snTW9yZScgfFxyXG4gICAgICAgICAgICAgICAgICAgIHRyYW5zbGF0ZX19PC9kaXY+XHJcbiAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwicm93IG1zLTAgbWUtMCBcIj5cclxuICAgICAgICAgICAgICAgIDxpbnB1dCBbZGlzYWJsZWRdPVwiZmFsc2VcIiBbbmdNb2RlbE9wdGlvbnNdPVwie3N0YW5kYWxvbmU6IHRydWV9XCIgWyhuZ01vZGVsKV09XCJvcGFjaXR5XCIgdHlwZT1cInJhbmdlXCJcclxuICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImZvcm0tcmFuZ2VcIiBtaW49XCIwXCIgbWF4PVwiMTAwXCIgdmFsdWU9XCI1MFwiIGlkPVwib3BhY2l0eVwiPlxyXG4gICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICA8L2Rpdj5cclxuICAgICAgICA8ZGl2IGNsYXNzPVwidG9vbFwiPlxyXG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwicm93IG1zLTAgbWUtMCBcIj5cclxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJsYWJlbC1sZWdlbmRcIj57eydDaGFuZ2UgVmlzaXQgRmxvb3InIHwgdHJhbnNsYXRlfX08L2Rpdj5cclxuICAgICAgICAgICAgICAgIDxkaXYgbmdiRHJvcGRvd24gY2xhc3M9XCJkLWlubGluZS1ibG9jayBtcy0zXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgPGJ1dHRvbiBjbGFzcz1cImJ0biBidG4tbGFiZWwtZmlsZSByb3VuZGVkLXBpbGxcIiBpZD1cImRyb3Bkb3duQmFzaWMxXCIgbmdiRHJvcGRvd25Ub2dnbGU+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHt7Y3VycmVudEZsb29yID8gY3VycmVudEZsb29yLmlkIDogKCdGbG9vcicgfCB0cmFuc2xhdGUpIH19PC9idXR0b24+XHJcbiAgICAgICAgICAgICAgICAgICAgPGRpdiBuZ2JEcm9wZG93bk1lbnUgYXJpYS1sYWJlbGxlZGJ5PVwiZHJvcGRvd25CYXNpYzFcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPGJ1dHRvbiBuZ2JEcm9wZG93bkl0ZW0gKm5nRm9yPVwibGV0IGZsb29yIG9mIGZsb29yc1wiIChjbGljayk9XCJvbkZsb29yQ2xpY2soZmxvb3IpXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7eyBmbG9vci5uYW1lLmxlbmd0aCA+IDAgPyBmbG9vci5uYW1lIDogKCdGbG9vciAnICsgZmxvb3IuaWQpIH19XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvYnV0dG9uPlxyXG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgIDwvZGl2PlxyXG5cclxuICAgICAgICA8L2Rpdj5cclxuICAgICAgICA8ZGl2IGNsYXNzPVwidG9vbFwiPlxyXG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwicm93IG1zLTAgbWUtMCBcIj5cclxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJ0b29sLWNoZWNrYm94LWNvbnRhaW5lclwiPlxyXG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJ0b29sLWNoZWNrYm94LXN1YmNvbnRhaW5lclwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibGFiZWwtbGVnZW5kIG1lLTNcIj57eydQYW4vWm9vbSBWaXNpdCcgfCB0cmFuc2xhdGV9fSB7e3pvb21DYW5CZUNoYW5nZWQgPyBcIk9OXCIgOlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgXCJPRkZcIn19XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8aW5wdXQgdHlwZT1cImNoZWNrYm94XCIgKGNoYW5nZSk9XCJvbkFjdGl2YXRlWm9vbUNoYW5nZSgpXCIgc3R5bGU9XCJtYXJnaW4tdG9wOiA1cHg7XCI+XHJcbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNhcmQgYm9yZGVyLXdhcm5pbmcgbWItMyBtdC0zXCIgKm5nSWY9XCJ6b29tQ2FuQmVDaGFuZ2VkXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjYXJkLWJvZHkgdGV4dC13YXJuaW5nXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aDUgY2xhc3M9XCJjYXJkLXRpdGxlXCI+e3tcImNhbGlicmF0aW9uLndhaXQtbWVzc2FnZVwiIHwgdHJhbnNsYXRlfX08L2g1PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICA8L2Rpdj5cclxuXHJcbiAgICAgICAgPGRpdiBjbGFzcz1cImFjdGlvblwiPlxyXG4gICAgICAgICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBjbGFzcz1cImJ0biBidG4tb3V0bGluZS1wcmltYXJ5IHJvdW5kZWQtcGlsbFwiIChjbGljayk9XCJvblByZXZpZXcoKVwiXHJcbiAgICAgICAgICAgICAgICBbZGlzYWJsZWRdPVwiem9vbUNhbkJlQ2hhbmdlZFwiPnt7J1ByZXZpZXcnIHwgdHJhbnNsYXRlfX08L2J1dHRvbj5cclxuICAgICAgICAgICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgY2xhc3M9XCJidG4gYnRuLW91dGxpbmUtcHJpbWFyeSByb3VuZGVkLXBpbGxcIiAoY2xpY2spPVwib25DYW5jZWwoKVwiPnt7J0NhbmNlbCcgfFxyXG4gICAgICAgICAgICAgICAgdHJhbnNsYXRlfX08L2J1dHRvbj5cclxuXHJcbiAgICAgICAgPC9kaXY+XHJcblxyXG4gICAgPC9kaXY+XHJcbiAgICA8ZGl2IGNsYXNzPVwiY2FsaWJyYXRpb24tdG9vbHMgY29udGFpbmVyLWZsdWlkXCIgKm5nSWY9XCJwcmV2aWV3XCI+XHJcbiAgICAgICAgPGgxPnt7J1ZhbGlkYXRpb24nIHwgdHJhbnNsYXRlfX08L2gxPlxyXG4gICAgICAgIDxkaXYgY2xhc3M9XCJhY3Rpb25cIj5cclxuICAgICAgICAgICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgY2xhc3M9XCJidG4gYnRuLW91dGxpbmUtcHJpbWFyeSByb3VuZGVkLXBpbGxcIiAoY2xpY2spPVwib25TYXZlKClcIj57eydWYWxpZGF0ZScgfFxyXG4gICAgICAgICAgICAgICAgdHJhbnNsYXRlfX08L2J1dHRvbj5cclxuICAgICAgICAgICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgY2xhc3M9XCJidG4gYnRuLW91dGxpbmUtcHJpbWFyeSByb3VuZGVkLXBpbGxcIiAoY2xpY2spPVwib25SZXNldCgpXCI+e3snUmVzZXQnIHxcclxuICAgICAgICAgICAgICAgIHRyYW5zbGF0ZX19PC9idXR0b24+XHJcbiAgICAgICAgICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIGNsYXNzPVwiYnRuIGJ0bi1vdXRsaW5lLXByaW1hcnkgcm91bmRlZC1waWxsXCIgKGNsaWNrKT1cIm9uQ2FuY2VsKClcIj57eydDYW5jZWwnIHxcclxuICAgICAgICAgICAgICAgIHRyYW5zbGF0ZX19PC9idXR0b24+XHJcblxyXG4gICAgICAgIDwvZGl2PlxyXG4gICAgPC9kaXY+XHJcblxyXG5cclxuICAgIDxkaXYgY2xhc3M9XCJjYWxpYnJhdGlvbi10b29scyBjb250YWluZXItZmx1aWRcIiAqbmdJZj1cImxvYWRpbmdcIj5cclxuICAgICAgICA8aDM+e3tcIldhaXRpbmcgZm9yIE1hdHRlcnBvcnRcIiB8IHRyYW5zbGF0ZX19Li4uPC9oMz5cclxuICAgICAgICA8ZGl2IGNsYXNzPVwiZC1mbGV4IGp1c3RpZnktY29udGVudC1jZW50ZXJcIj5cclxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cInNwaW5uZXItYm9yZGVyXCIgcm9sZT1cInN0YXR1c1wiPlxyXG4gICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJ2aXN1YWxseS1oaWRkZW5cIj5Mb2FkaW5nLi4uPC9zcGFuPlxyXG4gICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICA8L2Rpdj5cclxuXHJcbiAgICA8L2Rpdj5cclxuPC9kaXY+Il19
|