tango-app-ui-store-builder 1.0.1-beta-1
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/README.md +24 -0
- package/esm2022/lib/components/create-layout/create-layout.component.mjs +1815 -0
- package/esm2022/lib/components/create-layout/popups/add-floor/add-floor.component.mjs +40 -0
- package/esm2022/lib/components/create-layout/popups/clear-all-steps/clear-all-steps.component.mjs +16 -0
- package/esm2022/lib/components/create-layout/popups/delete-layout/delete-layout.component.mjs +16 -0
- package/esm2022/lib/components/custom-select/custom-select.component.mjs +155 -0
- package/esm2022/lib/components/layout-builder/layout-builder.component.mjs +56 -0
- package/esm2022/lib/components/layout-summary/layout-summary.component.mjs +809 -0
- package/esm2022/lib/components/layout-summary/popups/complete-layout/complete-layout.component.mjs +16 -0
- package/esm2022/lib/components/reactive-select/reactive-select.component.mjs +87 -0
- package/esm2022/lib/components/store-layout-table/store-layout-table.component.mjs +709 -0
- package/esm2022/lib/components/store-offcanvas-component/store-offcanvas-component.component.mjs +99 -0
- package/esm2022/lib/interfaces/layout-builder.interface.mjs +2 -0
- package/esm2022/lib/services/store-builder.service.mjs +99 -0
- package/esm2022/lib/tango-store-builder-routing.module.mjs +41 -0
- package/esm2022/lib/tango-store-builder.module.mjs +71 -0
- package/esm2022/public-api.mjs +5 -0
- package/esm2022/tango-app-ui-store-builder.mjs +5 -0
- package/esm2022/tango-store-builder.mjs +5 -0
- package/fesm2022/tango-app-ui-store-builder.mjs +3947 -0
- package/fesm2022/tango-app-ui-store-builder.mjs.map +1 -0
- package/fesm2022/tango-store-builder.mjs +3947 -0
- package/fesm2022/tango-store-builder.mjs.map +1 -0
- package/index.d.ts +5 -0
- package/lib/components/create-layout/create-layout.component.d.ts +197 -0
- package/lib/components/create-layout/popups/add-floor/add-floor.component.d.ts +16 -0
- package/lib/components/create-layout/popups/clear-all-steps/clear-all-steps.component.d.ts +8 -0
- package/lib/components/create-layout/popups/delete-layout/delete-layout.component.d.ts +8 -0
- package/lib/components/custom-select/custom-select.component.d.ts +33 -0
- package/lib/components/layout-builder/layout-builder.component.d.ts +18 -0
- package/lib/components/layout-summary/layout-summary.component.d.ts +92 -0
- package/lib/components/layout-summary/popups/complete-layout/complete-layout.component.d.ts +8 -0
- package/lib/components/reactive-select/reactive-select.component.d.ts +26 -0
- package/lib/components/store-layout-table/store-layout-table.component.d.ts +73 -0
- package/lib/components/store-offcanvas-component/store-offcanvas-component.component.d.ts +26 -0
- package/lib/interfaces/layout-builder.interface.d.ts +23 -0
- package/lib/services/store-builder.service.d.ts +33 -0
- package/lib/tango-store-builder-routing.module.d.ts +7 -0
- package/lib/tango-store-builder.module.d.ts +22 -0
- package/package.json +25 -0
- package/public-api.d.ts +1 -0
|
@@ -0,0 +1,1815 @@
|
|
|
1
|
+
import { FormControl } from '@angular/forms';
|
|
2
|
+
import { moveItemInArray } from '@angular/cdk/drag-drop';
|
|
3
|
+
import { Subject, takeUntil } from 'rxjs';
|
|
4
|
+
import { Component, HostListener, ViewChild } from '@angular/core';
|
|
5
|
+
import { StoreOffcanvasComponentComponent } from '../store-offcanvas-component/store-offcanvas-component.component';
|
|
6
|
+
import { AddFloorComponent } from './popups/add-floor/add-floor.component';
|
|
7
|
+
import { ClearAllStepsComponent } from './popups/clear-all-steps/clear-all-steps.component';
|
|
8
|
+
import { DeleteLayoutComponent } from './popups/delete-layout/delete-layout.component';
|
|
9
|
+
import * as XLSX from 'xlsx';
|
|
10
|
+
import * as i0 from "@angular/core";
|
|
11
|
+
import * as i1 from "@angular/router";
|
|
12
|
+
import * as i2 from "../../services/store-builder.service";
|
|
13
|
+
import * as i3 from "@ng-bootstrap/ng-bootstrap";
|
|
14
|
+
import * as i4 from "tango-app-ui-shared";
|
|
15
|
+
import * as i5 from "@angular/common";
|
|
16
|
+
import * as i6 from "@angular/forms";
|
|
17
|
+
import * as i7 from "@angular/cdk/drag-drop";
|
|
18
|
+
import * as i8 from "../custom-select/custom-select.component";
|
|
19
|
+
export class CreateLayoutComponent {
|
|
20
|
+
cd;
|
|
21
|
+
renderer;
|
|
22
|
+
route;
|
|
23
|
+
apiService;
|
|
24
|
+
router;
|
|
25
|
+
offcanvasService;
|
|
26
|
+
toastService;
|
|
27
|
+
modalDef;
|
|
28
|
+
floorsInput = new FormControl();
|
|
29
|
+
canvasRef;
|
|
30
|
+
widgetCanvasRef;
|
|
31
|
+
scrollContainerRef;
|
|
32
|
+
gridWidth = 1;
|
|
33
|
+
gridHeight = 1;
|
|
34
|
+
ctx;
|
|
35
|
+
canvas;
|
|
36
|
+
widgetCtx;
|
|
37
|
+
widgetCanvas;
|
|
38
|
+
elementType = 'wall';
|
|
39
|
+
layoutPolygon = [[
|
|
40
|
+
{
|
|
41
|
+
"x": 100,
|
|
42
|
+
"y": 100
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
"x": 100,
|
|
46
|
+
"y": 100
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
"elementType": "wall",
|
|
50
|
+
"distance": 0,
|
|
51
|
+
"unit": "ft",
|
|
52
|
+
"direction": "right",
|
|
53
|
+
"angle": 90,
|
|
54
|
+
"elementNumber": 1
|
|
55
|
+
}
|
|
56
|
+
]];
|
|
57
|
+
popupVisible = false;
|
|
58
|
+
popupPosition = { x: 100, y: 100 };
|
|
59
|
+
selectedLine;
|
|
60
|
+
selectedLineIndex;
|
|
61
|
+
movePixels = 0;
|
|
62
|
+
moveAngle = 0;
|
|
63
|
+
unit = 'ft';
|
|
64
|
+
moveDirection = 'right';
|
|
65
|
+
layoutMode = 'half';
|
|
66
|
+
elementSelect = { show: false, index: 0 };
|
|
67
|
+
directionSelect = { show: false, index: 0 };
|
|
68
|
+
lineOptionsSelect = { show: false, index: 0 };
|
|
69
|
+
widgetElementSelect = { show: false };
|
|
70
|
+
layoutOptionSelect = { show: false };
|
|
71
|
+
floorSelect = { show: false, deleteIndex: null };
|
|
72
|
+
scale = 1;
|
|
73
|
+
panOffset = { x: 0, y: 0 };
|
|
74
|
+
breakpoints = [0, 360];
|
|
75
|
+
circleRef;
|
|
76
|
+
pointerRef;
|
|
77
|
+
lines = [];
|
|
78
|
+
minAngle;
|
|
79
|
+
maxAngle;
|
|
80
|
+
destroy$ = new Subject();
|
|
81
|
+
headerData;
|
|
82
|
+
planoStoreList = [];
|
|
83
|
+
selectedStore;
|
|
84
|
+
selectedFloor;
|
|
85
|
+
undoStack = [];
|
|
86
|
+
redoStack = [];
|
|
87
|
+
planoIds = [];
|
|
88
|
+
itemsPerPage = 1;
|
|
89
|
+
currentPage = 0;
|
|
90
|
+
totalItems = 1;
|
|
91
|
+
paginationSizes = [1];
|
|
92
|
+
pageSize = 1;
|
|
93
|
+
pixelPerMetre = 50;
|
|
94
|
+
cumulativeRotation = 0;
|
|
95
|
+
onPageChange(val) {
|
|
96
|
+
this.selectedStore = this.planoStoreList[val - 1];
|
|
97
|
+
this.selectedFloor = this.selectedStore.floor[0];
|
|
98
|
+
this.floorsInput.setValue(this.selectedFloor.id, { emitEvent: false });
|
|
99
|
+
this.generateLayoutPolygon(this.selectedFloor.layoutPolygon);
|
|
100
|
+
this.redoStack = [];
|
|
101
|
+
this.undoStack = [];
|
|
102
|
+
}
|
|
103
|
+
saveStateToUndo() {
|
|
104
|
+
this.undoStack.push(JSON.parse(JSON.stringify(this.layoutPolygon)));
|
|
105
|
+
}
|
|
106
|
+
undo() {
|
|
107
|
+
if (this.undoStack.length > 0) {
|
|
108
|
+
this.redoStack.push(JSON.parse(JSON.stringify(this.layoutPolygon)));
|
|
109
|
+
this.layoutPolygon = this.undoStack.pop();
|
|
110
|
+
this.redrawCanvas();
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
redo() {
|
|
114
|
+
if (this.redoStack.length > 0) {
|
|
115
|
+
this.undoStack.push(JSON.parse(JSON.stringify(this.layoutPolygon)));
|
|
116
|
+
this.layoutPolygon = this.redoStack.pop();
|
|
117
|
+
this.redrawCanvas();
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
constructor(cd, renderer, route, apiService, router, offcanvasService, toastService, modalDef) {
|
|
121
|
+
this.cd = cd;
|
|
122
|
+
this.renderer = renderer;
|
|
123
|
+
this.route = route;
|
|
124
|
+
this.apiService = apiService;
|
|
125
|
+
this.router = router;
|
|
126
|
+
this.offcanvasService = offcanvasService;
|
|
127
|
+
this.toastService = toastService;
|
|
128
|
+
this.modalDef = modalDef;
|
|
129
|
+
this.headerData = JSON.parse(localStorage.getItem('header-filters'));
|
|
130
|
+
}
|
|
131
|
+
initializeLayout() {
|
|
132
|
+
const centerX = this.canvas.width / 2 / this.scale;
|
|
133
|
+
const centerY = this.canvas.height / 2 / this.scale;
|
|
134
|
+
this.layoutPolygon = [
|
|
135
|
+
[
|
|
136
|
+
{
|
|
137
|
+
"x": this.snapToGrid(centerX, this.gridHeight),
|
|
138
|
+
"y": this.snapToGrid(centerY, this.gridWidth)
|
|
139
|
+
},
|
|
140
|
+
{
|
|
141
|
+
"x": this.snapToGrid(centerX, this.gridHeight),
|
|
142
|
+
"y": this.snapToGrid(centerY, this.gridWidth)
|
|
143
|
+
},
|
|
144
|
+
{
|
|
145
|
+
"elementType": "wall",
|
|
146
|
+
"distance": 0,
|
|
147
|
+
"unit": "ft",
|
|
148
|
+
"direction": "right",
|
|
149
|
+
"angle": 90,
|
|
150
|
+
"elementNumber": 1
|
|
151
|
+
}
|
|
152
|
+
]
|
|
153
|
+
];
|
|
154
|
+
this.openWidget({
|
|
155
|
+
"x": this.snapToGrid(centerX, this.gridHeight),
|
|
156
|
+
"y": this.snapToGrid(centerY, this.gridWidth)
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
ngOnInit() {
|
|
160
|
+
this.canvas = this.canvasRef.nativeElement;
|
|
161
|
+
this.ctx = this.canvas.getContext('2d');
|
|
162
|
+
this.canvas.width = 10000;
|
|
163
|
+
this.canvas.height = 10000;
|
|
164
|
+
this.drawGrid();
|
|
165
|
+
this.canvas.addEventListener('mousedown', this.onMouseDown.bind(this));
|
|
166
|
+
this.canvas.addEventListener('mousemove', this.onMouseMove.bind(this));
|
|
167
|
+
this.minAngle = Math.min(...this.breakpoints);
|
|
168
|
+
this.maxAngle = Math.max(...this.breakpoints);
|
|
169
|
+
for (let i = 0; i < 360; i += 45) {
|
|
170
|
+
this.lines.push({
|
|
171
|
+
transform: `rotate(${i}deg)`,
|
|
172
|
+
highlight: false,
|
|
173
|
+
invisible: i < this.minAngle || i > this.maxAngle
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
this.route.queryParams
|
|
177
|
+
.pipe(takeUntil(this.destroy$))
|
|
178
|
+
.subscribe((params) => {
|
|
179
|
+
if (params?.id) {
|
|
180
|
+
this.planoIds = params.id.split(',') || [];
|
|
181
|
+
this.getPlanoData();
|
|
182
|
+
}
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
onFloorSelect(floorId) {
|
|
186
|
+
if (this.layoutPolygon[0][0].x !== this.layoutPolygon[0][1].x && this.layoutPolygon[0][0].y !== this.layoutPolygon[0][1].y) {
|
|
187
|
+
this.updateFloorLayout();
|
|
188
|
+
}
|
|
189
|
+
this.selectedFloor = this.selectedStore.floor.filter((floor) => floor.id === floorId)[0];
|
|
190
|
+
this.generateLayoutPolygon(this.selectedFloor.layoutPolygon);
|
|
191
|
+
this.redoStack = [];
|
|
192
|
+
this.undoStack = [];
|
|
193
|
+
}
|
|
194
|
+
ngOnDestroy() {
|
|
195
|
+
this.destroy$.next();
|
|
196
|
+
this.destroy$.complete();
|
|
197
|
+
}
|
|
198
|
+
onStoreChange(event) {
|
|
199
|
+
if (this.layoutPolygon[0][0].x !== this.layoutPolygon[0][1].x && this.layoutPolygon[0][0].y !== this.layoutPolygon[0][1].y) {
|
|
200
|
+
this.updateFloorLayout();
|
|
201
|
+
}
|
|
202
|
+
const index = this.planoStoreList.findIndex(item => item.planoId === event.planoId);
|
|
203
|
+
this.currentPage = index + 1;
|
|
204
|
+
this.selectedStore = event;
|
|
205
|
+
this.selectedFloor = this.selectedStore.floor[0];
|
|
206
|
+
this.floorsInput.setValue(this.selectedFloor.id, { emitEvent: false });
|
|
207
|
+
this.generateLayoutPolygon(this.selectedFloor.layoutPolygon);
|
|
208
|
+
this.redoStack = [];
|
|
209
|
+
this.undoStack = [];
|
|
210
|
+
}
|
|
211
|
+
openOffCanva() {
|
|
212
|
+
let canvaRef = this.offcanvasService.open(StoreOffcanvasComponentComponent, { position: 'end', panelClass: 'set-height' });
|
|
213
|
+
canvaRef.componentInstance.store = this.selectedStore;
|
|
214
|
+
canvaRef.componentInstance.clientId = this.headerData?.client;
|
|
215
|
+
canvaRef.componentInstance.id = this.selectedStore.planoId;
|
|
216
|
+
}
|
|
217
|
+
getPlanoData() {
|
|
218
|
+
const payload = {
|
|
219
|
+
id: this.planoIds
|
|
220
|
+
};
|
|
221
|
+
this.apiService.getPlano(payload).subscribe({
|
|
222
|
+
next: (res) => {
|
|
223
|
+
this.planoStoreList = res.data;
|
|
224
|
+
this.totalItems = res.data.length;
|
|
225
|
+
if (!this.selectedStore) {
|
|
226
|
+
this.selectedStore = this.planoStoreList[0];
|
|
227
|
+
}
|
|
228
|
+
else {
|
|
229
|
+
this.selectedStore = this.planoStoreList.filter((store) => store.planoId === this.selectedStore.planoId)[0];
|
|
230
|
+
}
|
|
231
|
+
if (!this.selectedFloor) {
|
|
232
|
+
this.selectedFloor = this.selectedStore.floor[0];
|
|
233
|
+
}
|
|
234
|
+
else {
|
|
235
|
+
this.selectedFloor = this.selectedStore.floor.filter((floor) => floor.id === this.selectedFloor.id)[0];
|
|
236
|
+
if (!this.selectedFloor) {
|
|
237
|
+
this.selectedFloor = this.selectedStore.floor[0];
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
this.floorsInput.setValue(this.selectedFloor.id, { emitEvent: false });
|
|
241
|
+
this.generateLayoutPolygon(this.selectedFloor.layoutPolygon);
|
|
242
|
+
},
|
|
243
|
+
error: (err) => {
|
|
244
|
+
console.log(err);
|
|
245
|
+
}
|
|
246
|
+
});
|
|
247
|
+
}
|
|
248
|
+
updateFloorLayout() {
|
|
249
|
+
const payload = {
|
|
250
|
+
id: this.selectedFloor.id,
|
|
251
|
+
layoutPolygon: this.layoutPolygon.map((segment) => {
|
|
252
|
+
const [point1, point2, properties] = segment;
|
|
253
|
+
return properties;
|
|
254
|
+
}),
|
|
255
|
+
status: 'draft'
|
|
256
|
+
};
|
|
257
|
+
this.apiService.updateFloorLayout(payload).subscribe({
|
|
258
|
+
next: (res) => {
|
|
259
|
+
if (res.code === 200) {
|
|
260
|
+
this.getPlanoData();
|
|
261
|
+
this.toastService.getSuccessToast(res.message);
|
|
262
|
+
}
|
|
263
|
+
},
|
|
264
|
+
error: (err) => {
|
|
265
|
+
console.log(err);
|
|
266
|
+
}
|
|
267
|
+
});
|
|
268
|
+
}
|
|
269
|
+
deleteFloor(index) {
|
|
270
|
+
this.floorSelect = {
|
|
271
|
+
show: !this.floorSelect.show,
|
|
272
|
+
deleteIndex: null
|
|
273
|
+
};
|
|
274
|
+
const modelRef = this.modalDef.open(DeleteLayoutComponent, { centered: true });
|
|
275
|
+
modelRef.result.then((val) => {
|
|
276
|
+
if (val.message === 'confirm') {
|
|
277
|
+
const payload = {
|
|
278
|
+
id: this.selectedStore.floor[index].id,
|
|
279
|
+
};
|
|
280
|
+
this.apiService.deleteFloor(payload).subscribe({
|
|
281
|
+
next: (res) => {
|
|
282
|
+
if (res.code === 200) {
|
|
283
|
+
this.getPlanoData();
|
|
284
|
+
this.toastService.getSuccessToast(res.message);
|
|
285
|
+
}
|
|
286
|
+
},
|
|
287
|
+
error: (err) => {
|
|
288
|
+
console.log(err);
|
|
289
|
+
}
|
|
290
|
+
});
|
|
291
|
+
}
|
|
292
|
+
});
|
|
293
|
+
}
|
|
294
|
+
addFloor(planoId, floorCount) {
|
|
295
|
+
const payload = {
|
|
296
|
+
id: planoId,
|
|
297
|
+
floorNumber: floorCount
|
|
298
|
+
};
|
|
299
|
+
this.apiService.addFloor(payload).subscribe({
|
|
300
|
+
next: (res) => {
|
|
301
|
+
if (res.code === 200) {
|
|
302
|
+
this.getPlanoData();
|
|
303
|
+
this.toastService.getSuccessToast(res.message);
|
|
304
|
+
}
|
|
305
|
+
},
|
|
306
|
+
error: (err) => {
|
|
307
|
+
console.log(err);
|
|
308
|
+
}
|
|
309
|
+
});
|
|
310
|
+
}
|
|
311
|
+
onSaveAsDraft() {
|
|
312
|
+
if (this.layoutPolygon.length === 1 && this.layoutPolygon[0][0].x === this.layoutPolygon[0][1].x && this.layoutPolygon[0][0].y === this.layoutPolygon[0][1].y) {
|
|
313
|
+
return;
|
|
314
|
+
}
|
|
315
|
+
this.updateFloorLayout();
|
|
316
|
+
}
|
|
317
|
+
onConfigure() {
|
|
318
|
+
if (this.planoStoreList.length === 1) {
|
|
319
|
+
for (let index = 0; index < this.selectedStore.floor.length; index++) {
|
|
320
|
+
let layoutInstruction;
|
|
321
|
+
if (this.selectedStore.floor[index].id === this.selectedFloor.id) {
|
|
322
|
+
layoutInstruction = this.layoutPolygon.map((line) => {
|
|
323
|
+
const [stert, end, properties] = line;
|
|
324
|
+
return properties;
|
|
325
|
+
});
|
|
326
|
+
}
|
|
327
|
+
else {
|
|
328
|
+
layoutInstruction = this.selectedStore.floor[index].layoutPolygon;
|
|
329
|
+
}
|
|
330
|
+
if (!this.isFloorCompleted(layoutInstruction)) {
|
|
331
|
+
this.toastService.getErrorToast(`Please complete ${this.selectedStore.floor[index].floorName}`);
|
|
332
|
+
return;
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
else if (this.planoStoreList.length > 1) {
|
|
337
|
+
for (let i = 0; i < this.planoStoreList.length; i++) {
|
|
338
|
+
for (let j = 0; j < this.planoStoreList[i].floor.length; j++) {
|
|
339
|
+
let layoutInstruction;
|
|
340
|
+
if (this.planoStoreList[i].floor[j].id === this.selectedFloor.id) {
|
|
341
|
+
layoutInstruction = this.layoutPolygon.map((line) => {
|
|
342
|
+
const [stert, end, properties] = line;
|
|
343
|
+
return properties;
|
|
344
|
+
});
|
|
345
|
+
}
|
|
346
|
+
else {
|
|
347
|
+
layoutInstruction = this.planoStoreList[i].floor[j].layoutPolygon;
|
|
348
|
+
}
|
|
349
|
+
if (!this.isFloorCompleted(layoutInstruction)) {
|
|
350
|
+
this.toastService.getErrorToast(`Please complete ${this.planoStoreList[i].floor[j].floorName} of ${this.planoStoreList[i].storeName}`);
|
|
351
|
+
return;
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
this.updateFloorLayout();
|
|
357
|
+
this.router.navigate(['/manage/planogram/layout-builder/summary'], {
|
|
358
|
+
queryParamsHandling: 'merge'
|
|
359
|
+
});
|
|
360
|
+
}
|
|
361
|
+
drawWidgetRing() {
|
|
362
|
+
this.widgetCanvas = this.widgetCanvasRef.nativeElement;
|
|
363
|
+
this.widgetCtx = this.widgetCanvas.getContext('2d');
|
|
364
|
+
this.widgetCanvas.width = 229;
|
|
365
|
+
this.widgetCanvas.height = 229;
|
|
366
|
+
this.widgetCtx.clearRect(0, 0, this.widgetCanvas.width, this.widgetCanvas.height);
|
|
367
|
+
const direction = this.moveDirection;
|
|
368
|
+
const centerX = this.widgetCanvas.width / 2;
|
|
369
|
+
const centerY = this.widgetCanvas.height / 2;
|
|
370
|
+
const outerRadius = 114.5;
|
|
371
|
+
const innerRadius = 85;
|
|
372
|
+
this.widgetCtx.beginPath();
|
|
373
|
+
this.widgetCtx.arc(centerX, centerY, outerRadius, 0, Math.PI * 2);
|
|
374
|
+
this.widgetCtx.fillStyle = '#F9FAFB';
|
|
375
|
+
this.widgetCtx.fill();
|
|
376
|
+
this.widgetCtx.globalCompositeOperation = 'destination-out';
|
|
377
|
+
this.widgetCtx.beginPath();
|
|
378
|
+
this.widgetCtx.arc(centerX, centerY, innerRadius, 0, Math.PI * 2);
|
|
379
|
+
this.widgetCtx.fill();
|
|
380
|
+
this.widgetCtx.globalCompositeOperation = 'source-over';
|
|
381
|
+
this.widgetCtx.beginPath();
|
|
382
|
+
let startAngle, endAngle, color;
|
|
383
|
+
switch (direction) {
|
|
384
|
+
case 'down':
|
|
385
|
+
startAngle = 0;
|
|
386
|
+
endAngle = Math.PI;
|
|
387
|
+
color = '#EAF7FF';
|
|
388
|
+
break;
|
|
389
|
+
case 'up':
|
|
390
|
+
startAngle = Math.PI;
|
|
391
|
+
endAngle = Math.PI * 2;
|
|
392
|
+
color = '#EAF7FF';
|
|
393
|
+
break;
|
|
394
|
+
case 'right':
|
|
395
|
+
startAngle = Math.PI * 1.5;
|
|
396
|
+
endAngle = Math.PI * 0.5;
|
|
397
|
+
color = '#EAF7FF';
|
|
398
|
+
break;
|
|
399
|
+
case 'left':
|
|
400
|
+
startAngle = Math.PI * 0.5;
|
|
401
|
+
endAngle = Math.PI * 1.5;
|
|
402
|
+
color = '#EAF7FF';
|
|
403
|
+
break;
|
|
404
|
+
default:
|
|
405
|
+
return;
|
|
406
|
+
}
|
|
407
|
+
this.widgetCtx.moveTo(centerX, centerY);
|
|
408
|
+
this.widgetCtx.arc(centerX, centerY, outerRadius, startAngle, endAngle);
|
|
409
|
+
this.widgetCtx.lineTo(centerX, centerY);
|
|
410
|
+
this.widgetCtx.fillStyle = color;
|
|
411
|
+
this.widgetCtx.fill();
|
|
412
|
+
this.widgetCtx.globalCompositeOperation = 'destination-out';
|
|
413
|
+
this.widgetCtx.beginPath();
|
|
414
|
+
this.widgetCtx.arc(centerX, centerY, innerRadius, 0, Math.PI * 2);
|
|
415
|
+
this.widgetCtx.fill();
|
|
416
|
+
this.widgetCtx.globalCompositeOperation = 'source-over';
|
|
417
|
+
}
|
|
418
|
+
updateWidgetPointer() {
|
|
419
|
+
let angle;
|
|
420
|
+
switch (this.moveDirection) {
|
|
421
|
+
case 'right':
|
|
422
|
+
angle = 0 + this.moveAngle;
|
|
423
|
+
break;
|
|
424
|
+
case 'down':
|
|
425
|
+
angle = 90 + this.moveAngle;
|
|
426
|
+
break;
|
|
427
|
+
case 'left':
|
|
428
|
+
angle = 180 + this.moveAngle;
|
|
429
|
+
break;
|
|
430
|
+
case 'up':
|
|
431
|
+
angle = 270 + this.moveAngle;
|
|
432
|
+
break;
|
|
433
|
+
default:
|
|
434
|
+
return;
|
|
435
|
+
}
|
|
436
|
+
const pointer = this.pointerRef?.nativeElement;
|
|
437
|
+
this.renderer.setStyle(pointer, 'transform', `rotate(${angle}deg)`);
|
|
438
|
+
this.lines.forEach((line) => {
|
|
439
|
+
const lineAngle = parseInt(line.transform.replace('rotate(', ''), 10);
|
|
440
|
+
line.highlight = angle >= lineAngle && angle >= this.minAngle && lineAngle <= this.maxAngle;
|
|
441
|
+
});
|
|
442
|
+
}
|
|
443
|
+
drawGrid() {
|
|
444
|
+
this.ctx.save();
|
|
445
|
+
this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
|
|
446
|
+
this.ctx.scale(this.scale, this.scale);
|
|
447
|
+
this.ctx.translate(this.panOffset.x, this.panOffset.y);
|
|
448
|
+
// for (let x = 0; x <= this.canvas.width; x += this.gridWidth) {
|
|
449
|
+
// for (let y = 0; y <= this.canvas.height; y += this.gridHeight) {
|
|
450
|
+
// this.ctx.beginPath();
|
|
451
|
+
// this.ctx.arc(x, y, 1, 0, Math.PI * 2);
|
|
452
|
+
// this.ctx.fillStyle = 'rgba(0, 0, 0, 0.3)';
|
|
453
|
+
// this.ctx.fill();
|
|
454
|
+
// }
|
|
455
|
+
// }
|
|
456
|
+
this.ctx.restore();
|
|
457
|
+
}
|
|
458
|
+
drawPolygon(polygon = this.layoutPolygon) {
|
|
459
|
+
if (polygon.length < 1)
|
|
460
|
+
return; // If the polygon has no edges, exit early.
|
|
461
|
+
this.ctx.save(); // Save the current canvas state.
|
|
462
|
+
this.ctx.scale(this.scale, this.scale); // Scale the canvas context to match the desired scale.
|
|
463
|
+
this.ctx.translate(this.panOffset.x, this.panOffset.y);
|
|
464
|
+
// Function to draw an arrowhead at a specific location and angle.
|
|
465
|
+
function drawArrowhead(ctx, x, y, angle) {
|
|
466
|
+
const size = 5; // Define the size of the arrowhead.
|
|
467
|
+
ctx.save(); // Save the current canvas state.
|
|
468
|
+
ctx.translate(x, y); // Move the context to the arrowhead position.
|
|
469
|
+
ctx.rotate(angle); // Rotate the context to match the arrow's angle.
|
|
470
|
+
ctx.beginPath(); // Start a new path.
|
|
471
|
+
ctx.moveTo(0, 0); // Move to the tip of the arrowhead.
|
|
472
|
+
ctx.lineTo(-size, -size / 2); // Draw one side of the arrowhead.
|
|
473
|
+
ctx.lineTo(-size, size / 2); // Draw the other side of the arrowhead.
|
|
474
|
+
ctx.closePath(); // Close the arrowhead path.
|
|
475
|
+
ctx.fillStyle = 'black'; // Set the arrowhead color.
|
|
476
|
+
ctx.fill(); // Fill the arrowhead.
|
|
477
|
+
ctx.restore(); // Restore the previous canvas state.
|
|
478
|
+
}
|
|
479
|
+
this.ctx.beginPath(); // Begin the main polygon path.
|
|
480
|
+
polygon.forEach((edge, edgeIndex) => {
|
|
481
|
+
const point = edge[0]; // Starting point of the edge.
|
|
482
|
+
const nextPoint = edge[1]; // Ending point of the edge.
|
|
483
|
+
const properties = edge[2]; // Properties of the edge (e.g., labels, distances).
|
|
484
|
+
// Draw the main polygon edge.
|
|
485
|
+
if (edgeIndex === 0)
|
|
486
|
+
this.ctx.moveTo(point.x, point.y); // Move to the first edge starting point.
|
|
487
|
+
this.ctx.lineTo(nextPoint.x, nextPoint.y); // Draw a line to the next point.
|
|
488
|
+
// Calculate the perpendicular offset for the bounding box.
|
|
489
|
+
const dx = nextPoint.x - point.x; // X-difference between start and end points.
|
|
490
|
+
const dy = nextPoint.y - point.y; // Y-difference between start and end points.
|
|
491
|
+
const length = Math.sqrt(dx * dx + dy * dy); // Length of the edge.
|
|
492
|
+
const offsetX = (dy / length) * 20; // Offset in the X direction.
|
|
493
|
+
const offsetY = (-dx / length) * 20; // Offset in the Y direction.
|
|
494
|
+
// Define the bounding box points.
|
|
495
|
+
const boxPoints = [
|
|
496
|
+
{ x: point.x, y: point.y },
|
|
497
|
+
{ x: nextPoint.x, y: nextPoint.y },
|
|
498
|
+
{ x: nextPoint.x + offsetX, y: nextPoint.y + offsetY },
|
|
499
|
+
{ x: point.x + offsetX, y: point.y + offsetY },
|
|
500
|
+
];
|
|
501
|
+
// Draw the bounding box.
|
|
502
|
+
this.ctx.beginPath();
|
|
503
|
+
this.ctx.moveTo(boxPoints[0].x, boxPoints[0].y);
|
|
504
|
+
boxPoints.forEach((pt, index) => {
|
|
505
|
+
if (properties.elementType === 'entrance') {
|
|
506
|
+
if (index < 2) {
|
|
507
|
+
this.ctx.lineTo(pt.x, pt.y);
|
|
508
|
+
}
|
|
509
|
+
}
|
|
510
|
+
else {
|
|
511
|
+
this.ctx.lineTo(pt.x, pt.y); // Draw each edge of the box.
|
|
512
|
+
}
|
|
513
|
+
});
|
|
514
|
+
if (properties.elementType === 'opening') {
|
|
515
|
+
this.ctx.closePath(); // Close the bounding box path.
|
|
516
|
+
this.ctx.fillStyle = '#F9FAFB'; // Set a translucent fill color.
|
|
517
|
+
this.ctx.fill(); // Fill the bounding box.
|
|
518
|
+
this.selectedLineIndex === edgeIndex ? this.ctx.strokeStyle = '#008EDF' : this.ctx.strokeStyle = '#F9FAFB';
|
|
519
|
+
this.ctx.stroke(); // Draw the bounding box border.
|
|
520
|
+
}
|
|
521
|
+
else {
|
|
522
|
+
this.ctx.closePath(); // Close the bounding box path.
|
|
523
|
+
this.ctx.fillStyle = '#F9FAFB'; // Set a translucent fill color.
|
|
524
|
+
this.ctx.fill(); // Fill the bounding box.
|
|
525
|
+
this.selectedLineIndex === edgeIndex ? this.ctx.strokeStyle = '#008EDF' : this.ctx.strokeStyle = '#1D2939';
|
|
526
|
+
this.ctx.stroke(); // Draw the bounding box border.
|
|
527
|
+
}
|
|
528
|
+
// Position text in the middle of the bounding box.
|
|
529
|
+
const textX = (boxPoints[1].x + boxPoints[3].x) / 2;
|
|
530
|
+
const textY = (boxPoints[1].y + boxPoints[3].y) / 2;
|
|
531
|
+
this.ctx.save(); // Save the current canvas state.
|
|
532
|
+
this.ctx.translate(textX, textY); // Move the context to the text position.
|
|
533
|
+
// Rotate text based on the edge direction.
|
|
534
|
+
if (dx === 0) {
|
|
535
|
+
this.ctx.rotate(-Math.PI / 2); // Rotate for vertical edges.
|
|
536
|
+
}
|
|
537
|
+
else if (dy !== 0) {
|
|
538
|
+
const angle = Math.atan2(dy, dx); // Calculate angle for diagonal edges.
|
|
539
|
+
this.ctx.rotate(angle); // Rotate the text to match the angle.
|
|
540
|
+
}
|
|
541
|
+
// Draw the edge properties as text.
|
|
542
|
+
this.ctx.font = '12px Arial'; // Set the font style and size.
|
|
543
|
+
this.ctx.fillStyle = 'black'; // Set the text color.
|
|
544
|
+
this.ctx.textAlign = 'center'; // Align text to the center.
|
|
545
|
+
this.ctx.textBaseline = 'middle'; // Align text vertically in the middle.
|
|
546
|
+
this.ctx.fillText(`${properties.elementType} ${properties.elementNumber} - ${properties.distance} ${properties.unit}`, 0, 0);
|
|
547
|
+
this.ctx.restore(); // Restore the previous canvas state.
|
|
548
|
+
if (properties.distance >= 4) {
|
|
549
|
+
// Define the midpoints of the left and right edges of the bounding box.
|
|
550
|
+
const centerX = textX;
|
|
551
|
+
const centerY = textY;
|
|
552
|
+
const rightX = (boxPoints[1].x + boxPoints[2].x) / 2;
|
|
553
|
+
const rightY = (boxPoints[1].y + boxPoints[2].y) / 2;
|
|
554
|
+
const leftX = (boxPoints[0].x + boxPoints[3].x) / 2;
|
|
555
|
+
const leftY = (boxPoints[0].y + boxPoints[3].y) / 2;
|
|
556
|
+
// Helper function to adjust points by a specific distance.
|
|
557
|
+
function adjustPoint(x1, y1, x2, y2, distance) {
|
|
558
|
+
const angle = Math.atan2(y2 - y1, x2 - x1); // Calculate the angle.
|
|
559
|
+
return {
|
|
560
|
+
x: x1 + Math.cos(angle) * distance,
|
|
561
|
+
y: y1 + Math.sin(angle) * distance, // Adjust Y by distance.
|
|
562
|
+
};
|
|
563
|
+
}
|
|
564
|
+
// Define the arrow line start and end points for the right side.
|
|
565
|
+
const rightStart = adjustPoint(centerX, centerY, rightX, rightY, 50);
|
|
566
|
+
const rightEnd = adjustPoint(rightX, rightY, centerX, centerY, 10);
|
|
567
|
+
// Define the arrow line start and end points for the left side.
|
|
568
|
+
const leftStart = adjustPoint(centerX, centerY, leftX, leftY, 50);
|
|
569
|
+
const leftEnd = adjustPoint(leftX, leftY, centerX, centerY, 10);
|
|
570
|
+
// Draw the right arrow.
|
|
571
|
+
this.ctx.beginPath();
|
|
572
|
+
this.ctx.moveTo(rightStart.x, rightStart.y);
|
|
573
|
+
this.ctx.lineTo(rightEnd.x, rightEnd.y);
|
|
574
|
+
this.ctx.strokeStyle = 'black'; // Set the arrow line color.
|
|
575
|
+
this.ctx.stroke(); // Draw the arrow line.
|
|
576
|
+
let rightAngle = Math.atan2(rightEnd.y - rightStart.y, rightEnd.x - rightStart.x);
|
|
577
|
+
drawArrowhead(this.ctx, rightEnd.x, rightEnd.y, rightAngle); // Draw the arrowhead.
|
|
578
|
+
// Draw the left arrow.
|
|
579
|
+
this.ctx.beginPath();
|
|
580
|
+
this.ctx.moveTo(leftStart.x, leftStart.y);
|
|
581
|
+
this.ctx.lineTo(leftEnd.x, leftEnd.y);
|
|
582
|
+
this.ctx.strokeStyle = 'black'; // Set the arrow line color.
|
|
583
|
+
this.ctx.stroke(); // Draw the arrow line.
|
|
584
|
+
let leftAngle = Math.atan2(leftEnd.y - leftStart.y, leftEnd.x - leftStart.x);
|
|
585
|
+
drawArrowhead(this.ctx, leftEnd.x, leftEnd.y, leftAngle); // Draw the arrowhead.
|
|
586
|
+
}
|
|
587
|
+
// For Entrance
|
|
588
|
+
if (properties.elementType === 'entrance') {
|
|
589
|
+
// Calculate the angle of the main line (edge) in radians.
|
|
590
|
+
const angle = Math.atan2(nextPoint.y - point.y, nextPoint.x - point.x);
|
|
591
|
+
// Add 15 degrees to the angle for the entrance line.
|
|
592
|
+
const entranceAngle = angle + (15 * Math.PI) / 180; // Convert 15 degrees to radians.
|
|
593
|
+
// Define the length of the entrance line.
|
|
594
|
+
const lineLength = this.convertToPixels(properties.distance, properties.unit) * 0.75;
|
|
595
|
+
// Calculate the endpoint of the entrance line based on the angle.
|
|
596
|
+
const endPoint = {
|
|
597
|
+
x: point.x + Math.cos(entranceAngle) * lineLength,
|
|
598
|
+
y: point.y + Math.sin(entranceAngle) * lineLength,
|
|
599
|
+
};
|
|
600
|
+
// Draw the entrance line.
|
|
601
|
+
this.ctx.beginPath();
|
|
602
|
+
this.ctx.moveTo(point.x, point.y);
|
|
603
|
+
this.ctx.lineTo(endPoint.x, endPoint.y);
|
|
604
|
+
this.selectedLineIndex === edgeIndex ? this.ctx.strokeStyle = '#008EDF' : this.ctx.strokeStyle = '#1D2939';
|
|
605
|
+
this.ctx.stroke();
|
|
606
|
+
}
|
|
607
|
+
});
|
|
608
|
+
this.ctx.restore(); // Restore the original canvas state.
|
|
609
|
+
}
|
|
610
|
+
onMouseWheel(event) {
|
|
611
|
+
if (event.ctrlKey) {
|
|
612
|
+
event.preventDefault();
|
|
613
|
+
const scaleFactor = event.deltaY < 0 ? 1.01 : 1 / 1.01;
|
|
614
|
+
this.adjustZoom(event, scaleFactor);
|
|
615
|
+
}
|
|
616
|
+
}
|
|
617
|
+
adjustZoom(event, scaleFactor) {
|
|
618
|
+
const rect = this.canvas.getBoundingClientRect();
|
|
619
|
+
const mouseX = (event.clientX - rect.left - this.panOffset.x) / this.scale;
|
|
620
|
+
const mouseY = (event.clientY - rect.top - this.panOffset.y) / this.scale;
|
|
621
|
+
this.scale *= scaleFactor;
|
|
622
|
+
this.panOffset.x -= mouseX * (scaleFactor - 1) * this.scale;
|
|
623
|
+
this.panOffset.y -= mouseY * (scaleFactor - 1) * this.scale;
|
|
624
|
+
this.redrawCanvas();
|
|
625
|
+
}
|
|
626
|
+
resetZoom() {
|
|
627
|
+
this.scale = 1;
|
|
628
|
+
this.panOffset = { x: 0, y: 0 };
|
|
629
|
+
this.redrawCanvas();
|
|
630
|
+
}
|
|
631
|
+
transformPoint(point) {
|
|
632
|
+
return {
|
|
633
|
+
x: point.x * this.scale + this.panOffset.x,
|
|
634
|
+
y: point.y * this.scale + this.panOffset.y,
|
|
635
|
+
};
|
|
636
|
+
}
|
|
637
|
+
drawLine(ctx, line) {
|
|
638
|
+
if (line.length < 2)
|
|
639
|
+
return;
|
|
640
|
+
ctx.beginPath();
|
|
641
|
+
ctx.moveTo(line[0].x, line[0].y);
|
|
642
|
+
for (let i = 1; i < line.length; i++) {
|
|
643
|
+
ctx.lineTo(line[i].x, line[i].y);
|
|
644
|
+
}
|
|
645
|
+
ctx.stroke();
|
|
646
|
+
}
|
|
647
|
+
redrawCanvas() {
|
|
648
|
+
this.drawGrid();
|
|
649
|
+
this.drawPolygon();
|
|
650
|
+
}
|
|
651
|
+
onOutsideClick(event) {
|
|
652
|
+
const clickedInside1 = event.target.closest('.elipsis-icon-dropdown');
|
|
653
|
+
if (!clickedInside1) {
|
|
654
|
+
this.lineOptionsSelect = { show: false, index: 0 };
|
|
655
|
+
}
|
|
656
|
+
const clickedInside2 = event.target.closest('.direction-dropdown');
|
|
657
|
+
if (!clickedInside2) {
|
|
658
|
+
this.directionSelect = { show: false, index: 0 };
|
|
659
|
+
}
|
|
660
|
+
const clickedInside3 = event.target.closest('.element-type-dropdown');
|
|
661
|
+
if (!clickedInside3) {
|
|
662
|
+
this.elementSelect = { show: false, index: 0 };
|
|
663
|
+
}
|
|
664
|
+
const clickedInside4 = event.target.closest('.widget-element-type-dropdown');
|
|
665
|
+
if (!clickedInside4) {
|
|
666
|
+
this.widgetElementSelect = { show: false };
|
|
667
|
+
}
|
|
668
|
+
const clickedInside5 = event.target.closest('.top-elipsis-menu');
|
|
669
|
+
if (!clickedInside5) {
|
|
670
|
+
this.layoutOptionSelect = { show: false };
|
|
671
|
+
}
|
|
672
|
+
const clickedInside6 = event.target.closest('.floor-select');
|
|
673
|
+
if (!clickedInside6) {
|
|
674
|
+
this.floorSelect = { show: false, deleteIndex: null };
|
|
675
|
+
}
|
|
676
|
+
}
|
|
677
|
+
toggleLineOptionsSelect(index) {
|
|
678
|
+
this.lineOptionsSelect = {
|
|
679
|
+
show: this.lineOptionsSelect.index !== index || !this.lineOptionsSelect.show,
|
|
680
|
+
index,
|
|
681
|
+
};
|
|
682
|
+
}
|
|
683
|
+
toggleDirectionSelect(index) {
|
|
684
|
+
this.directionSelect = {
|
|
685
|
+
show: this.directionSelect.index !== index || !this.directionSelect.show,
|
|
686
|
+
index,
|
|
687
|
+
};
|
|
688
|
+
}
|
|
689
|
+
toggleElementSelect(index) {
|
|
690
|
+
this.elementSelect = {
|
|
691
|
+
show: this.elementSelect.index !== index || !this.elementSelect.show,
|
|
692
|
+
index,
|
|
693
|
+
};
|
|
694
|
+
}
|
|
695
|
+
toggleWidgetElementSelect() {
|
|
696
|
+
this.widgetElementSelect = {
|
|
697
|
+
show: !this.widgetElementSelect.show,
|
|
698
|
+
};
|
|
699
|
+
}
|
|
700
|
+
toggleLayoutOptionSelect() {
|
|
701
|
+
this.layoutOptionSelect = {
|
|
702
|
+
show: !this.layoutOptionSelect.show,
|
|
703
|
+
};
|
|
704
|
+
}
|
|
705
|
+
toggleFloorSelect() {
|
|
706
|
+
this.floorSelect = {
|
|
707
|
+
show: !this.floorSelect.show,
|
|
708
|
+
deleteIndex: null
|
|
709
|
+
};
|
|
710
|
+
}
|
|
711
|
+
drop(event) {
|
|
712
|
+
this.saveStateToUndo();
|
|
713
|
+
moveItemInArray(this.layoutPolygon, event.previousIndex, event.currentIndex);
|
|
714
|
+
const instructions = this.layoutPolygon.map((segment) => {
|
|
715
|
+
const [point1, point2, properties] = segment;
|
|
716
|
+
return properties;
|
|
717
|
+
});
|
|
718
|
+
this.generateLayoutPolygon(instructions);
|
|
719
|
+
this.redoStack = [];
|
|
720
|
+
}
|
|
721
|
+
snapToGrid(value, gridSize) {
|
|
722
|
+
return Math.round(value / gridSize) * gridSize;
|
|
723
|
+
}
|
|
724
|
+
isPointInPolygon(point, polygon) {
|
|
725
|
+
let { x, y } = point;
|
|
726
|
+
let inside = false;
|
|
727
|
+
for (let i = 0, j = polygon.length - 1; i < polygon.length; j = i++) {
|
|
728
|
+
const xi = polygon[i].x, yi = polygon[i].y;
|
|
729
|
+
const xj = polygon[j].x, yj = polygon[j].y;
|
|
730
|
+
const onEdge = (y - yi) * (xj - xi) === (x - xi) * (yj - yi) &&
|
|
731
|
+
Math.min(xi, xj) <= x && x <= Math.max(xi, xj) &&
|
|
732
|
+
Math.min(yi, yj) <= y && y <= Math.max(yi, yj);
|
|
733
|
+
if (onEdge) {
|
|
734
|
+
return true;
|
|
735
|
+
}
|
|
736
|
+
const intersect = ((yi > y) !== (yj > y)) &&
|
|
737
|
+
(x < (xj - xi) * (y - yi) / (yj - yi) + xi);
|
|
738
|
+
if (intersect)
|
|
739
|
+
inside = !inside;
|
|
740
|
+
}
|
|
741
|
+
return inside;
|
|
742
|
+
}
|
|
743
|
+
movePointWithAngle() {
|
|
744
|
+
if (this.movePixels <= 0)
|
|
745
|
+
return;
|
|
746
|
+
this.saveStateToUndo();
|
|
747
|
+
let radians;
|
|
748
|
+
switch (this.moveDirection) {
|
|
749
|
+
case 'up':
|
|
750
|
+
radians = ((180 - this.moveAngle) * Math.PI) / 180;
|
|
751
|
+
break;
|
|
752
|
+
case 'left':
|
|
753
|
+
radians = ((270 - this.moveAngle) * Math.PI) / 180;
|
|
754
|
+
break;
|
|
755
|
+
case 'down':
|
|
756
|
+
radians = ((360 - this.moveAngle) * Math.PI) / 180;
|
|
757
|
+
break;
|
|
758
|
+
case 'right':
|
|
759
|
+
radians = ((90 - this.moveAngle) * Math.PI) / 180;
|
|
760
|
+
break;
|
|
761
|
+
default:
|
|
762
|
+
return;
|
|
763
|
+
}
|
|
764
|
+
if (this.selectedLine) {
|
|
765
|
+
const lineIndex = ((array1 = this.layoutPolygon, array2 = this.selectedLine) => {
|
|
766
|
+
return array1.findIndex(innerArray => innerArray.length === array2.length &&
|
|
767
|
+
innerArray.every((item, index) => JSON.stringify(item) === JSON.stringify(array2[index])));
|
|
768
|
+
})();
|
|
769
|
+
const [start, end, properties] = this.layoutPolygon[lineIndex];
|
|
770
|
+
const newX = start.x + Math.cos(radians) * this.convertToPixels(this.movePixels, this.unit);
|
|
771
|
+
const newY = start.y - Math.sin(radians) * this.convertToPixels(this.movePixels, this.unit);
|
|
772
|
+
const snappedX = this.snapToGrid(newX, this.gridWidth);
|
|
773
|
+
const snappedY = this.snapToGrid(newY, this.gridHeight);
|
|
774
|
+
this.layoutPolygon[lineIndex][1].x = snappedX;
|
|
775
|
+
this.layoutPolygon[lineIndex][1].y = snappedY;
|
|
776
|
+
this.layoutPolygon[lineIndex][2].angle = this.moveAngle;
|
|
777
|
+
this.layoutPolygon[lineIndex][2].direction = this.moveDirection;
|
|
778
|
+
this.layoutPolygon[lineIndex][2].distance = this.movePixels;
|
|
779
|
+
this.layoutPolygon[lineIndex][2].elementType = this.elementType;
|
|
780
|
+
this.redrawCanvas();
|
|
781
|
+
this.closeWidget();
|
|
782
|
+
this.selectedLine = null;
|
|
783
|
+
}
|
|
784
|
+
else {
|
|
785
|
+
const lastLine = this.layoutPolygon[this.layoutPolygon.length - 1];
|
|
786
|
+
const newX = lastLine[1].x + Math.cos(radians) * this.convertToPixels(this.movePixels, this.unit);
|
|
787
|
+
const newY = lastLine[1].y - Math.sin(radians) * this.convertToPixels(this.movePixels, this.unit);
|
|
788
|
+
const snappedX = this.snapToGrid(newX, this.gridWidth);
|
|
789
|
+
const snappedY = this.snapToGrid(newY, this.gridHeight);
|
|
790
|
+
const newPoint = { x: snappedX, y: snappedY };
|
|
791
|
+
if (this.layoutPolygon.length > 0) {
|
|
792
|
+
const lastPoint = lastLine[1];
|
|
793
|
+
const firstPoint = this.layoutPolygon[0][0];
|
|
794
|
+
if (newPoint.x === firstPoint.x && newPoint.y === firstPoint.y) {
|
|
795
|
+
this.layoutPolygon.push([lastPoint, newPoint, { elementType: this.elementType, distance: this.movePixels, unit: this.unit, direction: this.moveDirection, angle: this.moveAngle, elementNumber: this.getMaxElementNumber(this.layoutPolygon, this.elementType) }]);
|
|
796
|
+
this.closeWidget();
|
|
797
|
+
}
|
|
798
|
+
else if (!this.layoutPolygon.some(line => (line[0].x === newPoint.x && line[0].y === newPoint.y) ||
|
|
799
|
+
(line[1].x === newPoint.x && line[1].y === newPoint.y))) {
|
|
800
|
+
if (this.layoutPolygon.length === 1 && this.layoutPolygon[0][0].x === this.layoutPolygon[0][1].x && this.layoutPolygon[0][0].y === this.layoutPolygon[0][1].y) {
|
|
801
|
+
this.layoutPolygon[0] = [this.layoutPolygon[0][0], newPoint, { elementType: this.elementType, distance: this.movePixels, unit: this.unit, direction: this.moveDirection, angle: this.moveAngle, elementNumber: 1 }];
|
|
802
|
+
}
|
|
803
|
+
else {
|
|
804
|
+
this.layoutPolygon.push([lastPoint, newPoint, { elementType: this.elementType, distance: this.movePixels, unit: this.unit, direction: this.moveDirection, angle: this.moveAngle, elementNumber: this.getMaxElementNumber(this.layoutPolygon, this.elementType) }]);
|
|
805
|
+
}
|
|
806
|
+
this.openWidget(newPoint);
|
|
807
|
+
}
|
|
808
|
+
}
|
|
809
|
+
this.redoStack = [];
|
|
810
|
+
this.cd.detectChanges();
|
|
811
|
+
this.redrawCanvas();
|
|
812
|
+
}
|
|
813
|
+
}
|
|
814
|
+
getMaxElementNumber(data, elementType) {
|
|
815
|
+
if (!Array.isArray(data)) {
|
|
816
|
+
throw new Error("Invalid data format: data should be an array.");
|
|
817
|
+
}
|
|
818
|
+
return Math.round(data.reduce((maxNumber, segment) => {
|
|
819
|
+
if (Array.isArray(segment)) {
|
|
820
|
+
const element = segment.find(item => item.elementType === elementType);
|
|
821
|
+
if (element && typeof element.elementNumber === 'number') {
|
|
822
|
+
maxNumber = Math.max(maxNumber, element.elementNumber);
|
|
823
|
+
}
|
|
824
|
+
}
|
|
825
|
+
return maxNumber;
|
|
826
|
+
}, 0)) + 1;
|
|
827
|
+
}
|
|
828
|
+
onMouseDown(event) {
|
|
829
|
+
const rect = this.canvas.getBoundingClientRect();
|
|
830
|
+
const mouseX = event.clientX - rect.left;
|
|
831
|
+
const mouseY = event.clientY - rect.top;
|
|
832
|
+
for (const line of this.layoutPolygon) {
|
|
833
|
+
const point = line[0];
|
|
834
|
+
const nextPoint = line[1];
|
|
835
|
+
const dx = nextPoint.x - point.x;
|
|
836
|
+
const dy = nextPoint.y - point.y;
|
|
837
|
+
const length = Math.sqrt(dx * dx + dy * dy);
|
|
838
|
+
const offsetX = (dy / length) * 20;
|
|
839
|
+
const offsetY = (-dx / length) * 20;
|
|
840
|
+
const boxCorners = [
|
|
841
|
+
{ x: point.x, y: point.y },
|
|
842
|
+
{ x: nextPoint.x, y: nextPoint.y },
|
|
843
|
+
{ x: nextPoint.x + offsetX, y: nextPoint.y + offsetY },
|
|
844
|
+
{ x: point.x + offsetX, y: point.y + offsetY }
|
|
845
|
+
];
|
|
846
|
+
if (this.isPointInPolygon({ x: mouseX, y: mouseY }, boxCorners)) {
|
|
847
|
+
for (let i = 0; i < this.layoutPolygon.length; i++) {
|
|
848
|
+
const [start, end, properties] = this.layoutPolygon[i];
|
|
849
|
+
if (this.isLineEqual(start, end, boxCorners[0], boxCorners[1], 0)) {
|
|
850
|
+
this.selectLine(line, i);
|
|
851
|
+
return;
|
|
852
|
+
}
|
|
853
|
+
}
|
|
854
|
+
}
|
|
855
|
+
}
|
|
856
|
+
if (this.layoutPolygon.length === 1 && this.layoutPolygon[0][0].x === this.layoutPolygon[0][1].x && this.layoutPolygon[0][0].y === this.layoutPolygon[0][1].y) {
|
|
857
|
+
return;
|
|
858
|
+
}
|
|
859
|
+
this.selectedLine = null;
|
|
860
|
+
this.selectedLineIndex = null;
|
|
861
|
+
this.redrawCanvas();
|
|
862
|
+
this.closeWidget();
|
|
863
|
+
}
|
|
864
|
+
selectLine(line, index) {
|
|
865
|
+
const [start, end, properties] = line;
|
|
866
|
+
this.selectedLine = line;
|
|
867
|
+
this.selectedLineIndex = index;
|
|
868
|
+
this.elementType = properties.elementType;
|
|
869
|
+
this.movePixels = properties.distance;
|
|
870
|
+
this.moveDirection = properties.direction;
|
|
871
|
+
this.moveAngle = properties.angle;
|
|
872
|
+
this.unit = properties.unit;
|
|
873
|
+
this.openWidget(end);
|
|
874
|
+
this.redrawCanvas();
|
|
875
|
+
}
|
|
876
|
+
openWidget(position, offset = { up: 0, right: 5, down: 15, left: 0, }) {
|
|
877
|
+
this.popupVisible = true;
|
|
878
|
+
const adjustedPosition = {
|
|
879
|
+
x: position.x + offset.right + offset.left,
|
|
880
|
+
y: position.y + offset.up + offset.down,
|
|
881
|
+
};
|
|
882
|
+
this.popupPosition = adjustedPosition;
|
|
883
|
+
this.scrollToCanvasPosition(adjustedPosition);
|
|
884
|
+
setTimeout(() => {
|
|
885
|
+
this.drawWidgetRing();
|
|
886
|
+
this.updateWidgetPointer();
|
|
887
|
+
}, 500);
|
|
888
|
+
}
|
|
889
|
+
closeWidget() {
|
|
890
|
+
this.popupVisible = false;
|
|
891
|
+
}
|
|
892
|
+
onMouseMove(event) {
|
|
893
|
+
const rect = this.canvas.getBoundingClientRect();
|
|
894
|
+
const mouseX = event.clientX - rect.left;
|
|
895
|
+
const mouseY = event.clientY - rect.top;
|
|
896
|
+
let hoveredPolygonBox = this.layoutPolygon.some(line => {
|
|
897
|
+
const point = line[0];
|
|
898
|
+
const nextPoint = line[1];
|
|
899
|
+
const dx = nextPoint.x - point.x;
|
|
900
|
+
const dy = nextPoint.y - point.y;
|
|
901
|
+
const length = Math.sqrt(dx * dx + dy * dy);
|
|
902
|
+
const offsetX = (dy / length) * 20;
|
|
903
|
+
const offsetY = (-dx / length) * 20;
|
|
904
|
+
const boxCorners = [
|
|
905
|
+
{ x: point.x, y: point.y },
|
|
906
|
+
{ x: nextPoint.x, y: nextPoint.y },
|
|
907
|
+
{ x: nextPoint.x + offsetX, y: nextPoint.y + offsetY },
|
|
908
|
+
{ x: point.x + offsetX, y: point.y + offsetY }
|
|
909
|
+
];
|
|
910
|
+
return this.isPointInPolygon({ x: mouseX, y: mouseY }, boxCorners);
|
|
911
|
+
});
|
|
912
|
+
this.canvas.style.cursor = hoveredPolygonBox ? 'pointer' : 'default';
|
|
913
|
+
}
|
|
914
|
+
drawLineWithLength(start, end) {
|
|
915
|
+
const midX = (start.x + end.x) / 2;
|
|
916
|
+
const midY = (start.y + end.y) / 2;
|
|
917
|
+
const distance = Math.sqrt(Math.pow(end.x - start.x, 2) + Math.pow(end.y - start.y, 2)).toFixed(0);
|
|
918
|
+
const textSpacing = 10;
|
|
919
|
+
let textX = midX;
|
|
920
|
+
let textY = midY;
|
|
921
|
+
if (start.y === end.y) {
|
|
922
|
+
textY += textSpacing;
|
|
923
|
+
}
|
|
924
|
+
else if (start.x === end.x) {
|
|
925
|
+
textX += textSpacing;
|
|
926
|
+
}
|
|
927
|
+
else {
|
|
928
|
+
const angle = Math.atan2(end.y - start.y, end.x - start.x);
|
|
929
|
+
textX += textSpacing * Math.cos(angle);
|
|
930
|
+
textY += textSpacing * Math.sin(angle);
|
|
931
|
+
}
|
|
932
|
+
this.ctx.beginPath();
|
|
933
|
+
this.ctx.moveTo(start.x, start.y);
|
|
934
|
+
this.ctx.lineTo(end.x, end.y);
|
|
935
|
+
this.ctx.strokeStyle = 'black';
|
|
936
|
+
this.ctx.stroke();
|
|
937
|
+
this.ctx.save();
|
|
938
|
+
if (start.y === end.y) {
|
|
939
|
+
this.ctx.font = '12px Arial';
|
|
940
|
+
this.ctx.fillStyle = 'black';
|
|
941
|
+
this.ctx.fillText(`${distance}px`, textX, textY);
|
|
942
|
+
}
|
|
943
|
+
else if (start.x === end.x) {
|
|
944
|
+
this.ctx.translate(textX, textY);
|
|
945
|
+
this.ctx.rotate(-Math.PI / 2);
|
|
946
|
+
this.ctx.font = '12px Arial';
|
|
947
|
+
this.ctx.fillStyle = 'black';
|
|
948
|
+
this.ctx.fillText(`${distance}px`, 0, 0);
|
|
949
|
+
this.ctx.restore();
|
|
950
|
+
}
|
|
951
|
+
else {
|
|
952
|
+
this.ctx.font = '12px Arial';
|
|
953
|
+
this.ctx.fillStyle = 'black';
|
|
954
|
+
this.ctx.fillText(`${distance}px`, textX, textY);
|
|
955
|
+
}
|
|
956
|
+
this.ctx.restore();
|
|
957
|
+
}
|
|
958
|
+
layoutLengthPreview() {
|
|
959
|
+
if (this.layoutPolygon.length === 1 && this.layoutPolygon[0][0].x === this.layoutPolygon[0][1].x && this.layoutPolygon[0][0].y === this.layoutPolygon[0][1].y) {
|
|
960
|
+
return;
|
|
961
|
+
}
|
|
962
|
+
this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
|
|
963
|
+
let radians;
|
|
964
|
+
switch (this.moveDirection) {
|
|
965
|
+
case 'up':
|
|
966
|
+
radians = ((180 - this.moveAngle) * Math.PI) / 180;
|
|
967
|
+
break;
|
|
968
|
+
case 'left':
|
|
969
|
+
radians = ((270 - this.moveAngle) * Math.PI) / 180;
|
|
970
|
+
break;
|
|
971
|
+
case 'down':
|
|
972
|
+
radians = ((360 - this.moveAngle) * Math.PI) / 180;
|
|
973
|
+
break;
|
|
974
|
+
case 'right':
|
|
975
|
+
radians = ((90 - this.moveAngle) * Math.PI) / 180;
|
|
976
|
+
break;
|
|
977
|
+
default:
|
|
978
|
+
return;
|
|
979
|
+
}
|
|
980
|
+
const lastLine = this.layoutPolygon[this.layoutPolygon.length - 1];
|
|
981
|
+
const newX = lastLine[1].x + Math.cos(radians) * this.convertToPixels(this.movePixels, this.unit);
|
|
982
|
+
const newY = lastLine[1].y - Math.sin(radians) * this.convertToPixels(this.movePixels, this.unit);
|
|
983
|
+
const snappedX = this.snapToGrid(newX, this.gridWidth);
|
|
984
|
+
const snappedY = this.snapToGrid(newY, this.gridHeight);
|
|
985
|
+
const previewPoint = { x: snappedX, y: snappedY };
|
|
986
|
+
this.redrawCanvas();
|
|
987
|
+
this.drawLineWithLength(lastLine[1], previewPoint);
|
|
988
|
+
}
|
|
989
|
+
rotatePolygons() {
|
|
990
|
+
this.saveStateToUndo();
|
|
991
|
+
this.closeWidget();
|
|
992
|
+
const angle = 90;
|
|
993
|
+
this.cumulativeRotation = (this.cumulativeRotation + angle) % 360;
|
|
994
|
+
const rotatePoint = (point, center, angle) => {
|
|
995
|
+
const dx = point.x - center.x;
|
|
996
|
+
const dy = point.y - center.y;
|
|
997
|
+
const radianAngle = angle * (Math.PI / 180);
|
|
998
|
+
const cos = Math.cos(radianAngle);
|
|
999
|
+
const sin = Math.sin(radianAngle);
|
|
1000
|
+
return {
|
|
1001
|
+
x: center.x + dx * cos - dy * sin,
|
|
1002
|
+
y: center.y + dx * sin + dy * cos,
|
|
1003
|
+
};
|
|
1004
|
+
};
|
|
1005
|
+
const getPolygonLineCenter = (line) => {
|
|
1006
|
+
const [start, end] = line;
|
|
1007
|
+
return {
|
|
1008
|
+
x: (start.x + end.x) / 2,
|
|
1009
|
+
y: (start.y + end.y) / 2,
|
|
1010
|
+
};
|
|
1011
|
+
};
|
|
1012
|
+
const getOverallCenter = (lines) => {
|
|
1013
|
+
const sum = lines.reduce((acc, line) => {
|
|
1014
|
+
const center = getPolygonLineCenter(line);
|
|
1015
|
+
acc.x += center.x;
|
|
1016
|
+
acc.y += center.y;
|
|
1017
|
+
return acc;
|
|
1018
|
+
}, { x: 0, y: 0 });
|
|
1019
|
+
return { x: sum.x / lines.length, y: sum.y / lines.length };
|
|
1020
|
+
};
|
|
1021
|
+
const overallCenter = getOverallCenter(this.layoutPolygon);
|
|
1022
|
+
this.layoutPolygon = this.layoutPolygon.map((line) => {
|
|
1023
|
+
const [start, end, properties] = line;
|
|
1024
|
+
return [
|
|
1025
|
+
rotatePoint(start, overallCenter, angle),
|
|
1026
|
+
rotatePoint(end, overallCenter, angle),
|
|
1027
|
+
properties,
|
|
1028
|
+
];
|
|
1029
|
+
});
|
|
1030
|
+
this.redoStack = [];
|
|
1031
|
+
this.redrawCanvas();
|
|
1032
|
+
}
|
|
1033
|
+
resetOrientation() {
|
|
1034
|
+
if (this.cumulativeRotation === 0)
|
|
1035
|
+
return;
|
|
1036
|
+
const angleToReset = -this.cumulativeRotation;
|
|
1037
|
+
const resetRotation = (point, center, angle) => {
|
|
1038
|
+
const dx = point.x - center.x;
|
|
1039
|
+
const dy = point.y - center.y;
|
|
1040
|
+
const radianAngle = angle * (Math.PI / 180);
|
|
1041
|
+
const cos = Math.cos(radianAngle);
|
|
1042
|
+
const sin = Math.sin(radianAngle);
|
|
1043
|
+
return {
|
|
1044
|
+
x: center.x + dx * cos - dy * sin,
|
|
1045
|
+
y: center.y + dx * sin + dy * cos,
|
|
1046
|
+
};
|
|
1047
|
+
};
|
|
1048
|
+
const getPolygonLineCenter = (line) => {
|
|
1049
|
+
const [start, end] = line;
|
|
1050
|
+
return {
|
|
1051
|
+
x: (start.x + end.x) / 2,
|
|
1052
|
+
y: (start.y + end.y) / 2,
|
|
1053
|
+
};
|
|
1054
|
+
};
|
|
1055
|
+
const getOverallCenter = (lines) => {
|
|
1056
|
+
const sum = lines.reduce((acc, line) => {
|
|
1057
|
+
const center = getPolygonLineCenter(line);
|
|
1058
|
+
acc.x += center.x;
|
|
1059
|
+
acc.y += center.y;
|
|
1060
|
+
return acc;
|
|
1061
|
+
}, { x: 0, y: 0 });
|
|
1062
|
+
return { x: sum.x / lines.length, y: sum.y / lines.length };
|
|
1063
|
+
};
|
|
1064
|
+
const overallCenter = getOverallCenter(this.layoutPolygon);
|
|
1065
|
+
this.layoutPolygon = this.layoutPolygon.map((line) => {
|
|
1066
|
+
const [start, end, properties] = line;
|
|
1067
|
+
return [
|
|
1068
|
+
resetRotation(start, overallCenter, angleToReset),
|
|
1069
|
+
resetRotation(end, overallCenter, angleToReset),
|
|
1070
|
+
properties,
|
|
1071
|
+
];
|
|
1072
|
+
});
|
|
1073
|
+
this.cumulativeRotation = 0; // Reset rotation tracker
|
|
1074
|
+
this.redrawCanvas();
|
|
1075
|
+
}
|
|
1076
|
+
isLineEqual(start1, end1, start2, end2, tolerance) {
|
|
1077
|
+
const arePointsEqual = (p1, p2) => Math.abs(p1.x - p2.x) <= tolerance && Math.abs(p1.y - p2.y) <= tolerance;
|
|
1078
|
+
return ((arePointsEqual(start1, start2) && arePointsEqual(end1, end2)) ||
|
|
1079
|
+
(arePointsEqual(start1, end2) && arePointsEqual(end1, start2)));
|
|
1080
|
+
}
|
|
1081
|
+
convertToPixels(value, unit) {
|
|
1082
|
+
const PIXELS_PER_METER = this.pixelPerMetre;
|
|
1083
|
+
const PIXELS_PER_FOOT = PIXELS_PER_METER / 3.28084;
|
|
1084
|
+
if (typeof value !== 'number' || value < 0) {
|
|
1085
|
+
throw new Error('Value must be a non-negative number');
|
|
1086
|
+
}
|
|
1087
|
+
switch (unit) {
|
|
1088
|
+
case 'm':
|
|
1089
|
+
return value * PIXELS_PER_METER;
|
|
1090
|
+
case 'ft':
|
|
1091
|
+
return value * PIXELS_PER_FOOT;
|
|
1092
|
+
default:
|
|
1093
|
+
throw new Error("Invalid unit. Supported units are 'mt' for meters and 'ft' for feet.");
|
|
1094
|
+
}
|
|
1095
|
+
}
|
|
1096
|
+
onElementTypeChange(type, index) {
|
|
1097
|
+
const [point1, point2, properties] = this.layoutPolygon[index];
|
|
1098
|
+
properties.elementType = type;
|
|
1099
|
+
this.layoutPolygon[index] = [point1, point2, properties];
|
|
1100
|
+
this.elementSelect = { show: false, index: 0 };
|
|
1101
|
+
this.redrawCanvas();
|
|
1102
|
+
}
|
|
1103
|
+
onDistanceChange(value, index) {
|
|
1104
|
+
this.saveStateToUndo();
|
|
1105
|
+
const [point1, point2, properties] = this.layoutPolygon[index];
|
|
1106
|
+
let radians;
|
|
1107
|
+
switch (properties.direction) {
|
|
1108
|
+
case 'up':
|
|
1109
|
+
radians = ((180 - properties.angle) * Math.PI) / 180;
|
|
1110
|
+
break;
|
|
1111
|
+
case 'left':
|
|
1112
|
+
radians = ((270 - properties.angle) * Math.PI) / 180;
|
|
1113
|
+
break;
|
|
1114
|
+
case 'down':
|
|
1115
|
+
radians = ((360 - properties.angle) * Math.PI) / 180;
|
|
1116
|
+
break;
|
|
1117
|
+
case 'right':
|
|
1118
|
+
radians = ((90 - properties.angle) * Math.PI) / 180;
|
|
1119
|
+
break;
|
|
1120
|
+
default:
|
|
1121
|
+
return;
|
|
1122
|
+
}
|
|
1123
|
+
if (value === 'increment') {
|
|
1124
|
+
const newX = point2.x + Math.cos(radians) * this.convertToPixels(1, properties.unit);
|
|
1125
|
+
const newY = point2.y - Math.sin(radians) * this.convertToPixels(1, properties.unit);
|
|
1126
|
+
const snappedX = this.snapToGrid(newX, this.gridWidth);
|
|
1127
|
+
const snappedY = this.snapToGrid(newY, this.gridHeight);
|
|
1128
|
+
const newpoint = { x: snappedX, y: snappedY };
|
|
1129
|
+
point2.x = newpoint.x;
|
|
1130
|
+
point2.y = newpoint.y;
|
|
1131
|
+
properties.distance = properties.distance + 1;
|
|
1132
|
+
}
|
|
1133
|
+
else if (value === 'decrement') {
|
|
1134
|
+
const newX = point2.x - Math.cos(radians) * this.convertToPixels(1, properties.unit);
|
|
1135
|
+
const newY = point2.y + Math.sin(radians) * this.convertToPixels(1, properties.unit);
|
|
1136
|
+
const snappedX = this.snapToGrid(newX, this.gridWidth);
|
|
1137
|
+
const snappedY = this.snapToGrid(newY, this.gridHeight);
|
|
1138
|
+
const newpoint = { x: snappedX, y: snappedY };
|
|
1139
|
+
if (properties.distance > 1) {
|
|
1140
|
+
point2.x = newpoint.x;
|
|
1141
|
+
point2.y = newpoint.y;
|
|
1142
|
+
properties.distance = properties.distance - 1;
|
|
1143
|
+
}
|
|
1144
|
+
}
|
|
1145
|
+
this.layoutPolygon[index] = [point1, point2, properties];
|
|
1146
|
+
this.lineOptionsSelect = { show: false, index: 0 };
|
|
1147
|
+
this.redoStack = [];
|
|
1148
|
+
this.redrawCanvas();
|
|
1149
|
+
}
|
|
1150
|
+
onWidgetDistanceChange(value) {
|
|
1151
|
+
if (value === 'increment') {
|
|
1152
|
+
this.movePixels = this.movePixels + 1;
|
|
1153
|
+
}
|
|
1154
|
+
else if (value === 'decrement') {
|
|
1155
|
+
if (this.movePixels > 1) {
|
|
1156
|
+
this.movePixels = this.movePixels - 1;
|
|
1157
|
+
}
|
|
1158
|
+
}
|
|
1159
|
+
}
|
|
1160
|
+
onWidgetAngleChange(value) {
|
|
1161
|
+
if (value === 'increment') {
|
|
1162
|
+
if (this.moveAngle < 180) {
|
|
1163
|
+
this.moveAngle = this.moveAngle + 5;
|
|
1164
|
+
}
|
|
1165
|
+
}
|
|
1166
|
+
else if (value === 'decrement') {
|
|
1167
|
+
if (this.moveAngle > 0) {
|
|
1168
|
+
this.moveAngle = this.moveAngle - 5;
|
|
1169
|
+
}
|
|
1170
|
+
}
|
|
1171
|
+
this.updateWidgetPointer();
|
|
1172
|
+
}
|
|
1173
|
+
onWidgetDirectionChange(direction) {
|
|
1174
|
+
this.moveDirection = direction;
|
|
1175
|
+
this.drawWidgetRing();
|
|
1176
|
+
this.updateWidgetPointer();
|
|
1177
|
+
}
|
|
1178
|
+
onDirectionChange(value, index) {
|
|
1179
|
+
this.saveStateToUndo();
|
|
1180
|
+
const [point1, point2, properties] = this.layoutPolygon[index];
|
|
1181
|
+
let radians;
|
|
1182
|
+
switch (value) {
|
|
1183
|
+
case 'up':
|
|
1184
|
+
radians = ((180 - properties.angle) * Math.PI) / 180;
|
|
1185
|
+
break;
|
|
1186
|
+
case 'left':
|
|
1187
|
+
radians = ((270 - properties.angle) * Math.PI) / 180;
|
|
1188
|
+
break;
|
|
1189
|
+
case 'down':
|
|
1190
|
+
radians = ((360 - properties.angle) * Math.PI) / 180;
|
|
1191
|
+
break;
|
|
1192
|
+
case 'right':
|
|
1193
|
+
radians = ((90 - properties.angle) * Math.PI) / 180;
|
|
1194
|
+
break;
|
|
1195
|
+
default:
|
|
1196
|
+
return;
|
|
1197
|
+
}
|
|
1198
|
+
const movementDistance = this.convertToPixels(properties.distance, properties.unit);
|
|
1199
|
+
const newX = point1.x + Math.cos(radians) * movementDistance;
|
|
1200
|
+
const newY = point1.y - Math.sin(radians) * movementDistance;
|
|
1201
|
+
const snappedX = this.snapToGrid(newX, this.gridWidth);
|
|
1202
|
+
const snappedY = this.snapToGrid(newY, this.gridHeight);
|
|
1203
|
+
point2.x = snappedX;
|
|
1204
|
+
point2.y = snappedY;
|
|
1205
|
+
properties.direction = value;
|
|
1206
|
+
this.layoutPolygon[index] = [point1, point2, properties];
|
|
1207
|
+
this.directionSelect = { show: false, index: 0 };
|
|
1208
|
+
this.redoStack = [];
|
|
1209
|
+
this.redrawCanvas();
|
|
1210
|
+
}
|
|
1211
|
+
onLineDelete(index) {
|
|
1212
|
+
this.saveStateToUndo();
|
|
1213
|
+
this.layoutPolygon.splice(index, 1);
|
|
1214
|
+
this.redoStack = [];
|
|
1215
|
+
this.redrawCanvas();
|
|
1216
|
+
}
|
|
1217
|
+
onAddStep(index) {
|
|
1218
|
+
this.saveStateToUndo();
|
|
1219
|
+
const [point1, point2, properties] = this.layoutPolygon[index];
|
|
1220
|
+
let radians = ((90 - 90) * Math.PI) / 180;
|
|
1221
|
+
;
|
|
1222
|
+
const newX = point2.x + Math.cos(radians) * this.convertToPixels(1, this.unit);
|
|
1223
|
+
const newY = point2.y - Math.sin(radians) * this.convertToPixels(1, this.unit);
|
|
1224
|
+
const snappedX = this.snapToGrid(newX, this.gridWidth);
|
|
1225
|
+
const snappedY = this.snapToGrid(newY, this.gridHeight);
|
|
1226
|
+
const newpoint = { x: snappedX, y: snappedY };
|
|
1227
|
+
this.layoutPolygon.splice(index + 1, 0, [point2, newpoint,
|
|
1228
|
+
{ elementType: 'wall', distance: 1, unit: this.unit, direction: 'right', angle: 90, elementNumber: this.getMaxElementNumber(this.layoutPolygon, 'wall') }]);
|
|
1229
|
+
this.redoStack = [];
|
|
1230
|
+
this.redrawCanvas();
|
|
1231
|
+
this.lineOptionsSelect = { show: false, index: 0 };
|
|
1232
|
+
}
|
|
1233
|
+
onDuplicateStep(index) {
|
|
1234
|
+
this.redoStack = [];
|
|
1235
|
+
const [point1, point2, properties] = JSON.parse(JSON.stringify(this.layoutPolygon[index]));
|
|
1236
|
+
let radians;
|
|
1237
|
+
switch (properties.direction) {
|
|
1238
|
+
case 'up':
|
|
1239
|
+
radians = ((180 - properties.angle) * Math.PI) / 180;
|
|
1240
|
+
break;
|
|
1241
|
+
case 'left':
|
|
1242
|
+
radians = ((270 - properties.angle) * Math.PI) / 180;
|
|
1243
|
+
break;
|
|
1244
|
+
case 'down':
|
|
1245
|
+
radians = ((360 - properties.angle) * Math.PI) / 180;
|
|
1246
|
+
break;
|
|
1247
|
+
case 'right':
|
|
1248
|
+
radians = ((90 - properties.angle) * Math.PI) / 180;
|
|
1249
|
+
break;
|
|
1250
|
+
default:
|
|
1251
|
+
return;
|
|
1252
|
+
}
|
|
1253
|
+
const newX = point2.x + Math.cos(radians) * this.convertToPixels(properties.distance, properties.unit);
|
|
1254
|
+
const newY = point2.y - Math.sin(radians) * this.convertToPixels(properties.distance, properties.unit);
|
|
1255
|
+
const snappedX = this.snapToGrid(newX, this.gridWidth);
|
|
1256
|
+
const snappedY = this.snapToGrid(newY, this.gridHeight);
|
|
1257
|
+
const newpoint = { x: snappedX, y: snappedY };
|
|
1258
|
+
properties.elementNumber = this.getMaxElementNumber(this.layoutPolygon, properties.elementType);
|
|
1259
|
+
this.layoutPolygon.splice(index + 1, 0, [point2, newpoint, properties]);
|
|
1260
|
+
this.lineOptionsSelect = { show: false, index: 0 };
|
|
1261
|
+
this.redoStack = [];
|
|
1262
|
+
this.redrawCanvas();
|
|
1263
|
+
}
|
|
1264
|
+
scrollToCanvasPosition(coordinates) {
|
|
1265
|
+
const container = this.scrollContainerRef.nativeElement;
|
|
1266
|
+
const containerRect = container.getBoundingClientRect();
|
|
1267
|
+
const containerScrollLeft = container.scrollLeft;
|
|
1268
|
+
const containerScrollTop = container.scrollTop;
|
|
1269
|
+
const targetX = coordinates.x;
|
|
1270
|
+
const targetY = coordinates.y;
|
|
1271
|
+
const offset = {
|
|
1272
|
+
up: 100,
|
|
1273
|
+
down: 200,
|
|
1274
|
+
left: 100,
|
|
1275
|
+
right: 100,
|
|
1276
|
+
};
|
|
1277
|
+
const visibleLeft = containerScrollLeft + offset.left;
|
|
1278
|
+
const visibleRight = containerScrollLeft + containerRect.width - offset.right;
|
|
1279
|
+
const visibleTop = containerScrollTop + offset.up;
|
|
1280
|
+
const visibleBottom = containerScrollTop + containerRect.height - offset.down;
|
|
1281
|
+
const isXInView = targetX >= visibleLeft && targetX <= visibleRight;
|
|
1282
|
+
const isYInView = targetY >= visibleTop && targetY <= visibleBottom;
|
|
1283
|
+
if (!isXInView || !isYInView) {
|
|
1284
|
+
const adjustedX = Math.max(0, targetX - offset.left);
|
|
1285
|
+
const adjustedY = Math.max(0, targetY - offset.up);
|
|
1286
|
+
container.scrollTo({
|
|
1287
|
+
left: adjustedX,
|
|
1288
|
+
top: adjustedY,
|
|
1289
|
+
behavior: 'smooth',
|
|
1290
|
+
});
|
|
1291
|
+
}
|
|
1292
|
+
}
|
|
1293
|
+
onClearAll() {
|
|
1294
|
+
const modelRef = this.modalDef.open(ClearAllStepsComponent, { centered: true });
|
|
1295
|
+
modelRef.result.then((val) => {
|
|
1296
|
+
if (val.message === 'confirm') {
|
|
1297
|
+
this.toastService.getSuccessToast('Layout cleared successfully');
|
|
1298
|
+
this.undoStack = [];
|
|
1299
|
+
this.redoStack = [];
|
|
1300
|
+
this.initializeLayout();
|
|
1301
|
+
this.redrawCanvas();
|
|
1302
|
+
}
|
|
1303
|
+
});
|
|
1304
|
+
}
|
|
1305
|
+
onDeleteLayout() {
|
|
1306
|
+
const modelRef = this.modalDef.open(DeleteLayoutComponent, { centered: true });
|
|
1307
|
+
modelRef.result.then((val) => {
|
|
1308
|
+
if (val.message === 'confirm') {
|
|
1309
|
+
this.undoStack = [];
|
|
1310
|
+
this.redoStack = [];
|
|
1311
|
+
this.layoutPolygon = [];
|
|
1312
|
+
this.updateFloorLayout();
|
|
1313
|
+
this.initializeLayout();
|
|
1314
|
+
this.redrawCanvas();
|
|
1315
|
+
}
|
|
1316
|
+
});
|
|
1317
|
+
}
|
|
1318
|
+
async exportAsPng() {
|
|
1319
|
+
const padding = 100;
|
|
1320
|
+
const canvas = document.createElement('canvas');
|
|
1321
|
+
const ctx = canvas.getContext('2d');
|
|
1322
|
+
canvas.width = 10000;
|
|
1323
|
+
canvas.height = 10000;
|
|
1324
|
+
const centerX = canvas.width / 2 / this.scale;
|
|
1325
|
+
const centerY = canvas.height / 2 / this.scale;
|
|
1326
|
+
let currentPoint = {
|
|
1327
|
+
x: this.snapToGrid(centerX, this.gridHeight),
|
|
1328
|
+
y: this.snapToGrid(centerY, this.gridWidth),
|
|
1329
|
+
};
|
|
1330
|
+
const renderCanvas = async (layoutPolygon) => {
|
|
1331
|
+
const exportLayout = [];
|
|
1332
|
+
layoutPolygon.forEach((instruction) => {
|
|
1333
|
+
const radians = {
|
|
1334
|
+
up: ((180 - instruction.angle) * Math.PI) / 180,
|
|
1335
|
+
left: ((270 - instruction.angle) * Math.PI) / 180,
|
|
1336
|
+
down: ((360 - instruction.angle) * Math.PI) / 180,
|
|
1337
|
+
right: ((90 - instruction.angle) * Math.PI) / 180,
|
|
1338
|
+
}[instruction.direction];
|
|
1339
|
+
if (radians === undefined) {
|
|
1340
|
+
throw new Error(`Invalid direction: ${instruction.direction}`);
|
|
1341
|
+
}
|
|
1342
|
+
const distanceInPixels = this.convertToPixels(instruction.distance, instruction.unit);
|
|
1343
|
+
const newX = currentPoint.x + Math.cos(radians) * distanceInPixels;
|
|
1344
|
+
const newY = currentPoint.y - Math.sin(radians) * distanceInPixels;
|
|
1345
|
+
const newPoint = {
|
|
1346
|
+
x: this.snapToGrid(newX, this.gridWidth),
|
|
1347
|
+
y: this.snapToGrid(newY, this.gridHeight),
|
|
1348
|
+
};
|
|
1349
|
+
const lineSegment = [
|
|
1350
|
+
currentPoint,
|
|
1351
|
+
newPoint,
|
|
1352
|
+
{
|
|
1353
|
+
elementType: instruction.elementType,
|
|
1354
|
+
distance: instruction.distance,
|
|
1355
|
+
unit: instruction.unit,
|
|
1356
|
+
direction: instruction.direction,
|
|
1357
|
+
angle: instruction.angle,
|
|
1358
|
+
elementNumber: instruction.elementNumber,
|
|
1359
|
+
},
|
|
1360
|
+
];
|
|
1361
|
+
exportLayout.push(lineSegment);
|
|
1362
|
+
currentPoint = newPoint;
|
|
1363
|
+
});
|
|
1364
|
+
let minX = Infinity, minY = Infinity, maxX = -Infinity, maxY = -Infinity;
|
|
1365
|
+
exportLayout.forEach(([point1, point2]) => {
|
|
1366
|
+
[point1, point2].forEach((point) => {
|
|
1367
|
+
if (point.x !== undefined) {
|
|
1368
|
+
minX = Math.min(minX, point.x);
|
|
1369
|
+
maxX = Math.max(maxX, point.x);
|
|
1370
|
+
}
|
|
1371
|
+
if (point.y !== undefined) {
|
|
1372
|
+
minY = Math.min(minY, point.y);
|
|
1373
|
+
maxY = Math.max(maxY, point.y);
|
|
1374
|
+
}
|
|
1375
|
+
});
|
|
1376
|
+
});
|
|
1377
|
+
minX -= padding;
|
|
1378
|
+
minY -= padding;
|
|
1379
|
+
maxX += padding;
|
|
1380
|
+
maxY += padding;
|
|
1381
|
+
canvas.width = maxX - minX;
|
|
1382
|
+
canvas.height = maxY - minY;
|
|
1383
|
+
ctx.fillStyle = 'white';
|
|
1384
|
+
ctx.fillRect(0, 0, canvas.width, canvas.height);
|
|
1385
|
+
ctx.save();
|
|
1386
|
+
ctx.translate(-minX, -minY);
|
|
1387
|
+
ctx.scale(this.scale, this.scale);
|
|
1388
|
+
function drawArrowhead(ctx, x, y, angle) {
|
|
1389
|
+
const size = 5;
|
|
1390
|
+
ctx.save();
|
|
1391
|
+
ctx.translate(x, y);
|
|
1392
|
+
ctx.rotate(angle);
|
|
1393
|
+
ctx.beginPath();
|
|
1394
|
+
ctx.moveTo(0, 0);
|
|
1395
|
+
ctx.lineTo(-size, -size / 2);
|
|
1396
|
+
ctx.lineTo(-size, size / 2);
|
|
1397
|
+
ctx.closePath();
|
|
1398
|
+
ctx.fillStyle = 'black';
|
|
1399
|
+
ctx.fill();
|
|
1400
|
+
ctx.restore();
|
|
1401
|
+
}
|
|
1402
|
+
ctx.beginPath();
|
|
1403
|
+
exportLayout.forEach((edge, edgeIndex) => {
|
|
1404
|
+
const point = edge[0];
|
|
1405
|
+
const nextPoint = edge[1];
|
|
1406
|
+
const properties = edge[2];
|
|
1407
|
+
if (edgeIndex === 0)
|
|
1408
|
+
ctx.moveTo(point.x, point.y);
|
|
1409
|
+
ctx.lineTo(nextPoint.x, nextPoint.y);
|
|
1410
|
+
const dx = nextPoint.x - point.x;
|
|
1411
|
+
const dy = nextPoint.y - point.y;
|
|
1412
|
+
const length = Math.sqrt(dx * dx + dy * dy);
|
|
1413
|
+
const offsetX = (dy / length) * 20;
|
|
1414
|
+
const offsetY = (-dx / length) * 20;
|
|
1415
|
+
const boxPoints = [
|
|
1416
|
+
{ x: point.x, y: point.y },
|
|
1417
|
+
{ x: nextPoint.x, y: nextPoint.y },
|
|
1418
|
+
{ x: nextPoint.x + offsetX, y: nextPoint.y + offsetY },
|
|
1419
|
+
{ x: point.x + offsetX, y: point.y + offsetY },
|
|
1420
|
+
];
|
|
1421
|
+
ctx.beginPath();
|
|
1422
|
+
ctx.moveTo(boxPoints[0].x, boxPoints[0].y);
|
|
1423
|
+
boxPoints.forEach((pt, index) => {
|
|
1424
|
+
if (properties.elementType === 'entrance') {
|
|
1425
|
+
if (index < 2) {
|
|
1426
|
+
ctx.lineTo(pt.x, pt.y);
|
|
1427
|
+
}
|
|
1428
|
+
}
|
|
1429
|
+
else {
|
|
1430
|
+
ctx.lineTo(pt.x, pt.y);
|
|
1431
|
+
}
|
|
1432
|
+
});
|
|
1433
|
+
if (properties.elementType === 'opening') {
|
|
1434
|
+
ctx.closePath();
|
|
1435
|
+
ctx.fillStyle = '#F9FAFB';
|
|
1436
|
+
ctx.fill();
|
|
1437
|
+
ctx.strokeStyle = '#F9FAFB';
|
|
1438
|
+
ctx.stroke();
|
|
1439
|
+
}
|
|
1440
|
+
else {
|
|
1441
|
+
ctx.closePath();
|
|
1442
|
+
ctx.fillStyle = '#F9FAFB';
|
|
1443
|
+
ctx.fill();
|
|
1444
|
+
ctx.strokeStyle = '#1D2939';
|
|
1445
|
+
ctx.stroke();
|
|
1446
|
+
}
|
|
1447
|
+
const textX = (boxPoints[1].x + boxPoints[3].x) / 2;
|
|
1448
|
+
const textY = (boxPoints[1].y + boxPoints[3].y) / 2;
|
|
1449
|
+
ctx.save();
|
|
1450
|
+
ctx.translate(textX, textY);
|
|
1451
|
+
if (dx === 0) {
|
|
1452
|
+
ctx.rotate(-Math.PI / 2);
|
|
1453
|
+
}
|
|
1454
|
+
else if (dy !== 0) {
|
|
1455
|
+
const angle = Math.atan2(dy, dx);
|
|
1456
|
+
ctx.rotate(angle);
|
|
1457
|
+
}
|
|
1458
|
+
ctx.font = '12px Arial';
|
|
1459
|
+
ctx.fillStyle = 'black';
|
|
1460
|
+
ctx.textAlign = 'center';
|
|
1461
|
+
ctx.textBaseline = 'middle';
|
|
1462
|
+
ctx.fillText(`${properties.elementType} ${properties.elementNumber} - ${properties.distance} ${properties.unit}`, 0, 0);
|
|
1463
|
+
ctx.restore();
|
|
1464
|
+
if (properties.distance >= 4) {
|
|
1465
|
+
const centerX = textX;
|
|
1466
|
+
const centerY = textY;
|
|
1467
|
+
const rightX = (boxPoints[1].x + boxPoints[2].x) / 2;
|
|
1468
|
+
const rightY = (boxPoints[1].y + boxPoints[2].y) / 2;
|
|
1469
|
+
const leftX = (boxPoints[0].x + boxPoints[3].x) / 2;
|
|
1470
|
+
const leftY = (boxPoints[0].y + boxPoints[3].y) / 2;
|
|
1471
|
+
function adjustPoint(x1, y1, x2, y2, distance) {
|
|
1472
|
+
const angle = Math.atan2(y2 - y1, x2 - x1);
|
|
1473
|
+
return {
|
|
1474
|
+
x: x1 + Math.cos(angle) * distance,
|
|
1475
|
+
y: y1 + Math.sin(angle) * distance,
|
|
1476
|
+
};
|
|
1477
|
+
}
|
|
1478
|
+
const rightStart = adjustPoint(centerX, centerY, rightX, rightY, 50);
|
|
1479
|
+
const rightEnd = adjustPoint(rightX, rightY, centerX, centerY, 10);
|
|
1480
|
+
const leftStart = adjustPoint(centerX, centerY, leftX, leftY, 50);
|
|
1481
|
+
const leftEnd = adjustPoint(leftX, leftY, centerX, centerY, 10);
|
|
1482
|
+
ctx.beginPath();
|
|
1483
|
+
ctx.moveTo(rightStart.x, rightStart.y);
|
|
1484
|
+
ctx.lineTo(rightEnd.x, rightEnd.y);
|
|
1485
|
+
ctx.strokeStyle = 'black';
|
|
1486
|
+
ctx.stroke();
|
|
1487
|
+
let rightAngle = Math.atan2(rightEnd.y - rightStart.y, rightEnd.x - rightStart.x);
|
|
1488
|
+
drawArrowhead(ctx, rightEnd.x, rightEnd.y, rightAngle);
|
|
1489
|
+
ctx.beginPath();
|
|
1490
|
+
ctx.moveTo(leftStart.x, leftStart.y);
|
|
1491
|
+
ctx.lineTo(leftEnd.x, leftEnd.y);
|
|
1492
|
+
ctx.strokeStyle = 'black';
|
|
1493
|
+
ctx.stroke();
|
|
1494
|
+
let leftAngle = Math.atan2(leftEnd.y - leftStart.y, leftEnd.x - leftStart.x);
|
|
1495
|
+
drawArrowhead(ctx, leftEnd.x, leftEnd.y, leftAngle);
|
|
1496
|
+
}
|
|
1497
|
+
if (properties.elementType === 'entrance') {
|
|
1498
|
+
const angle = Math.atan2(nextPoint.y - point.y, nextPoint.x - point.x);
|
|
1499
|
+
const entranceAngle = angle + (15 * Math.PI) / 180;
|
|
1500
|
+
const lineLength = this.convertToPixels(properties.distance, properties.unit) * 0.75;
|
|
1501
|
+
const endPoint = {
|
|
1502
|
+
x: point.x + Math.cos(entranceAngle) * lineLength,
|
|
1503
|
+
y: point.y + Math.sin(entranceAngle) * lineLength,
|
|
1504
|
+
};
|
|
1505
|
+
ctx.beginPath();
|
|
1506
|
+
ctx.moveTo(point.x, point.y);
|
|
1507
|
+
ctx.lineTo(endPoint.x, endPoint.y);
|
|
1508
|
+
ctx.strokeStyle = '#1D2939';
|
|
1509
|
+
ctx.stroke();
|
|
1510
|
+
}
|
|
1511
|
+
});
|
|
1512
|
+
ctx.restore();
|
|
1513
|
+
return new Promise((resolve) => {
|
|
1514
|
+
canvas.toBlob((blob) => {
|
|
1515
|
+
const link = document.createElement('a');
|
|
1516
|
+
link.download = `${this.selectedStore.storeName}_${this.selectedFloor.floorName}_layout.png`;
|
|
1517
|
+
link.href = URL.createObjectURL(blob);
|
|
1518
|
+
link.click();
|
|
1519
|
+
canvas.remove();
|
|
1520
|
+
resolve('');
|
|
1521
|
+
});
|
|
1522
|
+
});
|
|
1523
|
+
};
|
|
1524
|
+
const layoutInstructions = this.layoutPolygon.map((segment) => {
|
|
1525
|
+
const [, , properties] = segment;
|
|
1526
|
+
return properties;
|
|
1527
|
+
});
|
|
1528
|
+
await renderCanvas(layoutInstructions);
|
|
1529
|
+
}
|
|
1530
|
+
generateLayoutPolygon(layoutInstructions) {
|
|
1531
|
+
this.pixelPerMetre = this.normalizedPixelPerMetre(layoutInstructions);
|
|
1532
|
+
this.layoutPolygon = [];
|
|
1533
|
+
const centerX = this.canvas.width / 2 / this.scale;
|
|
1534
|
+
const centerY = this.canvas.height / 2 / this.scale;
|
|
1535
|
+
if (!layoutInstructions.length) {
|
|
1536
|
+
this.initializeLayout();
|
|
1537
|
+
this.redrawCanvas();
|
|
1538
|
+
return;
|
|
1539
|
+
}
|
|
1540
|
+
let currentPoint = {
|
|
1541
|
+
"x": this.snapToGrid(centerX, this.gridHeight),
|
|
1542
|
+
"y": this.snapToGrid(centerY, this.gridWidth)
|
|
1543
|
+
};
|
|
1544
|
+
layoutInstructions.forEach((instruction) => {
|
|
1545
|
+
const radians = {
|
|
1546
|
+
'up': ((180 - instruction.angle) * Math.PI) / 180,
|
|
1547
|
+
'left': ((270 - instruction.angle) * Math.PI) / 180,
|
|
1548
|
+
'down': ((360 - instruction.angle) * Math.PI) / 180,
|
|
1549
|
+
'right': ((90 - instruction.angle) * Math.PI) / 180,
|
|
1550
|
+
}[instruction.direction];
|
|
1551
|
+
if (radians === undefined) {
|
|
1552
|
+
throw new Error(`Invalid direction: ${instruction.direction}`);
|
|
1553
|
+
}
|
|
1554
|
+
const distanceInPixels = this.convertToPixels(instruction.distance, instruction.unit);
|
|
1555
|
+
const newX = currentPoint.x + Math.cos(radians) * distanceInPixels;
|
|
1556
|
+
const newY = currentPoint.y - Math.sin(radians) * distanceInPixels;
|
|
1557
|
+
const newPoint = {
|
|
1558
|
+
x: this.snapToGrid(newX, this.gridWidth),
|
|
1559
|
+
y: this.snapToGrid(newY, this.gridHeight),
|
|
1560
|
+
};
|
|
1561
|
+
const lineSegment = [
|
|
1562
|
+
currentPoint,
|
|
1563
|
+
newPoint,
|
|
1564
|
+
{
|
|
1565
|
+
elementType: instruction.elementType,
|
|
1566
|
+
distance: instruction.distance,
|
|
1567
|
+
unit: instruction.unit,
|
|
1568
|
+
direction: instruction.direction,
|
|
1569
|
+
angle: instruction.angle,
|
|
1570
|
+
elementNumber: instruction.elementNumber,
|
|
1571
|
+
},
|
|
1572
|
+
];
|
|
1573
|
+
this.layoutPolygon.push(lineSegment);
|
|
1574
|
+
currentPoint = newPoint;
|
|
1575
|
+
});
|
|
1576
|
+
const lastPoint = this.layoutPolygon[this.layoutPolygon.length - 1][1];
|
|
1577
|
+
if (this.isFloorCompleted(layoutInstructions)) {
|
|
1578
|
+
this.findPolygonCenterAndScroll();
|
|
1579
|
+
this.closeWidget();
|
|
1580
|
+
}
|
|
1581
|
+
else {
|
|
1582
|
+
this.openWidget(lastPoint);
|
|
1583
|
+
}
|
|
1584
|
+
this.redrawCanvas();
|
|
1585
|
+
}
|
|
1586
|
+
normalizedPixelPerMetre(polygon) {
|
|
1587
|
+
const MIN_PIXELS_PER_METER = 50;
|
|
1588
|
+
const MAX_PIXELS_PER_METER = 150;
|
|
1589
|
+
let totalLength = 0;
|
|
1590
|
+
let lineCount = 0;
|
|
1591
|
+
polygon.forEach((line) => {
|
|
1592
|
+
if (line.unit === 'ft') {
|
|
1593
|
+
totalLength = totalLength + (line.distance * 3.28084);
|
|
1594
|
+
}
|
|
1595
|
+
else {
|
|
1596
|
+
totalLength = totalLength + line.distance;
|
|
1597
|
+
}
|
|
1598
|
+
lineCount++;
|
|
1599
|
+
});
|
|
1600
|
+
const averageLength = lineCount > 0 ? totalLength / lineCount : 0;
|
|
1601
|
+
const MAX_AVERAGE_LENGTH = 50;
|
|
1602
|
+
const MIN_AVERAGE_LENGTH = 5;
|
|
1603
|
+
const normalizedLength = Math.min(Math.max(averageLength, MIN_AVERAGE_LENGTH), MAX_AVERAGE_LENGTH);
|
|
1604
|
+
const pixelsPerMeter = MAX_PIXELS_PER_METER -
|
|
1605
|
+
((normalizedLength - MIN_AVERAGE_LENGTH) / (MAX_AVERAGE_LENGTH - MIN_AVERAGE_LENGTH)) *
|
|
1606
|
+
(MAX_PIXELS_PER_METER - MIN_PIXELS_PER_METER);
|
|
1607
|
+
return Math.round(pixelsPerMeter);
|
|
1608
|
+
}
|
|
1609
|
+
isFloorCompleted(layoutInstructions, thresholdInFeet = 1) {
|
|
1610
|
+
const layoutPolygon = [];
|
|
1611
|
+
const centerX = this.canvas.width / 2 / this.scale;
|
|
1612
|
+
const centerY = this.canvas.height / 2 / this.scale;
|
|
1613
|
+
let currentPoint = {
|
|
1614
|
+
x: this.snapToGrid(centerX, this.gridHeight),
|
|
1615
|
+
y: this.snapToGrid(centerY, this.gridWidth),
|
|
1616
|
+
};
|
|
1617
|
+
layoutInstructions.forEach((instruction) => {
|
|
1618
|
+
const radians = {
|
|
1619
|
+
'up': ((180 - instruction.angle) * Math.PI) / 180,
|
|
1620
|
+
'left': ((270 - instruction.angle) * Math.PI) / 180,
|
|
1621
|
+
'down': ((360 - instruction.angle) * Math.PI) / 180,
|
|
1622
|
+
'right': ((90 - instruction.angle) * Math.PI) / 180,
|
|
1623
|
+
}[instruction.direction];
|
|
1624
|
+
if (radians === undefined) {
|
|
1625
|
+
throw new Error(`Invalid direction: ${instruction.direction}`);
|
|
1626
|
+
}
|
|
1627
|
+
const distanceInPixels = this.convertToPixels(instruction.distance, instruction.unit);
|
|
1628
|
+
const newX = currentPoint.x + Math.cos(radians) * distanceInPixels;
|
|
1629
|
+
const newY = currentPoint.y - Math.sin(radians) * distanceInPixels;
|
|
1630
|
+
const newPoint = {
|
|
1631
|
+
x: this.snapToGrid(newX, this.gridWidth),
|
|
1632
|
+
y: this.snapToGrid(newY, this.gridHeight),
|
|
1633
|
+
};
|
|
1634
|
+
const lineSegment = [
|
|
1635
|
+
currentPoint,
|
|
1636
|
+
newPoint,
|
|
1637
|
+
{
|
|
1638
|
+
elementType: instruction.elementType,
|
|
1639
|
+
distance: instruction.distance,
|
|
1640
|
+
unit: instruction.unit,
|
|
1641
|
+
direction: instruction.direction,
|
|
1642
|
+
angle: instruction.angle,
|
|
1643
|
+
elementNumber: instruction.elementNumber,
|
|
1644
|
+
},
|
|
1645
|
+
];
|
|
1646
|
+
layoutPolygon.push(lineSegment);
|
|
1647
|
+
currentPoint = newPoint;
|
|
1648
|
+
});
|
|
1649
|
+
const firstPoint = layoutPolygon?.[0]?.[0];
|
|
1650
|
+
const lastPoint = layoutPolygon?.[layoutPolygon.length - 1]?.[1];
|
|
1651
|
+
if (layoutPolygon.length <= 1 || !firstPoint || !lastPoint) {
|
|
1652
|
+
return false;
|
|
1653
|
+
}
|
|
1654
|
+
const distanceBetweenPoints = Math.sqrt(Math.pow(lastPoint.x - firstPoint.x, 2) + Math.pow(lastPoint.y - firstPoint.y, 2));
|
|
1655
|
+
const thresholdInPixels = this.convertToPixels(thresholdInFeet, 'ft');
|
|
1656
|
+
return distanceBetweenPoints <= thresholdInPixels;
|
|
1657
|
+
}
|
|
1658
|
+
validateAngleInput(event, index) {
|
|
1659
|
+
const inputElement = event.target;
|
|
1660
|
+
let value = parseInt(inputElement.value, 10);
|
|
1661
|
+
if (isNaN(value)) {
|
|
1662
|
+
value = 0;
|
|
1663
|
+
}
|
|
1664
|
+
if (value < 0) {
|
|
1665
|
+
value = 0;
|
|
1666
|
+
}
|
|
1667
|
+
else if (value > 180) {
|
|
1668
|
+
value = 180;
|
|
1669
|
+
}
|
|
1670
|
+
inputElement.value = value.toString();
|
|
1671
|
+
this.layoutPolygon[index][2].angle = value;
|
|
1672
|
+
}
|
|
1673
|
+
onAngleChange(index) {
|
|
1674
|
+
this.saveStateToUndo();
|
|
1675
|
+
const [point1, point2, properties] = this.layoutPolygon[index];
|
|
1676
|
+
let radians;
|
|
1677
|
+
switch (properties.direction) {
|
|
1678
|
+
case 'up':
|
|
1679
|
+
radians = ((180 - properties.angle) * Math.PI) / 180;
|
|
1680
|
+
break;
|
|
1681
|
+
case 'left':
|
|
1682
|
+
radians = ((270 - properties.angle) * Math.PI) / 180;
|
|
1683
|
+
break;
|
|
1684
|
+
case 'down':
|
|
1685
|
+
radians = ((360 - properties.angle) * Math.PI) / 180;
|
|
1686
|
+
break;
|
|
1687
|
+
case 'right':
|
|
1688
|
+
radians = ((90 - properties.angle) * Math.PI) / 180;
|
|
1689
|
+
break;
|
|
1690
|
+
default:
|
|
1691
|
+
return;
|
|
1692
|
+
}
|
|
1693
|
+
const movementDistance = this.convertToPixels(properties.distance, properties.unit);
|
|
1694
|
+
const newX = point1.x + Math.cos(radians) * movementDistance;
|
|
1695
|
+
const newY = point1.y - Math.sin(radians) * movementDistance;
|
|
1696
|
+
const snappedX = this.snapToGrid(newX, this.gridWidth);
|
|
1697
|
+
const snappedY = this.snapToGrid(newY, this.gridHeight);
|
|
1698
|
+
point2.x = snappedX;
|
|
1699
|
+
point2.y = snappedY;
|
|
1700
|
+
properties.angle = this.layoutPolygon[index][2].angle;
|
|
1701
|
+
this.layoutPolygon[index] = [point1, point2, properties];
|
|
1702
|
+
this.redoStack = [];
|
|
1703
|
+
this.redrawCanvas();
|
|
1704
|
+
}
|
|
1705
|
+
openAddFloorModal() {
|
|
1706
|
+
const modelRef = this.modalDef.open(AddFloorComponent, { centered: true });
|
|
1707
|
+
modelRef.result.then((val) => {
|
|
1708
|
+
if (val.floorNumber) {
|
|
1709
|
+
this.addFloor(this.selectedStore.planoId, val.floorNumber);
|
|
1710
|
+
}
|
|
1711
|
+
}).catch((err) => {
|
|
1712
|
+
if (err.floorNumber) {
|
|
1713
|
+
this.addFloor(this.selectedStore.planoId, err.floorNumber);
|
|
1714
|
+
}
|
|
1715
|
+
});
|
|
1716
|
+
}
|
|
1717
|
+
findPolygonCenterAndScroll(polygon = this.layoutPolygon) {
|
|
1718
|
+
const vertices = polygon.flatMap((line) => line.slice(0, 2));
|
|
1719
|
+
const minX = Math.min(...vertices.map((v) => v.x));
|
|
1720
|
+
const maxX = Math.max(...vertices.map((v) => v.x));
|
|
1721
|
+
const minY = Math.min(...vertices.map((v) => v.y));
|
|
1722
|
+
const maxY = Math.max(...vertices.map((v) => v.y));
|
|
1723
|
+
let center = { x: (minX + maxX) / 2, y: (minY + maxY) / 2 };
|
|
1724
|
+
const step = 1;
|
|
1725
|
+
let bestPoint = center;
|
|
1726
|
+
let bestDistanceSum = Number.MAX_VALUE;
|
|
1727
|
+
for (let x = minX; x <= maxX; x += step) {
|
|
1728
|
+
for (let y = minY; y <= maxY; y += step) {
|
|
1729
|
+
const point = { x, y };
|
|
1730
|
+
if (isPointInsidePolygon(point, vertices)) {
|
|
1731
|
+
const distanceSum = vertices.reduce((sum, vertex) => sum + Math.sqrt((point.x - vertex.x) ** 2 + (point.y - vertex.y) ** 2), 0);
|
|
1732
|
+
if (distanceSum < bestDistanceSum) {
|
|
1733
|
+
bestDistanceSum = distanceSum;
|
|
1734
|
+
bestPoint = point;
|
|
1735
|
+
}
|
|
1736
|
+
}
|
|
1737
|
+
}
|
|
1738
|
+
}
|
|
1739
|
+
const scrollContainer = this.scrollContainerRef.nativeElement;
|
|
1740
|
+
scrollContainer.scrollTo({
|
|
1741
|
+
left: bestPoint.x - scrollContainer.offsetWidth / 2,
|
|
1742
|
+
top: bestPoint.y - scrollContainer.offsetHeight / 2,
|
|
1743
|
+
behavior: 'smooth'
|
|
1744
|
+
});
|
|
1745
|
+
this.resetZoom();
|
|
1746
|
+
this.resetOrientation();
|
|
1747
|
+
function isPointInsidePolygon(point, vertices) {
|
|
1748
|
+
let count = 0;
|
|
1749
|
+
for (let i = 0; i < vertices.length; i++) {
|
|
1750
|
+
const start = vertices[i];
|
|
1751
|
+
const end = vertices[(i + 1) % vertices.length];
|
|
1752
|
+
if (rayIntersectsSegment(point, { start, end })) {
|
|
1753
|
+
count++;
|
|
1754
|
+
}
|
|
1755
|
+
}
|
|
1756
|
+
return count % 2 === 1;
|
|
1757
|
+
}
|
|
1758
|
+
function rayIntersectsSegment(point, segment) {
|
|
1759
|
+
const { x, y } = point;
|
|
1760
|
+
const { start, end } = segment;
|
|
1761
|
+
if (y < Math.min(start.y, end.y) || y > Math.max(start.y, end.y)) {
|
|
1762
|
+
return false;
|
|
1763
|
+
}
|
|
1764
|
+
const t = (y - start.y) / (end.y - start.y);
|
|
1765
|
+
const intersectX = start.x + t * (end.x - start.x);
|
|
1766
|
+
return intersectX >= x;
|
|
1767
|
+
}
|
|
1768
|
+
}
|
|
1769
|
+
exportToExcel() {
|
|
1770
|
+
const layoutPolygon = this.layoutPolygon.map((segment) => {
|
|
1771
|
+
const [point1, point2, properties] = segment;
|
|
1772
|
+
return properties;
|
|
1773
|
+
});
|
|
1774
|
+
const formattedData = layoutPolygon.map((item, index) => ({
|
|
1775
|
+
'Step': index + 1,
|
|
1776
|
+
'Elements': `${item.elementType} ${item.elementNumber}`,
|
|
1777
|
+
'Measurements(ft)': item.distance,
|
|
1778
|
+
'Direction': item.direction,
|
|
1779
|
+
'Degree': item.angle
|
|
1780
|
+
}));
|
|
1781
|
+
const worksheet = XLSX.utils.json_to_sheet(formattedData);
|
|
1782
|
+
const workbook = XLSX.utils.book_new();
|
|
1783
|
+
XLSX.utils.book_append_sheet(workbook, worksheet, 'Sheet1');
|
|
1784
|
+
const fileName = `${this.selectedStore.storeName}_${this.selectedFloor.floorName}_layout.xlsx`;
|
|
1785
|
+
XLSX.writeFile(workbook, fileName);
|
|
1786
|
+
}
|
|
1787
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: CreateLayoutComponent, deps: [{ token: i0.ChangeDetectorRef }, { token: i0.Renderer2 }, { token: i1.ActivatedRoute }, { token: i2.StoreBuilderService }, { token: i1.Router }, { token: i3.NgbOffcanvas }, { token: i4.ToastService }, { token: i3.NgbModal }], target: i0.ɵɵFactoryTarget.Component });
|
|
1788
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: CreateLayoutComponent, selector: "lib-create-layout", host: { listeners: { "wheel": "onMouseWheel($event)", "document:click": "onOutsideClick($event)" } }, viewQueries: [{ propertyName: "canvasRef", first: true, predicate: ["gridCanvas"], descendants: true, static: true }, { propertyName: "widgetCanvasRef", first: true, predicate: ["widgetCanvas"], descendants: true }, { propertyName: "scrollContainerRef", first: true, predicate: ["scrollContainer"], descendants: true }, { propertyName: "circleRef", first: true, predicate: ["circle"], descendants: true }, { propertyName: "pointerRef", first: true, predicate: ["pointer"], descendants: true }], ngImport: i0, template: "<div class=\"d-flex align-items-center justify-content-between mb-6\">\r\n <div>\r\n <div *ngIf=\"planoStoreList.length === 1\" class=\"storename-txt\">\r\n {{selectedStore?.storeName}} - Layout\r\n </div>\r\n <div *ngIf=\"planoStoreList.length > 1\">\r\n <lib-select-plano [items]=\"planoStoreList\" [multi]=\"false\" [searchField]=\"'storeName'\" [idField]=\"'storeId'\"\r\n (selected)=\"onStoreChange($event)\" [selectedValues]=\"[selectedStore]\"></lib-select-plano>\r\n </div>\r\n </div>\r\n\r\n <div class=\"d-flex align-items-center\">\r\n <button (click)=\"onSaveAsDraft()\" class=\"btn btn-outline bg-white me-5\">Save As Draft</button>\r\n <button (click)=\"onConfigure()\" class=\"btn btn-sm btn-primary me-5\">Configure</button>\r\n <button (click)=\"openOffCanva()\" class=\"btn btn-sm btn-outline bg-white\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\">\r\n <path\r\n d=\"M9 3V21M5 3H19C20.1046 3 21 3.89543 21 5V19C21 20.1046 20.1046 21 19 21H5C3.89543 21 3 20.1046 3 19V5C3 3.89543 3.89543 3 5 3Z\"\r\n stroke=\"#101828\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\r\n </svg>\r\n </button>\r\n </div>\r\n</div>\r\n\r\n<div class=\"row\">\r\n <div [ngClass]=\"layoutMode === 'full' ? 'col-2' : 'col-5'\">\r\n <div class=\"c-card\" style=\"height: 75dvh; position: relative;\">\r\n <div class=\"resize-icon\" *ngIf=\"layoutMode === 'half'\" (click)=\"layoutMode = 'full'\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" viewBox=\"0 0 18 18\" fill=\"none\">\r\n <path\r\n d=\"M8.27259 12.6365L4.63623 9.00013L8.27259 5.36377M13.3635 12.6365L9.72714 9.00013L13.3635 5.36377\"\r\n stroke=\"#101828\" stroke-width=\"1.45455\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\r\n </svg>\r\n </div>\r\n <div class=\"resize-icon\" *ngIf=\"layoutMode === 'full'\" (click)=\"layoutMode = 'half'\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" viewBox=\"0 0 18 18\" fill=\"none\">\r\n <path\r\n d=\"M9.72741 5.36399L13.3638 9.00036L9.72741 12.6367M4.6365 5.36399L8.27286 9.00036L4.6365 12.6367\"\r\n stroke=\"#101828\" stroke-width=\"1.45455\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\r\n </svg>\r\n </div>\r\n <div class=\"d-flex align-items-center justify-content-between mb-5\" style=\"height: 8%;\">\r\n <div>\r\n <div class=\"l-pane-head\">\r\n Layout details\r\n </div>\r\n <div *ngIf=\"layoutMode === 'half'\" class=\"l-pane-desc\">\r\n Below are the sequence of steps for this layout\r\n </div>\r\n </div>\r\n <div class=\"d-flex align-items-center\">\r\n <ng-container *ngIf=\"layoutMode === 'half'\">\r\n <svg (click)=\"undo()\" class=\"me-3 cursor-pointer\" xmlns=\"http://www.w3.org/2000/svg\" width=\"24\"\r\n height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\">\r\n <path [attr.fill]=\"undoStack.length ? '#1D2939' : '#D0D5DD'\"\r\n d=\"M7 19V17H14.1C15.15 17 16.0627 16.6667 16.838 16C17.6133 15.3333 18.0007 14.5 18 13.5C18 12.5 17.6123 11.6667 16.837 11C16.0617 10.3333 15.1493 10 14.1 10H7.8L10.4 12.6L9 14L4 9L9 4L10.4 5.4L7.8 8H14.1C15.7167 8 17.1043 8.525 18.263 9.575C19.4217 10.625 20.0007 11.9333 20 13.5C20 15.0667 19.4207 16.375 18.262 17.425C17.1033 18.475 15.716 19 14.1 19H7Z\"\r\n fill=\"#D0D5DD\" />\r\n </svg>\r\n <svg (click)=\"redo()\" class=\"me-6 cursor-pointer\" xmlns=\"http://www.w3.org/2000/svg\" width=\"24\"\r\n height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\">\r\n <path [attr.fill]=\"redoStack.length ? '#1D2939' : '#D0D5DD'\"\r\n d=\"M9.9 19C8.28333 19 6.89567 18.475 5.737 17.425C4.57833 16.375 3.99933 15.0667 4 13.5C4 11.9333 4.57933 10.625 5.738 9.575C6.89667 8.525 8.284 8 9.9 8H16.2L13.6 5.4L15 4L20 9L15 14L13.6 12.6L16.2 10H9.9C8.85 10 7.93733 10.3333 7.162 11C6.38667 11.6667 5.99933 12.5 6 13.5C6 14.5 6.38767 15.3333 7.163 16C7.93833 16.6667 8.85067 17 9.9 17H17V19H9.9Z\"\r\n fill=\"#D0D5DD\" />\r\n </svg>\r\n <div (click)=\"toggleLayoutOptionSelect()\"\r\n class=\"d-flex align-items-center justify-content-center h-100 elipsis-icon-dropdown top-elipsis-menu\">\r\n <div class=\"elipsis-btn\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\"\r\n fill=\"none\">\r\n <path\r\n d=\"M11 11.9997C11 12.5289 11.4477 12.958 12 12.958C12.5523 12.958 13 12.5289 13 11.9997C13 11.4704 12.5523 11.0413 12 11.0413C11.4477 11.0413 11 11.4704 11 11.9997Z\"\r\n stroke=\"#101828\" stroke-width=\"2\" stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\" />\r\n <path\r\n d=\"M11 18.708C11 19.2373 11.4477 19.6663 12 19.6663C12.5523 19.6663 13 19.2373 13 18.708C13 18.1787 12.5523 17.7497 12 17.7497C11.4477 17.7497 11 18.1787 11 18.708Z\"\r\n stroke=\"#101828\" stroke-width=\"2\" stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\" />\r\n <path\r\n d=\"M11 5.29134C11 5.82061 11.4477 6.24967 12 6.24967C12.5523 6.24967 13 5.82061 13 5.29134C13 4.76207 12.5523 4.33301 12 4.33301C11.4477 4.33301 11 4.76207 11 5.29134Z\"\r\n stroke=\"#101828\" stroke-width=\"2\" stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\" />\r\n </svg>\r\n </div>\r\n <ul *ngIf=\"layoutOptionSelect?.show\" [ngClass]=\" (layoutOptionSelect.show ) ? 'z-1': ''\"\r\n class=\"list-unstyled mb-2\">\r\n <li>\r\n <div class=\"d-flex justify-content-between w-100\">\r\n <div class=\"menu-txt1\">Export</div>\r\n <span>\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"8\" height=\"14\" viewBox=\"0 0 8 14\" fill=\"none\">\r\n <path d=\"M1 13L7 7L1 1\" stroke=\"#101828\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\r\n </svg>\r\n </span>\r\n </div>\r\n <div class=\"export-options\">\r\n <ul>\r\n <li (click)=\"exportToExcel()\" >XLSX</li>\r\n <li (click)=\"exportAsPng()\" >PNG</li>\r\n </ul>\r\n </div>\r\n\r\n </li>\r\n <li (click)=\"onClearAll()\">\r\n <div class=\"d-flex\">\r\n <div class=\"menu-txt1\">Clear all</div>\r\n </div>\r\n\r\n </li>\r\n <li (click)=\"onDeleteLayout()\">\r\n <div class=\"d-flex\">\r\n <div class=\"menu-txt1 text-danger\">Delete</div>\r\n </div>\r\n </li>\r\n\r\n </ul>\r\n </div>\r\n\r\n </ng-container>\r\n\r\n\r\n\r\n </div>\r\n\r\n </div>\r\n\r\n <!-- <div class=\"d-flex align-items-center flex-column mx-auto\" style=\"margin-top: 200px;\" >\r\n <div class=\"no-steps-txt mb-3\">\r\n No steps have been created so far\r\n </div>\r\n <div class=\"no-text-desc text-center\">\r\n Start designing the layout by applying the steps using elements and dimensions.\r\n </div>\r\n </div> -->\r\n\r\n <div class=\"table-responsive hide-scrollbar \" style=\"height: 92%;\">\r\n <table class=\"table\">\r\n <thead class=\"thead-light\">\r\n <tr>\r\n <th>Steps</th>\r\n <th>Elements and Definition</th>\r\n <th>Feet</th>\r\n <th>Direction</th>\r\n <th>Degree</th>\r\n <th></th>\r\n </tr>\r\n </thead>\r\n <tbody cdkDropList (cdkDropListDropped)=\"drop($event)\">\r\n <ng-container *ngFor=\"let item of layoutPolygon; let i = index\">\r\n <tr [ngClass]=\"selectedLineIndex === i ? 'selected-element' : ''\" *ngIf=\"item?.[2]\" cdkDrag>\r\n <td>\r\n <div class=\"d-flex align-items-center justify-content-center w-100 h-100 drag-handler\">\r\n <span class=\"mr-2 \" >\r\n <svg class=\"cursor-pointer\" xmlns=\"http://www.w3.org/2000/svg\" width=\"19\" height=\"19\" viewBox=\"0 0 19 19\">\r\n <circle cx=\"5\" cy=\"5\" r=\"2\" fill=\"gray\" />\r\n <circle cx=\"14\" cy=\"5\" r=\"2\" fill=\"gray\" />\r\n <circle cx=\"5\" cy=\"10\" r=\"2\" fill=\"gray\" />\r\n <circle cx=\"14\" cy=\"10\" r=\"2\" fill=\"gray\" />\r\n <circle cx=\"5\" cy=\"15\" r=\"2\" fill=\"gray\" />\r\n <circle cx=\"14\" cy=\"15\" r=\"2\" fill=\"gray\" />\r\n </svg>\r\n </span>\r\n <span>{{ i + 1}}</span>\r\n </div>\r\n </td>\r\n <td>\r\n <div class=\"d-flex\">\r\n <div (click)=\"toggleElementSelect(i)\"\r\n class=\"element-type-dropdown me-2 position-relative\">\r\n <div>\r\n <svg *ngIf=\"item[2].elementType === 'wall'\"\r\n xmlns=\"http://www.w3.org/2000/svg\" width=\"20\" height=\"20\"\r\n viewBox=\"0 0 20 20\" fill=\"none\">\r\n <path fill-rule=\"evenodd\" clip-rule=\"evenodd\"\r\n d=\"M1.33333 1.33333V0L2.66667 0V1.33333L6.66667 1.33333V0L8 0V1.33333L12 1.33333V0L13.3333 0V1.33333L17.3333 1.33333V0L18.6667 0V1.33333H20V2.66667H18.6667V6.66667H20V8H18.6667V12H20V13.3333H18.6667V17.3333H20V18.6667H18.6667V20H17.3333V18.6667H13.3333V20H12V18.6667H8V20H6.66667V18.6667H2.66667V20H1.33333V18.6667H0L0 17.3333H1.33333L1.33333 13.3333H0L0 12H1.33333L1.33333 8H0L0 6.66667H1.33333L1.33333 2.66667H0L0 1.33333H1.33333ZM2.66667 2.66667L2.66667 6.66667H6.66667V2.66667L2.66667 2.66667ZM8 2.66667V6.66667H12V2.66667L8 2.66667ZM13.3333 2.66667V6.66667H17.3333V2.66667H13.3333ZM17.3333 8L13.3333 8V12L17.3333 12V8ZM17.3333 13.3333L13.3333 13.3333L13.3333 17.3333H17.3333V13.3333ZM12 17.3333L12 13.3333H8L8 17.3333H12ZM6.66667 17.3333V13.3333H2.66667V17.3333H6.66667ZM2.66667 12H6.66667V8H2.66667L2.66667 12ZM8 8V12H12V8H8Z\"\r\n fill=\"#344054\" />\r\n </svg>\r\n\r\n <svg *ngIf=\"item[2].elementType === 'facade'\"\r\n xmlns=\"http://www.w3.org/2000/svg\" width=\"22\" height=\"22\"\r\n viewBox=\"0 0 22 22\" fill=\"none\">\r\n <path\r\n d=\"M1 11V2.25C1 1.5625 1.5625 1 2.25 1H19.75C20.4375 1 21 1.5625 21 2.25V19.75C21 20.4375 20.4375 21 19.75 21H2.25C1.5625 21 1 20.4375 1 19.75V11Z\"\r\n stroke=\"#344054\" stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\" />\r\n </svg>\r\n\r\n <svg *ngIf=\"item[2].elementType === 'opening'\"\r\n xmlns=\"http://www.w3.org/2000/svg\" width=\"20\" height=\"20\"\r\n viewBox=\"0 0 20 20\" fill=\"none\">\r\n <path\r\n d=\"M12.5 2.5H15.8333C16.2754 2.5 16.6993 2.6756 17.0118 2.98816C17.3244 3.30072 17.5 3.72464 17.5 4.16667V15.8333C17.5 16.2754 17.3244 16.6993 17.0118 17.0118C16.6993 17.3244 16.2754 17.5 15.8333 17.5H12.5M8.33333 14.1667L12.5 10M12.5 10L8.33333 5.83333M12.5 10H2.5\"\r\n stroke=\"#101828\" stroke-width=\"1.5\" stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\" />\r\n </svg>\r\n\r\n <svg *ngIf=\"item[2].elementType === 'entrance'\"\r\n xmlns=\"http://www.w3.org/2000/svg\" width=\"21\" height=\"18\"\r\n viewBox=\"0 0 21 18\" fill=\"none\">\r\n <path fill-rule=\"evenodd\" clip-rule=\"evenodd\"\r\n d=\"M17.9333 1.37949C8.7909 1.37949 1.37949 8.7909 1.37949 17.9333H0C0 8.02903 8.02903 0 17.9333 0V1.37949Z\"\r\n fill=\"#1D2939\" />\r\n <path fill-rule=\"evenodd\" clip-rule=\"evenodd\"\r\n d=\"M19.3132 1.37949H17.9333L17.9337 16.5538H19.3132V1.37949ZM16.5542 0V17.9333H20.6927V0H16.5542Z\"\r\n fill=\"#1D2939\" />\r\n </svg>\r\n </div>\r\n\r\n <div class=\"down-arrow\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"20\" height=\"20\"\r\n viewBox=\"0 0 20 20\" fill=\"none\">\r\n <path d=\"M5 7.5L10 12.5L15 7.5\" stroke=\"#667085\"\r\n stroke-width=\"1.66667\" stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\" />\r\n </svg>\r\n </div>\r\n\r\n <ul *ngIf=\"elementSelect?.show && elementSelect?.index === i\"\r\n [ngClass]=\" (elementSelect.show && elementSelect.index === i) ? 'z-1': ''\"\r\n class=\"list-unstyled mb-2\">\r\n <li (click)=\"onElementTypeChange('wall', i)\"\r\n [ngClass]=\"item[2].elementType === 'wall' ? 'selected' : ''\">\r\n <div class=\"d-flex\">\r\n <div class=\"me-3\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"20\"\r\n height=\"20\" viewBox=\"0 0 20 20\" fill=\"none\">\r\n <path fill-rule=\"evenodd\" clip-rule=\"evenodd\"\r\n d=\"M1.33333 1.33333V0L2.66667 0V1.33333L6.66667 1.33333V0L8 0V1.33333L12 1.33333V0L13.3333 0V1.33333L17.3333 1.33333V0L18.6667 0V1.33333H20V2.66667H18.6667V6.66667H20V8H18.6667V12H20V13.3333H18.6667V17.3333H20V18.6667H18.6667V20H17.3333V18.6667H13.3333V20H12V18.6667H8V20H6.66667V18.6667H2.66667V20H1.33333V18.6667H0L0 17.3333H1.33333L1.33333 13.3333H0L0 12H1.33333L1.33333 8H0L0 6.66667H1.33333L1.33333 2.66667H0L0 1.33333H1.33333ZM2.66667 2.66667L2.66667 6.66667H6.66667V2.66667L2.66667 2.66667ZM8 2.66667V6.66667H12V2.66667L8 2.66667ZM13.3333 2.66667V6.66667H17.3333V2.66667H13.3333ZM17.3333 8L13.3333 8V12L17.3333 12V8ZM17.3333 13.3333L13.3333 13.3333L13.3333 17.3333H17.3333V13.3333ZM12 17.3333L12 13.3333H8L8 17.3333H12ZM6.66667 17.3333V13.3333H2.66667V17.3333H6.66667ZM2.66667 12H6.66667V8H2.66667L2.66667 12ZM8 8V12H12V8H8Z\"\r\n fill=\"#344054\" />\r\n </svg>\r\n </div>\r\n <div>Wall</div>\r\n </div>\r\n <div>\r\n <svg *ngIf=\"item[2].elementType === 'wall'\"\r\n xmlns=\"http://www.w3.org/2000/svg\" width=\"20\" height=\"20\"\r\n viewBox=\"0 0 20 20\" fill=\"none\">\r\n <path d=\"M16.6663 5L7.49967 14.1667L3.33301 10\"\r\n stroke=\"#00A3FF\" stroke-width=\"1.66667\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\" />\r\n </svg>\r\n </div>\r\n </li>\r\n <li (click)=\"onElementTypeChange('facade', i)\"\r\n [ngClass]=\"item[2].elementType === 'facade' ? 'selected' : ''\">\r\n <div class=\"d-flex\">\r\n <div class=\"me-3\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"22\"\r\n height=\"22\" viewBox=\"0 0 22 22\" fill=\"none\">\r\n <path\r\n d=\"M1 11V2.25C1 1.5625 1.5625 1 2.25 1H19.75C20.4375 1 21 1.5625 21 2.25V19.75C21 20.4375 20.4375 21 19.75 21H2.25C1.5625 21 1 20.4375 1 19.75V11Z\"\r\n stroke=\"#344054\" stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\" />\r\n </svg>\r\n </div>\r\n <div>Glass/Facade</div>\r\n </div>\r\n <div>\r\n <svg *ngIf=\"item[2].elementType === 'facade'\"\r\n xmlns=\"http://www.w3.org/2000/svg\" width=\"20\" height=\"20\"\r\n viewBox=\"0 0 20 20\" fill=\"none\">\r\n <path d=\"M16.6663 5L7.49967 14.1667L3.33301 10\"\r\n stroke=\"#00A3FF\" stroke-width=\"1.66667\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\" />\r\n </svg>\r\n </div>\r\n </li>\r\n <li (click)=\"onElementTypeChange('opening', i)\"\r\n [ngClass]=\"item[2].elementType === 'opening' ? 'selected' : ''\">\r\n <div class=\"d-flex\">\r\n <div class=\"me-3\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"20\"\r\n height=\"20\" viewBox=\"0 0 20 20\" fill=\"none\">\r\n <path\r\n d=\"M12.5 2.5H15.8333C16.2754 2.5 16.6993 2.6756 17.0118 2.98816C17.3244 3.30072 17.5 3.72464 17.5 4.16667V15.8333C17.5 16.2754 17.3244 16.6993 17.0118 17.0118C16.6993 17.3244 16.2754 17.5 15.8333 17.5H12.5M8.33333 14.1667L12.5 10M12.5 10L8.33333 5.83333M12.5 10H2.5\"\r\n stroke=\"#101828\" stroke-width=\"1.5\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\" />\r\n </svg>\r\n </div>\r\n <div>Opening</div>\r\n </div>\r\n <div>\r\n <svg *ngIf=\"item[2].elementType === 'opening'\"\r\n xmlns=\"http://www.w3.org/2000/svg\" width=\"20\" height=\"20\"\r\n viewBox=\"0 0 20 20\" fill=\"none\">\r\n <path d=\"M16.6663 5L7.49967 14.1667L3.33301 10\"\r\n stroke=\"#00A3FF\" stroke-width=\"1.66667\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\" />\r\n </svg>\r\n </div>\r\n </li>\r\n <li (click)=\"onElementTypeChange('entrance', i)\"\r\n [ngClass]=\"item[2].elementType === 'entrance' ? 'selected' : ''\">\r\n <div class=\"d-flex\">\r\n <div class=\"me-3\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"21\"\r\n height=\"18\" viewBox=\"0 0 21 18\" fill=\"none\">\r\n <path fill-rule=\"evenodd\" clip-rule=\"evenodd\"\r\n d=\"M17.9333 1.37949C8.7909 1.37949 1.37949 8.7909 1.37949 17.9333H0C0 8.02903 8.02903 0 17.9333 0V1.37949Z\"\r\n fill=\"#1D2939\" />\r\n <path fill-rule=\"evenodd\" clip-rule=\"evenodd\"\r\n d=\"M19.3132 1.37949H17.9333L17.9337 16.5538H19.3132V1.37949ZM16.5542 0V17.9333H20.6927V0H16.5542Z\"\r\n fill=\"#1D2939\" />\r\n </svg>\r\n </div>\r\n <div>Entrance</div>\r\n </div>\r\n <div>\r\n <svg *ngIf=\"item[2].elementType === 'entrance'\"\r\n xmlns=\"http://www.w3.org/2000/svg\" width=\"20\" height=\"20\"\r\n viewBox=\"0 0 20 20\" fill=\"none\">\r\n <path d=\"M16.6663 5L7.49967 14.1667L3.33301 10\"\r\n stroke=\"#00A3FF\" stroke-width=\"1.66667\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\" />\r\n </svg>\r\n </div>\r\n </li>\r\n </ul>\r\n\r\n </div>\r\n <div class=\"element-name\">{{item[2].elementType}} {{item[2].elementNumber}}\r\n </div>\r\n </div>\r\n </td>\r\n <td>\r\n <div class=\"unit-input\">\r\n <svg (click)=\"onDistanceChange('decrement', i)\" class=\"cursor-pointer\"\r\n xmlns=\"http://www.w3.org/2000/svg\" width=\"14\" height=\"14\"\r\n viewBox=\"0 0 14 14\" fill=\"none\">\r\n <path d=\"M2.9165 7H11.0832\" stroke=\"#667085\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\" />\r\n </svg>\r\n <span>{{item[2].distance}}</span>\r\n <svg (click)=\"onDistanceChange('increment', i)\" class=\"cursor-pointer\"\r\n xmlns=\"http://www.w3.org/2000/svg\" width=\"14\" height=\"14\"\r\n viewBox=\"0 0 14 14\" fill=\"none\">\r\n <path d=\"M6.99984 2.9165V11.0832M2.9165 6.99984H11.0832\" stroke=\"#667085\"\r\n stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\r\n </svg>\r\n </div>\r\n </td>\r\n <td>\r\n <div (click)=\"toggleDirectionSelect(i)\"\r\n class=\"direction-dropdown position-relative\">\r\n <div>\r\n {{item[2].direction}}\r\n </div>\r\n\r\n <div class=\"down-arrow\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"20\" height=\"20\"\r\n viewBox=\"0 0 20 20\" fill=\"none\">\r\n <path d=\"M5 7.5L10 12.5L15 7.5\" stroke=\"#667085\" stroke-width=\"1.66667\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\" />\r\n </svg>\r\n </div>\r\n\r\n <ul *ngIf=\"directionSelect?.show && directionSelect?.index === i\"\r\n [ngClass]=\" (directionSelect.show && directionSelect.index === i) ? 'z-1': ''\"\r\n class=\"list-unstyled mb-2\">\r\n <li (click)=\"onDirectionChange('up', i)\"\r\n [ngClass]=\"item[2].direction === 'up' ? 'selected' : ''\">\r\n <div class=\"d-flex\">\r\n <div>Up</div>\r\n </div>\r\n <div>\r\n <svg *ngIf=\"item[2].direction === 'up'\"\r\n xmlns=\"http://www.w3.org/2000/svg\" width=\"20\" height=\"20\"\r\n viewBox=\"0 0 20 20\" fill=\"none\">\r\n <path d=\"M16.6663 5L7.49967 14.1667L3.33301 10\" stroke=\"#00A3FF\"\r\n stroke-width=\"1.66667\" stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\" />\r\n </svg>\r\n </div>\r\n </li>\r\n <li (click)=\"onDirectionChange('down', i)\"\r\n [ngClass]=\"item[2].direction === 'down' ? 'selected' : ''\">\r\n <div class=\"d-flex\">\r\n\r\n <div>Down</div>\r\n </div>\r\n <div>\r\n <svg *ngIf=\"item[2].direction === 'down'\"\r\n xmlns=\"http://www.w3.org/2000/svg\" width=\"20\" height=\"20\"\r\n viewBox=\"0 0 20 20\" fill=\"none\">\r\n <path d=\"M16.6663 5L7.49967 14.1667L3.33301 10\" stroke=\"#00A3FF\"\r\n stroke-width=\"1.66667\" stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\" />\r\n </svg>\r\n </div>\r\n </li>\r\n <li (click)=\"onDirectionChange('right', i)\"\r\n [ngClass]=\"item[2].direction === 'right' ? 'selected' : ''\">\r\n <div class=\"d-flex\">\r\n\r\n <div>Right</div>\r\n </div>\r\n <div>\r\n <svg *ngIf=\"item[2].direction === 'right'\"\r\n xmlns=\"http://www.w3.org/2000/svg\" width=\"20\" height=\"20\"\r\n viewBox=\"0 0 20 20\" fill=\"none\">\r\n <path d=\"M16.6663 5L7.49967 14.1667L3.33301 10\" stroke=\"#00A3FF\"\r\n stroke-width=\"1.66667\" stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\" />\r\n </svg>\r\n </div>\r\n </li>\r\n <li (click)=\"onDirectionChange('left', i)\"\r\n [ngClass]=\"item[2].direction === 'left' ? 'selected' : ''\">\r\n <div class=\"d-flex\">\r\n\r\n <div>Left</div>\r\n </div>\r\n <div>\r\n <svg *ngIf=\"item[2].direction === 'left'\"\r\n xmlns=\"http://www.w3.org/2000/svg\" width=\"20\" height=\"20\"\r\n viewBox=\"0 0 20 20\" fill=\"none\">\r\n <path d=\"M16.6663 5L7.49967 14.1667L3.33301 10\" stroke=\"#00A3FF\"\r\n stroke-width=\"1.66667\" stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\" />\r\n </svg>\r\n </div>\r\n </li>\r\n </ul>\r\n\r\n </div>\r\n </td>\r\n\r\n <td>\r\n <input min=\"0\" max=\"180\" class=\"angle-input\" [(ngModel)]=\"item[2].angle\"\r\n type=\"number\" (input)=\"validateAngleInput($event, i)\" (blur)=\"onAngleChange(i)\">\r\n <!-- <span class=\"angle-input\">\r\n {{item[2].angle}}\u00B0\r\n </span> -->\r\n </td>\r\n <td>\r\n <div (click)=\"toggleLineOptionsSelect(i)\"\r\n class=\"d-flex align-items-center justify-content-center h-100 elipsis-icon-dropdown\">\r\n <svg class=\"cursor-pointer\" xmlns=\"http://www.w3.org/2000/svg\" width=\"4\"\r\n height=\"19\" viewBox=\"0 0 4 19\" fill=\"none\">\r\n <path\r\n d=\"M1 9.50016C1 10.0294 1.44771 10.4585 2 10.4585C2.55228 10.4585 3 10.0294 3 9.50016C3 8.97089 2.55228 8.54183 2 8.54183C1.44771 8.54183 1 8.97089 1 9.50016Z\"\r\n stroke=\"#101828\" stroke-width=\"2\" stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\" />\r\n <path\r\n d=\"M0.999999 16.2085C0.999999 16.7378 1.44771 17.1668 2 17.1668C2.55228 17.1668 3 16.7378 3 16.2085C3 15.6792 2.55228 15.2502 2 15.2502C1.44771 15.2502 0.999999 15.6792 0.999999 16.2085Z\"\r\n stroke=\"#101828\" stroke-width=\"2\" stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\" />\r\n <path\r\n d=\"M1 2.79183C1 3.3211 1.44772 3.75016 2 3.75016C2.55228 3.75016 3 3.3211 3 2.79183C3 2.26256 2.55228 1.8335 2 1.8335C1.44772 1.8335 1 2.26256 1 2.79183Z\"\r\n stroke=\"#101828\" stroke-width=\"2\" stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\" />\r\n </svg>\r\n <ul *ngIf=\"lineOptionsSelect?.show && lineOptionsSelect?.index === i\"\r\n [ngClass]=\" (lineOptionsSelect.show && lineOptionsSelect.index === i) ? 'z-1': ''\"\r\n class=\"list-unstyled mb-2\">\r\n <li (click)=\"onAddStep(i)\">\r\n <div class=\"d-flex\">\r\n <div>Add new step</div>\r\n </div>\r\n\r\n </li>\r\n <li (click)=\"onDuplicateStep(i)\">\r\n <div class=\"d-flex\">\r\n <div>Duplicate</div>\r\n </div>\r\n\r\n </li>\r\n <li (click)=\"onLineDelete(i)\">\r\n <div class=\"d-flex\">\r\n <div class=\"text-danger\">Delete</div>\r\n </div>\r\n\r\n </li>\r\n\r\n </ul>\r\n </div>\r\n\r\n </td>\r\n </tr>\r\n </ng-container>\r\n\r\n </tbody>\r\n </table>\r\n </div>\r\n\r\n\r\n </div>\r\n </div>\r\n <div [ngClass]=\"layoutMode === 'full' ? 'col-10' : 'col-7'\">\r\n <div class=\"c-card \" style=\"height: 75dvh;\">\r\n <div style=\"height: 7%;\" class=\"d-flex align-items-center justify-content-between\">\r\n <div>\r\n <!-- <lib-reactive-select *ngIf=\"floorsInput.value\" [formControl]=\"floorsInput\" [idField]=\"'id'\"\r\n [nameField]=\"'floorName'\" [data]=\"selectedStore?.floor\"></lib-reactive-select> -->\r\n <div (click)=\"toggleFloorSelect()\" class=\"floor-select\">\r\n <div>{{selectedFloor?.floorName}}</div>\r\n <div><svg xmlns=\"http://www.w3.org/2000/svg\" width=\"20\" height=\"20\" viewBox=\"0 0 20 20\"\r\n fill=\"none\">\r\n <path d=\"M5 7.5L10 12.5L15 7.5\" stroke=\"#344054\" stroke-width=\"1.67\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\" />\r\n </svg></div>\r\n <ul *ngIf=\"floorSelect?.show\" class=\"list-unstyled mb-2\">\r\n <li (click)=\"onFloorSelect(floor.id)\"\r\n *ngFor=\"let floor of selectedStore?.floor; let i = index\"\r\n [ngClass]=\"floor.id === selectedFloor.id ? 'selected': ''\">\r\n <div class=\"d-flex justify-content-between\">\r\n <span>{{floor?.floorName}}</span>\r\n <span *ngIf=\"selectedStore?.floor.length > 1\"\r\n (click)=\"$event.stopPropagation(); floorSelect.deleteIndex = i\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"23\"\r\n viewBox=\"0 0 24 23\" fill=\"none\">\r\n <path\r\n d=\"M11 11.4999C11 12.0292 11.4477 12.4583 12 12.4583C12.5523 12.4583 13 12.0292 13 11.4999C13 10.9706 12.5523 10.5416 12 10.5416C11.4477 10.5416 11 10.9706 11 11.4999Z\"\r\n stroke=\"#101828\" stroke-width=\"2\" stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\" />\r\n <path\r\n d=\"M11 18.2083C11 18.7375 11.4477 19.1666 12 19.1666C12.5523 19.1666 13 18.7375 13 18.2083C13 17.679 12.5523 17.2499 12 17.2499C11.4477 17.2499 11 17.679 11 18.2083Z\"\r\n stroke=\"#101828\" stroke-width=\"2\" stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\" />\r\n <path\r\n d=\"M11 4.79159C11 5.32086 11.4477 5.74992 12 5.74992C12.5523 5.74992 13 5.32086 13 4.79159C13 4.26231 12.5523 3.83325 12 3.83325C11.4477 3.83325 11 4.26231 11 4.79159Z\"\r\n stroke=\"#101828\" stroke-width=\"2\" stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\" />\r\n </svg>\r\n </span>\r\n </div>\r\n\r\n <div *ngIf=\"floorSelect.deleteIndex === i\"\r\n (click)=\"$event.stopPropagation(); deleteFloor(i)\" class=\"option\">Delete</div>\r\n </li>\r\n <li (click)=\"openAddFloorModal()\">\r\n <span>\r\n <span class=\"mr-2\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\"\r\n viewBox=\"0 0 16 16\" fill=\"none\">\r\n <path d=\"M8.00016 3.33325V12.6666M3.3335 7.99992H12.6668\" stroke=\"#101828\"\r\n stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\r\n </svg>\r\n </span>\r\n <span>Add floor</span>\r\n </span>\r\n\r\n </li>\r\n </ul>\r\n </div>\r\n </div>\r\n <div class=\"d-flex align-items-center\" >\r\n <button (click)=\"findPolygonCenterAndScroll()\" class=\"btn btn-sm btn-outline bg-white me-3\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"26\" height=\"26\" fill=\"none\" viewBox=\"0 0 128 128\" id=\"recenter\">\r\n <path stroke=\"#000\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"7\" d=\"M38 74L49 63.5 38 53M53.5 37.5L64 48.5 74.5 37.5M90 53L79 63.5 90 74M74.5 89.5L64 78.5 53.5 89.5\"></path>\r\n <path stroke=\"#000\" stroke-linecap=\"round\" stroke-width=\"7\" d=\"M44 64L16 64M63.5 43.5L63.5 15.5M84 63L112 63M64.5 83.5L64.5 111.5\"></path>\r\n <circle cx=\"64\" cy=\"64\" r=\"5\" fill=\"#000\"></circle>\r\n </svg>\r\n </button>\r\n <button class=\"btn btn-sm btn-outline bg-white\" (click)=\"rotatePolygons()\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"26\" height=\"26\" viewBox=\"0 0 26 26\" fill=\"none\">\r\n <path\r\n d=\"M6.36265 7.17838L7.17625 6.36238L5.90425 5.09158L5.08945 5.90518L6.36265 7.17838ZM15.671 6.36358L19.6379 10.3304L20.9099 9.0572L16.9442 5.09038L15.671 6.36358ZM19.6379 18.8252L18.8243 19.6388L20.0963 20.9096L20.9099 20.0972L19.6379 18.8252ZM10.3295 19.6388L6.36265 15.672L5.09065 16.9452L9.05626 20.9108L10.3295 19.6388ZM18.8243 19.6388C17.6543 20.8076 16.8407 21.6188 16.1459 22.1492C15.4715 22.664 15.0155 22.8284 14.5763 22.8284V24.6284C15.5675 24.6284 16.4027 24.2168 17.2367 23.5808C18.0503 22.9604 18.9635 22.0448 20.0963 20.912L18.8243 19.6388ZM9.05626 20.9108C10.1891 22.0448 11.1023 22.9592 11.9159 23.5808C12.7499 24.2168 13.5851 24.6284 14.5763 24.6284V22.8284C14.1371 22.8284 13.6823 22.664 13.0067 22.1492C12.3119 21.6188 11.4983 20.8076 10.3295 19.6388L9.05626 20.9108ZM19.6379 10.3304C20.8067 11.4992 21.6179 12.3128 22.1483 13.0076C22.6631 13.6832 22.8275 14.138 22.8275 14.5772H24.6275C24.6275 13.586 24.2159 12.7508 23.5799 11.9168C22.9595 11.1032 22.0427 10.19 20.9099 9.0572L19.6379 10.3304ZM20.9099 20.0972C22.0439 18.9632 22.9583 18.0512 23.5799 17.2376C24.2159 16.4036 24.6275 15.5684 24.6275 14.5772H22.8275C22.8275 15.0164 22.6631 15.4724 22.1483 16.1468C21.6179 16.8416 20.8067 17.6552 19.6379 18.8252L20.9099 20.0972ZM7.17625 6.36238C8.34625 5.19358 9.15985 4.38118 9.85465 3.85078C10.529 3.33598 10.985 3.17278 11.4242 3.17278V1.37158C10.433 1.37158 9.59785 1.78318 8.76385 2.41918C7.94905 3.04078 7.03705 3.95518 5.90425 5.08798L7.17625 6.36238ZM16.9442 5.09038C15.8114 3.95638 14.8982 3.04078 14.0846 2.41918C13.2506 1.78318 12.4154 1.37158 11.4242 1.37158V3.17278C11.8634 3.17278 12.3182 3.33598 12.9938 3.85078C13.6886 4.38118 14.5022 5.19238 15.671 6.36118L16.9442 5.09038ZM5.08945 5.90278C3.95665 7.03558 3.04225 7.94758 2.42065 8.76238C1.78465 9.59638 1.37305 10.4316 1.37305 11.4228H3.17305C3.17305 10.9836 3.33745 10.5276 3.85225 9.85318C4.38265 9.15838 5.19385 8.34478 6.36265 7.17478L5.08945 5.90278ZM6.36265 15.6708C5.19385 14.5008 4.38265 13.6872 3.85225 12.9924C3.33745 12.318 3.17305 11.862 3.17305 11.4228H1.37305C1.37305 12.414 1.78465 13.2492 2.42065 14.0832C3.04225 14.8968 3.95665 15.81 5.08945 16.9428L6.36265 15.6708Z\"\r\n fill=\"#1D2939\" />\r\n <path\r\n d=\"M23.2 6.9832L25 8.2C25 4.582 22.4056 1.5796 19 1M2.8 19.0168L1 17.8C1 21.418 3.5944 24.4204 7 25\"\r\n stroke=\"#1D2939\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\r\n </svg>\r\n </button> \r\n </div>\r\n \r\n </div>\r\n <div class=\"hide-scrollbar\" style=\"height: 93%; overflow: scroll; position: relative;\" #scrollContainer>\r\n <canvas #gridCanvas>\r\n\r\n </canvas>\r\n\r\n <div *ngIf=\"popupVisible && popupPosition\" [style.top.px]=\"popupPosition.y\"\r\n [style.left.px]=\"popupPosition.x\" class=\"angle-widget\">\r\n <div (click)=\"toggleWidgetElementSelect()\" style=\"width: 147px;\"\r\n class=\"element-type-dropdown widget-element-type-dropdown d-flex justify-content-between position-relative\">\r\n <div>\r\n <span class=\"d-flex align-items-center\" *ngIf=\"elementType === 'wall'\">\r\n <svg class=\"me-3\" xmlns=\"http://www.w3.org/2000/svg\" width=\"20\" height=\"20\"\r\n viewBox=\"0 0 20 20\" fill=\"none\">\r\n <path fill-rule=\"evenodd\" clip-rule=\"evenodd\"\r\n d=\"M1.33333 1.33333V0L2.66667 0V1.33333L6.66667 1.33333V0L8 0V1.33333L12 1.33333V0L13.3333 0V1.33333L17.3333 1.33333V0L18.6667 0V1.33333H20V2.66667H18.6667V6.66667H20V8H18.6667V12H20V13.3333H18.6667V17.3333H20V18.6667H18.6667V20H17.3333V18.6667H13.3333V20H12V18.6667H8V20H6.66667V18.6667H2.66667V20H1.33333V18.6667H0L0 17.3333H1.33333L1.33333 13.3333H0L0 12H1.33333L1.33333 8H0L0 6.66667H1.33333L1.33333 2.66667H0L0 1.33333H1.33333ZM2.66667 2.66667L2.66667 6.66667H6.66667V2.66667L2.66667 2.66667ZM8 2.66667V6.66667H12V2.66667L8 2.66667ZM13.3333 2.66667V6.66667H17.3333V2.66667H13.3333ZM17.3333 8L13.3333 8V12L17.3333 12V8ZM17.3333 13.3333L13.3333 13.3333L13.3333 17.3333H17.3333V13.3333ZM12 17.3333L12 13.3333H8L8 17.3333H12ZM6.66667 17.3333V13.3333H2.66667V17.3333H6.66667ZM2.66667 12H6.66667V8H2.66667L2.66667 12ZM8 8V12H12V8H8Z\"\r\n fill=\"#344054\" />\r\n </svg>\r\n <span class=\"type-txt\">Wall</span>\r\n </span>\r\n\r\n <span class=\"d-flex align-items-center\" *ngIf=\"elementType === 'facade'\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"22\" height=\"22\" viewBox=\"0 0 22 22\"\r\n fill=\"none\">\r\n <path\r\n d=\"M1 11V2.25C1 1.5625 1.5625 1 2.25 1H19.75C20.4375 1 21 1.5625 21 2.25V19.75C21 20.4375 20.4375 21 19.75 21H2.25C1.5625 21 1 20.4375 1 19.75V11Z\"\r\n stroke=\"#344054\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\r\n </svg>\r\n <span class=\"type-txt\">Glass...</span>\r\n </span>\r\n\r\n <span class=\"d-flex align-items-center\" *ngIf=\"elementType === 'opening'\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"20\" height=\"20\" viewBox=\"0 0 20 20\"\r\n fill=\"none\">\r\n <path\r\n d=\"M12.5 2.5H15.8333C16.2754 2.5 16.6993 2.6756 17.0118 2.98816C17.3244 3.30072 17.5 3.72464 17.5 4.16667V15.8333C17.5 16.2754 17.3244 16.6993 17.0118 17.0118C16.6993 17.3244 16.2754 17.5 15.8333 17.5H12.5M8.33333 14.1667L12.5 10M12.5 10L8.33333 5.83333M12.5 10H2.5\"\r\n stroke=\"#101828\" stroke-width=\"1.5\" stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\" />\r\n </svg>\r\n <span class=\"type-txt\">Openi...</span>\r\n </span>\r\n\r\n <span class=\"d-flex align-items-center\" *ngIf=\"elementType === 'entrance'\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"21\" height=\"18\" viewBox=\"0 0 21 18\"\r\n fill=\"none\">\r\n <path fill-rule=\"evenodd\" clip-rule=\"evenodd\"\r\n d=\"M17.9333 1.37949C8.7909 1.37949 1.37949 8.7909 1.37949 17.9333H0C0 8.02903 8.02903 0 17.9333 0V1.37949Z\"\r\n fill=\"#1D2939\" />\r\n <path fill-rule=\"evenodd\" clip-rule=\"evenodd\"\r\n d=\"M19.3132 1.37949H17.9333L17.9337 16.5538H19.3132V1.37949ZM16.5542 0V17.9333H20.6927V0H16.5542Z\"\r\n fill=\"#1D2939\" />\r\n </svg>\r\n <span class=\"type-txt\">Entra...</span>\r\n </span>\r\n\r\n </div>\r\n\r\n <div class=\"down-arrow\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"20\" height=\"20\" viewBox=\"0 0 20 20\"\r\n fill=\"none\">\r\n <path d=\"M5 7.5L10 12.5L15 7.5\" stroke=\"#667085\" stroke-width=\"1.66667\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\" />\r\n </svg>\r\n </div>\r\n\r\n <ul *ngIf=\"widgetElementSelect?.show \" [ngClass]=\" widgetElementSelect.show ? 'z-4': ''\"\r\n class=\"list-unstyled mb-2\">\r\n <li (click)=\"elementType = 'wall'\" [ngClass]=\"elementType === 'wall' ? 'selected' : ''\"\r\n class=\"selected\">\r\n <div class=\"d-flex\">\r\n <div class=\"me-3\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"20\" height=\"20\"\r\n viewBox=\"0 0 20 20\" fill=\"none\">\r\n <path fill-rule=\"evenodd\" clip-rule=\"evenodd\"\r\n d=\"M1.33333 1.33333V0L2.66667 0V1.33333L6.66667 1.33333V0L8 0V1.33333L12 1.33333V0L13.3333 0V1.33333L17.3333 1.33333V0L18.6667 0V1.33333H20V2.66667H18.6667V6.66667H20V8H18.6667V12H20V13.3333H18.6667V17.3333H20V18.6667H18.6667V20H17.3333V18.6667H13.3333V20H12V18.6667H8V20H6.66667V18.6667H2.66667V20H1.33333V18.6667H0L0 17.3333H1.33333L1.33333 13.3333H0L0 12H1.33333L1.33333 8H0L0 6.66667H1.33333L1.33333 2.66667H0L0 1.33333H1.33333ZM2.66667 2.66667L2.66667 6.66667H6.66667V2.66667L2.66667 2.66667ZM8 2.66667V6.66667H12V2.66667L8 2.66667ZM13.3333 2.66667V6.66667H17.3333V2.66667H13.3333ZM17.3333 8L13.3333 8V12L17.3333 12V8ZM17.3333 13.3333L13.3333 13.3333L13.3333 17.3333H17.3333V13.3333ZM12 17.3333L12 13.3333H8L8 17.3333H12ZM6.66667 17.3333V13.3333H2.66667V17.3333H6.66667ZM2.66667 12H6.66667V8H2.66667L2.66667 12ZM8 8V12H12V8H8Z\"\r\n fill=\"#344054\" />\r\n </svg>\r\n </div>\r\n <div>Wall</div>\r\n </div>\r\n <div>\r\n <svg *ngIf=\"elementType === 'wall'\" xmlns=\"http://www.w3.org/2000/svg\" width=\"20\"\r\n height=\"20\" viewBox=\"0 0 20 20\" fill=\"none\">\r\n <path d=\"M16.6663 5L7.49967 14.1667L3.33301 10\" stroke=\"#00A3FF\"\r\n stroke-width=\"1.66667\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\r\n </svg>\r\n </div>\r\n </li>\r\n <li (click)=\"elementType = 'facade'\" [ngClass]=\"elementType === 'facade' ? 'selected' : ''\">\r\n <div class=\"d-flex\">\r\n <div class=\"me-3\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"22\" height=\"22\"\r\n viewBox=\"0 0 22 22\" fill=\"none\">\r\n <path\r\n d=\"M1 11V2.25C1 1.5625 1.5625 1 2.25 1H19.75C20.4375 1 21 1.5625 21 2.25V19.75C21 20.4375 20.4375 21 19.75 21H2.25C1.5625 21 1 20.4375 1 19.75V11Z\"\r\n stroke=\"#344054\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\r\n </svg>\r\n </div>\r\n <div>Glass/Facade</div>\r\n </div>\r\n <div>\r\n <svg *ngIf=\"elementType === 'facade'\" xmlns=\"http://www.w3.org/2000/svg\" width=\"20\"\r\n height=\"20\" viewBox=\"0 0 20 20\" fill=\"none\">\r\n <path d=\"M16.6663 5L7.49967 14.1667L3.33301 10\" stroke=\"#00A3FF\"\r\n stroke-width=\"1.66667\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\r\n </svg>\r\n </div>\r\n </li>\r\n <li (click)=\"elementType = 'opening'\"\r\n [ngClass]=\"elementType === 'opening' ? 'selected' : ''\">\r\n <div class=\"d-flex\">\r\n <div class=\"me-3\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"20\" height=\"20\"\r\n viewBox=\"0 0 20 20\" fill=\"none\">\r\n <path\r\n d=\"M12.5 2.5H15.8333C16.2754 2.5 16.6993 2.6756 17.0118 2.98816C17.3244 3.30072 17.5 3.72464 17.5 4.16667V15.8333C17.5 16.2754 17.3244 16.6993 17.0118 17.0118C16.6993 17.3244 16.2754 17.5 15.8333 17.5H12.5M8.33333 14.1667L12.5 10M12.5 10L8.33333 5.83333M12.5 10H2.5\"\r\n stroke=\"#101828\" stroke-width=\"1.5\" stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\" />\r\n </svg>\r\n </div>\r\n <div>Opening</div>\r\n </div>\r\n <div>\r\n <svg *ngIf=\"elementType === 'opening'\" xmlns=\"http://www.w3.org/2000/svg\" width=\"20\"\r\n height=\"20\" viewBox=\"0 0 20 20\" fill=\"none\">\r\n <path d=\"M16.6663 5L7.49967 14.1667L3.33301 10\" stroke=\"#00A3FF\"\r\n stroke-width=\"1.66667\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\r\n </svg>\r\n </div>\r\n </li>\r\n <li (click)=\"elementType = 'entrance'\"\r\n [ngClass]=\"elementType === 'entrance' ? 'selected' : ''\">\r\n <div class=\"d-flex\">\r\n <div class=\"me-3\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"21\" height=\"18\"\r\n viewBox=\"0 0 21 18\" fill=\"none\">\r\n <path fill-rule=\"evenodd\" clip-rule=\"evenodd\"\r\n d=\"M17.9333 1.37949C8.7909 1.37949 1.37949 8.7909 1.37949 17.9333H0C0 8.02903 8.02903 0 17.9333 0V1.37949Z\"\r\n fill=\"#1D2939\" />\r\n <path fill-rule=\"evenodd\" clip-rule=\"evenodd\"\r\n d=\"M19.3132 1.37949H17.9333L17.9337 16.5538H19.3132V1.37949ZM16.5542 0V17.9333H20.6927V0H16.5542Z\"\r\n fill=\"#1D2939\" />\r\n </svg>\r\n </div>\r\n <div>Entrance</div>\r\n </div>\r\n <div>\r\n <svg *ngIf=\"elementType === 'entrance'\" xmlns=\"http://www.w3.org/2000/svg\"\r\n width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" fill=\"none\">\r\n <path d=\"M16.6663 5L7.49967 14.1667L3.33301 10\" stroke=\"#00A3FF\"\r\n stroke-width=\"1.66667\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\r\n </svg>\r\n </div>\r\n </li>\r\n </ul>\r\n\r\n </div>\r\n\r\n <div class=\"unit-input\">\r\n <svg (click)=\"onWidgetDistanceChange('decrement')\" class=\"cursor-pointer\"\r\n xmlns=\"http://www.w3.org/2000/svg\" width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" fill=\"none\">\r\n <path d=\"M2.9165 7H11.0832\" stroke=\"#667085\" stroke-width=\"2\" stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\" />\r\n </svg>\r\n <span>{{movePixels}}</span>\r\n <svg (click)=\"onWidgetDistanceChange('increment')\" class=\"cursor-pointer\"\r\n xmlns=\"http://www.w3.org/2000/svg\" width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" fill=\"none\">\r\n <path d=\"M6.99984 2.9165V11.0832M2.9165 6.99984H11.0832\" stroke=\"#667085\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\" />\r\n </svg>\r\n </div>\r\n\r\n <div class=\"position-relative\" style=\"position: relative; width: 229px; height: 229px;\">\r\n <div\r\n style=\"position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); z-index: 3;\">\r\n <div style=\"margin-bottom: 27px;\" class=\"d-flex justify-content-center\">\r\n <div (click)=\"onWidgetDirectionChange('up')\"\r\n [ngClass]=\"moveDirection === 'up' ? 'direction-selected' : ''\"\r\n class=\"direction-input\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"12\" height=\"12\" viewBox=\"0 0 12 12\"\r\n fill=\"none\">\r\n <path\r\n d=\"M6.00016 10.6673L6.00016 1.33398M6.00016 1.33398L1.3335 6.00065M6.00016 1.33398L10.6668 6.00065\"\r\n stroke=\"#667085\" stroke-width=\"2\" stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\" />\r\n </svg>\r\n </div>\r\n </div>\r\n <div class=\"d-flex justify-content-center align-items-center\">\r\n <div (click)=\"onWidgetDirectionChange('left')\"\r\n [ngClass]=\"moveDirection === 'left' ? 'direction-selected' : ''\"\r\n style=\"margin-right: 8px;\" class=\"direction-input\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"12\" height=\"12\" viewBox=\"0 0 12 12\"\r\n fill=\"none\">\r\n <path\r\n d=\"M10.6663 5.99935L1.33301 5.99935M1.33301 5.99935L5.99967 10.666M1.33301 5.99935L5.99968 1.33268\"\r\n stroke=\"#667085\" stroke-width=\"2\" stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\" />\r\n </svg>\r\n </div>\r\n\r\n <div class=\"unit-input\">\r\n <svg (click)=\"onWidgetAngleChange('decrement')\" class=\"cursor-pointer\"\r\n xmlns=\"http://www.w3.org/2000/svg\" width=\"14\" height=\"14\" viewBox=\"0 0 14 14\"\r\n fill=\"none\">\r\n <path d=\"M2.9165 7H11.0832\" stroke=\"#667085\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\" />\r\n </svg>\r\n <span>{{moveAngle}}\u00B0</span>\r\n <svg (click)=\"onWidgetAngleChange('increment')\" class=\"cursor-pointer\"\r\n xmlns=\"http://www.w3.org/2000/svg\" width=\"14\" height=\"14\" viewBox=\"0 0 14 14\"\r\n fill=\"none\">\r\n <path d=\"M6.99984 2.9165V11.0832M2.9165 6.99984H11.0832\" stroke=\"#667085\"\r\n stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\r\n </svg>\r\n </div>\r\n\r\n <div (click)=\"onWidgetDirectionChange('right')\"\r\n [ngClass]=\"moveDirection === 'right' ? 'direction-selected' : ''\"\r\n style=\"margin-left: 8px;\" class=\"direction-input\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"12\" height=\"12\" viewBox=\"0 0 12 12\"\r\n fill=\"none\">\r\n <path\r\n d=\"M1.33366 6.00065L10.667 6.00065M10.667 6.00065L6.00033 1.33398M10.667 6.00065L6.00033 10.6673\"\r\n stroke=\"#667085\" stroke-width=\"2\" stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\" />\r\n </svg>\r\n </div>\r\n\r\n </div>\r\n\r\n <div style=\"margin-top: 27px;\" class=\"d-flex justify-content-center\">\r\n <div (click)=\"onWidgetDirectionChange('down')\"\r\n [ngClass]=\"moveDirection === 'down' ? 'direction-selected' : ''\"\r\n class=\"direction-input\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"12\" height=\"12\" viewBox=\"0 0 12 12\"\r\n fill=\"none\">\r\n <path\r\n d=\"M5.99984 1.33268L5.99984 10.666M5.99984 10.666L10.6665 5.99935M5.99984 10.666L1.33317 5.99935\"\r\n stroke=\"#667085\" stroke-width=\"2\" stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\" />\r\n </svg>\r\n </div>\r\n </div>\r\n </div>\r\n <canvas height=\"229px\" width=\"229px\" #widgetCanvas\r\n style=\"position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); z-index: 1;\"></canvas>\r\n <div style=\"position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); z-index: 2;\"\r\n #circle class=\"circle\">\r\n <div class=\"line\" *ngFor=\"let line of lines\"\r\n [ngClass]=\"{'line--highlight': line.highlight, 'line--invisible': line.invisible}\"\r\n [style.transform]=\"line.transform\"></div>\r\n\r\n <div #pointer class=\"pointer\"></div>\r\n </div>\r\n </div>\r\n\r\n <button (click)=\"movePointWithAngle()\"\r\n [disabled]=\"!movePixels && moveAngle !== undefined && moveAngle !== null\"\r\n class=\" w-100 go-btn\">Go</button>\r\n\r\n </div>\r\n\r\n <!-- <div *ngIf=\"popupVisible && popupPosition\" [style.top.px]=\"popupPosition.y\" [style.left.px]=\"popupPosition.x\"\r\n class=\"popup\">\r\n <label>Move Pixels:</label>\r\n <select [(ngModel)]=\"elementType\">\r\n <option value=\"wall\">Wall</option>\r\n <option value=\"facade\">Glass/Facade</option>\r\n <option value=\"opening\">Opening</option>\r\n <option value=\"entrance\">Entrance</option>\r\n </select>\r\n <input type=\"number\" [(ngModel)]=\"movePixels\" />\r\n\r\n <select [(ngModel)]=\"moveDirection\">\r\n <option value=\"right\">Right</option>\r\n <option value=\"down\">Down</option>\r\n <option value=\"left\">Left</option>\r\n <option value=\"up\">Up</option>\r\n </select>\r\n <input type=\"number\" [(ngModel)]=\"moveAngle\" (ngModelChange)=\"layoutLengthPreview()\" />\r\n <button (click)=\"movePointWithAngle()\">Move with angle</button>\r\n </div> -->\r\n </div>\r\n\r\n </div>\r\n </div>\r\n\r\n <div *ngIf=\"planoStoreList.length > 1\" class=\"col-12 mt-6\">\r\n <div style=\"padding: 0px !important;\" class=\"c-card\">\r\n <lib-pagination [itemsPerPage]=\"itemsPerPage\" (pageChange)=\"onPageChange($event)\" [currentPage]=\"currentPage\" [totalItems]=\"totalItems\"\r\n [paginationSizes]=\"paginationSizes\" [pageSize]=\"pageSize\"></lib-pagination>\r\n </div>\r\n </div>\r\n\r\n</div>", styles: [".storename-txt{color:#101828;font-size:16px;font-weight:600;line-height:24px}.c-card{padding:16px;border-radius:8px;background:#fff}.l-pane-head{color:#101828;font-size:18px;font-weight:600;line-height:28px}.l-pane-desc{color:#475467;font-size:12px;font-weight:400;line-height:18px}.elipsis-btn{display:flex;width:40px;height:40px;padding:10px;justify-content:center;align-items:center;gap:8px;border-radius:48px;border:1px solid #D0D5DD;background:#fff;cursor:pointer}.no-steps-txt{color:#101828;font-size:18px;font-weight:500;line-height:28px}.no-text-desc{color:#101828;font-size:14px;font-weight:400;line-height:20px}.hide-scrollbar{overflow:scroll;-ms-overflow-style:none;scrollbar-width:none}.hide-scrollbar::-webkit-scrollbar{display:none}.popup{position:absolute;background:#fff;border:1px solid black;padding:10px;box-shadow:0 4px 8px #0003;z-index:1000}.resize-icon{cursor:pointer;border-radius:727.273px;background:#fff;box-shadow:0 8.727px 11.636px -2.909px #10182814,0 2.909px 4.364px -1.455px #10182808;position:absolute;right:-13px;top:70px;padding:7.273px}.resize-icon svg{width:17.455px;height:17.455px}th{background-color:#fff!important;color:#667085!important;font-size:12px!important;font-weight:400!important}td{color:#101828!important;font-size:14px!important;font-weight:500!important}.element-type-dropdown{display:flex;height:44px;padding:10px 14px;align-items:center;gap:8px;flex-shrink:0;align-self:stretch;border-radius:8px;border:1px solid #D0D5DD;background:#fff;cursor:pointer;position:relative}.element-type-dropdown .type-txt{color:#1d2939;font-family:Inter;font-size:16px;font-style:normal;font-weight:400;line-height:24px}.element-type-dropdown .down-arrow{width:20px;height:20px}.element-type-dropdown ul{position:absolute;top:45px;width:200px;left:0;border-radius:4px;border:1px solid #EAECF0;background:#fff;box-shadow:0 12px 16px -4px #10182814,0 4px 6px -2px #10182808}.element-type-dropdown ul li{display:flex;align-items:center;justify-content:space-between;padding:10px 16px}.element-type-dropdown ul .selected{background:#f9fafb}.direction-dropdown{display:flex;height:44px;padding:10px 14px;align-items:center;gap:8px;flex-shrink:0;align-self:stretch;border-radius:8px;border:1px solid #D0D5DD;background:#fff;cursor:pointer;position:relative}.direction-dropdown .down-arrow{width:20px;height:20px}.direction-dropdown ul{position:absolute;top:45px;width:200px;left:0;border-radius:4px;border:1px solid #EAECF0;background:#fff;box-shadow:0 12px 16px -4px #10182814,0 4px 6px -2px #10182808}.direction-dropdown ul li{display:flex;align-items:center;justify-content:space-between;padding:10px 16px}.direction-dropdown ul .selected{background:#f9fafb}.elipsis-icon-dropdown{position:relative}.elipsis-icon-dropdown ul{position:absolute;top:45px;width:200px;right:0;border-radius:4px;border:1px solid #EAECF0;background:#fff;box-shadow:0 12px 16px -4px #10182814,0 4px 6px -2px #10182808}.elipsis-icon-dropdown ul li{display:flex;align-items:center;justify-content:space-between;padding:10px 16px;cursor:pointer;position:relative}.elipsis-icon-dropdown ul li .export-options{display:none;position:absolute;left:298px;top:-47px}.elipsis-icon-dropdown ul li .export-options ul{border-radius:4px;border:1px solid #EAECF0;background:#fff;box-shadow:0 12px 16px -4px #10182814,0 4px 6px -2px #10182808;z-index:5;width:100px;padding:0}.elipsis-icon-dropdown ul li .export-options ul li{display:flex;align-items:center;justify-content:space-between;padding:10px 16px;cursor:pointer}.elipsis-icon-dropdown ul li:hover .export-options{display:block}.elipsis-icon-dropdown ul li:hover{background:#f9fafb}.element-name{display:flex;padding:10px 14px;align-items:center;gap:8px;flex:1 0 0;align-self:stretch;border-radius:8px;background:#f9fafb;color:#101828;font-family:Inter;font-size:14px;font-style:normal;font-weight:500;line-height:20px;white-space:nowrap}.unit-input{display:flex;justify-content:space-between;width:72px;height:44px;padding:4px 6px;align-items:center;gap:4px;border-radius:8px;border:1px solid #D0D5DD;background:#fff}.angle-input{width:55px;display:flex;padding:10px 14px;align-items:center;gap:8px;align-self:stretch;border-radius:8px;border:1px solid #D0D5DD;background:#fff}.angle-widget{position:absolute;display:flex;min-width:259px;padding:14px;align-items:flex-start;align-content:flex-start;gap:14px 10px;flex-wrap:wrap;border-radius:8px;border:1px solid #6BCAFF;background:#fff;box-shadow:0 12px 16px -4px #10182814,0 4px 6px -2px #10182808}.angle-widget .go-btn{border-radius:8px;border:1px solid #EAF8FF;background:#eaf8ff;padding:10px 16px;color:#009bf3;font-size:12px;font-weight:600;line-height:18px}.angle-widget .go-btn:disabled{border:1px solid #F6FCFF;background:#f6fcff;color:#6bcaff}.angle-widget .direction-input{padding:4px 8px;border-radius:8px;border:1px solid #667085;background:#fff;cursor:pointer}.angle-widget .direction-selected{border:1px solid #33B5FF}.angle-widget .direction-selected svg path{stroke:#33b5ff;fill:#33b5ff}.angle-widget .circle{width:229px;height:229px;border-radius:50%;position:relative;transform:rotate(-180deg)}.angle-widget .line{background:linear-gradient(to top,transparent 80%,rgba(0,0,0,.2) 80%);width:1px;height:114.5px;left:calc(50% - .5px);top:0;position:absolute;transform-origin:bottom;display:flex;justify-content:center}.angle-widget .line--highlight{background:linear-gradient(to top,transparent 80%,black 80%)}.angle-widget .line--invisible{background:transparent!important}.angle-widget .pointer{width:0px;height:114.5px;transform-origin:bottom;position:absolute;top:0;left:50%;background:#000;display:flex;justify-content:center}.angle-widget .pointer:after{display:block;content:\"\";width:0;height:25px;border-left:5px solid transparent;border-right:5px solid transparent;border-bottom:10px solid #33B5FF}.angle-widget .z-4{z-index:4}.menu-txt1{color:#344054;font-size:14px;font-weight:500;line-height:20px}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{-webkit-appearance:none;margin:0}input[type=number]{-moz-appearance:textfield}.floor-select{width:155px;height:44px;border-radius:8px;border:1px solid #D0D5DD;background:#fff;box-shadow:0 1px 2px #1018280d;position:relative;display:flex;justify-content:space-between;padding:10px 16px;cursor:pointer;color:#344054;font-size:14px;font-weight:600;line-height:20px}.floor-select ul{width:240px;box-shadow:0 20px 24px -4px #10182814,0 8px 8px -4px #10182808;position:absolute;top:45px;left:0;background:#fff;z-index:4}.floor-select ul li{position:relative;padding:10px 16px;color:#1d2939;font-size:14px;font-weight:500;line-height:20px;align-items:center;cursor:pointer}.floor-select ul li .option{width:200px;position:absolute;padding:10px 16px;background:#fef3f2;color:#d92d20;font-size:14px;font-weight:500;line-height:20px;right:-200px;top:0}.floor-select ul li:hover,.floor-select ul .selected{background:#f2f4f7}.selected-element{border:1px solid #008EDF!important}td .drag-handler svg{display:none}td .drag-handler:hover svg{display:block}\n"], dependencies: [{ kind: "directive", type: i5.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { 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: 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.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i6.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i6.MinValidator, selector: "input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]", inputs: ["min"] }, { kind: "directive", type: i6.MaxValidator, selector: "input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]", inputs: ["max"] }, { kind: "directive", type: i6.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i4.PaginationComponent, selector: "lib-pagination", inputs: ["collection", "itemsPerPage", "currentPage", "totalItems", "directionLinks", "pageSize", "paginationSizes"], outputs: ["pageChange", "pageSizeChange"] }, { kind: "directive", type: i7.CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: i7.CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "component", type: i8.CustomSelectComponent, selector: "lib-select-plano", inputs: ["items", "searchField", "multi", "idField", "selectedValues", "disabled", "label"], outputs: ["selected"] }] });
|
|
1789
|
+
}
|
|
1790
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: CreateLayoutComponent, decorators: [{
|
|
1791
|
+
type: Component,
|
|
1792
|
+
args: [{ selector: 'lib-create-layout', template: "<div class=\"d-flex align-items-center justify-content-between mb-6\">\r\n <div>\r\n <div *ngIf=\"planoStoreList.length === 1\" class=\"storename-txt\">\r\n {{selectedStore?.storeName}} - Layout\r\n </div>\r\n <div *ngIf=\"planoStoreList.length > 1\">\r\n <lib-select-plano [items]=\"planoStoreList\" [multi]=\"false\" [searchField]=\"'storeName'\" [idField]=\"'storeId'\"\r\n (selected)=\"onStoreChange($event)\" [selectedValues]=\"[selectedStore]\"></lib-select-plano>\r\n </div>\r\n </div>\r\n\r\n <div class=\"d-flex align-items-center\">\r\n <button (click)=\"onSaveAsDraft()\" class=\"btn btn-outline bg-white me-5\">Save As Draft</button>\r\n <button (click)=\"onConfigure()\" class=\"btn btn-sm btn-primary me-5\">Configure</button>\r\n <button (click)=\"openOffCanva()\" class=\"btn btn-sm btn-outline bg-white\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\">\r\n <path\r\n d=\"M9 3V21M5 3H19C20.1046 3 21 3.89543 21 5V19C21 20.1046 20.1046 21 19 21H5C3.89543 21 3 20.1046 3 19V5C3 3.89543 3.89543 3 5 3Z\"\r\n stroke=\"#101828\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\r\n </svg>\r\n </button>\r\n </div>\r\n</div>\r\n\r\n<div class=\"row\">\r\n <div [ngClass]=\"layoutMode === 'full' ? 'col-2' : 'col-5'\">\r\n <div class=\"c-card\" style=\"height: 75dvh; position: relative;\">\r\n <div class=\"resize-icon\" *ngIf=\"layoutMode === 'half'\" (click)=\"layoutMode = 'full'\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" viewBox=\"0 0 18 18\" fill=\"none\">\r\n <path\r\n d=\"M8.27259 12.6365L4.63623 9.00013L8.27259 5.36377M13.3635 12.6365L9.72714 9.00013L13.3635 5.36377\"\r\n stroke=\"#101828\" stroke-width=\"1.45455\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\r\n </svg>\r\n </div>\r\n <div class=\"resize-icon\" *ngIf=\"layoutMode === 'full'\" (click)=\"layoutMode = 'half'\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" viewBox=\"0 0 18 18\" fill=\"none\">\r\n <path\r\n d=\"M9.72741 5.36399L13.3638 9.00036L9.72741 12.6367M4.6365 5.36399L8.27286 9.00036L4.6365 12.6367\"\r\n stroke=\"#101828\" stroke-width=\"1.45455\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\r\n </svg>\r\n </div>\r\n <div class=\"d-flex align-items-center justify-content-between mb-5\" style=\"height: 8%;\">\r\n <div>\r\n <div class=\"l-pane-head\">\r\n Layout details\r\n </div>\r\n <div *ngIf=\"layoutMode === 'half'\" class=\"l-pane-desc\">\r\n Below are the sequence of steps for this layout\r\n </div>\r\n </div>\r\n <div class=\"d-flex align-items-center\">\r\n <ng-container *ngIf=\"layoutMode === 'half'\">\r\n <svg (click)=\"undo()\" class=\"me-3 cursor-pointer\" xmlns=\"http://www.w3.org/2000/svg\" width=\"24\"\r\n height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\">\r\n <path [attr.fill]=\"undoStack.length ? '#1D2939' : '#D0D5DD'\"\r\n d=\"M7 19V17H14.1C15.15 17 16.0627 16.6667 16.838 16C17.6133 15.3333 18.0007 14.5 18 13.5C18 12.5 17.6123 11.6667 16.837 11C16.0617 10.3333 15.1493 10 14.1 10H7.8L10.4 12.6L9 14L4 9L9 4L10.4 5.4L7.8 8H14.1C15.7167 8 17.1043 8.525 18.263 9.575C19.4217 10.625 20.0007 11.9333 20 13.5C20 15.0667 19.4207 16.375 18.262 17.425C17.1033 18.475 15.716 19 14.1 19H7Z\"\r\n fill=\"#D0D5DD\" />\r\n </svg>\r\n <svg (click)=\"redo()\" class=\"me-6 cursor-pointer\" xmlns=\"http://www.w3.org/2000/svg\" width=\"24\"\r\n height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\">\r\n <path [attr.fill]=\"redoStack.length ? '#1D2939' : '#D0D5DD'\"\r\n d=\"M9.9 19C8.28333 19 6.89567 18.475 5.737 17.425C4.57833 16.375 3.99933 15.0667 4 13.5C4 11.9333 4.57933 10.625 5.738 9.575C6.89667 8.525 8.284 8 9.9 8H16.2L13.6 5.4L15 4L20 9L15 14L13.6 12.6L16.2 10H9.9C8.85 10 7.93733 10.3333 7.162 11C6.38667 11.6667 5.99933 12.5 6 13.5C6 14.5 6.38767 15.3333 7.163 16C7.93833 16.6667 8.85067 17 9.9 17H17V19H9.9Z\"\r\n fill=\"#D0D5DD\" />\r\n </svg>\r\n <div (click)=\"toggleLayoutOptionSelect()\"\r\n class=\"d-flex align-items-center justify-content-center h-100 elipsis-icon-dropdown top-elipsis-menu\">\r\n <div class=\"elipsis-btn\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\"\r\n fill=\"none\">\r\n <path\r\n d=\"M11 11.9997C11 12.5289 11.4477 12.958 12 12.958C12.5523 12.958 13 12.5289 13 11.9997C13 11.4704 12.5523 11.0413 12 11.0413C11.4477 11.0413 11 11.4704 11 11.9997Z\"\r\n stroke=\"#101828\" stroke-width=\"2\" stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\" />\r\n <path\r\n d=\"M11 18.708C11 19.2373 11.4477 19.6663 12 19.6663C12.5523 19.6663 13 19.2373 13 18.708C13 18.1787 12.5523 17.7497 12 17.7497C11.4477 17.7497 11 18.1787 11 18.708Z\"\r\n stroke=\"#101828\" stroke-width=\"2\" stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\" />\r\n <path\r\n d=\"M11 5.29134C11 5.82061 11.4477 6.24967 12 6.24967C12.5523 6.24967 13 5.82061 13 5.29134C13 4.76207 12.5523 4.33301 12 4.33301C11.4477 4.33301 11 4.76207 11 5.29134Z\"\r\n stroke=\"#101828\" stroke-width=\"2\" stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\" />\r\n </svg>\r\n </div>\r\n <ul *ngIf=\"layoutOptionSelect?.show\" [ngClass]=\" (layoutOptionSelect.show ) ? 'z-1': ''\"\r\n class=\"list-unstyled mb-2\">\r\n <li>\r\n <div class=\"d-flex justify-content-between w-100\">\r\n <div class=\"menu-txt1\">Export</div>\r\n <span>\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"8\" height=\"14\" viewBox=\"0 0 8 14\" fill=\"none\">\r\n <path d=\"M1 13L7 7L1 1\" stroke=\"#101828\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\r\n </svg>\r\n </span>\r\n </div>\r\n <div class=\"export-options\">\r\n <ul>\r\n <li (click)=\"exportToExcel()\" >XLSX</li>\r\n <li (click)=\"exportAsPng()\" >PNG</li>\r\n </ul>\r\n </div>\r\n\r\n </li>\r\n <li (click)=\"onClearAll()\">\r\n <div class=\"d-flex\">\r\n <div class=\"menu-txt1\">Clear all</div>\r\n </div>\r\n\r\n </li>\r\n <li (click)=\"onDeleteLayout()\">\r\n <div class=\"d-flex\">\r\n <div class=\"menu-txt1 text-danger\">Delete</div>\r\n </div>\r\n </li>\r\n\r\n </ul>\r\n </div>\r\n\r\n </ng-container>\r\n\r\n\r\n\r\n </div>\r\n\r\n </div>\r\n\r\n <!-- <div class=\"d-flex align-items-center flex-column mx-auto\" style=\"margin-top: 200px;\" >\r\n <div class=\"no-steps-txt mb-3\">\r\n No steps have been created so far\r\n </div>\r\n <div class=\"no-text-desc text-center\">\r\n Start designing the layout by applying the steps using elements and dimensions.\r\n </div>\r\n </div> -->\r\n\r\n <div class=\"table-responsive hide-scrollbar \" style=\"height: 92%;\">\r\n <table class=\"table\">\r\n <thead class=\"thead-light\">\r\n <tr>\r\n <th>Steps</th>\r\n <th>Elements and Definition</th>\r\n <th>Feet</th>\r\n <th>Direction</th>\r\n <th>Degree</th>\r\n <th></th>\r\n </tr>\r\n </thead>\r\n <tbody cdkDropList (cdkDropListDropped)=\"drop($event)\">\r\n <ng-container *ngFor=\"let item of layoutPolygon; let i = index\">\r\n <tr [ngClass]=\"selectedLineIndex === i ? 'selected-element' : ''\" *ngIf=\"item?.[2]\" cdkDrag>\r\n <td>\r\n <div class=\"d-flex align-items-center justify-content-center w-100 h-100 drag-handler\">\r\n <span class=\"mr-2 \" >\r\n <svg class=\"cursor-pointer\" xmlns=\"http://www.w3.org/2000/svg\" width=\"19\" height=\"19\" viewBox=\"0 0 19 19\">\r\n <circle cx=\"5\" cy=\"5\" r=\"2\" fill=\"gray\" />\r\n <circle cx=\"14\" cy=\"5\" r=\"2\" fill=\"gray\" />\r\n <circle cx=\"5\" cy=\"10\" r=\"2\" fill=\"gray\" />\r\n <circle cx=\"14\" cy=\"10\" r=\"2\" fill=\"gray\" />\r\n <circle cx=\"5\" cy=\"15\" r=\"2\" fill=\"gray\" />\r\n <circle cx=\"14\" cy=\"15\" r=\"2\" fill=\"gray\" />\r\n </svg>\r\n </span>\r\n <span>{{ i + 1}}</span>\r\n </div>\r\n </td>\r\n <td>\r\n <div class=\"d-flex\">\r\n <div (click)=\"toggleElementSelect(i)\"\r\n class=\"element-type-dropdown me-2 position-relative\">\r\n <div>\r\n <svg *ngIf=\"item[2].elementType === 'wall'\"\r\n xmlns=\"http://www.w3.org/2000/svg\" width=\"20\" height=\"20\"\r\n viewBox=\"0 0 20 20\" fill=\"none\">\r\n <path fill-rule=\"evenodd\" clip-rule=\"evenodd\"\r\n d=\"M1.33333 1.33333V0L2.66667 0V1.33333L6.66667 1.33333V0L8 0V1.33333L12 1.33333V0L13.3333 0V1.33333L17.3333 1.33333V0L18.6667 0V1.33333H20V2.66667H18.6667V6.66667H20V8H18.6667V12H20V13.3333H18.6667V17.3333H20V18.6667H18.6667V20H17.3333V18.6667H13.3333V20H12V18.6667H8V20H6.66667V18.6667H2.66667V20H1.33333V18.6667H0L0 17.3333H1.33333L1.33333 13.3333H0L0 12H1.33333L1.33333 8H0L0 6.66667H1.33333L1.33333 2.66667H0L0 1.33333H1.33333ZM2.66667 2.66667L2.66667 6.66667H6.66667V2.66667L2.66667 2.66667ZM8 2.66667V6.66667H12V2.66667L8 2.66667ZM13.3333 2.66667V6.66667H17.3333V2.66667H13.3333ZM17.3333 8L13.3333 8V12L17.3333 12V8ZM17.3333 13.3333L13.3333 13.3333L13.3333 17.3333H17.3333V13.3333ZM12 17.3333L12 13.3333H8L8 17.3333H12ZM6.66667 17.3333V13.3333H2.66667V17.3333H6.66667ZM2.66667 12H6.66667V8H2.66667L2.66667 12ZM8 8V12H12V8H8Z\"\r\n fill=\"#344054\" />\r\n </svg>\r\n\r\n <svg *ngIf=\"item[2].elementType === 'facade'\"\r\n xmlns=\"http://www.w3.org/2000/svg\" width=\"22\" height=\"22\"\r\n viewBox=\"0 0 22 22\" fill=\"none\">\r\n <path\r\n d=\"M1 11V2.25C1 1.5625 1.5625 1 2.25 1H19.75C20.4375 1 21 1.5625 21 2.25V19.75C21 20.4375 20.4375 21 19.75 21H2.25C1.5625 21 1 20.4375 1 19.75V11Z\"\r\n stroke=\"#344054\" stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\" />\r\n </svg>\r\n\r\n <svg *ngIf=\"item[2].elementType === 'opening'\"\r\n xmlns=\"http://www.w3.org/2000/svg\" width=\"20\" height=\"20\"\r\n viewBox=\"0 0 20 20\" fill=\"none\">\r\n <path\r\n d=\"M12.5 2.5H15.8333C16.2754 2.5 16.6993 2.6756 17.0118 2.98816C17.3244 3.30072 17.5 3.72464 17.5 4.16667V15.8333C17.5 16.2754 17.3244 16.6993 17.0118 17.0118C16.6993 17.3244 16.2754 17.5 15.8333 17.5H12.5M8.33333 14.1667L12.5 10M12.5 10L8.33333 5.83333M12.5 10H2.5\"\r\n stroke=\"#101828\" stroke-width=\"1.5\" stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\" />\r\n </svg>\r\n\r\n <svg *ngIf=\"item[2].elementType === 'entrance'\"\r\n xmlns=\"http://www.w3.org/2000/svg\" width=\"21\" height=\"18\"\r\n viewBox=\"0 0 21 18\" fill=\"none\">\r\n <path fill-rule=\"evenodd\" clip-rule=\"evenodd\"\r\n d=\"M17.9333 1.37949C8.7909 1.37949 1.37949 8.7909 1.37949 17.9333H0C0 8.02903 8.02903 0 17.9333 0V1.37949Z\"\r\n fill=\"#1D2939\" />\r\n <path fill-rule=\"evenodd\" clip-rule=\"evenodd\"\r\n d=\"M19.3132 1.37949H17.9333L17.9337 16.5538H19.3132V1.37949ZM16.5542 0V17.9333H20.6927V0H16.5542Z\"\r\n fill=\"#1D2939\" />\r\n </svg>\r\n </div>\r\n\r\n <div class=\"down-arrow\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"20\" height=\"20\"\r\n viewBox=\"0 0 20 20\" fill=\"none\">\r\n <path d=\"M5 7.5L10 12.5L15 7.5\" stroke=\"#667085\"\r\n stroke-width=\"1.66667\" stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\" />\r\n </svg>\r\n </div>\r\n\r\n <ul *ngIf=\"elementSelect?.show && elementSelect?.index === i\"\r\n [ngClass]=\" (elementSelect.show && elementSelect.index === i) ? 'z-1': ''\"\r\n class=\"list-unstyled mb-2\">\r\n <li (click)=\"onElementTypeChange('wall', i)\"\r\n [ngClass]=\"item[2].elementType === 'wall' ? 'selected' : ''\">\r\n <div class=\"d-flex\">\r\n <div class=\"me-3\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"20\"\r\n height=\"20\" viewBox=\"0 0 20 20\" fill=\"none\">\r\n <path fill-rule=\"evenodd\" clip-rule=\"evenodd\"\r\n d=\"M1.33333 1.33333V0L2.66667 0V1.33333L6.66667 1.33333V0L8 0V1.33333L12 1.33333V0L13.3333 0V1.33333L17.3333 1.33333V0L18.6667 0V1.33333H20V2.66667H18.6667V6.66667H20V8H18.6667V12H20V13.3333H18.6667V17.3333H20V18.6667H18.6667V20H17.3333V18.6667H13.3333V20H12V18.6667H8V20H6.66667V18.6667H2.66667V20H1.33333V18.6667H0L0 17.3333H1.33333L1.33333 13.3333H0L0 12H1.33333L1.33333 8H0L0 6.66667H1.33333L1.33333 2.66667H0L0 1.33333H1.33333ZM2.66667 2.66667L2.66667 6.66667H6.66667V2.66667L2.66667 2.66667ZM8 2.66667V6.66667H12V2.66667L8 2.66667ZM13.3333 2.66667V6.66667H17.3333V2.66667H13.3333ZM17.3333 8L13.3333 8V12L17.3333 12V8ZM17.3333 13.3333L13.3333 13.3333L13.3333 17.3333H17.3333V13.3333ZM12 17.3333L12 13.3333H8L8 17.3333H12ZM6.66667 17.3333V13.3333H2.66667V17.3333H6.66667ZM2.66667 12H6.66667V8H2.66667L2.66667 12ZM8 8V12H12V8H8Z\"\r\n fill=\"#344054\" />\r\n </svg>\r\n </div>\r\n <div>Wall</div>\r\n </div>\r\n <div>\r\n <svg *ngIf=\"item[2].elementType === 'wall'\"\r\n xmlns=\"http://www.w3.org/2000/svg\" width=\"20\" height=\"20\"\r\n viewBox=\"0 0 20 20\" fill=\"none\">\r\n <path d=\"M16.6663 5L7.49967 14.1667L3.33301 10\"\r\n stroke=\"#00A3FF\" stroke-width=\"1.66667\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\" />\r\n </svg>\r\n </div>\r\n </li>\r\n <li (click)=\"onElementTypeChange('facade', i)\"\r\n [ngClass]=\"item[2].elementType === 'facade' ? 'selected' : ''\">\r\n <div class=\"d-flex\">\r\n <div class=\"me-3\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"22\"\r\n height=\"22\" viewBox=\"0 0 22 22\" fill=\"none\">\r\n <path\r\n d=\"M1 11V2.25C1 1.5625 1.5625 1 2.25 1H19.75C20.4375 1 21 1.5625 21 2.25V19.75C21 20.4375 20.4375 21 19.75 21H2.25C1.5625 21 1 20.4375 1 19.75V11Z\"\r\n stroke=\"#344054\" stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\" />\r\n </svg>\r\n </div>\r\n <div>Glass/Facade</div>\r\n </div>\r\n <div>\r\n <svg *ngIf=\"item[2].elementType === 'facade'\"\r\n xmlns=\"http://www.w3.org/2000/svg\" width=\"20\" height=\"20\"\r\n viewBox=\"0 0 20 20\" fill=\"none\">\r\n <path d=\"M16.6663 5L7.49967 14.1667L3.33301 10\"\r\n stroke=\"#00A3FF\" stroke-width=\"1.66667\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\" />\r\n </svg>\r\n </div>\r\n </li>\r\n <li (click)=\"onElementTypeChange('opening', i)\"\r\n [ngClass]=\"item[2].elementType === 'opening' ? 'selected' : ''\">\r\n <div class=\"d-flex\">\r\n <div class=\"me-3\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"20\"\r\n height=\"20\" viewBox=\"0 0 20 20\" fill=\"none\">\r\n <path\r\n d=\"M12.5 2.5H15.8333C16.2754 2.5 16.6993 2.6756 17.0118 2.98816C17.3244 3.30072 17.5 3.72464 17.5 4.16667V15.8333C17.5 16.2754 17.3244 16.6993 17.0118 17.0118C16.6993 17.3244 16.2754 17.5 15.8333 17.5H12.5M8.33333 14.1667L12.5 10M12.5 10L8.33333 5.83333M12.5 10H2.5\"\r\n stroke=\"#101828\" stroke-width=\"1.5\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\" />\r\n </svg>\r\n </div>\r\n <div>Opening</div>\r\n </div>\r\n <div>\r\n <svg *ngIf=\"item[2].elementType === 'opening'\"\r\n xmlns=\"http://www.w3.org/2000/svg\" width=\"20\" height=\"20\"\r\n viewBox=\"0 0 20 20\" fill=\"none\">\r\n <path d=\"M16.6663 5L7.49967 14.1667L3.33301 10\"\r\n stroke=\"#00A3FF\" stroke-width=\"1.66667\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\" />\r\n </svg>\r\n </div>\r\n </li>\r\n <li (click)=\"onElementTypeChange('entrance', i)\"\r\n [ngClass]=\"item[2].elementType === 'entrance' ? 'selected' : ''\">\r\n <div class=\"d-flex\">\r\n <div class=\"me-3\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"21\"\r\n height=\"18\" viewBox=\"0 0 21 18\" fill=\"none\">\r\n <path fill-rule=\"evenodd\" clip-rule=\"evenodd\"\r\n d=\"M17.9333 1.37949C8.7909 1.37949 1.37949 8.7909 1.37949 17.9333H0C0 8.02903 8.02903 0 17.9333 0V1.37949Z\"\r\n fill=\"#1D2939\" />\r\n <path fill-rule=\"evenodd\" clip-rule=\"evenodd\"\r\n d=\"M19.3132 1.37949H17.9333L17.9337 16.5538H19.3132V1.37949ZM16.5542 0V17.9333H20.6927V0H16.5542Z\"\r\n fill=\"#1D2939\" />\r\n </svg>\r\n </div>\r\n <div>Entrance</div>\r\n </div>\r\n <div>\r\n <svg *ngIf=\"item[2].elementType === 'entrance'\"\r\n xmlns=\"http://www.w3.org/2000/svg\" width=\"20\" height=\"20\"\r\n viewBox=\"0 0 20 20\" fill=\"none\">\r\n <path d=\"M16.6663 5L7.49967 14.1667L3.33301 10\"\r\n stroke=\"#00A3FF\" stroke-width=\"1.66667\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\" />\r\n </svg>\r\n </div>\r\n </li>\r\n </ul>\r\n\r\n </div>\r\n <div class=\"element-name\">{{item[2].elementType}} {{item[2].elementNumber}}\r\n </div>\r\n </div>\r\n </td>\r\n <td>\r\n <div class=\"unit-input\">\r\n <svg (click)=\"onDistanceChange('decrement', i)\" class=\"cursor-pointer\"\r\n xmlns=\"http://www.w3.org/2000/svg\" width=\"14\" height=\"14\"\r\n viewBox=\"0 0 14 14\" fill=\"none\">\r\n <path d=\"M2.9165 7H11.0832\" stroke=\"#667085\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\" />\r\n </svg>\r\n <span>{{item[2].distance}}</span>\r\n <svg (click)=\"onDistanceChange('increment', i)\" class=\"cursor-pointer\"\r\n xmlns=\"http://www.w3.org/2000/svg\" width=\"14\" height=\"14\"\r\n viewBox=\"0 0 14 14\" fill=\"none\">\r\n <path d=\"M6.99984 2.9165V11.0832M2.9165 6.99984H11.0832\" stroke=\"#667085\"\r\n stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\r\n </svg>\r\n </div>\r\n </td>\r\n <td>\r\n <div (click)=\"toggleDirectionSelect(i)\"\r\n class=\"direction-dropdown position-relative\">\r\n <div>\r\n {{item[2].direction}}\r\n </div>\r\n\r\n <div class=\"down-arrow\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"20\" height=\"20\"\r\n viewBox=\"0 0 20 20\" fill=\"none\">\r\n <path d=\"M5 7.5L10 12.5L15 7.5\" stroke=\"#667085\" stroke-width=\"1.66667\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\" />\r\n </svg>\r\n </div>\r\n\r\n <ul *ngIf=\"directionSelect?.show && directionSelect?.index === i\"\r\n [ngClass]=\" (directionSelect.show && directionSelect.index === i) ? 'z-1': ''\"\r\n class=\"list-unstyled mb-2\">\r\n <li (click)=\"onDirectionChange('up', i)\"\r\n [ngClass]=\"item[2].direction === 'up' ? 'selected' : ''\">\r\n <div class=\"d-flex\">\r\n <div>Up</div>\r\n </div>\r\n <div>\r\n <svg *ngIf=\"item[2].direction === 'up'\"\r\n xmlns=\"http://www.w3.org/2000/svg\" width=\"20\" height=\"20\"\r\n viewBox=\"0 0 20 20\" fill=\"none\">\r\n <path d=\"M16.6663 5L7.49967 14.1667L3.33301 10\" stroke=\"#00A3FF\"\r\n stroke-width=\"1.66667\" stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\" />\r\n </svg>\r\n </div>\r\n </li>\r\n <li (click)=\"onDirectionChange('down', i)\"\r\n [ngClass]=\"item[2].direction === 'down' ? 'selected' : ''\">\r\n <div class=\"d-flex\">\r\n\r\n <div>Down</div>\r\n </div>\r\n <div>\r\n <svg *ngIf=\"item[2].direction === 'down'\"\r\n xmlns=\"http://www.w3.org/2000/svg\" width=\"20\" height=\"20\"\r\n viewBox=\"0 0 20 20\" fill=\"none\">\r\n <path d=\"M16.6663 5L7.49967 14.1667L3.33301 10\" stroke=\"#00A3FF\"\r\n stroke-width=\"1.66667\" stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\" />\r\n </svg>\r\n </div>\r\n </li>\r\n <li (click)=\"onDirectionChange('right', i)\"\r\n [ngClass]=\"item[2].direction === 'right' ? 'selected' : ''\">\r\n <div class=\"d-flex\">\r\n\r\n <div>Right</div>\r\n </div>\r\n <div>\r\n <svg *ngIf=\"item[2].direction === 'right'\"\r\n xmlns=\"http://www.w3.org/2000/svg\" width=\"20\" height=\"20\"\r\n viewBox=\"0 0 20 20\" fill=\"none\">\r\n <path d=\"M16.6663 5L7.49967 14.1667L3.33301 10\" stroke=\"#00A3FF\"\r\n stroke-width=\"1.66667\" stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\" />\r\n </svg>\r\n </div>\r\n </li>\r\n <li (click)=\"onDirectionChange('left', i)\"\r\n [ngClass]=\"item[2].direction === 'left' ? 'selected' : ''\">\r\n <div class=\"d-flex\">\r\n\r\n <div>Left</div>\r\n </div>\r\n <div>\r\n <svg *ngIf=\"item[2].direction === 'left'\"\r\n xmlns=\"http://www.w3.org/2000/svg\" width=\"20\" height=\"20\"\r\n viewBox=\"0 0 20 20\" fill=\"none\">\r\n <path d=\"M16.6663 5L7.49967 14.1667L3.33301 10\" stroke=\"#00A3FF\"\r\n stroke-width=\"1.66667\" stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\" />\r\n </svg>\r\n </div>\r\n </li>\r\n </ul>\r\n\r\n </div>\r\n </td>\r\n\r\n <td>\r\n <input min=\"0\" max=\"180\" class=\"angle-input\" [(ngModel)]=\"item[2].angle\"\r\n type=\"number\" (input)=\"validateAngleInput($event, i)\" (blur)=\"onAngleChange(i)\">\r\n <!-- <span class=\"angle-input\">\r\n {{item[2].angle}}\u00B0\r\n </span> -->\r\n </td>\r\n <td>\r\n <div (click)=\"toggleLineOptionsSelect(i)\"\r\n class=\"d-flex align-items-center justify-content-center h-100 elipsis-icon-dropdown\">\r\n <svg class=\"cursor-pointer\" xmlns=\"http://www.w3.org/2000/svg\" width=\"4\"\r\n height=\"19\" viewBox=\"0 0 4 19\" fill=\"none\">\r\n <path\r\n d=\"M1 9.50016C1 10.0294 1.44771 10.4585 2 10.4585C2.55228 10.4585 3 10.0294 3 9.50016C3 8.97089 2.55228 8.54183 2 8.54183C1.44771 8.54183 1 8.97089 1 9.50016Z\"\r\n stroke=\"#101828\" stroke-width=\"2\" stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\" />\r\n <path\r\n d=\"M0.999999 16.2085C0.999999 16.7378 1.44771 17.1668 2 17.1668C2.55228 17.1668 3 16.7378 3 16.2085C3 15.6792 2.55228 15.2502 2 15.2502C1.44771 15.2502 0.999999 15.6792 0.999999 16.2085Z\"\r\n stroke=\"#101828\" stroke-width=\"2\" stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\" />\r\n <path\r\n d=\"M1 2.79183C1 3.3211 1.44772 3.75016 2 3.75016C2.55228 3.75016 3 3.3211 3 2.79183C3 2.26256 2.55228 1.8335 2 1.8335C1.44772 1.8335 1 2.26256 1 2.79183Z\"\r\n stroke=\"#101828\" stroke-width=\"2\" stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\" />\r\n </svg>\r\n <ul *ngIf=\"lineOptionsSelect?.show && lineOptionsSelect?.index === i\"\r\n [ngClass]=\" (lineOptionsSelect.show && lineOptionsSelect.index === i) ? 'z-1': ''\"\r\n class=\"list-unstyled mb-2\">\r\n <li (click)=\"onAddStep(i)\">\r\n <div class=\"d-flex\">\r\n <div>Add new step</div>\r\n </div>\r\n\r\n </li>\r\n <li (click)=\"onDuplicateStep(i)\">\r\n <div class=\"d-flex\">\r\n <div>Duplicate</div>\r\n </div>\r\n\r\n </li>\r\n <li (click)=\"onLineDelete(i)\">\r\n <div class=\"d-flex\">\r\n <div class=\"text-danger\">Delete</div>\r\n </div>\r\n\r\n </li>\r\n\r\n </ul>\r\n </div>\r\n\r\n </td>\r\n </tr>\r\n </ng-container>\r\n\r\n </tbody>\r\n </table>\r\n </div>\r\n\r\n\r\n </div>\r\n </div>\r\n <div [ngClass]=\"layoutMode === 'full' ? 'col-10' : 'col-7'\">\r\n <div class=\"c-card \" style=\"height: 75dvh;\">\r\n <div style=\"height: 7%;\" class=\"d-flex align-items-center justify-content-between\">\r\n <div>\r\n <!-- <lib-reactive-select *ngIf=\"floorsInput.value\" [formControl]=\"floorsInput\" [idField]=\"'id'\"\r\n [nameField]=\"'floorName'\" [data]=\"selectedStore?.floor\"></lib-reactive-select> -->\r\n <div (click)=\"toggleFloorSelect()\" class=\"floor-select\">\r\n <div>{{selectedFloor?.floorName}}</div>\r\n <div><svg xmlns=\"http://www.w3.org/2000/svg\" width=\"20\" height=\"20\" viewBox=\"0 0 20 20\"\r\n fill=\"none\">\r\n <path d=\"M5 7.5L10 12.5L15 7.5\" stroke=\"#344054\" stroke-width=\"1.67\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\" />\r\n </svg></div>\r\n <ul *ngIf=\"floorSelect?.show\" class=\"list-unstyled mb-2\">\r\n <li (click)=\"onFloorSelect(floor.id)\"\r\n *ngFor=\"let floor of selectedStore?.floor; let i = index\"\r\n [ngClass]=\"floor.id === selectedFloor.id ? 'selected': ''\">\r\n <div class=\"d-flex justify-content-between\">\r\n <span>{{floor?.floorName}}</span>\r\n <span *ngIf=\"selectedStore?.floor.length > 1\"\r\n (click)=\"$event.stopPropagation(); floorSelect.deleteIndex = i\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"23\"\r\n viewBox=\"0 0 24 23\" fill=\"none\">\r\n <path\r\n d=\"M11 11.4999C11 12.0292 11.4477 12.4583 12 12.4583C12.5523 12.4583 13 12.0292 13 11.4999C13 10.9706 12.5523 10.5416 12 10.5416C11.4477 10.5416 11 10.9706 11 11.4999Z\"\r\n stroke=\"#101828\" stroke-width=\"2\" stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\" />\r\n <path\r\n d=\"M11 18.2083C11 18.7375 11.4477 19.1666 12 19.1666C12.5523 19.1666 13 18.7375 13 18.2083C13 17.679 12.5523 17.2499 12 17.2499C11.4477 17.2499 11 17.679 11 18.2083Z\"\r\n stroke=\"#101828\" stroke-width=\"2\" stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\" />\r\n <path\r\n d=\"M11 4.79159C11 5.32086 11.4477 5.74992 12 5.74992C12.5523 5.74992 13 5.32086 13 4.79159C13 4.26231 12.5523 3.83325 12 3.83325C11.4477 3.83325 11 4.26231 11 4.79159Z\"\r\n stroke=\"#101828\" stroke-width=\"2\" stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\" />\r\n </svg>\r\n </span>\r\n </div>\r\n\r\n <div *ngIf=\"floorSelect.deleteIndex === i\"\r\n (click)=\"$event.stopPropagation(); deleteFloor(i)\" class=\"option\">Delete</div>\r\n </li>\r\n <li (click)=\"openAddFloorModal()\">\r\n <span>\r\n <span class=\"mr-2\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\"\r\n viewBox=\"0 0 16 16\" fill=\"none\">\r\n <path d=\"M8.00016 3.33325V12.6666M3.3335 7.99992H12.6668\" stroke=\"#101828\"\r\n stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\r\n </svg>\r\n </span>\r\n <span>Add floor</span>\r\n </span>\r\n\r\n </li>\r\n </ul>\r\n </div>\r\n </div>\r\n <div class=\"d-flex align-items-center\" >\r\n <button (click)=\"findPolygonCenterAndScroll()\" class=\"btn btn-sm btn-outline bg-white me-3\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"26\" height=\"26\" fill=\"none\" viewBox=\"0 0 128 128\" id=\"recenter\">\r\n <path stroke=\"#000\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"7\" d=\"M38 74L49 63.5 38 53M53.5 37.5L64 48.5 74.5 37.5M90 53L79 63.5 90 74M74.5 89.5L64 78.5 53.5 89.5\"></path>\r\n <path stroke=\"#000\" stroke-linecap=\"round\" stroke-width=\"7\" d=\"M44 64L16 64M63.5 43.5L63.5 15.5M84 63L112 63M64.5 83.5L64.5 111.5\"></path>\r\n <circle cx=\"64\" cy=\"64\" r=\"5\" fill=\"#000\"></circle>\r\n </svg>\r\n </button>\r\n <button class=\"btn btn-sm btn-outline bg-white\" (click)=\"rotatePolygons()\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"26\" height=\"26\" viewBox=\"0 0 26 26\" fill=\"none\">\r\n <path\r\n d=\"M6.36265 7.17838L7.17625 6.36238L5.90425 5.09158L5.08945 5.90518L6.36265 7.17838ZM15.671 6.36358L19.6379 10.3304L20.9099 9.0572L16.9442 5.09038L15.671 6.36358ZM19.6379 18.8252L18.8243 19.6388L20.0963 20.9096L20.9099 20.0972L19.6379 18.8252ZM10.3295 19.6388L6.36265 15.672L5.09065 16.9452L9.05626 20.9108L10.3295 19.6388ZM18.8243 19.6388C17.6543 20.8076 16.8407 21.6188 16.1459 22.1492C15.4715 22.664 15.0155 22.8284 14.5763 22.8284V24.6284C15.5675 24.6284 16.4027 24.2168 17.2367 23.5808C18.0503 22.9604 18.9635 22.0448 20.0963 20.912L18.8243 19.6388ZM9.05626 20.9108C10.1891 22.0448 11.1023 22.9592 11.9159 23.5808C12.7499 24.2168 13.5851 24.6284 14.5763 24.6284V22.8284C14.1371 22.8284 13.6823 22.664 13.0067 22.1492C12.3119 21.6188 11.4983 20.8076 10.3295 19.6388L9.05626 20.9108ZM19.6379 10.3304C20.8067 11.4992 21.6179 12.3128 22.1483 13.0076C22.6631 13.6832 22.8275 14.138 22.8275 14.5772H24.6275C24.6275 13.586 24.2159 12.7508 23.5799 11.9168C22.9595 11.1032 22.0427 10.19 20.9099 9.0572L19.6379 10.3304ZM20.9099 20.0972C22.0439 18.9632 22.9583 18.0512 23.5799 17.2376C24.2159 16.4036 24.6275 15.5684 24.6275 14.5772H22.8275C22.8275 15.0164 22.6631 15.4724 22.1483 16.1468C21.6179 16.8416 20.8067 17.6552 19.6379 18.8252L20.9099 20.0972ZM7.17625 6.36238C8.34625 5.19358 9.15985 4.38118 9.85465 3.85078C10.529 3.33598 10.985 3.17278 11.4242 3.17278V1.37158C10.433 1.37158 9.59785 1.78318 8.76385 2.41918C7.94905 3.04078 7.03705 3.95518 5.90425 5.08798L7.17625 6.36238ZM16.9442 5.09038C15.8114 3.95638 14.8982 3.04078 14.0846 2.41918C13.2506 1.78318 12.4154 1.37158 11.4242 1.37158V3.17278C11.8634 3.17278 12.3182 3.33598 12.9938 3.85078C13.6886 4.38118 14.5022 5.19238 15.671 6.36118L16.9442 5.09038ZM5.08945 5.90278C3.95665 7.03558 3.04225 7.94758 2.42065 8.76238C1.78465 9.59638 1.37305 10.4316 1.37305 11.4228H3.17305C3.17305 10.9836 3.33745 10.5276 3.85225 9.85318C4.38265 9.15838 5.19385 8.34478 6.36265 7.17478L5.08945 5.90278ZM6.36265 15.6708C5.19385 14.5008 4.38265 13.6872 3.85225 12.9924C3.33745 12.318 3.17305 11.862 3.17305 11.4228H1.37305C1.37305 12.414 1.78465 13.2492 2.42065 14.0832C3.04225 14.8968 3.95665 15.81 5.08945 16.9428L6.36265 15.6708Z\"\r\n fill=\"#1D2939\" />\r\n <path\r\n d=\"M23.2 6.9832L25 8.2C25 4.582 22.4056 1.5796 19 1M2.8 19.0168L1 17.8C1 21.418 3.5944 24.4204 7 25\"\r\n stroke=\"#1D2939\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\r\n </svg>\r\n </button> \r\n </div>\r\n \r\n </div>\r\n <div class=\"hide-scrollbar\" style=\"height: 93%; overflow: scroll; position: relative;\" #scrollContainer>\r\n <canvas #gridCanvas>\r\n\r\n </canvas>\r\n\r\n <div *ngIf=\"popupVisible && popupPosition\" [style.top.px]=\"popupPosition.y\"\r\n [style.left.px]=\"popupPosition.x\" class=\"angle-widget\">\r\n <div (click)=\"toggleWidgetElementSelect()\" style=\"width: 147px;\"\r\n class=\"element-type-dropdown widget-element-type-dropdown d-flex justify-content-between position-relative\">\r\n <div>\r\n <span class=\"d-flex align-items-center\" *ngIf=\"elementType === 'wall'\">\r\n <svg class=\"me-3\" xmlns=\"http://www.w3.org/2000/svg\" width=\"20\" height=\"20\"\r\n viewBox=\"0 0 20 20\" fill=\"none\">\r\n <path fill-rule=\"evenodd\" clip-rule=\"evenodd\"\r\n d=\"M1.33333 1.33333V0L2.66667 0V1.33333L6.66667 1.33333V0L8 0V1.33333L12 1.33333V0L13.3333 0V1.33333L17.3333 1.33333V0L18.6667 0V1.33333H20V2.66667H18.6667V6.66667H20V8H18.6667V12H20V13.3333H18.6667V17.3333H20V18.6667H18.6667V20H17.3333V18.6667H13.3333V20H12V18.6667H8V20H6.66667V18.6667H2.66667V20H1.33333V18.6667H0L0 17.3333H1.33333L1.33333 13.3333H0L0 12H1.33333L1.33333 8H0L0 6.66667H1.33333L1.33333 2.66667H0L0 1.33333H1.33333ZM2.66667 2.66667L2.66667 6.66667H6.66667V2.66667L2.66667 2.66667ZM8 2.66667V6.66667H12V2.66667L8 2.66667ZM13.3333 2.66667V6.66667H17.3333V2.66667H13.3333ZM17.3333 8L13.3333 8V12L17.3333 12V8ZM17.3333 13.3333L13.3333 13.3333L13.3333 17.3333H17.3333V13.3333ZM12 17.3333L12 13.3333H8L8 17.3333H12ZM6.66667 17.3333V13.3333H2.66667V17.3333H6.66667ZM2.66667 12H6.66667V8H2.66667L2.66667 12ZM8 8V12H12V8H8Z\"\r\n fill=\"#344054\" />\r\n </svg>\r\n <span class=\"type-txt\">Wall</span>\r\n </span>\r\n\r\n <span class=\"d-flex align-items-center\" *ngIf=\"elementType === 'facade'\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"22\" height=\"22\" viewBox=\"0 0 22 22\"\r\n fill=\"none\">\r\n <path\r\n d=\"M1 11V2.25C1 1.5625 1.5625 1 2.25 1H19.75C20.4375 1 21 1.5625 21 2.25V19.75C21 20.4375 20.4375 21 19.75 21H2.25C1.5625 21 1 20.4375 1 19.75V11Z\"\r\n stroke=\"#344054\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\r\n </svg>\r\n <span class=\"type-txt\">Glass...</span>\r\n </span>\r\n\r\n <span class=\"d-flex align-items-center\" *ngIf=\"elementType === 'opening'\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"20\" height=\"20\" viewBox=\"0 0 20 20\"\r\n fill=\"none\">\r\n <path\r\n d=\"M12.5 2.5H15.8333C16.2754 2.5 16.6993 2.6756 17.0118 2.98816C17.3244 3.30072 17.5 3.72464 17.5 4.16667V15.8333C17.5 16.2754 17.3244 16.6993 17.0118 17.0118C16.6993 17.3244 16.2754 17.5 15.8333 17.5H12.5M8.33333 14.1667L12.5 10M12.5 10L8.33333 5.83333M12.5 10H2.5\"\r\n stroke=\"#101828\" stroke-width=\"1.5\" stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\" />\r\n </svg>\r\n <span class=\"type-txt\">Openi...</span>\r\n </span>\r\n\r\n <span class=\"d-flex align-items-center\" *ngIf=\"elementType === 'entrance'\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"21\" height=\"18\" viewBox=\"0 0 21 18\"\r\n fill=\"none\">\r\n <path fill-rule=\"evenodd\" clip-rule=\"evenodd\"\r\n d=\"M17.9333 1.37949C8.7909 1.37949 1.37949 8.7909 1.37949 17.9333H0C0 8.02903 8.02903 0 17.9333 0V1.37949Z\"\r\n fill=\"#1D2939\" />\r\n <path fill-rule=\"evenodd\" clip-rule=\"evenodd\"\r\n d=\"M19.3132 1.37949H17.9333L17.9337 16.5538H19.3132V1.37949ZM16.5542 0V17.9333H20.6927V0H16.5542Z\"\r\n fill=\"#1D2939\" />\r\n </svg>\r\n <span class=\"type-txt\">Entra...</span>\r\n </span>\r\n\r\n </div>\r\n\r\n <div class=\"down-arrow\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"20\" height=\"20\" viewBox=\"0 0 20 20\"\r\n fill=\"none\">\r\n <path d=\"M5 7.5L10 12.5L15 7.5\" stroke=\"#667085\" stroke-width=\"1.66667\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\" />\r\n </svg>\r\n </div>\r\n\r\n <ul *ngIf=\"widgetElementSelect?.show \" [ngClass]=\" widgetElementSelect.show ? 'z-4': ''\"\r\n class=\"list-unstyled mb-2\">\r\n <li (click)=\"elementType = 'wall'\" [ngClass]=\"elementType === 'wall' ? 'selected' : ''\"\r\n class=\"selected\">\r\n <div class=\"d-flex\">\r\n <div class=\"me-3\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"20\" height=\"20\"\r\n viewBox=\"0 0 20 20\" fill=\"none\">\r\n <path fill-rule=\"evenodd\" clip-rule=\"evenodd\"\r\n d=\"M1.33333 1.33333V0L2.66667 0V1.33333L6.66667 1.33333V0L8 0V1.33333L12 1.33333V0L13.3333 0V1.33333L17.3333 1.33333V0L18.6667 0V1.33333H20V2.66667H18.6667V6.66667H20V8H18.6667V12H20V13.3333H18.6667V17.3333H20V18.6667H18.6667V20H17.3333V18.6667H13.3333V20H12V18.6667H8V20H6.66667V18.6667H2.66667V20H1.33333V18.6667H0L0 17.3333H1.33333L1.33333 13.3333H0L0 12H1.33333L1.33333 8H0L0 6.66667H1.33333L1.33333 2.66667H0L0 1.33333H1.33333ZM2.66667 2.66667L2.66667 6.66667H6.66667V2.66667L2.66667 2.66667ZM8 2.66667V6.66667H12V2.66667L8 2.66667ZM13.3333 2.66667V6.66667H17.3333V2.66667H13.3333ZM17.3333 8L13.3333 8V12L17.3333 12V8ZM17.3333 13.3333L13.3333 13.3333L13.3333 17.3333H17.3333V13.3333ZM12 17.3333L12 13.3333H8L8 17.3333H12ZM6.66667 17.3333V13.3333H2.66667V17.3333H6.66667ZM2.66667 12H6.66667V8H2.66667L2.66667 12ZM8 8V12H12V8H8Z\"\r\n fill=\"#344054\" />\r\n </svg>\r\n </div>\r\n <div>Wall</div>\r\n </div>\r\n <div>\r\n <svg *ngIf=\"elementType === 'wall'\" xmlns=\"http://www.w3.org/2000/svg\" width=\"20\"\r\n height=\"20\" viewBox=\"0 0 20 20\" fill=\"none\">\r\n <path d=\"M16.6663 5L7.49967 14.1667L3.33301 10\" stroke=\"#00A3FF\"\r\n stroke-width=\"1.66667\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\r\n </svg>\r\n </div>\r\n </li>\r\n <li (click)=\"elementType = 'facade'\" [ngClass]=\"elementType === 'facade' ? 'selected' : ''\">\r\n <div class=\"d-flex\">\r\n <div class=\"me-3\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"22\" height=\"22\"\r\n viewBox=\"0 0 22 22\" fill=\"none\">\r\n <path\r\n d=\"M1 11V2.25C1 1.5625 1.5625 1 2.25 1H19.75C20.4375 1 21 1.5625 21 2.25V19.75C21 20.4375 20.4375 21 19.75 21H2.25C1.5625 21 1 20.4375 1 19.75V11Z\"\r\n stroke=\"#344054\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\r\n </svg>\r\n </div>\r\n <div>Glass/Facade</div>\r\n </div>\r\n <div>\r\n <svg *ngIf=\"elementType === 'facade'\" xmlns=\"http://www.w3.org/2000/svg\" width=\"20\"\r\n height=\"20\" viewBox=\"0 0 20 20\" fill=\"none\">\r\n <path d=\"M16.6663 5L7.49967 14.1667L3.33301 10\" stroke=\"#00A3FF\"\r\n stroke-width=\"1.66667\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\r\n </svg>\r\n </div>\r\n </li>\r\n <li (click)=\"elementType = 'opening'\"\r\n [ngClass]=\"elementType === 'opening' ? 'selected' : ''\">\r\n <div class=\"d-flex\">\r\n <div class=\"me-3\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"20\" height=\"20\"\r\n viewBox=\"0 0 20 20\" fill=\"none\">\r\n <path\r\n d=\"M12.5 2.5H15.8333C16.2754 2.5 16.6993 2.6756 17.0118 2.98816C17.3244 3.30072 17.5 3.72464 17.5 4.16667V15.8333C17.5 16.2754 17.3244 16.6993 17.0118 17.0118C16.6993 17.3244 16.2754 17.5 15.8333 17.5H12.5M8.33333 14.1667L12.5 10M12.5 10L8.33333 5.83333M12.5 10H2.5\"\r\n stroke=\"#101828\" stroke-width=\"1.5\" stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\" />\r\n </svg>\r\n </div>\r\n <div>Opening</div>\r\n </div>\r\n <div>\r\n <svg *ngIf=\"elementType === 'opening'\" xmlns=\"http://www.w3.org/2000/svg\" width=\"20\"\r\n height=\"20\" viewBox=\"0 0 20 20\" fill=\"none\">\r\n <path d=\"M16.6663 5L7.49967 14.1667L3.33301 10\" stroke=\"#00A3FF\"\r\n stroke-width=\"1.66667\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\r\n </svg>\r\n </div>\r\n </li>\r\n <li (click)=\"elementType = 'entrance'\"\r\n [ngClass]=\"elementType === 'entrance' ? 'selected' : ''\">\r\n <div class=\"d-flex\">\r\n <div class=\"me-3\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"21\" height=\"18\"\r\n viewBox=\"0 0 21 18\" fill=\"none\">\r\n <path fill-rule=\"evenodd\" clip-rule=\"evenodd\"\r\n d=\"M17.9333 1.37949C8.7909 1.37949 1.37949 8.7909 1.37949 17.9333H0C0 8.02903 8.02903 0 17.9333 0V1.37949Z\"\r\n fill=\"#1D2939\" />\r\n <path fill-rule=\"evenodd\" clip-rule=\"evenodd\"\r\n d=\"M19.3132 1.37949H17.9333L17.9337 16.5538H19.3132V1.37949ZM16.5542 0V17.9333H20.6927V0H16.5542Z\"\r\n fill=\"#1D2939\" />\r\n </svg>\r\n </div>\r\n <div>Entrance</div>\r\n </div>\r\n <div>\r\n <svg *ngIf=\"elementType === 'entrance'\" xmlns=\"http://www.w3.org/2000/svg\"\r\n width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" fill=\"none\">\r\n <path d=\"M16.6663 5L7.49967 14.1667L3.33301 10\" stroke=\"#00A3FF\"\r\n stroke-width=\"1.66667\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\r\n </svg>\r\n </div>\r\n </li>\r\n </ul>\r\n\r\n </div>\r\n\r\n <div class=\"unit-input\">\r\n <svg (click)=\"onWidgetDistanceChange('decrement')\" class=\"cursor-pointer\"\r\n xmlns=\"http://www.w3.org/2000/svg\" width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" fill=\"none\">\r\n <path d=\"M2.9165 7H11.0832\" stroke=\"#667085\" stroke-width=\"2\" stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\" />\r\n </svg>\r\n <span>{{movePixels}}</span>\r\n <svg (click)=\"onWidgetDistanceChange('increment')\" class=\"cursor-pointer\"\r\n xmlns=\"http://www.w3.org/2000/svg\" width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" fill=\"none\">\r\n <path d=\"M6.99984 2.9165V11.0832M2.9165 6.99984H11.0832\" stroke=\"#667085\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\" />\r\n </svg>\r\n </div>\r\n\r\n <div class=\"position-relative\" style=\"position: relative; width: 229px; height: 229px;\">\r\n <div\r\n style=\"position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); z-index: 3;\">\r\n <div style=\"margin-bottom: 27px;\" class=\"d-flex justify-content-center\">\r\n <div (click)=\"onWidgetDirectionChange('up')\"\r\n [ngClass]=\"moveDirection === 'up' ? 'direction-selected' : ''\"\r\n class=\"direction-input\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"12\" height=\"12\" viewBox=\"0 0 12 12\"\r\n fill=\"none\">\r\n <path\r\n d=\"M6.00016 10.6673L6.00016 1.33398M6.00016 1.33398L1.3335 6.00065M6.00016 1.33398L10.6668 6.00065\"\r\n stroke=\"#667085\" stroke-width=\"2\" stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\" />\r\n </svg>\r\n </div>\r\n </div>\r\n <div class=\"d-flex justify-content-center align-items-center\">\r\n <div (click)=\"onWidgetDirectionChange('left')\"\r\n [ngClass]=\"moveDirection === 'left' ? 'direction-selected' : ''\"\r\n style=\"margin-right: 8px;\" class=\"direction-input\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"12\" height=\"12\" viewBox=\"0 0 12 12\"\r\n fill=\"none\">\r\n <path\r\n d=\"M10.6663 5.99935L1.33301 5.99935M1.33301 5.99935L5.99967 10.666M1.33301 5.99935L5.99968 1.33268\"\r\n stroke=\"#667085\" stroke-width=\"2\" stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\" />\r\n </svg>\r\n </div>\r\n\r\n <div class=\"unit-input\">\r\n <svg (click)=\"onWidgetAngleChange('decrement')\" class=\"cursor-pointer\"\r\n xmlns=\"http://www.w3.org/2000/svg\" width=\"14\" height=\"14\" viewBox=\"0 0 14 14\"\r\n fill=\"none\">\r\n <path d=\"M2.9165 7H11.0832\" stroke=\"#667085\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\" />\r\n </svg>\r\n <span>{{moveAngle}}\u00B0</span>\r\n <svg (click)=\"onWidgetAngleChange('increment')\" class=\"cursor-pointer\"\r\n xmlns=\"http://www.w3.org/2000/svg\" width=\"14\" height=\"14\" viewBox=\"0 0 14 14\"\r\n fill=\"none\">\r\n <path d=\"M6.99984 2.9165V11.0832M2.9165 6.99984H11.0832\" stroke=\"#667085\"\r\n stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\r\n </svg>\r\n </div>\r\n\r\n <div (click)=\"onWidgetDirectionChange('right')\"\r\n [ngClass]=\"moveDirection === 'right' ? 'direction-selected' : ''\"\r\n style=\"margin-left: 8px;\" class=\"direction-input\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"12\" height=\"12\" viewBox=\"0 0 12 12\"\r\n fill=\"none\">\r\n <path\r\n d=\"M1.33366 6.00065L10.667 6.00065M10.667 6.00065L6.00033 1.33398M10.667 6.00065L6.00033 10.6673\"\r\n stroke=\"#667085\" stroke-width=\"2\" stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\" />\r\n </svg>\r\n </div>\r\n\r\n </div>\r\n\r\n <div style=\"margin-top: 27px;\" class=\"d-flex justify-content-center\">\r\n <div (click)=\"onWidgetDirectionChange('down')\"\r\n [ngClass]=\"moveDirection === 'down' ? 'direction-selected' : ''\"\r\n class=\"direction-input\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"12\" height=\"12\" viewBox=\"0 0 12 12\"\r\n fill=\"none\">\r\n <path\r\n d=\"M5.99984 1.33268L5.99984 10.666M5.99984 10.666L10.6665 5.99935M5.99984 10.666L1.33317 5.99935\"\r\n stroke=\"#667085\" stroke-width=\"2\" stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\" />\r\n </svg>\r\n </div>\r\n </div>\r\n </div>\r\n <canvas height=\"229px\" width=\"229px\" #widgetCanvas\r\n style=\"position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); z-index: 1;\"></canvas>\r\n <div style=\"position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); z-index: 2;\"\r\n #circle class=\"circle\">\r\n <div class=\"line\" *ngFor=\"let line of lines\"\r\n [ngClass]=\"{'line--highlight': line.highlight, 'line--invisible': line.invisible}\"\r\n [style.transform]=\"line.transform\"></div>\r\n\r\n <div #pointer class=\"pointer\"></div>\r\n </div>\r\n </div>\r\n\r\n <button (click)=\"movePointWithAngle()\"\r\n [disabled]=\"!movePixels && moveAngle !== undefined && moveAngle !== null\"\r\n class=\" w-100 go-btn\">Go</button>\r\n\r\n </div>\r\n\r\n <!-- <div *ngIf=\"popupVisible && popupPosition\" [style.top.px]=\"popupPosition.y\" [style.left.px]=\"popupPosition.x\"\r\n class=\"popup\">\r\n <label>Move Pixels:</label>\r\n <select [(ngModel)]=\"elementType\">\r\n <option value=\"wall\">Wall</option>\r\n <option value=\"facade\">Glass/Facade</option>\r\n <option value=\"opening\">Opening</option>\r\n <option value=\"entrance\">Entrance</option>\r\n </select>\r\n <input type=\"number\" [(ngModel)]=\"movePixels\" />\r\n\r\n <select [(ngModel)]=\"moveDirection\">\r\n <option value=\"right\">Right</option>\r\n <option value=\"down\">Down</option>\r\n <option value=\"left\">Left</option>\r\n <option value=\"up\">Up</option>\r\n </select>\r\n <input type=\"number\" [(ngModel)]=\"moveAngle\" (ngModelChange)=\"layoutLengthPreview()\" />\r\n <button (click)=\"movePointWithAngle()\">Move with angle</button>\r\n </div> -->\r\n </div>\r\n\r\n </div>\r\n </div>\r\n\r\n <div *ngIf=\"planoStoreList.length > 1\" class=\"col-12 mt-6\">\r\n <div style=\"padding: 0px !important;\" class=\"c-card\">\r\n <lib-pagination [itemsPerPage]=\"itemsPerPage\" (pageChange)=\"onPageChange($event)\" [currentPage]=\"currentPage\" [totalItems]=\"totalItems\"\r\n [paginationSizes]=\"paginationSizes\" [pageSize]=\"pageSize\"></lib-pagination>\r\n </div>\r\n </div>\r\n\r\n</div>", styles: [".storename-txt{color:#101828;font-size:16px;font-weight:600;line-height:24px}.c-card{padding:16px;border-radius:8px;background:#fff}.l-pane-head{color:#101828;font-size:18px;font-weight:600;line-height:28px}.l-pane-desc{color:#475467;font-size:12px;font-weight:400;line-height:18px}.elipsis-btn{display:flex;width:40px;height:40px;padding:10px;justify-content:center;align-items:center;gap:8px;border-radius:48px;border:1px solid #D0D5DD;background:#fff;cursor:pointer}.no-steps-txt{color:#101828;font-size:18px;font-weight:500;line-height:28px}.no-text-desc{color:#101828;font-size:14px;font-weight:400;line-height:20px}.hide-scrollbar{overflow:scroll;-ms-overflow-style:none;scrollbar-width:none}.hide-scrollbar::-webkit-scrollbar{display:none}.popup{position:absolute;background:#fff;border:1px solid black;padding:10px;box-shadow:0 4px 8px #0003;z-index:1000}.resize-icon{cursor:pointer;border-radius:727.273px;background:#fff;box-shadow:0 8.727px 11.636px -2.909px #10182814,0 2.909px 4.364px -1.455px #10182808;position:absolute;right:-13px;top:70px;padding:7.273px}.resize-icon svg{width:17.455px;height:17.455px}th{background-color:#fff!important;color:#667085!important;font-size:12px!important;font-weight:400!important}td{color:#101828!important;font-size:14px!important;font-weight:500!important}.element-type-dropdown{display:flex;height:44px;padding:10px 14px;align-items:center;gap:8px;flex-shrink:0;align-self:stretch;border-radius:8px;border:1px solid #D0D5DD;background:#fff;cursor:pointer;position:relative}.element-type-dropdown .type-txt{color:#1d2939;font-family:Inter;font-size:16px;font-style:normal;font-weight:400;line-height:24px}.element-type-dropdown .down-arrow{width:20px;height:20px}.element-type-dropdown ul{position:absolute;top:45px;width:200px;left:0;border-radius:4px;border:1px solid #EAECF0;background:#fff;box-shadow:0 12px 16px -4px #10182814,0 4px 6px -2px #10182808}.element-type-dropdown ul li{display:flex;align-items:center;justify-content:space-between;padding:10px 16px}.element-type-dropdown ul .selected{background:#f9fafb}.direction-dropdown{display:flex;height:44px;padding:10px 14px;align-items:center;gap:8px;flex-shrink:0;align-self:stretch;border-radius:8px;border:1px solid #D0D5DD;background:#fff;cursor:pointer;position:relative}.direction-dropdown .down-arrow{width:20px;height:20px}.direction-dropdown ul{position:absolute;top:45px;width:200px;left:0;border-radius:4px;border:1px solid #EAECF0;background:#fff;box-shadow:0 12px 16px -4px #10182814,0 4px 6px -2px #10182808}.direction-dropdown ul li{display:flex;align-items:center;justify-content:space-between;padding:10px 16px}.direction-dropdown ul .selected{background:#f9fafb}.elipsis-icon-dropdown{position:relative}.elipsis-icon-dropdown ul{position:absolute;top:45px;width:200px;right:0;border-radius:4px;border:1px solid #EAECF0;background:#fff;box-shadow:0 12px 16px -4px #10182814,0 4px 6px -2px #10182808}.elipsis-icon-dropdown ul li{display:flex;align-items:center;justify-content:space-between;padding:10px 16px;cursor:pointer;position:relative}.elipsis-icon-dropdown ul li .export-options{display:none;position:absolute;left:298px;top:-47px}.elipsis-icon-dropdown ul li .export-options ul{border-radius:4px;border:1px solid #EAECF0;background:#fff;box-shadow:0 12px 16px -4px #10182814,0 4px 6px -2px #10182808;z-index:5;width:100px;padding:0}.elipsis-icon-dropdown ul li .export-options ul li{display:flex;align-items:center;justify-content:space-between;padding:10px 16px;cursor:pointer}.elipsis-icon-dropdown ul li:hover .export-options{display:block}.elipsis-icon-dropdown ul li:hover{background:#f9fafb}.element-name{display:flex;padding:10px 14px;align-items:center;gap:8px;flex:1 0 0;align-self:stretch;border-radius:8px;background:#f9fafb;color:#101828;font-family:Inter;font-size:14px;font-style:normal;font-weight:500;line-height:20px;white-space:nowrap}.unit-input{display:flex;justify-content:space-between;width:72px;height:44px;padding:4px 6px;align-items:center;gap:4px;border-radius:8px;border:1px solid #D0D5DD;background:#fff}.angle-input{width:55px;display:flex;padding:10px 14px;align-items:center;gap:8px;align-self:stretch;border-radius:8px;border:1px solid #D0D5DD;background:#fff}.angle-widget{position:absolute;display:flex;min-width:259px;padding:14px;align-items:flex-start;align-content:flex-start;gap:14px 10px;flex-wrap:wrap;border-radius:8px;border:1px solid #6BCAFF;background:#fff;box-shadow:0 12px 16px -4px #10182814,0 4px 6px -2px #10182808}.angle-widget .go-btn{border-radius:8px;border:1px solid #EAF8FF;background:#eaf8ff;padding:10px 16px;color:#009bf3;font-size:12px;font-weight:600;line-height:18px}.angle-widget .go-btn:disabled{border:1px solid #F6FCFF;background:#f6fcff;color:#6bcaff}.angle-widget .direction-input{padding:4px 8px;border-radius:8px;border:1px solid #667085;background:#fff;cursor:pointer}.angle-widget .direction-selected{border:1px solid #33B5FF}.angle-widget .direction-selected svg path{stroke:#33b5ff;fill:#33b5ff}.angle-widget .circle{width:229px;height:229px;border-radius:50%;position:relative;transform:rotate(-180deg)}.angle-widget .line{background:linear-gradient(to top,transparent 80%,rgba(0,0,0,.2) 80%);width:1px;height:114.5px;left:calc(50% - .5px);top:0;position:absolute;transform-origin:bottom;display:flex;justify-content:center}.angle-widget .line--highlight{background:linear-gradient(to top,transparent 80%,black 80%)}.angle-widget .line--invisible{background:transparent!important}.angle-widget .pointer{width:0px;height:114.5px;transform-origin:bottom;position:absolute;top:0;left:50%;background:#000;display:flex;justify-content:center}.angle-widget .pointer:after{display:block;content:\"\";width:0;height:25px;border-left:5px solid transparent;border-right:5px solid transparent;border-bottom:10px solid #33B5FF}.angle-widget .z-4{z-index:4}.menu-txt1{color:#344054;font-size:14px;font-weight:500;line-height:20px}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{-webkit-appearance:none;margin:0}input[type=number]{-moz-appearance:textfield}.floor-select{width:155px;height:44px;border-radius:8px;border:1px solid #D0D5DD;background:#fff;box-shadow:0 1px 2px #1018280d;position:relative;display:flex;justify-content:space-between;padding:10px 16px;cursor:pointer;color:#344054;font-size:14px;font-weight:600;line-height:20px}.floor-select ul{width:240px;box-shadow:0 20px 24px -4px #10182814,0 8px 8px -4px #10182808;position:absolute;top:45px;left:0;background:#fff;z-index:4}.floor-select ul li{position:relative;padding:10px 16px;color:#1d2939;font-size:14px;font-weight:500;line-height:20px;align-items:center;cursor:pointer}.floor-select ul li .option{width:200px;position:absolute;padding:10px 16px;background:#fef3f2;color:#d92d20;font-size:14px;font-weight:500;line-height:20px;right:-200px;top:0}.floor-select ul li:hover,.floor-select ul .selected{background:#f2f4f7}.selected-element{border:1px solid #008EDF!important}td .drag-handler svg{display:none}td .drag-handler:hover svg{display:block}\n"] }]
|
|
1793
|
+
}], ctorParameters: () => [{ type: i0.ChangeDetectorRef }, { type: i0.Renderer2 }, { type: i1.ActivatedRoute }, { type: i2.StoreBuilderService }, { type: i1.Router }, { type: i3.NgbOffcanvas }, { type: i4.ToastService }, { type: i3.NgbModal }], propDecorators: { canvasRef: [{
|
|
1794
|
+
type: ViewChild,
|
|
1795
|
+
args: ['gridCanvas', { static: true }]
|
|
1796
|
+
}], widgetCanvasRef: [{
|
|
1797
|
+
type: ViewChild,
|
|
1798
|
+
args: ['widgetCanvas', { static: false }]
|
|
1799
|
+
}], scrollContainerRef: [{
|
|
1800
|
+
type: ViewChild,
|
|
1801
|
+
args: ['scrollContainer']
|
|
1802
|
+
}], circleRef: [{
|
|
1803
|
+
type: ViewChild,
|
|
1804
|
+
args: ['circle']
|
|
1805
|
+
}], pointerRef: [{
|
|
1806
|
+
type: ViewChild,
|
|
1807
|
+
args: ['pointer']
|
|
1808
|
+
}], onMouseWheel: [{
|
|
1809
|
+
type: HostListener,
|
|
1810
|
+
args: ['wheel', ['$event']]
|
|
1811
|
+
}], onOutsideClick: [{
|
|
1812
|
+
type: HostListener,
|
|
1813
|
+
args: ['document:click', ['$event']]
|
|
1814
|
+
}] } });
|
|
1815
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY3JlYXRlLWxheW91dC5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy90YW5nby1zdG9yZS1idWlsZGVyL3NyYy9saWIvY29tcG9uZW50cy9jcmVhdGUtbGF5b3V0L2NyZWF0ZS1sYXlvdXQuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvdGFuZ28tc3RvcmUtYnVpbGRlci9zcmMvbGliL2NvbXBvbmVudHMvY3JlYXRlLWxheW91dC9jcmVhdGUtbGF5b3V0LmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUM3QyxPQUFPLEVBQWUsZUFBZSxFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFFdEUsT0FBTyxFQUFFLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFJMUMsT0FBTyxFQUFxQixTQUFTLEVBQWMsWUFBWSxFQUFnQyxTQUFTLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDaEksT0FBTyxFQUFFLGdDQUFnQyxFQUFFLE1BQU0sa0VBQWtFLENBQUM7QUFFcEgsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sd0NBQXdDLENBQUM7QUFDM0UsT0FBTyxFQUFFLHNCQUFzQixFQUFFLE1BQU0sb0RBQW9ELENBQUM7QUFDNUYsT0FBTyxFQUFFLHFCQUFxQixFQUFFLE1BQU0sZ0RBQWdELENBQUM7QUFDdkYsT0FBTyxLQUFLLElBQUksTUFBTSxNQUFNLENBQUM7Ozs7Ozs7Ozs7QUFTN0IsTUFBTSxPQUFPLHFCQUFxQjtJQTRIWjtJQUErQjtJQUE2QjtJQUN0RTtJQUF5QztJQUF3QjtJQUF3QztJQUFvQztJQTVIdkosV0FBVyxHQUFHLElBQUksV0FBVyxFQUFFLENBQUE7SUFDWSxTQUFTLENBQWlDO0lBQ3ZDLGVBQWUsQ0FBaUM7SUFDaEUsa0JBQWtCLENB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SyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ2pELElBQUksQ0FBQyxXQUFXLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsRUFBRSxFQUFFLEVBQUUsU0FBUyxFQUFFLEtBQUssRUFBRSxDQUFDLENBQUM7UUFDdkUsSUFBSSxDQUFDLHFCQUFxQixDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsYUFBYSxDQUFDLENBQUM7UUFDN0QsSUFBSSxDQUFDLFNBQVMsR0FBRyxFQUFFLENBQUM7UUFDcEIsSUFBSSxDQUFDLFNBQVMsR0FBRyxFQUFFLENBQUM7SUFDdEIsQ0FBQztJQUVELGVBQWU7UUFDYixJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUN0RSxDQUFDO0lBRUQsSUFBSTtRQUNGLElBQUksSUFBSSxDQUFDLFNBQVMsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFO1lBQzdCLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBRXBFLElBQUksQ0FBQyxhQUFhLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxHQUFHLEVBQUUsQ0FBQztZQUUxQyxJQUFJLENBQUMsWUFBWSxFQUFFLENBQUE7U0FDcEI7SUFDSCxDQUFDO0lBRUQsSUFBSTtRQUNGLElBQUksSUFBSSxDQUFDLFNBQVMsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFO1lBQzdCLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBRXBFLElBQUksQ0FBQyxhQUFhLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxHQUFH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QWEsQ0FBQyxTQUFTLElBQUksSUFBSSxDQUFDLGFBQWEsQ0FBQyxTQUFTLGNBQWMsQ0FBQTtRQUU5RixJQUFJLENBQUMsU0FBUyxDQUFDLFFBQVEsRUFBRSxRQUFRLENBQUMsQ0FBQztJQUN2QyxDQUFDO3dHQTdvRVkscUJBQXFCOzRGQUFyQixxQkFBcUIsOG9CQ3RCbEMseTRzRUE0MUJNOzs0RkR0MEJPLHFCQUFxQjtrQkFMakMsU0FBUzsrQkFDRSxtQkFBbUI7K1FBTWMsU0FBUztzQkFBbkQsU0FBUzt1QkFBQyxZQUFZLEVBQUUsRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFFO2dCQUNLLGVBQWU7c0JBQTVELFNBQVM7dUJBQUMsY0FBYyxFQUFFLEVBQUUsTUFBTSxFQUFFLEtBQUssRUFBRTtnQkFDZCxrQkFBa0I7c0JBQS9DLFNBQVM7dUJBQUMsaUJBQWlCO2dCQXVEUCxTQUFTO3NCQUE3QixTQUFTO3VCQUFDLFFBQVE7Z0JBQ0csVUFBVTtzQkFBL0IsU0FBUzt1QkFBQyxTQUFTO2dCQXNuQnBCLFlBQVk7c0JBRFgsWUFBWTt1QkFBQyxPQUFPLEVBQUUsQ0FBQyxRQUFRLENBQUM7Z0JBNkRqQyxjQUFjO3NCQURiLFlBQVk7dUJBQUMsZ0JBQWdCLEVBQUUsQ0FBQyxRQUFRLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBGb3JtQ29udHJvbCB9IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcclxuaW1wb3J0IHsgQ2RrRHJhZ0Ryb3AsIG1vdmVJdGVtSW5BcnJheSB9IGZyb20gJ0Bhbmd1bGFyL2Nkay9kcmFnLWRyb3AnO1xyXG5pbXBvcnQgeyBBY3RpdmF0ZWRSb3V0ZSwgUm91dGVyIH0gZnJvbSAnQGFuZ3VsYXIvcm91dGVyJztcclxuaW1wb3J0IHsgU3ViamVjdCwgdGFrZVVudGlsIH0gZnJvbSAncnhqcyc7XHJcbmltcG9ydCB7IFN0b3JlQnVpbGRlclNlcnZpY2UgfSBmcm9tICcuLi8uLi9zZXJ2aWNlcy9zdG9yZS1idWlsZGVyLnNlcnZpY2UnO1xyXG5pbXBvcnQgeyBIZWFkZXJGaWx0ZXIgfSBmcm9tICcuLi8uLi9pbnRlcmZhY2VzL2xheW91dC1idWlsZGVyLmludGVyZmFjZSc7XHJcbmltcG9ydCB7IE5nYk1vZGFsLCBOZ2JPZmZjYW52YXMgfSBmcm9tICdAbmctYm9vdHN0cmFwL25nLWJvb3RzdHJhcCc7XHJcbmltcG9ydCB7IENoYW5nZURldGVjdG9yUmVmLCBDb21wb25lbnQsIEVsZW1lbnRSZWYsIEhvc3RMaXN0ZW5lciwgT25EZXN0cm95LCBPbkluaXQsIFJlbmRlcmVyMiwgVmlld0NoaWxkIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcbmltcG9ydCB7IFN0b3JlT2ZmY2FudmFzQ29tcG9uZW50Q29tcG9uZW50IH0gZnJvbSAnLi4vc3RvcmUtb2ZmY2FudmFzLWNvbXBvbmVudC9zdG9yZS1vZmZjYW52YXMtY29tcG9uZW50LmNvbXBvbmVudCc7XHJcbmltcG9ydCB7IFRvYXN0U2VydmljZSB9IGZyb20gJ3RhbmdvLWFwcC11aS1zaGFyZWQnO1xyXG5pbXBvcnQgeyBBZGRGbG9vckNvbXBvbmVudCB9IGZyb20gJy4vcG9wdXBzL2FkZC1mbG9vci9hZGQtZmxvb3IuY29tcG9uZW50JztcclxuaW1wb3J0IHsgQ2xlYXJBbGxTdGVwc0NvbXBvbmVudCB9IGZyb20gJy4vcG9wdXBzL2NsZWFyLWFsbC1zdGVwcy9jbGVhci1hbGwtc3RlcHMuY29tcG9uZW50JztcclxuaW1wb3J0IHsgRGVsZXRlTGF5b3V0Q29tcG9uZW50IH0gZnJvbSAnLi9wb3B1cHMvZGVsZXRlLWxheW91dC9kZWxldGUtbGF5b3V0LmNvbXBvbmVudCc7XHJcbmltcG9ydCAqIGFzIFhMU1ggZnJvbSAneGxzeCc7XHJcblxyXG5cclxuXHJcbkBDb21wb25lbnQoe1xyXG4gIHNlbGVjdG9yOiAnbGliLWNyZWF0ZS1sYXlvdXQnLFxyXG4gIHRlbXBsYXRlVXJsOiAnLi9jcmVhdGUtbGF5b3V0LmNvbXBvbmVudC5odG1sJyxcclxuICBzdHlsZVVybDogJy4vY3JlYXRlLWxheW91dC5jb21wb25lbnQuc2NzcydcclxufSlcclxuZXhwb3J0IGNsYXNzIENyZWF0ZUxheW91dENvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCwgT25EZXN0cm95IHtcclxuICBmbG9vcnNJbnB1dCA9IG5ldyBGb3JtQ29udHJvbCgpXHJcbiAgQFZpZXdDaGlsZCgnZ3JpZENhbnZhcycsIHsgc3RhdGljOiB0cnVlIH0pIGNhbnZhc1JlZiE6IEVsZW1lbnRSZWY8SFRNTENhbnZhc0VsZW1lbnQ+O1xyXG4gIEBWaWV3Q2hpbGQoJ3dpZGdldENhbnZhcycsIHsgc3RhdGljOiBmYWxzZSB9KSB3aWRnZXRDYW52YXNSZWYhOiBFbGVtZW50UmVmPEhUTUxDYW52YXNFbGVtZW50PjtcclxuICBAVmlld0NoaWxkKCdzY3JvbGxDb250YWluZXInKSBzY3JvbGxDb250YWluZXJSZWYhOiBFbGVtZW50UmVmO1xyXG5cclxuXHJcbiAgZ3JpZFdpZHRoID0gMTtcclxuICBncmlkSGVpZ2h0ID0gMTtcclxuXHJcbiAgcHJpdmF0ZSBjdHghOiBDYW52YXNSZW5kZXJpbmdDb250ZXh0MkQ7XHJcbiAgcHJpdmF0ZSBjYW52YXMhOiBIVE1MQ2FudmFzRWxlbWVudDtcclxuXHJcbiAgcHJpdmF0ZSB3aWRnZXRDdHghOiBDYW52YXNSZW5kZXJpbmdDb250ZXh0MkQ7XHJcbiAgcHJpdmF0ZSB3aWRnZXRDYW52YXMhOiBIVE1MQ2FudmFzRWxlbWVudDtcclxuXHJcbiAgZWxlbWVudFR5cGU6ICd3YWxsJyB8ICdmYWNhZGUnIHwgJ29wZW5pbmcnIHwgJ2VudHJhbmNlJyA9ICd3YWxsJ1xyXG4gIGxheW91dFBvbHlnb246IGFueVtdID0gW1tcclxuICAgIHtcclxuICAgICAgXCJ4XCI6IDEwMCxcclxuICAgICAgXCJ5XCI6IDEwMFxyXG4gICAgfSxcclxuICAgIHtcclxuICAgICAgXCJ4XCI6IDEwMCxcclxuICAgICAgXCJ5XCI6IDEwMFxyXG4gICAgfSxcclxuICAgIHtcclxuICAgICAgXCJlbGVtZW50VHlwZVwiOiBcIndhbGxcIixcclxuICAgICAgXCJkaXN0YW5jZVwiOiAwLFxyXG4gICAgICBcInVuaXRcIjogXCJmdFwiLFxyXG4gICAgICBcImRpcmVjdGlvblwiOiBcInJpZ2h0XCIsXHJcbiAgICAgIFwiYW5nbGVcIjogOTAsXHJcbiAgICAgIFwiZWxlbWVudE51bWJlclwiOiAxXHJcbiAgICB9XHJcbiAgXV1cclxuXHJcbiAgcG9wdXBWaXNpYmxlID0gZmFsc2U7XHJcbiAgcG9wdXBQb3NpdGlvbjogYW55ID0geyB4OiAxMDAsIHk6IDEwMCB9O1xyXG4gIHNlbGVjdGVkTGluZTogYW55XHJcbiAgc2VsZWN0ZWRMaW5lSW5kZXg6IG51bWJlciB8IG51bGxcclxuICBtb3ZlUGl4ZWxzID0gMDtcclxuICBtb3ZlQW5nbGUgPSAwO1xyXG4gIHVuaXQ6ICdmdCcgPSAnZnQnXHJcbiAgbW92ZURpcmVjdGlvbjogJ2xlZnQnIHwgJ3JpZ2h0JyB8ICd1cCcgfCAnZG93bicgPSAncmlnaHQnO1xyXG5cclxuICBsYXlvdXRNb2RlOiAnZnVsbCcgfCAnaGFsZicgPSAnaGFsZidcclxuXHJcbiAgZWxlbWVudFNlbGVjdDogeyBzaG93OiBib29sZWFuLCBpbmRleDogbnVtYmVyIH0gPSB7IHNob3c6IGZhbHNlLCBpbmRleDogMCB9XHJcbiAgZGlyZWN0aW9uU2VsZWN0OiB7IHNob3c6IGJvb2xlYW4sIGluZGV4OiBudW1iZXIgfSA9IHsgc2hvdzogZmFsc2UsIGluZGV4OiAwIH1cclxuICBsaW5lT3B0aW9uc1NlbGVjdDogeyBzaG93OiBib29sZWFuLCBpbmRleDogbnVtYmVyIH0gPSB7IHNob3c6IGZhbHNlLCBpbmRleDogMCB9XHJcbiAgd2lkZ2V0RWxlbWVudFNlbGVjdDogeyBzaG93OiBib29sZWFuIH0gPSB7IHNob3c6IGZhbHNlIH1cclxuICBsYXlvdXRPcHRpb25TZWxlY3Q6IHsgc2hvdzogYm9vbGVhbiwgfSA9IHsgc2hvdzogZmFsc2UgfVxyXG4gIGZsb29yU2VsZWN0OiB7IHNob3c6IGJvb2xlYW4sIGRlbGV0ZUluZGV4OiBudW1iZXIgfCBudWxsIH0gPSB7IHNob3c6IGZhbHNlLCBkZWxldGVJbmRleDogbnVsbCB9XHJcblxyXG4gIHByaXZhdGUgc2NhbGUgPSAxO1xyXG4gIHBhbk9mZnNldCA9IHsgeDogMCwgeTogMCB9O1xyXG5cclxuXHJcbiAgYnJlYWtwb2ludHM6IG51bWJlcltdID0gWzAsIDM2MF07XHJcbiAgQFZpZXdDaGlsZCgnY2lyY2xlJykgY2lyY2xlUmVmITogRWxlbWVudFJlZjtcclxuICBAVmlld0NoaWxkKCdwb2ludGVyJykgcG9pbnRlclJlZiE6IEVsZW1lbnRSZWY7XHJcblxyXG4gIGxpbmVzOiB7IHRyYW5zZm9ybTogc3RyaW5nOyBoaWdobGlnaHQ6IGJvb2xlYW47IGludmlzaWJsZTogYm9vbGVhbiB9W10gPSBbXTtcclxuICBwcml2YXRlIG1pbkFuZ2xlITogbnVtYmVyO1xyXG4gIHByaXZhdGUgbWF4QW5nbGUhOiBudW1iZXI7XHJcblxyXG4gIHByaXZhdGUgZGVzdHJveSQgPSBuZXcgU3ViamVjdDx2b2lkPigpO1xyXG5cclxuICBoZWFkZXJEYXRhOiBIZWFkZXJGaWx0ZXIgfCBudWxsIHwgdW5kZWZpbmVkO1xyXG5cclxuICBwbGFub1N0b3JlTGlzdDogYW55W10gPSBbXVxyXG4gIHNlbGVjdGVkU3RvcmU6IGFueVxyXG4gIHNlbGVjdGVkRmxvb3I6IGFueVxyXG5cclxuICB1bmRvU3RhY2s6IGFueVtdID0gW107XHJcbiAgcmVkb1N0YWNrOiBhbnlbXSA9IFtdO1xyXG5cclxuICBwbGFub0lkczogc3RyaW5nW10gPSBbXVxyXG5cclxuICBpdGVtc1BlclBhZ2UgPSAxXHJcbiAgY3VycmVudFBhZ2UgPSAwXHJcbiAgdG90YWxJdGVtcyA9IDFcclxuICBwYWdpbmF0aW9uU2l6ZXMgPSBbMV1cclxuICBwYWdlU2l6ZSA9IDFcclxuXHJcbiAgcGl4ZWxQZXJNZXRyZTogbnVtYmVyID0gNTBcclxuXHJcbiAgY3VtdWxhdGl2ZVJvdGF0aW9uID0gMFxyXG5cclxuXHJcblxyXG4gIG9uUGFnZUNoYW5nZSh2YWw6IG51bWJlcikge1xyXG4gICAgdGhpcy5zZWxlY3RlZFN0b3JlID0gdGhpcy5wbGFub1N0b3JlTGlzdFt2YWwgLSAxXTtcclxuICAgIHRoaXMuc2VsZWN0ZWRGbG9vciA9IHRoaXMuc2VsZWN0ZWRTdG9yZS5mbG9vclswXTtcclxuICAgIHRoaXMuZmxvb3JzSW5wdXQuc2V0VmFsdWUodGhpcy5zZWxlY3RlZEZsb29yLmlkLCB7IGVtaXRFdmVudDogZmFsc2UgfSk7XHJcbiAgICB0aGlzLmdlbmVyYXRlTGF5b3V0UG9seWdvbih0aGlzLnNlbGVjdGVkRmxvb3IubGF5b3V0UG9seWdvbik7XHJcbiAgICB0aGlzLnJlZG9TdGFjayA9IFtdO1xyXG4gICAgdGhpcy51bmRvU3RhY2sgPSBbXTtcclxuICB9XHJcblxyXG4gIHNhdmVTdGF0ZVRvVW5kbygpOiB2b2lkIHtcclxuICAgIHRoaXMudW5kb1N0YWNrLnB1c2goSlNPTi5wYXJzZShKU09OLnN0cmluZ2lmeSh0aGlzLmxheW91dFBvbHlnb24pKSk7XHJcbiAgfVxyXG5cclxuICB1bmRvKCk6IHZvaWQge1xyXG4gICAgaWYgKHRoaXMudW5kb1N0YWNrLmxlbmd0aCA+IDApIHtcclxuICAgICAgdGhpcy5yZWRvU3RhY2sucHVzaChKU09OLnBhcnNlKEpTT04uc3RyaW5naWZ5KHRoaXMubGF5b3V0UG9seWdvbikpKTtcclxuXHJcbiAgICAgIHRoaXMubGF5b3V0UG9seWdvbiA9IHRoaXMudW5kb1N0YWNrLnBvcCgpO1xyXG5cclxuICAgICAgdGhpcy5yZWRyYXdDYW52YXMoKVxyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgcmVkbygpOiB2b2lkIHtcclxuICAgIGlmICh0aGlzLnJlZG9TdGFjay5sZW5ndGggPiAwKSB7XHJcbiAgICAgIHRoaXMudW5kb1N0YWNrLnB1c2goSlNPTi5wYXJzZShKU09OLnN0cmluZ2lmeSh0aGlzLmxheW91dFBvbHlnb24pKSk7XHJcblxyXG4gICAgICB0aGlzLmxheW91dFBvbHlnb24gPSB0aGlzLnJlZG9TdGFjay5wb3AoKTtcclxuXHJcbiAgICAgIHRoaXMucmVkcmF3Q2FudmFzKClcclxuICAgIH1cclxuICB9XHJcblxyXG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgY2Q6IENoYW5nZURldGVjdG9yUmVmLCBwcml2YXRlIHJlbmRlcmVyOiBSZW5kZXJlcjIsIHByaXZhdGUgcm91dGU6IEFjdGl2YXRlZFJvdXRlLFxyXG4gICAgcHJpdmF0ZSBhcGlTZXJ2aWNlOiBTdG9yZUJ1aWxkZXJTZXJ2aWNlLCBwcml2YXRlIHJvdXRlcjogUm91dGVyLCBwcml2YXRlIG9mZmNhbnZhc1NlcnZpY2U6IE5nYk9mZmNhbnZhcywgcHJpdmF0ZSB0b2FzdFNlcnZpY2U6IFRvYXN0U2VydmljZSwgcHJpdmF0ZSBtb2RhbERlZjogTmdiTW9kYWwpIHtcclxuICAgIHRoaXMuaGVhZGVyRGF0YSA9IEpTT04ucGFyc2UobG9jYWxTdG9yYWdlLmdldEl0ZW0oJ2hlYWRlci1maWx0ZXJzJykgYXMgc3RyaW5nKVxyXG4gIH1cclxuXHJcbiAgaW5pdGlhbGl6ZUxheW91dCgpIHtcclxuICAgIGNvbnN0IGNlbnRlclggPSB0aGlzLmNhbnZhcy53aWR0aCAvIDIgLyB0aGlzLnNjYWxlO1xyXG4gICAgY29uc3QgY2VudGVyWSA9IHRoaXMuY2FudmFzLmhlaWdodCAvIDIgLyB0aGlzLnNjYWxlO1xyXG5cclxuICAgIHRoaXMubGF5b3V0UG9seWdvbiA9IFtcclxuICAgICAgW1xyXG4gICAgICAgIHtcclxuICAgICAgICAgIFwieFwiOiB0aGlzLnNuYXBUb0dyaWQoY2VudGVyWCwgdGhpcy5ncmlkSGVpZ2h0KSxcclxuICAgICAgICAgIFwieVwiOiB0aGlzLnNuYXBUb0dyaWQoY2VudGVyWSwgdGhpcy5ncmlkV2lkdGgpXHJcbiAgICAgICAgfSxcclxuICAgICAgICB7XHJcbiAgICAgICAgICBcInhcIjogdGhpcy5zbmFwVG9HcmlkKGNlbnRlclgsIHRoaXMuZ3JpZEhlaWdodCksXHJcbiAgICAgICAgICBcInlcIjogdGhpcy5zbmFwVG9HcmlkKGNlbnRlclksIHRoaXMuZ3JpZFdpZHRoKVxyXG4gICAgICAgIH0sXHJcbiAgICAgICAge1xyXG4gICAgICAgICAgXCJlbGVtZW50VHlwZVwiOiBcIndhbGxcIixcclxuICAgICAgICAgIFwiZGlzdGFuY2VcIjogMCxcclxuICAgICAgICAgIFwidW5pdFwiOiBcImZ0XCIsXHJcbiAgICAgICAgICBcImRpcmVjdGlvblwiOiBcInJpZ2h0XCIsXHJcbiAgICAgICAgICBcImFuZ2xlXCI6IDkwLFxyXG4gICAgICAgICAgXCJlbGVtZW50TnVtYmVyXCI6IDFcclxuICAgICAgICB9XHJcbiAgICAgIF1cclxuICAgIF1cclxuICAgIHRoaXMub3BlbldpZGdldCh7XHJcbiAgICAgIFwieFwiOiB0aGlzLnNuYXBUb0dyaWQoY2VudGVyWCwgdGhpcy5ncmlkSGVpZ2h0KSxcclxuICAgICAgXCJ5XCI6IHRoaXMuc25hcFRvR3JpZChjZW50ZXJZLCB0aGlzLmdyaWRXaWR0aClcclxuICAgIH0pXHJcbiAgfVxyXG5cclxuICBuZ09uSW5pdCgpOiB2b2lkIHtcclxuICAgIHRoaXMuY2FudmFzID0gdGhpcy5jYW52YXNSZWYubmF0aXZlRWxlbWVudDtcclxuICAgIHRoaXMuY3R4ID0gdGhpcy5jYW52YXMuZ2V0Q29udGV4dCgnMmQnKSE7XHJcblxyXG4gICAgdGhpcy5jYW52YXMud2lkdGggPSAxMDAwMDtcclxuICAgIHRoaXMuY2FudmFzLmhlaWdodCA9IDEwMDAwO1xyXG5cclxuICAgIHRoaXMuZHJhd0dyaWQoKTtcclxuXHJcbiAgICB0aGlzLmNhbnZhcy5hZGRFdmVudExpc3RlbmVyKCdtb3VzZWRvd24nLCB0aGlzLm9uTW91c2VEb3duLmJpbmQodGhpcykpO1xyXG4gICAgdGhpcy5jYW52YXMuYWRkRXZlbnRMaXN0ZW5lcignbW91c2Vtb3ZlJywgdGhpcy5vbk1vdXNlTW92ZS5iaW5kKHRoaXMpKTtcclxuXHJcbiAgICB0aGlzLm1pbkFuZ2xlID0gTWF0aC5taW4oLi4udGhpcy5icmVha3BvaW50cyk7XHJcbiAgICB0aGlzLm1heEFuZ2xlID0gTWF0aC5tYXgoLi4udGhpcy5icmVha3BvaW50cyk7XHJcblxyXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCAzNjA7IGkgKz0gNDUpIHtcclxuICAgICAgdGhpcy5saW5lcy5wdXNoKHtcclxuICAgICAgICB0cmFuc2Zvcm06IGByb3RhdGUoJHtpfWRlZylgLFxyXG4gICAgICAgIGhpZ2hsaWdodDogZmFsc2UsXHJcbiAgICAgICAgaW52aXNpYmxlOiBpIDwgdGhpcy5taW5BbmdsZSB8fCBpID4gdGhpcy5tYXhBbmdsZVxyXG4gICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICB0aGlzLnJvdXRlLnF1ZXJ5UGFyYW1zXHJcbiAgICAgIC5waXBlKHRha2VVbnRpbCh0aGlzLmRlc3Ryb3kkKSlcclxuICAgICAgLnN1YnNjcmliZSgocGFyYW1zKSA9PiB7XHJcbiAgICAgICAgaWYgKHBhcmFtcz8uaWQpIHtcclxuICAgICAgICAgIHRoaXMucGxhbm9JZHMgPSBwYXJhbXMuaWQuc3BsaXQoJywnKSB8fCBbXTtcclxuICAgICAgICAgIHRoaXMuZ2V0UGxhbm9EYXRhKClcclxuICAgICAgICB9XHJcbiAgICAgIH0pO1xyXG5cclxuXHJcbiAgfVxyXG5cclxuICBvbkZsb29yU2VsZWN0KGZsb29ySWQ6IHN0cmluZykge1xyXG4gICAgaWYgKHRoaXMubGF5b3V0UG9seWdvblswXVswXS54ICE9PSB0aGlzLmxheW91dFBvbHlnb25bMF1bMV0ueCAmJiB0aGlzLmxheW91dFBvbHlnb25bMF1bMF0ueSAhPT0gdGhpcy5sYXlvdXRQb2x5Z29uWzBdWzFdLnkpIHtcclxuICAgICAgdGhpcy51cGRhdGVGbG9vckxheW91dCgpXHJcbiAgICB9XHJcbiAgICB0aGlzLnNlbGVjdGVkRmxvb3IgPSB0aGlzLnNlbGVjdGVkU3RvcmUuZmxvb3IuZmlsdGVyKChmbG9vcjogYW55KSA9PiBmbG9vci5pZCA9PT0gZmxvb3JJZClbMF1cclxuICAgIHRoaXMuZ2VuZXJhdGVMYXlvdXRQb2x5Z29uKHRoaXMuc2VsZWN0ZWRGbG9vci5sYXlvdXRQb2x5Z29uKVxyXG4gICAgdGhpcy5yZWRvU3RhY2sgPSBbXVxyXG4gICAgdGhpcy51bmRvU3RhY2sgPSBbXVxyXG4gIH1cclxuXHJcblxyXG4gIG5nT25EZXN0cm95KCk6IHZvaWQge1xyXG4gICAgdGhpcy5kZXN0cm95JC5uZXh0KCk7XHJcbiAgICB0aGlzLmRlc3Ryb3kkLmNvbXBsZXRlKCk7XHJcbiAgfVxyXG5cclxuICBvblN0b3JlQ2hhbmdlKGV2ZW50OiBhbnkpIHtcclxuICAgIGlmICh0aGlzLmxheW91dFBvbHlnb25bMF1bMF0ueCAhPT0gdGhpcy5sYXlvdXRQb2x5Z29uWzBdWzFdLnggJiYgdGhpcy5sYXlvdXRQb2x5Z29uWzBdWzBdLnkgIT09IHRoaXMubGF5b3V0UG9seWdvblswXVsxXS55KSB7XHJcbiAgICAgIHRoaXMudXBkYXRlRmxvb3JMYXlvdXQoKVxyXG4gICAgfVxyXG4gICAgY29uc3QgaW5kZXggPSB0aGlzLnBsYW5vU3RvcmVMaXN0LmZpbmRJbmRleChpdGVtID0+IGl0ZW0ucGxhbm9JZCA9PT0gZXZlbnQucGxhbm9JZCk7XHJcbiAgICB0aGlzLmN1cnJlbnRQYWdlID0gaW5kZXggKyAxXHJcbiAgICB0aGlzLnNlbGVjdGVkU3RvcmUgPSBldmVudDtcclxuICAgIHRoaXMuc2VsZWN0ZWRGbG9vciA9IHRoaXMuc2VsZWN0ZWRTdG9yZS5mbG9vclswXTtcclxuICAgIHRoaXMuZmxvb3JzSW5wdXQuc2V0VmFsdWUodGhpcy5zZWxlY3RlZEZsb29yLmlkLCB7IGVtaXRFdmVudDogZmFsc2UgfSk7XHJcbiAgICB0aGlzLmdlbmVyYXRlTGF5b3V0UG9seWdvbih0aGlzLnNlbGVjdGVkRmxvb3IubGF5b3V0UG9seWdvbik7XHJcbiAgICB0aGlzLnJlZG9TdGFjayA9IFtdO1xyXG4gICAgdGhpcy51bmRvU3RhY2sgPSBbXTtcclxuICB9XHJcblxyXG4gIG9wZW5PZmZDYW52YSgpIHtcclxuICAgIGxldCBjYW52YVJlZiA9IHRoaXMub2ZmY2FudmFzU2VydmljZS5vcGVuKFN0b3JlT2ZmY2FudmFzQ29tcG9uZW50Q29tcG9uZW50LCB7IHBvc2l0aW9uOiAnZW5kJywgcGFuZWxDbGFzczogJ3NldC1oZWlnaHQnIH0pXHJcbiAgICBjYW52YVJlZi5jb21wb25lbnRJbnN0YW5jZS5zdG9yZSA9IHRoaXMuc2VsZWN0ZWRTdG9yZTtcclxuICAgIGNhbnZhUmVmLmNvbXBvbmVudEluc3RhbmNlLmNsaWVudElkID0gdGhpcy5oZWFkZXJEYXRhPy5jbGllbnQ7XHJcbiAgICBjYW52YVJlZi5jb21wb25lbnRJbnN0YW5jZS5pZCA9IHRoaXMuc2VsZWN0ZWRTdG9yZS5wbGFub0lkO1xyXG4gIH1cclxuXHJcbiAgZ2V0UGxhbm9EYXRhKCkge1xyXG4gICAgY29uc3QgcGF5bG9hZCA9IHtcclxuICAgICAgaWQ6IHRoaXMucGxhbm9JZHNcclxuICAgIH1cclxuXHJcbiAgICB0aGlzLmFwaVNlcnZpY2UuZ2V0UGxhbm8ocGF5bG9hZCkuc3Vic2NyaWJlKHtcclxuICAgICAgbmV4dDogKHJlczogYW55KSA9PiB7XHJcbiAgICAgICAgdGhpcy5wbGFub1N0b3JlTGlzdCA9IHJlcy5kYXRhXHJcbiAgICAgICAgdGhpcy50b3RhbEl0ZW1zID0gcmVzLmRhdGEubGVuZ3RoXHJcbiAgICAgICAgaWYgKCF0aGlzLnNlbGVjdGVkU3RvcmUpIHtcclxuICAgICAgICAgIHRoaXMuc2VsZWN0ZWRTdG9yZSA9IHRoaXMucGxhbm9TdG9yZUxpc3RbMF1cclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgdGhpcy5zZWxlY3RlZFN0b3JlID0gdGhpcy5wbGFub1N0b3JlTGlzdC5maWx0ZXIoKHN0b3JlOiBhbnkpID0+IHN0b3JlLnBsYW5vSWQgPT09IHRoaXMuc2VsZWN0ZWRTdG9yZS5wbGFub0lkKVswXVxyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAoIXRoaXMuc2VsZWN0ZWRGbG9vcikge1xyXG4gICAgICAgICAgdGhpcy5zZWxlY3RlZEZsb29yID0gdGhpcy5zZWxlY3RlZFN0b3JlLmZsb29yWzBdXHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgIHRoaXMuc2VsZWN0ZWRGbG9vciA9IHRoaXMuc2VsZWN0ZWRTdG9yZS5mbG9vci5maWx0ZXIoKGZsb29yOiBhbnkpID0+IGZsb29yLmlkID09PSB0aGlzLnNlbGVjdGVkRmxvb3IuaWQpWzBdXHJcbiAgICAgICAgICBpZiAoIXRoaXMuc2VsZWN0ZWRGbG9vcikge1xyXG4gICAgICAgICAgICB0aGlzLnNlbGVjdGVkRmxvb3IgPSB0aGlzLnNlbGVjdGVkU3RvcmUuZmxvb3JbMF1cclxuICAgICAgICAgIH1cclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHRoaXMuZmxvb3JzSW5wdXQuc2V0VmFsdWUodGhpcy5zZWxlY3RlZEZsb29yLmlkLCB7IGVtaXRFdmVudDogZmFsc2UgfSlcclxuICAgICAgICB0aGlzLmdlbmVyYXRlTGF5b3V0UG9seWdvbih0aGlzLnNlbGVjdGVkRmxvb3IubGF5b3V0UG9seWdvbilcclxuICAgICAgfSxcclxuICAgICAgZXJyb3I6IChlcnIpID0+IHtcclxuICAgICAgICBjb25zb2xlLmxvZyhlcnIpXHJcbiAgICAgIH1cclxuICAgIH0pXHJcbiAgfVxyXG5cclxuICB1cGRhdGVGbG9vckxheW91dCgpIHtcclxuICAgIGNvbnN0IHBheWxvYWQgPSB7XHJcbiAgICAgIGlkOiB0aGlzLnNlbGVjdGVkRmxvb3IuaWQsXHJcbiAgICAgIGxheW91dFBvbHlnb246IHRoaXMubGF5b3V0UG9seWdvbi5tYXAoKHNlZ21lbnQpID0+IHtcclxuICAgICAgICBjb25zdCBbcG9pbnQxLCBwb2ludDIsIHByb3BlcnRpZXNdID0gc2VnbWVudFxyXG4gICAgICAgIHJldHVybiBwcm9wZXJ0aWVzXHJcbiAgICAgIH0pLFxyXG4gICAgICBzdGF0dXM6ICdkcmFmdCdcclxuICAgIH1cclxuXHJcbiAgICB0aGlzLmFwaVNlcnZpY2UudXBkYXRlRmxvb3JMYXlvdXQocGF5bG9hZCkuc3Vic2NyaWJlKHtcclxuICAgICAgbmV4dDogKHJlczogYW55KSA9PiB7XHJcbiAgICAgICAgaWYgKHJlcy5jb2RlID09PSAyMDApIHtcclxuICAgICAgICAgIHRoaXMuZ2V0UGxhbm9EYXRhKClcclxuICAgICAgICAgIHRoaXMudG9hc3RTZXJ2aWNlLmdldFN1Y2Nlc3NUb2FzdChyZXMubWVzc2FnZSlcclxuICAgICAgICB9XHJcbiAgICAgIH0sXHJcbiAgICAgIGVycm9yOiAoZXJyKSA9PiB7XHJcbiAgICAgICAgY29uc29sZS5sb2coZXJyKVxyXG4gICAgICB9XHJcbiAgICB9KVxyXG4gIH1cclxuXHJcbiAgZGVsZXRlRmxvb3IoaW5kZXg6IG51bWJlcikge1xyXG5cclxuICAgIHRoaXMuZmxvb3JTZWxlY3QgPSB7XHJcbiAgICAgIHNob3c6ICF0aGlzLmZsb29yU2VsZWN0LnNob3csXHJcbiAgICAgIGRlbGV0ZUluZGV4OiBudWxsXHJcbiAgICB9O1xyXG5cclxuICAgIGNvbnN0IG1vZGVsUmVmID0gdGhpcy5tb2RhbERlZi5vcGVuKERlbGV0ZUxheW91dENvbXBvbmVudCwgeyBjZW50ZXJlZDogdHJ1ZSB9KTtcclxuICAgIG1vZGVsUmVmLnJlc3VsdC50aGVuKCh2YWw6IGFueSkgPT4ge1xyXG4gICAgICBpZiAodmFsLm1lc3NhZ2UgPT09ICdjb25maXJtJykge1xyXG4gICAgICAgIGNvbnN0IHBheWxvYWQgPSB7XHJcbiAgICAgICAgICBpZDogdGhpcy5zZWxlY3RlZFN0b3JlLmZsb29yW2luZGV4XS5pZCxcclxuICAgICAgICB9XHJcbiAgICBcclxuICAgICAgICB0aGlzLmFwaVNlcnZpY2UuZGVsZXRlRmxvb3IocGF5bG9hZCkuc3Vic2NyaWJlKHtcclxuICAgICAgICAgIG5leHQ6IChyZXM6IGFueSkgPT4ge1xyXG4gICAgICAgICAgICBpZiAocmVzLmNvZGUgPT09IDIwMCkge1xyXG4gICAgICAgICAgICAgIHRoaXMuZ2V0UGxhbm9EYXRhKClcclxuICAgICAgICAgICAgICB0aGlzLnRvYXN0U2VydmljZS5nZXRTdWNjZXNzVG9hc3QocmVzLm1lc3NhZ2UpXHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgIH0sXHJcbiAgICAgICAgICBlcnJvcjogKGVycikgPT4ge1xyXG4gICAgICAgICAgICBjb25zb2xlLmxvZyhlcnIpXHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfSlcclxuICAgICAgfVxyXG4gICAgfSlcclxuXHJcbiAgfVxyXG5cclxuICBhZGRGbG9vcihwbGFub0lkOiBzdHJpbmcsIGZsb29yQ291bnQ6IG51bWJlcikge1xyXG4gICAgY29uc3QgcGF5bG9hZCA9IHtcclxuICAgICAgaWQ6IHBsYW5vSWQsXHJcbiAgICAgIGZsb29yTnVtYmVyOiBmbG9vckNvdW50XHJcbiAgICB9O1xyXG5cclxuICAgIHRoaXMuYXBpU2VydmljZS5hZGRGbG9vcihwYXlsb2FkKS5zdWJzY3JpYmUoe1xyXG4gICAgICBuZXh0OiAocmVzOiBhbnkpID0+IHtcclxuICAgICAgICBpZiAocmVzLmNvZGUgPT09IDIwMCkge1xyXG4gICAgICAgICAgdGhpcy5nZXRQbGFub0RhdGEoKVxyXG4gICAgICAgICAgdGhpcy50b2FzdFNlcnZpY2UuZ2V0U3VjY2Vzc1RvYXN0KHJlcy5tZXNzYWdlKVxyXG4gICAgICAgIH1cclxuICAgICAgfSxcclxuICAgICAgZXJyb3I6IChlcnIpID0+IHtcclxuICAgICAgICBjb25zb2xlLmxvZyhlcnIpXHJcbiAgICAgIH1cclxuICAgIH0pXHJcbiAgfVxyXG5cclxuICBvblNhdmVBc0RyYWZ0KCkge1xyXG4gICAgaWYgKHRoaXMubGF5b3V0UG9seWdvbi5sZW5ndGggPT09IDEgJiYgdGhpcy5sYXlvdXRQb2x5Z29uWzBdWzBdLnggPT09IHRoaXMubGF5b3V0UG9seWdvblswXVsxXS54ICYmIHRoaXMubGF5b3V0UG9seWdvblswXVswXS55ID09PSB0aGlzLmxheW91dFBvbHlnb25bMF1bMV0ueSkge1xyXG4gICAgICByZXR1cm5cclxuICAgIH1cclxuXHJcbiAgICB0aGlzLnVwZGF0ZUZsb29yTGF5b3V0KClcclxuXHJcbiAgfVxyXG5cclxuICBvbkNvbmZpZ3VyZSgpIHtcclxuICAgIGlmICh0aGlzLnBsYW5vU3RvcmVMaXN0Lmxlbmd0aCA9PT0gMSkge1xyXG4gICAgICBmb3IgKGxldCBpbmRleCA9IDA7IGluZGV4IDwgdGhpcy5zZWxlY3RlZFN0b3JlLmZsb29yLmxlbmd0aDsgaW5kZXgrKykge1xyXG4gICAgICAgIGxldCBsYXlvdXRJbnN0cnVjdGlvblxyXG4gICAgICAgIGlmICh0aGlzLnNlbGVjdGVkU3RvcmUuZmxvb3JbaW5kZXhdLmlkID09PSB0aGlzLnNlbGVjdGVkRmxvb3IuaWQpIHtcclxuICAgICAgICAgIGxheW91dEluc3RydWN0aW9uID0gdGhpcy5sYXlvdXRQb2x5Z29uLm1hcCgobGluZSkgPT4ge1xyXG4gICAgICAgICAgICBjb25zdCBbc3RlcnQsIGVuZCwgcHJvcGVydGllc10gPSBsaW5lXHJcbiAgICAgICAgICAgIHJldHVybiBwcm9wZXJ0aWVzXHJcbiAgICAgICAgICB9KVxyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICBsYXlvdXRJbnN0cnVjdGlvbiA9IHRoaXMuc2VsZWN0ZWRTdG9yZS5mbG9vcltpbmRleF0ubGF5b3V0UG9seWdvblxyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAoIXRoaXMuaXNGbG9vckNvbXBsZXRlZChsYXlvdXRJbnN0cnVjdGlvbikpIHtcclxuICAgICAgICAgIHRoaXMudG9hc3RTZXJ2aWNlLmdldEVycm9yVG9hc3QoYFBsZWFzZSBjb21wbGV0ZSAke3RoaXMuc2VsZWN0ZWRTdG9yZS5mbG9vcltpbmRleF0uZmxvb3JOYW1lfWApXHJcbiAgICAgICAgICByZXR1cm5cclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuICAgIH0gZWxzZSBpZiAodGhpcy5wbGFub1N0b3JlTGlzdC5sZW5ndGggPiAxKSB7XHJcbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5wbGFub1N0b3JlTGlzdC5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgIGZvciAobGV0IGogPSAwOyBqIDwgdGhpcy5wbGFub1N0b3JlTGlzdFtpXS5mbG9vci5sZW5ndGg7IGorKykge1xyXG4gICAgICAgICAgbGV0IGxheW91dEluc3RydWN0aW9uXHJcbiAgICAgICAgICBpZiAodGhpcy5wbGFub1N0b3JlTGlzdFtpXS5mbG9vcltqXS5pZCA9PT0gdGhpcy5zZWxlY3RlZEZsb29yLmlkKSB7XHJcbiAgICAgICAgICAgIGxheW91dEluc3RydWN0aW9uID0gdGhpcy5sYXlvdXRQb2x5Z29uLm1hcCgobGluZSkgPT4ge1xyXG4gICAgICAgICAgICAgIGNvbnN0IFtzdGVydCwgZW5kLCBwcm9wZXJ0aWVzXSA9IGxpbmVcclxuICAgICAgICAgICAgICByZXR1cm4gcHJvcGVydGllc1xyXG4gICAgICAgICAgICB9KVxyXG4gICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgbGF5b3V0SW5zdHJ1Y3Rpb24gPSB0aGlzLnBsYW5vU3RvcmVMaXN0W2ldLmZsb29yW2pdLmxheW91dFBvbHlnb25cclxuICAgICAgICAgIH1cclxuICAgICAgICAgIGlmICghdGhpcy5pc0Zsb29yQ29tcGxldGVkKGxheW91dEluc3RydWN0aW9uKSkge1xyXG4gICAgICAgICAgICB0aGlzLnRvYXN0U2VydmljZS5nZXRFcnJvclRvYXN0KGBQbGVhc2UgY29tcGxldGUgJHt0aGlzLnBsYW5vU3RvcmVMaXN0W2ldLmZsb29yW2pdLmZsb29yTmFtZX0gb2YgJHt0aGlzLnBsYW5vU3RvcmVMaXN0W2ldLnN0b3JlTmFtZX1gKVxyXG4gICAgICAgICAgICByZXR1cm5cclxuICAgICAgICAgIH1cclxuICAgICAgICB9XHJcblxyXG4gICAgICB9XHJcblxyXG4gICAgfVxyXG5cclxuICAgIHRoaXMudXBkYXRlRmxvb3JMYXlvdXQoKVxyXG4gICAgdGhpcy5yb3V0ZXIubmF2aWdhdGUoWycvbWFuYWdlL3BsYW5vZ3JhbS9sYXlvdXQtYnVpbGRlci9zdW1tYXJ5J10sIHtcclxuICAgICAgcXVlcnlQYXJhbXNIYW5kbGluZzogJ21lcmdlJ1xyXG4gICAgfSk7XHJcblxyXG4gIH1cclxuXHJcbiAgZHJhd1dpZGdldFJpbmcoKSB7XHJcbiAgICB0aGlzLndpZGdldENhbnZhcyA9IHRoaXMud2lkZ2V0Q2FudmFzUmVmLm5hdGl2ZUVsZW1lbnQ7XHJcbiAgICB0aGlzLndpZGdldEN0eCA9IHRoaXMud2lkZ2V0Q2FudmFzLmdldENvbnRleHQoJzJkJykhO1xyXG5cclxuICAgIHRoaXMud2lkZ2V0Q2FudmFzLndpZHRoID0gMjI5O1xyXG4gICAgdGhpcy53aWRnZXRDYW52YXMuaGVpZ2h0ID0gMjI5O1xyXG4gICAgdGhpcy53aWRnZXRDdHguY2xlYXJSZWN0KDAsIDAsIHRoaXMud2lkZ2V0Q2FudmFzLndpZHRoLCB0aGlzLndpZGdldENhbnZhcy5oZWlnaHQpO1xyXG5cclxuICAgIGNvbnN0IGRpcmVjdGlvbjogYW55ID0gdGhpcy5tb3ZlRGlyZWN0aW9uXHJcbiAgICBjb25zdCBjZW50ZXJYID0gdGhpcy53aWRnZXRDYW52YXMud2lkdGggLyAyO1xyXG4gICAgY29uc3QgY2VudGVyWSA9IHRoaXMud2lkZ2V0Q2FudmFzLmhlaWdodCAvIDI7XHJcbiAgICBjb25zdCBvdXRlclJhZGl1cyA9IDExNC41O1xyXG4gICAgY29uc3QgaW5uZXJSYWRpdXMgPSA4NTtcclxuXHJcbiAgICB0aGlzLndpZGdldEN0eC5iZWdpblBhdGgoKTtcclxuICAgIHRoaXMud2lkZ2V0Q3R4LmFyYyhjZW50ZXJYLCBjZW50ZXJZLCBvdXRlclJhZGl1cywgMCwgTWF0aC5QSSAqIDIpO1xyXG4gICAgdGhpcy53aWRnZXRDdHguZmlsbFN0eWxlID0gJyNGOUZBRkInO1xyXG4gICAgdGhpcy53aWRnZXRDdHguZmlsbCgpO1xyXG5cclxuICAgIHRoaXMud2lkZ2V0Q3R4Lmdsb2JhbENvbXBvc2l0ZU9wZXJhdGlvbiA9ICdkZXN0aW5hdGlvbi1vdXQnO1xyXG4gICAgdGhpcy53aWRnZXRDdHguYmVnaW5QYXRoKCk7XHJcbiAgICB0aGlzLndpZGdldEN0eC5hcmMoY2VudGVyWCwgY2VudGVyWSwgaW5uZXJSYWRpdXMsIDAsIE1hdGguUEkgKiAyKTtcclxuICAgIHRoaXMud2lkZ2V0Q3R4LmZpbGwoKTtcclxuXHJcbiAgICB0aGlzLndpZGdldEN0eC5nbG9iYWxDb21wb3NpdGVPcGVyYXRpb24gPSAnc291cmNlLW92ZXInO1xyXG5cclxuICAgIHRoaXMud2lkZ2V0Q3R4LmJlZ2luUGF0aCgpO1xyXG4gICAgbGV0IHN0YXJ0QW5nbGUsIGVuZEFuZ2xlLCBjb2xvcjtcclxuICAgIHN3aXRjaCAoZGlyZWN0aW9uKSB7XHJcbiAgICAgIGNhc2UgJ2Rvd24nOlxyXG4gICAgICAgIHN0YXJ0QW5nbGUgPSAwO1xyXG4gICAgICAgIGVuZEFuZ2xlID0gTWF0aC5QSTtcclxuICAgICAgICBjb2xvciA9ICcjRUFGN0ZGJztcclxuICAgICAgICBicmVhaztcclxuICAgICAgY2FzZSAndXAnOlxyXG4gICAgICAgIHN0YXJ0QW5nbGUgPSBNYXRoLlBJO1xyXG4gICAgICAgIGVuZEFuZ2xlID0gTWF0aC5QSSAqIDI7XHJcbiAgICAgICAgY29sb3IgPSAnI0VBRjdGRic7XHJcbiAgICAgICAgYnJlYWs7XHJcbiAgICAgIGNhc2UgJ3JpZ2h0JzpcclxuICAgICAgICBzdGFydEFuZ2xlID0gTWF0aC5QSSAqIDEuNTtcclxuICAgICAgICBlbmRBbmdsZSA9IE1hdGguUEkgKiAwLjU7XHJcbiAgICAgICAgY29sb3IgPSAnI0VBRjdGRic7XHJcbiAgICAgICAgYnJlYWs7XHJcbiAgICAgIGNhc2UgJ2xlZnQnOlxyXG4gICAgICAgIHN0YXJ0QW5nbGUgPSBNYXRoLlBJICogMC41O1xyXG4gICAgICAgIGVuZEFuZ2xlID0gTWF0aC5QSSAqIDEuNTtcclxuICAgICAgICBjb2xvciA9ICcjRUFGN0ZGJztcclxuICAgICAgICBicmVhaztcclxuICAgICAgZGVmYXVsdDpcclxuICAgICAgICByZXR1cm47XHJcbiAgICB9XHJcblxyXG4gICAgdGhpcy53aWRnZXRDdHgubW92ZVRvKGNlbnRlclgsIGNlbnRlclkpO1xyXG4gICAgdGhpcy53aWRnZXRDdHguYXJjKGNlbnRlclgsIGNlbnRlclksIG91dGVyUmFkaXVzLCBzdGFydEFuZ2xlLCBlbmRBbmdsZSk7XHJcbiAgICB0aGlzLndpZGdldEN0eC5saW5lVG8oY2VudGVyWCwgY2VudGVyWSk7XHJcbiAgICB0aGlzLndpZGdldEN0eC5maWxsU3R5bGUgPSBjb2xvcjtcclxuICAgIHRoaXMud2lkZ2V0Q3R4LmZpbGwoKTtcclxuXHJcbiAgICB0aGlzLndpZGdldEN0eC5nbG9iYWxDb21wb3NpdGVPcGVyYXRpb24gPSAnZGVzdGluYXRpb24tb3V0JztcclxuICAgIHRoaXMud2lkZ2V0Q3R4LmJlZ2luUGF0aCgpO1xyXG4gICAgdGhpcy53aWRnZXRDdHguYXJjKGNlbnRlclgsIGNlbnRlclksIGlubmVyUmFkaXVzLCAwLCBNYXRoLlBJICogMik7XHJcbiAgICB0aGlzLndpZGdldEN0eC5maWxsKCk7XHJcblxyXG4gICAgdGhpcy53aWRnZXRDdHguZ2xvYmFsQ29tcG9zaXRlT3BlcmF0aW9uID0gJ3NvdXJjZS1vdmVyJztcclxuICB9XHJcblxyXG4gIHByaXZhdGUgdXBkYXRlV2lkZ2V0UG9pbnRlcigpOiB2b2lkIHtcclxuICAgIGxldCBhbmdsZTogbnVtYmVyO1xyXG4gICAgc3dpdGNoICh0aGlzLm1vdmVEaXJlY3Rpb24pIHtcclxuICAgICAgY2FzZSAncmlnaHQnOlxyXG4gICAgICAgIGFuZ2xlID0gMCArIHRoaXMubW92ZUFuZ2xlO1xyXG4gICAgICAgIGJyZWFrO1xyXG4gICAgICBjYXNlICdkb3duJzpcclxuICAgICAgICBhbmdsZSA9IDkwICsgdGhpcy5tb3ZlQW5nbGU7XHJcbiAgICAgICAgYnJlYWs7XHJcbiAgICAgIGNhc2UgJ2xlZnQnOlxyXG4gICAgICAgIGFuZ2xlID0gMTgwICsgdGhpcy5tb3ZlQW5nbGU7XHJcbiAgICAgICAgYnJlYWs7XHJcbiAgICAgIGNhc2UgJ3VwJzpcclxuICAgICAgICBhbmdsZSA9IDI3MCArIHRoaXMubW92ZUFuZ2xlO1xyXG4gICAgICAgIGJyZWFrO1xyXG4gICAgICBkZWZhdWx0OlxyXG4gICAgICAgIHJldHVybjtcclxuICAgIH1cclxuICAgIGNvbnN0IHBvaW50ZXIgPSB0aGlzLnBvaW50ZXJSZWY/Lm5hdGl2ZUVsZW1lbnQ7XHJcbiAgICB0aGlzLnJlbmRlcmVyLnNldFN0eWxlKHBvaW50ZXIsICd0cmFuc2Zvcm0nLCBgcm90YXRlKCR7YW5nbGV9ZGVnKWApO1xyXG5cclxuICAgIHRoaXMubGluZXMuZm9yRWFjaCgobGluZSkgPT4ge1xyXG4gICAgICBjb25zdCBsaW5lQW5nbGUgPSBwYXJzZUludChsaW5lLnRyYW5zZm9ybS5yZXBsYWNlKCdyb3RhdGUoJywgJycpLCAxMCk7XHJcbiAgICAgIGxpbmUuaGlnaGxpZ2h0ID0gYW5nbGUgPj0gbGluZUFuZ2xlICYmIGFuZ2xlID49IHRoaXMubWluQW5nbGUgJiYgbGluZUFuZ2xlIDw9IHRoaXMubWF4QW5nbGU7XHJcbiAgICB9KTtcclxuXHJcblxyXG4gIH1cclxuXHJcblxyXG4gIGRyYXdHcmlkKCk6IHZvaWQge1xyXG4gICAgdGhpcy5jdHguc2F2ZSgpO1xyXG4gICAgdGhpcy5jdHguY2xlYXJSZWN0KDAsIDAsIHRoaXMuY2FudmFzLndpZHRoLCB0aGlzLmNhbnZhcy5oZWlnaHQpO1xyXG5cclxuICAgIHRoaXMuY3R4LnNjYWxlKHRoaXMuc2NhbGUsIHRoaXMuc2NhbGUpO1xyXG4gICAgdGhpcy5jdHgudHJhbnNsYXRlKHRoaXMucGFuT2Zmc2V0LngsIHRoaXMucGFuT2Zmc2V0LnkpO1xyXG5cclxuXHJcbiAgICAvLyBmb3IgKGxldCB4ID0gMDsgeCA8PSB0aGlzLmNhbnZhcy53aWR0aDsgeCArPSB0aGlzLmdyaWRXaWR0aCkge1xyXG4gICAgLy8gICBmb3IgKGxldCB5ID0gMDsgeSA8PSB0aGlzLmNhbnZhcy5oZWlnaHQ7IHkgKz0gdGhpcy5ncmlkSGVpZ2h0KSB7XHJcbiAgICAvLyAgICAgdGhpcy5jdHguYmVnaW5QYXRoKCk7XHJcbiAgICAvLyAgICAgdGhpcy5jdHguYXJjKHgsIHksIDEsIDAsIE1hdGguUEkgKiAyKTtcclxuICAgIC8vICAgICB0aGlzLmN0eC5maWxsU3R5bGUgPSAncmdiYSgwLCAwLCAwLCAwLjMpJztcclxuICAgIC8vICAgICB0aGlzLmN0eC5maWxsKCk7XHJcbiAgICAvLyAgIH1cclxuICAgIC8vIH1cclxuXHJcbiAgICB0aGlzLmN0eC5yZXN0b3JlKCk7XHJcbiAgfVxyXG5cclxuICBkcmF3UG9seWdvbihwb2x5Z29uID0gdGhpcy5sYXlvdXRQb2x5Z29uKSB7XHJcbiAgICBpZiAocG9seWdvbi5sZW5ndGggPCAxKSByZXR1cm47IC8vIElmIHRoZSBwb2x5Z29uIGhhcyBubyBlZGdlcywgZXhpdCBlYXJseS5cclxuXHJcbiAgICB0aGlzLmN0eC5zYXZlKCk7IC8vIFNhdmUgdGhlIGN1cnJlbnQgY2FudmFzIHN0YXRlLlxyXG4gICAgdGhpcy5jdHguc2NhbGUodGhpcy5zY2FsZSwgdGhpcy5zY2FsZSk7IC8vIFNjYWxlIHRoZSBjYW52YXMgY29udGV4dCB0byBtYXRjaCB0aGUgZGVzaXJlZCBzY2FsZS5cclxuICAgIHRoaXMuY3R4LnRyYW5zbGF0ZSh0aGlzLnBhbk9mZnNldC54LCB0aGlzLnBhbk9mZnNldC55KTtcclxuXHJcblxyXG4gICAgLy8gRnVuY3Rpb24gdG8gZHJhdyBhbiBhcnJvd2hlYWQgYXQgYSBzcGVjaWZpYyBsb2NhdGlvbiBhbmQgYW5nbGUuXHJcbiAgICBmdW5jdGlvbiBkcmF3QXJyb3doZWFkKGN0eDogYW55LCB4OiBhbnksIHk6IGFueSwgYW5nbGU6IGFueSkge1xyXG4gICAgICBjb25zdCBzaXplID0gNTsgLy8gRGVmaW5lIHRoZSBzaXplIG9mIHRoZSBhcnJvd2hlYWQuXHJcbiAgICAgIGN0eC5zYXZlKCk7IC8vIFNhdmUgdGhlIGN1cnJlbnQgY2FudmFzIHN0YXRlLlxyXG4gICAgICBjdHgudHJhbnNsYXRlKHgsIHkpOyAvLyBNb3ZlIHRoZSBjb250ZXh0IHRvIHRoZSBhcnJvd2hlYWQgcG9zaXRpb24uXHJcbiAgICAgIGN0eC5yb3RhdGUoYW5nbGUpOyAvLyBSb3RhdGUgdGhlIGNvbnRleHQgdG8gbWF0Y2ggdGhlIGFycm93J3MgYW5nbGUuXHJcbiAgICAgIGN0eC5iZWdpblBhdGgoKTsgLy8gU3RhcnQgYSBuZXcgcGF0aC5cclxuICAgICAgY3R4Lm1vdmVUbygwLCAwKTsgLy8gTW92ZSB0byB0aGUgdGlwIG9mIHRoZSBhcnJvd2hlYWQuXHJcbiAgICAgIGN0eC5saW5lVG8oLXNpemUsIC1zaXplIC8gMik7IC8vIERyYXcgb25lIHNpZGUgb2YgdGhlIGFycm93aGVhZC5cclxuICAgICAgY3R4LmxpbmVUbygtc2l6ZSwgc2l6ZSAvIDIpOyAvLyBEcmF3IHRoZSBvdGhlciBzaWRlIG9mIHRoZSBhcnJvd2hlYWQuXHJcbiAgICAgIGN0eC5jbG9zZVBhdGgoKTsgLy8gQ2xvc2UgdGhlIGFycm93aGVhZCBwYXRoLlxyXG4gICAgICBjdHguZmlsbFN0eWxlID0gJ2JsYWNrJzsgLy8gU2V0IHRoZSBhcnJvd2hlYWQgY29sb3IuXHJcbiAgICAgIGN0eC5maWxsKCk7IC8vIEZpbGwgdGhlIGFycm93aGVhZC5cclxuICAgICAgY3R4LnJlc3RvcmUoKTsgLy8gUmVzdG9yZSB0aGUgcHJldmlvdXMgY2FudmFzIHN0YXRlLlxyXG4gICAgfVxyXG5cclxuICAgIHRoaXMuY3R4LmJlZ2luUGF0aCgpOyAvLyBCZWdpbiB0aGUgbWFpbiBwb2x5Z29uIHBhdGguXHJcbiAgICBwb2x5Z29uLmZvckVhY2goKGVkZ2UsIGVkZ2VJbmRleCkgPT4ge1xyXG4gICAgICBjb25zdCBwb2ludCA9IGVkZ2VbMF07IC8vIFN0YXJ0aW5nIHBvaW50IG9mIHRoZSBlZGdlLlxyXG4gICAgICBjb25zdCBuZXh0UG9pbnQgPSBlZGdlWzFdOyAvLyBFbmRpbmcgcG9pbnQgb2YgdGhlIGVkZ2UuXHJcbiAgICAgIGNvbnN0IHByb3BlcnRpZXMgPSBlZGdlWzJdOyAvLyBQcm9wZXJ0aWVzIG9mIHRoZSBlZGdlIChlLmcuLCBsYWJlbHMsIGRpc3RhbmNlcykuXHJcblxyXG4gICAgICAvLyBEcmF3IHRoZSBtYWluIHBvbHlnb24gZWRnZS5cclxuICAgICAgaWYgKGVkZ2VJbmRleCA9PT0gMCkgdGhpcy5jdHgubW92ZVRvKHBvaW50LngsIHBvaW50LnkpOyAvLyBNb3ZlIHRvIHRoZSBmaXJzdCBlZGdlIHN0YXJ0aW5nIHBvaW50LlxyXG4gICAgICB0aGlzLmN0eC5saW5lVG8obmV4dFBvaW50LngsIG5leHRQb2ludC55KTsgLy8gRHJhdyBhIGxpbmUgdG8gdGhlIG5leHQgcG9pbnQuXHJcblxyXG4gICAgICAvLyBDYWxjdWxhdGUgdGhlIHBlcnBlbmRpY3VsYXIgb2Zmc2V0IGZvciB0aGUgYm91bmRpbmcgYm94LlxyXG4gICAgICBjb25zdCBkeCA9IG5leHRQb2ludC54IC0gcG9pbnQueDsgLy8gWC1kaWZmZXJlbmNlIGJldHdlZW4gc3RhcnQgYW5kIGVuZCBwb2ludHMuXHJcbiAgICAgIGNvbnN0IGR5ID0gbmV4dFBvaW50LnkgLSBwb2ludC55OyAvLyBZLWRpZmZlcmVuY2UgYmV0d2VlbiBzdGFydCBhbmQgZW5kIHBvaW50cy5cclxuICAgICAgY29uc3QgbGVuZ3RoID0gTWF0aC5zcXJ0KGR4ICogZHggKyBkeSAqIGR5KTsgLy8gTGVuZ3RoIG9mIHRoZSBlZGdlLlxyXG4gICAgICBjb25zdCBvZmZzZXRYID0gKGR5IC8gbGVuZ3RoKSAqIDIwOyAvLyBPZmZzZXQgaW4gdGhlIFggZGlyZWN0aW9uLlxyXG4gICAgICBjb25zdCBvZmZzZXRZID0gKC1keCAvIGxlbmd0aCkgKiAyMDsgLy8gT2Zmc2V0IGluIHRoZSBZIGRpcmVjdGlvbi5cclxuXHJcbiAgICAgIC8vIERlZmluZSB0aGUgYm91bmRpbmcgYm94IHBvaW50cy5cclxuICAgICAgY29uc3QgYm94UG9pbnRzID0gW1xyXG4gICAgICAgIHsgeDogcG9pbnQueCwgeTogcG9pbnQueSB9LFxyXG4gICAgICAgIHsgeDogbmV4dFBvaW50LngsIHk6IG5leHRQb2ludC55IH0sXHJcbiAgICAgICAgeyB4OiBuZXh0UG9pbnQueCArIG9mZnNldFgsIHk6IG5leHRQb2ludC55ICsgb2Zmc2V0WSB9LFxyXG4gICAgICAgIHsgeDogcG9pbnQueCArIG9mZnNldFgsIHk6IHBvaW50LnkgKyBvZmZzZXRZIH0sXHJcbiAgICAgIF07XHJcblxyXG4gICAgICAvLyBEcmF3IHRoZSBib3VuZGluZyBib3guXHJcbiAgICAgIHRoaXMuY3R4LmJlZ2luUGF0aCgpO1xyXG4gICAgICB0aGlzLmN0eC5tb3ZlVG8oYm94UG9pbnRzWzBdLngsIGJveFBvaW50c1swXS55KTtcclxuICAgICAgYm94UG9pbnRzLmZvckVhY2goKHB0LCBpbmRleCkgPT4ge1xyXG4gICAgICAgIGlmIChwcm9wZXJ0aWVzLmVsZW1lbnRUeXBlID09PSAnZW50cmFuY2UnKSB7XHJcbiAgICAgICAgICBpZiAoaW5kZXggPCAyKSB7XHJcbiAgICAgICAgICAgIHRoaXMuY3R4LmxpbmVUbyhwdC54LCBwdC55KVxyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICB0aGlzLmN0eC5saW5lVG8ocHQueCwgcHQueSk7IC8vIERyYXcgZWFjaCBlZGdlIG9mIHRoZSBib3guXHJcbiAgICAgICAgfVxyXG4gICAgICB9KTtcclxuICAgICAgaWYgKHByb3BlcnRpZXMuZWxlbWVudFR5cGUgPT09ICdvcGVuaW5nJykge1xyXG4gICAgICAgIHRoaXMuY3R4LmNsb3NlUGF0aCgpOyAvLyBDbG9zZSB0aGUgYm91bmRpbmcgYm94IHBhdGguXHJcbiAgICAgICAgdGhpcy5jdHguZmlsbFN0eWxlID0gJyNGOUZBRkInOyAvLyBTZXQgYSB0cmFuc2x1Y2VudCBmaWxsIGNvbG9yLlxyXG4gICAgICAgIHRoaXMuY3R4LmZpbGwoKTsgLy8gRmlsbCB0aGUgYm91bmRpbmcgYm94LlxyXG5cclxuICAgICAgICB0aGlzLnNlbGVjdGVkTGluZUluZGV4ID09PSBlZGdlSW5kZXggPyB0aGlzLmN0eC5zdHJva2VTdHlsZSA9ICcjMDA4RURGJyA6IHRoaXMuY3R4LnN0cm9rZVN0eWxlID0gJyNGOUZBRkInXHJcblxyXG4gICAgICAgIHRoaXMuY3R4LnN0cm9rZSgpOyAvLyBEcmF3IHRoZSBib3VuZGluZyBib3ggYm9yZGVyLiBcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICB0aGlzLmN0eC5jbG9zZVBhdGgoKTsgLy8gQ2xvc2UgdGhlIGJvdW5kaW5nIGJveCBwYXRoLlxyXG4gICAgICAgIHRoaXMuY3R4LmZpbGxTdHlsZSA9ICcjRjlGQUZCJzsgLy8gU2V0IGEgdHJhbnNsdWNlbnQgZmlsbCBjb2xvci5cclxuICAgICAgICB0aGlzLmN0eC5maWxsKCk7IC8vIEZpbGwgdGhlIGJvdW5kaW5nIGJveC5cclxuICAgICAgICB0aGlzLnNlbGVjdGVkTGluZUluZGV4ID09PSBlZGdlSW5kZXggPyB0aGlzLmN0eC5zdHJva2VTdHlsZSA9ICcjMDA4RURGJyA6IHRoaXMuY3R4LnN0cm9rZVN0eWxlID0gJyMxRDI5MzknXHJcbiAgICAgICAgdGhpcy5jdHguc3Ryb2tlKCk7IC8vIERyYXcgdGhlIGJvdW5kaW5nIGJveCBib3JkZXIuIFxyXG4gICAgICB9XHJcblxyXG5cclxuICAgICAgLy8gUG9zaXRpb24gdGV4dCBpbiB0aGUgbWlkZGxlIG9mIHRoZSBib3VuZGluZyBib3guXHJcbiAgICAgIGNvbnN0IHRleHRYID0gKGJveFBvaW50c1sxXS54ICsgYm94UG9pbnRzWzNdLngpIC8gMjtcclxuICAgICAgY29uc3QgdGV4dFkgPSAoYm94UG9pbnRzWzFdLnkgKyBib3hQb2ludHNbM10ueSkgLyAyO1xyXG5cclxuICAgICAgdGhpcy5jdHguc2F2ZSgpOyAvLyBTYXZlIHRoZSBjdXJyZW50IGNhbnZhcyBzdGF0ZS5cclxuICAgICAgdGhpcy5jdHgudHJhbnNsYXRlKHRleHRYLCB0ZXh0WSk7IC8vIE1vdmUgdGhlIGNvbnRleHQgdG8gdGhlIHRleHQgcG9zaXRpb24uXHJcblxyXG4gICAgICAvLyBSb3RhdGUgdGV4dCBiYXNlZCBvbiB0aGUgZWRnZSBkaXJlY3Rpb24uXHJcbiAgICAgIGlmIChkeCA9PT0gMCkge1xyXG4gICAgICAgIHRoaXMuY3R4LnJvdGF0ZSgtTWF0aC5QSSAvIDIpOyAvLyBSb3RhdGUgZm9yIHZlcnRpY2FsIGVkZ2VzLlxyXG4gICAgICB9IGVsc2UgaWYgKGR5ICE9PSAwKSB7XHJcbiAgICAgICAgY29uc3QgYW5nbGUgPSBNYXRoLmF0YW4yKGR5LCBkeCk7IC8vIENhbGN1bGF0ZSBhbmdsZSBmb3IgZGlhZ29uYWwgZWRnZXMuXHJcbiAgICAgICAgdGhpcy5jdHgucm90YXRlKGFuZ2xlKTsgLy8gUm90YXRlIHRoZSB0ZXh0IHRvIG1hdGNoIHRoZSBhbmdsZS5cclxuICAgICAgfVxyXG5cclxuICAgICAgLy8gRHJhdyB0aGUgZWRnZSBwcm9wZXJ0aWVzIGFzIHRleHQuXHJcbiAgICAgIHRoaXMuY3R4LmZvbnQgPSAnMTJweCBBcmlhbCc7IC8vIFNldCB0aGUgZm9udCBzdHlsZSBhbmQgc2l6ZS5cclxuICAgICAgdGhpcy5jdHguZmlsbFN0eWxlID0gJ2JsYWNrJzsgLy8gU2V0IHRoZSB0ZXh0IGNvbG9yLlxyXG4gICAgICB0aGlzLmN0eC50ZXh0QWxpZ24gPSAnY2VudGVyJzsgLy8gQWxpZ24gdGV4dCB0byB0aGUgY2VudGVyLlxyXG4gICAgICB0aGlzLmN0eC50ZXh0QmFzZWxpbmUgPSAnbWlkZGxlJzsgLy8gQWxpZ24gdGV4dCB2ZXJ0aWNhbGx5IGluIHRoZSBtaWRkbGUuXHJcbiAgICAgIHRoaXMuY3R4LmZpbGxUZXh0KFxyXG4gICAgICAgIGAke3Byb3BlcnRpZXMuZWxlbWVudFR5cGV9ICR7cHJvcGVydGllcy5lbGVtZW50TnVtYmVyfSAtICR7cHJvcGVydGllcy5kaXN0YW5jZX0gJHtwcm9wZXJ0aWVzLnVuaXR9YCxcclxuICAgICAgICAwLFxyXG4gICAgICAgIDBcclxuICAgICAgKTtcclxuICAgICAgdGhpcy5jdHgucmVzdG9yZSgpOyAvLyBSZXN0b3JlIHRoZSBwcmV2aW91cyBjYW52YXMgc3RhdGUuXHJcblxyXG4gICAgICBpZiAocHJvcGVydGllcy5kaXN0YW5jZSA+PSA0KSB7XHJcbiAgICAgICAgLy8gRGVmaW5lIHRoZSBtaWRwb2ludHMgb2YgdGhlIGxlZnQgYW5kIHJpZ2h0IGVkZ2VzIG9mIHRoZSBib3VuZGluZyBib3guXHJcbiAgICAgICAgY29uc3QgY2VudGVyWCA9IHRleHRYO1xyXG4gICAgICAgIGNvbnN0IGNlbnRlclkgPSB0ZXh0WTtcclxuICAgICAgICBjb25zdCByaWdodFggPSAoYm94UG9pbnRzWzFdLnggKyBib3hQb2ludHNbMl0ueCkgLyAyO1xyXG4gICAgICAgIGNvbnN0IHJpZ2h0WSA9IChib3hQb2ludHNbMV0ueSArIGJveFBvaW50c1syXS55KSAvIDI7XHJcbiAgICAgICAgY29uc3QgbGVmdFggPSAoYm94UG9pbnRzWzBdLnggKyBib3hQb2ludHNbM10ueCkgLyAyO1xyXG4gICAgICAgIGNvbnN0IGxlZnRZID0gKGJveFBvaW50c1swXS55ICsgYm94UG9pbnRzWzNdLnkpIC8gMjtcclxuXHJcbiAgICAgICAgLy8gSGVscGVyIGZ1bmN0aW9uIHRvIGFkanVzdCBwb2ludHMgYnkgYSBzcGVjaWZpYyBkaXN0YW5jZS5cclxuICAgICAgICBmdW5jdGlvbiBhZGp1c3RQb2ludCh4MTogYW55LCB5MTogYW55LCB4MjogYW55LCB5MjogYW55LCBkaXN0YW5jZTogYW55KSB7XHJcbiAgICAgICAgICBjb25zdCBhbmdsZSA9IE1hdGguYXRhbjIoeTIgLSB5MSwgeDIgLSB4MSk7IC8vIENhbGN1bGF0ZSB0aGUgYW5nbGUuXHJcbiAgICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgICB4OiB4MSArIE1hdGguY29zKGFuZ2xlKSAqIGRpc3RhbmNlLCAvLyBBZGp1c3QgWCBieSBkaXN0YW5jZS5cclxuICAgICAgICAgICAgeTogeTEgKyBNYXRoLnNpbihhbmdsZSkgKiBkaXN0YW5jZSwgLy8gQWRqdXN0IFkgYnkgZGlzdGFuY2UuXHJcbiAgICAgICAgICB9O1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy8gRGVmaW5lIHRoZSBhcnJvdyBsaW5lIHN0YXJ0IGFuZCBlbmQgcG9pbnRzIGZvciB0aGUgcmlnaHQgc2lkZS5cclxuICAgICAgICBjb25zdCByaWdodFN0YXJ0ID0gYWRqdXN0UG9pbnQoY2VudGVyWCwgY2VudGVyWSwgcmlnaHRYLCByaWdodFksIDUwKTtcclxuICAgICAgICBjb25zdCByaWdodEVuZCA9IGFkanVzdFBvaW50KHJpZ2h0WCwgcmlnaHRZLCBjZW50ZXJYLCBjZW50ZXJZLCAxMCk7XHJcblxyXG4gICAgICAgIC8vIERlZmluZSB0aGUgYXJyb3cgbGluZSBzdGFydCBhbmQgZW5kIHBvaW50cyBmb3IgdGhlIGxlZnQgc2lkZS5cclxuICAgICAgICBjb25zdCBsZWZ0U3RhcnQgPSBhZGp1c3RQb2ludChjZW50ZXJYLCBjZW50ZXJZLCBsZWZ0WCwgbGVmdFksIDUwKTtcclxuICAgICAgICBjb25zdCBsZWZ0RW5kID0gYWRqdXN0UG9pbnQobGVmdFgsIGxlZnRZLCBjZW50ZXJYLCBjZW50ZXJZLCAxMCk7XHJcblxyXG4gICAgICAgIC8vIERyYXcgdGhlIHJpZ2h0IGFycm93LlxyXG4gICAgICAgIHRoaXMuY3R4LmJlZ2luUGF0aCgpO1xyXG4gICAgICAgIHRoaXMuY3R4Lm1vdmVUbyhyaWdodFN0YXJ0LngsIHJpZ2h0U3RhcnQueSk7XHJcbiAgICAgICAgdGhpcy5jdHgubGluZVRvKHJpZ2h0RW5kLngsIHJpZ2h0RW5kLnkpO1xyXG4gICAgICAgIHRoaXMuY3R4LnN0cm9rZVN0eWxlID0gJ2JsYWNrJzsgLy8gU2V0IHRoZSBhcnJvdyBsaW5lIGNvbG9yLlxyXG4gICAgICAgIHRoaXMuY3R4LnN0cm9rZSgpOyAvLyBEcmF3IHRoZSBhcnJvdyBsaW5lLlxyXG4gICAgICAgIGxldCByaWdodEFuZ2xlID0gTWF0aC5hdGFuMihyaWdodEVuZC55IC0gcmlnaHRTdGFydC55LCByaWdodEVuZC54IC0gcmlnaHRTdGFydC54KTtcclxuICAgICAgICBkcmF3QXJyb3doZWFkKHRoaXMuY3R4LCByaWdodEVuZC54LCByaWdodEVuZC55LCByaWdodEFuZ2xlKTsgLy8gRHJhdyB0aGUgYXJyb3doZWFkLlxyXG5cclxuICAgICAgICAvLyBEcmF3IHRoZSBsZWZ0IGFycm93LlxyXG4gICAgICAgIHRoaXMuY3R4LmJlZ2luUGF0aCgpO1xyXG4gICAgICAgIHRoaXMuY3R4Lm1vdmVUbyhsZWZ0U3RhcnQueCwgbGVmdFN0YXJ0LnkpO1xyXG4gICAgICAgIHRoaXMuY3R4LmxpbmVUbyhsZWZ0RW5kLngsIGxlZnRFbmQueSk7XHJcbiAgICAgICAgdGhpcy5jdHguc3Ryb2tlU3R5bGUgPSAnYmxhY2snOyAvLyBTZXQgdGhlIGFycm93IGxpbmUgY29sb3IuXHJcbiAgICAgICAgdGhpcy5jdHguc3Ryb2tlKCk7IC8vIERyYXcgdGhlIGFycm93IGxpbmUuXHJcbiAgICAgICAgbGV0IGxlZnRBbmdsZSA9IE1hdGguYXRhbjIobGVmdEVuZC55IC0gbGVmdFN0YXJ0LnksIGxlZnRFbmQueCAtIGxlZnRTdGFydC54KTtcclxuICAgICAgICBkcmF3QXJyb3doZWFkKHRoaXMuY3R4LCBsZWZ0RW5kLngsIGxlZnRFbmQueSwgbGVmdEFuZ2xlKTsgLy8gRHJhdyB0aGUgYXJyb3doZWFkLlxyXG5cclxuICAgICAgfVxyXG5cclxuICAgICAgLy8gRm9yIEVudHJhbmNlXHJcbiAgICAgIGlmIChwcm9wZXJ0aWVzLmVsZW1lbnRUeXBlID09PSAnZW50cmFuY2UnKSB7XHJcbiAgICAgICAgLy8gQ2FsY3VsYXRlIHRoZSBhbmdsZSBvZiB0aGUgbWFpbiBsaW5lIChlZGdlKSBpbiByYWRpYW5zLlxyXG4gICAgICAgIGNvbnN0IGFuZ2xlID0gTWF0aC5hdGFuMihuZXh0UG9pbnQueSAtIHBvaW50LnksIG5leHRQb2ludC54IC0gcG9pbnQueCk7XHJcblxyXG4gICAgICAgIC8vIEFkZCAxNSBkZWdyZWVzIHRvIHRoZSBhbmdsZSBmb3IgdGhlIGVudHJhbmNlIGxpbmUuXHJcbiAgICAgICAgY29uc3QgZW50cmFuY2VBbmdsZSA9IGFuZ2xlICsgKDE1ICogTWF0aC5QSSkgLyAxODA7IC8vIENvbnZlcnQgMTUgZGVncmVlcyB0byByYWRpYW5zLlxyXG5cclxuICAgICAgICAvLyBEZWZpbmUgdGhlIGxlbmd0aCBvZiB0aGUgZW50cmFuY2UgbGluZS5cclxuICAgICAgICBjb25zdCBsaW5lTGVuZ3RoID0gdGhpcy5jb252ZXJ0VG9QaXhlbHMocHJvcGVydGllcy5kaXN0YW5jZSwgcHJvcGVydGllcy51bml0KSAqIDAuNzU7XHJcblxyXG4gICAgICAgIC8vIENhbGN1bGF0ZSB0aGUgZW5kcG9pbnQgb2YgdGhlIGVudHJhbmNlIGxpbmUgYmFzZWQgb24gdGhlIGFuZ2xlLlxyXG4gICAgICAgIGNvbnN0IGVuZFBvaW50ID0ge1xyXG4gICAgICAgICAgeDogcG9pbnQueCArIE1hdGguY29zKGVudHJhbmNlQW5nbGUpICogbGluZUxlbmd0aCxcclxuICAgICAgICAgIHk6IHBvaW50LnkgKyBNYXRoLnNpbihlbnRyYW5jZUFuZ2xlKSAqIGxpbmVMZW5ndGgsXHJcbiAgICAgICAgfTtcclxuXHJcbiAgICAgICAgLy8gRHJhdyB0aGUgZW50cmFuY2UgbGluZS5cclxuICAgICAgICB0aGlzLmN0eC5iZWdpblBhdGgoKTtcclxuICAgICAgICB0aGlzLmN0eC5tb3ZlVG8ocG9pbnQueCwgcG9pbnQueSk7XHJcbiAgICAgICAgdGhpcy5jdHgubGluZVRvKGVuZFBvaW50LngsIGVuZFBvaW50LnkpO1xyXG4gICAgICAgIHRoaXMuc2VsZWN0ZWRMaW5lSW5kZXggPT09IGVkZ2VJbmRleCA/IHRoaXMuY3R4LnN0cm9rZVN0eWxlID0gJyMwMDhFREYnIDogdGhpcy5jdHguc3Ryb2tlU3R5bGUgPSAnIzFEMjkzOSdcclxuICAgICAgICB0aGlzLmN0eC5zdHJva2UoKTtcclxuICAgICAgfVxyXG5cclxuXHJcbiAgICB9KTtcclxuXHJcbiAgICB0aGlzLmN0eC5yZXN0b3JlKCk7IC8vIFJlc3RvcmUgdGhlIG9yaWdpbmFsIGNhbnZhcyBzdGF0ZS5cclxuICB9XHJcblxyXG4gIEBIb3N0TGlzdGVuZXIoJ3doZWVsJywgWyckZXZlbnQnXSlcclxuICBvbk1vdXNlV2hlZWwoZXZlbnQ6IFdoZWVsRXZlbnQpIHtcclxuICAgIGlmIChldmVudC5jdHJsS2V5KSB7XHJcbiAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XHJcbiAgICAgIGNvbnN0IHNjYWxlRmFjdG9yID0gZXZlbnQuZGVsdGFZIDwgMCA/IDEuMDEgOiAxIC8gMS4wMTtcclxuICAgICAgdGhpcy5hZGp1c3Rab29tKGV2ZW50LCBzY2FsZUZhY3Rvcik7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBhZGp1c3Rab29tKGV2ZW50OiBNb3VzZUV2ZW50LCBzY2FsZUZhY3RvcjogbnVtYmVyKTogdm9pZCB7XHJcbiAgICBjb25zdCByZWN0ID0gdGhpcy5jYW52YXMuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XHJcblxyXG4gICAgY29uc3QgbW91c2VYID0gKGV2ZW50LmNsaWVudFggLSByZWN0LmxlZnQgLSB0aGlzLnBhbk9mZnNldC54KSAvIHRoaXMuc2NhbGU7XHJcbiAgICBjb25zdCBtb3VzZVkgPSAoZXZlbnQuY2xpZW50WSAtIHJlY3QudG9wIC0gdGhpcy5wYW5PZmZzZXQueSkgLyB0aGlzLnNjYWxlO1xyXG5cclxuICAgIHRoaXMuc2NhbGUgKj0gc2NhbGVGYWN0b3I7XHJcblxyXG4gICAgdGhpcy5wYW5PZmZzZXQueCAtPSBtb3VzZVggKiAoc2NhbGVGYWN0b3IgLSAxKSAqIHRoaXMuc2NhbGU7XHJcbiAgICB0aGlzLnBhbk9mZnNldC55IC09IG1vdXNlWSAqIChzY2FsZUZhY3RvciAtIDEpICogdGhpcy5zY2FsZTtcclxuXHJcbiAgICB0aGlzLnJlZHJhd0NhbnZhcygpO1xyXG4gIH1cclxuXHJcbiAgcmVzZXRab29tKCk6IHZvaWQge1xyXG4gICAgdGhpcy5zY2FsZSA9IDE7XHJcbiAgICB0aGlzLnBhbk9mZnNldCA9IHsgeDogMCwgeTogMCB9O1xyXG4gICAgdGhpcy5yZWRyYXdDYW52YXMoKTtcclxuICB9XHJcblxyXG5cclxuXHJcbiAgdHJhbnNmb3JtUG9pbnQocG9pbnQ6IHsgeDogbnVtYmVyOyB5OiBudW1iZXIgfSk6IHsgeDogbnVtYmVyOyB5OiBudW1iZXIgfSB7XHJcbiAgICByZXR1cm4ge1xyXG4gICAgICB4OiBwb2ludC54ICogdGhpcy5zY2FsZSArIHRoaXMucGFuT2Zmc2V0LngsXHJcbiAgICAgIHk6IHBvaW50LnkgKiB0aGlzLnNjYWxlICsgdGhpcy5wYW5PZmZzZXQueSxcclxuICAgIH07XHJcbiAgfVxyXG5cclxuICBkcmF3TGluZShjdHg6IENhbnZhc1JlbmRlcmluZ0NvbnRleHQyRCwgbGluZTogeyB4OiBudW1iZXI7IHk6IG51bWJlciB9W10pOiB2b2lkIHtcclxuICAgIGlmIChsaW5lLmxlbmd0aCA8IDIpIHJldHVybjtcclxuXHJcbiAgICBjdHguYmVnaW5QYXRoKCk7XHJcbiAgICBjdHgubW92ZVRvKGxpbmVbMF0ueCwgbGluZVswXS55KTtcclxuICAgIGZvciAobGV0IGkgPSAxOyBpIDwgbGluZS5sZW5ndGg7IGkrKykge1xyXG4gICAgICBjdHgubGluZVRvKGxpbmVbaV0ueCwgbGluZVtpXS55KTtcclxuICAgIH1cclxuICAgIGN0eC5zdHJva2UoKTtcclxuICB9XHJcblxyXG5cclxuXHJcblxyXG4gIHJlZHJhd0NhbnZhcygpOiB2b2lkIHtcclxuICAgIHRoaXMuZHJhd0dyaWQoKTtcclxuICAgIHRoaXMuZHJhd1BvbHlnb24oKTtcclxuICB9XHJcblxyXG5cclxuXHJcblxyXG4gIEBIb3N0TGlzdGVuZXIoJ2RvY3VtZW50OmNsaWNrJywgWyckZXZlbnQnXSlcclxuICBvbk91dHNpZGVDbGljayhldmVudDogTW91c2VFdmVudCk6IHZvaWQge1xyXG4gICAgY29uc3QgY2xpY2tlZEluc2lkZTEgPSAoZXZlbnQudGFyZ2V0IGFzIEhUTUxFbGVtZW50KS5jbG9zZXN0KCcuZWxpcHNpcy1pY29uLWRyb3Bkb3duJyk7XHJcbiAgICBpZiAoIWNsaWNrZWRJbnNpZGUxKSB7XHJcbiAgICAgIHRoaXMubGluZU9wdGlvbnNTZWxlY3QgPSB7IHNob3c6IGZhbHNlLCBpbmRleDogMCB9O1xyXG4gICAgfVxyXG5cclxuICAgIGNvbnN0IGNsaWNrZWRJbnNpZGUyID0gKGV2ZW50LnRhcmdldCBhcyBIVE1MRWxlbWVudCkuY2xvc2VzdCgnLmRpcmVjdGlvbi1kcm9wZG93bicpO1xyXG4gICAgaWYgKCFjbGlja2VkSW5zaWRlMikge1xyXG4gICAgICB0aGlzLmRpcmVjdGlvblNlbGVjdCA9IHsgc2hvdzogZmFsc2UsIGluZGV4OiAwIH07XHJcbiAgICB9XHJcblxyXG4gICAgY29uc3QgY2xpY2tlZEluc2lkZTMgPSAoZXZlbnQudGFyZ2V0IGFzIEhUTUxFbGVtZW50KS5jbG9zZXN0KCcuZWxlbWVudC10eXBlLWRyb3Bkb3duJyk7XHJcbiAgICBpZiAoIWNsaWNrZWRJbnNpZGUzKSB7XHJcbiAgICAgIHRoaXMuZWxlbWVudFNlbGVjdCA9IHsgc2hvdzogZmFsc2UsIGluZGV4OiAwIH07XHJcbiAgICB9XHJcblxyXG4gICAgY29uc3QgY2xpY2tlZEluc2lkZTQgPSAoZXZlbnQudGFyZ2V0IGFzIEhUTUxFbGVtZW50KS5jbG9zZXN0KCcud2lkZ2V0LWVsZW1lbnQtdHlwZS1kcm9wZG93bicpO1xyXG4gICAgaWYgKCFjbGlja2VkSW5zaWRlNCkge1xyXG4gICAgICB0aGlzLndpZGdldEVsZW1lbnRTZWxlY3QgPSB7IHNob3c6IGZhbHNlIH07XHJcbiAgICB9XHJcblxyXG4gICAgY29uc3QgY2xpY2tlZEluc2lkZTUgPSAoZXZlbnQudGFyZ2V0IGFzIEhUTUxFbGVtZW50KS5jbG9zZXN0KCcudG9wLWVsaXBzaXMtbWVudScpO1xyXG4gICAgaWYgKCFjbGlja2VkSW5zaWRlNSkge1xyXG4gICAgICB0aGlzLmxheW91dE9wdGlvblNlbGVjdCA9IHsgc2hvdzogZmFsc2UgfTtcclxuICAgIH1cclxuXHJcbiAgICBjb25zdCBjbGlja2VkSW5zaWRlNiA9IChldmVudC50YXJnZXQgYXMgSFRNTEVsZW1lbnQpLmNsb3Nlc3QoJy5mbG9vci1zZWxlY3QnKTtcclxuICAgIGlmICghY2xpY2tlZEluc2lkZTYpIHtcclxuICAgICAgdGhpcy5mbG9vclNlbGVjdCA9IHsgc2hvdzogZmFsc2UsIGRlbGV0ZUluZGV4OiBudWxsIH07XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICB0b2dnbGVMaW5lT3B0aW9uc1NlbGVjdChpbmRleDogbnVtYmVyKTogdm9pZCB7XHJcbiAgICB0aGlzLmxpbmVPcHRpb25zU2VsZWN0ID0ge1xyXG4gICAgICBzaG93OiB0aGlzLmxpbmVPcHRpb25zU2VsZWN0LmluZGV4ICE9PSBpbmRleCB8fCAhdGhpcy5saW5lT3B0aW9uc1NlbGVjdC5zaG93LFxyXG4gICAgICBpbmRleCxcclxuICAgIH07XHJcbiAgfVxyXG5cclxuICB0b2dnbGVEaXJlY3Rpb25TZWxlY3QoaW5kZXg6IG51bWJlcik6IHZvaWQge1xyXG4gICAgdGhpcy5kaXJlY3Rpb25TZWxlY3QgPSB7XHJcbiAgICAgIHNob3c6IHRoaXMuZGlyZWN0aW9uU2VsZWN0LmluZGV4ICE9PSBpbmRleCB8fCAhdGhpcy5kaXJlY3Rpb25TZWxlY3Quc2hvdyxcclxuICAgICAgaW5kZXgsXHJcbiAgICB9O1xyXG4gIH1cclxuXHJcbiAgdG9nZ2xlRWxlbWVudFNlbGVjdChpbmRleDogbnVtYmVyKTogdm9pZCB7XHJcbiAgICB0aGlzLmVsZW1lbnRTZWxlY3QgPSB7XHJcbiAgICAgIHNob3c6IHRoaXMuZWxlbWVudFNlbGVjdC5pbmRleCAhPT0gaW5kZXggfHwgIXRoaXMuZWxlbWVudFNlbGVjdC5zaG93LFxyXG4gICAgICBpbmRleCxcclxuICAgIH07XHJcbiAgfVxyXG5cclxuICB0b2dnbGVXaWRnZXRFbGVtZW50U2VsZWN0KCk6IHZvaWQge1xyXG4gICAgdGhpcy53aWRnZXRFbGVtZW50U2VsZWN0ID0ge1xyXG4gICAgICBzaG93OiAhdGhpcy53aWRnZXRFbGVtZW50U2VsZWN0LnNob3csXHJcbiAgICB9O1xyXG4gIH1cclxuXHJcbiAgdG9nZ2xlTGF5b3V0T3B0aW9uU2VsZWN0KCk6IHZvaWQge1xyXG4gICAgdGhpcy5sYXlvdXRPcHRpb25TZWxlY3QgPSB7XHJcbiAgICAgIHNob3c6ICF0aGlzLmxheW91dE9wdGlvblNlbGVjdC5zaG93LFxyXG4gICAgfTtcclxuICB9XHJcblxyXG4gIHRvZ2dsZUZsb29yU2VsZWN0KCk6IHZvaWQge1xyXG4gICAgdGhpcy5mbG9vclNlbGVjdCA9IHtcclxuICAgICAgc2hvdzogIXRoaXMuZmxvb3JTZWxlY3Quc2hvdyxcclxuICAgICAgZGVsZXRlSW5kZXg6IG51bGxcclxuICAgIH07XHJcbiAgfVxyXG5cclxuXHJcbiAgZHJvcChldmVudDogQ2RrRHJhZ0Ryb3A8YW55W10+KSB7XHJcblxyXG4gICAgdGhpcy5zYXZlU3RhdGVUb1VuZG8oKVxyXG4gICAgbW92ZUl0ZW1JbkFycmF5KHRoaXMubGF5b3V0UG9seWdvbiwgZXZlbnQucHJldmlvdXNJbmRleCwgZXZlbnQuY3VycmVudEluZGV4KTtcclxuXHJcbiAgICBjb25zdCBpbnN0cnVjdGlvbnMgPSB0aGlzLmxheW91dFBvbHlnb24ubWFwKChzZWdtZW50KSA9PiB7XHJcbiAgICAgIGNvbnN0IFtwb2ludDEsIHBvaW50MiwgcHJvcGVydGllc10gPSBzZWdtZW50XHJcbiAgICAgIHJldHVybiBwcm9wZXJ0aWVzXHJcbiAgICB9KVxyXG5cclxuICAgIHRoaXMuZ2VuZXJhdGVMYXlvdXRQb2x5Z29uKGluc3RydWN0aW9ucylcclxuICAgIHRoaXMucmVkb1N0YWNrID0gW107XHJcblxyXG5cclxuICB9XHJcblxyXG5cclxuICBzbmFwVG9HcmlkKHZhbHVlOiBudW1iZXIsIGdyaWRTaXplOiBudW1iZXIpOiBudW1iZXIge1xyXG4gICAgcmV0dXJuIE1hdGgucm91bmQodmFsdWUgLyBncmlkU2l6ZSkgKiBncmlkU2l6ZTtcclxuICB9XHJcblxyXG4gIGlzUG9pbnRJblBvbHlnb24ocG9pbnQ6IGFueSwgcG9seWdvbjogYW55W10pOiBib29sZWFuIHtcclxuICAgIGxldCB7IHgsIHkgfSA9IHBvaW50O1xyXG4gICAgbGV0IGluc2lkZSA9IGZhbHNlO1xyXG5cclxuICAgIGZvciAobGV0IGkgPSAwLCBqID0gcG9seWdvbi5sZW5ndGggLSAxOyBpIDwgcG9seWdvbi5sZW5ndGg7IGogPSBpKyspIHtcclxuICAgICAgY29uc3QgeGkgPSBwb2x5Z29uW2ldLngsIHlpID0gcG9seWdvbltpXS55O1xyXG4gICAgICBjb25zdCB4aiA9IHBvbHlnb25bal0ueCwgeWogPSBwb2x5Z29uW2pdLnk7XHJcblxyXG4gICAgICBjb25zdCBvbkVkZ2UgPVxyXG4gICAgICAgICh5IC0geWkpICogKHhqIC0geGkpID09PSAoeCAtIHhpKSAqICh5aiAtIHlpKSAmJlxyXG4gICAgICAgIE1hdGgubWluKHhpLCB4aikgPD0geCAmJiB4IDw9IE1hdGgubWF4KHhpLCB4aikgJiZcclxuICAgICAgICBNYXRoLm1pbih5aSwgeWopIDw9IHkgJiYgeSA8PSBNYXRoLm1heCh5aSwgeWopO1xyXG5cclxuICAgICAgaWYgKG9uRWRnZSkge1xyXG4gICAgICAgIHJldHVybiB0cnVlO1xyXG4gICAgICB9XHJcblxyXG4gICAgICBjb25zdCBpbnRlcnNlY3QgPSAoKHlpID4geSkgIT09ICh5aiA+IHkpKSAmJlxyXG4gICAgICAgICh4IDwgKHhqIC0geGkpICogKHkgLSB5aSkgLyAoeWogLSB5aSkgKyB4aSk7XHJcbiAgICAgIGlmIChpbnRlcnNlY3QpIGluc2lkZSA9ICFpbnNpZGU7XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIGluc2lkZTtcclxuICB9XHJcblxyXG5cclxuICBtb3ZlUG9pbnRXaXRoQW5nbGUoKTogdm9pZCB7XHJcbiAgICBpZiAodGhpcy5tb3ZlUGl4ZWxzIDw9IDApIHJldHVybjtcclxuXHJcbiAgICB0aGlzLnNhdmVTdGF0ZVRvVW5kbygpXHJcblxyXG4gICAgbGV0IHJhZGlhbnM6IG51bWJlcjtcclxuXHJcbiAgICBzd2l0Y2ggKHRoaXMubW92ZURpcmVjdGlvbikge1xyXG4gICAgICBjYXNlICd1cCc6XHJcbiAgICAgICAgcmFkaWFucyA9ICgoMTgwIC0gdGhpcy5tb3ZlQW5nbGUpICogTWF0aC5QSSkgLyAxODA7XHJcbiAgICAgICAgYnJlYWs7XHJcbiAgICAgIGNhc2UgJ2xlZnQnOlxyXG4gICAgICAgIHJhZGlhbnMgPSAoKDI3MCAtIHRoaXMubW92ZUFuZ2xlKSAqIE1hdGguUEkpIC8gMTgwO1xyXG4gICAgICAgIGJyZWFrO1xyXG4gICAgICBjYXNlICdkb3duJzpcclxuICAgICAgICByYWRpYW5zID0gKCgzNjAgLSB0aGlzLm1vdmVBbmdsZSkgKiBNYXRoLlBJKSAvIDE4MDtcclxuICAgICAgICBicmVhaztcclxuICAgICAgY2FzZSAncmlnaHQnOlxyXG4gICAgICAgIHJhZGlhbnMgPSAoKDkwIC0gdGhpcy5tb3ZlQW5nbGUpICogTWF0aC5QSSkgLyAxODA7XHJcbiAgICAgICAgYnJlYWs7XHJcbiAgICAgIGRlZmF1bHQ6XHJcbiAgICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG5cclxuICAgIGlmICh0aGlzLnNlbGVjdGVkTGluZSkge1xyXG4gICAgICBjb25zdCBsaW5lSW5kZXggPSAoKGFycmF5MSA9IHRoaXMubGF5b3V0UG9seWdvbiwgYXJyYXkyID0gdGhpcy5zZWxlY3RlZExpbmUpID0+IHtcclxuICAgICAgICByZXR1cm4gYXJyYXkxLmZpbmRJbmRleChpbm5lckFycmF5ID0+XHJcbiAgICAgICAgICBpbm5lckFycmF5Lmxlbmd0aCA9PT0gYXJyYXkyLmxlbmd0aCAmJlxyXG4gICAgICAgICAgaW5uZXJBcnJheS5ldmVyeSgoaXRlbTogYW55LCBpbmRleDogYW55KSA9PiBKU09OLnN0cmluZ2lmeShpdGVtKSA9PT0gSlNPTi5zdHJpbmdpZnkoYXJyYXkyW2luZGV4XSkpXHJcbiAgICAgICAgKTtcclxuICAgICAgfSkoKTtcclxuXHJcbiAgICAgIGNvbnN0IFtzdGFydCwgZW5kLCBwcm9wZXJ0aWVzXSA9IHRoaXMubGF5b3V0UG9seWdvbltsaW5lSW5kZXhdO1xyXG4gICAgICBjb25zdCBuZXdYID0gc3RhcnQueCArIE1hdGguY29zKHJhZGlhbnMpICogdGhpcy5jb252ZXJ0VG9QaXhlbHModGhpcy5tb3ZlUGl4ZWxzLCB0aGlzLnVuaXQpO1xyXG4gICAgICBjb25zdCBuZXdZID0gc3RhcnQueSAtIE1hdGguc2luKHJhZGlhbnMpICogdGhpcy5jb252ZXJ0VG9QaXhlbHModGhpcy5tb3ZlUGl4ZWxzLCB0aGlzLnVuaXQpO1xyXG5cclxuICAgICAgY29uc3Qgc25hcHBlZFggPSB0aGlzLnNuYXBUb0dyaWQobmV3WCwgdGhpcy5ncmlkV2lkdGgpO1xyXG4gICAgICBjb25zdCBzbmFwcGVkWSA9IHRoaXMuc25hcFRvR3JpZChuZXdZLCB0aGlzLmdyaWRIZWlnaHQpO1xyXG5cclxuICAgICAgdGhpcy5sYXlvdXRQb2x5Z29uW2xpbmVJbmRleF1bMV0ueCA9IHNuYXBwZWRYO1xyXG4gICAgICB0aGlzLmxheW91dFBvbHlnb25bbGluZUluZGV4XVsxXS55ID0gc25hcHBlZFk7XHJcbiAgICAgIHRoaXMubGF5b3V0UG9seWdvbltsaW5lSW5kZXhdWzJdLmFuZ2xlID0gdGhpcy5tb3ZlQW5nbGU7XHJcbiAgICAgIHRoaXMubGF5b3V0UG9seWdvbltsaW5lSW5kZXhdWzJdLmRpcmVjdGlvbiA9IHRoaXMubW92ZURpcmVjdGlvbjtcclxuICAgICAgdGhpcy5sYXlvdXRQb2x5Z29uW2xpbmVJbmRleF1bMl0uZGlzdGFuY2UgPSB0aGlzLm1vdmVQaXhlbHM7XHJcbiAgICAgIHRoaXMubGF5b3V0UG9seWdvbltsaW5lSW5kZXhdWzJdLmVsZW1lbnRUeXBlID0gdGhpcy5lbGVtZW50VHlwZTtcclxuXHJcbiAgICAgIHRoaXMucmVkcmF3Q2FudmFzKClcclxuICAgICAgdGhpcy5jbG9zZVdpZGdldCgpXHJcbiAgICAgIHRoaXMuc2VsZWN0ZWRMaW5lID0gbnVsbFxyXG5cclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIGNvbnN0IGxhc3RMaW5lID0gdGhpcy5sYXlvdXRQb2x5Z29uW3RoaXMubGF5b3V0UG9seWdvbi5sZW5ndGggLSAxXTtcclxuICAgICAgY29uc3QgbmV3WCA9IGxhc3RMaW5lWzFdLnggKyBNYXRoLmNvcyhyYWRpYW5zKSAqIHRoaXMuY29udmVydFRvUGl4ZWxzKHRoaXMubW92ZVBpeGVscywgdGhpcy51bml0KTtcclxuICAgICAgY29uc3QgbmV3WSA9IGxhc3RMaW5lWzFdLnkgLSBNYXRoLnNpbihyYWRpYW5zKSAqIHRoaXMuY29udmVydFRvUGl4ZWxzKHRoaXMubW92ZVBpeGVscywgdGhpcy51bml0KTtcclxuXHJcbiAgICAgIGNvbnN0IHNuYXBwZWRYID0gdGhpcy5zbmFwVG9HcmlkKG5ld1gsIHRoaXMuZ3JpZFdpZHRoKTtcclxuICAgICAgY29uc3Qgc25hcHBlZFkgPSB0aGlzLnNuYXBUb0dyaWQobmV3WSwgdGhpcy5ncmlkSGVpZ2h0KTtcclxuXHJcbiAgICAgIGNvbnN0IG5ld1BvaW50ID0geyB4OiBzbmFwcGVkWCwgeTogc25hcHBlZFkgfTtcclxuXHJcblxyXG4gICAgICBpZiAodGhpcy5sYXlvdXRQb2x5Z29uLmxlbmd0aCA+IDApIHtcclxuICAgICAgICBjb25zdCBsYXN0UG9pbnQgPSBsYXN0TGluZVsxXTtcclxuICAgICAgICBjb25zdCBmaXJzdFBvaW50ID0gdGhpcy5sYXlvdXRQb2x5Z29uWzBdWzBdO1xyXG5cclxuXHJcbiAgICAgICAgaWYgKG5ld1BvaW50LnggPT09IGZpcnN0UG9pbnQueCAmJiBuZXdQb2ludC55ID09PSBmaXJzdFBvaW50LnkpIHtcclxuICAgICAgICAgIHRoaXMubGF5b3V0UG9seWdvbi5wdXNoKFtsYXN0UG9pbnQsIG5ld1BvaW50LCB7IGVsZW1lbnRUeXBlOiB0aGlzLmVsZW1lbnRUeXBlLCBkaXN0YW5jZTogdGhpcy5tb3ZlUGl4ZWxzLCB1bml0OiB0aGlzLnVuaXQsIGRpcmVjdGlvbjogdGhpcy5tb3ZlRGlyZWN0aW9uLCBhbmdsZTogdGhpcy5tb3ZlQW5nbGUsIGVsZW1lbnROdW1iZXI6IHRoaXMuZ2V0TWF4RWxlbWVudE51bWJlcih0aGlzLmxheW91dFBvbHlnb24sIHRoaXMuZWxlbWVudFR5cGUpIH1dKTtcclxuICAgICAgICAgIHRoaXMuY2xvc2VXaWRnZXQoKVxyXG5cclxuICAgICAgICB9IGVsc2UgaWYgKFxyXG4gICAgICAgICAgIXRoaXMubGF5b3V0UG9seWdvbi5zb21lKGxpbmUgPT5cclxuICAgICAgICAgICAgKGxpbmVbMF0ueCA9PT0gbmV3UG9pbnQueCAmJiBsaW5lWzBdLnkgPT09IG5ld1BvaW50LnkpIHx8XHJcbiAgICAgICAgICAgIChsaW5lWzFdLnggPT09IG5ld1BvaW50LnggJiYgbGluZVsxXS55ID09PSBuZXdQb2ludC55KVxyXG4gICAgICAgICAgKVxyXG4gICAgICAgICkge1xyXG4gICAgICAgICAgaWYgKHRoaXMubGF5b3V0UG9seWdvbi5sZW5ndGggPT09IDEgJiYgdGhpcy5sYXlvdXRQb2x5Z29uWzBdWzBdLnggPT09IHRoaXMubGF5b3V0UG9seWdvblswXVsxXS54ICYmIHRoaXMubGF5b3V0UG9seWdvblswXVswXS55ID09PSB0aGlzLmxheW91dFBvbHlnb25bMF1bMV0ueSkge1xyXG4gICAgICAgICAgICB0aGlzLmxheW91dFBvbHlnb25bMF0gPSBbdGhpcy5sYXlvdXRQb2x5Z29uWzBdWzBdLCBuZXdQb2ludCwgeyBlbGVtZW50VHlwZTogdGhpcy5lbGVtZW50VHlwZSwgZGlzdGFuY2U6IHRoaXMubW92ZVBpeGVscywgdW5pdDogdGhpcy51bml0LCBkaXJlY3Rpb246IHRoaXMubW92ZURpcmVjdGlvbiwgYW5nbGU6IHRoaXMubW92ZUFuZ2xlLCBlbGVtZW50TnVtYmVyOiAxIH1dXHJcbiAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICB0aGlzLmxheW91dFBvbHlnb24ucHVzaChbbGFzdFBvaW50LCBuZXdQb2ludCwgeyBlbGVtZW50VHlwZTogdGhpcy5lbGVtZW50VHlwZSwgZGlzdGFuY2U6IHRoaXMubW92ZVBpeGVscywgdW5pdDogdGhpcy51bml0LCBkaXJlY3Rpb246IHRoaXMubW92ZURpcmVjdGlvbiwgYW5nbGU6IHRoaXMubW92ZUFuZ2xlLCBlbGVtZW50TnVtYmVyOiB0aGlzLmdldE1heEVsZW1lbnROdW1iZXIodGhpcy5sYXlvdXRQb2x5Z29uLCB0aGlzLmVsZW1lbnRUeXBlKSB9XSk7XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgICB0aGlzLm9wZW5XaWRnZXQobmV3UG9pbnQpXHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcblxyXG4gICAgICB0aGlzLnJlZG9TdGFjayA9IFtdO1xyXG5cclxuICAgICAgdGhpcy5jZC5kZXRlY3RDaGFuZ2VzKCk7XHJcbiAgICAgIHRoaXMucmVkcmF3Q2FudmFzKClcclxuICAgIH1cclxuXHJcblxyXG4gIH1cclxuXHJcbiAgZ2V0TWF4RWxlbWVudE51bWJlcihkYXRhOiBhbnksIGVsZW1lbnRUeXBlOiBzdHJpbmcpIHtcclxuICAgIGlmICghQXJyYXkuaXNBcnJheShkYXRhKSkge1xyXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJJbnZhbGlkIGRhdGEgZm9ybWF0OiBkYXRhIHNob3VsZCBiZSBhbiBhcnJheS5cIik7XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIE1hdGgucm91bmQoZGF0YS5yZWR1Y2UoKG1heE51bWJlciwgc2VnbWVudCkgPT4ge1xyXG4gICAgICBpZiAoQXJyYXkuaXNBcnJheShzZWdtZW50KSkge1xyXG4gICAgICAgIGNvbnN0IGVsZW1lbnQgPSBzZWdtZW50LmZpbmQoaXRlbSA9PiBpdGVtLmVsZW1lbnRUeXBlID09PSBlbGVtZW50VHlwZSk7XHJcbiAgICAgICAgaWYgKGVsZW1lbnQgJiYgdHlwZW9mIGVsZW1lbnQuZWxlbWVudE51bWJlciA9PT0gJ251bWJlcicpIHtcclxuICAgICAgICAgIG1heE51bWJlciA9IE1hdGgubWF4KG1heE51bWJlciwgZWxlbWVudC5lbGVtZW50TnVtYmVyKTtcclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuICAgICAgcmV0dXJuIG1heE51bWJlcjtcclxuICAgIH0sIDApKSArIDE7XHJcbiAgfVxyXG5cclxuICBvbk1vdXNlRG93bihldmVudDogTW91c2VFdmVudCk6IHZvaWQge1xyXG4gICAgY29uc3QgcmVjdCA9IHRoaXMuY2FudmFzLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xyXG4gICAgY29uc3QgbW91c2VYID0gZXZlbnQuY2xpZW50WCAtIHJlY3QubGVmdDtcclxuICAgIGNvbnN0IG1vdXNlWSA9IGV2ZW50LmNsaWVudFkgLSByZWN0LnRvcDtcclxuXHJcblxyXG4gICAgZm9yIChjb25zdCBsaW5lIG9mIHRoaXMubGF5b3V0UG9seWdvbikge1xyXG4gICAgICBjb25zdCBwb2ludCA9IGxpbmVbMF07XHJcbiAgICAgIGNvbnN0IG5leHRQb2ludCA9IGxpbmVbMV07XHJcblxyXG4gICAgICBjb25zdCBkeCA9IG5leHRQb2ludC54IC0gcG9pbnQueDtcclxuICAgICAgY29uc3QgZHkgPSBuZXh0UG9pbnQueSAtIHBvaW50Lnk7XHJcbiAgICAgIGNvbnN0IGxlbmd0aCA9IE1hdGguc3FydChkeCAqIGR4ICsgZHkgKiBkeSk7XHJcbiAgICAgIGNvbnN0IG9mZnNldFggPSAoZHkgLyBsZW5ndGgpICogMjA7XHJcbiAgICAgIGNvbnN0IG9mZnNldFkgPSAoLWR4IC8gbGVuZ3RoKSAqIDIwO1xyXG5cclxuICAgICAgY29uc3QgYm94Q29ybmVycyA9IFtcclxuICAgICAgICB7IHg6IHBvaW50LngsIHk6IHBvaW50LnkgfSxcclxuICAgICAgICB7IHg6IG5leHRQb2ludC54LCB5OiBuZXh0UG9pbnQueSB9LFxyXG4gICAgICAgIHsgeDogbmV4dFBvaW50LnggKyBvZmZzZXRYLCB5OiBuZXh0UG9pbnQueSArIG9mZnNldFkgfSxcclxuICAgICAgICB7IHg6IHBvaW50LnggKyBvZmZzZXRYLCB5OiBwb2ludC55ICsgb2Zmc2V0WSB9XHJcbiAgICAgIF07XHJcblxyXG4gICAgICBpZiAodGhpcy5pc1BvaW50SW5Qb2x5Z29uKHsgeDogbW91c2VYLCB5OiBtb3VzZVkgfSwgYm94Q29ybmVycykpIHtcclxuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMubGF5b3V0UG9seWdvbi5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgY29uc3QgW3N0YXJ0LCBlbmQsIHByb3BlcnRpZXNdID0gdGhpcy5sYXlvdXRQb2x5Z29uW2ldO1xyXG4gICAgICAgICAgaWYgKHRoaXMuaXNMaW5lRXF1YWwoc3RhcnQsIGVuZCwgYm94Q29ybmVyc1swXSwgYm94Q29ybmVyc1sxXSwgMCkpIHtcclxuICAgICAgICAgICAgdGhpcy5zZWxlY3RMaW5lKGxpbmUsIGkpO1xyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHRoaXMubGF5b3V0UG9seWdvbi5sZW5ndGggPT09IDEgJiYgdGhpcy5sYXlvdXRQb2x5Z29uWzBdWzBdLnggPT09IHRoaXMubGF5b3V0UG9seWdvblswXVsxXS54ICYmIHRoaXMubGF5b3V0UG9seWdvblswXVswXS55ID09PSB0aGlzLmxheW91dFBvbHlnb25bMF1bMV0ueSkge1xyXG4gICAgICByZXR1cm5cclxuICAgIH1cclxuXHJcbiAgICB0aGlzLnNlbGVjdGVkTGluZSA9IG51bGxcclxuICAgIHRoaXMuc2VsZWN0ZWRMaW5lSW5kZXggPSBudWxsXHJcbiAgICB0aGlzLnJlZHJhd0NhbnZhcygpXHJcbiAgICB0aGlzLmNsb3NlV2lkZ2V0KClcclxuICB9XHJcblxyXG5cclxuICBzZWxlY3RMaW5lKGxpbmU6IGFueSwgaW5kZXg6IG51bWJlcikge1xyXG4gICAgY29uc3QgW3N0YXJ0LCBlbmQsIHByb3BlcnRpZXNdID0gbGluZVxyXG5cclxuICAgIHRoaXMuc2VsZWN0ZWRMaW5lID0gbGluZVxyXG4gICAgdGhpcy5zZWxlY3RlZExpbmVJbmRleCA9IGluZGV4XHJcbiAgICB0aGlzLmVsZW1lbnRUeXBlID0gcHJvcGVydGllcy5lbGVtZW50VHlwZVxyXG4gICAgdGhpcy5tb3ZlUGl4ZWxzID0gcHJvcGVydGllcy5kaXN0YW5jZVxyXG4gICAgdGhpcy5tb3ZlRGlyZWN0aW9uID0gcHJvcGVydGllcy5kaXJlY3Rpb25cclxuICAgIHRoaXMubW92ZUFuZ2xlID0gcHJvcGVydGllcy5hbmdsZVxyXG4gICAgdGhpcy51bml0ID0gcHJvcGVydGllcy51bml0XHJcbiAgICB0aGlzLm9wZW5XaWRnZXQoZW5kKVxyXG4gICAgdGhpcy5yZWRyYXdDYW52YXMoKVxyXG4gIH1cclxuXHJcbiAgb3BlbldpZGdldChwb3NpdGlvbjogeyB4OiBudW1iZXIsIHk6IG51bWJlciB9LCBvZmZzZXQgPSB7IHVwOiAwLCByaWdodDogNSwgZG93bjogMTUsIGxlZnQ6IDAsIH0pIHtcclxuICAgIHRoaXMucG9wdXBWaXNpYmxlID0gdHJ1ZVxyXG4gICAgY29uc3QgYWRqdXN0ZWRQb3NpdGlvbiA9IHtcclxuICAgICAgeDogcG9zaXRpb24ueCArIG9mZnNldC5yaWdodCArIG9mZnNldC5sZWZ0LFxyXG4gICAgICB5OiBwb3NpdGlvbi55ICsgb2Zmc2V0LnVwICsgb2Zmc2V0LmRvd24sXHJcbiAgICB9O1xyXG5cclxuICAgIHRoaXMucG9wdXBQb3NpdGlvbiA9IGFkanVzdGVkUG9zaXRpb25cclxuICAgIHRoaXMuc2Nyb2xsVG9DYW52YXNQb3NpdGlvbihhZGp1c3RlZFBvc2l0aW9uKVxyXG4gICAgc2V0VGltZW91dCgoKSA9PiB7XHJcbiAgICAgIHRoaXMuZHJhd1dpZGdldFJpbmcoKVxyXG4gICAgICB0aGlzLnVwZGF0ZVdpZGdldFBvaW50ZXIoKVxyXG4gICAgfSwgNTAwKTtcclxuXHJcbiAgfVxyXG5cclxuICBjbG9zZVdpZGdldCgpIHtcclxuICAgIHRoaXMucG9wdXBWaXNpYmxlID0gZmFsc2VcclxuICB9XHJcblxyXG4gIG9uTW91c2VNb3ZlKGV2ZW50OiBNb3VzZUV2ZW50KTogdm9pZCB7XHJcbiAgICBjb25zdCByZWN0ID0gdGhpcy5jYW52YXMuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XHJcbiAgICBjb25zdCBtb3VzZVggPSBldmVudC5jbGllbnRYIC0gcmVjdC5sZWZ0O1xyXG4gICAgY29uc3QgbW91c2VZID0gZXZlbnQuY2xpZW50WSAtIHJlY3QudG9wO1xyXG5cclxuICAgIGxldCBob3ZlcmVkUG9seWdvbkJveCA9IHRoaXMubGF5b3V0UG9seWdvbi5zb21lKGxpbmUgPT4ge1xyXG4gICAgICBjb25zdCBwb2ludCA9IGxpbmVbMF07XHJcbiAgICAgIGNvbnN0IG5leHRQb2ludCA9IGxpbmVbMV07XHJcblxyXG4gICAgICBjb25zdCBkeCA9IG5leHRQb2ludC54IC0gcG9pbnQueDtcclxuICAgICAgY29uc3QgZHkgPSBuZXh0UG9pbnQueSAtIHBvaW50Lnk7XHJcbiAgICAgIGNvbnN0IGxlbmd0aCA9IE1hdGguc3FydChkeCAqIGR4ICsgZHkgKiBkeSk7XHJcbiAgICAgIGNvbnN0IG9mZnNldFggPSAoZHkgLyBsZW5ndGgpICogMjA7XHJcbiAgICAgIGNvbnN0IG9mZnNldFkgPSAoLWR4IC8gbGVuZ3RoKSAqIDIwO1xyXG5cclxuICAgICAgY29uc3QgYm94Q29ybmVycyA9IFtcclxuICAgICAgICB7IHg6IHBvaW50LngsIHk6IHBvaW50LnkgfSxcclxuICAgICAgICB7IHg6IG5leHRQb2ludC54LCB5OiBuZXh0UG9pbnQueSB9LFxyXG4gICAgICAgIHsgeDogbmV4dFBvaW50LnggKyBvZmZzZXRYLCB5OiBuZXh0UG9pbnQueSArIG9mZnNldFkgfSxcclxuICAgICAgICB7IHg6IHBvaW50LnggKyBvZmZzZXRYLCB5OiBwb2ludC55ICsgb2Zmc2V0WSB9XHJcbiAgICAgIF07XHJcblxyXG4gICAgICByZXR1cm4gdGhpcy5pc1BvaW50SW5Qb2x5Z29uKHsgeDogbW91c2VYLCB5OiBtb3VzZVkgfSwgYm94Q29ybmVycyk7XHJcbiAgICB9KTtcclxuXHJcblxyXG4gICAgdGhpcy5jYW52YXMuc3R5bGUuY3Vyc29yID0gaG92ZXJlZFBvbHlnb25Cb3ggPyAncG9pbnRlcicgOiAnZGVmYXVsdCc7XHJcblxyXG4gIH1cclxuXHJcblxyXG4gIGRyYXdMaW5lV2l0aExlbmd0aChzdGFydDogYW55LCBlbmQ6IGFueSk6IHZvaWQge1xyXG4gICAgY29uc3QgbWlkWCA9IChzdGFydC54ICsgZW5kLngpIC8gMjtcclxuICAgIGNvbnN0IG1pZFkgPSAoc3RhcnQueSArIGVuZC55KSAvIDI7XHJcblxyXG4gICAgY29uc3QgZGlzdGFuY2UgPSBNYXRoLnNxcnQoXHJcbiAgICAgIE1hdGgucG93KGVuZC54IC0gc3RhcnQueCwgMikgKyBNYXRoLnBvdyhlbmQueSAtIHN0YXJ0LnksIDIpXHJcbiAgICApLnRvRml4ZWQoMCk7XHJcblxyXG4gICAgY29uc3QgdGV4dFNwYWNpbmcgPSAxMDtcclxuICAgIGxldCB0ZXh0WCA9IG1pZFg7XHJcbiAgICBsZXQgdGV4dFkgPSBtaWRZO1xyXG5cclxuICAgIGlmIChzdGFydC55ID09PSBlbmQueSkge1xyXG4gICAgICB0ZXh0WSArPSB0ZXh0U3BhY2luZztcclxuICAgIH0gZWxzZSBpZiAoc3RhcnQueCA9PT0gZW5kLngpIHtcclxuICAgICAgdGV4dFggKz0gdGV4dFNwYWNpbmc7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICBjb25zdCBhbmdsZSA9IE1hdGguYXRhbjIoZW5kLnkgLSBzdGFydC55LCBlbmQueCAtIHN0YXJ0LngpO1xyXG4gICAgICB0ZXh0WCArPSB0ZXh0U3BhY2luZyAqIE1hdGguY29zKGFuZ2xlKTtcclxuICAgICAgdGV4dFkgKz0gdGV4dFNwYWNpbmcgKiBNYXRoLnNpbihhbmdsZSk7XHJcbiAgICB9XHJcblxyXG4gICAgdGhpcy5jdHguYmVnaW5QYXRoKCk7XHJcbiAgICB0aGlzLmN0eC5tb3ZlVG8oc3RhcnQueCwgc3RhcnQueSk7XHJcbiAgICB0aGlzLmN0eC5saW5lVG8oZW5kLngsIGVuZC55KTtcclxuICAgIHRoaXMuY3R4LnN0cm9rZVN0eWxlID0gJ2JsYWNrJztcclxuICAgIHRoaXMuY3R4LnN0cm9rZSgpO1xyXG5cclxuICAgIHRoaXMuY3R4LnNhdmUoKTtcclxuICAgIGlmIChzdGFydC55ID09PSBlbmQueSkge1xyXG4gICAgICB0aGlzLmN0eC5mb250ID0gJzEycHggQXJpYWwnO1xyXG4gICAgICB0aGlzLmN0eC5maWxsU3R5bGUgPSAnYmxhY2snO1xyXG4gICAgICB0aGlzLmN0eC5maWxsVGV4dChgJHtkaXN0YW5jZX1weGAsIHRleHRYLCB0ZXh0WSk7XHJcbiAgICB9IGVsc2UgaWYgKHN0YXJ0LnggPT09IGVuZC54KSB7XHJcbiAgICAgIHRoaXMuY3R4LnRyYW5zbGF0ZSh0ZXh0WCwgdGV4dFkpO1xyXG4gICAgICB0aGlzLmN0eC5yb3RhdGUoLU1hdGguUEkgLyAyKTtcclxuICAgICAgdGhpcy5jdHguZm9udCA9ICcxMnB4IEFyaWFsJztcclxuICAgICAgdGhpcy5jdHguZmlsbFN0eWxlID0gJ2JsYWNrJztcclxuICAgICAgdGhpcy5jdHguZmlsbFRleHQoYCR7ZGlzdGFuY2V9cHhgLCAwLCAwKTtcclxuICAgICAgdGhpcy5jdHgucmVzdG9yZSgpO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgdGhpcy5jdHguZm9udCA9ICcxMnB4IEFyaWFsJztcclxuICAgICAgdGhpcy5jdHguZmlsbFN0eWxlID0gJ2JsYWNrJztcclxuICAgICAgdGhpcy5jdHguZmlsbFRleHQoYCR7ZGlzdGFuY2V9cHhgLCB0ZXh0WCwgdGV4dFkpO1xyXG4gICAgfVxyXG4gICAgdGhpcy5jdHgucmVzdG9yZSgpO1xyXG4gIH1cclxuXHJcbiAgbGF5b3V0TGVuZ3RoUHJldmlldygpIHtcclxuICAgIGlmICh0aGlzLmxheW91dFBvbHlnb24ubGVuZ3RoID09PSAxICYmIHRoaXMubGF5b3V0UG9seWdvblswXVswXS54ID09PSB0aGlzLmxheW91dFBvbHlnb25bMF1bMV0ueCAmJiB0aGlzLmxheW91dFBvbHlnb25bMF1bMF0ueSA9PT0gdGhpcy5sYXlvdXRQb2x5Z29uWzBdWzFdLnkpIHtcclxuICAgICAgcmV0dXJuXHJcbiAgICB9XHJcbiAgICB0aGlzLmN0eC5jbGVhclJlY3QoMCwgMCwgdGhpcy5jYW52YXMud2lkdGgsIHRoaXMuY2FudmFzLmhlaWdodCk7XHJcbiAgICBsZXQgcmFkaWFuczogbnVtYmVyO1xyXG4gICAgc3dpdGNoICh0aGlzLm1vdmVEaXJlY3Rpb24pIHtcclxuICAgICAgY2FzZSAndXAnOlxyXG4gICAgICAgIHJhZGlhbnMgPSAoKDE4MCAtIHRoaXMubW92ZUFuZ2xlKSAqIE1hdGguUEkpIC8gMTgwO1xyXG4gICAgICAgIGJyZWFrO1xyXG4gICAgICBjYXNlICdsZWZ0JzpcclxuICAgICAgICByYWRpYW5zID0gKCgyNzAgLSB0aGlzLm1vdmVBbmdsZSkgKiBNYXRoLlBJKSAvIDE4MDtcclxuICAgICAgICBicmVhaztcclxuICAgICAgY2FzZSAnZG93bic6XHJcbiAgICAgICAgcmFkaWFucyA9ICgoMzYwIC0gdGhpcy5tb3ZlQW5nbGUpICogTWF0aC5QSSkgLyAxODA7XHJcbiAgICAgICAgYnJlYWs7XHJcbiAgICAgIGNhc2UgJ3JpZ2h0JzpcclxuICAgICAgICByYWRpYW5zID0gKCg5MCAtIHRoaXMubW92ZUFuZ2xlKSAqIE1hdGguUEkpIC8gMTgwO1xyXG4gICAgICAgIGJyZWFrO1xyXG4gICAgICBkZWZhdWx0OlxyXG4gICAgICAgIHJldHVybjtcclxuICAgIH1cclxuXHJcbiAgICBjb25zdCBsYXN0TGluZSA9IHRoaXMubGF5b3V0UG9seWdvblt0aGlzLmxheW91dFBvbHlnb24ubGVuZ3RoIC0gMV07XHJcbiAgICBjb25zdCBuZXdYID0gbGFzdExpbmVbMV0ueCArIE1hdGguY29zKHJhZGlhbnMpICogdGhpcy5jb252ZXJ0VG9QaXhlbHModGhpcy5tb3ZlUGl4ZWxzLCB0aGlzLnVuaXQpO1xyXG4gICAgY29uc3QgbmV3WSA9IGxhc3RMaW5lWzFdLnkgLSBNYXRoLnNpbihyYWRpYW5zKSAqIHRoaXMuY29udmVydFRvUGl4ZWxzKHRoaXMubW92ZVBpeGVscywgdGhpcy51bml0KTtcclxuXHJcbiAgICBjb25zdCBzbmFwcGVkWCA9IHRoaXMuc25hcFRvR3JpZChuZXdYLCB0aGlzLmdyaWRXaWR0aCk7XHJcbiAgICBjb25zdCBzbmFwcGVkWSA9IHRoaXMuc25hcFRvR3JpZChuZXdZLCB0aGlzLmdyaWRIZWlnaHQpO1xyXG5cclxuICAgIGNvbnN0IHByZXZpZXdQb2ludCA9IHsgeDogc25hcHBlZFgsIHk6IHNuYXBwZWRZIH07XHJcblxyXG4gICAgdGhpcy5yZWRyYXdDYW52YXMoKVxyXG4gICAgdGhpcy5kcmF3TGluZVdpdGhMZW5ndGgobGFzdExpbmVbMV0sIHByZXZpZXdQb2ludClcclxuXHJcblxyXG4gIH1cclxuXHJcblxyXG4gIHJvdGF0ZVBvbHlnb25zKCk6IHZvaWQge1xyXG4gICAgdGhpcy5zYXZlU3RhdGVUb1VuZG8oKTtcclxuICAgIHRoaXMuY2xvc2VXaWRnZXQoKVxyXG5cclxuICAgIGNvbnN0IGFuZ2xlID0gOTA7XHJcbiAgICB0aGlzLmN1bXVsYXRpdmVSb3RhdGlvbiA9ICh0aGlzLmN1bXVsYXRpdmVSb3RhdGlvbiArIGFuZ2xlKSAlIDM2MDtcclxuXHJcbiAgICBjb25zdCByb3RhdGVQb2ludCA9IChwb2ludDogeyB4OiBudW1iZXI7IHk6IG51bWJlciB9LCBjZW50ZXI6IHsgeDogbnVtYmVyOyB5OiBudW1iZXIgfSwgYW5nbGU6IG51bWJlcik6IHsgeDogbnVtYmVyOyB5OiBudW1iZXIgfSA9PiB7XHJcbiAgICAgIGNvbnN0IGR4ID0gcG9pbnQueCAtIGNlbnRlci54O1xyXG4gICAgICBjb25zdCBkeSA9IHBvaW50LnkgLSBjZW50ZXIueTtcclxuICAgICAgY29uc3QgcmFkaWFuQW5nbGUgPSBhbmdsZSAqIChNYXRoLlBJIC8gMTgwKTtcclxuXHJcbiAgICAgIGNvbnN0IGNvcyA9IE1hdGguY29zKHJhZGlhbkFuZ2xlKTtcclxuICAgICAgY29uc3Qgc2luID0gTWF0aC5zaW4ocmFkaWFuQW5nbGUpO1xyXG5cclxuICAgICAgcmV0dXJuIHtcclxuICAgICAgICB4OiBjZW50ZXIueCArIGR4ICogY29zIC0gZHkgKiBzaW4sXHJcbiAgICAgICAgeTogY2VudGVyLnkgKyBkeCAqIHNpbiArIGR5ICogY29zLFxyXG4gICAgICB9O1xyXG4gICAgfTtcclxuXHJcbiAgICBjb25zdCBnZXRQb2x5Z29uTGluZUNlbnRlciA9IChsaW5lOiBhbnlbXSk6IHsgeDogbnVtYmVyOyB5OiBudW1iZXIgfSA9PiB7XHJcbiAgICAgIGNvbnN0IFtzdGFydCwgZW5kXSA9IGxpbmU7XHJcbiAgICAgIHJldHVybiB7XHJcbiAgICAgICAgeDogKHN0YXJ0LnggKyBlbmQueCkgLyAyLFxyXG4gICAgICAgIHk6IChzdGFydC55ICsgZW5kLnkpIC8gMixcclxuICAgICAgfTtcclxuICAgIH07XHJcblxyXG4gICAgY29uc3QgZ2V0T3ZlcmFsbENlbnRlciA9IChsaW5lczogYW55W10pOiB7IHg6IG51bWJlcjsgeTogbnVtYmVyIH0gPT4ge1xyXG4gICAgICBjb25zdCBzdW0gPSBsaW5lcy5yZWR1Y2UoXHJcbiAgICAgICAgKGFjYywgbGluZSkgPT4ge1xyXG4gICAgICAgICAgY29uc3QgY2VudGVyID0gZ2V0UG9seWdvbkxpbmVDZW50ZXIobGluZSk7XHJcbiAgICAgICAgICBhY2MueCArPSBjZW50ZXIueDtcclxuICAgICAgICAgIGFjYy55ICs9IGNlbnRlci55O1xyXG4gICAgICAgICAgcmV0dXJuIGFjYztcclxuICAgICAgICB9LFxyXG4gICAgICAgIHsgeDogMCwgeTogMCB9XHJcbiAgICAgICk7XHJcblxyXG4gICAgICByZXR1cm4geyB4OiBzdW0ueCAvIGxpbmVzLmxlbmd0aCwgeTogc3VtLnkgLyBsaW5lcy5sZW5ndGggfTtcclxuICAgIH07XHJcblxyXG4gICAgY29uc3Qgb3ZlcmFsbENlbnRlciA9IGdldE92ZXJhbGxDZW50ZXIodGhpcy5sYXlvdXRQb2x5Z29uKTtcclxuXHJcbiAgICB0aGlzLmxheW91dFBvbHlnb24gPSB0aGlzLmxheW91dFBvbHlnb24ubWFwKChsaW5lKSA9PiB7XHJcbiAgICAgIGNvbnN0IFtzdGFydCwgZW5kLCBwcm9wZXJ0aWVzXSA9IGxpbmU7XHJcbiAgICAgIHJldHVybiBbXHJcbiAgICAgICAgcm90YXRlUG9pbnQoc3RhcnQsIG92ZXJhbGxDZW50ZXIsIGFuZ2xlKSxcclxuICAgICAgICByb3RhdGVQb2ludChlbmQsIG92ZXJhbGxDZW50ZXIsIGFuZ2xlKSxcclxuICAgICAgICBwcm9wZXJ0aWVzLFxyXG4gICAgICBdO1xyXG4gICAgfSk7XHJcblxyXG4gICAgdGhpcy5yZWRvU3RhY2sgPSBbXTtcclxuICAgIHRoaXMucmVkcmF3Q2FudmFzKCk7XHJcbiAgfVxyXG5cclxuICByZXNldE9yaWVudGF0aW9uKCk6IHZvaWQge1xyXG4gICAgaWYgKHRoaXMuY3VtdWxhdGl2ZVJvdGF0aW9uID09PSAwKSByZXR1cm47XHJcblxyXG4gICAgY29uc3QgYW5nbGVUb1Jlc2V0ID0gLXRoaXMuY3VtdWxhdGl2ZVJvdGF0aW9uO1xyXG4gICAgY29uc3QgcmVzZXRSb3RhdGlvbiA9IChwb2ludDogeyB4OiBudW1iZXI7IHk6IG51bWJlciB9LCBjZW50ZXI6IHsgeDogbnVtYmVyOyB5OiBudW1iZXIgfSwgYW5nbGU6IG51bWJlcik6IHsgeDogbnVtYmVyOyB5OiBudW1iZXIgfSA9PiB7XHJcbiAgICAgIGNvbnN0IGR4ID0gcG9pbnQueCAtIGNlbnRlci54O1xyXG4gICAgICBjb25zdCBkeSA9IHBvaW50LnkgLSBjZW50ZXIueTtcclxuICAgICAgY29uc3QgcmFkaWFuQW5nbGUgPSBhbmdsZSAqIChNYXRoLlBJIC8gMTgwKTtcclxuXHJcbiAgICAgIGNvbnN0IGNvcyA9IE1hdGguY29zKHJhZGlhbkFuZ2xlKTtcclxuICAgICAgY29uc3Qgc2luID0gTWF0aC5zaW4ocmFkaWFuQW5nbGUpO1xyXG5cclxuICAgICAgcmV0dXJuIHtcclxuICAgICAgICB4OiBjZW50ZXIueCArIGR4ICogY29zIC0gZHkgKiBzaW4sXHJcbiAgICAgICAgeTogY2VudGVyLnkgKyBkeCAqIHNpbiArIGR5ICogY29zLFxyXG4gICAgICB9O1xyXG4gICAgfTtcclxuXHJcbiAgICBjb25zdCBnZXRQb2x5Z29uTGluZUNlbnRlciA9IChsaW5lOiBhbnlbXSk6IHsgeDogbnVtYmVyOyB5OiBudW1iZXIgfSA9PiB7XHJcbiAgICAgIGNvbnN0IFtzdGFydCwgZW5kXSA9IGxpbmU7XHJcbiAgICAgIHJldHVybiB7XHJcbiAgICAgICAgeDogKHN0YXJ0LnggKyBlbmQueCkgLyAyLFxyXG4gICAgICAgIHk6IChzdGFydC55ICsgZW5kLnkpIC8gMixcclxuICAgICAgfTtcclxuICAgIH07XHJcblxyXG4gICAgY29uc3QgZ2V0T3ZlcmFsbENlbnRlciA9IChsaW5lczogYW55W10pOiB7IHg6IG51bWJlcjsgeTogbnVtYmVyIH0gPT4ge1xyXG4gICAgICBjb25zdCBzdW0gPSBsaW5lcy5yZWR1Y2UoXHJcbiAgICAgICAgKGFjYywgbGluZSkgPT4ge1xyXG4gICAgICAgICAgY29uc3QgY2VudGVyID0gZ2V0UG9seWdvbkxpbmVDZW50ZXIobGluZSk7XHJcbiAgICAgICAgICBhY2MueCArPSBjZW50ZXIueDtcclxuICAgICAgICAgIGFjYy55ICs9IGNlbnRlci55O1xyXG4gICAgICAgICAgcmV0dXJuIGFjYztcclxuICAgICAgICB9LFxyXG4gICAgICAgIHsgeDogMCwgeTogMCB9XHJcbiAgICAgICk7XHJcblxyXG4gICAgICByZXR1cm4geyB4OiBzdW0ueCAvIGxpbmVzLmxlbmd0aCwgeTogc3VtLnkgLyBsaW5lcy5sZW5ndGggfTtcclxuICAgIH07XHJcblxyXG4gICAgY29uc3Qgb3ZlcmFsbENlbnRlciA9IGdldE92ZXJhbGxDZW50ZXIodGhpcy5sYXlvdXRQb2x5Z29uKTtcclxuXHJcbiAgICB0aGlzLmxheW91dFBvbHlnb24gPSB0aGlzLmxheW91dFBvbHlnb24ubWFwKChsaW5lKSA9PiB7XHJcbiAgICAgIGNvbnN0IFtzdGFydCwgZW5kLCBwcm9wZXJ0aWVzXSA9IGxpbmU7XHJcbiAgICAgIHJldHVybiBbXHJcbiAgICAgICAgcmVzZXRSb3RhdGlvbihzdGFydCwgb3ZlcmFsbENlbnRlciwgYW5nbGVUb1Jlc2V0KSxcclxuICAgICAgICByZXNldFJvdGF0aW9uKGVuZCwgb3ZlcmFsbENlbnRlciwgYW5nbGVUb1Jlc2V0KSxcclxuICAgICAgICBwcm9wZXJ0aWVzLFxyXG4gICAgICBdO1xyXG4gICAgfSk7XHJcblxyXG4gICAgdGhpcy5jdW11bGF0aXZlUm90YXRpb24gPSAwOyAvLyBSZXNldCByb3RhdGlvbiB0cmFja2VyXHJcbiAgICB0aGlzLnJlZHJhd0NhbnZhcygpO1xyXG4gIH1cclxuXHJcblxyXG5cclxuXHJcbiAgaXNMaW5lRXF1YWwoXHJcbiAgICBzdGFydDE6IHsgeDogbnVtYmVyLCB5OiBudW1iZXIgfSxcclxuICAgIGVuZDE6IHsgeDogbnVtYmVyLCB5OiBudW1iZXIgfSxcclxuICAgIHN0YXJ0MjogeyB4OiBudW1iZXIsIHk6IG51bWJlciB9LFxyXG4gICAgZW5kMjogeyB4OiBudW1iZXIsIHk6IG51bWJlciB9LFxyXG4gICAgdG9sZXJhbmNlOiBudW1iZXJcclxuICApOiBib29sZWFuIHtcclxuICAgIGNvbnN0IGFyZVBvaW50c0VxdWFsID0gKHAxOiB7IHg6IG51bWJlciwgeTogbnVtYmVyIH0sIHAyOiB7IHg6IG51bWJlciwgeTogbnVtYmVyIH0pID0+XHJcbiAgICAgIE1hdGguYWJzKHAxLnggLSBwMi54KSA8PSB0b2xlcmFuY2UgJiYgTWF0aC5hYnMocDEueSAtIHAyLnkpIDw9IHRvbGVyYW5jZTtcclxuXHJcbiAgICByZXR1cm4gKFxyXG4gICAgICAoYXJlUG9pbnRzRXF1YWwoc3RhcnQxLCBzdGFydDIpICYmIGFyZVBvaW50c0VxdWFsKGVuZDEsIGVuZDIpKSB8fFxyXG4gICAgICAoYXJlUG9pbnRzRXF1YWwoc3RhcnQxLCBlbmQyKSAmJiBhcmVQb2ludHNFcXVhbChlbmQxLCBzdGFydDIpKVxyXG4gICAgKTtcclxuICB9XHJcblxyXG4gIGNvbnZlcnRUb1BpeGVscyh2YWx1ZTogbnVtYmVyLCB1bml0OiAnZnQnIHwgJ20nKTogbnVtYmVyIHtcclxuICAgIGNvbnN0IFBJWEVMU19QRVJfTUVURVIgPSB0aGlzLnBpeGVsUGVyTWV0cmU7XHJcbiAgICBjb25zdCBQSVhFTFNfUEVSX0ZPT1QgPSBQSVhFTFNfUEVSX01FVEVSIC8gMy4yODA4NDtcclxuXHJcbiAgICBpZiAodHlwZW9mIHZhbHVlICE9PSAnbnVtYmVyJyB8fCB2YWx1ZSA8IDApIHtcclxuICAgICAgdGhyb3cgbmV3IEVycm9yKCdWYWx1ZSBtdXN0IGJlIGEgbm9uLW5lZ2F0aXZlIG51bWJlcicpO1xyXG4gICAgfVxyXG5cclxuICAgIHN3aXRjaCAodW5pdCkge1xyXG4gICAgICBjYXNlICdtJzpcclxuICAgICAgICByZXR1cm4gdmFsdWUgKiBQSVhFTFNfUEVSX01FVEVSO1xyXG4gICAgICBjYXNlICdmdCc6XHJcbiAgICAgICAgcmV0dXJuIHZhbHVlICogUElYRUxTX1BFUl9GT09UO1xyXG4gICAgICBkZWZhdWx0OlxyXG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcIkludmFsaWQgdW5pdC4gU3VwcG9ydGVkIHVuaXRzIGFyZSAnbXQnIGZvciBtZXRlcnMgYW5kICdmdCcgZm9yIGZlZXQuXCIpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgb25FbGVtZW50VHlwZUNoYW5nZSh0eXBlOiBzdHJpbmcsIGluZGV4OiBudW1iZXIpIHtcclxuICAgIGNvbnN0IFtwb2ludDEsIHBvaW50MiwgcHJvcGVydGllc10gPSB0aGlzLmxheW91dFBvbHlnb25baW5kZXhdXHJcbiAgICBwcm9wZXJ0aWVzLmVsZW1lbnRUeXBlID0gdHlwZVxyXG4gICAgdGhpcy5sYXlvdXRQb2x5Z29uW2luZGV4XSA9IFtwb2ludDEsIHBvaW50MiwgcHJvcGVydGllc11cclxuICAgIHRoaXMuZWxlbWVudFNlbGVjdCA9IHsgc2hvdzogZmFsc2UsIGluZGV4OiAwIH07XHJcbiAgICB0aGlzLnJlZHJhd0NhbnZhcygpXHJcbiAgfVxyXG5cclxuICBvbkRpc3RhbmNlQ2hhbmdlKHZhbHVlOiAnaW5jcmVtZW50JyB8ICdkZWNyZW1lbnQnLCBpbmRleDogbnVtYmVyKSB7XHJcbiAgICB0aGlzLnNhdmVTdGF0ZVRvVW5kbygpXHJcbiAgICBjb25zdCBbcG9pbnQxLCBwb2ludDIsIHByb3BlcnRpZXNdID0gdGhpcy5sYXlvdXRQb2x5Z29uW2luZGV4XTtcclxuICAgIGxldCByYWRpYW5zOiBudW1iZXI7XHJcbiAgICBzd2l0Y2ggKHByb3BlcnRpZXMuZGlyZWN0aW9uKSB7XHJcbiAgICAgIGNhc2UgJ3VwJzpcclxuICAgICAgICByYWRpYW5zID0gKCgxODAgLSBwcm9wZXJ0aWVzLmFuZ2xlKSAqIE1hdGguUEkpIC8gMTgwO1xyXG4gICAgICAgIGJyZWFrO1xyXG4gICAgICBjYXNlICdsZWZ0JzpcclxuICAgICAgICByYWRpYW5zID0gKCgyNzAgLSBwcm9wZXJ0aWVzLmFuZ2xlKSAqIE1hdGguUEkpIC8gMTgwO1xyXG4gICAgICAgIGJyZWFrO1xyXG4gICAgICBjYXNlICdkb3duJzpcclxuICAgICAgICByYWRpYW5zID0gKCgzNjAgLSBwcm9wZXJ0aWVzLmFuZ2xlKSAqIE1hdGguUEkpIC8gMTgwO1xyXG4gICAgICAgIGJyZWFrO1xyXG4gICAgICBjYXNlICdyaWdodCc6XHJcbiAgICAgICAgcmFkaWFucyA9ICgoOTAgLSBwcm9wZXJ0aWVzLmFuZ2xlKSAqIE1hdGguUEkpIC8gMTgwO1xyXG4gICAgICAgIGJyZWFrO1xyXG4gICAgICBkZWZhdWx0OlxyXG4gICAgICAgIHJldHVybjtcclxuICAgIH1cclxuICAgIGlmICh2YWx1ZSA9PT0gJ2luY3JlbWVudCcpIHtcclxuXHJcbiAgICAgIGNvbnN0IG5ld1ggPSBwb2ludDIueCArIE1hdGguY29zKHJhZGlhbnMpICogdGhpcy5jb252ZXJ0VG9QaXhlbHMoMSwgcHJvcGVydGllcy51bml0KTtcclxuICAgICAgY29uc3QgbmV3WSA9IHBvaW50Mi55IC0gTWF0aC5zaW4ocmFkaWFucykgKiB0aGlzLmNvbnZlcnRUb1BpeGVscygxLCBwcm9wZXJ0aWVzLnVuaXQpO1xyXG5cclxuICAgICAgY29uc3Qgc25hcHBlZFggPSB0aGlzLnNuYXBUb0dyaWQobmV3WCwgdGhpcy5ncmlkV2lkdGgpO1xyXG4gICAgICBjb25zdCBzbmFwcGVkWSA9IHRoaXMuc25hcFRvR3JpZChuZXdZLCB0aGlzLmdyaWRIZWlnaHQpO1xyXG5cclxuICAgICAgY29uc3QgbmV3cG9pbnQgPSB7IHg6IHNuYXBwZWRYLCB5OiBzbmFwcGVkWSB9O1xyXG4gICAgICBwb2ludDIueCA9IG5ld3BvaW50Lng7XHJcbiAgICAgIHBvaW50Mi55ID0gbmV3cG9pbnQueTtcclxuICAgICAgcHJvcGVydGllcy5kaXN0YW5jZSA9IHByb3BlcnRpZXMuZGlzdGFuY2UgKyAxO1xyXG4gICAgfSBlbHNlIGlmICh2YWx1ZSA9PT0gJ2RlY3JlbWVudCcpIHtcclxuXHJcbiAgICAgIGNvbnN0IG5ld1ggPSBwb2ludDIueCAtIE1hdGguY29zKHJhZGlhbnMpICogdGhpcy5jb252ZXJ0VG9QaXhlbHMoMSwgcHJvcGVydGllcy51bml0KTtcclxuICAgICAgY29uc3QgbmV3WSA9IHBvaW50Mi55ICsgTWF0aC5zaW4ocmFkaWFucykgKiB0aGlzLmNvbnZlcnRUb1BpeGVscygxLCBwcm9wZXJ0aWVzLnVuaXQpO1xyXG5cclxuICAgICAgY29uc3Qgc25hcHBlZFggPSB0aGlzLnNuYXBUb0dyaWQobmV3WCwgdGhpcy5ncmlkV2lkdGgpO1xyXG4gICAgICBjb25zdCBzbmFwcGVkWSA9IHRoaXMuc25hcFRvR3JpZChuZXdZLCB0aGlzLmdyaWRIZWlnaHQpO1xyXG5cclxuICAgICAgY29uc3QgbmV3cG9pbnQgPSB7IHg6IHNuYXBwZWRYLCB5OiBzbmFwcGVkWSB9O1xyXG4gICAgICBpZiAocHJvcGVydGllcy5kaXN0YW5jZSA+IDEpIHtcclxuICAgICAgICBwb2ludDIueCA9IG5ld3BvaW50Lng7XHJcbiAgICAgICAgcG9pbnQyLnkgPSBuZXdwb2ludC55O1xyXG4gICAgICAgIHByb3BlcnRpZXMuZGlzdGFuY2UgPSBwcm9wZXJ0aWVzLmRpc3RhbmNlIC0gMTtcclxuICAgICAgfVxyXG5cclxuICAgIH1cclxuICAgIHRoaXMubGF5b3V0UG9seWdvbltpbmRleF0gPSBbcG9pbnQxLCBwb2ludDIsIHByb3BlcnRpZXNdO1xyXG4gICAgdGhpcy5saW5lT3B0aW9uc1NlbGVjdCA9IHsgc2hvdzogZmFsc2UsIGluZGV4OiAwIH07XHJcbiAgICB0aGlzLnJlZG9TdGFjayA9IFtdO1xyXG4gICAgdGhpcy5yZWRyYXdDYW52YXMoKVxyXG5cclxuICB9XHJcblxyXG4gIG9uV2lkZ2V0RGlzdGFuY2VDaGFuZ2UodmFsdWU6ICdpbmNyZW1lbnQnIHwgJ2RlY3JlbWVudCcpIHtcclxuICAgIGlmICh2YWx1ZSA9PT0gJ2luY3JlbWVudCcpIHtcclxuICAgICAgdGhpcy5tb3ZlUGl4ZWxzID0gdGhpcy5tb3ZlUGl4ZWxzICsgMTtcclxuICAgIH0gZWxzZSBpZiAodmFsdWUgPT09ICdkZWNyZW1lbnQnKSB7XHJcbiAgICAgIGlmICh0aGlzLm1vdmVQaXhlbHMgPiAxKSB7XHJcbiAgICAgICAgdGhpcy5tb3ZlUGl4ZWxzID0gdGhpcy5tb3ZlUGl4ZWxzIC0gMTtcclxuICAgICAgfVxyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgb25XaWRnZXRBbmdsZUNoYW5nZSh2YWx1ZTogJ2luY3JlbWVudCcgfCAnZGVjcmVtZW50Jykge1xyXG4gICAgaWYgKHZhbHVlID09PSAnaW5jcmVtZW50Jykge1xyXG4gICAgICBpZiAodGhpcy5tb3ZlQW5nbGUgPCAxODApIHtcclxuICAgICAgICB0aGlzLm1vdmVBbmdsZSA9IHRoaXMubW92ZUFuZ2xlICsgNTtcclxuICAgICAgfVxyXG4gICAgfSBlbHNlIGlmICh2YWx1ZSA9PT0gJ2RlY3JlbWVudCcpIHtcclxuICAgICAgaWYgKHRoaXMubW92ZUFuZ2xlID4gMCkge1xyXG4gICAgICAgIHRoaXMubW92ZUFuZ2xlID0gdGhpcy5tb3ZlQW5nbGUgLSA1O1xyXG4gICAgICB9XHJcbiAgICB9XHJcblxyXG5cclxuICAgIHRoaXMudXBkYXRlV2lkZ2V0UG9pbnRlcigpXHJcbiAgfVxyXG5cclxuICBvbldpZGdldERpcmVjdGlvbkNoYW5nZShkaXJlY3Rpb246ICdsZWZ0JyB8ICdyaWdodCcgfCAndXAnIHwgJ2Rvd24nKSB7XHJcbiAgICB0aGlzLm1vdmVEaXJlY3Rpb24gPSBkaXJlY3Rpb247XHJcbiAgICB0aGlzLmRyYXdXaWRnZXRSaW5nKClcclxuICAgIHRoaXMudXBkYXRlV2lkZ2V0UG9pbnRlcigpXHJcbiAgfVxyXG5cclxuICBvbkRpcmVjdGlvbkNoYW5nZSh2YWx1ZTogJ3VwJyB8ICdsZWZ0JyB8ICdkb3duJyB8ICdyaWdodCcsIGluZGV4OiBudW1iZXIpIHtcclxuICAgIHRoaXMuc2F2ZVN0YXRlVG9VbmRvKClcclxuICAgIGNvbnN0IFtwb2ludDEsIHBvaW50MiwgcHJvcGVydGllc10gPSB0aGlzLmxheW91dFBvbHlnb25baW5kZXhdO1xyXG5cclxuICAgIGxldCByYWRpYW5zOiBudW1iZXI7XHJcbiAgICBzd2l0Y2ggKHZhbHVlKSB7XHJcbiAgICAgIGNhc2UgJ3VwJzpcclxuICAgICAgICByYWRpYW5zID0gKCgxODAgLSBwcm9wZXJ0aWVzLmFuZ2xlKSAqIE1hdGguUEkpIC8gMTgwO1xyXG4gICAgICAgIGJyZWFrO1xyXG4gICAgICBjYXNlICdsZWZ0JzpcclxuICAgICAgICByYWRpYW5zID0gKCgyNzAgLSBwcm9wZXJ0aWVzLmFuZ2xlKSAqIE1hdGguUEkpIC8gMTgwO1xyXG4gICAgICAgIGJyZWFrO1xyXG4gICAgICBjYXNlICdkb3duJzpcclxuICAgICAgICByYWRpYW5zID0gKCgzNjAgLSBwcm9wZXJ0aWVzLmFuZ2xlKSAqIE1hdGguUEkpIC8gMTgwO1xyXG4gICAgICAgIGJyZWFrO1xyXG4gICAgICBjYXNlICdyaWdodCc6XHJcbiAgICAgICAgcmFkaWFucyA9ICgoOTAgLSBwcm9wZXJ0aWVzLmFuZ2xlKSAqIE1hdGguUEkpIC8gMTgwO1xyXG4gICAgICAgIGJyZWFrO1xyXG4gICAgICBkZWZhdWx0OlxyXG4gICAgICAgIHJldHVybjtcclxuICAgIH1cclxuXHJcbiAgICBjb25zdCBtb3ZlbWVudERpc3RhbmNlID0gdGhpcy5jb252ZXJ0VG9QaXhlbHMocHJvcGVydGllcy5kaXN0YW5jZSwgcHJvcGVydGllcy51bml0KTtcclxuXHJcbiAgICBjb25zdCBuZXdYID0gcG9pbnQxLnggKyBNYXRoLmNvcyhyYWRpYW5zKSAqIG1vdmVtZW50RGlzdGFuY2U7XHJcbiAgICBjb25zdCBuZXdZID0gcG9pbnQxLnkgLSBNYXRoLnNpbihyYWRpYW5zKSAqIG1vdmVtZW50RGlzdGFuY2U7XHJcblxyXG4gICAgY29uc3Qgc25hcHBlZFggPSB0aGlzLnNuYXBUb0dyaWQobmV3WCwgdGhpcy5ncmlkV2lkdGgpO1xyXG4gICAgY29uc3Qgc25hcHBlZFkgPSB0aGlzLnNuYXBUb0dyaWQobmV3WSwgdGhpcy5ncmlkSGVpZ2h0KTtcclxuXHJcbiAgICBwb2ludDIueCA9IHNuYXBwZWRYO1xyXG4gICAgcG9pbnQyLnkgPSBzbmFwcGVkWTtcclxuICAgIHByb3BlcnRpZXMuZGlyZWN0aW9uID0gdmFsdWU7XHJcblxyXG4gICAgdGhpcy5sYXlvdXRQb2x5Z29uW2luZGV4XSA9IFtwb2ludDEsIHBvaW50MiwgcHJvcGVydGllc107XHJcbiAgICB0aGlzLmRpcmVjdGlvblNlbGVjdCA9IHsgc2hvdzogZmFsc2UsIGluZGV4OiAwIH07XHJcbiAgICB0aGlzLnJlZG9TdGFjayA9IFtdO1xyXG4gICAgdGhpcy5yZWRyYXdDYW52YXMoKVxyXG4gIH1cclxuXHJcbiAgb25MaW5lRGVsZXRlKGluZGV4OiBudW1iZXIpIHtcclxuICAgIHRoaXMuc2F2ZVN0YXRlVG9VbmRvKClcclxuICAgIHRoaXMubGF5b3V0UG9seWdvbi5zcGxpY2UoaW5kZXgsIDEpO1xyXG4gICAgdGhpcy5yZWRvU3RhY2sgPSBbXTtcclxuICAgIHRoaXMucmVkcmF3Q2FudmFzKClcclxuICB9XHJcblxyXG4gIG9uQWRkU3RlcChpbmRleDogbnVtYmVyKSB7XHJcbiAgICB0aGlzLnNhdmVTdGF0ZVRvVW5kbygpXHJcbiAgICBjb25zdCBbcG9pbnQxLCBwb2ludDIsIHByb3BlcnRpZXNdID0gdGhpcy5sYXlvdXRQb2x5Z29uW2luZGV4XTtcclxuICAgIGxldCByYWRpYW5zID0gKCg5MCAtIDkwKSAqIE1hdGguUEkpIC8gMTgwOztcclxuXHJcbiAgICBjb25zdCBuZXdYID0gcG9pbnQyLnggKyBNYXRoLmNvcyhyYWRpYW5zKSAqIHRoaXMuY29udmVydFRvUGl4ZWxzKDEsIHRoaXMudW5pdCk7XHJcbiAgICBjb25zdCBuZXdZID0gcG9pbnQyLnkgLSBNYXRoLnNpbihyYWRpYW5zKSAqIHRoaXMuY29udmVydFRvUGl4ZWxzKDEsIHRoaXMudW5pdCk7XHJcblxyXG4gICAgY29uc3Qgc25hcHBlZFggPSB0aGlzLnNuYXBUb0dyaWQobmV3WCwgdGhpcy5ncmlkV2lkdGgpO1xyXG4gICAgY29uc3Qgc25hcHBlZFkgPSB0aGlzLnNuYXBUb0dyaWQobmV3WSwgdGhpcy5ncmlkSGVpZ2h0KTtcclxuXHJcbiAgICBjb25zdCBuZXdwb2ludCA9IHsgeDogc25hcHBlZFgsIHk6IHNuYXBwZWRZIH07XHJcblxyXG4gICAgdGhpcy5sYXlvdXRQb2x5Z29uLnNwbGljZShpbmRleCArIDEsIDAsXHJcbiAgICAgIFtwb2ludDIsIG5ld3BvaW50LFxyXG4gICAgICAgIHsgZWxlbWVudFR5cGU6ICd3YWxsJywgZGlzdGFuY2U6IDEsIHVuaXQ6IHRoaXMudW5pdCwgZGlyZWN0aW9uOiAncmlnaHQnLCBhbmdsZTogOTAsIGVsZW1lbnROdW1iZXI6IHRoaXMuZ2V0TWF4RWxlbWVudE51bWJlcih0aGlzLmxheW91dFBvbHlnb24sICd3YWxsJykgfV0pO1xyXG4gICAgdGhpcy5yZWRvU3RhY2sgPSBbXTtcclxuICAgIHRoaXMucmVkcmF3Q2FudmFzKClcclxuICAgIHRoaXMubGluZU9wdGlvbnNTZWxlY3QgPSB7IHNob3c6IGZhbHNlLCBpbmRleDogMCB9XHJcblxyXG4gIH1cclxuXHJcbiAgb25EdXBsaWNhdGVTdGVwKGluZGV4OiBudW1iZXIpIHtcclxuICAgIHRoaXMucmVkb1N0YWNrID0gW107XHJcbiAgICBjb25zdCBbcG9pbnQxLCBwb2ludDIsIHByb3BlcnRpZXNdID0gSlNPTi5wYXJzZShKU09OLnN0cmluZ2lmeSh0aGlzLmxheW91dFBvbHlnb25baW5kZXhdKSk7XHJcbiAgICBsZXQgcmFkaWFuczogbnVtYmVyO1xyXG4gICAgc3dpdGNoIChwcm9wZXJ0aWVzLmRpcmVjdGlvbikge1xyXG4gICAgICBjYXNlICd1cCc6XHJcbiAgICAgICAgcmFkaWFucyA9ICgoMTgwIC0gcHJvcGVydGllcy5hbmdsZSkgKiBNYXRoLlBJKSAvIDE4MDtcclxuICAgICAgICBicmVhaztcclxuICAgICAgY2FzZSAnbGVmdCc6XHJcbiAgICAgICAgcmFkaWFucyA9ICgoMjcwIC0gcHJvcGVydGllcy5hbmdsZSkgKiBNYXRoLlBJKSAvIDE4MDtcclxuICAgICAgICBicmVhaztcclxuICAgICAgY2FzZSAnZG93bic6XHJcbiAgICAgICAgcmFkaWFucyA9ICgoMzYwIC0gcHJvcGVydGllcy5hbmdsZSkgKiBNYXRoLlBJKSAvIDE4MDtcclxuICAgICAgICBicmVhaztcclxuICAgICAgY2FzZSAncmlnaHQnOlxyXG4gICAgICAgIHJhZGlhbnMgPSAoKDkwIC0gcHJvcGVydGllcy5hbmdsZSkgKiBNYXRoLlBJKSAvIDE4MDtcclxuICAgICAgICBicmVhaztcclxuICAgICAgZGVmYXVsdDpcclxuICAgICAgICByZXR1cm47XHJcbiAgICB9XHJcblxyXG4gICAgY29uc3QgbmV3WCA9IHBvaW50Mi54ICsgTWF0aC5jb3MocmFkaWFucykgKiB0aGlzLmNvbnZlcnRUb1BpeGVscyhwcm9wZXJ0aWVzLmRpc3RhbmNlLCBwcm9wZXJ0aWVzLnVuaXQpO1xyXG4gICAgY29uc3QgbmV3WSA9IHBvaW50Mi55IC0gTWF0aC5zaW4ocmFkaWFucykgKiB0aGlzLmNvbnZlcnRUb1BpeGVscyhwcm9wZXJ0aWVzLmRpc3RhbmNlLCBwcm9wZXJ0aWVzLnVuaXQpO1xyXG5cclxuICAgIGNvbnN0IHNuYXBwZWRYID0gdGhpcy5zbmFwVG9HcmlkKG5ld1gsIHRoaXMuZ3JpZFdpZHRoKTtcclxuICAgIGNvbnN0IHNuYXBwZWRZID0gdGhpcy5zbmFwVG9HcmlkKG5ld1ksIHRoaXMuZ3JpZEhlaWdodCk7XHJcblxyXG4gICAgY29uc3QgbmV3cG9pbnQgPSB7IHg6IHNuYXBwZWRYLCB5OiBzbmFwcGVkWSB9O1xyXG5cclxuICAgIHByb3BlcnRpZXMuZWxlbWVudE51bWJlciA9IHRoaXMuZ2V0TWF4RWxlbWVudE51bWJlcih0aGlzLmxheW91dFBvbHlnb24sIHByb3BlcnRpZXMuZWxlbWVudFR5cGUpXHJcblxyXG4gICAgdGhpcy5sYXlvdXRQb2x5Z29uLnNwbGljZShpbmRleCArIDEsIDAsXHJcbiAgICAgIFtwb2ludDIsIG5ld3BvaW50LCBwcm9wZXJ0aWVzXSk7XHJcbiAgICB0aGlzLmxpbmVPcHRpb25zU2VsZWN0ID0geyBzaG93OiBmYWxzZSwgaW5kZXg6IDAgfTtcclxuICAgIHRoaXMucmVkb1N0YWNrID0gW107XHJcbiAgICB0aGlzLnJlZHJhd0NhbnZhcygpXHJcblxyXG4gIH1cclxuXHJcblxyXG4gIHNjcm9sbFRvQ2FudmFzUG9zaXRpb24oY29vcmRpbmF0ZXM6IHsgeDogbnVtYmVyOyB5OiBudW1iZXIgfSk6IHZvaWQge1xyXG4gICAgY29uc3QgY29udGFpbmVyID0gdGhpcy5zY3JvbGxDb250YWluZXJSZWYubmF0aXZlRWxlbWVudDtcclxuXHJcbiAgICBjb25zdCBjb250YWluZXJSZWN0ID0gY29udGFpbmVyLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xyXG4gICAgY29uc3QgY29udGFpbmVyU2Nyb2xsTGVmdCA9IGNvbnRhaW5lci5zY3JvbGxMZWZ0O1xyXG4gICAgY29uc3QgY29udGFpbmVyU2Nyb2xsVG9wID0gY29udGFpbmVyLnNjcm9sbFRvcDtcclxuXHJcbiAgICBjb25zdCB0YXJnZXRYID0gY29vcmRpbmF0ZXMueDtcclxuICAgIGNvbnN0IHRhcmdldFkgPSBjb29yZGluYXRlcy55O1xyXG5cclxuICAgIGNvbnN0IG9mZnNldCA9IHtcclxuICAgICAgdXA6IDEwMCxcclxuICAgICAgZG93bjogMjAwLFxyXG4gICAgICBsZWZ0OiAxMDAsXHJcbiAgICAgIHJpZ2h0OiAxMDAsXHJcbiAgICB9O1xyXG5cclxuICAgIGNvbnN0IHZpc2libGVMZWZ0ID0gY29udGFpbmVyU2Nyb2xsTGVmdCArIG9mZnNldC5sZWZ0O1xyXG4gICAgY29uc3QgdmlzaWJsZVJpZ2h0ID0gY29udGFpbmVyU2Nyb2xsTGVmdCArIGNvbnRhaW5lclJlY3Qud2lkdGggLSBvZmZzZXQucmlnaHQ7XHJcbiAgICBjb25zdCB2aXNpYmxlVG9wID0gY29udGFpbmVyU2Nyb2xsVG9wICsgb2Zmc2V0LnVwO1xyXG4gICAgY29uc3QgdmlzaWJsZUJvdHRvbSA9IGNvbnRhaW5lclNjcm9sbFRvcCArIGNvbnRhaW5lclJlY3QuaGVpZ2h0IC0gb2Zmc2V0LmRvd247XHJcblxyXG4gICAgY29uc3QgaXNYSW5WaWV3ID0gdGFyZ2V0WCA+PSB2aXNpYmxlTGVmdCAmJiB0YXJnZXRYIDw9IHZpc2libGVSaWdodDtcclxuICAgIGNvbnN0IGlzWUluVmlldyA9IHRhcmdldFkgPj0gdmlzaWJsZVRvcCAmJiB0YXJnZXRZIDw9IHZpc2libGVCb3R0b207XHJcblxyXG4gICAgaWYgKCFpc1hJblZpZXcgfHwgIWlzWUluVmlldykge1xyXG4gICAgICBjb25zdCBhZGp1c3RlZFggPSBNYXRoLm1heCgwLCB0YXJnZXRYIC0gb2Zmc2V0LmxlZnQpO1xyXG4gICAgICBjb25zdCBhZGp1c3RlZFkgPSBNYXRoLm1heCgwLCB0YXJnZXRZIC0gb2Zmc2V0LnVwKTtcclxuXHJcbiAgICAgIGNvbnRhaW5lci5zY3JvbGxUbyh7XHJcbiAgICAgICAgbGVmdDogYWRqdXN0ZWRYLFxyXG4gICAgICAgIHRvcDogYWRqdXN0ZWRZLFxyXG4gICAgICAgIGJlaGF2aW9yOiAnc21vb3RoJyxcclxuICAgICAgfSk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBvbkNsZWFyQWxsKCkge1xyXG4gICAgY29uc3QgbW9kZWxSZWYgPSB0aGlzLm1vZGFsRGVmLm9wZW4oQ2xlYXJBbGxTdGVwc0NvbXBvbmVudCwgeyBjZW50ZXJlZDogdHJ1ZSB9KTtcclxuICAgIG1vZGVsUmVmLnJlc3VsdC50aGVuKCh2YWw6IGFueSkgPT4ge1xyXG4gICAgICBpZiAodmFsLm1lc3NhZ2UgPT09ICdjb25maXJtJykge1xyXG4gICAgICAgIHRoaXMudG9hc3RTZXJ2aWNlLmdldFN1Y2Nlc3NUb2FzdCgnTGF5b3V0IGNsZWFyZWQgc3VjY2Vzc2Z1bGx5JylcclxuICAgICAgICB0aGlzLnVuZG9TdGFjayA9IFtdXHJcbiAgICAgICAgdGhpcy5yZWRvU3RhY2sgPSBbXVxyXG4gICAgICAgIHRoaXMuaW5pdGlhbGl6ZUxheW91dCgpXHJcbiAgICAgICAgdGhpcy5yZWRyYXdDYW52YXMoKVxyXG4gICAgICB9XHJcbiAgICB9KVxyXG5cclxuICB9XHJcblxyXG4gIG9uRGVsZXRlTGF5b3V0KCkge1xyXG4gICAgY29uc3QgbW9kZWxSZWYgPSB0aGlzLm1vZGFsRGVmLm9wZW4oRGVsZXRlTGF5b3V0Q29tcG9uZW50LCB7IGNlbnRlcmVkOiB0cnVlIH0pO1xyXG4gICAgbW9kZWxSZWYucmVzdWx0LnRoZW4oKHZhbDogYW55KSA9PiB7XHJcbiAgICAgIGlmICh2YWwubWVzc2FnZSA9PT0gJ2NvbmZpcm0nKSB7XHJcbiAgICAgICAgdGhpcy51bmRvU3RhY2sgPSBbXVxyXG4gICAgICAgIHRoaXMucmVkb1N0YWNrID0gW11cclxuICAgICAgICB0aGlzLmxheW91dFBvbHlnb24gPSBbXTtcclxuICAgICAgICB0aGlzLnVwZGF0ZUZsb29yTGF5b3V0KClcclxuICAgICAgICB0aGlzLmluaXRpYWxpemVMYXlvdXQoKVxyXG4gICAgICAgIHRoaXMucmVkcmF3Q2FudmFzKClcclxuICAgICAgfVxyXG4gICAgfSlcclxuXHJcbiAgfVxyXG5cclxuICBhc3luYyBleHBvcnRBc1BuZygpIHtcclxuICAgIGNvbnN0IHBhZGRpbmcgPSAxMDA7XHJcbiAgICBjb25zdCBjYW52YXMgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdjYW52YXMnKTtcclxuICAgIGNvbnN0IGN0eCA9IGNhbnZhcy5nZXRDb250ZXh0KCcyZCcpITtcclxuICAgIGNhbnZhcy53aWR0aCA9IDEwMDAwOyBcclxuICAgIGNhbnZhcy5oZWlnaHQgPSAxMDAwMDtcclxuICBcclxuICAgIGNvbnN0IGNlbnRlclggPSBjYW52YXMud2lkdGggLyAyIC8gdGhpcy5zY2FsZTtcclxuICAgIGNvbnN0IGNlbnRlclkgPSBjYW52YXMuaGVpZ2h0IC8gMiAvIHRoaXMuc2NhbGU7XHJcbiAgXHJcbiAgICBsZXQgY3VycmVudFBvaW50ID0ge1xyXG4gICAgICB4OiB0aGlzLnNuYXBUb0dyaWQoY2VudGVyWCwgdGhpcy5ncmlkSGVpZ2h0KSxcclxuICAgICAgeTogdGhpcy5zbmFwVG9HcmlkKGNlbnRlclksIHRoaXMuZ3JpZFdpZHRoKSxcclxuICAgIH07XHJcbiAgXHJcbiAgICBjb25zdCByZW5kZXJDYW52YXMgPSBhc3luYyAobGF5b3V0UG9seWdvbjogYW55W10pOiBQcm9taXNlPHN0cmluZz4gPT4ge1xyXG4gICAgICBjb25zdCBleHBvcnRMYXlvdXQ6IGFueVtdID0gW107XHJcbiAgXHJcbiAgICAgIGxheW91dFBvbHlnb24uZm9yRWFjaCgoaW5zdHJ1Y3Rpb246IGFueSkgPT4ge1xyXG4gICAgICAgIGNvbnN0IHJhZGlhbnM6IG51bWJlciA9IHtcclxuICAgICAgICAgIHVwOiAoKDE4MCAtIGluc3RydWN0aW9uLmFuZ2xlKSAqIE1hdGguUEkpIC8gMTgwLFxyXG4gICAgICAgICAgbGVmdDogKCgyNzAgLSBpbnN0cnVjdGlvbi5hbmdsZSkgKiBNYXRoLlBJKSAvIDE4MCxcclxuICAgICAgICAgIGRvd246ICgoMzYwIC0gaW5zdHJ1Y3Rpb24uYW5nbGUpICogTWF0aC5QSSkgLyAxODAsXHJcbiAgICAgICAgICByaWdodDogKCg5MCAtIGluc3RydWN0aW9uLmFuZ2xlKSAqIE1hdGguUEkpIC8gMTgwLFxyXG4gICAgICAgIH1baW5zdHJ1Y3Rpb24uZGlyZWN0aW9uIGFzICd1cCcgfCAnbGVmdCcgfCAnZG93bicgfCAncmlnaHQnXTtcclxuICBcclxuICAgICAgICBpZiAocmFkaWFucyA9PT0gdW5kZWZpbmVkKSB7XHJcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYEludmFsaWQgZGlyZWN0aW9uOiAke2luc3RydWN0aW9uLmRpcmVjdGlvbn1gKTtcclxuICAgICAgICB9XHJcbiAgXHJcbiAgICAgICAgY29uc3QgZGlzdGFuY2VJblBpeGVscyA9IHRoaXMuY29udmVydFRvUGl4ZWxzKGluc3RydWN0aW9uLmRpc3RhbmNlLCBpbnN0cnVjdGlvbi51bml0KTtcclxuICAgICAgICBjb25zdCBuZXdYID0gY3VycmVudFBvaW50LnggKyBNYXRoLmNvcyhyYWRpYW5zKSAqIGRpc3RhbmNlSW5QaXhlbHM7XHJcbiAgICAgICAgY29uc3QgbmV3WSA9IGN1cnJlbnRQb2ludC55IC0gTWF0aC5zaW4ocmFkaWFucykgKiBkaXN0YW5jZUluUGl4ZWxzO1xyXG4gIFxyXG4gICAgICAgIGNvbnN0IG5ld1BvaW50ID0ge1xyXG4gICAgICAgICAgeDogdGhpcy5zbmFwVG9HcmlkKG5ld1gsIHRoaXMuZ3JpZFdpZHRoKSxcclxuICAgICAgICAgIHk6IHRoaXMuc25hcFRvR3JpZChuZXdZLCB0aGlzLmdyaWRIZWlnaHQpLFxyXG4gICAgICAgIH07XHJcbiAgXHJcbiAgICAgICAgY29uc3QgbGluZVNlZ21lbnQgPSBbXHJcbiAgICAgICAgICBjdXJyZW50UG9pbnQsXHJcbiAgICAgICAgICBuZXdQb2ludCxcclxuICAgICAgICAgIHtcclxuICAgICAgICAgICAgZWxlbWVudFR5cGU6IGluc3RydWN0aW9uLmVsZW1lbnRUeXBlLFxyXG4gICAgICAgICAgICBkaXN0YW5jZTogaW5zdHJ1Y3Rpb24uZGlzdGFuY2UsXHJcbiAgICAgICAgICAgIHVuaXQ6IGluc3RydWN0aW9uLnVuaXQsXHJcbiAgICAgICAgICAgIGRpcmVjdGlvbjogaW5zdHJ1Y3Rpb24uZGlyZWN0aW9uLFxyXG4gICAgICAgICAgICBhbmdsZTogaW5zdHJ1Y3Rpb24uYW5nbGUsXHJcbiAgICAgICAgICAgIGVsZW1lbnROdW1iZXI6IGluc3RydWN0aW9uLmVsZW1lbnROdW1iZXIsXHJcbiAgICAgICAgICB9LFxyXG4gICAgICAgIF07XHJcbiAgXHJcbiAgICAgICAgZXhwb3J0TGF5b3V0LnB1c2gobGluZVNlZ21lbnQpO1xyXG4gICAgICAgIGN1cnJlbnRQb2ludCA9IG5ld1BvaW50O1xyXG4gICAgICB9KTtcclxuICBcclxuICAgICAgbGV0IG1pblggPSBJbmZpbml0eSxcclxuICAgICAgICBtaW5ZID0gSW5maW5pdHksXHJcbiAgICAgICAgbWF4WCA9IC1JbmZpbml0eSxcclxuICAgICAgICBtYXhZID0gLUluZmluaXR5O1xyXG4gIFxyXG4gICAgICBleHBvcnRMYXlvdXQuZm9yRWFjaCgoW3BvaW50MSwgcG9pbnQyXSkgPT4ge1xyXG4gICAgICAgIFtwb2ludDEsIHBvaW50Ml0uZm9yRWFjaCgocG9pbnQpID0+IHtcclxuICAgICAgICAgIGlmIChwb2ludC54ICE9PSB1bmRlZmluZWQpIHtcclxuICAgICAgICAgICAgbWluWCA9IE1hdGgubWluKG1pblgsIHBvaW50LngpO1xyXG4gICAgICAgICAgICBtYXhYID0gTWF0aC5tYXgobWF4WCwgcG9pbnQueCk7XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgICBpZiAocG9pbnQueSAhPT0gdW5kZWZpbmVkKSB7XHJcbiAgICAgICAgICAgIG1pblkgPSBNYXRoLm1pbihtaW5ZLCBwb2ludC55KTtcclxuICAgICAgICAgICAgbWF4WSA9IE1hdGgubWF4KG1heFksIHBvaW50LnkpO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH0pO1xyXG4gICAgICB9KTtcclxuICBcclxuICAgICAgbWluWCAtPSBwYWRkaW5nO1xyXG4gICAgICBtaW5ZIC09IHBhZGRpbmc7XHJcbiAgICAgIG1heFggKz0gcGFkZGluZztcclxuICAgICAgbWF4WSArPSBwYWRkaW5nO1xyXG4gIFxyXG4gICAgICBjYW52YXMud2lkdGggPSBtYXhYIC0gbWluWDtcclxuICAgICAgY2FudmFzLmhlaWdodCA9IG1heFkgLSBtaW5ZO1xyXG4gIFxyXG4gICAgICBjdHguZmlsbFN0eWxlID0gJ3doaXRlJztcclxuICAgICAgY3R4LmZpbGxSZWN0KDAsIDAsIGNhbnZhcy53aWR0aCwgY2FudmFzLmhlaWdodCk7XHJcbiAgXHJcbiAgICAgIGN0eC5zYXZlKCk7XHJcbiAgICAgIGN0eC50cmFuc2xhdGUoLW1pblgsIC1taW5ZKTtcclxuICAgICAgY3R4LnNjYWxlKHRoaXMuc2NhbGUsIHRoaXMuc2NhbGUpO1xyXG4gIFxyXG4gICAgICBmdW5jdGlvbiBkcmF3QXJyb3doZWFkKGN0eDogQ2FudmFzUmVuZGVyaW5nQ29udGV4dDJELCB4OiBudW1iZXIsIHk6IG51bWJlciwgYW5nbGU6IG51bWJlcikge1xyXG4gICAgICAgIGNvbnN0IHNpemUgPSA1O1xyXG4gICAgICAgIGN0eC5zYXZlKCk7XHJcbiAgICAgICAgY3R4LnRyYW5zbGF0ZSh4LCB5KTtcclxuICAgICAgICBjdHgucm90YXRlKGFuZ2xlKTtcclxuICAgICAgICBjdHguYmVnaW5QYXRoKCk7XHJcbiAgICAgICAgY3R4Lm1vdmVUbygwLCAwKTtcclxuICAgICAgICBjdHgubGluZVRvKC1zaXplLCAtc2l6ZSAvIDIpO1xyXG4gICAgICAgIGN0eC5saW5lVG8oLXNpemUsIHNpemUgLyAyKTtcclxuICAgICAgICBjdHguY2xvc2VQYXRoKCk7XHJcbiAgICAgICAgY3R4LmZpbGxTdHlsZSA9ICdibGFjayc7XHJcbiAgICAgICAgY3R4LmZpbGwoKTtcclxuICAgICAgICBjdHgucmVzdG9yZSgpO1xyXG4gICAgICB9XHJcbiAgXHJcbiAgICAgIGN0eC5iZWdpblBhdGgoKTtcclxuICAgICAgZXhwb3J0TGF5b3V0LmZvckVhY2goKGVkZ2UsIGVkZ2VJbmRleCkgPT4ge1xyXG4gICAgICAgIGNvbnN0IHBvaW50ID0gZWRnZVswXTtcclxuICAgICAgICBjb25zdCBuZXh0UG9pbnQgPSBlZGdlWzFdO1xyXG4gICAgICAgIGNvbnN0IHByb3BlcnRpZXMgPSBlZGdlWzJdO1xyXG5cclxuICAgICAgICBpZiAoZWRnZUluZGV4ID09PSAwKSBjdHgubW92ZVRvKHBvaW50LngsIHBvaW50LnkpO1xyXG4gICAgICAgIGN0eC5saW5lVG8obmV4dFBvaW50LngsIG5leHRQb2ludC55KTtcclxuXHJcbiAgICAgICAgY29uc3QgZHggPSBuZXh0UG9pbnQueCAtIHBvaW50Lng7XHJcbiAgICAgICAgY29uc3QgZHkgPSBuZXh0UG9pbnQueSAtIHBvaW50Lnk7XHJcbiAgICAgICAgY29uc3QgbGVuZ3RoID0gTWF0aC5zcXJ0KGR4ICogZHggKyBkeSAqIGR5KTtcclxuICAgICAgICBjb25zdCBvZmZzZXRYID0gKGR5IC8gbGVuZ3RoKSAqIDIwO1xyXG4gICAgICAgIGNvbnN0IG9mZnNldFkgPSAoLWR4IC8gbGVuZ3RoKSAqIDIwO1xyXG5cclxuICAgICAgICBjb25zdCBib3hQb2ludHMgPSBbXHJcbiAgICAgICAgICB7IHg6IHBvaW50LngsIHk6IHBvaW50LnkgfSxcclxuICAgICAgICAgIHsgeDogbmV4dFBvaW50LngsIHk6IG5leHRQb2ludC55IH0sXHJcbiAgICAgICAgICB7IHg6IG5leHRQb2ludC54ICsgb2Zmc2V0WCwgeTogbmV4dFBvaW50LnkgKyBvZmZzZXRZIH0sXHJcbiAgICAgICAgICB7IHg6IHBvaW50LnggKyBvZmZzZXRYLCB5OiBwb2ludC55ICsgb2Zmc2V0WSB9LFxyXG4gICAgICAgIF07XHJcblxyXG4gICAgICAgIGN0eC5iZWdpblBhdGgoKTtcclxuICAgICAgICBjdHgubW92ZVRvKGJveFBvaW50c1swXS54LCBib3hQb2ludHNbMF0ueSk7XHJcbiAgICAgICAgYm94UG9pbnRzLmZvckVhY2goKHB0LCBpbmRleCkgPT4ge1xyXG4gICAgICAgICAgaWYgKHByb3BlcnRpZXMuZWxlbWVudFR5cGUgPT09ICdlbnRyYW5jZScpIHtcclxuICAgICAgICAgICAgaWYgKGluZGV4IDwgMikge1xyXG4gICAgICAgICAgICAgIGN0eC5saW5lVG8ocHQueCwgcHQueSlcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgY3R4LmxpbmVUbyhwdC54LCBwdC55KTtcclxuICAgICAgICAgIH1cclxuICAgICAgICB9KTtcclxuICAgICAgICBpZiAocHJvcGVydGllcy5lbGVtZW50VHlwZSA9PT0gJ29wZW5pbmcnKSB7XHJcbiAgICAgICAgICBjdHguY2xvc2VQYXRoKCk7XHJcbiAgICAgICAgICBjdHguZmlsbFN0eWxlID0gJyNGOUZBRkInO1xyXG4gICAgICAgICAgY3R4LmZpbGwoKTtcclxuXHJcbiAgICAgICAgICBjdHguc3Ryb2tlU3R5bGUgPSAnI0Y5RkFGQic7XHJcblxyXG4gICAgICAgICAgY3R4LnN0cm9rZSgpO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICBjdHguY2xvc2VQYXRoKCk7XHJcbiAgICAgICAgICBjdHguZmlsbFN0eWxlID0gJyNGOUZBRkInO1xyXG4gICAgICAgICAgY3R4LmZpbGwoKTtcclxuICAgICAgICAgIGN0eC5zdHJva2VTdHlsZSA9ICcjMUQyOTM5JztcclxuICAgICAgICAgIGN0eC5zdHJva2UoKTtcclxuICAgICAgICB9XHJcblxyXG5cclxuICAgICAgICBjb25zdCB0ZXh0WCA9IChib3hQb2ludHNbMV0ueCArIGJveFBvaW50c1szXS54KSAvIDI7XHJcbiAgICAgICAgY29uc3QgdGV4dFkgPSAoYm94UG9pbnRzWzFdLnkgKyBib3hQb2ludHNbM10ueSkgLyAyO1xyXG5cclxuICAgICAgICBjdHguc2F2ZSgpO1xyXG4gICAgICAgIGN0eC50cmFuc2xhdGUodGV4dFgsIHRleHRZKTtcclxuXHJcbiAgICAgICAgaWYgKGR4ID09PSAwKSB7XHJcbiAgICAgICAgICBjdHgucm90YXRlKC1NYXRoLlBJIC8gMik7XHJcbiAgICAgICAgfSBlbHNlIGlmIChkeSAhPT0gMCkge1xyXG4gICAgICAgICAgY29uc3QgYW5nbGUgPSBNYXRoLmF0YW4yKGR5LCBkeCk7XHJcbiAgICAgICAgICBjdHgucm90YXRlKGFuZ2xlKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGN0eC5mb250ID0gJzEycHggQXJpYWwnO1xyXG4gICAgICAgIGN0eC5maWxsU3R5bGUgPSAnYmxhY2snO1xyXG4gICAgICAgIGN0eC50ZXh0QWxpZ24gPSAnY2VudGVyJztcclxuICAgICAgICBjdHgudGV4dEJhc2VsaW5lID0gJ21pZGRsZSc7XHJcbiAgICAgICAgY3R4LmZpbGxUZXh0KFxyXG4gICAgICAgICAgYCR7cHJvcGVydGllcy5lbGVtZW50VHlwZX0gJHtwcm9wZXJ0aWVzLmVsZW1lbnROdW1iZXJ9IC0gJHtwcm9wZXJ0aWVzLmRpc3RhbmNlfSAke3Byb3BlcnRpZXMudW5pdH1gLFxyXG4gICAgICAgICAgMCxcclxuICAgICAgICAgIDBcclxuICAgICAgICApO1xyXG4gICAgICAgIGN0eC5yZXN0b3JlKCk7XHJcbiAgICAgICAgaWYgKHByb3BlcnRpZXMuZGlzdGFuY2UgPj0gNCkge1xyXG4gICAgICAgICAgY29uc3QgY2VudGVyWCA9IHRleHRYO1xyXG4gICAgICAgICAgY29uc3QgY2VudGVyWSA9IHRleHRZO1xyXG4gICAgICAgICAgY29uc3QgcmlnaHRYID0gKGJveFBvaW50c1sxXS54ICsgYm94UG9pbnRzWzJdLngpIC8gMjtcclxuICAgICAgICAgIGNvbnN0IHJpZ2h0WSA9IChib3hQb2ludHNbMV0ueSArIGJveFBvaW50c1syXS55KSAvIDI7XHJcbiAgICAgICAgICBjb25zdCBsZWZ0WCA9IChib3hQb2ludHNbMF0ueCArIGJveFBvaW50c1szXS54KSAvIDI7XHJcbiAgICAgICAgICBjb25zdCBsZWZ0WSA9IChib3hQb2ludHNbMF0ueSArIGJveFBvaW50c1szXS55KSAvIDI7XHJcblxyXG4gICAgICAgICAgZnVuY3Rpb24gYWRqdXN0UG9pbnQoeDE6IGFueSwgeTE6IGFueSwgeDI6IGFueSwgeTI6IGFueSwgZGlzdGFuY2U6IGFueSkge1xyXG4gICAgICAgICAgICBjb25zdCBhbmdsZSA9IE1hdGguYXRhbjIoeTIgLSB5MSwgeDIgLSB4MSk7XHJcbiAgICAgICAgICAgIHJldHVybiB7XHJcbiAgICAgICAgICAgICAgeDogeDEgKyBNYXRoLmNvcyhhbmdsZSkgKiBkaXN0YW5jZSxcclxuICAgICAgICAgICAgICB5OiB5MSArIE1hdGguc2luKGFuZ2xlKSAqIGRpc3RhbmNlLFxyXG4gICAgICAgICAgICB9O1xyXG4gICAgICAgICAgfVxyXG5cclxuICAgICAgICAgIGNvbnN0IHJpZ2h0U3RhcnQgPSBhZGp1c3RQb2ludChjZW50ZXJYLCBjZW50ZXJZLCByaWdodFgsIHJpZ2h0WSwgNTApO1xyXG4gICAgICAgICAgY29uc3QgcmlnaHRFbmQgPSBhZGp1c3RQb2ludChyaWdodFgsIHJpZ2h0WSwgY2VudGVyWCwgY2VudGVyWSwgMTApO1xyXG4gICAgICAgICAgY29uc3QgbGVmdFN0YXJ0ID0gYWRqdXN0UG9pbnQoY2VudGVyWCwgY2VudGVyWSwgbGVmdFgsIGxlZnRZLCA1MCk7XHJcbiAgICAgICAgICBjb25zdCBsZWZ0RW5kID0gYWRqdXN0UG9pbnQobGVmdFgsIGxlZnRZLCBjZW50ZXJYLCBjZW50ZXJZLCAxMCk7XHJcblxyXG4gICAgICAgICAgY3R4LmJlZ2luUGF0aCgpO1xyXG4gICAgICAgICAgY3R4Lm1vdmVUbyhyaWdodFN0YXJ0LngsIHJpZ2h0U3RhcnQueSk7XHJcbiAgICAgICAgICBjdHgubGluZVRvKHJpZ2h0RW5kLngsIHJpZ2h0RW5kLnkpO1xyXG4gICAgICAgICAgY3R4LnN0cm9rZVN0eWxlID0gJ2JsYWNrJztcclxuICAgICAgICAgIGN0eC5zdHJva2UoKTtcclxuICAgICAgICAgIGxldCByaWdodEFuZ2xlID0gTWF0aC5hdGFuMihyaWdodEVuZC55IC0gcmlnaHRTdGFydC55LCByaWdodEVuZC54IC0gcmlnaHRTdGFydC54KTtcclxuICAgICAgICAgIGRyYXdBcnJvd2hlYWQoY3R4LCByaWdodEVuZC54LCByaWdodEVuZC55LCByaWdodEFuZ2xlKTtcclxuXHJcbiAgICAgICAgICBjdHguYmVnaW5QYXRoKCk7XHJcbiAgICAgICAgICBjdHgubW92ZVRvKGxlZnRTdGFydC54LCBsZWZ0U3RhcnQueSk7XHJcbiAgICAgICAgICBjdHgubGluZVRvKGxlZnRFbmQueCwgbGVmdEVuZC55KTtcclxuICAgICAgICAgIGN0eC5zdHJva2VTdHlsZSA9ICdibGFjayc7XHJcbiAgICAgICAgICBjdHguc3Ryb2tlKCk7XHJcbiAgICAgICAgICBsZXQgbGVmdEFuZ2xlID0gTWF0aC5hdGFuMihsZWZ0RW5kLnkgLSBsZWZ0U3RhcnQueSwgbGVmdEVuZC54IC0gbGVmdFN0YXJ0LngpO1xyXG4gICAgICAgICAgZHJhd0Fycm93aGVhZChjdHgsIGxlZnRFbmQueCwgbGVmdEVuZC55LCBsZWZ0QW5nbGUpO1xyXG5cclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmIChwcm9wZXJ0aWVzLmVsZW1lbnRUeXBlID09PSAnZW50cmFuY2UnKSB7XHJcbiAgICAgICAgICBjb25zdCBhbmdsZSA9IE1hdGguYXRhbjIobmV4dFBvaW50LnkgLSBwb2ludC55LCBuZXh0UG9pbnQueCAtIHBvaW50LngpO1xyXG5cclxuICAgICAgICAgIGNvbnN0IGVudHJhbmNlQW5nbGUgPSBhbmdsZSArICgxNSAqIE1hdGguUEkpIC8gMTgwO1xyXG5cclxuICAgICAgICAgIGNvbnN0IGxpbmVMZW5ndGggPSB0aGlzLmNvbnZlcnRUb1BpeGVscyhwcm9wZXJ0aWVzLmRpc3RhbmNlLCBwcm9wZXJ0aWVzLnVuaXQpICogMC43NTtcclxuICAgICAgICAgIGNvbnN0IGVuZFBvaW50ID0ge1xyXG4gICAgICAgICAgICB4OiBwb2ludC54ICsgTWF0aC5jb3MoZW50cmFuY2VBbmdsZSkgKiBsaW5lTGVuZ3RoLFxyXG4gICAgICAgICAgICB5OiBwb2ludC55ICsgTWF0aC5zaW4oZW50cmFuY2VBbmdsZSkgKiBsaW5lTGVuZ3RoLFxyXG4gICAgICAgICAgfTtcclxuXHJcbiAgICAgICAgICBjdHguYmVnaW5QYXRoKCk7XHJcbiAgICAgICAgICBjdHgubW92ZVRvKHBvaW50LngsIHBvaW50LnkpO1xyXG4gICAgICAgICAgY3R4LmxpbmVUbyhlbmRQb2ludC54LCBlbmRQb2ludC55KTtcclxuICAgICAgICAgIGN0eC5zdHJva2VTdHlsZSA9ICcjMUQyOTM5JztcclxuICAgICAgICAgIGN0eC5zdHJva2UoKTtcclxuICAgICAgICB9XHJcbiAgICAgIH0pO1xyXG4gIFxyXG4gICAgICBjdHgucmVzdG9yZSgpO1xyXG4gIFxyXG4gICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUpID0+IHtcclxuICAgICAgICBjYW52YXMudG9CbG9iKChibG9iOmFueSkgPT4ge1xyXG4gICAgICAgICAgY29uc3QgbGluayA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2EnKTtcclxuICAgICAgICAgIGxpbmsuZG93bmxvYWQgPSBgJHt0aGlzLnNlbGVjdGVkU3RvcmUuc3RvcmVOYW1lfV8ke3RoaXMuc2VsZWN0ZWRGbG9vci5mbG9vck5hbWV9X2xheW91dC5wbmdgO1xyXG4gICAgICAgICAgbGluay5ocmVmID0gVVJMLmNyZWF0ZU9iamVjdFVSTChibG9iKTtcclxuICAgICAgICAgIGxpbmsuY2xpY2soKTtcclxuICAgICAgICAgIGNhbnZhcy5yZW1vdmUoKTtcclxuICAgICAgICAgIHJlc29sdmUoJycpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgICB9KTtcclxuICAgIH07XHJcbiAgXHJcbiAgICBjb25zdCBsYXlvdXRJbnN0cnVjdGlvbnMgPSB0aGlzLmxheW91dFBvbHlnb24ubWFwKChzZWdtZW50KSA9PiB7XHJcbiAgICAgIGNvbnN0IFssICwgcHJvcGVydGllc10gPSBzZWdtZW50O1xyXG4gICAgICByZXR1cm4gcHJvcGVydGllcztcclxuICAgIH0pO1xyXG4gIFxyXG4gICAgYXdhaXQgcmVuZGVyQ2FudmFzKGxheW91dEluc3RydWN0aW9ucyk7XHJcbiAgfVxyXG4gIFxyXG5cclxuICBnZW5lcmF0ZUxheW91dFBvbHlnb24obGF5b3V0SW5zdHJ1Y3Rpb25zOiBhbnkpIHtcclxuICAgIHRoaXMucGl4ZWxQZXJNZXRyZSA9IHRoaXMubm9ybWFsaXplZFBpeGVsUGVyTWV0cmUobGF5b3V0SW5zdHJ1Y3Rpb25zKVxyXG5cclxuICAgIHRoaXMubGF5b3V0UG9seWdvbiA9IFtdO1xyXG5cclxuICAgIGNvbnN0IGNlbnRlclggPSB0aGlzLmNhbnZhcy53aWR0aCAvIDIgLyB0aGlzLnNjYWxlO1xyXG4gICAgY29uc3QgY2VudGVyWSA9IHRoaXMuY2FudmFzLmhlaWdodCAvIDIgLyB0aGlzLnNjYWxlO1xyXG5cclxuICAgIGlmICghbGF5b3V0SW5zdHJ1Y3Rpb25zLmxlbmd0aCkge1xyXG4gICAgICB0aGlzLmluaXRpYWxpemVMYXlvdXQoKVxyXG4gICAgICB0aGlzLnJlZHJhd0NhbnZhcygpXHJcbiAgICAgIHJldHVyblxyXG4gICAgfVxyXG5cclxuICAgIGxldCBjdXJyZW50UG9pbnQgPSB7XHJcbiAgICAgIFwieFwiOiB0aGlzLnNuYXBUb0dyaWQoY2VudGVyWCwgdGhpcy5ncmlkSGVpZ2h0KSxcclxuICAgICAgXCJ5XCI6IHRoaXMuc25hcFRvR3JpZChjZW50ZXJZLCB0aGlzLmdyaWRXaWR0aClcclxuICAgIH07XHJcblxyXG4gICAgbGF5b3V0SW5zdHJ1Y3Rpb25zLmZvckVhY2goKGluc3RydWN0aW9uOiBhbnkpID0+IHtcclxuICAgICAgY29uc3QgcmFkaWFuczogbnVtYmVyID0ge1xyXG4gICAgICAgICd1cCc6ICgoMTgwIC0gaW5zdHJ1Y3Rpb24uYW5nbGUpICogTWF0aC5QSSkgLyAxODAsXHJcbiAgICAgICAgJ2xlZnQnOiAoKDI3MCAtIGluc3RydWN0aW9uLmFuZ2xlKSAqIE1hdGguUEkpIC8gMTgwLFxyXG4gICAgICAgICdkb3duJzogKCgzNjAgLSBpbnN0cnVjdGlvbi5hbmdsZSkgKiBNYXRoLlBJKSAvIDE4MCxcclxuICAgICAgICAncmlnaHQnOiAoKDkwIC0gaW5zdHJ1Y3Rpb24uYW5nbGUpICogTWF0aC5QSSkgLyAxODAsXHJcbiAgICAgIH1baW5zdHJ1Y3Rpb24uZGlyZWN0aW9uIGFzICd1cCcgfCAnbGVmdCcgfCAnZG93bicgfCAncmlnaHQnXTtcclxuXHJcbiAgICAgIGlmIChyYWRpYW5zID09PSB1bmRlZmluZWQpIHtcclxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYEludmFsaWQgZGlyZWN0aW9uOiAke2luc3RydWN0aW9uLmRpcmVjdGlvbn1gKTtcclxuICAgICAgfVxyXG5cclxuICAgICAgY29uc3QgZGlzdGFuY2VJblBpeGVscyA9IHRoaXMuY29udmVydFRvUGl4ZWxzKGluc3RydWN0aW9uLmRpc3RhbmNlLCBpbnN0cnVjdGlvbi51bml0KTtcclxuICAgICAgY29uc3QgbmV3WCA9IGN1cnJlbnRQb2ludC54ICsgTWF0aC5jb3MocmFkaWFucykgKiBkaXN0YW5jZUluUGl4ZWxzO1xyXG4gICAgICBjb25zdCBuZXdZID0gY3VycmVudFBvaW50LnkgLSBNYXRoLnNpbihyYWRpYW5zKSAqIGRpc3RhbmNlSW5QaXhlbHM7XHJcblxyXG4gICAgICBjb25zdCBuZXdQb2ludCA9IHtcclxuICAgICAgICB4OiB0aGlzLnNuYXBUb0dyaWQobmV3WCwgdGhpcy5ncmlkV2lkdGgpLFxyXG4gICAgICAgIHk6IHRoaXMuc25hcFRvR3JpZChuZXdZLCB0aGlzLmdyaWRIZWlnaHQpLFxyXG4gICAgICB9O1xyXG5cclxuICAgICAgY29uc3QgbGluZVNlZ21lbnQgPSBbXHJcbiAgICAgICAgY3VycmVudFBvaW50LFxyXG4gICAgICAgIG5ld1BvaW50LFxyXG4gICAgICAgIHtcclxuICAgICAgICAgIGVsZW1lbnRUeXBlOiBpbnN0cnVjdGlvbi5lbGVtZW50VHlwZSxcclxuICAgICAgICAgIGRpc3RhbmNlOiBpbnN0cnVjdGlvbi5kaXN0YW5jZSxcclxuICAgICAgICAgIHVuaXQ6IGluc3RydWN0aW9uLnVuaXQsXHJcbiAgICAgICAgICBkaXJlY3Rpb246IGluc3RydWN0aW9uLmRpcmVjdGlvbixcclxuICAgICAgICAgIGFuZ2xlOiBpbnN0cnVjdGlvbi5hbmdsZSxcclxuICAgICAgICAgIGVsZW1lbnROdW1iZXI6IGluc3RydWN0aW9uLmVsZW1lbnROdW1iZXIsXHJcbiAgICAgICAgfSxcclxuICAgICAgXTtcclxuXHJcbiAgICAgIHRoaXMubGF5b3V0UG9seWdvbi5wdXNoKGxpbmVTZWdtZW50KTtcclxuXHJcbiAgICAgIGN1cnJlbnRQb2ludCA9IG5ld1BvaW50O1xyXG4gICAgfSk7XHJcblxyXG5cclxuICAgIGNvbnN0IGxhc3RQb2ludCA9IHRoaXMubGF5b3V0UG9seWdvblt0aGlzLmxheW91dFBvbHlnb24ubGVuZ3RoIC0gMV1bMV1cclxuXHJcbiAgICBpZiAodGhpcy5pc0Zsb29yQ29tcGxldGVkKGxheW91dEluc3RydWN0aW9ucykpIHtcclxuICAgICAgdGhpcy5maW5kUG9seWdvbkNlbnRlckFuZFNjcm9sbCgpXHJcbiAgICAgIHRoaXMuY2xvc2VXaWRnZXQoKVxyXG4gICAgfSBlbHNlIHtcclxuICAgICAgdGhpcy5vcGVuV2lkZ2V0KGxhc3RQb2ludClcclxuICAgIH1cclxuXHJcbiAgICB0aGlzLnJlZHJhd0NhbnZhcygpXHJcblxyXG4gIH1cclxuXHJcbiAgbm9ybWFsaXplZFBpeGVsUGVyTWV0cmUocG9seWdvbjogYW55KTogbnVtYmVyIHtcclxuICAgIGNvbnN0IE1JTl9QSVhFTFNfUEVSX01FVEVSID0gNTA7XHJcbiAgICBjb25zdCBNQVhfUElYRUxTX1BFUl9NRVRFUiA9IDE1MDtcclxuXHJcbiAgICBsZXQgdG90YWxMZW5ndGggPSAwO1xyXG4gICAgbGV0IGxpbmVDb3VudCA9IDA7XHJcblxyXG4gICAgcG9seWdvbi5mb3JFYWNoKChsaW5lOiBhbnkpID0+IHtcclxuICAgICAgaWYgKGxpbmUudW5pdCA9PT0gJ2Z0Jykge1xyXG4gICAgICAgIHRvdGFsTGVuZ3RoID0gdG90YWxMZW5ndGggKyAobGluZS5kaXN0YW5jZSAqIDMuMjgwODQpO1xyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIHRvdGFsTGVuZ3RoID0gdG90YWxMZW5ndGggKyBsaW5lLmRpc3RhbmNlO1xyXG4gICAgICB9XHJcbiAgICAgIGxpbmVDb3VudCsrO1xyXG4gICAgfSk7XHJcblxyXG4gICAgY29uc3QgYXZlcmFnZUxlbmd0aCA9IGxpbmVDb3VudCA+IDAgPyB0b3RhbExlbmd0aCAvIGxpbmVDb3VudCA6IDA7XHJcblxyXG4gICAgY29uc3QgTUFYX0FWRVJBR0VfTEVOR1RIID0gNTA7XHJcbiAgICBjb25zdCBNSU5fQVZFUkFHRV9MRU5HVEggPSA1O1xyXG5cclxuICAgIGNvbnN0IG5vcm1hbGl6ZWRMZW5ndGggPSBNYXRoLm1pbihcclxuICAgICAgTWF0aC5tYXgoYXZlcmFnZUxlbmd0aCwgTUlOX0FWRVJBR0VfTEVOR1RIKSxcclxuICAgICAgTUFYX0FWRVJBR0VfTEVOR1RIXHJcbiAgICApO1xyXG5cclxuICAgIGNvbnN0IHBpeGVsc1Blck1ldGVyID1cclxuICAgICAgTUFYX1BJWEVMU19QRVJfTUVURVIgLVxyXG4gICAgICAoKG5vcm1hbGl6ZWRMZW5ndGggLSBNSU5fQVZFUkFHRV9MRU5HVEgpIC8gKE1BWF9BVkVSQUdFX0xFTkdUSCAtIE1JTl9BVkVSQUdFX0xFTkdUSCkpICpcclxuICAgICAgKE1BWF9QSVhFTFNfUEVSX01FVEVSIC0gTUlOX1BJWEVMU19QRVJfTUVURVIpO1xyXG5cclxuICAgIHJldHVybiBNYXRoLnJvdW5kKHBpeGVsc1Blck1ldGVyKTtcclxuICB9XHJcblxyXG4gIGlzRmxvb3JDb21wbGV0ZWQobGF5b3V0SW5zdHJ1Y3Rpb25zOiBhbnksIHRocmVzaG9sZEluRmVldDogbnVtYmVyID0gMSk6IGJvb2xlYW4ge1xyXG4gICAgY29uc3QgbGF5b3V0UG9seWdvbjogYW55W10gPSBbXTtcclxuICAgIGNvbnN0IGNlbnRlclggPSB0aGlzLmNhbnZhcy53aWR0aCAvIDIgLyB0aGlzLnNjYWxlO1xyXG4gICAgY29uc3QgY2VudGVyWSA9IHRoaXMuY2FudmFzLmhlaWdodCAvIDIgLyB0aGlzLnNjYWxlO1xyXG5cclxuICAgIGxldCBjdXJyZW50UG9pbnQgPSB7XHJcbiAgICAgIHg6IHRoaXMuc25hcFRvR3JpZChjZW50ZXJYLCB0aGlzLmdyaWRIZWlnaHQpLFxyXG4gICAgICB5OiB0aGlzLnNuYXBUb0dyaWQoY2VudGVyWSwgdGhpcy5ncmlkV2lkdGgpLFxyXG4gICAgfTtcclxuXHJcbiAgICBsYXlvdXRJbnN0cnVjdGlvbnMuZm9yRWFjaCgoaW5zdHJ1Y3Rpb246IGFueSkgPT4ge1xyXG4gICAgICBjb25zdCByYWRpYW5zOiBudW1iZXIgPSB7XHJcbiAgICAgICAgJ3VwJzogKCgxODAgLSBpbnN0cnVjdGlvbi5hbmdsZSkgKiBNYXRoLlBJKSAvIDE4MCxcclxuICAgICAgICAnbGVmdCc6ICgoMjcwIC0gaW5zdHJ1Y3Rpb24uYW5nbGUpICogTWF0aC5QSSkgLyAxODAsXHJcbiAgICAgICAgJ2Rvd24nOiAoKDM2MCAtIGluc3RydWN0aW9uLmFuZ2xlKSAqIE1hdGguUEkpIC8gMTgwLFxyXG4gICAgICAgICdyaWdodCc6ICgoOTAgLSBpbnN0cnVjdGlvbi5hbmdsZSkgKiBNYXRoLlBJKSAvIDE4MCxcclxuICAgICAgfVtpbnN0cnVjdGlvbi5kaXJlY3Rpb24gYXMgJ3VwJyB8ICdsZWZ0JyB8ICdkb3duJyB8ICdyaWdodCddO1xyXG5cclxuICAgICAgaWYgKHJhZGlhbnMgPT09IHVuZGVmaW5lZCkge1xyXG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgSW52YWxpZCBkaXJlY3Rpb246ICR7aW5zdHJ1Y3Rpb24uZGlyZWN0aW9ufWApO1xyXG4gICAgICB9XHJcblxyXG4gICAgICBjb25zdCBkaXN0YW5jZUluUGl4ZWxzID0gdGhpcy5jb252ZXJ0VG9QaXhlbHMoaW5zdHJ1Y3Rpb24uZGlzdGFuY2UsIGluc3RydWN0aW9uLnVuaXQpO1xyXG4gICAgICBjb25zdCBuZXdYID0gY3VycmVudFBvaW50LnggKyBNYXRoLmNvcyhyYWRpYW5zKSAqIGRpc3RhbmNlSW5QaXhlbHM7XHJcbiAgICAgIGNvbnN0IG5ld1kgPSBjdXJyZW50UG9pbnQueSAtIE1hdGguc2luKHJhZGlhbnMpICogZGlzdGFuY2VJblBpeGVscztcclxuXHJcbiAgICAgIGNvbnN0IG5ld1BvaW50ID0ge1xyXG4gICAgICAgIHg6IHRoaXMuc25hcFRvR3JpZChuZXdYLCB0aGlzLmdyaWRXaWR0aCksXHJcbiAgICAgICAgeTogdGhpcy5zbmFwVG9HcmlkKG5ld1ksIHRoaXMuZ3JpZEhlaWdodCksXHJcbiAgICAgIH07XHJcblxyXG4gICAgICBjb25zdCBsaW5lU2VnbWVudCA9IFtcclxuICAgICAgICBjdXJyZW50UG9pbnQsXHJcbiAgICAgICAgbmV3UG9pbnQsXHJcbiAgICAgICAge1xyXG4gICAgICAgICAgZWxlbWVudFR5cGU6IGluc3RydWN0aW9uLmVsZW1lbnRUeXBlLFxyXG4gICAgICAgICAgZGlzdGFuY2U6IGluc3RydWN0aW9uLmRpc3RhbmNlLFxyXG4gICAgICAgICAgdW5pdDogaW5zdHJ1Y3Rpb24udW5pdCxcclxuICAgICAgICAgIGRpcmVjdGlvbjogaW5zdHJ1Y3Rpb24uZGlyZWN0aW9uLFxyXG4gICAgICAgICAgYW5nbGU6IGluc3RydWN0aW9uLmFuZ2xlLFxyXG4gICAgICAgICAgZWxlbWVudE51bWJlcjogaW5zdHJ1Y3Rpb24uZWxlbWVudE51bWJlcixcclxuICAgICAgICB9LFxyXG4gICAgICBdO1xyXG5cclxuICAgICAgbGF5b3V0UG9seWdvbi5wdXNoKGxpbmVTZWdtZW50KTtcclxuICAgICAgY3VycmVudFBvaW50ID0gbmV3UG9pbnQ7XHJcbiAgICB9KTtcclxuXHJcbiAgICBjb25zdCBmaXJzdFBvaW50ID0gbGF5b3V0UG9seWdvbj8uWzBdPy5bMF07XHJcbiAgICBjb25zdCBsYXN0UG9pbnQgPSBsYXlvdXRQb2x5Z29uPy5bbGF5b3V0UG9seWdvbi5sZW5ndGggLSAxXT8uWzFdO1xyXG5cclxuICAgIGlmIChsYXlvdXRQb2x5Z29uLmxlbmd0aCA8PSAxIHx8ICFmaXJzdFBvaW50IHx8ICFsYXN0UG9pbnQpIHtcclxuICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgfVxyXG5cclxuICAgIGNvbnN0IGRpc3RhbmNlQmV0d2VlblBvaW50cyA9IE1hdGguc3FydChcclxuICAgICAgTWF0aC5wb3cobGFzdFBvaW50LnggLSBmaXJzdFBvaW50LngsIDIpICsgTWF0aC5wb3cobGFzdFBvaW50LnkgLSBmaXJzdFBvaW50LnksIDIpXHJcbiAgICApO1xyXG5cclxuICAgIGNvbnN0IHRocmVzaG9sZEluUGl4ZWxzID0gdGhpcy5jb252ZXJ0VG9QaXhlbHModGhyZXNob2xkSW5GZWV0LCAnZnQnKTtcclxuICAgIHJldHVybiBkaXN0YW5jZUJldHdlZW5Qb2ludHMgPD0gdGhyZXNob2xkSW5QaXhlbHM7XHJcbiAgfVxyXG5cclxuXHJcbiAgdmFsaWRhdGVBbmdsZUlucHV0KGV2ZW50OiBFdmVudCwgaW5kZXg6IG51bWJlcikge1xyXG4gICAgY29uc3QgaW5wdXRFbGVtZW50ID0gZXZlbnQudGFyZ2V0IGFzIEhUTUxJbnB1dEVsZW1lbnQ7XHJcbiAgICBsZXQgdmFsdWUgPSBwYXJzZUludChpbnB1dEVsZW1lbnQudmFsdWUsIDEwKTtcclxuXHJcbiAgICBpZiAoaXNOYU4odmFsdWUpKSB7XHJcbiAgICAgIHZhbHVlID0gMDtcclxuICAgIH1cclxuXHJcbiAgICBpZiAodmFsdWUgPCAwKSB7XHJcbiAgICAgIHZhbHVlID0gMDtcclxuICAgIH0gZWxzZSBpZiAodmFsdWUgPiAxODApIHtcclxuICAgICAgdmFsdWUgPSAxODA7XHJcbiAgICB9XHJcblxyXG4gICAgaW5wdXRFbGVtZW50LnZhbHVlID0gdmFsdWUudG9TdHJpbmcoKTtcclxuICAgIHRoaXMubGF5b3V0UG9seWdvbltpbmRleF1bMl0uYW5nbGUgPSB2YWx1ZTtcclxuXHJcblxyXG4gIH1cclxuXHJcbiAgb25BbmdsZUNoYW5nZShpbmRleDogbnVtYmVyKSB7XHJcbiAgICB0aGlzLnNhdmVTdGF0ZVRvVW5kbygpXHJcbiAgICBjb25zdCBbcG9pbnQxLCBwb2ludDIsIHByb3BlcnRpZXNdID0gdGhpcy5sYXlvdXRQb2x5Z29uW2luZGV4XTtcclxuXHJcbiAgICBsZXQgcmFkaWFuczogbnVtYmVyO1xyXG4gICAgc3dpdGNoIChwcm9wZXJ0aWVzLmRpcmVjdGlvbikge1xyXG4gICAgICBjYXNlICd1cCc6XHJcbiAgICAgICAgcmFkaWFucyA9ICgoMTgwIC0gcHJvcGVydGllcy5hbmdsZSkgKiBNYXRoLlBJKSAvIDE4MDtcclxuICAgICAgICBicmVhaztcclxuICAgICAgY2FzZSAnbGVmdCc6XHJcbiAgICAgICAgcmFkaWFucyA9ICgoMjcwIC0gcHJvcGVydGllcy5hbmdsZSkgKiBNYXRoLlBJKSAvIDE4MDtcclxuICAgICAgICBicmVhaztcclxuICAgICAgY2FzZSAnZG93bic6XHJcbiAgICAgICAgcmFkaWFucyA9ICgoMzYwIC0gcHJvcGVydGllcy5hbmdsZSkgKiBNYXRoLlBJKSAvIDE4MDtcclxuICAgICAgICBicmVhaztcclxuICAgICAgY2FzZSAncmlnaHQnOlxyXG4gICAgICAgIHJhZGlhbnMgPSAoKDkwIC0gcHJvcGVydGllcy5hbmdsZSkgKiBNYXRoLlBJKSAvIDE4MDtcclxuICAgICAgICBicmVhaztcclxuICAgICAgZGVmYXVsdDpcclxuICAgICAgICByZXR1cm47XHJcbiAgICB9XHJcblxyXG4gICAgY29uc3QgbW92ZW1lbnREaXN0YW5jZSA9IHRoaXMuY29udmVydFRvUGl4ZWxzKHByb3BlcnRpZXMuZGlzdGFuY2UsIHByb3BlcnRpZXMudW5pdCk7XHJcblxyXG4gICAgY29uc3QgbmV3WCA9IHBvaW50MS54ICsgTWF0aC5jb3MocmFkaWFucykgKiBtb3ZlbWVudERpc3RhbmNlO1xyXG4gICAgY29uc3QgbmV3WSA9IHBvaW50MS55IC0gTWF0aC5zaW4ocmFkaWFucykgKiBtb3ZlbWVudERpc3RhbmNlO1xyXG5cclxuICAgIGNvbnN0IHNuYXBwZWRYID0gdGhpcy5zbmFwVG9HcmlkKG5ld1gsIHRoaXMuZ3JpZFdpZHRoKTtcclxuICAgIGNvbnN0IHNuYXBwZWRZID0gdGhpcy5zbmFwVG9HcmlkKG5ld1ksIHRoaXMuZ3JpZEhlaWdodCk7XHJcblxyXG4gICAgcG9pbnQyLnggPSBzbmFwcGVkWDtcclxuICAgIHBvaW50Mi55ID0gc25hcHBlZFk7XHJcbiAgICBwcm9wZXJ0aWVzLmFuZ2xlID0gdGhpcy5sYXlvdXRQb2x5Z29uW2luZGV4XVsyXS5hbmdsZTtcclxuXHJcbiAgICB0aGlzLmxheW91dFBvbHlnb25baW5kZXhdID0gW3BvaW50MSwgcG9pbnQyLCBwcm9wZXJ0aWVzXTtcclxuXHJcbiAgICB0aGlzLnJlZG9TdGFjayA9IFtdO1xyXG4gICAgdGhpcy5yZWRyYXdDYW52YXMoKVxyXG4gIH1cclxuXHJcbiAgb3BlbkFkZEZsb29yTW9kYWwoKSB7XHJcbiAgICBjb25zdCBtb2RlbFJlZiA9IHRoaXMubW9kYWxEZWYub3BlbihBZGRGbG9vckNvbXBvbmVudCwgeyBjZW50ZXJlZDogdHJ1ZSB9KTtcclxuICAgIG1vZGVsUmVmLnJlc3VsdC50aGVuKCh2YWw6IGFueSkgPT4ge1xyXG4gICAgICBpZiAodmFsLmZsb29yTnVtYmVyKSB7XHJcbiAgICAgICAgdGhpcy5hZGRGbG9vcih0aGlzLnNlbGVjdGVkU3RvcmUucGxhbm9JZCwgdmFsLmZsb29yTnVtYmVyKVxyXG4gICAgICB9XHJcbiAgICB9KS5jYXRjaCgoZXJyKSA9PiB7XHJcbiAgICAgIGlmIChlcnIuZmxvb3JOdW1iZXIpIHtcclxuICAgICAgICB0aGlzLmFkZEZsb29yKHRoaXMuc2VsZWN0ZWRTdG9yZS5wbGFub0lkLCBlcnIuZmxvb3JOdW1iZXIpXHJcbiAgICAgIH1cclxuICAgIH0pXHJcblxyXG4gIH1cclxuXHJcblxyXG4gIGZpbmRQb2x5Z29uQ2VudGVyQW5kU2Nyb2xsKHBvbHlnb246IGFueSA9IHRoaXMubGF5b3V0UG9seWdvbik6IHZvaWQge1xyXG4gICAgY29uc3QgdmVydGljZXMgPSBwb2x5Z29uLmZsYXRNYXAoKGxpbmU6IGFueSkgPT4gbGluZS5zbGljZSgwLCAyKSk7XHJcblxyXG4gICAgY29uc3QgbWluWCA9IE1hdGgubWluKC4uLnZlcnRpY2VzLm1hcCgodjogYW55KSA9PiB2LngpKTtcclxuICAgIGNvbnN0IG1heFggPSBNYXRoLm1heCguLi52ZXJ0aWNlcy5tYXAoKHY6IGFueSkgPT4gdi54KSk7XHJcbiAgICBjb25zdCBtaW5ZID0gTWF0aC5taW4oLi4udmVydGljZXMubWFwKCh2OiBhbnkpID0+IHYueSkpO1xyXG4gICAgY29uc3QgbWF4WSA9IE1hdGgubWF4KC4uLnZlcnRpY2VzLm1hcCgodjogYW55KSA9PiB2LnkpKTtcclxuXHJcbiAgICBsZXQgY2VudGVyID0geyB4OiAobWluWCArIG1heFgpIC8gMiwgeTogKG1pblkgKyBtYXhZKSAvIDIgfTtcclxuXHJcbiAgICBjb25zdCBzdGVwID0gMTtcclxuICAgIGxldCBiZXN0UG9pbnQgPSBjZW50ZXI7XHJcbiAgICBsZXQgYmVzdERpc3RhbmNlU3VtID0gTnVtYmVyLk1BWF9WQUxVRTtcclxuXHJcbiAgICBmb3IgKGxldCB4ID0gbWluWDsgeCA8PSBtYXhYOyB4ICs9IHN0ZXApIHtcclxuICAgICAgZm9yIChsZXQgeSA9IG1pblk7IHkgPD0gbWF4WTsgeSArPSBzdGVwKSB7XHJcbiAgICAgICAgY29uc3QgcG9pbnQgPSB7IHgsIHkgfTtcclxuICAgICAgICBpZiAoaXNQb2ludEluc2lkZVBvbHlnb24ocG9pbnQsIHZlcnRpY2VzKSkge1xyXG4gICAgICAgICAgY29uc3QgZGlzdGFuY2VTdW0gPSB2ZXJ0aWNlcy5yZWR1Y2UoXHJcbiAgICAgICAgICAgIChzdW06IG51bWJlciwgdmVydGV4OiBhbnkpID0+IHN1bSArIE1hdGguc3FydCgocG9pbnQueCAtIHZlcnRleC54KSAqKiAyICsgKHBvaW50LnkgLSB2ZXJ0ZXgueSkgKiogMiksXHJcbiAgICAgICAgICAgIDBcclxuICAgICAgICAgICk7XHJcbiAgICAgICAgICBpZiAoZGlzdGFuY2VTdW0gPCBiZXN0RGlzdGFuY2VTdW0pIHtcclxuICAgICAgICAgICAgYmVzdERpc3RhbmNlU3VtID0gZGlzdGFuY2VTdW07XHJcbiAgICAgICAgICAgIGJlc3RQb2ludCA9IHBvaW50O1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIGNvbnN0IHNjcm9sbENvbnRhaW5lciA9IHRoaXMuc2Nyb2xsQ29udGFpbmVyUmVmLm5hdGl2ZUVsZW1lbnQ7XHJcbiAgICBzY3JvbGxDb250YWluZXIuc2Nyb2xsVG8oe1xyXG4gICAgICBsZWZ0OiBiZXN0UG9pbnQueCAtIHNjcm9sbENvbnRhaW5lci5vZmZzZXRXaWR0aCAvIDIsXHJcbiAgICAgIHRvcDogYmVzdFBvaW50LnkgLSBzY3JvbGxDb250YWluZXIub2Zmc2V0SGVpZ2h0IC8gMixcclxuICAgICAgYmVoYXZpb3I6ICdzbW9vdGgnXHJcbiAgICB9KTtcclxuXHJcbiAgICB0aGlzLnJlc2V0Wm9vbSgpXHJcbiAgICB0aGlzLnJlc2V0T3JpZW50YXRpb24oKVxyXG5cclxuICAgIGZ1bmN0aW9uIGlzUG9pbnRJbnNpZGVQb2x5Z29uKHBvaW50OiBhbnksIHZlcnRpY2VzOiBhbnkpOiBib29sZWFuIHtcclxuICAgICAgbGV0IGNvdW50ID0gMDtcclxuICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB2ZXJ0aWNlcy5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgIGNvbnN0IHN0YXJ0ID0gdmVydGljZXNbaV07XHJcbiAgICAgICAgY29uc3QgZW5kID0gdmVydGljZXNbKGkgKyAxKSAlIHZlcnRpY2VzLmxlbmd0aF07XHJcbiAgICAgICAgaWYgKHJheUludGVyc2VjdHNTZWdtZW50KHBvaW50LCB7IHN0YXJ0LCBlbmQgfSkpIHtcclxuICAgICAgICAgIGNvdW50Kys7XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcbiAgICAgIHJldHVybiBjb3VudCAlIDIgPT09IDE7XHJcbiAgICB9XHJcblxyXG4gICAgZnVuY3Rpb24gcmF5SW50ZXJzZWN0c1NlZ21lbnQocG9pbnQ6IGFueSwgc2VnbWVudDogYW55KTogYm9vbGVhbiB7XHJcbiAgICAgIGNvbnN0IHsgeCwgeSB9ID0gcG9pbnQ7XHJcbiAgICAgIGNvbnN0IHsgc3RhcnQsIGVuZCB9ID0gc2VnbWVudDtcclxuXHJcbiAgICAgIGlmICh5IDwgTWF0aC5taW4oc3RhcnQueSwgZW5kLnkpIHx8IHkgPiBNYXRoLm1heChzdGFydC55LCBlbmQueSkpIHtcclxuICAgICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIGNvbnN0IHQgPSAoeSAtIHN0YXJ0LnkpIC8gKGVuZC55IC0gc3RhcnQueSk7XHJcbiAgICAgIGNvbnN0IGludGVyc2VjdFggPSBzdGFydC54ICsgdCAqIChlbmQueCAtIHN0YXJ0LngpO1xyXG5cclxuICAgICAgcmV0dXJuIGludGVyc2VjdFggPj0geDtcclxuICAgIH1cclxuICB9XHJcblxyXG4gZXhwb3J0VG9FeGNlbCgpIHtcclxuXHJcbiAgIGNvbnN0IGxheW91dFBvbHlnb24gPSB0aGlzLmxheW91dFBvbHlnb24ubWFwKChzZWdtZW50KSA9PiB7XHJcbiAgICAgIGNvbnN0IFtwb2ludDEsIHBvaW50MiwgcHJvcGVydGllc10gPSBzZWdtZW50XHJcbiAgICAgIHJldHVybiBwcm9wZXJ0aWVzXHJcbiAgICB9KVxyXG5cclxuICAgIGNvbnN0IGZvcm1hdHRlZERhdGEgPSBsYXlvdXRQb2x5Z29uLm1hcCgoaXRlbTphbnksIGluZGV4Om51bWJlcikgPT4gKHtcclxuICAgICAgICAnU3RlcCc6IGluZGV4ICsgMSxcclxuICAgICAgICAnRWxlbWVudHMnOiBgJHtpdGVtLmVsZW1lbnRUeXBlfSAke2l0ZW0uZWxlbWVudE51bWJlcn1gLFxyXG4gICAgICAgICdNZWFzdXJlbWVudHMoZnQpJzogaXRlbS5kaXN0YW5jZSxcclxuICAgICAgICAnRGlyZWN0aW9uJzogaXRlbS5kaXJlY3Rpb24sXHJcbiAgICAgICAgJ0RlZ3JlZSc6IGl0ZW0uYW5nbGVcclxuICAgIH0pKTtcclxuXHJcbiAgICBjb25zdCB3b3Jrc2hlZXQgPSBYTFNYLnV0aWxzLmpzb25fdG9fc2hlZXQoZm9ybWF0dGVkRGF0YSk7XHJcblxyXG4gICAgY29uc3Qgd29ya2Jvb2sgPSBYTFNYLnV0aWxzLmJvb2tfbmV3KCk7XHJcbiAgICBYTFNYLnV0aWxzLmJvb2tfYXBwZW5kX3NoZWV0KHdvcmtib29rLCB3b3Jrc2hlZXQsICdTaGVldDEnKTtcclxuXHJcbiAgICBjb25zdCBmaWxlTmFtZSA9IGAke3RoaXMuc2VsZWN0ZWRTdG9yZS5zdG9yZU5hbWV9XyR7dGhpcy5zZWxlY3RlZEZsb29yLmZsb29yTmFtZX1fbGF5b3V0Lnhsc3hgXHJcblxyXG4gICAgWExTWC53cml0ZUZpbGUod29ya2Jvb2ssIGZpbGVOYW1lKTtcclxufVxyXG5cclxuXHJcblxyXG5cclxuXHJcblxyXG5cclxufVxyXG4iLCI8ZGl2IGNsYXNzPVwiZC1mbGV4IGFsaWduLWl0ZW1zLWNlbnRlciBqdXN0aWZ5LWNvbnRlbnQtYmV0d2VlbiBtYi02XCI+XHJcbiAgICA8ZGl2PlxyXG4gICAgICAgIDxkaXYgKm5nSWY9XCJwbGFub1N0b3JlTGlzdC5sZW5ndGggPT09IDFcIiBjbGFzcz1cInN0b3JlbmFtZS10eHRcIj5cclxuICAgICAgICAgICAge3tzZWxlY3RlZFN0b3JlPy5zdG9yZU5hbWV9fSAtIExheW91dFxyXG4gICAgICAgIDwvZGl2PlxyXG4gICAgICAgIDxkaXYgKm5nSWY9XCJwbGFub1N0b3JlTGlzdC5sZW5ndGggPiAxXCI+XHJcbiAgICAgICAgICAgIDxsaWItc2VsZWN0LXBsYW5vIFtpdGVtc109XCJwbGFub1N0b3JlTGlzdFwiIFttdWx0aV09XCJmYWxzZVwiIFtzZWFyY2hGaWVsZF09XCInc3RvcmVOYW1lJ1wiIFtpZEZpZWxkXT1cIidzdG9yZUlkJ1wiXHJcbiAgICAgICAgICAgICAgICAoc2VsZWN0ZWQpPVwib25TdG9yZUNoYW5nZSgkZXZlbnQpXCIgW3NlbGVjdGVkVmFsdWVzXT1cIltzZWxlY3RlZFN0b3JlXVwiPjwvbGliLXNlbGVjdC1wbGFubz5cclxuICAgICAgICA8L2Rpdj5cclxuICAgIDwvZGl2PlxyXG5cclxuICAgIDxkaXYgY2xhc3M9XCJkLWZsZXggYWxpZ24taXRlbXMtY2VudGVyXCI+XHJcbiAgICAgICAgPGJ1dHRvbiAoY2xpY2spPVwib25TYXZlQXNEcmFmdCgpXCIgY2xhc3M9XCJidG4gYnRuLW91dGxpbmUgYmctd2hpdGUgbWUtNVwiPlNhdmUgQXMgRHJhZnQ8L2J1dHRvbj5cclxuICAgICAgICA8YnV0dG9uIChjbGljayk9XCJvbkNvbmZpZ3VyZSgpXCIgY2xhc3M9XCJidG4gYnRuLXNtIGJ0bi1wcmltYXJ5IG1lLTVcIj5Db25maWd1cmU8L2J1dHRvbj5cclxuICAgICAgICA8YnV0dG9uIChjbGljayk9XCJvcGVuT2ZmQ2FudmEoKVwiIGNsYXNzPVwiYnRuIGJ0bi1zbSBidG4tb3V0bGluZSBiZy13aGl0ZVwiPlxyXG4gICAgICAgICAgICA8c3ZnIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIiB3aWR0aD1cIjI0XCIgaGVpZ2h0PVwiMjRcIiB2aWV3Qm94PVwiMCAwIDI0IDI0XCIgZmlsbD1cIm5vbmVcIj5cclxuICAgICAgICAgICAgICAgIDxwYXRoXHJcbiAgICAgICAgICAgICAgICAgICAgZD1cIk05IDNWMjFNNSAzSDE5QzIwLjEwNDYgMyAyMSAzLjg5NTQzIDIxIDVWMTlDMjEgMjAuMTA0NiAyMC4xMDQ2IDIxIDE5IDIxSDVDMy44OTU0MyAyMSAzIDIwLjEwNDYgMyAxOVY1QzMgMy44OTU0MyAzLjg5NTQzIDMgNSAzWlwiXHJcbiAgICAgICAgICAgICAgICAgICAgc3Ryb2tlPVwiIzEwMTgyOFwiIHN0cm9rZS13aWR0aD1cIjJcIiBzdHJva2UtbGluZWNhcD1cInJvdW5kXCIgc3Ryb2tlLWxpbmVqb2luPVwicm91bmRcIiAvPlxyXG4gICAgICAgICAgICA8L3N2Zz5cclxuICAgICAgICA8L2J1dHRvbj5cclxuICAgIDwvZGl2PlxyXG48L2Rpdj5cclxuXHJcbjxkaXYgY2xhc3M9XCJyb3dcIj5cclxuICAgIDxkaXYgW25nQ2xhc3NdPVwibGF5b3V0TW9kZSA9PT0gJ2Z1bGwnID8gJ2NvbC0yJyA6ICdjb2wtNSdcIj5cclxuICAgICAgICA8ZGl2IGNsYXNzPVwiYy1jYXJkXCIgc3R5bGU9XCJoZWlnaHQ6IDc1ZHZoOyBwb3NpdGlvbjogcmVsYXRpdmU7XCI+XHJcbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJyZXNpemUtaWNvblwiICpuZ0lmPVwibGF5b3V0TW9kZSA9PT0gJ2hhbGYnXCIgKGNsaWNrKT1cImxheW91dE1vZGUgPSAnZnVsbCdcIj5cclxuICAgICAgICAgICAgICAgIDxzdmcgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIHdpZHRoPVwiMThcIiBoZWlnaHQ9XCIxOFwiIHZpZXdCb3g9XCIwIDAgMTggMThcIiBmaWxsPVwibm9uZVwiPlxyXG4gICAgICAgICAgICAgICAgICAgIDxwYXRoXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGQ9XCJNOC4yNzI1OSAxMi42MzY1TDQuNjM2MjMgOS4wMDAxM0w4LjI3MjU5IDUuMzYzNzdNMTMuMzYzNSAxMi42MzY1TDkuNzI3MTQgOS4wMDAxM0wxMy4zNjM1IDUuMzYzNzdcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBzdHJva2U9XCIjMTAxODI4XCIgc3Ryb2tlLXdpZHRoPVwiMS40NTQ1NVwiIHN0cm9rZS1saW5lY2FwPVwicm91bmRcIiBzdHJva2UtbGluZWpvaW49XCJyb3VuZFwiIC8+XHJcbiAgICAgICAgICAgICAgICA8L3N2Zz5cclxuICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJyZXNpemUtaWNvblwiICpuZ0lmPVwibGF5b3V0TW9kZSA9PT0gJ2Z1bGwnXCIgKGNsaWNrKT1cImxheW91dE1vZGUgPSAnaGFsZidcIj5cclxuICAgICAgICAgICAgICAgIDxzdmcgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIHdpZHRoPVwiMThcIiBoZWlnaHQ9XCIxOFwiIHZpZXdCb3g9XCIwIDAgMTggMThcIiBmaWxsPVwibm9uZVwiPlxyXG4gICAgICAgICAgICAgICAgICAgIDxwYXRoXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGQ9XCJNOS43Mjc0MSA1LjM2Mzk5TDEzLjM2MzggOS4wMDAzNkw5LjcyNzQxIDEyLjYzNjdNNC42MzY1IDUuMzYzOTlMOC4yNzI4NiA5LjAwMDM2TDQuNjM2NSAxMi42MzY3XCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgc3Ryb2tlPVwiIzEwMTgyOFwiIHN0cm9rZS13aWR0aD1cIjEuNDU0NTVcIiBzdHJva2UtbGluZWNhcD1cInJvdW5kXCIgc3Ryb2tlLWxpbmVqb2luPVwicm91bmRcIiAvPlxyXG4gICAgICAgICAgICAgICAgPC9zdmc+XHJcbiAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZC1mbGV4IGFsaWduLWl0ZW1zLWNlbnRlciBqdXN0aWZ5LWNvbnRlbnQtYmV0d2VlbiBtYi01XCIgc3R5bGU9XCJoZWlnaHQ6IDglO1wiPlxyXG4gICAgICAgICAgICAgICAgPGRpdj5cclxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibC1wYW5lLWhlYWRcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgTGF5b3V0IGRldGFpbHNcclxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICA8ZGl2ICpuZ0lmPVwibGF5b3V0TW9kZSA9PT0gJ2hhbGYnXCIgY2xhc3M9XCJsLXBhbmUtZGVzY1wiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBCZWxvdyBhcmUgdGhlIHNlcXVlbmNlIG9mIHN0ZXBzIGZvciB0aGlzIGxheW91dFxyXG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZC1mbGV4IGFsaWduLWl0ZW1zLWNlbnRlclwiPlxyXG4gICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJsYXlvdXRNb2RlID09PSAnaGFsZidcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPHN2ZyAoY2xpY2spPVwidW5kbygpXCIgY2xhc3M9XCJtZS0zIGN1cnNvci1wb2ludGVyXCIgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIHdpZHRoPVwiMjRcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaGVpZ2h0PVwiMjRcIiB2aWV3Qm94PVwiMCAwIDI0IDI0XCIgZmlsbD1cIm5vbmVcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxwYXRoIFthdHRyLmZpbGxdPVwidW5kb1N0YWNrLmxlbmd0aCA/ICcjMUQyOTM5JyA6ICcjRDBENUREJ1wiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZD1cIk03IDE5VjE3SDE0LjFDMTUuMTUgMTcgMTYuMDYyNyAxNi42NjY3IDE2LjgzOCAxNkMxNy42MTMzIDE1LjMzMzMgMTguMDAwNyAxNC41IDE4IDEzLjVDMTggMTIuNSAxNy42MTIzIDExLjY2NjcgMTYuODM3IDExQzE2LjA2MTcgMTAuMzMzMyAxNS4xNDkzIDEwIDE0LjEgMTBINy44TDEwLjQgMTIuNkw5IDE0TDQgOUw5IDRMMTAuNCA1LjRMNy44IDhIMTQuMUMxNS43MTY3IDggMTcuMTA0MyA4LjUyNSAxOC4yNjMgOS41NzVDMTkuNDIxNyAxMC42MjUgMjAuMDAwNyAxMS45MzMzIDIwIDEzLjVDMjAgMTUuMDY2NyAxOS40MjA3IDE2LjM3NSAxOC4yNjIgMTcuNDI1QzE3LjEwMzMgMTguNDc1IDE1LjcxNiAxOSAxNC4xIDE5SDdaXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWxsPVwiI0QwRDVERFwiIC8+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvc3ZnPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8c3ZnIChjbGljayk9XCJyZWRvKClcIiBjbGFzcz1cIm1lLTYgY3Vyc29yLXBvaW50ZXJcIiB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCIgd2lkdGg9XCIyNFwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBoZWlnaHQ9XCIyNFwiIHZpZXdCb3g9XCIwIDAgMjQgMjRcIiBmaWxsPVwibm9uZVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPHBhdGggW2F0dHIuZmlsbF09XCJyZWRvU3RhY2subGVuZ3RoID8gJyMxRDI5MzknIDogJyNEMEQ1REQnXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkPVwiTTkuOSAxOUM4LjI4MzMzIDE5IDYuODk1NjcgMTguNDc1IDUuNzM3IDE3LjQyNUM0LjU3ODMzIDE2LjM3NSAzLjk5OTMzIDE1LjA2NjcgNCAxMy41QzQgMTEuOTMzMyA0LjU3OTMzIDEwLjYyNSA1LjczOCA5LjU3NUM2Ljg5NjY3IDguNTI1IDguMjg0IDggOS45IDhIMTYuMkwxMy42IDUuNEwxNSA0TDIwIDlMMTUgMTRMMTMuNiAxMi42TDE2LjIgMTBIOS45QzguODUgMTAgNy45MzczMyAxMC4zMzMzIDcuMTYyIDExQzYuMzg2NjcgMTEuNjY2NyA1Ljk5OTMzIDEyLjUgNiAxMy41QzYgMTQuNSA2LjM4NzY3IDE1LjMzMzMgNy4xNjMgMTZDNy45MzgzMyAxNi42NjY3IDguODUwNjcgMTcgOS45IDE3SDE3VjE5SDkuOVpcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbGw9XCIjRDBENUREXCIgLz5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPC9zdmc+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgKGNsaWNrKT1cInRvZ2dsZUxheW91dE9wdGlvblNlbGVjdCgpXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiZC1mbGV4ICBhbGlnbi1pdGVtcy1jZW50ZXIganVzdGlmeS1jb250ZW50LWNlbnRlciBoLTEwMCBlbGlwc2lzLWljb24tZHJvcGRvd24gdG9wLWVsaXBzaXMtbWVudVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImVsaXBzaXMtYnRuXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHN2ZyB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCIgd2lkdGg9XCIyNFwiIGhlaWdodD1cIjI0XCIgdmlld0JveD1cIjAgMCAyNCAyNFwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbGw9XCJub25lXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxwYXRoXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkPVwiTTExIDExLjk5OTdDMTEgMTIuNTI4OSAxMS40NDc3IDEyLjk1OCAxMiAxMi45NThDMTIuNTUyMyAxMi45NTggMTMgMTIuNTI4OSAxMyAxMS45OTk3QzEzIDExLjQ3MDQgMTIuNTUyMyAxMS4wNDEzIDEyIDExLjA0MTNDMTEuNDQ3NyAxMS4wNDEzIDExIDExLjQ3MDQgMTEgMTEuOTk5N1pcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3Ryb2tlPVwiIzEwMTgyOFwiIHN0cm9rZS13aWR0aD1cIjJcIiBzdHJva2UtbGluZWNhcD1cInJvdW5kXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cm9rZS1saW5lam9pbj1cInJvdW5kXCIgLz5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHBhdGhcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGQ9XCJNMTEgMTguNzA4QzExIDE5LjIzNzMgMTEuNDQ3NyAxOS42NjYzIDEyIDE5LjY2NjNDMTIuNTUyMyAxOS42NjYzIDEzIDE5LjIzNzMgMTMgMTguNzA4QzEzIDE4LjE3ODcgMTIuNTUyMyAxNy43NDk3IDEyIDE3Ljc0OTdDMTEuNDQ3NyAxNy43NDk3IDExIDE4LjE3ODcgMTEgMTguNzA4WlwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJva2U9XCIjMTAxODI4XCIgc3Ryb2tlLXdpZHRoPVwiMlwiIHN0cm9rZS1saW5lY2FwPVwicm91bmRcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3Ryb2tlLWxpbmVqb2luPVwicm91bmRcIiAvPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8cGF0aFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZD1cIk0xMSA1LjI5MTM0QzExIDUuODIwNjEgMTEuNDQ3NyA2LjI0OTY3IDEyIDYuMjQ5NjdDMTIuNTUyMyA2LjI0OTY3IDEzIDUuODIwNjEgMTMgNS4yOTEzNEMxMyA0Ljc2MjA3IDEyLjU1MjMgNC4zMzMwMSAxMiA0LjMzMzAxQzExLjQ0NzcgNC4zMzMwMSAxMSA0Ljc2MjA3IDExIDUuMjkxMzRaXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cm9rZT1cIiMxMDE4MjhcIiBzdHJva2Utd2lkdGg9XCIyXCIgc3Ryb2tlLWxpbmVjYXA9XCJyb3VuZFwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJva2UtbGluZWpvaW49XCJyb3VuZFwiIC8+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9zdmc+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx1bCAqbmdJZj1cImxheW91dE9wdGlvblNlbGVjdD8uc2hvd1wiIFtuZ0NsYXNzXT1cIiAobGF5b3V0T3B0aW9uU2VsZWN0LnNob3cgKSA/ICd6LTEnOiAnJ1wiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJsaXN0LXVuc3R5bGVkIG1iLTJcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bGk+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJkLWZsZXgganVzdGlmeS1jb250ZW50LWJldHdlZW4gdy0xMDBcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJtZW51LXR4dDFcIj5FeHBvcnQ8L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzdmcgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIHdpZHRoPVwiOFwiIGhlaWdodD1cIjE0XCIgdmlld0JveD1cIjAgMCA4IDE0XCIgZmlsbD1cIm5vbmVcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHBhdGggZD1cIk0xIDEzTDcgN0wxIDFcIiBzdHJva2U9XCIjMTAxODI4XCIgc3Ryb2tlLXdpZHRoPVwiMlwiIHN0cm9rZS1saW5lY2FwPVwicm91bmRcIiBzdHJva2UtbGluZWpvaW49XCJyb3VuZFwiLz5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvc3ZnPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9zcGFuPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImV4cG9ydC1vcHRpb25zXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dWw+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGxpIChjbGljayk9XCJleHBvcnRUb0V4Y2VsKClcIiA+WExTWDwvbGk+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGxpIChjbGljayk9XCJleHBvcnRBc1BuZygpXCIgPlBORzwvbGk+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3VsPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9saT5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bGkgKGNsaWNrKT1cIm9uQ2xlYXJBbGwoKVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZC1mbGV4XCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibWVudS10eHQxXCI+Q2xlYXIgYWxsPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2xpPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxsaSAoY2xpY2spPVwib25EZWxldGVMYXlvdXQoKVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZC1mbGV4XCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibWVudS10eHQxIHRleHQtZGFuZ2VyXCI+RGVsZXRlPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbGk+XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC91bD5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxyXG5cclxuXHJcblxyXG4gICAgICAgICAgICAgICAgPC9kaXY+XHJcblxyXG4gICAgICAgICAgICA8L2Rpdj5cclxuXHJcbiAgICAgICAgICAgIDwhLS0gPGRpdiBjbGFzcz1cImQtZmxleCBhbGlnbi1pdGVtcy1jZW50ZXIgZmxleC1jb2x1bW4gbXgtYXV0b1wiIHN0eWxlPVwibWFyZ2luLXRvcDogMjAwcHg7XCIgPlxyXG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm5vLXN0ZXBzLXR4dCBtYi0zXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgTm8gc3RlcHMgaGF2ZSBiZWVuIGNyZWF0ZWQgc28gZmFyXHJcbiAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJuby10ZXh0LWRlc2MgdGV4dC1jZW50ZXJcIj5cclxuICAgICAgICAgICAgICAgICAgICBTdGFydCBkZXNpZ25pbmcgdGhlIGxheW91dCBieSBhcHBseWluZyB0aGUgc3RlcHMgdXNpbmcgZWxlbWVudHMgYW5kIGRpbWVuc2lvbnMuXHJcbiAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgPC9kaXY+IC0tPlxyXG5cclxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cInRhYmxlLXJlc3BvbnNpdmUgaGlkZS1zY3JvbGxiYXIgXCIgc3R5bGU9XCJoZWlnaHQ6IDkyJTtcIj5cclxuICAgICAgICAgICAgICAgIDx0YWJsZSBjbGFzcz1cInRhYmxlXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgPHRoZWFkIGNsYXNzPVwidGhlYWQtbGlnaHRcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPHRyPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPHRoPlN0ZXBzPC90aD5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx0aD5FbGVtZW50cyBhbmQgRGVmaW5pdGlvbjwvdGg+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dGg+RmVldDwvdGg+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dGg+RGlyZWN0aW9uPC90aD5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx0aD5EZWdyZWU8L3RoPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPHRoPjwvdGg+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvdHI+XHJcbiAgICAgICAgICAgICAgICAgICAgPC90aGVhZD5cclxuICAgICAgICAgICAgICAgICAgICA8dGJvZHkgY2RrRHJvcExpc3QgKGNka0Ryb3BMaXN0RHJvcHBlZCk9XCJkcm9wKCRldmVudClcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdGb3I9XCJsZXQgaXRlbSBvZiBsYXlvdXRQb2x5Z29uOyBsZXQgaSA9IGluZGV4XCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dHIgW25nQ2xhc3NdPVwic2VsZWN0ZWRMaW5lSW5kZXggPT09IGkgPyAnc2VsZWN0ZWQtZWxlbWVudCcgOiAnJ1wiICpuZ0lmPVwiaXRlbT8uWzJdXCIgY2RrRHJhZz5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dGQ+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJkLWZsZXggYWxpZ24taXRlbXMtY2VudGVyIGp1c3RpZnktY29udGVudC1jZW50ZXIgdy0xMDAgaC0xMDAgZHJhZy1oYW5kbGVyXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cIm1yLTIgIFwiID5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3ZnIGNsYXNzPVwiY3Vyc29yLXBvaW50ZXJcIiAgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIHdpZHRoPVwiMTlcIiBoZWlnaHQ9XCIxOVwiIHZpZXdCb3g9XCIwIDAgMTkgMTlcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGNpcmNsZSBjeD1cIjVcIiBjeT1cIjVcIiByPVwiMlwiIGZpbGw9XCJncmF5XCIgLz5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGNpcmNsZSBjeD1cIjE0XCIgY3k9XCI1XCIgcj1cIjJcIiBmaWxsPVwiZ3JheVwiIC8+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxjaXJjbGUgY3g9XCI1XCIgY3k9XCIxMFwiIHI9XCIyXCIgZmlsbD1cImdyYXlcIiAvPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8Y2lyY2xlIGN4PVwiMTRcIiBjeT1cIjEwXCIgcj1cIjJcIiBmaWxsPVwiZ3JheVwiIC8+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxjaXJjbGUgY3g9XCI1XCIgY3k9XCIxNVwiIHI9XCIyXCIgZmlsbD1cImdyYXlcIiAvPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8Y2lyY2xlIGN4PVwiMTRcIiBjeT1cIjE1XCIgcj1cIjJcIiBmaWxsPVwiZ3JheVwiIC8+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3N2Zz5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvc3Bhbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuPnt7IGkgKyAxfX08L3NwYW4+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvdGQ+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHRkPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZC1mbGV4XCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IChjbGljayk9XCJ0b2dnbGVFbGVtZW50U2VsZWN0KGkpXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImVsZW1lbnQtdHlwZS1kcm9wZG93biBtZS0yIHBvc2l0aW9uLXJlbGF0aXZlXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHN2ZyAqbmdJZj1cIml0ZW1bMl0uZWxlbWVudFR5cGUgPT09ICd3YWxsJ1wiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCIgd2lkdGg9XCIyMFwiIGhlaWdodD1cIjIwXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZpZXdCb3g9XCIwIDAgMjAgMjBcIiBmaWxsPVwibm9uZVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHBhdGggZmlsbC1ydWxlPVwiZXZlbm9kZFwiIGNsaXAtcnVsZT1cImV2ZW5vZGRcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGQ9XCJNMS4zMzMzMyAxLjMzMzMzVjBMMi42NjY2NyAwVjEuMzMzMzNMNi42NjY2NyAxLjMzMzMzVjBMOCAwVjEuMzMzMzNMMTIgMS4zMzMzM1YwTDEzLjMzMzMgMFYxLjMzMzMzTDE3LjMzMzMgMS4zMzMzM1YwTDE4LjY2NjcgMFYxLjMzMzMzSDIwVjIuNjY2NjdIMTguNjY2N1Y2LjY2NjY3SDIwVjhIMTguNjY2N1YxMkgyMFYxMy4zMzMzSDE4LjY2NjdWMTcuMzMzM0gyMFYxOC42NjY3SDE4LjY2NjdWMjBIMTcuMzMzM1YxOC42NjY3SDEzLjMzMzNWMjBIMTJWMTguNjY2N0g4VjIwSDYuNjY2NjdWMTguNjY2N0gyLjY2NjY3VjIwSDEuMzMzMzNWMTguNjY2N0gwTDAgMTcuMzMzM0gxLjMzMzMzTDEuMzMzMzMgMTMuMzMzM0gwTDAgMTJIMS4zMzMzM0wxLjMzMzMzIDhIMEwwIDYuNjY2NjdIMS4zMzMzM0wxLjMzMzMzIDIuNjY2NjdIMEwwIDEuMzMzMzNIMS4zMzMzM1pNMi42NjY2NyAyLjY2NjY3TDIuNjY2NjcgNi42NjY2N0g2LjY2NjY3VjIuNjY2NjdMMi42NjY2NyAyLjY2NjY3Wk04IDIuNjY2NjdWNi42NjY2N0gxMlYyLjY2NjY3TDggMi42NjY2N1pNMTMuMzMzMyAyLjY2NjY3VjYuNjY2NjdIMTcuMzMzM1YyLjY2NjY3SDEzLjMzMzNaTTE3LjMzMzMgOEwxMy4zMzMzIDhWMTJMMTcuMzMzMyAxMlY4Wk0xNy4zMzMzIDEzLjMzMzNMMTMuMzMzMyAxMy4zMzMzTDEzLjMzMzMgMTcuMzMzM0gxNy4zMzMzVjEzLjMzMzNaTTEyIDE3LjMzMzNMMTIgMTMuMzMzM0g4TDggMTcuMzMzM0gxMlpNNi42NjY2NyAxNy4zMzMzVjEzLjMzMzNIMi42NjY2N1YxNy4zMzMzSDYuNjY2NjdaTTIuNjY2NjcgMTJINi42NjY2N1Y4SDIuNjY2NjdMMi42NjY2NyAxMlpNOCA4VjEySDEyVjhIOFpcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbGw9XCIjMzQ0MDU0XCIgLz5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9zdmc+XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3ZnICpuZ0lmPVwiaXRlbVsyXS5lbGVtZW50VHlwZSA9PT0gJ2ZhY2FkZSdcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIHdpZHRoPVwiMjJcIiBoZWlnaHQ9XCIyMlwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2aWV3Qm94PVwiMCAwIDIyIDIyXCIgZmlsbD1cIm5vbmVcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxwYXRoXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZD1cIk0xIDExVjIuMjVDMSAxLjU2MjUgMS41NjI1IDEgMi4yNSAxSDE5Ljc1QzIwLjQzNzUgMSAyMSAxLjU2MjUgMjEgMi4yNVYxOS43NUMyMSAyMC40Mzc1IDIwLjQzNzUgMjEgMTkuNzUgMjFIMi4yNUMxLjU2MjUgMjEgMSAyMC40Mzc1IDEgMTkuNzVWMTFaXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJva2U9XCIjMzQ0MDU0XCIgc3Ryb2tlLWxpbmVjYXA9XCJyb3VuZFwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3Ryb2tlLWxpbmVqb2luPVwicm91bmRcIiAvPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3N2Zz5cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzdmcgKm5nSWY9XCJpdGVtWzJdLmVsZW1lbnRUeXBlID09PSAnb3BlbmluZydcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIHdpZHRoPVwiMjBcIiBoZWlnaHQ9XCIyMFwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2aWV3Qm94PVwiMCAwIDIwIDIwXCIgZmlsbD1cIm5vbmVcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxwYXRoXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZD1cIk0xMi41IDIuNUgxNS44MzMzQzE2LjI3NTQgMi41IDE2LjY5OTMgMi42NzU2IDE3LjAxMTggMi45ODgxNkMxNy4zMjQ0IDMuMzAwNzIgMTcuNSAzLjcyNDY0IDE3LjUgNC4xNjY2N1YxNS44MzMzQzE3LjUgMTYuMjc1NCAxNy4zMjQ0IDE2LjY5OTMgMTcuMDExOCAxNy4wMTE4QzE2LjY5OTMgMTcuMzI0NCAxNi4yNzU0IDE3LjUgMTUuODMzMyAxNy41SDEyLjVNOC4zMzMzMyAxNC4xNjY3TDEyLjUgMTBNMTIuNSAxMEw4LjMzMzMzIDUuODMzMzNNMTIuNSAxMEgyLjVcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cm9rZT1cIiMxMDE4MjhcIiBzdHJva2Utd2lkdGg9XCIxLjVcIiBzdHJva2UtbGluZWNhcD1cInJvdW5kXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJva2UtbGluZWpvaW49XCJyb3VuZFwiIC8+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvc3ZnPlxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHN2ZyAqbmdJZj1cIml0ZW1bMl0uZWxlbWVudFR5cGUgPT09ICdlbnRyYW5jZSdcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIHdpZHRoPVwiMjFcIiBoZWlnaHQ9XCIxOFwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2aWV3Qm94PVwiMCAwIDIxIDE4XCIgZmlsbD1cIm5vbmVcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxwYXRoIGZpbGwtcnVsZT1cImV2ZW5vZGRcIiBjbGlwLXJ1bGU9XCJldmVub2RkXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkPVwiTTE3LjkzMzMgMS4zNzk0OUM4Ljc5MDkgMS4zNzk0OSAxLjM3OTQ5IDguNzkwOSAxLjM3OTQ5IDE3LjkzMzNIMEMwIDguMDI5MDMgOC4wMjkwMyAwIDE3LjkzMzMgMFYxLjM3OTQ5WlwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsbD1cIiMxRDI5MzlcIiAvPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHBhdGggZmlsbC1ydWxlPVwiZXZlbm9kZFwiIGNsaXAtcnVsZT1cImV2ZW5vZGRcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGQ9XCJNMTkuMzEzMiAxLjM3OTQ5SDE3LjkzMzNMMTcuOTMzNyAxNi41NTM4SDE5LjMxMzJWMS4zNzk0OVpNMTYuNTU0MiAwVjE3LjkzMzNIMjAuNjkyN1YwSDE2LjU1NDJaXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWxsPVwiIzFEMjkzOVwiIC8+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvc3ZnPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZG93bi1hcnJvd1wiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3ZnIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIiB3aWR0aD1cIjIwXCIgaGVpZ2h0PVwiMjBcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmlld0JveD1cIjAgMCAyMCAyMFwiIGZpbGw9XCJub25lXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8cGF0aCBkPVwiTTUgNy41TDEwIDEyLjVMMTUgNy41XCIgc3Ryb2tlPVwiIzY2NzA4NVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3Ryb2tlLXdpZHRoPVwiMS42NjY2N1wiIHN0cm9rZS1saW5lY2FwPVwicm91bmRcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cm9rZS1saW5lam9pbj1cInJvdW5kXCIgLz5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9zdmc+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx1bCAqbmdJZj1cImVsZW1lbnRTZWxlY3Q/LnNob3cgJiYgZWxlbWVudFNlbGVjdD8uaW5kZXggPT09IGlcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbbmdDbGFzc109XCIgKGVsZW1lbnRTZWxlY3Quc2hvdyAmJiBlbGVtZW50U2VsZWN0LmluZGV4ID09PSBpKSA/ICd6LTEnOiAnJ1wiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwibGlzdC11bnN0eWxlZCBtYi0yXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxsaSAoY2xpY2spPVwib25FbGVtZW50VHlwZUNoYW5nZSgnd2FsbCcsIGkpXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtuZ0NsYXNzXT1cIml0ZW1bMl0uZWxlbWVudFR5cGUgPT09ICd3YWxsJyA/ICdzZWxlY3RlZCcgOiAnJ1wiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImQtZmxleFwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJtZS0zXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzdmcgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIHdpZHRoPVwiMjBcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaGVpZ2h0PVwiMjBcIiB2aWV3Qm94PVwiMCAwIDIwIDIwXCIgZmlsbD1cIm5vbmVcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxwYXRoIGZpbGwtcnVsZT1cImV2ZW5vZGRcIiBjbGlwLXJ1bGU9XCJldmVub2RkXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkPVwiTTEuMzMzMzMgMS4zMzMzM1YwTDIuNjY2NjcgMFYxLjMzMzMzTDYuNjY2NjcgMS4zMzMzM1YwTDggMFYxLjMzMzMzTDEyIDEuMzMzMzNWMEwxMy4zMzMzIDBWMS4zMzMzM0wxNy4zMzMzIDEuMzMzMzNWMEwxOC42NjY3IDBWMS4zMzMzM0gyMFYyLjY2NjY3SDE4LjY2NjdWNi42NjY2N0gyMFY4SDE4LjY2NjdWMTJIMjBWMTMuMzMzM0gxOC42NjY3VjE3LjMzMzNIMjBWMTguNjY2N0gxOC42NjY3VjIwSDE3LjMzMzNWMTguNjY2N0gxMy4zMzMzVjIwSDEyVjE4LjY2NjdIOFYyMEg2LjY2NjY3VjE4LjY2NjdIMi42NjY2N1YyMEgxLjMzMzMzVjE4LjY2NjdIMEwwIDE3LjMzMzNIMS4zMzMzM0wxLjMzMzMzIDEzLjMzMzNIMEwwIDEySDEuMzMzMzNMMS4zMzMzMyA4SDBMMCA2LjY2NjY3SDEuMzMzMzNMMS4zMzMzMyAyLjY2NjY3SDBMMCAxLjMzMzMzSDEuMzMzMzNaTTIuNjY2NjcgMi42NjY2N0wyLjY2NjY3IDYuNjY2NjdINi42NjY2N1YyLjY2NjY3TDIuNjY2NjcgMi42NjY2N1pNOCAyLjY2NjY3VjYuNjY2NjdIMTJWMi42NjY2N0w4IDIuNjY2NjdaTTEzLjMzMzMgMi42NjY2N1Y2LjY2NjY3SDE3LjMzMzNWMi42NjY2N0gxMy4zMzMzWk0xNy4zMzMzIDhMMTMuMzMzMyA4VjEyTDE3LjMzMzMgMTJWOFpNMTcuMzMzMyAxMy4zMzMzTDEzLjMzMzMgMTMuMzMzM0wxMy4zMzMzIDE3LjMzMzNIMTcuMzMzM1YxMy4zMzMzWk0xMiAxNy4zMzMzTDEyIDEzLjMzMzNIOEw4IDE3LjMzMzNIMTJaTTYuNjY2NjcgMTcuMzMzM1YxMy4zMzMzSDIuNjY2NjdWMTcuMzMzM0g2LjY2NjY3Wk0yLjY2NjY3IDEySDYuNjY2NjdWOEgyLjY2NjY3TDIuNjY2NjcgMTJaTTggOFYxMkgxMlY4SDhaXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWxsPVwiIzM0NDA1NFwiIC8+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvc3ZnPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXY+V2FsbDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzdmcgKm5nSWY9XCJpdGVtWzJdLmVsZW1lbnRUeXBlID09PSAnd2FsbCdcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCIgd2lkdGg9XCIyMFwiIGhlaWdodD1cIjIwXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmlld0JveD1cIjAgMCAyMCAyMFwiIGZpbGw9XCJub25lXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxwYXRoIGQ9XCJNMTYuNjY2MyA1TDcuNDk5NjcgMTQuMTY2N0wzLjMzMzAxIDEwXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cm9rZT1cIiMwMEEzRkZcIiBzdHJva2Utd2lkdGg9XCIxLjY2NjY3XCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cm9rZS1saW5lY2FwPVwicm91bmRcIiBzdHJva2UtbGluZWpvaW49XCJyb3VuZFwiIC8+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9zdmc+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9saT5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGxpIChjbGljayk9XCJvbkVsZW1lbnRUeXBlQ2hhbmdlKCdmYWNhZGUnLCBpKVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbbmdDbGFzc109XCJpdGVtWzJdLmVsZW1lbnRUeXBlID09PSAnZmFjYWRlJyA/ICdzZWxlY3RlZCcgOiAnJ1wiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImQtZmxleFwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJtZS0zXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzdmcgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIHdpZHRoPVwiMjJcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaGVpZ2h0PVwiMjJcIiB2aWV3Qm94PVwiMCAwIDIyIDIyXCIgZmlsbD1cIm5vbmVcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxwYXRoXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZD1cIk0xIDExVjIuMjVDMSAxLjU2MjUgMS41NjI1IDEgMi4yNSAxSDE5Ljc1QzIwLjQzNzUgMSAyMSAxLjU2MjUgMjEgMi4yNVYxOS43NUMyMSAyMC40Mzc1IDIwLjQzNzUgMjEgMTkuNzUgMjFIMi4yNUMxLjU2MjUgMjEgMSAyMC40Mzc1IDEgMTkuNzVWMTFaXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJva2U9XCIjMzQ0MDU0XCIgc3Ryb2tlLWxpbmVjYXA9XCJyb3VuZFwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3Ryb2tlLWxpbmVqb2luPVwicm91bmRcIiAvPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3N2Zz5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2PkdsYXNzL0ZhY2FkZTwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzdmcgKm5nSWY9XCJpdGVtWzJdLmVsZW1lbnRUeXBlID09PSAnZmFjYWRlJ1wiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIiB3aWR0aD1cIjIwXCIgaGVpZ2h0PVwiMjBcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2aWV3Qm94PVwiMCAwIDIwIDIwXCIgZmlsbD1cIm5vbmVcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHBhdGggZD1cIk0xNi42NjYzIDVMNy40OTk2NyAxNC4xNjY3TDMuMzMzMDEgMTBcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3Ryb2tlPVwiIzAwQTNGRlwiIHN0cm9rZS13aWR0aD1cIjEuNjY2NjdcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3Ryb2tlLWxpbmVjYXA9XCJyb3VuZFwiIHN0cm9rZS1saW5lam9pbj1cInJvdW5kXCIgLz5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3N2Zz5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2xpPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bGkgKGNsaWNrKT1cIm9uRWxlbWVudFR5cGVDaGFuZ2UoJ29wZW5pbmcnLCBpKVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbbmdDbGFzc109XCJpdGVtWzJdLmVsZW1lbnRUeXBlID09PSAnb3BlbmluZycgPyAnc2VsZWN0ZWQnIDogJydcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJkLWZsZXhcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibWUtM1wiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3ZnIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIiB3aWR0aD1cIjIwXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhlaWdodD1cIjIwXCIgdmlld0JveD1cIjAgMCAyMCAyMFwiIGZpbGw9XCJub25lXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8cGF0aFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGQ9XCJNMTIuNSAyLjVIMTUuODMzM0MxNi4yNzU0IDIuNSAxNi42OTkzIDIuNjc1NiAxNy4wMTE4IDIuOTg4MTZDMTcuMzI0NCAzLjMwMDcyIDE3LjUgMy43MjQ2NCAxNy41IDQuMTY2NjdWMTUuODMzM0MxNy41IDE2LjI3NTQgMTcuMzI0NCAxNi42OTkzIDE3LjAxMTggMTcuMDExOEMxNi42OTkzIDE3LjMyNDQgMTYuMjc1NCAxNy41IDE1LjgzMzMgMTcuNUgxMi41TTguMzMzMzMgMTQuMTY2N0wxMi41IDEwTTEyLjUgMTBMOC4zMzMzMyA1LjgzMzMzTTEyLjUgMTBIMi41XCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJva2U9XCIjMTAxODI4XCIgc3Ryb2tlLXdpZHRoPVwiMS41XCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJva2UtbGluZWNhcD1cInJvdW5kXCIgc3Ryb2tlLWxpbmVqb2luPVwicm91bmRcIiAvPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3N2Zz5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2Pk9wZW5pbmc8L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3ZnICpuZ0lmPVwiaXRlbVsyXS5lbGVtZW50VHlwZSA9PT0gJ29wZW5pbmcnXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIHdpZHRoPVwiMjBcIiBoZWlnaHQ9XCIyMFwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZpZXdCb3g9XCIwIDAgMjAgMjBcIiBmaWxsPVwibm9uZVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8cGF0aCBkPVwiTTE2LjY2NjMgNUw3LjQ5OTY3IDE0LjE2NjdMMy4zMzMwMSAxMFwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJva2U9XCIjMDBBM0ZGXCIgc3Ryb2tlLXdpZHRoPVwiMS42NjY2N1wiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJva2UtbGluZWNhcD1cInJvdW5kXCIgc3Ryb2tlLWxpbmVqb2luPVwicm91bmRcIiAvPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvc3ZnPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbGk+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxsaSAoY2xpY2spPVwib25FbGVtZW50VHlwZUNoYW5nZSgnZW50cmFuY2UnLCBpKVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbbmdDbGFzc109XCJpdGVtWzJdLmVsZW1lbnRUeXBlID09PSAnZW50cmFuY2UnID8gJ3NlbGVjdGVkJyA6ICcnXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZC1mbGV4XCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm1lLTNcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHN2ZyB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCIgd2lkdGg9XCIyMVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoZWlnaHQ9XCIxOFwiIHZpZXdCb3g9XCIwIDAgMjEgMThcIiBmaWxsPVwibm9uZVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHBhdGggZmlsbC1ydWxlPVwiZXZlbm9kZFwiIGNsaXAtcnVsZT1cImV2ZW5vZGRcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGQ9XCJNMTcuOTMzMyAxLjM3OTQ5QzguNzkwOSAxLjM3OTQ5IDEuMzc5NDkgOC43OTA5IDEuMzc5NDkgMTcuOTMzM0gwQzAgOC4wMjkwMyA4LjAyOTAzIDAgMTcuOTMzMyAwVjEuMzc5NDlaXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWxsPVwiIzFEMjkzOVwiIC8+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8cGF0aCBmaWxsLXJ1bGU9XCJldmVub2RkXCIgY2xpcC1ydWxlPVwiZXZlbm9kZFwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZD1cIk0xOS4zMTMyIDEuMzc5NDlIMTcuOTMzM0wxNy45MzM3IDE2LjU1MzhIMTkuMzEzMlYxLjM3OTQ5Wk0xNi41NTQyIDBWMTcuOTMzM0gyMC42OTI3VjBIMTYuNTU0MlpcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbGw9XCIjMUQyOTM5XCIgLz5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9zdmc+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdj5FbnRyYW5jZTwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzdmcgKm5nSWY9XCJpdGVtWzJdLmVsZW1lbnRUeXBlID09PSAnZW50cmFuY2UnXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIHdpZHRoPVwiMjBcIiBoZWlnaHQ9XCIyMFwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZpZXdCb3g9XCIwIDAgMjAgMjBcIiBmaWxsPVwibm9uZVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8cGF0aCBkPVwiTTE2LjY2NjMgNUw3LjQ5OTY3IDE0LjE2NjdMMy4zMzMwMSAxMFwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJva2U9XCIjMDBBM0ZGXCIgc3Ryb2tlLXdpZHRoPVwiMS42NjY2N1wiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJva2UtbGluZWNhcD1cInJvdW5kXCIgc3Ryb2tlLWxpbmVqb2luPVwicm91bmRcIiAvPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvc3ZnPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbGk+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC91bD5cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJlbGVtZW50LW5hbWVcIj57e2l0ZW1bMl0uZWxlbWVudFR5cGV9fSB7e2l0ZW1bMl0uZWxlbWVudE51bWJlcn19XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC90ZD5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dGQ+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJ1bml0LWlucHV0XCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3ZnIChjbGljayk9XCJvbkRpc3RhbmNlQ2hhbmdlKCdkZWNyZW1lbnQnLCBpKVwiIGNsYXNzPVwiY3Vyc29yLXBvaW50ZXJcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIiB3aWR0aD1cIjE0XCIgaGVpZ2h0PVwiMTRcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZpZXdCb3g9XCIwIDAgMTQgMTRcIiBmaWxsPVwibm9uZVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxwYXRoIGQ9XCJNMi45MTY1IDdIMTEuMDgzMlwiIHN0cm9rZT1cIiM2NjcwODVcIiBzdHJva2Utd2lkdGg9XCIyXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3Ryb2tlLWxpbmVjYXA9XCJyb3VuZFwiIHN0cm9rZS1saW5lam9pbj1cInJvdW5kXCIgLz5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvc3ZnPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4+e3tpdGVtWzJdLmRpc3RhbmNlfX08L3NwYW4+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3ZnIChjbGljayk9XCJvbkRpc3RhbmNlQ2hhbmdlKCdpbmNyZW1lbnQnLCBpKVwiIGNsYXNzPVwiY3Vyc29yLXBvaW50ZXJcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIiB3aWR0aD1cIjE0XCIgaGVpZ2h0PVwiMTRcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZpZXdCb3g9XCIwIDAgMTQgMTRcIiBmaWxsPVwibm9uZVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxwYXRoIGQ9XCJNNi45OTk4NCAyLjkxNjVWMTEuMDgzMk0yLjkxNjUgNi45OTk4NEgxMS4wODMyXCIgc3Ryb2tlPVwiIzY2NzA4NVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cm9rZS13aWR0aD1cIjJcIiBzdHJva2UtbGluZWNhcD1cInJvdW5kXCIgc3Ryb2tlLWxpbmVqb2luPVwicm91bmRcIiAvPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9zdmc+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvdGQ+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHRkPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IChjbGljayk9XCJ0b2dnbGVEaXJlY3Rpb25TZWxlY3QoaSlcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJkaXJlY3Rpb24tZHJvcGRvd24gcG9zaXRpb24tcmVsYXRpdmVcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge3tpdGVtWzJdLmRpcmVjdGlvbn19XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZG93bi1hcnJvd1wiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzdmcgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIHdpZHRoPVwiMjBcIiBoZWlnaHQ9XCIyMFwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZpZXdCb3g9XCIwIDAgMjAgMjBcIiBmaWxsPVwibm9uZVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8cGF0aCBkPVwiTTUgNy41TDEwIDEyLjVMMTUgNy41XCIgc3Ryb2tlPVwiIzY2NzA4NVwiIHN0cm9rZS13aWR0aD1cIjEuNjY2NjdcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3Ryb2tlLWxpbmVjYXA9XCJyb3VuZFwiIHN0cm9rZS1saW5lam9pbj1cInJvdW5kXCIgLz5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3N2Zz5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx1bCAqbmdJZj1cImRpcmVjdGlvblNlbGVjdD8uc2hvdyAmJiBkaXJlY3Rpb25TZWxlY3Q/LmluZGV4ID09PSBpXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbbmdDbGFzc109XCIgKGRpcmVjdGlvblNlbGVjdC5zaG93ICYmIGRpcmVjdGlvblNlbGVjdC5pbmRleCA9PT0gaSkgPyAnei0xJzogJydcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwibGlzdC11bnN0eWxlZCBtYi0yXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGxpIChjbGljayk9XCJvbkRpcmVjdGlvbkNoYW5nZSgndXAnLCBpKVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtuZ0NsYXNzXT1cIml0ZW1bMl0uZGlyZWN0aW9uID09PSAndXAnID8gJ3NlbGVjdGVkJyA6ICcnXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJkLWZsZXhcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXY+VXA8L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3ZnICpuZ0lmPVwiaXRlbVsyXS5kaXJlY3Rpb24gPT09ICd1cCdcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIiB3aWR0aD1cIjIwXCIgaGVpZ2h0PVwiMjBcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZpZXdCb3g9XCIwIDAgMjAgMjBcIiBmaWxsPVwibm9uZVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxwYXRoIGQ9XCJNMTYuNjY2MyA1TDcuNDk5NjcgMTQuMTY2N0wzLjMzMzAxIDEwXCIgc3Ryb2tlPVwiIzAwQTNGRlwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cm9rZS13aWR0aD1cIjEuNjY2NjdcIiBzdHJva2UtbGluZWNhcD1cInJvdW5kXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3Ryb2tlLWxpbmVqb2luPVwicm91bmRcIiAvPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9zdmc+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbGk+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGxpIChjbGljayk9XCJvbkRpcmVjdGlvbkNoYW5nZSgnZG93bicsIGkpXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW25nQ2xhc3NdPVwiaXRlbVsyXS5kaXJlY3Rpb24gPT09ICdkb3duJyA/ICdzZWxlY3RlZCcgOiAnJ1wiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZC1mbGV4XCI+XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdj5Eb3duPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHN2ZyAqbmdJZj1cIml0ZW1bMl0uZGlyZWN0aW9uID09PSAnZG93bidcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIiB3aWR0aD1cIjIwXCIgaGVpZ2h0PVwiMjBcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZpZXdCb3g9XCIwIDAgMjAgMjBcIiBmaWxsPVwibm9uZVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxwYXRoIGQ9XCJNMTYuNjY2MyA1TDcuNDk5NjcgMTQuMTY2N0wzLjMzMzAxIDEwXCIgc3Ryb2tlPVwiIzAwQTNGRlwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cm9rZS13aWR0aD1cIjEuNjY2NjdcIiBzdHJva2UtbGluZWNhcD1cInJvdW5kXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3Ryb2tlLWxpbmVqb2luPVwicm91bmRcIiAvPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9zdmc+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbGk+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGxpIChjbGljayk9XCJvbkRpcmVjdGlvbkNoYW5nZSgncmlnaHQnLCBpKVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtuZ0NsYXNzXT1cIml0ZW1bMl0uZGlyZWN0aW9uID09PSAncmlnaHQnID8gJ3NlbGVjdGVkJyA6ICcnXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJkLWZsZXhcIj5cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2PlJpZ2h0PC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHN2ZyAqbmdJZj1cIml0ZW1bMl0uZGlyZWN0aW9uID09PSAncmlnaHQnXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCIgd2lkdGg9XCIyMFwiIGhlaWdodD1cIjIwXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2aWV3Qm94PVwiMCAwIDIwIDIwXCIgZmlsbD1cIm5vbmVcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8cGF0aCBkPVwiTTE2LjY2NjMgNUw3LjQ5OTY3IDE0LjE2NjdMMy4zMzMwMSAxMFwiIHN0cm9rZT1cIiMwMEEzRkZcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJva2Utd2lkdGg9XCIxLjY2NjY3XCIgc3Ryb2tlLWxpbmVjYXA9XCJyb3VuZFwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cm9rZS1saW5lam9pbj1cInJvdW5kXCIgLz5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvc3ZnPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2xpPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxsaSAoY2xpY2spPVwib25EaXJlY3Rpb25DaGFuZ2UoJ2xlZnQnLCBpKVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtuZ0NsYXNzXT1cIml0ZW1bMl0uZGlyZWN0aW9uID09PSAnbGVmdCcgPyAnc2VsZWN0ZWQnIDogJydcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImQtZmxleFwiPlxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXY+TGVmdDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzdmcgKm5nSWY9XCJpdGVtWzJdLmRpcmVjdGlvbiA9PT0gJ2xlZnQnXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCIgd2lkdGg9XCIyMFwiIGhlaWdodD1cIjIwXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2aWV3Qm94PVwiMCAwIDIwIDIwXCIgZmlsbD1cIm5vbmVcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8cGF0aCBkPVwiTTE2LjY2NjMgNUw3LjQ5OTY3IDE0LjE2NjdMMy4zMzMwMSAxMFwiIHN0cm9rZT1cIiMwMEEzRkZcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJva2Utd2lkdGg9XCIxLjY2NjY3XCIgc3Ryb2tlLWxpbmVjYXA9XCJyb3VuZFwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cm9rZS1saW5lam9pbj1cInJvdW5kXCIgLz5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvc3ZnPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2xpPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC91bD5cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvdGQ+XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx0ZD5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0IG1pbj1cIjBcIiBtYXg9XCIxODBcIiBjbGFzcz1cImFuZ2xlLWlucHV0XCIgWyhuZ01vZGVsKV09XCJpdGVtWzJdLmFuZ2xlXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGU9XCJudW1iZXJcIiAoaW5wdXQpPVwidmFsaWRhdGVBbmdsZUlucHV0KCRldmVudCwgaSlcIiAoYmx1cik9XCJvbkFuZ2xlQ2hhbmdlKGkpXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gPHNwYW4gY2xhc3M9XCJhbmdsZS1pbnB1dFwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge3tpdGVtWzJdLmFuZ2xlfX3CsFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3NwYW4+IC0tPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvdGQ+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHRkPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IChjbGljayk9XCJ0b2dnbGVMaW5lT3B0aW9uc1NlbGVjdChpKVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImQtZmxleCAgYWxpZ24taXRlbXMtY2VudGVyIGp1c3RpZnktY29udGVudC1jZW50ZXIgaC0xMDAgZWxpcHNpcy1pY29uLWRyb3Bkb3duXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3ZnIGNsYXNzPVwiY3Vyc29yLXBvaW50ZXJcIiB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCIgd2lkdGg9XCI0XCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoZWlnaHQ9XCIxOVwiIHZpZXdCb3g9XCIwIDAgNCAxOVwiIGZpbGw9XCJub25lXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHBhdGhcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZD1cIk0xIDkuNTAwMTZDMSAxMC4wMjk0IDEuNDQ3NzEgMTAuNDU4NSAyIDEwLjQ1ODVDMi41NTIyOCAxMC40NTg1IDMgMTAuMDI5NCAzIDkuNTAwMTZDMyA4Ljk3MDg5IDIuNTUyMjggOC41NDE4MyAyIDguNTQxODNDMS40NDc3MSA4LjU0MTgzIDEgOC45NzA4OSAxIDkuNTAwMTZaXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3Ryb2tlPVwiIzEwMTgyOFwiIHN0cm9rZS13aWR0aD1cIjJcIiBzdHJva2UtbGluZWNhcD1cInJvdW5kXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3Ryb2tlLWxpbmVqb2luPVwicm91bmRcIiAvPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxwYXRoXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGQ9XCJNMC45OTk5OTkgMTYuMjA4NUMwLjk5OTk5OSAxNi43Mzc4IDEuNDQ3NzEgMTcuMTY2OCAyIDE3LjE2NjhDMi41NTIyOCAxNy4xNjY4IDMgMTYuNzM3OCAzIDE2LjIwODVDMyAxNS42NzkyIDIuNTUyMjggMTUuMjUwMiAyIDE1LjI1MDJDMS40NDc3MSAxNS4yNTAyIDAuOTk5OTk5IDE1LjY3OTIgMC45OTk5OTkgMTYuMjA4NVpcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJva2U9XCIjMTAxODI4XCIgc3Ryb2tlLXdpZHRoPVwiMlwiIHN0cm9rZS1saW5lY2FwPVwicm91bmRcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJva2UtbGluZWpvaW49XCJyb3VuZFwiIC8+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHBhdGhcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZD1cIk0xIDIuNzkxODNDMSAzLjMyMTEgMS40NDc3MiAzLjc1MDE2IDIgMy43NTAxNkMyLjU1MjI4IDMuNzUwMTYgMyAzLjMyMTEgMyAyLjc5MTgzQzMgMi4yNjI1NiAyLjU1MjI4IDEuODMzNSAyIDEuODMzNUMxLjQ0NzcyIDEuODMzNSAxIDIuMjYyNTYgMSAyLjc5MTgzWlwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cm9rZT1cIiMxMDE4MjhcIiBzdHJva2Utd2lkdGg9XCIyXCIgc3Ryb2tlLWxpbmVjYXA9XCJyb3VuZFwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cm9rZS1saW5lam9pbj1cInJvdW5kXCIgLz5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvc3ZnPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHVsICpuZ0lmPVwibGluZU9wdGlvbnNTZWxlY3Q/LnNob3cgJiYgbGluZU9wdGlvbnNTZWxlY3Q/LmluZGV4ID09PSBpXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbbmdDbGFzc109XCIgKGxpbmVPcHRpb25zU2VsZWN0LnNob3cgJiYgbGluZU9wdGlvbnNTZWxlY3QuaW5kZXggPT09IGkpID8gJ3otMSc6ICcnXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImxpc3QtdW5zdHlsZWQgbWItMlwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxsaSAoY2xpY2spPVwib25BZGRTdGVwKGkpXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJkLWZsZXhcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXY+QWRkIG5ldyBzdGVwPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2xpPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxsaSAoY2xpY2spPVwib25EdXBsaWNhdGVTdGVwKGkpXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJkLWZsZXhcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXY+RHVwbGljYXRlPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2xpPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxsaSAoY2xpY2spPVwib25MaW5lRGVsZXRlKGkpXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJkLWZsZXhcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJ0ZXh0LWRhbmdlclwiPkRlbGV0ZTwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9saT5cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3VsPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC90ZD5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvdHI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxyXG5cclxuICAgICAgICAgICAgICAgICAgICA8L3Rib2R5PlxyXG4gICAgICAgICAgICAgICAgPC90YWJsZT5cclxuICAgICAgICAgICAgPC9kaXY+XHJcblxyXG5cclxuICAgICAgICA8L2Rpdj5cclxuICAgIDwvZGl2PlxyXG4gICAgPGRpdiBbbmdDbGFzc109XCJsYXlvdXRNb2RlID09PSAnZnVsbCcgPyAnY29sLTEwJyA6ICdjb2wtNydcIj5cclxuICAgICAgICA8ZGl2IGNsYXNzPVwiYy1jYXJkIFwiIHN0eWxlPVwiaGVpZ2h0OiA3NWR2aDtcIj5cclxuICAgICAgICAgICAgPGRpdiBzdHlsZT1cImhlaWdodDogNyU7XCIgY2xhc3M9XCJkLWZsZXggYWxpZ24taXRlbXMtY2VudGVyIGp1c3RpZnktY29udGVudC1iZXR3ZWVuXCI+XHJcbiAgICAgICAgICAgICAgICA8ZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgIDwhLS0gPGxpYi1yZWFjdGl2ZS1zZWxlY3QgKm5nSWY9XCJmbG9vcnNJbnB1dC52YWx1ZVwiIFtmb3JtQ29udHJvbF09XCJmbG9vcnNJbnB1dFwiIFtpZEZpZWxkXT1cIidpZCdcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBbbmFtZUZpZWxkXT1cIidmbG9vck5hbWUnXCIgW2RhdGFdPVwic2VsZWN0ZWRTdG9yZT8uZmxvb3JcIj48L2xpYi1yZWFjdGl2ZS1zZWxlY3Q+IC0tPlxyXG4gICAgICAgICAgICAgICAgICAgIDxkaXYgKGNsaWNrKT1cInRvZ2dsZUZsb29yU2VsZWN0KClcIiBjbGFzcz1cImZsb29yLXNlbGVjdFwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2Pnt7c2VsZWN0ZWRGbG9vcj8uZmxvb3JOYW1lfX08L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdj48c3ZnIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIiB3aWR0aD1cIjIwXCIgaGVpZ2h0PVwiMjBcIiB2aWV3Qm94PVwiMCAwIDIwIDIwXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWxsPVwibm9uZVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxwYXRoIGQ9XCJNNSA3LjVMMTAgMTIuNUwxNSA3LjVcIiBzdHJva2U9XCIjMzQ0MDU0XCIgc3Ryb2tlLXdpZHRoPVwiMS42N1wiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cm9rZS1saW5lY2FwPVwicm91bmRcIiBzdHJva2UtbGluZWpvaW49XCJyb3VuZFwiIC8+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3N2Zz48L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPHVsICpuZ0lmPVwiZmxvb3JTZWxlY3Q/LnNob3dcIiBjbGFzcz1cImxpc3QtdW5zdHlsZWQgbWItMlwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGxpIChjbGljayk9XCJvbkZsb29yU2VsZWN0KGZsb29yLmlkKVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKm5nRm9yPVwibGV0IGZsb29yIG9mIHNlbGVjdGVkU3RvcmU/LmZsb29yOyBsZXQgaSA9IGluZGV4XCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbbmdDbGFzc109XCJmbG9vci5pZCA9PT0gc2VsZWN0ZWRGbG9vci5pZCA/ICdzZWxlY3RlZCc6ICcnXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImQtZmxleCBqdXN0aWZ5LWNvbnRlbnQtYmV0d2VlblwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3Bhbj57e2Zsb29yPy5mbG9vck5hbWV9fTwvc3Bhbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gKm5nSWY9XCJzZWxlY3RlZFN0b3JlPy5mbG9vci5sZW5ndGggPiAxXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChjbGljayk9XCIkZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7IGZsb29yU2VsZWN0LmRlbGV0ZUluZGV4ID0gaVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHN2ZyB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCIgd2lkdGg9XCIyNFwiIGhlaWdodD1cIjIzXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2aWV3Qm94PVwiMCAwIDI0IDIzXCIgZmlsbD1cIm5vbmVcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8cGF0aFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkPVwiTTExIDExLjQ5OTlDMTEgMTIuMDI5MiAxMS40NDc3IDEyLjQ1ODMgMTIgMTIuNDU4M0MxMi41NTIzIDEyLjQ1ODMgMTMgMTIuMDI5MiAxMyAxMS40OTk5QzEzIDEwLjk3MDYgMTIuNTUyMyAxMC41NDE2IDEyIDEwLjU0MTZDMTEuNDQ3NyAxMC41NDE2IDExIDEwLjk3MDYgMTEgMTEuNDk5OVpcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJva2U9XCIjMTAxODI4XCIgc3Ryb2tlLXdpZHRoPVwiMlwiIHN0cm9rZS1saW5lY2FwPVwicm91bmRcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJva2UtbGluZWpvaW49XCJyb3VuZFwiIC8+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHBhdGhcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZD1cIk0xMSAxOC4yMDgzQzExIDE4LjczNzUgMTEuNDQ3NyAxOS4xNjY2IDEyIDE5LjE2NjZDMTIuNTUyMyAxOS4xNjY2IDEzIDE4LjczNzUgMTMgMTguMjA4M0MxMyAxNy42NzkgMTIuNTUyMyAxNy4yNDk5IDEyIDE3LjI0OTlDMTEuNDQ3NyAxNy4yNDk5IDExIDE3LjY3OSAxMSAxOC4yMDgzWlwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cm9rZT1cIiMxMDE4MjhcIiBzdHJva2Utd2lkdGg9XCIyXCIgc3Ryb2tlLWxpbmVjYXA9XCJyb3VuZFwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cm9rZS1saW5lam9pbj1cInJvdW5kXCIgLz5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8cGF0aFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkPVwiTTExIDQuNzkxNTlDMTEgNS4zMjA4NiAxMS40NDc3IDUuNzQ5OTIgMTIgNS43NDk5MkMxMi41NTIzIDUuNzQ5OTIgMTMgNS4zMjA4NiAxMyA0Ljc5MTU5QzEzIDQuMjYyMzEgMTIuNTUyMyAzLjgzMzI1IDEyIDMuODMzMjVDMTEuNDQ3NyAzLjgzMzI1IDExIDQuMjYyMzEgMTEgNC43OTE1OVpcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJva2U9XCIjMTAxODI4XCIgc3Ryb2tlLXdpZHRoPVwiMlwiIHN0cm9rZS1saW5lY2FwPVwicm91bmRcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJva2UtbGluZWpvaW49XCJyb3VuZFwiIC8+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3N2Zz5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9zcGFuPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2ICpuZ0lmPVwiZmxvb3JTZWxlY3QuZGVsZXRlSW5kZXggPT09IGlcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoY2xpY2spPVwiJGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpOyBkZWxldGVGbG9vcihpKVwiIGNsYXNzPVwib3B0aW9uXCI+RGVsZXRlPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2xpPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGxpIChjbGljayk9XCJvcGVuQWRkRmxvb3JNb2RhbCgpXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwibXItMlwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHN2ZyB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCIgd2lkdGg9XCIxNlwiIGhlaWdodD1cIjE2XCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2aWV3Qm94PVwiMCAwIDE2IDE2XCIgZmlsbD1cIm5vbmVcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8cGF0aCBkPVwiTTguMDAwMTYgMy4zMzMyNVYxMi42NjY2TTMuMzMzNSA3Ljk5OTkySDEyLjY2NjhcIiBzdHJva2U9XCIjMTAxODI4XCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3Ryb2tlLXdpZHRoPVwiMlwiIHN0cm9rZS1saW5lY2FwPVwicm91bmRcIiBzdHJva2UtbGluZWpvaW49XCJyb3VuZFwiIC8+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3N2Zz5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9zcGFuPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3Bhbj5BZGQgZmxvb3I8L3NwYW4+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9zcGFuPlxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbGk+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvdWw+XHJcbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJkLWZsZXggYWxpZ24taXRlbXMtY2VudGVyXCIgPlxyXG4gICAgICAgICAgICAgICAgPGJ1dHRvbiAoY2xpY2spPVwiZmluZFBvbHlnb25DZW50ZXJBbmRTY3JvbGwoKVwiIGNsYXNzPVwiYnRuIGJ0bi1zbSBidG4tb3V0bGluZSBiZy13aGl0ZSBtZS0zXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgPHN2ZyB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCIgd2lkdGg9XCIyNlwiIGhlaWdodD1cIjI2XCIgZmlsbD1cIm5vbmVcIiB2aWV3Qm94PVwiMCAwIDEyOCAxMjhcIiBpZD1cInJlY2VudGVyXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDxwYXRoIHN0cm9rZT1cIiMwMDBcIiBzdHJva2UtbGluZWNhcD1cInJvdW5kXCIgc3Ryb2tlLWxpbmVqb2luPVwicm91bmRcIiBzdHJva2Utd2lkdGg9XCI3XCIgZD1cIk0zOCA3NEw0OSA2My41IDM4IDUzTTUzLjUgMzcuNUw2NCA0OC41IDc0LjUgMzcuNU05MCA1M0w3OSA2My41IDkwIDc0TTc0LjUgODkuNUw2NCA3OC41IDUzLjUgODkuNVwiPjwvcGF0aD5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPHBhdGggc3Ryb2tlPVwiIzAwMFwiIHN0cm9rZS1saW5lY2FwPVwicm91bmRcIiBzdHJva2Utd2lkdGg9XCI3XCIgZD1cIk00NCA2NEwxNiA2NE02My41IDQzLjVMNjMuNSAxNS41TTg0IDYzTDExMiA2M002NC41IDgzLjVMNjQuNSAxMTEuNVwiPjwvcGF0aD5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPGNpcmNsZSBjeD1cIjY0XCIgY3k9XCI2NFwiIHI9XCI1XCIgZmlsbD1cIiMwMDBcIj48L2NpcmNsZT5cclxuICAgICAgICAgICAgICAgICAgICAgIDwvc3ZnPlxyXG4gICAgICAgICAgICAgICAgPC9idXR0b24+XHJcbiAgICAgICAgICAgICAgICA8YnV0dG9uIGNsYXNzPVwiYnRuIGJ0bi1zbSBidG4tb3V0bGluZSBiZy13aGl0ZVwiIChjbGljayk9XCJyb3RhdGVQb2x5Z29ucygpXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgPHN2ZyB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCIgd2lkdGg9XCIyNlwiIGhlaWdodD1cIjI2XCIgdmlld0JveD1cIjAgMCAyNiAyNlwiIGZpbGw9XCJub25lXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDxwYXRoXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkPVwiTTYuMzYyNjUgNy4xNzgzOEw3LjE3NjI1IDYuMzYyMzhMNS45MDQyNSA1LjA5MTU4TDUuMDg5NDUgNS45MDUxOEw2LjM2MjY1IDcuMTc4MzhaTTE1LjY3MSA2LjM2MzU4TDE5LjYzNzkgMTAuMzMwNEwyMC45MDk5IDkuMDU3MkwxNi45NDQyIDUuMDkwMzhMMTUuNjcxIDYuMzYzNThaTTE5LjYzNzkgMTguODI1MkwxOC44MjQzIDE5LjYzODhMMjAuMDk2MyAyMC45MDk2TDIwLjkwOTkgMjAuMDk3MkwxOS42Mzc5IDE4LjgyNTJaTTEwLjMyOTUgMTkuNjM4OEw2LjM2MjY1IDE1LjY3Mkw1LjA5MDY1IDE2Ljk0NTJMOS4wNTYyNiAyMC45MTA4TDEwLjMyOTUgMTkuNjM4OFpNMTguODI0MyAxOS42Mzg4QzE3LjY1NDMgMjAuODA3NiAxNi44NDA3IDIxLjYxODggMTYuMTQ1OSAyMi4xNDkyQzE1LjQ3MTUgMjIuNjY0IDE1LjAxNTUgMjIuODI4NCAxNC41NzYzIDIyLjgyODRWMjQuNjI4NEMxNS41Njc1IDI0LjYyODQgMTYuNDAyNyAyNC4yMTY4IDE3LjIzNjcgMjMuNTgwOEMxOC4wNTAzIDIyLjk2MDQgMTguOTYzNSAyMi4wNDQ4IDIwLjA5NjMgMjAuOTEyTDE4LjgyNDMgMTkuNjM4OFpNOS4wNTYyNiAyMC45MTA4QzEwLjE4OTEgMjIuMDQ0OCAxMS4xMDIzIDIyLjk1OTIgMTEuOTE1OSAyMy41ODA4QzEyLjc0OTkgMjQuMjE2OCAxMy41ODUxIDI0LjYyODQgMTQuNTc2MyAyNC42Mjg0VjIyLjgyODRDMTQuMTM3MSAyMi44Mjg0IDEzLjY4MjMgMjIuNjY0IDEzLjAwNjcgMjIuMTQ5MkMxMi4zMTE5IDIxLjYxODggMTEuNDk4MyAyMC44MDc2IDEwLjMyOTUgMTkuNjM4OEw5LjA1NjI2IDIwLjkxMDhaTTE5LjYzNzkgMTAuMzMwNEMyMC44MDY3IDExLjQ5OTIgMjEuNjE3OSAxMi4zMTI4IDIyLjE0ODMgMTMuMDA3NkMyMi42NjMxIDEzLjY4MzIgMjIuODI3NSAxNC4xMzggMjIuODI3NSAxNC41NzcySDI0LjYyNzVDMjQuNjI3NSAxMy41ODYgMjQuMjE1OSAxMi43NTA4IDIzLjU3OTkgMTEuOTE2OEMyMi45NTk1IDExLjEwMzIgMjIuMDQyNyAxMC4xOSAyMC45MDk5IDkuMDU3MkwxOS42Mzc5IDEwLjMzMDRaTTIwLjkwOTkgMjAuMDk3MkMyMi4wNDM5IDE4Ljk2MzIgMjIuOTU4MyAxOC4wNTEyIDIzLjU3OTkgMTcuMjM3NkMyNC4yMTU5IDE2LjQwMzYgMjQuNjI3NSAxNS41Njg0IDI0LjYyNzUgMTQuNTc3MkgyMi44Mjc1QzIyLjgyNzUgMTUuMDE2NCAyMi42NjMxIDE1LjQ3MjQgMjIuMTQ4MyAxNi4xNDY4QzIxLjYxNzkgMTYuODQxNiAyMC44MDY3IDE3LjY1NTIgMTkuNjM3OSAxOC44MjUyTDIwLjkwOTkgMjAuMDk3MlpNNy4xNzYyNSA2LjM2MjM4QzguMzQ2MjUgNS4xOTM1OCA5LjE1OTg1IDQuMzgxMTggOS44NTQ2NSAzLjg1MDc4QzEwLjUyOSAzLjMzNTk4IDEwLjk4NSAzLjE3Mjc4IDExLjQyNDIgMy4xNzI3OFYxLjM3MTU4QzEwLjQzMyAxLjM3MTU4IDkuNTk3ODUgMS43ODMxOCA4Ljc2Mzg1IDIuNDE5MThDNy45NDkwNSAzLjA0MDc4IDcuMDM3MDUgMy45NTUxOCA1LjkwNDI1IDUuMDg3OThMNy4xNzYyNSA2LjM2MjM4Wk0xNi45NDQyIDUuMDkwMzhDMTUuODExNCAzLjk1NjM4IDE0Ljg5ODIgMy4wNDA3OCAxNC4wODQ2IDIuNDE5MThDMTMuMjUwNiAxLjc4MzE4IDEyLjQxNTQgMS4zNzE1OCAxMS40MjQyIDEuMzcxNThWMy4xNzI3OEMxMS44NjM0IDMuMTcyNzggMTIuMzE4MiAzLjMzNTk4IDEyLjk5MzggMy44NTA3OEMxMy42ODg2IDQuMzgxMTggMTQuNTAyMiA1LjE5MjM4IDE1LjY3MSA2LjM2MTE4TDE2Ljk0NDIgNS4wOTAzOFpNNS4wODk0NSA1LjkwMjc4QzMuOTU2NjUgNy4wMzU1OCAzLjA0MjI1IDcuOTQ3NTggMi40MjA2NSA4Ljc2MjM4QzEuNzg0NjUgOS41OTYzOCAxLjM3MzA1IDEwLjQzMTYgMS4zNzMwNSAxMS40MjI4SDMuMTczMDVDMy4xNzMwNSAxMC45ODM2IDMuMzM3NDUgMTAuNTI3NiAzLjg1MjI1IDkuODUzMThDNC4zODI2NSA5LjE1ODM4IDUuMTkzODUgOC4zNDQ3OCA2LjM2MjY1IDcuMTc0NzhMNS4wODk0NSA1LjkwMjc4Wk02LjM2MjY1IDE1LjY3MDhDNS4xOTM4NSAxNC41MDA4IDQuMzgyNjUgMTMuNjg3MiAzLjg1MjI1IDEyLjk5MjRDMy4zMzc0NSAxMi4zMTggMy4xNzMwNSAxMS44NjIgMy4xNzMwNSAxMS40MjI4SDEuMzczMDVDMS4zNzMwNSAxMi40MTQgMS43ODQ2NSAxMy4yNDkyIDIuNDIwNjUgMTQuMDgzMkMzLjA0MjI1IDE0Ljg5NjggMy45NTY2NSAxNS44MSA1LjA4OTQ1IDE2Ljk0MjhMNi4zNjI2NSAxNS42NzA4WlwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWxsPVwiIzFEMjkzOVwiIC8+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDxwYXRoXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkPVwiTTIzLjIgNi45ODMyTDI1IDguMkMyNSA0LjU4MiAyMi40MDU2IDEuNTc5NiAxOSAxTTIuOCAxOS4wMTY4TDEgMTcuOEMxIDIxLjQxOCAzLjU5NDQgMjQuNDIwNCA3IDI1XCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cm9rZT1cIiMxRDI5MzlcIiBzdHJva2Utd2lkdGg9XCIyXCIgc3Ryb2tlLWxpbmVjYXA9XCJyb3VuZFwiIHN0cm9rZS1saW5lam9pbj1cInJvdW5kXCIgLz5cclxuICAgICAgICAgICAgICAgICAgICA8L3N2Zz5cclxuICAgICAgICAgICAgICAgIDwvYnV0dG9uPiAgICBcclxuICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgXHJcbiAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiaGlkZS1zY3JvbGxiYXJcIiBzdHlsZT1cImhlaWdodDogOTMlOyBvdmVyZmxvdzogc2Nyb2xsOyBwb3NpdGlvbjogcmVsYXRpdmU7XCIgI3Njcm9sbENvbnRhaW5lcj5cclxuICAgICAgICAgICAgICAgIDxjYW52YXMgI2dyaWRDYW52YXM+XHJcblxyXG4gICAgICAgICAgICAgICAgPC9jYW52YXM+XHJcblxyXG4gICAgICAgICAgICAgICAgPGRpdiAqbmdJZj1cInBvcHVwVmlzaWJsZSAmJiBwb3B1cFBvc2l0aW9uXCIgW3N0eWxlLnRvcC5weF09XCJwb3B1cFBvc2l0aW9uLnlcIlxyXG4gICAgICAgICAgICAgICAgICAgIFtzdHlsZS5sZWZ0LnB4XT1cInBvcHVwUG9zaXRpb24ueFwiIGNsYXNzPVwiYW5nbGUtd2lkZ2V0XCI+XHJcbiAgICAgICAgICAgICAgICAgICAgPGRpdiAoY2xpY2spPVwidG9nZ2xlV2lkZ2V0RWxlbWVudFNlbGVjdCgpXCIgc3R5bGU9XCJ3aWR0aDogMTQ3cHg7XCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJlbGVtZW50LXR5cGUtZHJvcGRvd24gd2lkZ2V0LWVsZW1lbnQtdHlwZS1kcm9wZG93biBkLWZsZXgganVzdGlmeS1jb250ZW50LWJldHdlZW4gcG9zaXRpb24tcmVsYXRpdmVcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiZC1mbGV4IGFsaWduLWl0ZW1zLWNlbnRlclwiICpuZ0lmPVwiZWxlbWVudFR5cGUgPT09ICd3YWxsJ1wiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzdmcgY2xhc3M9XCJtZS0zXCIgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIHdpZHRoPVwiMjBcIiBoZWlnaHQ9XCIyMFwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZpZXdCb3g9XCIwIDAgMjAgMjBcIiBmaWxsPVwibm9uZVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8cGF0aCBmaWxsLXJ1bGU9XCJldmVub2RkXCIgY2xpcC1ydWxlPVwiZXZlbm9kZFwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkPVwiTTEuMzMzMzMgMS4zMzMzM1YwTDIuNjY2NjcgMFYxLjMzMzMzTDYuNjY2NjcgMS4zMzMzM1YwTDggMFYxLjMzMzMzTDEyIDEuMzMzMzNWMEwxMy4zMzMzIDBWMS4zMzMzM0wxNy4zMzMzIDEuMzMzMzNWMEwxOC42NjY3IDBWMS4zMzMzM0gyMFYyLjY2NjY3SDE4LjY2NjdWNi42NjY2N0gyMFY4SDE4LjY2NjdWMTJIMjBWMTMuMzMzM0gxOC42NjY3VjE3LjMzMzNIMjBWMTguNjY2N0gxOC42NjY3VjIwSDE3LjMzMzNWMTguNjY2N0gxMy4zMzMzVjIwSDEyVjE4LjY2NjdIOFYyMEg2LjY2NjY3VjE4LjY2NjdIMi42NjY2N1YyMEgxLjMzMzMzVjE4LjY2NjdIMEwwIDE3LjMzMzNIMS4zMzMzM0wxLjMzMzMzIDEzLjMzMzNIMEwwIDEySDEuMzMzMzNMMS4zMzMzMyA4SDBMMCA2LjY2NjY3SDEuMzMzMzNMMS4zMzMzMyAyLjY2NjY3SDBMMCAxLjMzMzMzSDEuMzMzMzNaTTIuNjY2NjcgMi42NjY2N0wyLjY2NjY3IDYuNjY2NjdINi42NjY2N1YyLjY2NjY3TDIuNjY2NjcgMi42NjY2N1pNOCAyLjY2NjY3VjYuNjY2NjdIMTJWMi42NjY2N0w4IDIuNjY2NjdaTTEzLjMzMzMgMi42NjY2N1Y2LjY2NjY3SDE3LjMzMzNWMi42NjY2N0gxMy4zMzMzWk0xNy4zMzMzIDhMMTMuMzMzMyA4VjEyTDE3LjMzMzMgMTJWOFpNMTcuMzMzMyAxMy4zMzMzTDEzLjMzMzMgMTMuMzMzM0wxMy4zMzMzIDE3LjMzMzNIMTcuMzMzM1YxMy4zMzMzWk0xMiAxNy4zMzMzTDEyIDEzLjMzMzNIOEw4IDE3LjMzMzNIMTJaTTYuNjY2NjcgMTcuMzMzM1YxMy4zMzMzSDIuNjY2NjdWMTcuMzMzM0g2LjY2NjY3Wk0yLjY2NjY3IDEySDYuNjY2NjdWOEgyLjY2NjY3TDIuNjY2NjcgMTJaTTggOFYxMkgxMlY4SDhaXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbGw9XCIjMzQ0MDU0XCIgLz5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3N2Zz5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInR5cGUtdHh0XCI+V2FsbDwvc3Bhbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvc3Bhbj5cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImQtZmxleCBhbGlnbi1pdGVtcy1jZW50ZXJcIiAqbmdJZj1cImVsZW1lbnRUeXBlID09PSAnZmFjYWRlJ1wiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzdmcgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIHdpZHRoPVwiMjJcIiBoZWlnaHQ9XCIyMlwiIHZpZXdCb3g9XCIwIDAgMjIgMjJcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWxsPVwibm9uZVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8cGF0aFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZD1cIk0xIDExVjIuMjVDMSAxLjU2MjUgMS41NjI1IDEgMi4yNSAxSDE5Ljc1QzIwLjQzNzUgMSAyMSAxLjU2MjUgMjEgMi4yNVYxOS43NUMyMSAyMC40Mzc1IDIwLjQzNzUgMjEgMTkuNzUgMjFIMi4yNUMxLjU2MjUgMjEgMSAyMC40Mzc1IDEgMTkuNzVWMTFaXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cm9rZT1cIiMzNDQwNTRcIiBzdHJva2UtbGluZWNhcD1cInJvdW5kXCIgc3Ryb2tlLWxpbmVqb2luPVwicm91bmRcIiAvPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvc3ZnPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwidHlwZS10eHRcIj5HbGFzcy4uLjwvc3Bhbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvc3Bhbj5cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImQtZmxleCBhbGlnbi1pdGVtcy1jZW50ZXJcIiAqbmdJZj1cImVsZW1lbnRUeXBlID09PSAnb3BlbmluZydcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3ZnIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIiB3aWR0aD1cIjIwXCIgaGVpZ2h0PVwiMjBcIiB2aWV3Qm94PVwiMCAwIDIwIDIwXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsbD1cIm5vbmVcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHBhdGhcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGQ9XCJNMTIuNSAyLjVIMTUuODMzM0MxNi4yNzU0IDIuNSAxNi42OTkzIDIuNjc1NiAxNy4wMTE4IDIuOTg4MTZDMTcuMzI0NCAzLjMwMDcyIDE3LjUgMy43MjQ2NCAxNy41IDQuMTY2NjdWMTUuODMzM0MxNy41IDE2LjI3NTQgMTcuMzI0NCAxNi42OTkzIDE3LjAxMTggMTcuMDExOEMxNi42OTkzIDE3LjMyNDQgMTYuMjc1NCAxNy41IDE1LjgzMzMgMTcuNUgxMi41TTguMzMzMzMgMTQuMTY2N0wxMi41IDEwTTEyLjUgMTBMOC4zMzMzMyA1LjgzMzMzTTEyLjUgMTBIMi41XCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cm9rZT1cIiMxMDE4MjhcIiBzdHJva2Utd2lkdGg9XCIxLjVcIiBzdHJva2UtbGluZWNhcD1cInJvdW5kXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cm9rZS1saW5lam9pbj1cInJvdW5kXCIgLz5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3N2Zz5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInR5cGUtdHh0XCI+T3BlbmkuLi48L3NwYW4+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3NwYW4+XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJkLWZsZXggYWxpZ24taXRlbXMtY2VudGVyXCIgKm5nSWY9XCJlbGVtZW50VHlwZSA9PT0gJ2VudHJhbmNlJ1wiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzdmcgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIHdpZHRoPVwiMjFcIiBoZWlnaHQ9XCIxOFwiIHZpZXdCb3g9XCIwIDAgMjEgMThcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWxsPVwibm9uZVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8cGF0aCBmaWxsLXJ1bGU9XCJldmVub2RkXCIgY2xpcC1ydWxlPVwiZXZlbm9kZFwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkPVwiTTE3LjkzMzMgMS4zNzk0OUM4Ljc5MDkgMS4zNzk0OSAxLjM3OTQ5IDguNzkwOSAxLjM3OTQ5IDE3LjkzMzNIMEMwIDguMDI5MDMgOC4wMjkwMyAwIDE3LjkzMzMgMFYxLjM3OTQ5WlwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWxsPVwiIzFEMjkzOVwiIC8+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxwYXRoIGZpbGwtcnVsZT1cImV2ZW5vZGRcIiBjbGlwLXJ1bGU9XCJldmVub2RkXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGQ9XCJNMTkuMzEzMiAxLjM3OTQ5SDE3LjkzMzNMMTcuOTMzNyAxNi41NTM4SDE5LjMxMzJWMS4zNzk0OVpNMTYuNTU0MiAwVjE3LjkzMzNIMjAuNjkyN1YwSDE2LjU1NDJaXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbGw9XCIjMUQyOTM5XCIgLz5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3N2Zz5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInR5cGUtdHh0XCI+RW50cmEuLi48L3NwYW4+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3NwYW4+XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJkb3duLWFycm93XCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3ZnIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIiB3aWR0aD1cIjIwXCIgaGVpZ2h0PVwiMjBcIiB2aWV3Qm94PVwiMCAwIDIwIDIwXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWxsPVwibm9uZVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxwYXRoIGQ9XCJNNSA3LjVMMTAgMTIuNUwxNSA3LjVcIiBzdHJva2U9XCIjNjY3MDg1XCIgc3Ryb2tlLXdpZHRoPVwiMS42NjY2N1wiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cm9rZS1saW5lY2FwPVwicm91bmRcIiBzdHJva2UtbGluZWpvaW49XCJyb3VuZFwiIC8+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3N2Zz5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8dWwgKm5nSWY9XCJ3aWRnZXRFbGVtZW50U2VsZWN0Py5zaG93IFwiIFtuZ0NsYXNzXT1cIiB3aWRnZXRFbGVtZW50U2VsZWN0LnNob3cgPyAnei00JzogJydcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJsaXN0LXVuc3R5bGVkIG1iLTJcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxsaSAoY2xpY2spPVwiZWxlbWVudFR5cGUgPSAnd2FsbCdcIiBbbmdDbGFzc109XCJlbGVtZW50VHlwZSA9PT0gJ3dhbGwnID8gJ3NlbGVjdGVkJyA6ICcnXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cInNlbGVjdGVkXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImQtZmxleFwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibWUtM1wiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHN2ZyB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCIgd2lkdGg9XCIyMFwiIGhlaWdodD1cIjIwXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2aWV3Qm94PVwiMCAwIDIwIDIwXCIgZmlsbD1cIm5vbmVcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8cGF0aCBmaWxsLXJ1bGU9XCJldmVub2RkXCIgY2xpcC1ydWxlPVwiZXZlbm9kZFwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGQ9XCJNMS4zMzMzMyAxLjMzMzMzVjBMMi42NjY2NyAwVjEuMzMzMzNMNi42NjY2NyAxLjMzMzMzVjBMOCAwVjEuMzMzMzNMMTIgMS4zMzMzM1YwTDEzLjMzMzMgMFYxLjMzMzMzTDE3LjMzMzMgMS4zMzMzM1YwTDE4LjY2NjcgMFYxLjMzMzMzSDIwVjIuNjY2NjdIMTguNjY2N1Y2LjY2NjY3SDIwVjhIMTguNjY2N1YxMkgyMFYxMy4zMzMzSDE4LjY2NjdWMTcuMzMzM0gyMFYxOC42NjY3SDE4LjY2NjdWMjBIMTcuMzMzM1YxOC42NjY3SDEzLjMzMzNWMjBIMTJWMTguNjY2N0g4VjIwSDYuNjY2NjdWMTguNjY2N0gyLjY2NjY3VjIwSDEuMzMzMzNWMTguNjY2N0gwTDAgMTcuMzMzM0gxLjMzMzMzTDEuMzMzMzMgMTMuMzMzM0gwTDAgMTJIMS4zMzMzM0wxLjMzMzMzIDhIMEwwIDYuNjY2NjdIMS4zMzMzM0wxLjMzMzMzIDIuNjY2NjdIMEwwIDEuMzMzMzNIMS4zMzMzM1pNMi42NjY2NyAyLjY2NjY3TDIuNjY2NjcgNi42NjY2N0g2LjY2NjY3VjIuNjY2NjdMMi42NjY2NyAyLjY2NjY3Wk04IDIuNjY2NjdWNi42NjY2N0gxMlYyLjY2NjY3TDggMi42NjY2N1pNMTMuMzMzMyAyLjY2NjY3VjYuNjY2NjdIMTcuMzMzM1YyLjY2NjY3SDEzLjMzMzNaTTE3LjMzMzMgOEwxMy4zMzMzIDhWMTJMMTcuMzMzMyAxMlY4Wk0xNy4zMzMzIDEzLjMzMzNMMTMuMzMzMyAxMy4zMzMzTDEzLjMzMzMgMTcuMzMzM0gxNy4zMzMzVjEzLjMzMzNaTTEyIDE3LjMzMzNMMTIgMTMuMzMzM0g4TDggMTcuMzMzM0gxMlpNNi42NjY2NyAxNy4zMzMzVjEzLjMzMzNIMi42NjY2N1YxNy4zMzMzSDYuNjY2NjdaTTIuNjY2NjcgMTJINi42NjY2N1Y4SDIuNjY2NjdMMi42NjY2NyAxMlpNOCA4VjEySDEyVjhIOFpcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWxsPVwiIzM0NDA1NFwiIC8+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3N2Zz5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXY+V2FsbDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzdmcgKm5nSWY9XCJlbGVtZW50VHlwZSA9PT0gJ3dhbGwnXCIgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIHdpZHRoPVwiMjBcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaGVpZ2h0PVwiMjBcIiB2aWV3Qm94PVwiMCAwIDIwIDIwXCIgZmlsbD1cIm5vbmVcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxwYXRoIGQ9XCJNMTYuNjY2MyA1TDcuNDk5NjcgMTQuMTY2N0wzLjMzMzAxIDEwXCIgc3Ryb2tlPVwiIzAwQTNGRlwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3Ryb2tlLXdpZHRoPVwiMS42NjY2N1wiIHN0cm9rZS1saW5lY2FwPVwicm91bmRcIiBzdHJva2UtbGluZWpvaW49XCJyb3VuZFwiIC8+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvc3ZnPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9saT5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxsaSAoY2xpY2spPVwiZWxlbWVudFR5cGUgPSAnZmFjYWRlJ1wiIFtuZ0NsYXNzXT1cImVsZW1lbnRUeXBlID09PSAnZmFjYWRlJyA/ICdzZWxlY3RlZCcgOiAnJ1wiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJkLWZsZXhcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm1lLTNcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzdmcgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIHdpZHRoPVwiMjJcIiBoZWlnaHQ9XCIyMlwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmlld0JveD1cIjAgMCAyMiAyMlwiIGZpbGw9XCJub25lXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHBhdGhcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZD1cIk0xIDExVjIuMjVDMSAxLjU2MjUgMS41NjI1IDEgMi4yNSAxSDE5Ljc1QzIwLjQzNzUgMSAyMSAxLjU2MjUgMjEgMi4yNVYxOS43NUMyMSAyMC40Mzc1IDIwLjQzNzUgMjEgMTkuNzUgMjFIMi4yNUMxLjU2MjUgMjEgMSAyMC40Mzc1IDEgMTkuNzVWMTFaXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3Ryb2tlPVwiIzM0NDA1NFwiIHN0cm9rZS1saW5lY2FwPVwicm91bmRcIiBzdHJva2UtbGluZWpvaW49XCJyb3VuZFwiIC8+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3N2Zz5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXY+R2xhc3MvRmFjYWRlPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHN2ZyAqbmdJZj1cImVsZW1lbnRUeXBlID09PSAnZmFjYWRlJ1wiIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIiB3aWR0aD1cIjIwXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhlaWdodD1cIjIwXCIgdmlld0JveD1cIjAgMCAyMCAyMFwiIGZpbGw9XCJub25lXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8cGF0aCBkPVwiTTE2LjY2NjMgNUw3LjQ5OTY3IDE0LjE2NjdMMy4zMzMwMSAxMFwiIHN0cm9rZT1cIiMwMEEzRkZcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cm9rZS13aWR0aD1cIjEuNjY2NjdcIiBzdHJva2UtbGluZWNhcD1cInJvdW5kXCIgc3Ryb2tlLWxpbmVqb2luPVwicm91bmRcIiAvPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3N2Zz5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbGk+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bGkgKGNsaWNrKT1cImVsZW1lbnRUeXBlID0gJ29wZW5pbmcnXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbbmdDbGFzc109XCJlbGVtZW50VHlwZSA9PT0gJ29wZW5pbmcnID8gJ3NlbGVjdGVkJyA6ICcnXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImQtZmxleFwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibWUtM1wiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHN2ZyB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCIgd2lkdGg9XCIyMFwiIGhlaWdodD1cIjIwXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2aWV3Qm94PVwiMCAwIDIwIDIwXCIgZmlsbD1cIm5vbmVcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8cGF0aFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkPVwiTTEyLjUgMi41SDE1LjgzMzNDMTYuMjc1NCAyLjUgMTYuNjk5MyAyLjY3NTYgMTcuMDExOCAyLjk4ODE2QzE3LjMyNDQgMy4zMDA3MiAxNy41IDMuNzI0NjQgMTcuNSA0LjE2NjY3VjE1LjgzMzNDMTcuNSAxNi4yNzU0IDE3LjMyNDQgMTYuNjk5MyAxNy4wMTE4IDE3LjAxMThDMTYuNjk5MyAxNy4zMjQ0IDE2LjI3NTQgMTcuNSAxNS44MzMzIDE3LjVIMTIuNU04LjMzMzMzIDE0LjE2NjdMMTIuNSAxME0xMi41IDEwTDguMzMzMzMgNS44MzMzM00xMi41IDEwSDIuNVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cm9rZT1cIiMxMDE4MjhcIiBzdHJva2Utd2lkdGg9XCIxLjVcIiBzdHJva2UtbGluZWNhcD1cInJvdW5kXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3Ryb2tlLWxpbmVqb2luPVwicm91bmRcIiAvPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9zdmc+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2Pk9wZW5pbmc8L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3ZnICpuZ0lmPVwiZWxlbWVudFR5cGUgPT09ICdvcGVuaW5nJ1wiIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIiB3aWR0aD1cIjIwXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhlaWdodD1cIjIwXCIgdmlld0JveD1cIjAgMCAyMCAyMFwiIGZpbGw9XCJub25lXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8cGF0aCBkPVwiTTE2LjY2NjMgNUw3LjQ5OTY3IDE0LjE2NjdMMy4zMzMwMSAxMFwiIHN0cm9rZT1cIiMwMEEzRkZcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cm9rZS13aWR0aD1cIjEuNjY2NjdcIiBzdHJva2UtbGluZWNhcD1cInJvdW5kXCIgc3Ryb2tlLWxpbmVqb2luPVwicm91bmRcIiAvPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3N2Zz5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbGk+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bGkgKGNsaWNrKT1cImVsZW1lbnRUeXBlID0gJ2VudHJhbmNlJ1wiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW25nQ2xhc3NdPVwiZWxlbWVudFR5cGUgPT09ICdlbnRyYW5jZScgPyAnc2VsZWN0ZWQnIDogJydcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZC1mbGV4XCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJtZS0zXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3ZnIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIiB3aWR0aD1cIjIxXCIgaGVpZ2h0PVwiMThcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZpZXdCb3g9XCIwIDAgMjEgMThcIiBmaWxsPVwibm9uZVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxwYXRoIGZpbGwtcnVsZT1cImV2ZW5vZGRcIiBjbGlwLXJ1bGU9XCJldmVub2RkXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZD1cIk0xNy45MzMzIDEuMzc5NDlDOC43OTA5IDEuMzc5NDkgMS4zNzk0OSA4Ljc5MDkgMS4zNzk0OSAxNy45MzMzSDBDMCA4LjAyOTAzIDguMDI5MDMgMCAxNy45MzMzIDBWMS4zNzk0OVpcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWxsPVwiIzFEMjkzOVwiIC8+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHBhdGggZmlsbC1ydWxlPVwiZXZlbm9kZFwiIGNsaXAtcnVsZT1cImV2ZW5vZGRcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkPVwiTTE5LjMxMzIgMS4zNzk0OUgxNy45MzMzTDE3LjkzMzcgMTYuNTUzOEgxOS4zMTMyVjEuMzc5NDlaTTE2LjU1NDIgMFYxNy45MzMzSDIwLjY5MjdWMEgxNi41NTQyWlwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbGw9XCIjMUQyOTM5XCIgLz5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvc3ZnPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdj5FbnRyYW5jZTwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzdmcgKm5nSWY9XCJlbGVtZW50VHlwZSA9PT0gJ2VudHJhbmNlJ1wiIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2lkdGg9XCIyMFwiIGhlaWdodD1cIjIwXCIgdmlld0JveD1cIjAgMCAyMCAyMFwiIGZpbGw9XCJub25lXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8cGF0aCBkPVwiTTE2LjY2NjMgNUw3LjQ5OTY3IDE0LjE2NjdMMy4zMzMwMSAxMFwiIHN0cm9rZT1cIiMwMEEzRkZcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cm9rZS13aWR0aD1cIjEuNjY2NjdcIiBzdHJva2UtbGluZWNhcD1cInJvdW5kXCIgc3Ryb2tlLWxpbmVqb2luPVwicm91bmRcIiAvPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3N2Zz5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbGk+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvdWw+XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG5cclxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwidW5pdC1pbnB1dFwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8c3ZnIChjbGljayk9XCJvbldpZGdldERpc3RhbmNlQ2hhbmdlKCdkZWNyZW1lbnQnKVwiIGNsYXNzPVwiY3Vyc29yLXBvaW50ZXJcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIHdpZHRoPVwiMTRcIiBoZWlnaHQ9XCIxNFwiIHZpZXdCb3g9XCIwIDAgMTQgMTRcIiBmaWxsPVwibm9uZVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPHBhdGggZD1cIk0yLjkxNjUgN0gxMS4wODMyXCIgc3Ryb2tlPVwiIzY2NzA4NVwiIHN0cm9rZS13aWR0aD1cIjJcIiBzdHJva2UtbGluZWNhcD1cInJvdW5kXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJva2UtbGluZWpvaW49XCJyb3VuZFwiIC8+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvc3ZnPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8c3Bhbj57e21vdmVQaXhlbHN9fTwvc3Bhbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPHN2ZyAoY2xpY2spPVwib25XaWRnZXREaXN0YW5jZUNoYW5nZSgnaW5jcmVtZW50JylcIiBjbGFzcz1cImN1cnNvci1wb2ludGVyXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIiB3aWR0aD1cIjE0XCIgaGVpZ2h0PVwiMTRcIiB2aWV3Qm94PVwiMCAwIDE0IDE0XCIgZmlsbD1cIm5vbmVcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxwYXRoIGQ9XCJNNi45OTk4NCAyLjkxNjVWMTEuMDgzMk0yLjkxNjUgNi45OTk4NEgxMS4wODMyXCIgc3Ryb2tlPVwiIzY2NzA4NVwiIHN0cm9rZS13aWR0aD1cIjJcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cm9rZS1saW5lY2FwPVwicm91bmRcIiBzdHJva2UtbGluZWpvaW49XCJyb3VuZFwiIC8+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvc3ZnPlxyXG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG5cclxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwicG9zaXRpb24tcmVsYXRpdmVcIiBzdHlsZT1cInBvc2l0aW9uOiByZWxhdGl2ZTsgd2lkdGg6IDIyOXB4OyBoZWlnaHQ6IDIyOXB4O1wiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHlsZT1cInBvc2l0aW9uOiBhYnNvbHV0ZTsgdG9wOiA1MCU7IGxlZnQ6IDUwJTsgdHJhbnNmb3JtOiB0cmFuc2xhdGUoLTUwJSwgLTUwJSk7IHotaW5kZXg6IDM7XCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IHN0eWxlPVwibWFyZ2luLWJvdHRvbTogMjdweDtcIiBjbGFzcz1cImQtZmxleCBqdXN0aWZ5LWNvbnRlbnQtY2VudGVyXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiAoY2xpY2spPVwib25XaWRnZXREaXJlY3Rpb25DaGFuZ2UoJ3VwJylcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbbmdDbGFzc109XCJtb3ZlRGlyZWN0aW9uID09PSAndXAnID8gJ2RpcmVjdGlvbi1zZWxlY3RlZCcgOiAnJ1wiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiZGlyZWN0aW9uLWlucHV0XCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzdmcgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIHdpZHRoPVwiMTJcIiBoZWlnaHQ9XCIxMlwiIHZpZXdCb3g9XCIwIDAgMTIgMTJcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsbD1cIm5vbmVcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxwYXRoXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZD1cIk02LjAwMDE2IDEwLjY2NzNMNi4wMDAxNiAxLjMzMzk4TTYuMDAwMTYgMS4zMzM5OEwxLjMzMzUgNi4wMDA2NU02LjAwMDE2IDEuMzMzOThMMTAuNjY2OCA2LjAwMDY1XCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJva2U9XCIjNjY3MDg1XCIgc3Ryb2tlLXdpZHRoPVwiMlwiIHN0cm9rZS1saW5lY2FwPVwicm91bmRcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cm9rZS1saW5lam9pbj1cInJvdW5kXCIgLz5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9zdmc+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJkLWZsZXgganVzdGlmeS1jb250ZW50LWNlbnRlciBhbGlnbi1pdGVtcy1jZW50ZXJcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IChjbGljayk9XCJvbldpZGdldERpcmVjdGlvbkNoYW5nZSgnbGVmdCcpXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW25nQ2xhc3NdPVwibW92ZURpcmVjdGlvbiA9PT0gJ2xlZnQnID8gJ2RpcmVjdGlvbi1zZWxlY3RlZCcgOiAnJ1wiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0eWxlPVwibWFyZ2luLXJpZ2h0OiA4cHg7XCIgY2xhc3M9XCJkaXJlY3Rpb24taW5wdXRcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHN2ZyB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCIgd2lkdGg9XCIxMlwiIGhlaWdodD1cIjEyXCIgdmlld0JveD1cIjAgMCAxMiAxMlwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWxsPVwibm9uZVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHBhdGhcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkPVwiTTEwLjY2NjMgNS45OTkzNUwxLjMzMzAxIDUuOTk5MzVNMS4zMzMwMSA1Ljk5OTM1TDUuOTk5NjcgMTAuNjY2TTEuMzMzMDEgNS45OTkzNUw1Ljk5OTY4IDEuMzMyNjhcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cm9rZT1cIiM2NjcwODVcIiBzdHJva2Utd2lkdGg9XCIyXCIgc3Ryb2tlLWxpbmVjYXA9XCJyb3VuZFwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3Ryb2tlLWxpbmVqb2luPVwicm91bmRcIiAvPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3N2Zz5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInVuaXQtaW5wdXRcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHN2ZyAoY2xpY2spPVwib25XaWRnZXRBbmdsZUNoYW5nZSgnZGVjcmVtZW50JylcIiBjbGFzcz1cImN1cnNvci1wb2ludGVyXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIiB3aWR0aD1cIjE0XCIgaGVpZ2h0PVwiMTRcIiB2aWV3Qm94PVwiMCAwIDE0IDE0XCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbGw9XCJub25lXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8cGF0aCBkPVwiTTIuOTE2NSA3SDExLjA4MzJcIiBzdHJva2U9XCIjNjY3MDg1XCIgc3Ryb2tlLXdpZHRoPVwiMlwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3Ryb2tlLWxpbmVjYXA9XCJyb3VuZFwiIHN0cm9rZS1saW5lam9pbj1cInJvdW5kXCIgLz5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9zdmc+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuPnt7bW92ZUFuZ2xlfX3CsDwvc3Bhbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHN2ZyAoY2xpY2spPVwib25XaWRnZXRBbmdsZUNoYW5nZSgnaW5jcmVtZW50JylcIiBjbGFzcz1cImN1cnNvci1wb2ludGVyXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIiB3aWR0aD1cIjE0XCIgaGVpZ2h0PVwiMTRcIiB2aWV3Qm94PVwiMCAwIDE0IDE0XCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbGw9XCJub25lXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8cGF0aCBkPVwiTTYuOTk5ODQgMi45MTY1VjExLjA4MzJNMi45MTY1IDYuOTk5ODRIMTEuMDgzMlwiIHN0cm9rZT1cIiM2NjcwODVcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cm9rZS13aWR0aD1cIjJcIiBzdHJva2UtbGluZWNhcD1cInJvdW5kXCIgc3Ryb2tlLWxpbmVqb2luPVwicm91bmRcIiAvPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3N2Zz5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiAoY2xpY2spPVwib25XaWRnZXREaXJlY3Rpb25DaGFuZ2UoJ3JpZ2h0JylcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbbmdDbGFzc109XCJtb3ZlRGlyZWN0aW9uID09PSAncmlnaHQnID8gJ2RpcmVjdGlvbi1zZWxlY3RlZCcgOiAnJ1wiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0eWxlPVwibWFyZ2luLWxlZnQ6IDhweDtcIiBjbGFzcz1cImRpcmVjdGlvbi1pbnB1dFwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3ZnIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIiB3aWR0aD1cIjEyXCIgaGVpZ2h0PVwiMTJcIiB2aWV3Qm94PVwiMCAwIDEyIDEyXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbGw9XCJub25lXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8cGF0aFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGQ9XCJNMS4zMzM2NiA2LjAwMDY1TDEwLjY2NyA2LjAwMDY1TTEwLjY2NyA2LjAwMDY1TDYuMDAwMzMgMS4zMzM5OE0xMC42NjcgNi4wMDA2NUw2LjAwMDMzIDEwLjY2NzNcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cm9rZT1cIiM2NjcwODVcIiBzdHJva2Utd2lkdGg9XCIyXCIgc3Ryb2tlLWxpbmVjYXA9XCJyb3VuZFwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3Ryb2tlLWxpbmVqb2luPVwicm91bmRcIiAvPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3N2Zz5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IHN0eWxlPVwibWFyZ2luLXRvcDogMjdweDtcIiBjbGFzcz1cImQtZmxleCBqdXN0aWZ5LWNvbnRlbnQtY2VudGVyXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiAoY2xpY2spPVwib25XaWRnZXREaXJlY3Rpb25DaGFuZ2UoJ2Rvd24nKVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtuZ0NsYXNzXT1cIm1vdmVEaXJlY3Rpb24gPT09ICdkb3duJyA/ICdkaXJlY3Rpb24tc2VsZWN0ZWQnIDogJydcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImRpcmVjdGlvbi1pbnB1dFwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3ZnIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIiB3aWR0aD1cIjEyXCIgaGVpZ2h0PVwiMTJcIiB2aWV3Qm94PVwiMCAwIDEyIDEyXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbGw9XCJub25lXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8cGF0aFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGQ9XCJNNS45OTk4NCAxLjMzMjY4TDUuOTk5ODQgMTAuNjY2TTUuOTk5ODQgMTAuNjY2TDEwLjY2NjUgNS45OTkzNU01Ljk5OTg0IDEwLjY2NkwxLjMzMzE3IDUuOTk5MzVcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cm9rZT1cIiM2NjcwODVcIiBzdHJva2Utd2lkdGg9XCIyXCIgc3Ryb2tlLWxpbmVjYXA9XCJyb3VuZFwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3Ryb2tlLWxpbmVqb2luPVwicm91bmRcIiAvPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3N2Zz5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPGNhbnZhcyBoZWlnaHQ9XCIyMjlweFwiIHdpZHRoPVwiMjI5cHhcIiAjd2lkZ2V0Q2FudmFzXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHlsZT1cInBvc2l0aW9uOiBhYnNvbHV0ZTsgdG9wOiA1MCU7IGxlZnQ6IDUwJTsgdHJhbnNmb3JtOiB0cmFuc2xhdGUoLTUwJSwgLTUwJSk7IHotaW5kZXg6IDE7XCI+PC9jYW52YXM+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgc3R5bGU9XCJwb3NpdGlvbjogYWJzb2x1dGU7IHRvcDogNTAlOyBsZWZ0OiA1MCU7IHRyYW5zZm9ybTogdHJhbnNsYXRlKC01MCUsIC01MCUpOyB6LWluZGV4OiAyO1wiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAjY2lyY2xlIGNsYXNzPVwiY2lyY2xlXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibGluZVwiICpuZ0Zvcj1cImxldCBsaW5lIG9mIGxpbmVzXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbbmdDbGFzc109XCJ7J2xpbmUtLWhpZ2hsaWdodCc6IGxpbmUuaGlnaGxpZ2h0LCAnbGluZS0taW52aXNpYmxlJzogbGluZS5pbnZpc2libGV9XCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbc3R5bGUudHJhbnNmb3JtXT1cImxpbmUudHJhbnNmb3JtXCI+PC9kaXY+XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiAjcG9pbnRlciBjbGFzcz1cInBvaW50ZXJcIj48L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIDxidXR0b24gKGNsaWNrKT1cIm1vdmVQb2ludFdpdGhBbmdsZSgpXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgW2Rpc2FibGVkXT1cIiFtb3ZlUGl4ZWxzICYmIG1vdmVBbmdsZSAgIT09IHVuZGVmaW5lZCAmJiBtb3ZlQW5nbGUgICE9PSBudWxsXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCIgdy0xMDAgZ28tYnRuXCI+R288L2J1dHRvbj5cclxuXHJcbiAgICAgICAgICAgICAgICA8L2Rpdj5cclxuXHJcbiAgICAgICAgICAgICAgICA8IS0tIDxkaXYgKm5nSWY9XCJwb3B1cFZpc2libGUgJiYgcG9wdXBQb3NpdGlvblwiIFtzdHlsZS50b3AucHhdPVwicG9wdXBQb3NpdGlvbi55XCIgW3N0eWxlLmxlZnQucHhdPVwicG9wdXBQb3NpdGlvbi54XCJcclxuICAgICAgICAgICAgICAgICAgICBjbGFzcz1cInBvcHVwXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgPGxhYmVsPk1vdmUgUGl4ZWxzOjwvbGFiZWw+XHJcbiAgICAgICAgICAgICAgICAgICAgPHNlbGVjdCBbKG5nTW9kZWwpXT1cImVsZW1lbnRUeXBlXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9XCJ3YWxsXCI+V2FsbDwvb3B0aW9uPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8b3B0aW9uIHZhbHVlPVwiZmFjYWRlXCI+R2xhc3MvRmFjYWRlPC9vcHRpb24+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9XCJvcGVuaW5nXCI+T3BlbmluZzwvb3B0aW9uPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8b3B0aW9uIHZhbHVlPVwiZW50cmFuY2VcIj5FbnRyYW5jZTwvb3B0aW9uPlxyXG4gICAgICAgICAgICAgICAgICAgIDwvc2VsZWN0PlxyXG4gICAgICAgICAgICAgICAgICAgIDxpbnB1dCB0eXBlPVwibnVtYmVyXCIgWyhuZ01vZGVsKV09XCJtb3ZlUGl4ZWxzXCIgLz5cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgPHNlbGVjdCBbKG5nTW9kZWwpXT1cIm1vdmVEaXJlY3Rpb25cIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPG9wdGlvbiB2YWx1ZT1cInJpZ2h0XCI+UmlnaHQ8L29wdGlvbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPG9wdGlvbiB2YWx1ZT1cImRvd25cIj5Eb3duPC9vcHRpb24+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9XCJsZWZ0XCI+TGVmdDwvb3B0aW9uPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8b3B0aW9uIHZhbHVlPVwidXBcIj5VcDwvb3B0aW9uPlxyXG4gICAgICAgICAgICAgICAgICAgIDwvc2VsZWN0PlxyXG4gICAgICAgICAgICAgICAgICAgIDxpbnB1dCB0eXBlPVwibnVtYmVyXCIgWyhuZ01vZGVsKV09XCJtb3ZlQW5nbGVcIiAobmdNb2RlbENoYW5nZSk9XCJsYXlvdXRMZW5ndGhQcmV2aWV3KClcIiAvPlxyXG4gICAgICAgICAgICAgICAgICAgIDxidXR0b24gKGNsaWNrKT1cIm1vdmVQb2ludFdpdGhBbmdsZSgpXCI+TW92ZSB3aXRoIGFuZ2xlPC9idXR0b24+XHJcbiAgICAgICAgICAgICAgICA8L2Rpdj4gLS0+XHJcbiAgICAgICAgICAgIDwvZGl2PlxyXG5cclxuICAgICAgICA8L2Rpdj5cclxuICAgIDwvZGl2PlxyXG5cclxuICAgIDxkaXYgKm5nSWY9XCJwbGFub1N0b3JlTGlzdC5sZW5ndGggPiAxXCIgY2xhc3M9XCJjb2wtMTIgbXQtNlwiPlxyXG4gICAgICAgIDxkaXYgc3R5bGU9XCJwYWRkaW5nOiAwcHggIWltcG9ydGFudDtcIiBjbGFzcz1cImMtY2FyZFwiPlxyXG4gICAgICAgICAgICA8bGliLXBhZ2luYXRpb24gW2l0ZW1zUGVyUGFnZV09XCJpdGVtc1BlclBhZ2VcIiAocGFnZUNoYW5nZSk9XCJvblBhZ2VDaGFuZ2UoJGV2ZW50KVwiIFtjdXJyZW50UGFnZV09XCJjdXJyZW50UGFnZVwiIFt0b3RhbEl0ZW1zXT1cInRvdGFsSXRlbXNcIlxyXG4gICAgICAgICAgICAgICAgW3BhZ2luYXRpb25TaXplc109XCJwYWdpbmF0aW9uU2l6ZXNcIiBbcGFnZVNpemVdPVwicGFnZVNpemVcIj48L2xpYi1wYWdpbmF0aW9uPlxyXG4gICAgICAgIDwvZGl2PlxyXG4gICAgPC9kaXY+XHJcblxyXG48L2Rpdj4iXX0=
|