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,809 @@
|
|
|
1
|
+
import { Component, HostListener, ViewChild } from '@angular/core';
|
|
2
|
+
import { FormControl } from '@angular/forms';
|
|
3
|
+
import { Subject, takeUntil } from 'rxjs';
|
|
4
|
+
import { StoreOffcanvasComponentComponent } from '../store-offcanvas-component/store-offcanvas-component.component';
|
|
5
|
+
import { CompleteLayoutComponent } from './popups/complete-layout/complete-layout.component';
|
|
6
|
+
import * as i0 from "@angular/core";
|
|
7
|
+
import * as i1 from "@angular/router";
|
|
8
|
+
import * as i2 from "../../services/store-builder.service";
|
|
9
|
+
import * as i3 from "@ng-bootstrap/ng-bootstrap";
|
|
10
|
+
import * as i4 from "tango-app-ui-shared";
|
|
11
|
+
import * as i5 from "@angular/common";
|
|
12
|
+
import * as i6 from "@angular/forms";
|
|
13
|
+
import * as i7 from "../custom-select/custom-select.component";
|
|
14
|
+
export class LayoutSummaryComponent {
|
|
15
|
+
route;
|
|
16
|
+
apiService;
|
|
17
|
+
modalService;
|
|
18
|
+
offcanvasService;
|
|
19
|
+
router;
|
|
20
|
+
modalDef;
|
|
21
|
+
toastService;
|
|
22
|
+
floorsInput = new FormControl();
|
|
23
|
+
canvasRef;
|
|
24
|
+
scrollContainerRef;
|
|
25
|
+
completeLayout;
|
|
26
|
+
gridWidth = 5;
|
|
27
|
+
gridHeight = 5;
|
|
28
|
+
ctx;
|
|
29
|
+
canvas;
|
|
30
|
+
layoutPolygon = [[
|
|
31
|
+
{
|
|
32
|
+
"x": 100,
|
|
33
|
+
"y": 100
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
"x": 100,
|
|
37
|
+
"y": 100
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
"elementType": "wall",
|
|
41
|
+
"distance": 0,
|
|
42
|
+
"unit": "ft",
|
|
43
|
+
"direction": "right",
|
|
44
|
+
"angle": 90,
|
|
45
|
+
"elementNumber": 1
|
|
46
|
+
}
|
|
47
|
+
]];
|
|
48
|
+
scale = 1;
|
|
49
|
+
destroy$ = new Subject();
|
|
50
|
+
headerData;
|
|
51
|
+
planoStoreList = [];
|
|
52
|
+
selectedStore;
|
|
53
|
+
selectedFloor;
|
|
54
|
+
wallCapacity;
|
|
55
|
+
facadeCapacity;
|
|
56
|
+
floorCapacity;
|
|
57
|
+
floorSelect = { show: false, deleteIndex: null };
|
|
58
|
+
markAsCompleteType = 'single';
|
|
59
|
+
itemsPerPage = 1;
|
|
60
|
+
currentPage = 0;
|
|
61
|
+
totalItems = 1;
|
|
62
|
+
paginationSizes = [1];
|
|
63
|
+
pageSize = 1;
|
|
64
|
+
pixelPerMetre = 50;
|
|
65
|
+
onFloorSelect(floorId) {
|
|
66
|
+
if (this.layoutPolygon[0][0].x !== this.layoutPolygon[0][1].x && this.layoutPolygon[0][0].y !== this.layoutPolygon[0][1].y) {
|
|
67
|
+
this.updateFloorLayout();
|
|
68
|
+
}
|
|
69
|
+
this.selectedFloor = this.selectedStore.floor.filter((floor) => floor.id === floorId)[0];
|
|
70
|
+
this.generateLayoutPolygon(this.selectedFloor.layoutPolygon);
|
|
71
|
+
}
|
|
72
|
+
onOutsideClick(event) {
|
|
73
|
+
const clickedInside6 = event.target.closest('.floor-select');
|
|
74
|
+
if (!clickedInside6) {
|
|
75
|
+
this.floorSelect = { show: false, deleteIndex: null };
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
toggleFloorSelect() {
|
|
79
|
+
this.floorSelect = {
|
|
80
|
+
show: !this.floorSelect.show,
|
|
81
|
+
deleteIndex: null
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
constructor(route, apiService, modalService, offcanvasService, router, modalDef, toastService) {
|
|
85
|
+
this.route = route;
|
|
86
|
+
this.apiService = apiService;
|
|
87
|
+
this.modalService = modalService;
|
|
88
|
+
this.offcanvasService = offcanvasService;
|
|
89
|
+
this.router = router;
|
|
90
|
+
this.modalDef = modalDef;
|
|
91
|
+
this.toastService = toastService;
|
|
92
|
+
this.headerData = JSON.parse(localStorage.getItem('header-filters'));
|
|
93
|
+
}
|
|
94
|
+
ngAfterViewInit() {
|
|
95
|
+
this.initializeLayout();
|
|
96
|
+
}
|
|
97
|
+
initializeLayout() {
|
|
98
|
+
const centerX = this.canvas.width / 2 / this.scale;
|
|
99
|
+
const centerY = this.canvas.height / 2 / this.scale;
|
|
100
|
+
this.layoutPolygon = [
|
|
101
|
+
[
|
|
102
|
+
{
|
|
103
|
+
"x": this.snapToGrid(centerX, this.gridHeight),
|
|
104
|
+
"y": this.snapToGrid(centerY, this.gridWidth)
|
|
105
|
+
},
|
|
106
|
+
{
|
|
107
|
+
"x": this.snapToGrid(centerX, this.gridHeight),
|
|
108
|
+
"y": this.snapToGrid(centerY, this.gridWidth)
|
|
109
|
+
},
|
|
110
|
+
{
|
|
111
|
+
"elementType": "wall",
|
|
112
|
+
"distance": 0,
|
|
113
|
+
"unit": "ft",
|
|
114
|
+
"direction": "right",
|
|
115
|
+
"angle": 90,
|
|
116
|
+
"elementNumber": 1
|
|
117
|
+
}
|
|
118
|
+
]
|
|
119
|
+
];
|
|
120
|
+
}
|
|
121
|
+
ngOnInit() {
|
|
122
|
+
this.canvas = this.canvasRef.nativeElement;
|
|
123
|
+
this.ctx = this.canvas.getContext('2d');
|
|
124
|
+
this.canvas.width = 10000;
|
|
125
|
+
this.canvas.height = 10000;
|
|
126
|
+
this.drawGrid();
|
|
127
|
+
this.route.queryParams
|
|
128
|
+
.pipe(takeUntil(this.destroy$))
|
|
129
|
+
.subscribe((params) => {
|
|
130
|
+
if (params?.id) {
|
|
131
|
+
const ids = params.id.split(',') || [];
|
|
132
|
+
this.getPlanoData(ids);
|
|
133
|
+
}
|
|
134
|
+
});
|
|
135
|
+
this.floorsInput.valueChanges.subscribe((val) => {
|
|
136
|
+
if (val) {
|
|
137
|
+
if (this.layoutPolygon[0][0].x !== this.layoutPolygon[0][1].x && this.layoutPolygon[0][0].y !== this.layoutPolygon[0][1].y) {
|
|
138
|
+
this.updateFloorLayout();
|
|
139
|
+
}
|
|
140
|
+
this.selectedFloor = this.selectedStore.floor.filter((floor) => floor.id === val)[0];
|
|
141
|
+
this.generateLayoutPolygon(this.selectedFloor.layoutPolygon);
|
|
142
|
+
}
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
ngOnDestroy() {
|
|
146
|
+
this.destroy$.next();
|
|
147
|
+
this.destroy$.complete();
|
|
148
|
+
}
|
|
149
|
+
onStoreChange(event) {
|
|
150
|
+
if (this.layoutPolygon[0][0].x !== this.layoutPolygon[0][1].x && this.layoutPolygon[0][0].y !== this.layoutPolygon[0][1].y) {
|
|
151
|
+
this.updateFloorLayout();
|
|
152
|
+
}
|
|
153
|
+
const index = this.planoStoreList.findIndex(item => item.planoId === event.planoId);
|
|
154
|
+
this.currentPage = index + 1;
|
|
155
|
+
this.selectedStore = event;
|
|
156
|
+
this.selectedFloor = this.selectedStore.floor[0];
|
|
157
|
+
this.floorsInput.setValue(this.selectedFloor.id, { emitEvent: false });
|
|
158
|
+
this.generateLayoutPolygon(this.selectedFloor.layoutPolygon);
|
|
159
|
+
}
|
|
160
|
+
getPlanoData(planoId) {
|
|
161
|
+
const payload = {
|
|
162
|
+
id: planoId
|
|
163
|
+
};
|
|
164
|
+
this.apiService.getPlano(payload).subscribe({
|
|
165
|
+
next: (res) => {
|
|
166
|
+
this.planoStoreList = res.data;
|
|
167
|
+
this.totalItems = res.data.length;
|
|
168
|
+
// this.planoStoreList = res.data.filter((plano:any) => plano.status !== 'completed');
|
|
169
|
+
if (!this.selectedStore) {
|
|
170
|
+
this.selectedStore = this.planoStoreList[0];
|
|
171
|
+
}
|
|
172
|
+
else {
|
|
173
|
+
this.selectedStore = this.planoStoreList.filter((store) => store.planoId === this.selectedStore.planoId)[0];
|
|
174
|
+
}
|
|
175
|
+
if (!this.selectedFloor) {
|
|
176
|
+
this.selectedFloor = this.selectedStore.floor[0];
|
|
177
|
+
}
|
|
178
|
+
else {
|
|
179
|
+
this.selectedFloor = this.selectedStore.floor.filter((floor) => floor.id === this.selectedFloor.id)[0];
|
|
180
|
+
}
|
|
181
|
+
this.planoStoreList.forEach((store) => {
|
|
182
|
+
if (store.planoId === this.selectedStore.planoId) {
|
|
183
|
+
store.selected = true;
|
|
184
|
+
}
|
|
185
|
+
});
|
|
186
|
+
this.floorsInput.setValue(this.selectedFloor.id, { emitEvent: false });
|
|
187
|
+
this.generateLayoutPolygon(this.selectedFloor.layoutPolygon);
|
|
188
|
+
},
|
|
189
|
+
error: (err) => {
|
|
190
|
+
console.log(err);
|
|
191
|
+
}
|
|
192
|
+
});
|
|
193
|
+
}
|
|
194
|
+
updateFloorLayout() {
|
|
195
|
+
const payload = {
|
|
196
|
+
id: this.selectedFloor.id,
|
|
197
|
+
layoutPolygon: this.layoutPolygon.map((segment) => {
|
|
198
|
+
const [point1, point2, properties] = segment;
|
|
199
|
+
return properties;
|
|
200
|
+
})
|
|
201
|
+
};
|
|
202
|
+
this.apiService.updateFloorLayout(payload).subscribe({
|
|
203
|
+
next: (res) => {
|
|
204
|
+
this.getPlanoData(this.selectedStore.planoId);
|
|
205
|
+
},
|
|
206
|
+
error: (err) => {
|
|
207
|
+
console.log(err);
|
|
208
|
+
}
|
|
209
|
+
});
|
|
210
|
+
}
|
|
211
|
+
onComplete() {
|
|
212
|
+
if (this.planoStoreList.length === 1) {
|
|
213
|
+
const modelRef = this.modalDef.open(CompleteLayoutComponent, { centered: true });
|
|
214
|
+
modelRef.result.then((val) => {
|
|
215
|
+
if (val.message === 'confirm') {
|
|
216
|
+
this.updatePlanoStatus();
|
|
217
|
+
}
|
|
218
|
+
});
|
|
219
|
+
}
|
|
220
|
+
else {
|
|
221
|
+
this.modalService.open(this.completeLayout, { centered: true, size: "lg" });
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
drawGrid() {
|
|
225
|
+
this.ctx.save();
|
|
226
|
+
this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
|
|
227
|
+
this.ctx.scale(this.scale, this.scale);
|
|
228
|
+
this.ctx.fillStyle = 'white';
|
|
229
|
+
this.ctx.fillRect(0, 0, this.canvas.width, this.canvas.height);
|
|
230
|
+
}
|
|
231
|
+
drawPolygon(polygon = this.layoutPolygon) {
|
|
232
|
+
if (polygon.length < 1)
|
|
233
|
+
return; // If the polygon has no edges, exit early.
|
|
234
|
+
this.ctx.save(); // Save the current canvas state.
|
|
235
|
+
this.ctx.scale(this.scale, this.scale); // Scale the canvas context to match the desired scale.
|
|
236
|
+
// this.ctx.translate(this.panOffset.x, this.panOffset.y);
|
|
237
|
+
// Function to draw an arrowhead at a specific location and angle.
|
|
238
|
+
function drawArrowhead(ctx, x, y, angle) {
|
|
239
|
+
const size = 5; // Define the size of the arrowhead.
|
|
240
|
+
ctx.save(); // Save the current canvas state.
|
|
241
|
+
ctx.translate(x, y); // Move the context to the arrowhead position.
|
|
242
|
+
ctx.rotate(angle); // Rotate the context to match the arrow's angle.
|
|
243
|
+
ctx.beginPath(); // Start a new path.
|
|
244
|
+
ctx.moveTo(0, 0); // Move to the tip of the arrowhead.
|
|
245
|
+
ctx.lineTo(-size, -size / 2); // Draw one side of the arrowhead.
|
|
246
|
+
ctx.lineTo(-size, size / 2); // Draw the other side of the arrowhead.
|
|
247
|
+
ctx.closePath(); // Close the arrowhead path.
|
|
248
|
+
ctx.fillStyle = 'black'; // Set the arrowhead color.
|
|
249
|
+
ctx.fill(); // Fill the arrowhead.
|
|
250
|
+
ctx.restore(); // Restore the previous canvas state.
|
|
251
|
+
}
|
|
252
|
+
this.ctx.beginPath(); // Begin the main polygon path.
|
|
253
|
+
polygon.forEach((edge, edgeIndex) => {
|
|
254
|
+
const point = edge[0]; // Starting point of the edge.
|
|
255
|
+
const nextPoint = edge[1]; // Ending point of the edge.
|
|
256
|
+
const properties = edge[2]; // Properties of the edge (e.g., labels, distances).
|
|
257
|
+
// Draw the main polygon edge.
|
|
258
|
+
if (edgeIndex === 0)
|
|
259
|
+
this.ctx.moveTo(point.x, point.y); // Move to the first edge starting point.
|
|
260
|
+
this.ctx.lineTo(nextPoint.x, nextPoint.y); // Draw a line to the next point.
|
|
261
|
+
// Calculate the perpendicular offset for the bounding box.
|
|
262
|
+
const dx = nextPoint.x - point.x; // X-difference between start and end points.
|
|
263
|
+
const dy = nextPoint.y - point.y; // Y-difference between start and end points.
|
|
264
|
+
const length = Math.sqrt(dx * dx + dy * dy); // Length of the edge.
|
|
265
|
+
const offsetX = (dy / length) * 20; // Offset in the X direction.
|
|
266
|
+
const offsetY = (-dx / length) * 20; // Offset in the Y direction.
|
|
267
|
+
// Define the bounding box points.
|
|
268
|
+
const boxPoints = [
|
|
269
|
+
{ x: point.x, y: point.y },
|
|
270
|
+
{ x: nextPoint.x, y: nextPoint.y },
|
|
271
|
+
{ x: nextPoint.x + offsetX, y: nextPoint.y + offsetY },
|
|
272
|
+
{ x: point.x + offsetX, y: point.y + offsetY },
|
|
273
|
+
];
|
|
274
|
+
// Draw the bounding box.
|
|
275
|
+
this.ctx.beginPath();
|
|
276
|
+
this.ctx.moveTo(boxPoints[0].x, boxPoints[0].y);
|
|
277
|
+
boxPoints.forEach((pt, index) => {
|
|
278
|
+
if (properties.elementType === 'entrance') {
|
|
279
|
+
if (index < 2) {
|
|
280
|
+
this.ctx.lineTo(pt.x, pt.y);
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
else {
|
|
284
|
+
this.ctx.lineTo(pt.x, pt.y); // Draw each edge of the box.
|
|
285
|
+
}
|
|
286
|
+
});
|
|
287
|
+
if (properties.elementType === 'opening') {
|
|
288
|
+
this.ctx.closePath(); // Close the bounding box path.
|
|
289
|
+
this.ctx.fillStyle = '#F9FAFB'; // Set a translucent fill color.
|
|
290
|
+
this.ctx.fill(); // Fill the bounding box.
|
|
291
|
+
this.ctx.strokeStyle = '#F9FAFB';
|
|
292
|
+
this.ctx.stroke(); // Draw the bounding box border.
|
|
293
|
+
}
|
|
294
|
+
else {
|
|
295
|
+
this.ctx.closePath(); // Close the bounding box path.
|
|
296
|
+
this.ctx.fillStyle = '#F9FAFB'; // Set a translucent fill color.
|
|
297
|
+
this.ctx.fill(); // Fill the bounding box.
|
|
298
|
+
this.ctx.strokeStyle = '#1D2939';
|
|
299
|
+
this.ctx.stroke(); // Draw the bounding box border.
|
|
300
|
+
}
|
|
301
|
+
// Position text in the middle of the bounding box.
|
|
302
|
+
const textX = (boxPoints[1].x + boxPoints[3].x) / 2;
|
|
303
|
+
const textY = (boxPoints[1].y + boxPoints[3].y) / 2;
|
|
304
|
+
this.ctx.save(); // Save the current canvas state.
|
|
305
|
+
this.ctx.translate(textX, textY); // Move the context to the text position.
|
|
306
|
+
// Rotate text based on the edge direction.
|
|
307
|
+
if (dx === 0) {
|
|
308
|
+
this.ctx.rotate(-Math.PI / 2); // Rotate for vertical edges.
|
|
309
|
+
}
|
|
310
|
+
else if (dy !== 0) {
|
|
311
|
+
const angle = Math.atan2(dy, dx); // Calculate angle for diagonal edges.
|
|
312
|
+
this.ctx.rotate(angle); // Rotate the text to match the angle.
|
|
313
|
+
}
|
|
314
|
+
// Draw the edge properties as text.
|
|
315
|
+
this.ctx.font = '12px Arial'; // Set the font style and size.
|
|
316
|
+
this.ctx.fillStyle = 'black'; // Set the text color.
|
|
317
|
+
this.ctx.textAlign = 'center'; // Align text to the center.
|
|
318
|
+
this.ctx.textBaseline = 'middle'; // Align text vertically in the middle.
|
|
319
|
+
this.ctx.fillText(`${properties.elementType} ${properties.elementNumber} - ${properties.distance} ${properties.unit}`, 0, 0);
|
|
320
|
+
this.ctx.restore(); // Restore the previous canvas state.
|
|
321
|
+
if (properties.distance >= 4) {
|
|
322
|
+
// Define the midpoints of the left and right edges of the bounding box.
|
|
323
|
+
const centerX = textX;
|
|
324
|
+
const centerY = textY;
|
|
325
|
+
const rightX = (boxPoints[1].x + boxPoints[2].x) / 2;
|
|
326
|
+
const rightY = (boxPoints[1].y + boxPoints[2].y) / 2;
|
|
327
|
+
const leftX = (boxPoints[0].x + boxPoints[3].x) / 2;
|
|
328
|
+
const leftY = (boxPoints[0].y + boxPoints[3].y) / 2;
|
|
329
|
+
// Helper function to adjust points by a specific distance.
|
|
330
|
+
function adjustPoint(x1, y1, x2, y2, distance) {
|
|
331
|
+
const angle = Math.atan2(y2 - y1, x2 - x1); // Calculate the angle.
|
|
332
|
+
return {
|
|
333
|
+
x: x1 + Math.cos(angle) * distance,
|
|
334
|
+
y: y1 + Math.sin(angle) * distance, // Adjust Y by distance.
|
|
335
|
+
};
|
|
336
|
+
}
|
|
337
|
+
// Define the arrow line start and end points for the right side.
|
|
338
|
+
const rightStart = adjustPoint(centerX, centerY, rightX, rightY, 50);
|
|
339
|
+
const rightEnd = adjustPoint(rightX, rightY, centerX, centerY, 10);
|
|
340
|
+
// Define the arrow line start and end points for the left side.
|
|
341
|
+
const leftStart = adjustPoint(centerX, centerY, leftX, leftY, 50);
|
|
342
|
+
const leftEnd = adjustPoint(leftX, leftY, centerX, centerY, 10);
|
|
343
|
+
// Draw the right arrow.
|
|
344
|
+
this.ctx.beginPath();
|
|
345
|
+
this.ctx.moveTo(rightStart.x, rightStart.y);
|
|
346
|
+
this.ctx.lineTo(rightEnd.x, rightEnd.y);
|
|
347
|
+
this.ctx.strokeStyle = 'black'; // Set the arrow line color.
|
|
348
|
+
this.ctx.stroke(); // Draw the arrow line.
|
|
349
|
+
let rightAngle = Math.atan2(rightEnd.y - rightStart.y, rightEnd.x - rightStart.x);
|
|
350
|
+
drawArrowhead(this.ctx, rightEnd.x, rightEnd.y, rightAngle); // Draw the arrowhead.
|
|
351
|
+
// Draw the left arrow.
|
|
352
|
+
this.ctx.beginPath();
|
|
353
|
+
this.ctx.moveTo(leftStart.x, leftStart.y);
|
|
354
|
+
this.ctx.lineTo(leftEnd.x, leftEnd.y);
|
|
355
|
+
this.ctx.strokeStyle = 'black'; // Set the arrow line color.
|
|
356
|
+
this.ctx.stroke(); // Draw the arrow line.
|
|
357
|
+
let leftAngle = Math.atan2(leftEnd.y - leftStart.y, leftEnd.x - leftStart.x);
|
|
358
|
+
drawArrowhead(this.ctx, leftEnd.x, leftEnd.y, leftAngle); // Draw the arrowhead.
|
|
359
|
+
}
|
|
360
|
+
// For Entrance
|
|
361
|
+
if (properties.elementType === 'entrance') {
|
|
362
|
+
// Calculate the angle of the main line (edge) in radians.
|
|
363
|
+
const angle = Math.atan2(nextPoint.y - point.y, nextPoint.x - point.x);
|
|
364
|
+
// Add 15 degrees to the angle for the entrance line.
|
|
365
|
+
const entranceAngle = angle + (15 * Math.PI) / 180; // Convert 15 degrees to radians.
|
|
366
|
+
// Define the length of the entrance line.
|
|
367
|
+
const lineLength = this.convertToPixels(properties.distance, properties.unit) * 0.75;
|
|
368
|
+
// Calculate the endpoint of the entrance line based on the angle.
|
|
369
|
+
const endPoint = {
|
|
370
|
+
x: point.x + Math.cos(entranceAngle) * lineLength,
|
|
371
|
+
y: point.y + Math.sin(entranceAngle) * lineLength,
|
|
372
|
+
};
|
|
373
|
+
// Draw the entrance line.
|
|
374
|
+
this.ctx.beginPath();
|
|
375
|
+
this.ctx.moveTo(point.x, point.y);
|
|
376
|
+
this.ctx.lineTo(endPoint.x, endPoint.y);
|
|
377
|
+
this.ctx.strokeStyle = '#1D2939';
|
|
378
|
+
this.ctx.stroke();
|
|
379
|
+
}
|
|
380
|
+
});
|
|
381
|
+
this.ctx.restore(); // Restore the original canvas state.
|
|
382
|
+
}
|
|
383
|
+
zoomIn() {
|
|
384
|
+
this.scale *= 1.1;
|
|
385
|
+
this.redrawCanvas();
|
|
386
|
+
}
|
|
387
|
+
zoomOut() {
|
|
388
|
+
this.scale /= 1.1;
|
|
389
|
+
this.redrawCanvas();
|
|
390
|
+
}
|
|
391
|
+
redrawCanvas() {
|
|
392
|
+
this.drawGrid();
|
|
393
|
+
this.drawPolygon();
|
|
394
|
+
}
|
|
395
|
+
snapToGrid(value, gridSize) {
|
|
396
|
+
return Math.round(value / gridSize) * gridSize;
|
|
397
|
+
}
|
|
398
|
+
rotatePolygons() {
|
|
399
|
+
const rotatePoint = (point, center) => {
|
|
400
|
+
const dx = point.x - center.x;
|
|
401
|
+
const dy = point.y - center.y;
|
|
402
|
+
return { x: center.x - dy, y: center.y + dx };
|
|
403
|
+
};
|
|
404
|
+
const getPolygonLineCenter = (line) => {
|
|
405
|
+
const [start, end] = line;
|
|
406
|
+
return {
|
|
407
|
+
x: (start.x + end.x) / 2,
|
|
408
|
+
y: (start.y + end.y) / 2,
|
|
409
|
+
};
|
|
410
|
+
};
|
|
411
|
+
const getOverallCenter = (lines) => {
|
|
412
|
+
const sum = lines.reduce((acc, line) => {
|
|
413
|
+
const center = getPolygonLineCenter(line);
|
|
414
|
+
acc.x += center.x;
|
|
415
|
+
acc.y += center.y;
|
|
416
|
+
return acc;
|
|
417
|
+
}, { x: 0, y: 0 });
|
|
418
|
+
return { x: sum.x / lines.length, y: sum.y / lines.length };
|
|
419
|
+
};
|
|
420
|
+
const overallCenter = getOverallCenter(this.layoutPolygon);
|
|
421
|
+
this.layoutPolygon = this.layoutPolygon.map((line) => {
|
|
422
|
+
const [start, end, properties] = line;
|
|
423
|
+
return [
|
|
424
|
+
rotatePoint(start, overallCenter),
|
|
425
|
+
rotatePoint(end, overallCenter),
|
|
426
|
+
properties
|
|
427
|
+
];
|
|
428
|
+
});
|
|
429
|
+
this.drawGrid();
|
|
430
|
+
this.drawPolygon();
|
|
431
|
+
}
|
|
432
|
+
convertToPixels(value, unit) {
|
|
433
|
+
const PIXELS_PER_METER = this.pixelPerMetre;
|
|
434
|
+
const PIXELS_PER_FOOT = PIXELS_PER_METER / 3.28084;
|
|
435
|
+
if (typeof value !== 'number' || value < 0) {
|
|
436
|
+
throw new Error('Value must be a non-negative number');
|
|
437
|
+
}
|
|
438
|
+
switch (unit) {
|
|
439
|
+
case 'm':
|
|
440
|
+
return value * PIXELS_PER_METER;
|
|
441
|
+
case 'ft':
|
|
442
|
+
return value * PIXELS_PER_FOOT;
|
|
443
|
+
default:
|
|
444
|
+
throw new Error("Invalid unit. Supported units are 'mt' for meters and 'ft' for feet.");
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
scrollToCanvasPosition(coordinates) {
|
|
448
|
+
const container = this.scrollContainerRef.nativeElement;
|
|
449
|
+
const containerRect = container.getBoundingClientRect();
|
|
450
|
+
const containerScrollLeft = container.scrollLeft;
|
|
451
|
+
const containerScrollTop = container.scrollTop;
|
|
452
|
+
const targetX = coordinates.x;
|
|
453
|
+
const targetY = coordinates.y;
|
|
454
|
+
const offset = {
|
|
455
|
+
up: 50,
|
|
456
|
+
down: 200,
|
|
457
|
+
left: 100,
|
|
458
|
+
right: 100,
|
|
459
|
+
};
|
|
460
|
+
const visibleLeft = containerScrollLeft + offset.left;
|
|
461
|
+
const visibleRight = containerScrollLeft + containerRect.width - offset.right;
|
|
462
|
+
const visibleTop = containerScrollTop + offset.up;
|
|
463
|
+
const visibleBottom = containerScrollTop + containerRect.height - offset.down;
|
|
464
|
+
const isXInView = targetX >= visibleLeft && targetX <= visibleRight;
|
|
465
|
+
const isYInView = targetY >= visibleTop && targetY <= visibleBottom;
|
|
466
|
+
if (!isXInView || !isYInView) {
|
|
467
|
+
const adjustedX = Math.max(0, targetX - offset.left);
|
|
468
|
+
const adjustedY = Math.max(0, targetY - offset.up);
|
|
469
|
+
container.scrollTo({
|
|
470
|
+
left: adjustedX,
|
|
471
|
+
top: adjustedY,
|
|
472
|
+
behavior: 'smooth',
|
|
473
|
+
});
|
|
474
|
+
}
|
|
475
|
+
}
|
|
476
|
+
calculatePolygonArea(elements) {
|
|
477
|
+
const vertices = [];
|
|
478
|
+
const centerX = 0; // Assuming (0,0) as the starting point for calculation
|
|
479
|
+
const centerY = 0;
|
|
480
|
+
let currentPoint = { x: centerX, y: centerY };
|
|
481
|
+
const conversionFactor = 50; // Pixels per foot (adjust as needed)
|
|
482
|
+
// Compute vertices based on layout instructions
|
|
483
|
+
for (const element of elements) {
|
|
484
|
+
const radians = {
|
|
485
|
+
up: ((180 - element.angle) * Math.PI) / 180,
|
|
486
|
+
left: ((270 - element.angle) * Math.PI) / 180,
|
|
487
|
+
down: ((360 - element.angle) * Math.PI) / 180,
|
|
488
|
+
right: ((90 - element.angle) * Math.PI) / 180,
|
|
489
|
+
}[element.direction];
|
|
490
|
+
if (radians === undefined) {
|
|
491
|
+
throw new Error(`Invalid direction: ${element.direction}`);
|
|
492
|
+
}
|
|
493
|
+
const distanceInPixels = element.distance * conversionFactor;
|
|
494
|
+
const newX = currentPoint.x + Math.cos(radians) * distanceInPixels;
|
|
495
|
+
const newY = currentPoint.y - Math.sin(radians) * distanceInPixels;
|
|
496
|
+
vertices.push({ x: currentPoint.x, y: currentPoint.y });
|
|
497
|
+
currentPoint = {
|
|
498
|
+
x: this.snapToGrid(newX, this.gridWidth),
|
|
499
|
+
y: this.snapToGrid(newY, this.gridHeight),
|
|
500
|
+
};
|
|
501
|
+
}
|
|
502
|
+
// Close the polygon by adding the starting vertex at the end
|
|
503
|
+
vertices.push(vertices[0]);
|
|
504
|
+
// Apply the Shoelace formula
|
|
505
|
+
let areaInPixels = 0;
|
|
506
|
+
for (let i = 0; i < vertices.length - 1; i++) {
|
|
507
|
+
const x1 = vertices[i].x;
|
|
508
|
+
const y1 = vertices[i].y;
|
|
509
|
+
const x2 = vertices[i + 1].x;
|
|
510
|
+
const y2 = vertices[i + 1].y;
|
|
511
|
+
areaInPixels += x1 * y2 - y1 * x2;
|
|
512
|
+
}
|
|
513
|
+
// Convert area from pixels² to feet²
|
|
514
|
+
const areaInSquareFeet = Math.abs(areaInPixels / 2) / (conversionFactor * conversionFactor);
|
|
515
|
+
return Math.round(areaInSquareFeet); // Return the area in square feet
|
|
516
|
+
}
|
|
517
|
+
generateLayoutPolygon(layoutInstructions) {
|
|
518
|
+
this.pixelPerMetre = this.normalizedPixelPerMetre(layoutInstructions);
|
|
519
|
+
this.wallCapacity = layoutInstructions.reduce((acc, val) => {
|
|
520
|
+
if (val.elementType === 'wall') {
|
|
521
|
+
return acc += val.distance;
|
|
522
|
+
}
|
|
523
|
+
else {
|
|
524
|
+
return acc;
|
|
525
|
+
}
|
|
526
|
+
}, 0);
|
|
527
|
+
this.facadeCapacity = layoutInstructions.reduce((acc, val) => {
|
|
528
|
+
if (val.elementType === 'facade') {
|
|
529
|
+
return acc += val.distance;
|
|
530
|
+
}
|
|
531
|
+
else {
|
|
532
|
+
return acc;
|
|
533
|
+
}
|
|
534
|
+
}, 0);
|
|
535
|
+
this.floorCapacity = this.calculatePolygonArea(layoutInstructions);
|
|
536
|
+
this.layoutPolygon = [];
|
|
537
|
+
const centerX = this.canvas.width / 2 / this.scale;
|
|
538
|
+
const centerY = this.canvas.height / 2 / this.scale;
|
|
539
|
+
let currentPoint = {
|
|
540
|
+
"x": this.snapToGrid(centerX, this.gridHeight),
|
|
541
|
+
"y": this.snapToGrid(centerY, this.gridWidth)
|
|
542
|
+
};
|
|
543
|
+
if (!layoutInstructions.length) {
|
|
544
|
+
this.layoutPolygon = [
|
|
545
|
+
[
|
|
546
|
+
{
|
|
547
|
+
"x": this.snapToGrid(centerX, this.gridHeight),
|
|
548
|
+
"y": this.snapToGrid(centerY, this.gridWidth)
|
|
549
|
+
},
|
|
550
|
+
{
|
|
551
|
+
"x": this.snapToGrid(centerX, this.gridHeight),
|
|
552
|
+
"y": this.snapToGrid(centerY, this.gridWidth)
|
|
553
|
+
},
|
|
554
|
+
{
|
|
555
|
+
"elementType": "wall",
|
|
556
|
+
"distance": 0,
|
|
557
|
+
"unit": "ft",
|
|
558
|
+
"direction": "right",
|
|
559
|
+
"angle": 90,
|
|
560
|
+
"elementNumber": 1
|
|
561
|
+
}
|
|
562
|
+
]
|
|
563
|
+
];
|
|
564
|
+
this.openWidget({ x: this.snapToGrid(centerX, this.gridHeight), y: this.snapToGrid(centerY, this.gridWidth) });
|
|
565
|
+
this.drawGrid();
|
|
566
|
+
this.drawPolygon();
|
|
567
|
+
return;
|
|
568
|
+
}
|
|
569
|
+
layoutInstructions.forEach((instruction) => {
|
|
570
|
+
const radians = {
|
|
571
|
+
'up': ((180 - instruction.angle) * Math.PI) / 180,
|
|
572
|
+
'left': ((270 - instruction.angle) * Math.PI) / 180,
|
|
573
|
+
'down': ((360 - instruction.angle) * Math.PI) / 180,
|
|
574
|
+
'right': ((90 - instruction.angle) * Math.PI) / 180,
|
|
575
|
+
}[instruction.direction];
|
|
576
|
+
if (radians === undefined) {
|
|
577
|
+
throw new Error(`Invalid direction: ${instruction.direction}`);
|
|
578
|
+
}
|
|
579
|
+
const distanceInPixels = this.convertToPixels(instruction.distance, instruction.unit);
|
|
580
|
+
const newX = currentPoint.x + Math.cos(radians) * distanceInPixels;
|
|
581
|
+
const newY = currentPoint.y - Math.sin(radians) * distanceInPixels;
|
|
582
|
+
const newPoint = {
|
|
583
|
+
x: this.snapToGrid(newX, this.gridWidth),
|
|
584
|
+
y: this.snapToGrid(newY, this.gridHeight),
|
|
585
|
+
};
|
|
586
|
+
const lineSegment = [
|
|
587
|
+
currentPoint,
|
|
588
|
+
newPoint,
|
|
589
|
+
{
|
|
590
|
+
elementType: instruction.elementType,
|
|
591
|
+
distance: instruction.distance,
|
|
592
|
+
unit: instruction.unit,
|
|
593
|
+
direction: instruction.direction,
|
|
594
|
+
angle: instruction.angle,
|
|
595
|
+
elementNumber: instruction.elementNumber,
|
|
596
|
+
},
|
|
597
|
+
];
|
|
598
|
+
this.layoutPolygon.push(lineSegment);
|
|
599
|
+
currentPoint = newPoint;
|
|
600
|
+
});
|
|
601
|
+
const lastPoint = this.layoutPolygon[this.layoutPolygon.length - 1][1];
|
|
602
|
+
if (this.isFloorCompleted(layoutInstructions)) {
|
|
603
|
+
this.findPolygonCenterAndScroll();
|
|
604
|
+
}
|
|
605
|
+
else {
|
|
606
|
+
this.openWidget(lastPoint);
|
|
607
|
+
}
|
|
608
|
+
this.drawGrid();
|
|
609
|
+
this.drawPolygon();
|
|
610
|
+
}
|
|
611
|
+
isFloorCompleted(layoutInstructions, thresholdInFeet = 1) {
|
|
612
|
+
const layoutPolygon = [];
|
|
613
|
+
const centerX = this.canvas.width / 2 / this.scale;
|
|
614
|
+
const centerY = this.canvas.height / 2 / this.scale;
|
|
615
|
+
let currentPoint = {
|
|
616
|
+
x: this.snapToGrid(centerX, this.gridHeight),
|
|
617
|
+
y: this.snapToGrid(centerY, this.gridWidth),
|
|
618
|
+
};
|
|
619
|
+
layoutInstructions.forEach((instruction) => {
|
|
620
|
+
const radians = {
|
|
621
|
+
'up': ((180 - instruction.angle) * Math.PI) / 180,
|
|
622
|
+
'left': ((270 - instruction.angle) * Math.PI) / 180,
|
|
623
|
+
'down': ((360 - instruction.angle) * Math.PI) / 180,
|
|
624
|
+
'right': ((90 - instruction.angle) * Math.PI) / 180,
|
|
625
|
+
}[instruction.direction];
|
|
626
|
+
if (radians === undefined) {
|
|
627
|
+
throw new Error(`Invalid direction: ${instruction.direction}`);
|
|
628
|
+
}
|
|
629
|
+
const distanceInPixels = this.convertToPixels(instruction.distance, instruction.unit);
|
|
630
|
+
const newX = currentPoint.x + Math.cos(radians) * distanceInPixels;
|
|
631
|
+
const newY = currentPoint.y - Math.sin(radians) * distanceInPixels;
|
|
632
|
+
const newPoint = {
|
|
633
|
+
x: this.snapToGrid(newX, this.gridWidth),
|
|
634
|
+
y: this.snapToGrid(newY, this.gridHeight),
|
|
635
|
+
};
|
|
636
|
+
const lineSegment = [
|
|
637
|
+
currentPoint,
|
|
638
|
+
newPoint,
|
|
639
|
+
{
|
|
640
|
+
elementType: instruction.elementType,
|
|
641
|
+
distance: instruction.distance,
|
|
642
|
+
unit: instruction.unit,
|
|
643
|
+
direction: instruction.direction,
|
|
644
|
+
angle: instruction.angle,
|
|
645
|
+
elementNumber: instruction.elementNumber,
|
|
646
|
+
},
|
|
647
|
+
];
|
|
648
|
+
layoutPolygon.push(lineSegment);
|
|
649
|
+
currentPoint = newPoint;
|
|
650
|
+
});
|
|
651
|
+
const firstPoint = layoutPolygon?.[0]?.[0];
|
|
652
|
+
const lastPoint = layoutPolygon?.[layoutPolygon.length - 1]?.[1];
|
|
653
|
+
if (layoutPolygon.length <= 1 || !firstPoint || !lastPoint) {
|
|
654
|
+
return false;
|
|
655
|
+
}
|
|
656
|
+
const distanceBetweenPoints = Math.sqrt(Math.pow(lastPoint.x - firstPoint.x, 2) + Math.pow(lastPoint.y - firstPoint.y, 2));
|
|
657
|
+
const thresholdInPixels = this.convertToPixels(thresholdInFeet, 'ft');
|
|
658
|
+
return distanceBetweenPoints <= thresholdInPixels;
|
|
659
|
+
}
|
|
660
|
+
openWidget(position, offset = { up: 0, right: 5, down: 15, left: 0, }) {
|
|
661
|
+
const adjustedPosition = {
|
|
662
|
+
x: position.x + offset.right + offset.left,
|
|
663
|
+
y: position.y + offset.up + offset.down,
|
|
664
|
+
};
|
|
665
|
+
this.scrollToCanvasPosition(adjustedPosition);
|
|
666
|
+
}
|
|
667
|
+
openOffCanva() {
|
|
668
|
+
let canvaRef = this.offcanvasService.open(StoreOffcanvasComponentComponent, { position: 'end', panelClass: 'set-height' });
|
|
669
|
+
canvaRef.componentInstance.store = this.selectedStore;
|
|
670
|
+
canvaRef.componentInstance.clientId = this.headerData?.client;
|
|
671
|
+
canvaRef.componentInstance.id = this.selectedStore.planoId;
|
|
672
|
+
}
|
|
673
|
+
onModalSelectAll(event) {
|
|
674
|
+
this.planoStoreList.forEach((store) => store.selected = event.target.checked);
|
|
675
|
+
}
|
|
676
|
+
get isAllStoreSelected() {
|
|
677
|
+
return this.planoStoreList.every((store) => store.selected);
|
|
678
|
+
}
|
|
679
|
+
onModalTypeChange(event) {
|
|
680
|
+
if (event === 'single') {
|
|
681
|
+
this.planoStoreList.forEach((store, index) => {
|
|
682
|
+
if (store.planoId === this.selectedStore.planoId) {
|
|
683
|
+
store.selected = true;
|
|
684
|
+
}
|
|
685
|
+
else {
|
|
686
|
+
store.selected = false;
|
|
687
|
+
}
|
|
688
|
+
});
|
|
689
|
+
}
|
|
690
|
+
else if (event === 'multiple') {
|
|
691
|
+
this.planoStoreList.forEach((store) => store.selected = true);
|
|
692
|
+
}
|
|
693
|
+
}
|
|
694
|
+
updatePlanoStatus() {
|
|
695
|
+
const payload = {
|
|
696
|
+
storeId: this.planoStoreList.filter((store) => store.selected === true).map((store) => store.storeId),
|
|
697
|
+
status: "completed"
|
|
698
|
+
};
|
|
699
|
+
this.apiService.updatePlanoStatus(payload).subscribe({
|
|
700
|
+
next: (res) => {
|
|
701
|
+
if (res.code === 200) {
|
|
702
|
+
this.toastService.getSuccessToast(res.message);
|
|
703
|
+
this.router.navigateByUrl('/manage/planogram/store-layout');
|
|
704
|
+
}
|
|
705
|
+
},
|
|
706
|
+
error: (err) => {
|
|
707
|
+
console.log(err);
|
|
708
|
+
}
|
|
709
|
+
});
|
|
710
|
+
}
|
|
711
|
+
onPageChange(val) {
|
|
712
|
+
this.selectedStore = this.planoStoreList[val - 1];
|
|
713
|
+
this.selectedFloor = this.selectedStore.floor[0];
|
|
714
|
+
this.floorsInput.setValue(this.selectedFloor.id, { emitEvent: false });
|
|
715
|
+
this.generateLayoutPolygon(this.selectedFloor.layoutPolygon);
|
|
716
|
+
}
|
|
717
|
+
normalizedPixelPerMetre(polygon) {
|
|
718
|
+
const MIN_PIXELS_PER_METER = 50;
|
|
719
|
+
const MAX_PIXELS_PER_METER = 150;
|
|
720
|
+
let totalLength = 0;
|
|
721
|
+
let lineCount = 0;
|
|
722
|
+
polygon.forEach((line) => {
|
|
723
|
+
if (line.unit === 'ft') {
|
|
724
|
+
totalLength = totalLength + (line.distance * 3.28084);
|
|
725
|
+
}
|
|
726
|
+
else {
|
|
727
|
+
totalLength = totalLength + line.distance;
|
|
728
|
+
}
|
|
729
|
+
lineCount++;
|
|
730
|
+
});
|
|
731
|
+
const averageLength = lineCount > 0 ? totalLength / lineCount : 0;
|
|
732
|
+
const MAX_AVERAGE_LENGTH = 50;
|
|
733
|
+
const MIN_AVERAGE_LENGTH = 5;
|
|
734
|
+
const normalizedLength = Math.min(Math.max(averageLength, MIN_AVERAGE_LENGTH), MAX_AVERAGE_LENGTH);
|
|
735
|
+
const pixelsPerMeter = MAX_PIXELS_PER_METER -
|
|
736
|
+
((normalizedLength - MIN_AVERAGE_LENGTH) / (MAX_AVERAGE_LENGTH - MIN_AVERAGE_LENGTH)) *
|
|
737
|
+
(MAX_PIXELS_PER_METER - MIN_PIXELS_PER_METER);
|
|
738
|
+
return Math.round(pixelsPerMeter);
|
|
739
|
+
}
|
|
740
|
+
findPolygonCenterAndScroll(polygon = this.layoutPolygon) {
|
|
741
|
+
const vertices = polygon.flatMap((line) => line.slice(0, 2));
|
|
742
|
+
const minX = Math.min(...vertices.map((v) => v.x));
|
|
743
|
+
const maxX = Math.max(...vertices.map((v) => v.x));
|
|
744
|
+
const minY = Math.min(...vertices.map((v) => v.y));
|
|
745
|
+
const maxY = Math.max(...vertices.map((v) => v.y));
|
|
746
|
+
let center = { x: (minX + maxX) / 2, y: (minY + maxY) / 2 };
|
|
747
|
+
const step = 1;
|
|
748
|
+
let bestPoint = center;
|
|
749
|
+
let bestDistanceSum = Number.MAX_VALUE;
|
|
750
|
+
for (let x = minX; x <= maxX; x += step) {
|
|
751
|
+
for (let y = minY; y <= maxY; y += step) {
|
|
752
|
+
const point = { x, y };
|
|
753
|
+
if (isPointInsidePolygon(point, vertices)) {
|
|
754
|
+
const distanceSum = vertices.reduce((sum, vertex) => sum + Math.sqrt((point.x - vertex.x) ** 2 + (point.y - vertex.y) ** 2), 0);
|
|
755
|
+
if (distanceSum < bestDistanceSum) {
|
|
756
|
+
bestDistanceSum = distanceSum;
|
|
757
|
+
bestPoint = point;
|
|
758
|
+
}
|
|
759
|
+
}
|
|
760
|
+
}
|
|
761
|
+
}
|
|
762
|
+
const scrollContainer = this.scrollContainerRef.nativeElement;
|
|
763
|
+
scrollContainer.scrollTo({
|
|
764
|
+
left: bestPoint.x - scrollContainer.offsetWidth / 2,
|
|
765
|
+
top: bestPoint.y - scrollContainer.offsetHeight / 2,
|
|
766
|
+
behavior: 'smooth'
|
|
767
|
+
});
|
|
768
|
+
function isPointInsidePolygon(point, vertices) {
|
|
769
|
+
let count = 0;
|
|
770
|
+
for (let i = 0; i < vertices.length; i++) {
|
|
771
|
+
const start = vertices[i];
|
|
772
|
+
const end = vertices[(i + 1) % vertices.length];
|
|
773
|
+
if (rayIntersectsSegment(point, { start, end })) {
|
|
774
|
+
count++;
|
|
775
|
+
}
|
|
776
|
+
}
|
|
777
|
+
return count % 2 === 1;
|
|
778
|
+
}
|
|
779
|
+
function rayIntersectsSegment(point, segment) {
|
|
780
|
+
const { x, y } = point;
|
|
781
|
+
const { start, end } = segment;
|
|
782
|
+
if (y < Math.min(start.y, end.y) || y > Math.max(start.y, end.y)) {
|
|
783
|
+
return false;
|
|
784
|
+
}
|
|
785
|
+
const t = (y - start.y) / (end.y - start.y);
|
|
786
|
+
const intersectX = start.x + t * (end.x - start.x);
|
|
787
|
+
return intersectX >= x;
|
|
788
|
+
}
|
|
789
|
+
}
|
|
790
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: LayoutSummaryComponent, deps: [{ token: i1.ActivatedRoute }, { token: i2.StoreBuilderService }, { token: i3.NgbModal }, { token: i3.NgbOffcanvas }, { token: i1.Router }, { token: i3.NgbModal }, { token: i4.ToastService }], target: i0.ɵɵFactoryTarget.Component });
|
|
791
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: LayoutSummaryComponent, selector: "lib-layout-summary", host: { listeners: { "document:click": "onOutsideClick($event)" } }, viewQueries: [{ propertyName: "canvasRef", first: true, predicate: ["gridCanvas"], descendants: true, static: true }, { propertyName: "scrollContainerRef", first: true, predicate: ["scrollContainer"], descendants: true }, { propertyName: "completeLayout", first: true, predicate: ["completeLayout"], 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)=\"onComplete()\" class=\"btn btn-sm btn-primary me-5\">Complete</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 mb-6\">\r\n <div class=\"col-4\">\r\n <div class=\"area-card\">\r\n <div>\r\n <div> <span class=\"main-txt me-2\">{{wallCapacity || 0}}</span> <span class=\"unit-txt\">rft</span> </div>\r\n <div class=\"sub-txt\">Wall capacity</div>\r\n </div>\r\n <div>\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"65\" height=\"65\" viewBox=\"0 0 65 65\" fill=\"none\">\r\n <path fill-rule=\"evenodd\" clip-rule=\"evenodd\"\r\n d=\"M4.33333 4.33333V0H8.66667V4.33333H21.6667V0H26V4.33333H39V0H43.3333V4.33333H56.3333V0H60.6667V4.33333H65V8.66667H60.6667V21.6667H65V26H60.6667V39H65V43.3333H60.6667V56.3333H65V60.6667H60.6667V65H56.3333V60.6667H43.3333V65H39V60.6667H26V65H21.6667V60.6667H8.66667V65H4.33333V60.6667H0V56.3333H4.33333V43.3333H0V39H4.33333V26H0V21.6667H4.33333V8.66667H0V4.33333H4.33333ZM8.66667 8.66667V21.6667H21.6667V8.66667H8.66667ZM26 8.66667V21.6667H39V8.66667H26ZM43.3333 8.66667V21.6667H56.3333V8.66667H43.3333ZM56.3333 26H43.3333V39H56.3333V26ZM56.3333 43.3333H43.3333V56.3333H56.3333V43.3333ZM39 56.3333V43.3333H26V56.3333H39ZM21.6667 56.3333V43.3333H8.66667V56.3333H21.6667ZM8.66667 39H21.6667V26H8.66667V39ZM26 26V39H39V26H26Z\"\r\n fill=\"#344054\" />\r\n </svg>\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"col-4\">\r\n <div class=\"area-card\">\r\n <div>\r\n <div> <span class=\"main-txt me-2\">{{facadeCapacity || 0}}</span> <span class=\"unit-txt\">rft</span> </div>\r\n <div class=\"sub-txt\">Facade capacity</div>\r\n </div>\r\n <div>\r\n <svg width=\"65\" height=\"65\" viewBox=\"0 0 65 65\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\r\n <rect x=\"0.5\" y=\"0.5\" width=\"64\" height=\"64\" fill=\"#FDFDFD\" stroke=\"black\" />\r\n </svg>\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"col-4\">\r\n <div class=\"area-card\">\r\n <div>\r\n <div> <span class=\"main-txt me-2\">{{floorCapacity || 0}}</span> <span class=\"unit-txt\">sqft</span> </div>\r\n <div class=\"sub-txt\">Floor capacity</div>\r\n </div>\r\n <div>\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"102\" height=\"58\" viewBox=\"0 0 102 58\" fill=\"none\">\r\n <path d=\"M3.54359 36.4607L29.8929 2.06432L98.0939 6.44191L99.908 55.5468L3.54359 36.4607Z\" stroke=\"#475467\"\r\n stroke-width=\"4\" />\r\n </svg>\r\n </div>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<div class=\"row\">\r\n <div class=\"col-4\">\r\n <div class=\"c-card\" style=\"height: 75dvh; position: relative;\">\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 Capacity details\r\n </div>\r\n <div class=\"l-pane-desc\">\r\n Below are the capacity details of the elements\r\n </div>\r\n </div>\r\n <div class=\"d-flex align-items-center\">\r\n\r\n </div>\r\n\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>#</th>\r\n <th> <svg class=\"me-2\" xmlns=\"http://www.w3.org/2000/svg\" width=\"20\" height=\"20\" viewBox=\"0 0 20 20\"\r\n 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> <span>Wall</span> </th>\r\n <th>RFT ({{wallCapacity || 0}})</th>\r\n\r\n </tr>\r\n </thead>\r\n <tbody>\r\n <ng-container *ngFor=\"let item of layoutPolygon; let i = index\">\r\n <tr *ngIf=\"item[2] && item[2].elementType === 'wall'\">\r\n <td>\r\n {{1}}\r\n </td>\r\n <td>\r\n <div class=\"table-td\">{{item[2].elementType}} {{item[2].elementNumber}}</div>\r\n </td>\r\n <td>\r\n <div class=\"table-td\">{{item[2].distance}}</div>\r\n\r\n </td>\r\n </tr>\r\n </ng-container>\r\n\r\n </tbody>\r\n </table>\r\n <table class=\"table\">\r\n <thead class=\"thead-light\">\r\n <tr>\r\n <th>#</th>\r\n <th> <svg class=\"me-2\" 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> <span>Facade</span> </th>\r\n <th>RFT ({{facadeCapacity || 0}})</th>\r\n\r\n </tr>\r\n </thead>\r\n <tbody>\r\n <ng-container *ngFor=\"let item of layoutPolygon; let i = index\">\r\n <tr *ngIf=\"item[2] && item[2].elementType === 'facade'\">\r\n <td>\r\n {{i}}\r\n </td>\r\n <td>\r\n <div class=\"table-td\">{{item[2].elementType}} {{item[2].elementNumber}}</div>\r\n </td>\r\n <td>\r\n <div class=\"table-td\">{{item[2].distance}}</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 </div>\r\n </div>\r\n <div class=\"col-8\">\r\n <div class=\"c-card \" style=\"height: 75dvh;\">\r\n <div style=\"height: 8%;\" 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\" fill=\"none\">\r\n <path d=\"M5 7.5L10 12.5L15 7.5\" stroke=\"#344054\" stroke-width=\"1.67\" stroke-linecap=\"round\"\r\n 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)\" *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\r\n </div>\r\n\r\n </li>\r\n </ul>\r\n </div>\r\n </div>\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 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 <div class=\"hide-scrollbar\" style=\"height: 92%; overflow: scroll; position: relative;\" #scrollContainer>\r\n <canvas #gridCanvas>\r\n\r\n </canvas>\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>\r\n\r\n<ng-template #completeLayout let-modal>\r\n <div class=\"card\">\r\n <div style=\"min-height: unset; border-bottom: unset; padding-top: 2.25rem;\" class=\"card-header\">\r\n <div class=\"card-title\">\r\n <span class=\"modal-header-txt\">Complete Layout</span>\r\n </div>\r\n </div>\r\n <div style=\"padding-top: 1rem;\" class=\"card-body\">\r\n <div class=\"form-check\">\r\n <input (ngModelChange)=\"onModalTypeChange($event)\" [(ngModel)]=\"markAsCompleteType\" class=\"form-check-input\" type=\"radio\" name=\"one\" id=\"single\"\r\n value=\"single\">\r\n <div class=\"ms-3\">\r\n <div class=\"modal-main-txt\">Mark as complete for only <span\r\n class=\"highlight-txt\">{{selectedStore?.storeName}}</span></div>\r\n <div class=\"modal-sub-txt\">This action will considered as layout completion for {{selectedStore?.storeName}}\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"w-100 h-0 border my-5 border-bottom-grey\"></div>\r\n <div class=\"form-check mb-5\">\r\n <input (ngModelChange)=\"onModalTypeChange($event)\" [(ngModel)]=\"markAsCompleteType\" class=\"form-check-input\" type=\"radio\" name=\"one\" id=\"multiple\"\r\n value=\"multiple\">\r\n <div class=\"ms-3\">\r\n <div class=\"modal-main-txt\">Mark as complete for all {{planoStoreList.length}} stores</div>\r\n </div>\r\n </div>\r\n <div *ngIf=\"markAsCompleteType === 'multiple'\" class=\"table-responsive\">\r\n <table class=\"table\">\r\n <thead>\r\n <tr style=\"border-bottom: 1px solid #EAECF0; background: #FCFCFD;\">\r\n <th>\r\n <div class=\"form-check\">\r\n <input (click)=\"onModalSelectAll($event)\" [(ngModel)]=\"isAllStoreSelected\" class=\"form-check-input c-checkbox\" type=\"checkbox\">\r\n <label class=\"form-check-label check-label modal-storeName\">\r\n Store Name\r\n </label>\r\n </div>\r\n </th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n <tr style=\"border-bottom: 1px solid #EAECF0;\" *ngFor=\"let store of planoStoreList\">\r\n <td>\r\n <div class=\"form-check\">\r\n <input [(ngModel)]=\"store.selected\" class=\"form-check-input c-checkbox\" type=\"checkbox\">\r\n <label class=\"form-check-label check-label modal-storeName\">\r\n {{store?.storeName}}\r\n </label>\r\n </div>\r\n </td>\r\n </tr>\r\n </tbody>\r\n </table>\r\n </div>\r\n <div class=\"d-flex align-items-center justify-content-end\">\r\n <button (click)=\"modal.dismiss()\" class=\"btn btn-outline bg-white me-5\">Cancel</button>\r\n <button (click)=\"updatePlanoStatus(); modal.dismiss()\" class=\"btn btn-sm btn-primary \">Complete</button>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n</ng-template>", styles: [".storename-txt{color:var(--Black, #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}.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}.area-card{padding:20px;border-radius:6px;border:1px solid #D0D5DD;background:#fff;box-shadow:0 1px 3px #1018281a,0 1px 2px #1018280f;display:flex;justify-content:space-between}.area-card .main-txt{color:#101828;font-size:30px;font-weight:600;line-height:38px}.area-card .unit-txt{color:#101828;font-size:20px;font-style:italic;font-weight:600;line-height:30px}.area-card .sub-txt{color:#475467;font-size:16px;font-weight:500;line-height:24px}th{background:unset!important;border-bottom:unset!important;color:#1d2939;font-size:14px!important;font-weight:600!important;line-height:20px!important}.table-td{padding:10px 14px;border-radius:8px;background:#f9fafb}.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:var(--Gray-100, #F2F4F7)}.modal-header-txt{color:#344054;font-size:16px;font-weight:500;line-height:24px}.modal-main-txt{color:#1d2939;font-size:18px;font-weight:600;line-height:28px}.modal-main-txt .highlight-txt{color:#344054;font-size:16px;font-weight:600;line-height:24px}.modal-sub-txt{color:#667085;font-size:16px;font-weight:400;line-height:24px}.modal-storeName{color:#667085;font-size:14px;font-weight:500;line-height:20px}\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.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i6.RadioControlValueAccessor, selector: "input[type=radio][formControlName],input[type=radio][formControl],input[type=radio][ngModel]", inputs: ["name", "formControlName", "value"] }, { kind: "directive", type: i6.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i6.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i4.PaginationComponent, selector: "lib-pagination", inputs: ["collection", "itemsPerPage", "currentPage", "totalItems", "directionLinks", "pageSize", "paginationSizes"], outputs: ["pageChange", "pageSizeChange"] }, { kind: "component", type: i7.CustomSelectComponent, selector: "lib-select-plano", inputs: ["items", "searchField", "multi", "idField", "selectedValues", "disabled", "label"], outputs: ["selected"] }] });
|
|
792
|
+
}
|
|
793
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: LayoutSummaryComponent, decorators: [{
|
|
794
|
+
type: Component,
|
|
795
|
+
args: [{ selector: 'lib-layout-summary', 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)=\"onComplete()\" class=\"btn btn-sm btn-primary me-5\">Complete</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 mb-6\">\r\n <div class=\"col-4\">\r\n <div class=\"area-card\">\r\n <div>\r\n <div> <span class=\"main-txt me-2\">{{wallCapacity || 0}}</span> <span class=\"unit-txt\">rft</span> </div>\r\n <div class=\"sub-txt\">Wall capacity</div>\r\n </div>\r\n <div>\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"65\" height=\"65\" viewBox=\"0 0 65 65\" fill=\"none\">\r\n <path fill-rule=\"evenodd\" clip-rule=\"evenodd\"\r\n d=\"M4.33333 4.33333V0H8.66667V4.33333H21.6667V0H26V4.33333H39V0H43.3333V4.33333H56.3333V0H60.6667V4.33333H65V8.66667H60.6667V21.6667H65V26H60.6667V39H65V43.3333H60.6667V56.3333H65V60.6667H60.6667V65H56.3333V60.6667H43.3333V65H39V60.6667H26V65H21.6667V60.6667H8.66667V65H4.33333V60.6667H0V56.3333H4.33333V43.3333H0V39H4.33333V26H0V21.6667H4.33333V8.66667H0V4.33333H4.33333ZM8.66667 8.66667V21.6667H21.6667V8.66667H8.66667ZM26 8.66667V21.6667H39V8.66667H26ZM43.3333 8.66667V21.6667H56.3333V8.66667H43.3333ZM56.3333 26H43.3333V39H56.3333V26ZM56.3333 43.3333H43.3333V56.3333H56.3333V43.3333ZM39 56.3333V43.3333H26V56.3333H39ZM21.6667 56.3333V43.3333H8.66667V56.3333H21.6667ZM8.66667 39H21.6667V26H8.66667V39ZM26 26V39H39V26H26Z\"\r\n fill=\"#344054\" />\r\n </svg>\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"col-4\">\r\n <div class=\"area-card\">\r\n <div>\r\n <div> <span class=\"main-txt me-2\">{{facadeCapacity || 0}}</span> <span class=\"unit-txt\">rft</span> </div>\r\n <div class=\"sub-txt\">Facade capacity</div>\r\n </div>\r\n <div>\r\n <svg width=\"65\" height=\"65\" viewBox=\"0 0 65 65\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\r\n <rect x=\"0.5\" y=\"0.5\" width=\"64\" height=\"64\" fill=\"#FDFDFD\" stroke=\"black\" />\r\n </svg>\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"col-4\">\r\n <div class=\"area-card\">\r\n <div>\r\n <div> <span class=\"main-txt me-2\">{{floorCapacity || 0}}</span> <span class=\"unit-txt\">sqft</span> </div>\r\n <div class=\"sub-txt\">Floor capacity</div>\r\n </div>\r\n <div>\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"102\" height=\"58\" viewBox=\"0 0 102 58\" fill=\"none\">\r\n <path d=\"M3.54359 36.4607L29.8929 2.06432L98.0939 6.44191L99.908 55.5468L3.54359 36.4607Z\" stroke=\"#475467\"\r\n stroke-width=\"4\" />\r\n </svg>\r\n </div>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<div class=\"row\">\r\n <div class=\"col-4\">\r\n <div class=\"c-card\" style=\"height: 75dvh; position: relative;\">\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 Capacity details\r\n </div>\r\n <div class=\"l-pane-desc\">\r\n Below are the capacity details of the elements\r\n </div>\r\n </div>\r\n <div class=\"d-flex align-items-center\">\r\n\r\n </div>\r\n\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>#</th>\r\n <th> <svg class=\"me-2\" xmlns=\"http://www.w3.org/2000/svg\" width=\"20\" height=\"20\" viewBox=\"0 0 20 20\"\r\n 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> <span>Wall</span> </th>\r\n <th>RFT ({{wallCapacity || 0}})</th>\r\n\r\n </tr>\r\n </thead>\r\n <tbody>\r\n <ng-container *ngFor=\"let item of layoutPolygon; let i = index\">\r\n <tr *ngIf=\"item[2] && item[2].elementType === 'wall'\">\r\n <td>\r\n {{1}}\r\n </td>\r\n <td>\r\n <div class=\"table-td\">{{item[2].elementType}} {{item[2].elementNumber}}</div>\r\n </td>\r\n <td>\r\n <div class=\"table-td\">{{item[2].distance}}</div>\r\n\r\n </td>\r\n </tr>\r\n </ng-container>\r\n\r\n </tbody>\r\n </table>\r\n <table class=\"table\">\r\n <thead class=\"thead-light\">\r\n <tr>\r\n <th>#</th>\r\n <th> <svg class=\"me-2\" 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> <span>Facade</span> </th>\r\n <th>RFT ({{facadeCapacity || 0}})</th>\r\n\r\n </tr>\r\n </thead>\r\n <tbody>\r\n <ng-container *ngFor=\"let item of layoutPolygon; let i = index\">\r\n <tr *ngIf=\"item[2] && item[2].elementType === 'facade'\">\r\n <td>\r\n {{i}}\r\n </td>\r\n <td>\r\n <div class=\"table-td\">{{item[2].elementType}} {{item[2].elementNumber}}</div>\r\n </td>\r\n <td>\r\n <div class=\"table-td\">{{item[2].distance}}</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 </div>\r\n </div>\r\n <div class=\"col-8\">\r\n <div class=\"c-card \" style=\"height: 75dvh;\">\r\n <div style=\"height: 8%;\" 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\" fill=\"none\">\r\n <path d=\"M5 7.5L10 12.5L15 7.5\" stroke=\"#344054\" stroke-width=\"1.67\" stroke-linecap=\"round\"\r\n 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)\" *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\r\n </div>\r\n\r\n </li>\r\n </ul>\r\n </div>\r\n </div>\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 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 <div class=\"hide-scrollbar\" style=\"height: 92%; overflow: scroll; position: relative;\" #scrollContainer>\r\n <canvas #gridCanvas>\r\n\r\n </canvas>\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>\r\n\r\n<ng-template #completeLayout let-modal>\r\n <div class=\"card\">\r\n <div style=\"min-height: unset; border-bottom: unset; padding-top: 2.25rem;\" class=\"card-header\">\r\n <div class=\"card-title\">\r\n <span class=\"modal-header-txt\">Complete Layout</span>\r\n </div>\r\n </div>\r\n <div style=\"padding-top: 1rem;\" class=\"card-body\">\r\n <div class=\"form-check\">\r\n <input (ngModelChange)=\"onModalTypeChange($event)\" [(ngModel)]=\"markAsCompleteType\" class=\"form-check-input\" type=\"radio\" name=\"one\" id=\"single\"\r\n value=\"single\">\r\n <div class=\"ms-3\">\r\n <div class=\"modal-main-txt\">Mark as complete for only <span\r\n class=\"highlight-txt\">{{selectedStore?.storeName}}</span></div>\r\n <div class=\"modal-sub-txt\">This action will considered as layout completion for {{selectedStore?.storeName}}\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"w-100 h-0 border my-5 border-bottom-grey\"></div>\r\n <div class=\"form-check mb-5\">\r\n <input (ngModelChange)=\"onModalTypeChange($event)\" [(ngModel)]=\"markAsCompleteType\" class=\"form-check-input\" type=\"radio\" name=\"one\" id=\"multiple\"\r\n value=\"multiple\">\r\n <div class=\"ms-3\">\r\n <div class=\"modal-main-txt\">Mark as complete for all {{planoStoreList.length}} stores</div>\r\n </div>\r\n </div>\r\n <div *ngIf=\"markAsCompleteType === 'multiple'\" class=\"table-responsive\">\r\n <table class=\"table\">\r\n <thead>\r\n <tr style=\"border-bottom: 1px solid #EAECF0; background: #FCFCFD;\">\r\n <th>\r\n <div class=\"form-check\">\r\n <input (click)=\"onModalSelectAll($event)\" [(ngModel)]=\"isAllStoreSelected\" class=\"form-check-input c-checkbox\" type=\"checkbox\">\r\n <label class=\"form-check-label check-label modal-storeName\">\r\n Store Name\r\n </label>\r\n </div>\r\n </th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n <tr style=\"border-bottom: 1px solid #EAECF0;\" *ngFor=\"let store of planoStoreList\">\r\n <td>\r\n <div class=\"form-check\">\r\n <input [(ngModel)]=\"store.selected\" class=\"form-check-input c-checkbox\" type=\"checkbox\">\r\n <label class=\"form-check-label check-label modal-storeName\">\r\n {{store?.storeName}}\r\n </label>\r\n </div>\r\n </td>\r\n </tr>\r\n </tbody>\r\n </table>\r\n </div>\r\n <div class=\"d-flex align-items-center justify-content-end\">\r\n <button (click)=\"modal.dismiss()\" class=\"btn btn-outline bg-white me-5\">Cancel</button>\r\n <button (click)=\"updatePlanoStatus(); modal.dismiss()\" class=\"btn btn-sm btn-primary \">Complete</button>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n</ng-template>", styles: [".storename-txt{color:var(--Black, #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}.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}.area-card{padding:20px;border-radius:6px;border:1px solid #D0D5DD;background:#fff;box-shadow:0 1px 3px #1018281a,0 1px 2px #1018280f;display:flex;justify-content:space-between}.area-card .main-txt{color:#101828;font-size:30px;font-weight:600;line-height:38px}.area-card .unit-txt{color:#101828;font-size:20px;font-style:italic;font-weight:600;line-height:30px}.area-card .sub-txt{color:#475467;font-size:16px;font-weight:500;line-height:24px}th{background:unset!important;border-bottom:unset!important;color:#1d2939;font-size:14px!important;font-weight:600!important;line-height:20px!important}.table-td{padding:10px 14px;border-radius:8px;background:#f9fafb}.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:var(--Gray-100, #F2F4F7)}.modal-header-txt{color:#344054;font-size:16px;font-weight:500;line-height:24px}.modal-main-txt{color:#1d2939;font-size:18px;font-weight:600;line-height:28px}.modal-main-txt .highlight-txt{color:#344054;font-size:16px;font-weight:600;line-height:24px}.modal-sub-txt{color:#667085;font-size:16px;font-weight:400;line-height:24px}.modal-storeName{color:#667085;font-size:14px;font-weight:500;line-height:20px}\n"] }]
|
|
796
|
+
}], ctorParameters: () => [{ type: i1.ActivatedRoute }, { type: i2.StoreBuilderService }, { type: i3.NgbModal }, { type: i3.NgbOffcanvas }, { type: i1.Router }, { type: i3.NgbModal }, { type: i4.ToastService }], propDecorators: { canvasRef: [{
|
|
797
|
+
type: ViewChild,
|
|
798
|
+
args: ['gridCanvas', { static: true }]
|
|
799
|
+
}], scrollContainerRef: [{
|
|
800
|
+
type: ViewChild,
|
|
801
|
+
args: ['scrollContainer']
|
|
802
|
+
}], completeLayout: [{
|
|
803
|
+
type: ViewChild,
|
|
804
|
+
args: ['completeLayout']
|
|
805
|
+
}], onOutsideClick: [{
|
|
806
|
+
type: HostListener,
|
|
807
|
+
args: ['document:click', ['$event']]
|
|
808
|
+
}] } });
|
|
809
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibGF5b3V0LXN1bW1hcnkuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvdGFuZ28tc3RvcmUtYnVpbGRlci9zcmMvbGliL2NvbXBvbmVudHMvbGF5b3V0LXN1bW1hcnkvbGF5b3V0LXN1bW1hcnkuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvdGFuZ28tc3RvcmUtYnVpbGRlci9zcmMvbGliL2NvbXBvbmVudHMvbGF5b3V0LXN1bW1hcnkvbGF5b3V0LXN1bW1hcnkuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQ0EsT0FBTyxFQUFvQyxTQUFTLEVBQTRCLFlBQVksRUFBK0MsU0FBUyxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQzVLLE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUU3QyxPQUFPLEVBQUUsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUkxQyxPQUFPLEVBQUUsZ0NBQWdDLEVBQUUsTUFBTSxrRUFBa0UsQ0FBQztBQUNwSCxPQUFPLEVBQUUsdUJBQXVCLEVBQUUsTUFBTSxvREFBb0QsQ0FBQzs7Ozs7Ozs7O0FBUTdGLE1BQU0sT0FBTyxzQkFBc0I7SUFtRmI7SUFBK0I7SUFBeUM7SUFDbEY7SUFBd0M7SUFBd0I7SUFBNEI7SUFsRnRHLFdBQVcsR0FBRyxJQUFJLFdBQVcsRUFBRSxDQUFBO0lBQ1ksU0FBUyxDQUFpQztJQUN2RCxrQkFBa0IsQ0FBYztJQUNqQyxjQUFjLENBQWM7SUFHekQsU0FBUyxHQUFHLENBQUMsQ0FBQztJQUNkLFVBQVUsR0FBRyxDQUFDLENBQUM7SUFFUCxHQUFHLENBQTRCO0lBQy9CLE1BQU0sQ0FBcUI7SUFFbkMsYUFBYSxHQUFVLENBQUM7WUFDdEI7Z0JBQ0UsR0FBRyxFQUFFLEdBQUc7Z0JBQ1IsR0FBRyxFQUFFLEdBQUc7YUFDVDtZQUNEO2dCQUNF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O3NCQUFuRCxTQUFTO3VCQUFDLFlBQVksRUFBRSxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUU7Z0JBQ1gsa0JBQWtCO3NCQUEvQyxTQUFTO3VCQUFDLGlCQUFpQjtnQkFDQyxjQUFjO3NCQUExQyxTQUFTO3VCQUFDLGdCQUFnQjtnQkErRDNCLGNBQWM7c0JBRGIsWUFBWTt1QkFBQyxnQkFBZ0IsRUFBRSxDQUFDLFFBQVEsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENka0RyYWdEcm9wLCBtb3ZlSXRlbUluQXJyYXkgfSBmcm9tICdAYW5ndWxhci9jZGsvZHJhZy1kcm9wJztcclxuaW1wb3J0IHsgQWZ0ZXJWaWV3SW5pdCwgQ2hhbmdlRGV0ZWN0b3JSZWYsIENvbXBvbmVudCwgRWxlbWVudFJlZiwgRXZlbnRFbWl0dGVyLCBIb3N0TGlzdGVuZXIsIElucHV0LCBPbkRlc3Ryb3ksIE9uSW5pdCwgT3V0cHV0LCBSZW5kZXJlcjIsIFZpZXdDaGlsZCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5pbXBvcnQgeyBGb3JtQ29udHJvbCB9IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcclxuaW1wb3J0IHsgQWN0aXZhdGVkUm91dGUsIFJvdXRlciB9IGZyb20gJ0Bhbmd1bGFyL3JvdXRlcic7XHJcbmltcG9ydCB7IFN1YmplY3QsIHRha2VVbnRpbCB9IGZyb20gJ3J4anMnO1xyXG5pbXBvcnQgeyBIZWFkZXJGaWx0ZXIgfSBmcm9tICcuLi8uLi9pbnRlcmZhY2VzL2xheW91dC1idWlsZGVyLmludGVyZmFjZSc7XHJcbmltcG9ydCB7IFN0b3JlQnVpbGRlclNlcnZpY2UgfSBmcm9tICcuLi8uLi9zZXJ2aWNlcy9zdG9yZS1idWlsZGVyLnNlcnZpY2UnO1xyXG5pbXBvcnQgeyBOZ2JNb2RhbCwgTmdiT2ZmY2FudmFzIH0gZnJvbSAnQG5nLWJvb3RzdHJhcC9uZy1ib290c3RyYXAnO1xyXG5pbXBvcnQgeyBTdG9yZU9mZmNhbnZhc0NvbXBvbmVudENvbXBvbmVudCB9IGZyb20gJy4uL3N0b3JlLW9mZmNhbnZhcy1jb21wb25lbnQvc3RvcmUtb2ZmY2FudmFzLWNvbXBvbmVudC5jb21wb25lbnQnO1xyXG5pbXBvcnQgeyBDb21wbGV0ZUxheW91dENvbXBvbmVudCB9IGZyb20gJy4vcG9wdXBzL2NvbXBsZXRlLWxheW91dC9jb21wbGV0ZS1sYXlvdXQuY29tcG9uZW50JztcclxuaW1wb3J0IHsgVG9hc3RTZXJ2aWNlIH0gZnJvbSAndGFuZ28tYXBwLXVpLXNoYXJlZCc7XHJcblxyXG5AQ29tcG9uZW50KHtcclxuICBzZWxlY3RvcjogJ2xpYi1sYXlvdXQtc3VtbWFyeScsXHJcbiAgdGVtcGxhdGVVcmw6ICcuL2xheW91dC1zdW1tYXJ5LmNvbXBvbmVudC5odG1sJyxcclxuICBzdHlsZVVybDogJy4vbGF5b3V0LXN1bW1hcnkuY29tcG9uZW50LnNjc3MnXHJcbn0pXHJcbmV4cG9ydCBjbGFzcyBMYXlvdXRTdW1tYXJ5Q29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0LCBBZnRlclZpZXdJbml0LCBPbkRlc3Ryb3kge1xyXG5cclxuICBmbG9vcnNJbnB1dCA9IG5ldyBGb3JtQ29udHJvbCgpXHJcbiAgQFZpZXdDaGlsZCgnZ3JpZENhbnZhcycsIHsgc3RhdGljOiB0cnVlIH0pIGNhbnZhc1JlZiE6IEVsZW1lbnRSZWY8SFRNTENhbnZhc0VsZW1lbnQ+O1xyXG4gIEBWaWV3Q2hpbGQoJ3Njcm9sbENvbnRhaW5lcicpIHNjcm9sbENvbnRhaW5lclJlZiE6IEVsZW1lbnRSZWY7XHJcbiAgQFZpZXdDaGlsZCgnY29tcGxldGVMYXlvdXQnKSBjb21wbGV0ZUxheW91dCE6IEVsZW1lbnRSZWY7XHJcblxyXG5cclxuICBncmlkV2lkdGggPSA1O1xyXG4gIGdyaWRIZWlnaHQgPSA1O1xyXG5cclxuICBwcml2YXRlIGN0eCE6IENhbnZhc1JlbmRlcmluZ0NvbnRleHQyRDtcclxuICBwcml2YXRlIGNhbnZhcyE6IEhUTUxDYW52YXNFbGVtZW50O1xyXG5cclxuICBsYXlvdXRQb2x5Z29uOiBhbnlbXSA9IFtbXHJcbiAgICB7XHJcbiAgICAgIFwieFwiOiAxMDAsXHJcbiAgICAgIFwieVwiOiAxMDBcclxuICAgIH0sXHJcbiAgICB7XHJcbiAgICAgIFwieFwiOiAxMDAsXHJcbiAgICAgIFwieVwiOiAxMDBcclxuICAgIH0sXHJcbiAgICB7XHJcbiAgICAgIFwiZWxlbWVudFR5cGVcIjogXCJ3YWxsXCIsXHJcbiAgICAgIFwiZGlzdGFuY2VcIjogMCxcclxuICAgICAgXCJ1bml0XCI6IFwiZnRcIixcclxuICAgICAgXCJkaXJlY3Rpb25cIjogXCJyaWdodFwiLFxyXG4gICAgICBcImFuZ2xlXCI6IDkwLFxyXG4gICAgICBcImVsZW1lbnROdW1iZXJcIjogMVxyXG4gICAgfVxyXG4gIF1dXHJcblxyXG4gIHByaXZhdGUgc2NhbGUgPSAxO1xyXG5cclxuICBwcml2YXRlIGRlc3Ryb3kkID0gbmV3IFN1YmplY3Q8dm9pZD4oKTtcclxuXHJcbiAgaGVhZGVyRGF0YTogSGVhZGVyRmlsdGVyIHwgbnVsbCB8IHVuZGVmaW5lZDtcclxuXHJcbiAgcGxhbm9TdG9yZUxpc3Q6IGFueVtdID0gW11cclxuICBzZWxlY3RlZFN0b3JlOiBhbnlcclxuICBzZWxlY3RlZEZsb29yOiBhbnlcclxuICB3YWxsQ2FwYWNpdHk6IG51bWJlclxyXG4gIGZhY2FkZUNhcGFjaXR5OiBudW1iZXJcclxuICBmbG9vckNhcGFjaXR5OiBudW1iZXJcclxuXHJcbiAgZmxvb3JTZWxlY3Q6IHsgc2hvdzogYm9vbGVhbiwgZGVsZXRlSW5kZXg6IG51bWJlciB8IG51bGwgfSA9IHsgc2hvdzogZmFsc2UsIGRlbGV0ZUluZGV4OiBudWxsIH1cclxuXHJcbiAgbWFya0FzQ29tcGxldGVUeXBlOiAnc2luZ2xlJyB8ICdtdWx0aXBsZScgPSAnc2luZ2xlJ1xyXG5cclxuICBpdGVtc1BlclBhZ2UgPSAxXHJcbiAgY3VycmVudFBhZ2UgPSAwXHJcbiAgdG90YWxJdGVtcyA9IDFcclxuICBwYWdpbmF0aW9uU2l6ZXMgPSBbMV1cclxuICBwYWdlU2l6ZSA9IDFcclxuXHJcbiAgcGl4ZWxQZXJNZXRyZTogbnVtYmVyID0gNTBcclxuXHJcblxyXG4gIG9uRmxvb3JTZWxlY3QoZmxvb3JJZDogc3RyaW5nKSB7XHJcbiAgICBpZiAodGhpcy5sYXlvdXRQb2x5Z29uWzBdWzBdLnggIT09IHRoaXMubGF5b3V0UG9seWdvblswXVsxXS54ICYmIHRoaXMubGF5b3V0UG9seWdvblswXVswXS55ICE9PSB0aGlzLmxheW91dFBvbHlnb25bMF1bMV0ueSkge1xyXG4gICAgICB0aGlzLnVwZGF0ZUZsb29yTGF5b3V0KClcclxuICAgIH1cclxuICAgIHRoaXMuc2VsZWN0ZWRGbG9vciA9IHRoaXMuc2VsZWN0ZWRTdG9yZS5mbG9vci5maWx0ZXIoKGZsb29yOiBhbnkpID0+IGZsb29yLmlkID09PSBmbG9vcklkKVswXVxyXG4gICAgdGhpcy5nZW5lcmF0ZUxheW91dFBvbHlnb24odGhpcy5zZWxlY3RlZEZsb29yLmxheW91dFBvbHlnb24pXHJcbiAgfVxyXG5cclxuICBASG9zdExpc3RlbmVyKCdkb2N1bWVudDpjbGljaycsIFsnJGV2ZW50J10pXHJcbiAgb25PdXRzaWRlQ2xpY2soZXZlbnQ6IE1vdXNlRXZlbnQpOiB2b2lkIHtcclxuXHJcbiAgICBjb25zdCBjbGlja2VkSW5zaWRlNiA9IChldmVudC50YXJnZXQgYXMgSFRNTEVsZW1lbnQpLmNsb3Nlc3QoJy5mbG9vci1zZWxlY3QnKTtcclxuICAgIGlmICghY2xpY2tlZEluc2lkZTYpIHtcclxuICAgICAgdGhpcy5mbG9vclNlbGVjdCA9IHsgc2hvdzogZmFsc2UsIGRlbGV0ZUluZGV4OiBudWxsIH07XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICB0b2dnbGVGbG9vclNlbGVjdCgpOiB2b2lkIHtcclxuICAgIHRoaXMuZmxvb3JTZWxlY3QgPSB7XHJcbiAgICAgIHNob3c6ICF0aGlzLmZsb29yU2VsZWN0LnNob3csXHJcbiAgICAgIGRlbGV0ZUluZGV4OiBudWxsXHJcbiAgICB9O1xyXG4gIH1cclxuXHJcbiAgY29uc3RydWN0b3IocHJpdmF0ZSByb3V0ZTogQWN0aXZhdGVkUm91dGUsIHByaXZhdGUgYXBpU2VydmljZTogU3RvcmVCdWlsZGVyU2VydmljZSwgcHJpdmF0ZSBtb2RhbFNlcnZpY2U6IE5nYk1vZGFsLFxyXG4gICAgcHJpdmF0ZSBvZmZjYW52YXNTZXJ2aWNlOiBOZ2JPZmZjYW52YXMsIHByaXZhdGUgcm91dGVyOiBSb3V0ZXIsIHByaXZhdGUgbW9kYWxEZWY6IE5nYk1vZGFsLCBwcml2YXRlIHRvYXN0U2VydmljZTpUb2FzdFNlcnZpY2UpIHtcclxuICAgIHRoaXMuaGVhZGVyRGF0YSA9IEpTT04ucGFyc2UobG9jYWxTdG9yYWdlLmdldEl0ZW0oJ2hlYWRlci1maWx0ZXJzJykgYXMgc3RyaW5nKVxyXG4gIH1cclxuXHJcbiAgbmdBZnRlclZpZXdJbml0KCk6IHZvaWQge1xyXG4gICAgdGhpcy5pbml0aWFsaXplTGF5b3V0KClcclxuICB9XHJcblxyXG4gIGluaXRpYWxpemVMYXlvdXQoKSB7XHJcbiAgICBjb25zdCBjZW50ZXJYID0gdGhpcy5jYW52YXMud2lkdGggLyAyIC8gdGhpcy5zY2FsZTtcclxuICAgIGNvbnN0IGNlbnRlclkgPSB0aGlzLmNhbnZhcy5oZWlnaHQgLyAyIC8gdGhpcy5zY2FsZTtcclxuXHJcbiAgICB0aGlzLmxheW91dFBvbHlnb24gPSBbXHJcbiAgICAgIFtcclxuICAgICAgICB7XHJcbiAgICAgICAgICBcInhcIjogdGhpcy5zbmFwVG9HcmlkKGNlbnRlclgsIHRoaXMuZ3JpZEhlaWdodCksXHJcbiAgICAgICAgICBcInlcIjogdGhpcy5zbmFwVG9HcmlkKGNlbnRlclksIHRoaXMuZ3JpZFdpZHRoKVxyXG4gICAgICAgIH0sXHJcbiAgICAgICAge1xyXG4gICAgICAgICAgXCJ4XCI6IHRoaXMuc25hcFRvR3JpZChjZW50ZXJYLCB0aGlzLmdyaWRIZWlnaHQpLFxyXG4gICAgICAgICAgXCJ5XCI6IHRoaXMuc25hcFRvR3JpZChjZW50ZXJZLCB0aGlzLmdyaWRXaWR0aClcclxuICAgICAgICB9LFxyXG4gICAgICAgIHtcclxuICAgICAgICAgIFwiZWxlbWVudFR5cGVcIjogXCJ3YWxsXCIsXHJcbiAgICAgICAgICBcImRpc3RhbmNlXCI6IDAsXHJcbiAgICAgICAgICBcInVuaXRcIjogXCJmdFwiLFxyXG4gICAgICAgICAgXCJkaXJlY3Rpb25cIjogXCJyaWdodFwiLFxyXG4gICAgICAgICAgXCJhbmdsZVwiOiA5MCxcclxuICAgICAgICAgIFwiZWxlbWVudE51bWJlclwiOiAxXHJcbiAgICAgICAgfVxyXG4gICAgICBdXHJcbiAgICBdXHJcbiAgfVxyXG5cclxuICBuZ09uSW5pdCgpOiB2b2lkIHtcclxuICAgIHRoaXMuY2FudmFzID0gdGhpcy5jYW52YXNSZWYubmF0aXZlRWxlbWVudDtcclxuICAgIHRoaXMuY3R4ID0gdGhpcy5jYW52YXMuZ2V0Q29udGV4dCgnMmQnKSE7XHJcblxyXG4gICAgdGhpcy5jYW52YXMud2lkdGggPSAxMDAwMDtcclxuICAgIHRoaXMuY2FudmFzLmhlaWdodCA9IDEwMDAwO1xyXG5cclxuXHJcbiAgICB0aGlzLmRyYXdHcmlkKCk7XHJcblxyXG4gICAgdGhpcy5yb3V0ZS5xdWVyeVBhcmFtc1xyXG4gICAgICAucGlwZSh0YWtlVW50aWwodGhpcy5kZXN0cm95JCkpXHJcbiAgICAgIC5zdWJzY3JpYmUoKHBhcmFtcykgPT4ge1xyXG4gICAgICAgIGlmIChwYXJhbXM/LmlkKSB7XHJcbiAgICAgICAgICBjb25zdCBpZHMgPSBwYXJhbXMuaWQuc3BsaXQoJywnKSB8fCBbXTtcclxuICAgICAgICAgIHRoaXMuZ2V0UGxhbm9EYXRhKGlkcylcclxuICAgICAgICB9XHJcbiAgICAgIH0pO1xyXG5cclxuICAgIHRoaXMuZmxvb3JzSW5wdXQudmFsdWVDaGFuZ2VzLnN1YnNjcmliZSgodmFsKSA9PiB7XHJcbiAgICAgIGlmICh2YWwpIHtcclxuICAgICAgICBpZiAodGhpcy5sYXlvdXRQb2x5Z29uWzBdWzBdLnggIT09IHRoaXMubGF5b3V0UG9seWdvblswXVsxXS54ICYmIHRoaXMubGF5b3V0UG9seWdvblswXVswXS55ICE9PSB0aGlzLmxheW91dFBvbHlnb25bMF1bMV0ueSkge1xyXG4gICAgICAgICAgdGhpcy51cGRhdGVGbG9vckxheW91dCgpXHJcbiAgICAgICAgfVxyXG4gICAgICAgIHRoaXMuc2VsZWN0ZWRGbG9vciA9IHRoaXMuc2VsZWN0ZWRTdG9yZS5mbG9vci5maWx0ZXIoKGZsb29yOiBhbnkpID0+IGZsb29yLmlkID09PSB2YWwpWzBdXHJcbiAgICAgICAgdGhpcy5nZW5lcmF0ZUxheW91dFBvbHlnb24odGhpcy5zZWxlY3RlZEZsb29yLmxheW91dFBvbHlnb24pXHJcbiAgICAgIH1cclxuICAgIH0pXHJcblxyXG4gIH1cclxuXHJcblxyXG4gIG5nT25EZXN0cm95KCk6IHZvaWQge1xyXG4gICAgdGhpcy5kZXN0cm95JC5uZXh0KCk7XHJcbiAgICB0aGlzLmRlc3Ryb3kkLmNvbXBsZXRlKCk7XHJcbiAgfVxyXG5cclxuICBvblN0b3JlQ2hhbmdlKGV2ZW50OiBhbnkpIHtcclxuICAgIGlmICh0aGlzLmxheW91dFBvbHlnb25bMF1bMF0ueCAhPT0gdGhpcy5sYXlvdXRQb2x5Z29uWzBdWzFdLnggJiYgdGhpcy5sYXlvdXRQb2x5Z29uWzBdWzBdLnkgIT09IHRoaXMubGF5b3V0UG9seWdvblswXVsxXS55KSB7XHJcbiAgICAgIHRoaXMudXBkYXRlRmxvb3JMYXlvdXQoKVxyXG4gICAgfVxyXG4gICAgY29uc3QgaW5kZXggPSB0aGlzLnBsYW5vU3RvcmVMaXN0LmZpbmRJbmRleChpdGVtID0+IGl0ZW0ucGxhbm9JZCA9PT0gZXZlbnQucGxhbm9JZCk7XHJcbiAgICB0aGlzLmN1cnJlbnRQYWdlID0gaW5kZXggKyAxXHJcbiAgICB0aGlzLnNlbGVjdGVkU3RvcmUgPSBldmVudDtcclxuICAgIHRoaXMuc2VsZWN0ZWRGbG9vciA9IHRoaXMuc2VsZWN0ZWRTdG9yZS5mbG9vclswXTtcclxuICAgIHRoaXMuZmxvb3JzSW5wdXQuc2V0VmFsdWUodGhpcy5zZWxlY3RlZEZsb29yLmlkLCB7IGVtaXRFdmVudDogZmFsc2UgfSk7XHJcbiAgICB0aGlzLmdlbmVyYXRlTGF5b3V0UG9seWdvbih0aGlzLnNlbGVjdGVkRmxvb3IubGF5b3V0UG9seWdvbik7XHJcbiAgfVxyXG5cclxuICBnZXRQbGFub0RhdGEocGxhbm9JZDogc3RyaW5nW10pIHtcclxuICAgIGNvbnN0IHBheWxvYWQgPSB7XHJcbiAgICAgIGlkOiBwbGFub0lkXHJcbiAgICB9XHJcblxyXG4gICAgdGhpcy5hcGlTZXJ2aWNlLmdldFBsYW5vKHBheWxvYWQpLnN1YnNjcmliZSh7XHJcbiAgICAgIG5leHQ6IChyZXM6IGFueSkgPT4ge1xyXG4gICAgICAgIHRoaXMucGxhbm9TdG9yZUxpc3QgPSByZXMuZGF0YVxyXG4gICAgICAgIHRoaXMudG90YWxJdGVtcyA9IHJlcy5kYXRhLmxlbmd0aFxyXG4gICAgICAgIC8vIHRoaXMucGxhbm9TdG9yZUxpc3QgPSByZXMuZGF0YS5maWx0ZXIoKHBsYW5vOmFueSkgPT4gcGxhbm8uc3RhdHVzICE9PSAnY29tcGxldGVkJyk7XHJcbiAgICAgICAgaWYgKCF0aGlzLnNlbGVjdGVkU3RvcmUpIHtcclxuICAgICAgICAgIHRoaXMuc2VsZWN0ZWRTdG9yZSA9IHRoaXMucGxhbm9TdG9yZUxpc3RbMF1cclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgdGhpcy5zZWxlY3RlZFN0b3JlID0gdGhpcy5wbGFub1N0b3JlTGlzdC5maWx0ZXIoKHN0b3JlOiBhbnkpID0+IHN0b3JlLnBsYW5vSWQgPT09IHRoaXMuc2VsZWN0ZWRTdG9yZS5wbGFub0lkKVswXVxyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAoIXRoaXMuc2VsZWN0ZWRGbG9vcikge1xyXG4gICAgICAgICAgdGhpcy5zZWxlY3RlZEZsb29yID0gdGhpcy5zZWxlY3RlZFN0b3JlLmZsb29yWzBdXHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgIHRoaXMuc2VsZWN0ZWRGbG9vciA9IHRoaXMuc2VsZWN0ZWRTdG9yZS5mbG9vci5maWx0ZXIoKGZsb29yOiBhbnkpID0+IGZsb29yLmlkID09PSB0aGlzLnNlbGVjdGVkRmxvb3IuaWQpWzBdXHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICB0aGlzLnBsYW5vU3RvcmVMaXN0LmZvckVhY2goKHN0b3JlKSA9PiB7XHJcbiAgICAgICAgICBpZiAoc3RvcmUucGxhbm9JZCA9PT0gdGhpcy5zZWxlY3RlZFN0b3JlLnBsYW5vSWQpIHtcclxuICAgICAgICAgICAgc3RvcmUuc2VsZWN0ZWQgPSB0cnVlXHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfSlcclxuXHJcbiAgICAgICAgdGhpcy5mbG9vcnNJbnB1dC5zZXRWYWx1ZSh0aGlzLnNlbGVjdGVkRmxvb3IuaWQsIHsgZW1pdEV2ZW50OiBmYWxzZSB9KVxyXG4gICAgICAgIHRoaXMuZ2VuZXJhdGVMYXlvdXRQb2x5Z29uKHRoaXMuc2VsZWN0ZWRGbG9vci5sYXlvdXRQb2x5Z29uKVxyXG4gICAgICB9LFxyXG4gICAgICBlcnJvcjogKGVycikgPT4ge1xyXG4gICAgICAgIGNvbnNvbGUubG9nKGVycilcclxuICAgICAgfVxyXG4gICAgfSlcclxuICB9XHJcblxyXG4gIHVwZGF0ZUZsb29yTGF5b3V0KCkge1xyXG4gICAgY29uc3QgcGF5bG9hZCA9IHtcclxuICAgICAgaWQ6IHRoaXMuc2VsZWN0ZWRGbG9vci5pZCxcclxuICAgICAgbGF5b3V0UG9seWdvbjogdGhpcy5sYXlvdXRQb2x5Z29uLm1hcCgoc2VnbWVudCkgPT4ge1xyXG4gICAgICAgIGNvbnN0IFtwb2ludDEsIHBvaW50MiwgcHJvcGVydGllc10gPSBzZWdtZW50XHJcbiAgICAgICAgcmV0dXJuIHByb3BlcnRpZXNcclxuICAgICAgfSlcclxuICAgIH1cclxuXHJcbiAgICB0aGlzLmFwaVNlcnZpY2UudXBkYXRlRmxvb3JMYXlvdXQocGF5bG9hZCkuc3Vic2NyaWJlKHtcclxuICAgICAgbmV4dDogKHJlcykgPT4ge1xyXG4gICAgICAgIHRoaXMuZ2V0UGxhbm9EYXRhKHRoaXMuc2VsZWN0ZWRTdG9yZS5wbGFub0lkKVxyXG4gICAgICB9LFxyXG4gICAgICBlcnJvcjogKGVycikgPT4ge1xyXG4gICAgICAgIGNvbnNvbGUubG9nKGVycilcclxuICAgICAgfVxyXG4gICAgfSlcclxuICB9XHJcblxyXG4gIG9uQ29tcGxldGUoKSB7XHJcblxyXG4gICAgaWYgKHRoaXMucGxhbm9TdG9yZUxpc3QubGVuZ3RoID09PSAxKSB7XHJcbiAgICAgIGNvbnN0IG1vZGVsUmVmID0gdGhpcy5tb2RhbERlZi5vcGVuKENvbXBsZXRlTGF5b3V0Q29tcG9uZW50LCB7IGNlbnRlcmVkOiB0cnVlIH0pO1xyXG4gICAgICBtb2RlbFJlZi5yZXN1bHQudGhlbigodmFsOiBhbnkpID0+IHtcclxuICAgICAgICBpZiAodmFsLm1lc3NhZ2UgPT09ICdjb25maXJtJykge1xyXG4gICAgICAgICAgdGhpcy51cGRhdGVQbGFub1N0YXR1cygpXHJcbiAgICAgICAgfVxyXG4gICAgICB9KVxyXG4gICAgfSBlbHNlIHtcclxuICAgICAgdGhpcy5tb2RhbFNlcnZpY2Uub3Blbih0aGlzLmNvbXBsZXRlTGF5b3V0LCB7IGNlbnRlcmVkOiB0cnVlLCBzaXplOiBcImxnXCIgfSlcclxuICAgIH1cclxuICB9XHJcblxyXG5cclxuICBkcmF3R3JpZCgpOiB2b2lkIHtcclxuICAgIHRoaXMuY3R4LnNhdmUoKTtcclxuICAgIHRoaXMuY3R4LmNsZWFyUmVjdCgwLCAwLCB0aGlzLmNhbnZhcy53aWR0aCwgdGhpcy5jYW52YXMuaGVpZ2h0KTtcclxuICAgIHRoaXMuY3R4LnNjYWxlKHRoaXMuc2NhbGUsIHRoaXMuc2NhbGUpO1xyXG4gICAgdGhpcy5jdHguZmlsbFN0eWxlID0gJ3doaXRlJztcclxuICAgIHRoaXMuY3R4LmZpbGxSZWN0KDAsIDAsIHRoaXMuY2FudmFzLndpZHRoLCB0aGlzLmNhbnZhcy5oZWlnaHQpO1xyXG5cclxuICB9XHJcblxyXG4gIGRyYXdQb2x5Z29uKHBvbHlnb24gPSB0aGlzLmxheW91dFBvbHlnb24pIHtcclxuICAgIGlmIChwb2x5Z29uLmxlbmd0aCA8IDEpIHJldHVybjsgLy8gSWYgdGhlIHBvbHlnb24gaGFzIG5vIGVkZ2VzLCBleGl0IGVhcmx5LlxyXG5cclxuICAgIHRoaXMuY3R4LnNhdmUoKTsgLy8gU2F2ZSB0aGUgY3VycmVudCBjYW52YXMgc3RhdGUuXHJcbiAgICB0aGlzLmN0eC5zY2FsZSh0aGlzLnNjYWxlLCB0aGlzLnNjYWxlKTsgLy8gU2NhbGUgdGhlIGNhbnZhcyBjb250ZXh0IHRvIG1hdGNoIHRoZSBkZXNpcmVkIHNjYWxlLlxyXG4gICAgLy8gdGhpcy5jdHgudHJhbnNsYXRlKHRoaXMucGFuT2Zmc2V0LngsIHRoaXMucGFuT2Zmc2V0LnkpO1xyXG5cclxuXHJcbiAgICAvLyBGdW5jdGlvbiB0byBkcmF3IGFuIGFycm93aGVhZCBhdCBhIHNwZWNpZmljIGxvY2F0aW9uIGFuZCBhbmdsZS5cclxuICAgIGZ1bmN0aW9uIGRyYXdBcnJvd2hlYWQoY3R4OiBhbnksIHg6IGFueSwgeTogYW55LCBhbmdsZTogYW55KSB7XHJcbiAgICAgIGNvbnN0IHNpemUgPSA1OyAvLyBEZWZpbmUgdGhlIHNpemUgb2YgdGhlIGFycm93aGVhZC5cclxuICAgICAgY3R4LnNhdmUoKTsgLy8gU2F2ZSB0aGUgY3VycmVudCBjYW52YXMgc3RhdGUuXHJcbiAgICAgIGN0eC50cmFuc2xhdGUoeCwgeSk7IC8vIE1vdmUgdGhlIGNvbnRleHQgdG8gdGhlIGFycm93aGVhZCBwb3NpdGlvbi5cclxuICAgICAgY3R4LnJvdGF0ZShhbmdsZSk7IC8vIFJvdGF0ZSB0aGUgY29udGV4dCB0byBtYXRjaCB0aGUgYXJyb3cncyBhbmdsZS5cclxuICAgICAgY3R4LmJlZ2luUGF0aCgpOyAvLyBTdGFydCBhIG5ldyBwYXRoLlxyXG4gICAgICBjdHgubW92ZVRvKDAsIDApOyAvLyBNb3ZlIHRvIHRoZSB0aXAgb2YgdGhlIGFycm93aGVhZC5cclxuICAgICAgY3R4LmxpbmVUbygtc2l6ZSwgLXNpemUgLyAyKTsgLy8gRHJhdyBvbmUgc2lkZSBvZiB0aGUgYXJyb3doZWFkLlxyXG4gICAgICBjdHgubGluZVRvKC1zaXplLCBzaXplIC8gMik7IC8vIERyYXcgdGhlIG90aGVyIHNpZGUgb2YgdGhlIGFycm93aGVhZC5cclxuICAgICAgY3R4LmNsb3NlUGF0aCgpOyAvLyBDbG9zZSB0aGUgYXJyb3doZWFkIHBhdGguXHJcbiAgICAgIGN0eC5maWxsU3R5bGUgPSAnYmxhY2snOyAvLyBTZXQgdGhlIGFycm93aGVhZCBjb2xvci5cclxuICAgICAgY3R4LmZpbGwoKTsgLy8gRmlsbCB0aGUgYXJyb3doZWFkLlxyXG4gICAgICBjdHgucmVzdG9yZSgpOyAvLyBSZXN0b3JlIHRoZSBwcmV2aW91cyBjYW52YXMgc3RhdGUuXHJcbiAgICB9XHJcblxyXG4gICAgdGhpcy5jdHguYmVnaW5QYXRoKCk7IC8vIEJlZ2luIHRoZSBtYWluIHBvbHlnb24gcGF0aC5cclxuICAgIHBvbHlnb24uZm9yRWFjaCgoZWRnZSwgZWRnZUluZGV4KSA9PiB7XHJcbiAgICAgIGNvbnN0IHBvaW50ID0gZWRnZVswXTsgLy8gU3RhcnRpbmcgcG9pbnQgb2YgdGhlIGVkZ2UuXHJcbiAgICAgIGNvbnN0IG5leHRQb2ludCA9IGVkZ2VbMV07IC8vIEVuZGluZyBwb2ludCBvZiB0aGUgZWRnZS5cclxuICAgICAgY29uc3QgcHJvcGVydGllcyA9IGVkZ2VbMl07IC8vIFByb3BlcnRpZXMgb2YgdGhlIGVkZ2UgKGUuZy4sIGxhYmVscywgZGlzdGFuY2VzKS5cclxuXHJcbiAgICAgIC8vIERyYXcgdGhlIG1haW4gcG9seWdvbiBlZGdlLlxyXG4gICAgICBpZiAoZWRnZUluZGV4ID09PSAwKSB0aGlzLmN0eC5tb3ZlVG8ocG9pbnQueCwgcG9pbnQueSk7IC8vIE1vdmUgdG8gdGhlIGZpcnN0IGVkZ2Ugc3RhcnRpbmcgcG9pbnQuXHJcbiAgICAgIHRoaXMuY3R4LmxpbmVUbyhuZXh0UG9pbnQueCwgbmV4dFBvaW50LnkpOyAvLyBEcmF3IGEgbGluZSB0byB0aGUgbmV4dCBwb2ludC5cclxuXHJcbiAgICAgIC8vIENhbGN1bGF0ZSB0aGUgcGVycGVuZGljdWxhciBvZmZzZXQgZm9yIHRoZSBib3VuZGluZyBib3guXHJcbiAgICAgIGNvbnN0IGR4ID0gbmV4dFBvaW50LnggLSBwb2ludC54OyAvLyBYLWRpZmZlcmVuY2UgYmV0d2VlbiBzdGFydCBhbmQgZW5kIHBvaW50cy5cclxuICAgICAgY29uc3QgZHkgPSBuZXh0UG9pbnQueSAtIHBvaW50Lnk7IC8vIFktZGlmZmVyZW5jZSBiZXR3ZWVuIHN0YXJ0IGFuZCBlbmQgcG9pbnRzLlxyXG4gICAgICBjb25zdCBsZW5ndGggPSBNYXRoLnNxcnQoZHggKiBkeCArIGR5ICogZHkpOyAvLyBMZW5ndGggb2YgdGhlIGVkZ2UuXHJcbiAgICAgIGNvbnN0IG9mZnNldFggPSAoZHkgLyBsZW5ndGgpICogMjA7IC8vIE9mZnNldCBpbiB0aGUgWCBkaXJlY3Rpb24uXHJcbiAgICAgIGNvbnN0IG9mZnNldFkgPSAoLWR4IC8gbGVuZ3RoKSAqIDIwOyAvLyBPZmZzZXQgaW4gdGhlIFkgZGlyZWN0aW9uLlxyXG5cclxuICAgICAgLy8gRGVmaW5lIHRoZSBib3VuZGluZyBib3ggcG9pbnRzLlxyXG4gICAgICBjb25zdCBib3hQb2ludHMgPSBbXHJcbiAgICAgICAgeyB4OiBwb2ludC54LCB5OiBwb2ludC55IH0sXHJcbiAgICAgICAgeyB4OiBuZXh0UG9pbnQueCwgeTogbmV4dFBvaW50LnkgfSxcclxuICAgICAgICB7IHg6IG5leHRQb2ludC54ICsgb2Zmc2V0WCwgeTogbmV4dFBvaW50LnkgKyBvZmZzZXRZIH0sXHJcbiAgICAgICAgeyB4OiBwb2ludC54ICsgb2Zmc2V0WCwgeTogcG9pbnQueSArIG9mZnNldFkgfSxcclxuICAgICAgXTtcclxuXHJcbiAgICAgIC8vIERyYXcgdGhlIGJvdW5kaW5nIGJveC5cclxuICAgICAgdGhpcy5jdHguYmVnaW5QYXRoKCk7XHJcbiAgICAgIHRoaXMuY3R4Lm1vdmVUbyhib3hQb2ludHNbMF0ueCwgYm94UG9pbnRzWzBdLnkpO1xyXG4gICAgICBib3hQb2ludHMuZm9yRWFjaCgocHQsIGluZGV4KSA9PiB7XHJcbiAgICAgICAgaWYgKHByb3BlcnRpZXMuZWxlbWVudFR5cGUgPT09ICdlbnRyYW5jZScpIHtcclxuICAgICAgICAgIGlmIChpbmRleCA8IDIpIHtcclxuICAgICAgICAgICAgdGhpcy5jdHgubGluZVRvKHB0LngsIHB0LnkpXHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgIHRoaXMuY3R4LmxpbmVUbyhwdC54LCBwdC55KTsgLy8gRHJhdyBlYWNoIGVkZ2Ugb2YgdGhlIGJveC5cclxuICAgICAgICB9XHJcbiAgICAgIH0pO1xyXG4gICAgICBpZiAocHJvcGVydGllcy5lbGVtZW50VHlwZSA9PT0gJ29wZW5pbmcnKSB7XHJcbiAgICAgICAgdGhpcy5jdHguY2xvc2VQYXRoKCk7IC8vIENsb3NlIHRoZSBib3VuZGluZyBib3ggcGF0aC5cclxuICAgICAgICB0aGlzLmN0eC5maWxsU3R5bGUgPSAnI0Y5RkFGQic7IC8vIFNldCBhIHRyYW5zbHVjZW50IGZpbGwgY29sb3IuXHJcbiAgICAgICAgdGhpcy5jdHguZmlsbCgpOyAvLyBGaWxsIHRoZSBib3VuZGluZyBib3guXHJcblxyXG4gICAgICAgIHRoaXMuY3R4LnN0cm9rZVN0eWxlID0gJyNGOUZBRkInXHJcblxyXG4gICAgICAgIHRoaXMuY3R4LnN0cm9rZSgpOyAvLyBEcmF3IHRoZSBib3VuZGluZyBib3ggYm9yZGVyLiBcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICB0aGlzLmN0eC5jbG9zZVBhdGgoKTsgLy8gQ2xvc2UgdGhlIGJvdW5kaW5nIGJveCBwYXRoLlxyXG4gICAgICAgIHRoaXMuY3R4LmZpbGxTdHlsZSA9ICcjRjlGQUZCJzsgLy8gU2V0IGEgdHJhbnNsdWNlbnQgZmlsbCBjb2xvci5cclxuICAgICAgICB0aGlzLmN0eC5maWxsKCk7IC8vIEZpbGwgdGhlIGJvdW5kaW5nIGJveC5cclxuICAgICAgICB0aGlzLmN0eC5zdHJva2VTdHlsZSA9ICcjMUQyOTM5J1xyXG4gICAgICAgIHRoaXMuY3R4LnN0cm9rZSgpOyAvLyBEcmF3IHRoZSBib3VuZGluZyBib3ggYm9yZGVyLiBcclxuICAgICAgfVxyXG5cclxuXHJcbiAgICAgIC8vIFBvc2l0aW9uIHRleHQgaW4gdGhlIG1pZGRsZSBvZiB0aGUgYm91bmRpbmcgYm94LlxyXG4gICAgICBjb25zdCB0ZXh0WCA9IChib3hQb2ludHNbMV0ueCArIGJveFBvaW50c1szXS54KSAvIDI7XHJcbiAgICAgIGNvbnN0IHRleHRZID0gKGJveFBvaW50c1sxXS55ICsgYm94UG9pbnRzWzNdLnkpIC8gMjtcclxuXHJcbiAgICAgIHRoaXMuY3R4LnNhdmUoKTsgLy8gU2F2ZSB0aGUgY3VycmVudCBjYW52YXMgc3RhdGUuXHJcbiAgICAgIHRoaXMuY3R4LnRyYW5zbGF0ZSh0ZXh0WCwgdGV4dFkpOyAvLyBNb3ZlIHRoZSBjb250ZXh0IHRvIHRoZSB0ZXh0IHBvc2l0aW9uLlxyXG5cclxuICAgICAgLy8gUm90YXRlIHRleHQgYmFzZWQgb24gdGhlIGVkZ2UgZGlyZWN0aW9uLlxyXG4gICAgICBpZiAoZHggPT09IDApIHtcclxuICAgICAgICB0aGlzLmN0eC5yb3RhdGUoLU1hdGguUEkgLyAyKTsgLy8gUm90YXRlIGZvciB2ZXJ0aWNhbCBlZGdlcy5cclxuICAgICAgfSBlbHNlIGlmIChkeSAhPT0gMCkge1xyXG4gICAgICAgIGNvbnN0IGFuZ2xlID0gTWF0aC5hdGFuMihkeSwgZHgpOyAvLyBDYWxjdWxhdGUgYW5nbGUgZm9yIGRpYWdvbmFsIGVkZ2VzLlxyXG4gICAgICAgIHRoaXMuY3R4LnJvdGF0ZShhbmdsZSk7IC8vIFJvdGF0ZSB0aGUgdGV4dCB0byBtYXRjaCB0aGUgYW5nbGUuXHJcbiAgICAgIH1cclxuXHJcbiAgICAgIC8vIERyYXcgdGhlIGVkZ2UgcHJvcGVydGllcyBhcyB0ZXh0LlxyXG4gICAgICB0aGlzLmN0eC5mb250ID0gJzEycHggQXJpYWwnOyAvLyBTZXQgdGhlIGZvbnQgc3R5bGUgYW5kIHNpemUuXHJcbiAgICAgIHRoaXMuY3R4LmZpbGxTdHlsZSA9ICdibGFjayc7IC8vIFNldCB0aGUgdGV4dCBjb2xvci5cclxuICAgICAgdGhpcy5jdHgudGV4dEFsaWduID0gJ2NlbnRlcic7IC8vIEFsaWduIHRleHQgdG8gdGhlIGNlbnRlci5cclxuICAgICAgdGhpcy5jdHgudGV4dEJhc2VsaW5lID0gJ21pZGRsZSc7IC8vIEFsaWduIHRleHQgdmVydGljYWxseSBpbiB0aGUgbWlkZGxlLlxyXG4gICAgICB0aGlzLmN0eC5maWxsVGV4dChcclxuICAgICAgICBgJHtwcm9wZXJ0aWVzLmVsZW1lbnRUeXBlfSAke3Byb3BlcnRpZXMuZWxlbWVudE51bWJlcn0gLSAke3Byb3BlcnRpZXMuZGlzdGFuY2V9ICR7cHJvcGVydGllcy51bml0fWAsXHJcbiAgICAgICAgMCxcclxuICAgICAgICAwXHJcbiAgICAgICk7XHJcbiAgICAgIHRoaXMuY3R4LnJlc3RvcmUoKTsgLy8gUmVzdG9yZSB0aGUgcHJldmlvdXMgY2FudmFzIHN0YXRlLlxyXG5cclxuICAgICAgaWYgKHByb3BlcnRpZXMuZGlzdGFuY2UgPj0gNCkge1xyXG4gICAgICAgIC8vIERlZmluZSB0aGUgbWlkcG9pbnRzIG9mIHRoZSBsZWZ0IGFuZCByaWdodCBlZGdlcyBvZiB0aGUgYm91bmRpbmcgYm94LlxyXG4gICAgICAgIGNvbnN0IGNlbnRlclggPSB0ZXh0WDtcclxuICAgICAgICBjb25zdCBjZW50ZXJZID0gdGV4dFk7XHJcbiAgICAgICAgY29uc3QgcmlnaHRYID0gKGJveFBvaW50c1sxXS54ICsgYm94UG9pbnRzWzJdLngpIC8gMjtcclxuICAgICAgICBjb25zdCByaWdodFkgPSAoYm94UG9pbnRzWzFdLnkgKyBib3hQb2ludHNbMl0ueSkgLyAyO1xyXG4gICAgICAgIGNvbnN0IGxlZnRYID0gKGJveFBvaW50c1swXS54ICsgYm94UG9pbnRzWzNdLngpIC8gMjtcclxuICAgICAgICBjb25zdCBsZWZ0WSA9IChib3hQb2ludHNbMF0ueSArIGJveFBvaW50c1szXS55KSAvIDI7XHJcblxyXG4gICAgICAgIC8vIEhlbHBlciBmdW5jdGlvbiB0byBhZGp1c3QgcG9pbnRzIGJ5IGEgc3BlY2lmaWMgZGlzdGFuY2UuXHJcbiAgICAgICAgZnVuY3Rpb24gYWRqdXN0UG9pbnQoeDE6IGFueSwgeTE6IGFueSwgeDI6IGFueSwgeTI6IGFueSwgZGlzdGFuY2U6IGFueSkge1xyXG4gICAgICAgICAgY29uc3QgYW5nbGUgPSBNYXRoLmF0YW4yKHkyIC0geTEsIHgyIC0geDEpOyAvLyBDYWxjdWxhdGUgdGhlIGFuZ2xlLlxyXG4gICAgICAgICAgcmV0dXJuIHtcclxuICAgICAgICAgICAgeDogeDEgKyBNYXRoLmNvcyhhbmdsZSkgKiBkaXN0YW5jZSwgLy8gQWRqdXN0IFggYnkgZGlzdGFuY2UuXHJcbiAgICAgICAgICAgIHk6IHkxICsgTWF0aC5zaW4oYW5nbGUpICogZGlzdGFuY2UsIC8vIEFkanVzdCBZIGJ5IGRpc3RhbmNlLlxyXG4gICAgICAgICAgfTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8vIERlZmluZSB0aGUgYXJyb3cgbGluZSBzdGFydCBhbmQgZW5kIHBvaW50cyBmb3IgdGhlIHJpZ2h0IHNpZGUuXHJcbiAgICAgICAgY29uc3QgcmlnaHRTdGFydCA9IGFkanVzdFBvaW50KGNlbnRlclgsIGNlbnRlclksIHJpZ2h0WCwgcmlnaHRZLCA1MCk7XHJcbiAgICAgICAgY29uc3QgcmlnaHRFbmQgPSBhZGp1c3RQb2ludChyaWdodFgsIHJpZ2h0WSwgY2VudGVyWCwgY2VudGVyWSwgMTApO1xyXG5cclxuICAgICAgICAvLyBEZWZpbmUgdGhlIGFycm93IGxpbmUgc3RhcnQgYW5kIGVuZCBwb2ludHMgZm9yIHRoZSBsZWZ0IHNpZGUuXHJcbiAgICAgICAgY29uc3QgbGVmdFN0YXJ0ID0gYWRqdXN0UG9pbnQoY2VudGVyWCwgY2VudGVyWSwgbGVmdFgsIGxlZnRZLCA1MCk7XHJcbiAgICAgICAgY29uc3QgbGVmdEVuZCA9IGFkanVzdFBvaW50KGxlZnRYLCBsZWZ0WSwgY2VudGVyWCwgY2VudGVyWSwgMTApO1xyXG5cclxuICAgICAgICAvLyBEcmF3IHRoZSByaWdodCBhcnJvdy5cclxuICAgICAgICB0aGlzLmN0eC5iZWdpblBhdGgoKTtcclxuICAgICAgICB0aGlzLmN0eC5tb3ZlVG8ocmlnaHRTdGFydC54LCByaWdodFN0YXJ0LnkpO1xyXG4gICAgICAgIHRoaXMuY3R4LmxpbmVUbyhyaWdodEVuZC54LCByaWdodEVuZC55KTtcclxuICAgICAgICB0aGlzLmN0eC5zdHJva2VTdHlsZSA9ICdibGFjayc7IC8vIFNldCB0aGUgYXJyb3cgbGluZSBjb2xvci5cclxuICAgICAgICB0aGlzLmN0eC5zdHJva2UoKTsgLy8gRHJhdyB0aGUgYXJyb3cgbGluZS5cclxuICAgICAgICBsZXQgcmlnaHRBbmdsZSA9IE1hdGguYXRhbjIocmlnaHRFbmQueSAtIHJpZ2h0U3RhcnQueSwgcmlnaHRFbmQueCAtIHJpZ2h0U3RhcnQueCk7XHJcbiAgICAgICAgZHJhd0Fycm93aGVhZCh0aGlzLmN0eCwgcmlnaHRFbmQueCwgcmlnaHRFbmQueSwgcmlnaHRBbmdsZSk7IC8vIERyYXcgdGhlIGFycm93aGVhZC5cclxuXHJcbiAgICAgICAgLy8gRHJhdyB0aGUgbGVmdCBhcnJvdy5cclxuICAgICAgICB0aGlzLmN0eC5iZWdpblBhdGgoKTtcclxuICAgICAgICB0aGlzLmN0eC5tb3ZlVG8obGVmdFN0YXJ0LngsIGxlZnRTdGFydC55KTtcclxuICAgICAgICB0aGlzLmN0eC5saW5lVG8obGVmdEVuZC54LCBsZWZ0RW5kLnkpO1xyXG4gICAgICAgIHRoaXMuY3R4LnN0cm9rZVN0eWxlID0gJ2JsYWNrJzsgLy8gU2V0IHRoZSBhcnJvdyBsaW5lIGNvbG9yLlxyXG4gICAgICAgIHRoaXMuY3R4LnN0cm9rZSgpOyAvLyBEcmF3IHRoZSBhcnJvdyBsaW5lLlxyXG4gICAgICAgIGxldCBsZWZ0QW5nbGUgPSBNYXRoLmF0YW4yKGxlZnRFbmQueSAtIGxlZnRTdGFydC55LCBsZWZ0RW5kLnggLSBsZWZ0U3RhcnQueCk7XHJcbiAgICAgICAgZHJhd0Fycm93aGVhZCh0aGlzLmN0eCwgbGVmdEVuZC54LCBsZWZ0RW5kLnksIGxlZnRBbmdsZSk7IC8vIERyYXcgdGhlIGFycm93aGVhZC5cclxuXHJcbiAgICAgIH1cclxuXHJcbiAgICAgIC8vIEZvciBFbnRyYW5jZVxyXG4gICAgICBpZiAocHJvcGVydGllcy5lbGVtZW50VHlwZSA9PT0gJ2VudHJhbmNlJykge1xyXG4gICAgICAgIC8vIENhbGN1bGF0ZSB0aGUgYW5nbGUgb2YgdGhlIG1haW4gbGluZSAoZWRnZSkgaW4gcmFkaWFucy5cclxuICAgICAgICBjb25zdCBhbmdsZSA9IE1hdGguYXRhbjIobmV4dFBvaW50LnkgLSBwb2ludC55LCBuZXh0UG9pbnQueCAtIHBvaW50LngpO1xyXG5cclxuICAgICAgICAvLyBBZGQgMTUgZGVncmVlcyB0byB0aGUgYW5nbGUgZm9yIHRoZSBlbnRyYW5jZSBsaW5lLlxyXG4gICAgICAgIGNvbnN0IGVudHJhbmNlQW5nbGUgPSBhbmdsZSArICgxNSAqIE1hdGguUEkpIC8gMTgwOyAvLyBDb252ZXJ0IDE1IGRlZ3JlZXMgdG8gcmFkaWFucy5cclxuXHJcbiAgICAgICAgLy8gRGVmaW5lIHRoZSBsZW5ndGggb2YgdGhlIGVudHJhbmNlIGxpbmUuXHJcbiAgICAgICAgY29uc3QgbGluZUxlbmd0aCA9IHRoaXMuY29udmVydFRvUGl4ZWxzKHByb3BlcnRpZXMuZGlzdGFuY2UsIHByb3BlcnRpZXMudW5pdCkgKiAwLjc1O1xyXG5cclxuICAgICAgICAvLyBDYWxjdWxhdGUgdGhlIGVuZHBvaW50IG9mIHRoZSBlbnRyYW5jZSBsaW5lIGJhc2VkIG9uIHRoZSBhbmdsZS5cclxuICAgICAgICBjb25zdCBlbmRQb2ludCA9IHtcclxuICAgICAgICAgIHg6IHBvaW50LnggKyBNYXRoLmNvcyhlbnRyYW5jZUFuZ2xlKSAqIGxpbmVMZW5ndGgsXHJcbiAgICAgICAgICB5OiBwb2ludC55ICsgTWF0aC5zaW4oZW50cmFuY2VBbmdsZSkgKiBsaW5lTGVuZ3RoLFxyXG4gICAgICAgIH07XHJcblxyXG4gICAgICAgIC8vIERyYXcgdGhlIGVudHJhbmNlIGxpbmUuXHJcbiAgICAgICAgdGhpcy5jdHguYmVnaW5QYXRoKCk7XHJcbiAgICAgICAgdGhpcy5jdHgubW92ZVRvKHBvaW50LngsIHBvaW50LnkpO1xyXG4gICAgICAgIHRoaXMuY3R4LmxpbmVUbyhlbmRQb2ludC54LCBlbmRQb2ludC55KTtcclxuICAgICAgICB0aGlzLmN0eC5zdHJva2VTdHlsZSA9ICcjMUQyOTM5J1xyXG4gICAgICAgIHRoaXMuY3R4LnN0cm9rZSgpO1xyXG4gICAgICB9XHJcblxyXG5cclxuICAgIH0pO1xyXG5cclxuICAgIHRoaXMuY3R4LnJlc3RvcmUoKTsgLy8gUmVzdG9yZSB0aGUgb3JpZ2luYWwgY2FudmFzIHN0YXRlLlxyXG4gIH1cclxuXHJcbiAgem9vbUluKCk6IHZvaWQge1xyXG4gICAgdGhpcy5zY2FsZSAqPSAxLjE7XHJcbiAgICB0aGlzLnJlZHJhd0NhbnZhcygpO1xyXG4gIH1cclxuXHJcbiAgem9vbU91dCgpOiB2b2lkIHtcclxuICAgIHRoaXMuc2NhbGUgLz0gMS4xO1xyXG4gICAgdGhpcy5yZWRyYXdDYW52YXMoKTtcclxuICB9XHJcblxyXG4gIHJlZHJhd0NhbnZhcygpOiB2b2lkIHtcclxuICAgIHRoaXMuZHJhd0dyaWQoKTtcclxuICAgIHRoaXMuZHJhd1BvbHlnb24oKTtcclxuICB9XHJcblxyXG5cclxuXHJcbiAgc25hcFRvR3JpZCh2YWx1ZTogbnVtYmVyLCBncmlkU2l6ZTogbnVtYmVyKTogbnVtYmVyIHtcclxuICAgIHJldHVybiBNYXRoLnJvdW5kKHZhbHVlIC8gZ3JpZFNpemUpICogZ3JpZFNpemU7XHJcbiAgfVxyXG5cclxuXHJcbiAgcm90YXRlUG9seWdvbnMoKTogdm9pZCB7XHJcbiAgICBjb25zdCByb3RhdGVQb2ludCA9IChwb2ludDogeyB4OiBudW1iZXI7IHk6IG51bWJlciB9LCBjZW50ZXI6IHsgeDogbnVtYmVyOyB5OiBudW1iZXIgfSk6IHsgeDogbnVtYmVyOyB5OiBudW1iZXIgfSA9PiB7XHJcbiAgICAgIGNvbnN0IGR4ID0gcG9pbnQueCAtIGNlbnRlci54O1xyXG4gICAgICBjb25zdCBkeSA9IHBvaW50LnkgLSBjZW50ZXIueTtcclxuICAgICAgcmV0dXJuIHsgeDogY2VudGVyLnggLSBkeSwgeTogY2VudGVyLnkgKyBkeCB9O1xyXG4gICAgfTtcclxuXHJcbiAgICBjb25zdCBnZXRQb2x5Z29uTGluZUNlbnRlciA9IChsaW5lOiBhbnlbXSk6IHsgeDogbnVtYmVyOyB5OiBudW1iZXIgfSA9PiB7XHJcbiAgICAgIGNvbnN0IFtzdGFydCwgZW5kXSA9IGxpbmU7XHJcbiAgICAgIHJldHVybiB7XHJcbiAgICAgICAgeDogKHN0YXJ0LnggKyBlbmQueCkgLyAyLFxyXG4gICAgICAgIHk6IChzdGFydC55ICsgZW5kLnkpIC8gMixcclxuICAgICAgfTtcclxuICAgIH07XHJcblxyXG4gICAgY29uc3QgZ2V0T3ZlcmFsbENlbnRlciA9IChsaW5lczogYW55W10pOiB7IHg6IG51bWJlcjsgeTogbnVtYmVyIH0gPT4ge1xyXG4gICAgICBjb25zdCBzdW0gPSBsaW5lcy5yZWR1Y2UoXHJcbiAgICAgICAgKGFjYywgbGluZSkgPT4ge1xyXG4gICAgICAgICAgY29uc3QgY2VudGVyID0gZ2V0UG9seWdvbkxpbmVDZW50ZXIobGluZSk7XHJcbiAgICAgICAgICBhY2MueCArPSBjZW50ZXIueDtcclxuICAgICAgICAgIGFjYy55ICs9IGNlbnRlci55O1xyXG4gICAgICAgICAgcmV0dXJuIGFjYztcclxuICAgICAgICB9LFxyXG4gICAgICAgIHsgeDogMCwgeTogMCB9XHJcbiAgICAgICk7XHJcblxyXG4gICAgICByZXR1cm4geyB4OiBzdW0ueCAvIGxpbmVzLmxlbmd0aCwgeTogc3VtLnkgLyBsaW5lcy5sZW5ndGggfTtcclxuICAgIH07XHJcblxyXG4gICAgY29uc3Qgb3ZlcmFsbENlbnRlciA9IGdldE92ZXJhbGxDZW50ZXIodGhpcy5sYXlvdXRQb2x5Z29uKTtcclxuXHJcbiAgICB0aGlzLmxheW91dFBvbHlnb24gPSB0aGlzLmxheW91dFBvbHlnb24ubWFwKChsaW5lKSA9PiB7XHJcbiAgICAgIGNvbnN0IFtzdGFydCwgZW5kLCBwcm9wZXJ0aWVzXSA9IGxpbmU7XHJcbiAgICAgIHJldHVybiBbXHJcbiAgICAgICAgcm90YXRlUG9pbnQoc3RhcnQsIG92ZXJhbGxDZW50ZXIpLFxyXG4gICAgICAgIHJvdGF0ZVBvaW50KGVuZCwgb3ZlcmFsbENlbnRlciksXHJcbiAgICAgICAgcHJvcGVydGllc1xyXG4gICAgICBdO1xyXG4gICAgfSk7XHJcblxyXG5cclxuICAgIHRoaXMuZHJhd0dyaWQoKTtcclxuICAgIHRoaXMuZHJhd1BvbHlnb24oKTtcclxuICB9XHJcblxyXG4gIGNvbnZlcnRUb1BpeGVscyh2YWx1ZTogbnVtYmVyLCB1bml0OiAnZnQnIHwgJ20nKTogbnVtYmVyIHtcclxuICAgIGNvbnN0IFBJWEVMU19QRVJfTUVURVIgPSB0aGlzLnBpeGVsUGVyTWV0cmU7XHJcbiAgICBjb25zdCBQSVhFTFNfUEVSX0ZPT1QgPSBQSVhFTFNfUEVSX01FVEVSIC8gMy4yODA4NDtcclxuXHJcbiAgICBpZiAodHlwZW9mIHZhbHVlICE9PSAnbnVtYmVyJyB8fCB2YWx1ZSA8IDApIHtcclxuICAgICAgdGhyb3cgbmV3IEVycm9yKCdWYWx1ZSBtdXN0IGJlIGEgbm9uLW5lZ2F0aXZlIG51bWJlcicpO1xyXG4gICAgfVxyXG5cclxuICAgIHN3aXRjaCAodW5pdCkge1xyXG4gICAgICBjYXNlICdtJzpcclxuICAgICAgICByZXR1cm4gdmFsdWUgKiBQSVhFTFNfUEVSX01FVEVSO1xyXG4gICAgICBjYXNlICdmdCc6XHJcbiAgICAgICAgcmV0dXJuIHZhbHVlICogUElYRUxTX1BFUl9GT09UO1xyXG4gICAgICBkZWZhdWx0OlxyXG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcIkludmFsaWQgdW5pdC4gU3VwcG9ydGVkIHVuaXRzIGFyZSAnbXQnIGZvciBtZXRlcnMgYW5kICdmdCcgZm9yIGZlZXQuXCIpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcblxyXG4gIHNjcm9sbFRvQ2FudmFzUG9zaXRpb24oY29vcmRpbmF0ZXM6IHsgeDogbnVtYmVyOyB5OiBudW1iZXIgfSk6IHZvaWQge1xyXG4gICAgY29uc3QgY29udGFpbmVyID0gdGhpcy5zY3JvbGxDb250YWluZXJSZWYubmF0aXZlRWxlbWVudDtcclxuXHJcbiAgICBjb25zdCBjb250YWluZXJSZWN0ID0gY29udGFpbmVyLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xyXG4gICAgY29uc3QgY29udGFpbmVyU2Nyb2xsTGVmdCA9IGNvbnRhaW5lci5zY3JvbGxMZWZ0O1xyXG4gICAgY29uc3QgY29udGFpbmVyU2Nyb2xsVG9wID0gY29udGFpbmVyLnNjcm9sbFRvcDtcclxuXHJcbiAgICBjb25zdCB0YXJnZXRYID0gY29vcmRpbmF0ZXMueDtcclxuICAgIGNvbnN0IHRhcmdldFkgPSBjb29yZGluYXRlcy55O1xyXG5cclxuICAgIGNvbnN0IG9mZnNldCA9IHtcclxuICAgICAgdXA6IDUwLFxyXG4gICAgICBkb3duOiAyMDAsXHJcbiAgICAgIGxlZnQ6IDEwMCxcclxuICAgICAgcmlnaHQ6IDEwMCxcclxuICAgIH07XHJcblxyXG4gICAgY29uc3QgdmlzaWJsZUxlZnQgPSBjb250YWluZXJTY3JvbGxMZWZ0ICsgb2Zmc2V0LmxlZnQ7XHJcbiAgICBjb25zdCB2aXNpYmxlUmlnaHQgPSBjb250YWluZXJTY3JvbGxMZWZ0ICsgY29udGFpbmVyUmVjdC53aWR0aCAtIG9mZnNldC5yaWdodDtcclxuICAgIGNvbnN0IHZpc2libGVUb3AgPSBjb250YWluZXJTY3JvbGxUb3AgKyBvZmZzZXQudXA7XHJcbiAgICBjb25zdCB2aXNpYmxlQm90dG9tID0gY29udGFpbmVyU2Nyb2xsVG9wICsgY29udGFpbmVyUmVjdC5oZWlnaHQgLSBvZmZzZXQuZG93bjtcclxuXHJcbiAgICBjb25zdCBpc1hJblZpZXcgPSB0YXJnZXRYID49IHZpc2libGVMZWZ0ICYmIHRhcmdldFggPD0gdmlzaWJsZVJpZ2h0O1xyXG4gICAgY29uc3QgaXNZSW5WaWV3ID0gdGFyZ2V0WSA+PSB2aXNpYmxlVG9wICYmIHRhcmdldFkgPD0gdmlzaWJsZUJvdHRvbTtcclxuXHJcbiAgICBpZiAoIWlzWEluVmlldyB8fCAhaXNZSW5WaWV3KSB7XHJcbiAgICAgIGNvbnN0IGFkanVzdGVkWCA9IE1hdGgubWF4KDAsIHRhcmdldFggLSBvZmZzZXQubGVmdCk7XHJcbiAgICAgIGNvbnN0IGFkanVzdGVkWSA9IE1hdGgubWF4KDAsIHRhcmdldFkgLSBvZmZzZXQudXApO1xyXG5cclxuICAgICAgY29udGFpbmVyLnNjcm9sbFRvKHtcclxuICAgICAgICBsZWZ0OiBhZGp1c3RlZFgsXHJcbiAgICAgICAgdG9wOiBhZGp1c3RlZFksXHJcbiAgICAgICAgYmVoYXZpb3I6ICdzbW9vdGgnLFxyXG4gICAgICB9KTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIGNhbGN1bGF0ZVBvbHlnb25BcmVhKGVsZW1lbnRzOiBhbnlbXSk6IG51bWJlciB7XHJcbiAgICBjb25zdCB2ZXJ0aWNlczogeyB4OiBudW1iZXI7IHk6IG51bWJlciB9W10gPSBbXTtcclxuICAgIGNvbnN0IGNlbnRlclggPSAwOyAvLyBBc3N1bWluZyAoMCwwKSBhcyB0aGUgc3RhcnRpbmcgcG9pbnQgZm9yIGNhbGN1bGF0aW9uXHJcbiAgICBjb25zdCBjZW50ZXJZID0gMDtcclxuICAgIGxldCBjdXJyZW50UG9pbnQgPSB7IHg6IGNlbnRlclgsIHk6IGNlbnRlclkgfTtcclxuXHJcbiAgICBjb25zdCBjb252ZXJzaW9uRmFjdG9yID0gNTA7IC8vIFBpeGVscyBwZXIgZm9vdCAoYWRqdXN0IGFzIG5lZWRlZClcclxuXHJcbiAgICAvLyBDb21wdXRlIHZlcnRpY2VzIGJhc2VkIG9uIGxheW91dCBpbnN0cnVjdGlvbnNcclxuICAgIGZvciAoY29uc3QgZWxlbWVudCBvZiBlbGVtZW50cykge1xyXG4gICAgICBjb25zdCByYWRpYW5zOiBudW1iZXIgPSB7XHJcbiAgICAgICAgdXA6ICgoMTgwIC0gZWxlbWVudC5hbmdsZSkgKiBNYXRoLlBJKSAvIDE4MCxcclxuICAgICAgICBsZWZ0OiAoKDI3MCAtIGVsZW1lbnQuYW5nbGUpICogTWF0aC5QSSkgLyAxODAsXHJcbiAgICAgICAgZG93bjogKCgzNjAgLSBlbGVtZW50LmFuZ2xlKSAqIE1hdGguUEkpIC8gMTgwLFxyXG4gICAgICAgIHJpZ2h0OiAoKDkwIC0gZWxlbWVudC5hbmdsZSkgKiBNYXRoLlBJKSAvIDE4MCxcclxuICAgICAgfVtlbGVtZW50LmRpcmVjdGlvbiBhcyAndXAnIHwgJ2xlZnQnIHwgJ2Rvd24nIHwgJ3JpZ2h0J107XHJcblxyXG4gICAgICBpZiAocmFkaWFucyA9PT0gdW5kZWZpbmVkKSB7XHJcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBJbnZhbGlkIGRpcmVjdGlvbjogJHtlbGVtZW50LmRpcmVjdGlvbn1gKTtcclxuICAgICAgfVxyXG5cclxuICAgICAgY29uc3QgZGlzdGFuY2VJblBpeGVscyA9IGVsZW1lbnQuZGlzdGFuY2UgKiBjb252ZXJzaW9uRmFjdG9yO1xyXG4gICAgICBjb25zdCBuZXdYID0gY3VycmVudFBvaW50LnggKyBNYXRoLmNvcyhyYWRpYW5zKSAqIGRpc3RhbmNlSW5QaXhlbHM7XHJcbiAgICAgIGNvbnN0IG5ld1kgPSBjdXJyZW50UG9pbnQueSAtIE1hdGguc2luKHJhZGlhbnMpICogZGlzdGFuY2VJblBpeGVscztcclxuXHJcbiAgICAgIHZlcnRpY2VzLnB1c2goeyB4OiBjdXJyZW50UG9pbnQueCwgeTogY3VycmVudFBvaW50LnkgfSk7XHJcblxyXG4gICAgICBjdXJyZW50UG9pbnQgPSB7XHJcbiAgICAgICAgeDogdGhpcy5zbmFwVG9HcmlkKG5ld1gsIHRoaXMuZ3JpZFdpZHRoKSxcclxuICAgICAgICB5OiB0aGlzLnNuYXBUb0dyaWQobmV3WSwgdGhpcy5ncmlkSGVpZ2h0KSxcclxuICAgICAgfTtcclxuICAgIH1cclxuXHJcbiAgICAvLyBDbG9zZSB0aGUgcG9seWdvbiBieSBhZGRpbmcgdGhlIHN0YXJ0aW5nIHZlcnRleCBhdCB0aGUgZW5kXHJcbiAgICB2ZXJ0aWNlcy5wdXNoKHZlcnRpY2VzWzBdKTtcclxuXHJcbiAgICAvLyBBcHBseSB0aGUgU2hvZWxhY2UgZm9ybXVsYVxyXG4gICAgbGV0IGFyZWFJblBpeGVscyA9IDA7XHJcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHZlcnRpY2VzLmxlbmd0aCAtIDE7IGkrKykge1xyXG4gICAgICBjb25zdCB4MSA9IHZlcnRpY2VzW2ldLng7XHJcbiAgICAgIGNvbnN0IHkxID0gdmVydGljZXNbaV0ueTtcclxuICAgICAgY29uc3QgeDIgPSB2ZXJ0aWNlc1tpICsgMV0ueDtcclxuICAgICAgY29uc3QgeTIgPSB2ZXJ0aWNlc1tpICsgMV0ueTtcclxuICAgICAgYXJlYUluUGl4ZWxzICs9IHgxICogeTIgLSB5MSAqIHgyO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIENvbnZlcnQgYXJlYSBmcm9tIHBpeGVsc8KyIHRvIGZlZXTCslxyXG4gICAgY29uc3QgYXJlYUluU3F1YXJlRmVldCA9IE1hdGguYWJzKGFyZWFJblBpeGVscyAvIDIpIC8gKGNvbnZlcnNpb25GYWN0b3IgKiBjb252ZXJzaW9uRmFjdG9yKTtcclxuXHJcbiAgICByZXR1cm4gTWF0aC5yb3VuZChhcmVhSW5TcXVhcmVGZWV0KTsgLy8gUmV0dXJuIHRoZSBhcmVhIGluIHNxdWFyZSBmZWV0XHJcbiAgfVxyXG5cclxuXHJcblxyXG5cclxuICBnZW5lcmF0ZUxheW91dFBvbHlnb24obGF5b3V0SW5zdHJ1Y3Rpb25zOiBhbnkpIHtcclxuXHJcbiAgICB0aGlzLnBpeGVsUGVyTWV0cmUgPSB0aGlzLm5vcm1hbGl6ZWRQaXhlbFBlck1ldHJlKGxheW91dEluc3RydWN0aW9ucylcclxuXHJcbiAgICB0aGlzLndhbGxDYXBhY2l0eSA9IGxheW91dEluc3RydWN0aW9ucy5yZWR1Y2UoKGFjYzogYW55LCB2YWw6IGFueSkgPT4ge1xyXG4gICAgICBpZiAodmFsLmVsZW1lbnRUeXBlID09PSAnd2FsbCcpIHtcclxuICAgICAgICByZXR1cm4gYWNjICs9IHZhbC5kaXN0YW5jZVxyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIHJldHVybiBhY2NcclxuICAgICAgfVxyXG4gICAgfSwgMClcclxuICAgIHRoaXMuZmFjYWRlQ2FwYWNpdHkgPSBsYXlvdXRJbnN0cnVjdGlvbnMucmVkdWNlKChhY2M6IGFueSwgdmFsOiBhbnkpID0+IHtcclxuICAgICAgaWYgKHZhbC5lbGVtZW50VHlwZSA9PT0gJ2ZhY2FkZScpIHtcclxuICAgICAgICByZXR1cm4gYWNjICs9IHZhbC5kaXN0YW5jZVxyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIHJldHVybiBhY2NcclxuICAgICAgfVxyXG4gICAgfSwgMClcclxuXHJcbiAgICB0aGlzLmZsb29yQ2FwYWNpdHkgPSB0aGlzLmNhbGN1bGF0ZVBvbHlnb25BcmVhKGxheW91dEluc3RydWN0aW9ucylcclxuXHJcbiAgICB0aGlzLmxheW91dFBvbHlnb24gPSBbXTtcclxuXHJcbiAgICBjb25zdCBjZW50ZXJYID0gdGhpcy5jYW52YXMud2lkdGggLyAyIC8gdGhpcy5zY2FsZTtcclxuICAgIGNvbnN0IGNlbnRlclkgPSB0aGlzLmNhbnZhcy5oZWlnaHQgLyAyIC8gdGhpcy5zY2FsZTtcclxuXHJcbiAgICBsZXQgY3VycmVudFBvaW50ID0ge1xyXG4gICAgICBcInhcIjogdGhpcy5zbmFwVG9HcmlkKGNlbnRlclgsIHRoaXMuZ3JpZEhlaWdodCksXHJcbiAgICAgIFwieVwiOiB0aGlzLnNuYXBUb0dyaWQoY2VudGVyWSwgdGhpcy5ncmlkV2lkdGgpXHJcbiAgICB9O1xyXG5cclxuICAgIGlmICghbGF5b3V0SW5zdHJ1Y3Rpb25zLmxlbmd0aCkge1xyXG5cclxuICAgICAgdGhpcy5sYXlvdXRQb2x5Z29uID0gW1xyXG4gICAgICAgIFtcclxuICAgICAgICAgIHtcclxuICAgICAgICAgICAgXCJ4XCI6IHRoaXMuc25hcFRvR3JpZChjZW50ZXJYLCB0aGlzLmdyaWRIZWlnaHQpLFxyXG4gICAgICAgICAgICBcInlcIjogdGhpcy5zbmFwVG9HcmlkKGNlbnRlclksIHRoaXMuZ3JpZFdpZHRoKVxyXG4gICAgICAgICAgfSxcclxuICAgICAgICAgIHtcclxuICAgICAgICAgICAgXCJ4XCI6IHRoaXMuc25hcFRvR3JpZChjZW50ZXJYLCB0aGlzLmdyaWRIZWlnaHQpLFxyXG4gICAgICAgICAgICBcInlcIjogdGhpcy5zbmFwVG9HcmlkKGNlbnRlclksIHRoaXMuZ3JpZFdpZHRoKVxyXG4gICAgICAgICAgfSxcclxuICAgICAgICAgIHtcclxuICAgICAgICAgICAgXCJlbGVtZW50VHlwZVwiOiBcIndhbGxcIixcclxuICAgICAgICAgICAgXCJkaXN0YW5jZVwiOiAwLFxyXG4gICAgICAgICAgICBcInVuaXRcIjogXCJmdFwiLFxyXG4gICAgICAgICAgICBcImRpcmVjdGlvblwiOiBcInJpZ2h0XCIsXHJcbiAgICAgICAgICAgIFwiYW5nbGVcIjogOTAsXHJcbiAgICAgICAgICAgIFwiZWxlbWVudE51bWJlclwiOiAxXHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgXVxyXG4gICAgICBdXHJcbiAgICAgIHRoaXMub3BlbldpZGdldCh7IHg6IHRoaXMuc25hcFRvR3JpZChjZW50ZXJYLCB0aGlzLmdyaWRIZWlnaHQpLCB5OiB0aGlzLnNuYXBUb0dyaWQoY2VudGVyWSwgdGhpcy5ncmlkV2lkdGgpIH0pXHJcbiAgICAgIHRoaXMuZHJhd0dyaWQoKVxyXG4gICAgICB0aGlzLmRyYXdQb2x5Z29uKClcclxuICAgICAgcmV0dXJuXHJcbiAgICB9XHJcblxyXG4gICAgbGF5b3V0SW5zdHJ1Y3Rpb25zLmZvckVhY2goKGluc3RydWN0aW9uOiBhbnkpID0+IHtcclxuICAgICAgY29uc3QgcmFkaWFuczogbnVtYmVyID0ge1xyXG4gICAgICAgICd1cCc6ICgoMTgwIC0gaW5zdHJ1Y3Rpb24uYW5nbGUpICogTWF0aC5QSSkgLyAxODAsXHJcbiAgICAgICAgJ2xlZnQnOiAoKDI3MCAtIGluc3RydWN0aW9uLmFuZ2xlKSAqIE1hdGguUEkpIC8gMTgwLFxyXG4gICAgICAgICdkb3duJzogKCgzNjAgLSBpbnN0cnVjdGlvbi5hbmdsZSkgKiBNYXRoLlBJKSAvIDE4MCxcclxuICAgICAgICAncmlnaHQnOiAoKDkwIC0gaW5zdHJ1Y3Rpb24uYW5nbGUpICogTWF0aC5QSSkgLyAxODAsXHJcbiAgICAgIH1baW5zdHJ1Y3Rpb24uZGlyZWN0aW9uIGFzICd1cCcgfCAnbGVmdCcgfCAnZG93bicgfCAncmlnaHQnXTtcclxuXHJcbiAgICAgIGlmIChyYWRpYW5zID09PSB1bmRlZmluZWQpIHtcclxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYEludmFsaWQgZGlyZWN0aW9uOiAke2luc3RydWN0aW9uLmRpcmVjdGlvbn1gKTtcclxuICAgICAgfVxyXG5cclxuICAgICAgY29uc3QgZGlzdGFuY2VJblBpeGVscyA9IHRoaXMuY29udmVydFRvUGl4ZWxzKGluc3RydWN0aW9uLmRpc3RhbmNlLCBpbnN0cnVjdGlvbi51bml0KTtcclxuICAgICAgY29uc3QgbmV3WCA9IGN1cnJlbnRQb2ludC54ICsgTWF0aC5jb3MocmFkaWFucykgKiBkaXN0YW5jZUluUGl4ZWxzO1xyXG4gICAgICBjb25zdCBuZXdZID0gY3VycmVudFBvaW50LnkgLSBNYXRoLnNpbihyYWRpYW5zKSAqIGRpc3RhbmNlSW5QaXhlbHM7XHJcblxyXG4gICAgICBjb25zdCBuZXdQb2ludCA9IHtcclxuICAgICAgICB4OiB0aGlzLnNuYXBUb0dyaWQobmV3WCwgdGhpcy5ncmlkV2lkdGgpLFxyXG4gICAgICAgIHk6IHRoaXMuc25hcFRvR3JpZChuZXdZLCB0aGlzLmdyaWRIZWlnaHQpLFxyXG4gICAgICB9O1xyXG5cclxuICAgICAgY29uc3QgbGluZVNlZ21lbnQgPSBbXHJcbiAgICAgICAgY3VycmVudFBvaW50LFxyXG4gICAgICAgIG5ld1BvaW50LFxyXG4gICAgICAgIHtcclxuICAgICAgICAgIGVsZW1lbnRUeXBlOiBpbnN0cnVjdGlvbi5lbGVtZW50VHlwZSxcclxuICAgICAgICAgIGRpc3RhbmNlOiBpbnN0cnVjdGlvbi5kaXN0YW5jZSxcclxuICAgICAgICAgIHVuaXQ6IGluc3RydWN0aW9uLnVuaXQsXHJcbiAgICAgICAgICBkaXJlY3Rpb246IGluc3RydWN0aW9uLmRpcmVjdGlvbixcclxuICAgICAgICAgIGFuZ2xlOiBpbnN0cnVjdGlvbi5hbmdsZSxcclxuICAgICAgICAgIGVsZW1lbnROdW1iZXI6IGluc3RydWN0aW9uLmVsZW1lbnROdW1iZXIsXHJcbiAgICAgICAgfSxcclxuICAgICAgXTtcclxuXHJcbiAgICAgIHRoaXMubGF5b3V0UG9seWdvbi5wdXNoKGxpbmVTZWdtZW50KTtcclxuXHJcbiAgICAgIGN1cnJlbnRQb2ludCA9IG5ld1BvaW50O1xyXG4gICAgfSk7XHJcblxyXG4gICAgY29uc3QgbGFzdFBvaW50ID0gdGhpcy5sYXlvdXRQb2x5Z29uW3RoaXMubGF5b3V0UG9seWdvbi5sZW5ndGggLSAxXVsxXVxyXG5cclxuICAgIGlmICh0aGlzLmlzRmxvb3JDb21wbGV0ZWQobGF5b3V0SW5zdHJ1Y3Rpb25zKSkge1xyXG4gICAgICB0aGlzLmZpbmRQb2x5Z29uQ2VudGVyQW5kU2Nyb2xsKClcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHRoaXMub3BlbldpZGdldChsYXN0UG9pbnQpXHJcbiAgICB9XHJcblxyXG4gICAgdGhpcy5kcmF3R3JpZCgpXHJcbiAgICB0aGlzLmRyYXdQb2x5Z29uKClcclxuXHJcbiAgfVxyXG5cclxuICBpc0Zsb29yQ29tcGxldGVkKGxheW91dEluc3RydWN0aW9uczogYW55LCB0aHJlc2hvbGRJbkZlZXQ6IG51bWJlciA9IDEpOiBib29sZWFuIHtcclxuICAgIGNvbnN0IGxheW91dFBvbHlnb246IGFueVtdID0gW107XHJcbiAgICBjb25zdCBjZW50ZXJYID0gdGhpcy5jYW52YXMud2lkdGggLyAyIC8gdGhpcy5zY2FsZTtcclxuICAgIGNvbnN0IGNlbnRlclkgPSB0aGlzLmNhbnZhcy5oZWlnaHQgLyAyIC8gdGhpcy5zY2FsZTtcclxuXHJcbiAgICBsZXQgY3VycmVudFBvaW50ID0ge1xyXG4gICAgICB4OiB0aGlzLnNuYXBUb0dyaWQoY2VudGVyWCwgdGhpcy5ncmlkSGVpZ2h0KSxcclxuICAgICAgeTogdGhpcy5zbmFwVG9HcmlkKGNlbnRlclksIHRoaXMuZ3JpZFdpZHRoKSxcclxuICAgIH07XHJcblxyXG4gICAgbGF5b3V0SW5zdHJ1Y3Rpb25zLmZvckVhY2goKGluc3RydWN0aW9uOiBhbnkpID0+IHtcclxuICAgICAgY29uc3QgcmFkaWFuczogbnVtYmVyID0ge1xyXG4gICAgICAgICd1cCc6ICgoMTgwIC0gaW5zdHJ1Y3Rpb24uYW5nbGUpICogTWF0aC5QSSkgLyAxODAsXHJcbiAgICAgICAgJ2xlZnQnOiAoKDI3MCAtIGluc3RydWN0aW9uLmFuZ2xlKSAqIE1hdGguUEkpIC8gMTgwLFxyXG4gICAgICAgICdkb3duJzogKCgzNjAgLSBpbnN0cnVjdGlvbi5hbmdsZSkgKiBNYXRoLlBJKSAvIDE4MCxcclxuICAgICAgICAncmlnaHQnOiAoKDkwIC0gaW5zdHJ1Y3Rpb24uYW5nbGUpICogTWF0aC5QSSkgLyAxODAsXHJcbiAgICAgIH1baW5zdHJ1Y3Rpb24uZGlyZWN0aW9uIGFzICd1cCcgfCAnbGVmdCcgfCAnZG93bicgfCAncmlnaHQnXTtcclxuXHJcbiAgICAgIGlmIChyYWRpYW5zID09PSB1bmRlZmluZWQpIHtcclxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYEludmFsaWQgZGlyZWN0aW9uOiAke2luc3RydWN0aW9uLmRpcmVjdGlvbn1gKTtcclxuICAgICAgfVxyXG5cclxuICAgICAgY29uc3QgZGlzdGFuY2VJblBpeGVscyA9IHRoaXMuY29udmVydFRvUGl4ZWxzKGluc3RydWN0aW9uLmRpc3RhbmNlLCBpbnN0cnVjdGlvbi51bml0KTtcclxuICAgICAgY29uc3QgbmV3WCA9IGN1cnJlbnRQb2ludC54ICsgTWF0aC5jb3MocmFkaWFucykgKiBkaXN0YW5jZUluUGl4ZWxzO1xyXG4gICAgICBjb25zdCBuZXdZID0gY3VycmVudFBvaW50LnkgLSBNYXRoLnNpbihyYWRpYW5zKSAqIGRpc3RhbmNlSW5QaXhlbHM7XHJcblxyXG4gICAgICBjb25zdCBuZXdQb2ludCA9IHtcclxuICAgICAgICB4OiB0aGlzLnNuYXBUb0dyaWQobmV3WCwgdGhpcy5ncmlkV2lkdGgpLFxyXG4gICAgICAgIHk6IHRoaXMuc25hcFRvR3JpZChuZXdZLCB0aGlzLmdyaWRIZWlnaHQpLFxyXG4gICAgICB9O1xyXG5cclxuICAgICAgY29uc3QgbGluZVNlZ21lbnQgPSBbXHJcbiAgICAgICAgY3VycmVudFBvaW50LFxyXG4gICAgICAgIG5ld1BvaW50LFxyXG4gICAgICAgIHtcclxuICAgICAgICAgIGVsZW1lbnRUeXBlOiBpbnN0cnVjdGlvbi5lbGVtZW50VHlwZSxcclxuICAgICAgICAgIGRpc3RhbmNlOiBpbnN0cnVjdGlvbi5kaXN0YW5jZSxcclxuICAgICAgICAgIHVuaXQ6IGluc3RydWN0aW9uLnVuaXQsXHJcbiAgICAgICAgICBkaXJlY3Rpb246IGluc3RydWN0aW9uLmRpcmVjdGlvbixcclxuICAgICAgICAgIGFuZ2xlOiBpbnN0cnVjdGlvbi5hbmdsZSxcclxuICAgICAgICAgIGVsZW1lbnROdW1iZXI6IGluc3RydWN0aW9uLmVsZW1lbnROdW1iZXIsXHJcbiAgICAgICAgfSxcclxuICAgICAgXTtcclxuXHJcbiAgICAgIGxheW91dFBvbHlnb24ucHVzaChsaW5lU2VnbWVudCk7XHJcbiAgICAgIGN1cnJlbnRQb2ludCA9IG5ld1BvaW50O1xyXG4gICAgfSk7XHJcblxyXG4gICAgY29uc3QgZmlyc3RQb2ludCA9IGxheW91dFBvbHlnb24/LlswXT8uWzBdO1xyXG4gICAgY29uc3QgbGFzdFBvaW50ID0gbGF5b3V0UG9seWdvbj8uW2xheW91dFBvbHlnb24ubGVuZ3RoIC0gMV0/LlsxXTtcclxuXHJcbiAgICBpZiAobGF5b3V0UG9seWdvbi5sZW5ndGggPD0gMSB8fCAhZmlyc3RQb2ludCB8fCAhbGFzdFBvaW50KSB7XHJcbiAgICAgIHJldHVybiBmYWxzZTtcclxuICAgIH1cclxuXHJcbiAgICBjb25zdCBkaXN0YW5jZUJldHdlZW5Qb2ludHMgPSBNYXRoLnNxcnQoXHJcbiAgICAgIE1hdGgucG93KGxhc3RQb2ludC54IC0gZmlyc3RQb2ludC54LCAyKSArIE1hdGgucG93KGxhc3RQb2ludC55IC0gZmlyc3RQb2ludC55LCAyKVxyXG4gICAgKTtcclxuXHJcbiAgICBjb25zdCB0aHJlc2hvbGRJblBpeGVscyA9IHRoaXMuY29udmVydFRvUGl4ZWxzKHRocmVzaG9sZEluRmVldCwgJ2Z0Jyk7XHJcbiAgICByZXR1cm4gZGlzdGFuY2VCZXR3ZWVuUG9pbnRzIDw9IHRocmVzaG9sZEluUGl4ZWxzO1xyXG4gIH1cclxuXHJcbiAgb3BlbldpZGdldChwb3NpdGlvbjogeyB4OiBudW1iZXIsIHk6IG51bWJlciB9LCBvZmZzZXQgPSB7IHVwOiAwLCByaWdodDogNSwgZG93bjogMTUsIGxlZnQ6IDAsIH0pIHtcclxuICAgIGNvbnN0IGFkanVzdGVkUG9zaXRpb24gPSB7XHJcbiAgICAgIHg6IHBvc2l0aW9uLnggKyBvZmZzZXQucmlnaHQgKyBvZmZzZXQubGVmdCxcclxuICAgICAgeTogcG9zaXRpb24ueSArIG9mZnNldC51cCArIG9mZnNldC5kb3duLFxyXG4gICAgfTtcclxuXHJcbiAgICB0aGlzLnNjcm9sbFRvQ2FudmFzUG9zaXRpb24oYWRqdXN0ZWRQb3NpdGlvbilcclxuXHJcbiAgfVxyXG5cclxuICBvcGVuT2ZmQ2FudmEoKSB7XHJcbiAgICBsZXQgY2FudmFSZWYgPSB0aGlzLm9mZmNhbnZhc1NlcnZpY2Uub3BlbihTdG9yZU9mZmNhbnZhc0NvbXBvbmVudENvbXBvbmVudCwgeyBwb3NpdGlvbjogJ2VuZCcsIHBhbmVsQ2xhc3M6ICdzZXQtaGVpZ2h0JyB9KVxyXG4gICAgY2FudmFSZWYuY29tcG9uZW50SW5zdGFuY2Uuc3RvcmUgPSB0aGlzLnNlbGVjdGVkU3RvcmU7XHJcbiAgICBjYW52YVJlZi5jb21wb25lbnRJbnN0YW5jZS5jbGllbnRJZCA9IHRoaXMuaGVhZGVyRGF0YT8uY2xpZW50O1xyXG4gICAgY2FudmFSZWYuY29tcG9uZW50SW5zdGFuY2UuaWQgPSB0aGlzLnNlbGVjdGVkU3RvcmUucGxhbm9JZDtcclxuICB9XHJcblxyXG4gIG9uTW9kYWxTZWxlY3RBbGwoZXZlbnQ6IGFueSkge1xyXG4gICAgdGhpcy5wbGFub1N0b3JlTGlzdC5mb3JFYWNoKChzdG9yZSkgPT4gc3RvcmUuc2VsZWN0ZWQgPSBldmVudC50YXJnZXQuY2hlY2tlZClcclxuICB9XHJcblxyXG4gIGdldCBpc0FsbFN0b3JlU2VsZWN0ZWQoKSB7XHJcbiAgICByZXR1cm4gdGhpcy5wbGFub1N0b3JlTGlzdC5ldmVyeSgoc3RvcmUpID0+IHN0b3JlLnNlbGVjdGVkKVxyXG4gIH1cclxuXHJcbiAgb25Nb2RhbFR5cGVDaGFuZ2UoZXZlbnQ6ICdzaW5nbGUnIHwgJ211bHRpcGxlJykge1xyXG4gICAgaWYgKGV2ZW50ID09PSAnc2luZ2xlJykge1xyXG4gICAgICB0aGlzLnBsYW5vU3RvcmVMaXN0LmZvckVhY2goKHN0b3JlLCBpbmRleCkgPT4ge1xyXG4gICAgICAgIGlmIChzdG9yZS5wbGFub0lkID09PSB0aGlzLnNlbGVjdGVkU3RvcmUucGxhbm9JZCkge1xyXG4gICAgICAgICAgc3RvcmUuc2VsZWN0ZWQgPSB0cnVlXHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgIHN0b3JlLnNlbGVjdGVkID0gZmFsc2VcclxuICAgICAgICB9XHJcbiAgICAgIH0pXHJcbiAgICB9IGVsc2UgaWYgKGV2ZW50ID09PSAnbXVsdGlwbGUnKSB7XHJcbiAgICAgIHRoaXMucGxhbm9TdG9yZUxpc3QuZm9yRWFjaCgoc3RvcmUpID0+IHN0b3JlLnNlbGVjdGVkID0gdHJ1ZSlcclxuICAgIH1cclxuXHJcbiAgfVxyXG5cclxuICB1cGRhdGVQbGFub1N0YXR1cygpIHtcclxuICAgIGNvbnN0IHBheWxvYWQgPSB7XHJcbiAgICAgIHN0b3JlSWQ6IHRoaXMucGxhbm9TdG9yZUxpc3QuZmlsdGVyKChzdG9yZSkgPT4gc3RvcmUuc2VsZWN0ZWQgPT09IHRydWUpLm1hcCgoc3RvcmUpID0+IHN0b3JlLnN0b3JlSWQpLFxyXG4gICAgICBzdGF0dXM6IFwiY29tcGxldGVkXCJcclxuICAgIH1cclxuXHJcbiAgICB0aGlzLmFwaVNlcnZpY2UudXBkYXRlUGxhbm9TdGF0dXMocGF5bG9hZCkuc3Vic2NyaWJlKHtcclxuICAgICAgbmV4dDogKHJlczphbnkpID0+IHtcclxuICAgICAgICBpZihyZXMuY29kZSA9PT0gMjAwKXtcclxuICAgICAgICAgIHRoaXMudG9hc3RTZXJ2aWNlLmdldFN1Y2Nlc3NUb2FzdChyZXMubWVzc2FnZSlcclxuICAgICAgICAgIHRoaXMucm91dGVyLm5hdmlnYXRlQnlVcmwoJy9tYW5hZ2UvcGxhbm9ncmFtL3N0b3JlLWxheW91dCcpXHJcbiAgICAgICAgfVxyXG4gICAgICB9LFxyXG4gICAgICBlcnJvcjogKGVycikgPT4ge1xyXG4gICAgICAgIGNvbnNvbGUubG9nKGVycilcclxuICAgICAgfVxyXG4gICAgfSlcclxuICB9XHJcblxyXG4gIG9uUGFnZUNoYW5nZSh2YWw6IG51bWJlcikge1xyXG4gICAgdGhpcy5zZWxlY3RlZFN0b3JlID0gdGhpcy5wbGFub1N0b3JlTGlzdFt2YWwgLSAxXTtcclxuICAgIHRoaXMuc2VsZWN0ZWRGbG9vciA9IHRoaXMuc2VsZWN0ZWRTdG9yZS5mbG9vclswXTtcclxuICAgIHRoaXMuZmxvb3JzSW5wdXQuc2V0VmFsdWUodGhpcy5zZWxlY3RlZEZsb29yLmlkLCB7IGVtaXRFdmVudDogZmFsc2UgfSk7XHJcbiAgICB0aGlzLmdlbmVyYXRlTGF5b3V0UG9seWdvbih0aGlzLnNlbGVjdGVkRmxvb3IubGF5b3V0UG9seWdvbik7XHJcbiAgfVxyXG5cclxuICBub3JtYWxpemVkUGl4ZWxQZXJNZXRyZShwb2x5Z29uOiBhbnkpOiBudW1iZXIge1xyXG4gICAgY29uc3QgTUlOX1BJWEVMU19QRVJfTUVURVIgPSA1MDtcclxuICAgIGNvbnN0IE1BWF9QSVhFTFNfUEVSX01FVEVSID0gMTUwO1xyXG5cclxuICAgIGxldCB0b3RhbExlbmd0aCA9IDA7XHJcbiAgICBsZXQgbGluZUNvdW50ID0gMDtcclxuXHJcbiAgICBwb2x5Z29uLmZvckVhY2goKGxpbmU6IGFueSkgPT4ge1xyXG4gICAgICBpZiAobGluZS51bml0ID09PSAnZnQnKSB7XHJcbiAgICAgICAgdG90YWxMZW5ndGggPSB0b3RhbExlbmd0aCArIChsaW5lLmRpc3RhbmNlICogMy4yODA4NCk7XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgdG90YWxMZW5ndGggPSB0b3RhbExlbmd0aCArIGxpbmUuZGlzdGFuY2U7XHJcbiAgICAgIH1cclxuICAgICAgbGluZUNvdW50Kys7XHJcbiAgICB9KTtcclxuXHJcbiAgICBjb25zdCBhdmVyYWdlTGVuZ3RoID0gbGluZUNvdW50ID4gMCA/IHRvdGFsTGVuZ3RoIC8gbGluZUNvdW50IDogMDtcclxuXHJcbiAgICBjb25zdCBNQVhfQVZFUkFHRV9MRU5HVEggPSA1MDtcclxuICAgIGNvbnN0IE1JTl9BVkVSQUdFX0xFTkdUSCA9IDU7XHJcblxyXG4gICAgY29uc3Qgbm9ybWFsaXplZExlbmd0aCA9IE1hdGgubWluKFxyXG4gICAgICBNYXRoLm1heChhdmVyYWdlTGVuZ3RoLCBNSU5fQVZFUkFHRV9MRU5HVEgpLFxyXG4gICAgICBNQVhfQVZFUkFHRV9MRU5HVEhcclxuICAgICk7XHJcblxyXG4gICAgY29uc3QgcGl4ZWxzUGVyTWV0ZXIgPVxyXG4gICAgICBNQVhfUElYRUxTX1BFUl9NRVRFUiAtXHJcbiAgICAgICgobm9ybWFsaXplZExlbmd0aCAtIE1JTl9BVkVSQUdFX0xFTkdUSCkgLyAoTUFYX0FWRVJBR0VfTEVOR1RIIC0gTUlOX0FWRVJBR0VfTEVOR1RIKSkgKlxyXG4gICAgICAoTUFYX1BJWEVMU19QRVJfTUVURVIgLSBNSU5fUElYRUxTX1BFUl9NRVRFUik7XHJcblxyXG4gICAgcmV0dXJuIE1hdGgucm91bmQocGl4ZWxzUGVyTWV0ZXIpO1xyXG4gIH1cclxuXHJcbiAgZmluZFBvbHlnb25DZW50ZXJBbmRTY3JvbGwocG9seWdvbjogYW55ID0gdGhpcy5sYXlvdXRQb2x5Z29uKTogdm9pZCB7XHJcbiAgICBjb25zdCB2ZXJ0aWNlcyA9IHBvbHlnb24uZmxhdE1hcCgobGluZTogYW55KSA9PiBsaW5lLnNsaWNlKDAsIDIpKTtcclxuXHJcbiAgICBjb25zdCBtaW5YID0gTWF0aC5taW4oLi4udmVydGljZXMubWFwKCh2OiBhbnkpID0+IHYueCkpO1xyXG4gICAgY29uc3QgbWF4WCA9IE1hdGgubWF4KC4uLnZlcnRpY2VzLm1hcCgodjogYW55KSA9PiB2LngpKTtcclxuICAgIGNvbnN0IG1pblkgPSBNYXRoLm1pbiguLi52ZXJ0aWNlcy5tYXAoKHY6IGFueSkgPT4gdi55KSk7XHJcbiAgICBjb25zdCBtYXhZID0gTWF0aC5tYXgoLi4udmVydGljZXMubWFwKCh2OiBhbnkpID0+IHYueSkpO1xyXG5cclxuICAgIGxldCBjZW50ZXIgPSB7IHg6IChtaW5YICsgbWF4WCkgLyAyLCB5OiAobWluWSArIG1heFkpIC8gMiB9O1xyXG5cclxuICAgIGNvbnN0IHN0ZXAgPSAxO1xyXG4gICAgbGV0IGJlc3RQb2ludCA9IGNlbnRlcjtcclxuICAgIGxldCBiZXN0RGlzdGFuY2VTdW0gPSBOdW1iZXIuTUFYX1ZBTFVFO1xyXG5cclxuICAgIGZvciAobGV0IHggPSBtaW5YOyB4IDw9IG1heFg7IHggKz0gc3RlcCkge1xyXG4gICAgICBmb3IgKGxldCB5ID0gbWluWTsgeSA8PSBtYXhZOyB5ICs9IHN0ZXApIHtcclxuICAgICAgICBjb25zdCBwb2ludCA9IHsgeCwgeSB9O1xyXG4gICAgICAgIGlmIChpc1BvaW50SW5zaWRlUG9seWdvbihwb2ludCwgdmVydGljZXMpKSB7XHJcbiAgICAgICAgICBjb25zdCBkaXN0YW5jZVN1bSA9IHZlcnRpY2VzLnJlZHVjZShcclxuICAgICAgICAgICAgKHN1bTogbnVtYmVyLCB2ZXJ0ZXg6IGFueSkgPT4gc3VtICsgTWF0aC5zcXJ0KChwb2ludC54IC0gdmVydGV4LngpICoqIDIgKyAocG9pbnQueSAtIHZlcnRleC55KSAqKiAyKSxcclxuICAgICAgICAgICAgMFxyXG4gICAgICAgICAgKTtcclxuICAgICAgICAgIGlmIChkaXN0YW5jZVN1bSA8IGJlc3REaXN0YW5jZVN1bSkge1xyXG4gICAgICAgICAgICBiZXN0RGlzdGFuY2VTdW0gPSBkaXN0YW5jZVN1bTtcclxuICAgICAgICAgICAgYmVzdFBvaW50ID0gcG9pbnQ7XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgY29uc3Qgc2Nyb2xsQ29udGFpbmVyID0gdGhpcy5zY3JvbGxDb250YWluZXJSZWYubmF0aXZlRWxlbWVudDtcclxuICAgIHNjcm9sbENvbnRhaW5lci5zY3JvbGxUbyh7XHJcbiAgICAgIGxlZnQ6IGJlc3RQb2ludC54IC0gc2Nyb2xsQ29udGFpbmVyLm9mZnNldFdpZHRoIC8gMixcclxuICAgICAgdG9wOiBiZXN0UG9pbnQueSAtIHNjcm9sbENvbnRhaW5lci5vZmZzZXRIZWlnaHQgLyAyLFxyXG4gICAgICBiZWhhdmlvcjogJ3Ntb290aCdcclxuICAgIH0pO1xyXG5cclxuICAgIGZ1bmN0aW9uIGlzUG9pbnRJbnNpZGVQb2x5Z29uKHBvaW50OiBhbnksIHZlcnRpY2VzOiBhbnkpOiBib29sZWFuIHtcclxuICAgICAgbGV0IGNvdW50ID0gMDtcclxuICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB2ZXJ0aWNlcy5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgIGNvbnN0IHN0YXJ0ID0gdmVydGljZXNbaV07XHJcbiAgICAgICAgY29uc3QgZW5kID0gdmVydGljZXNbKGkgKyAxKSAlIHZlcnRpY2VzLmxlbmd0aF07XHJcbiAgICAgICAgaWYgKHJheUludGVyc2VjdHNTZWdtZW50KHBvaW50LCB7IHN0YXJ0LCBlbmQgfSkpIHtcclxuICAgICAgICAgIGNvdW50Kys7XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcbiAgICAgIHJldHVybiBjb3VudCAlIDIgPT09IDE7XHJcbiAgICB9XHJcblxyXG4gICAgZnVuY3Rpb24gcmF5SW50ZXJzZWN0c1NlZ21lbnQocG9pbnQ6IGFueSwgc2VnbWVudDogYW55KTogYm9vbGVhbiB7XHJcbiAgICAgIGNvbnN0IHsgeCwgeSB9ID0gcG9pbnQ7XHJcbiAgICAgIGNvbnN0IHsgc3RhcnQsIGVuZCB9ID0gc2VnbWVudDtcclxuXHJcbiAgICAgIGlmICh5IDwgTWF0aC5taW4oc3RhcnQueSwgZW5kLnkpIHx8IHkgPiBNYXRoLm1heChzdGFydC55LCBlbmQueSkpIHtcclxuICAgICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIGNvbnN0IHQgPSAoeSAtIHN0YXJ0LnkpIC8gKGVuZC55IC0gc3RhcnQueSk7XHJcbiAgICAgIGNvbnN0IGludGVyc2VjdFggPSBzdGFydC54ICsgdCAqIChlbmQueCAtIHN0YXJ0LngpO1xyXG5cclxuICAgICAgcmV0dXJuIGludGVyc2VjdFggPj0geDtcclxuICAgIH1cclxuICB9XHJcblxyXG5cclxuXHJcblxyXG59XHJcbiIsIjxkaXYgY2xhc3M9XCJkLWZsZXggYWxpZ24taXRlbXMtY2VudGVyIGp1c3RpZnktY29udGVudC1iZXR3ZWVuIG1iLTZcIj5cclxuICA8ZGl2PlxyXG4gICAgPGRpdiAqbmdJZj1cInBsYW5vU3RvcmVMaXN0Lmxlbmd0aCA9PT0gMVwiIGNsYXNzPVwic3RvcmVuYW1lLXR4dFwiPlxyXG4gICAgICB7e3NlbGVjdGVkU3RvcmU/LnN0b3JlTmFtZX19IC0gTGF5b3V0XHJcbiAgICA8L2Rpdj5cclxuICAgIDxkaXYgKm5nSWY9XCJwbGFub1N0b3JlTGlzdC5sZW5ndGggPiAxXCI+XHJcbiAgICAgIDxsaWItc2VsZWN0LXBsYW5vIFtpdGVtc109XCJwbGFub1N0b3JlTGlzdFwiIFttdWx0aV09XCJmYWxzZVwiIFtzZWFyY2hGaWVsZF09XCInc3RvcmVOYW1lJ1wiIFtpZEZpZWxkXT1cIidzdG9yZUlkJ1wiXHJcbiAgICAgICAgKHNlbGVjdGVkKT1cIm9uU3RvcmVDaGFuZ2UoJGV2ZW50KVwiIFtzZWxlY3RlZFZhbHVlc109XCJbc2VsZWN0ZWRTdG9yZV1cIj48L2xpYi1zZWxlY3QtcGxhbm8+XHJcbiAgICA8L2Rpdj5cclxuICA8L2Rpdj5cclxuXHJcbiAgPGRpdiBjbGFzcz1cImQtZmxleCBhbGlnbi1pdGVtcy1jZW50ZXJcIj5cclxuICAgIDxidXR0b24gKGNsaWNrKT1cIm9uQ29tcGxldGUoKVwiIGNsYXNzPVwiYnRuIGJ0bi1zbSBidG4tcHJpbWFyeSBtZS01XCI+Q29tcGxldGU8L2J1dHRvbj5cclxuICAgIDxidXR0b24gKGNsaWNrKT1cIm9wZW5PZmZDYW52YSgpXCIgY2xhc3M9XCJidG4gYnRuLXNtIGJ0bi1vdXRsaW5lIGJnLXdoaXRlXCI+XHJcbiAgICAgIDxzdmcgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIHdpZHRoPVwiMjRcIiBoZWlnaHQ9XCIyNFwiIHZpZXdCb3g9XCIwIDAgMjQgMjRcIiBmaWxsPVwibm9uZVwiPlxyXG4gICAgICAgIDxwYXRoXHJcbiAgICAgICAgICBkPVwiTTkgM1YyMU01IDNIMTlDMjAuMTA0NiAzIDIxIDMuODk1NDMgMjEgNVYxOUMyMSAyMC4xMDQ2IDIwLjEwNDYgMjEgMTkgMjFINUMzLjg5NTQzIDIxIDMgMjAuMTA0NiAzIDE5VjVDMyAzLjg5NTQzIDMuODk1NDMgMyA1IDNaXCJcclxuICAgICAgICAgIHN0cm9rZT1cIiMxMDE4MjhcIiBzdHJva2Utd2lkdGg9XCIyXCIgc3Ryb2tlLWxpbmVjYXA9XCJyb3VuZFwiIHN0cm9rZS1saW5lam9pbj1cInJvdW5kXCIgLz5cclxuICAgICAgPC9zdmc+XHJcbiAgICA8L2J1dHRvbj5cclxuICA8L2Rpdj5cclxuPC9kaXY+XHJcblxyXG48ZGl2IGNsYXNzPVwicm93IG1iLTZcIj5cclxuICA8ZGl2IGNsYXNzPVwiY29sLTRcIj5cclxuICAgIDxkaXYgY2xhc3M9XCJhcmVhLWNhcmRcIj5cclxuICAgICAgPGRpdj5cclxuICAgICAgICA8ZGl2PiA8c3BhbiBjbGFzcz1cIm1haW4tdHh0IG1lLTJcIj57e3dhbGxDYXBhY2l0eSB8fCAwfX08L3NwYW4+IDxzcGFuIGNsYXNzPVwidW5pdC10eHRcIj5yZnQ8L3NwYW4+IDwvZGl2PlxyXG4gICAgICAgIDxkaXYgY2xhc3M9XCJzdWItdHh0XCI+V2FsbCBjYXBhY2l0eTwvZGl2PlxyXG4gICAgICA8L2Rpdj5cclxuICAgICAgPGRpdj5cclxuICAgICAgICA8c3ZnIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIiB3aWR0aD1cIjY1XCIgaGVpZ2h0PVwiNjVcIiB2aWV3Qm94PVwiMCAwIDY1IDY1XCIgZmlsbD1cIm5vbmVcIj5cclxuICAgICAgICAgIDxwYXRoIGZpbGwtcnVsZT1cImV2ZW5vZGRcIiBjbGlwLXJ1bGU9XCJldmVub2RkXCJcclxuICAgICAgICAgICAgZD1cIk00LjMzMzMzIDQuMzMzMzNWMEg4LjY2NjY3VjQuMzMzMzNIMjEuNjY2N1YwSDI2VjQuMzMzMzNIMzlWMEg0My4zMzMzVjQuMzMzMzNINTYuMzMzM1YwSDYwLjY2NjdWNC4zMzMzM0g2NVY4LjY2NjY3SDYwLjY2NjdWMjEuNjY2N0g2NVYyNkg2MC42NjY3VjM5SDY1VjQzLjMzMzNINjAuNjY2N1Y1Ni4zMzMzSDY1VjYwLjY2NjdINjAuNjY2N1Y2NUg1Ni4zMzMzVjYwLjY2NjdINDMuMzMzM1Y2NUgzOVY2MC42NjY3SDI2VjY1SDIxLjY2NjdWNjAuNjY2N0g4LjY2NjY3VjY1SDQuMzMzMzNWNjAuNjY2N0gwVjU2LjMzMzNINC4zMzMzM1Y0My4zMzMzSDBWMzlINC4zMzMzM1YyNkgwVjIxLjY2NjdINC4zMzMzM1Y4LjY2NjY3SDBWNC4zMzMzM0g0LjMzMzMzWk04LjY2NjY3IDguNjY2NjdWMjEuNjY2N0gyMS42NjY3VjguNjY2NjdIOC42NjY2N1pNMjYgOC42NjY2N1YyMS42NjY3SDM5VjguNjY2NjdIMjZaTTQzLjMzMzMgOC42NjY2N1YyMS42NjY3SDU2LjMzMzNWOC42NjY2N0g0My4zMzMzWk01Ni4zMzMzIDI2SDQzLjMzMzNWMzlINTYuMzMzM1YyNlpNNTYuMzMzMyA0My4zMzMzSDQzLjMzMzNWNTYuMzMzM0g1Ni4zMzMzVjQzLjMzMzNaTTM5IDU2LjMzMzNWNDMuMzMzM0gyNlY1Ni4zMzMzSDM5Wk0yMS42NjY3IDU2LjMzMzNWNDMuMzMzM0g4LjY2NjY3VjU2LjMzMzNIMjEuNjY2N1pNOC42NjY2NyAzOUgyMS42NjY3VjI2SDguNjY2NjdWMzlaTTI2IDI2VjM5SDM5VjI2SDI2WlwiXHJcbiAgICAgICAgICAgIGZpbGw9XCIjMzQ0MDU0XCIgLz5cclxuICAgICAgICA8L3N2Zz5cclxuICAgICAgPC9kaXY+XHJcbiAgICA8L2Rpdj5cclxuICA8L2Rpdj5cclxuICA8ZGl2IGNsYXNzPVwiY29sLTRcIj5cclxuICAgIDxkaXYgY2xhc3M9XCJhcmVhLWNhcmRcIj5cclxuICAgICAgPGRpdj5cclxuICAgICAgICA8ZGl2PiA8c3BhbiBjbGFzcz1cIm1haW4tdHh0IG1lLTJcIj57e2ZhY2FkZUNhcGFjaXR5IHx8IDB9fTwvc3Bhbj4gPHNwYW4gY2xhc3M9XCJ1bml0LXR4dFwiPnJmdDwvc3Bhbj4gPC9kaXY+XHJcbiAgICAgICAgPGRpdiBjbGFzcz1cInN1Yi10eHRcIj5GYWNhZGUgY2FwYWNpdHk8L2Rpdj5cclxuICAgICAgPC9kaXY+XHJcbiAgICAgIDxkaXY+XHJcbiAgICAgICAgPHN2ZyB3aWR0aD1cIjY1XCIgaGVpZ2h0PVwiNjVcIiB2aWV3Qm94PVwiMCAwIDY1IDY1XCIgZmlsbD1cIm5vbmVcIiB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCI+XHJcbiAgICAgICAgICA8cmVjdCB4PVwiMC41XCIgeT1cIjAuNVwiIHdpZHRoPVwiNjRcIiBoZWlnaHQ9XCI2NFwiIGZpbGw9XCIjRkRGREZEXCIgc3Ryb2tlPVwiYmxhY2tcIiAvPlxyXG4gICAgICAgIDwvc3ZnPlxyXG4gICAgICA8L2Rpdj5cclxuICAgIDwvZGl2PlxyXG4gIDwvZGl2PlxyXG4gIDxkaXYgY2xhc3M9XCJjb2wtNFwiPlxyXG4gICAgPGRpdiBjbGFzcz1cImFyZWEtY2FyZFwiPlxyXG4gICAgICA8ZGl2PlxyXG4gICAgICAgIDxkaXY+IDxzcGFuIGNsYXNzPVwibWFpbi10eHQgbWUtMlwiPnt7Zmxvb3JDYXBhY2l0eSB8fCAwfX08L3NwYW4+IDxzcGFuIGNsYXNzPVwidW5pdC10eHRcIj5zcWZ0PC9zcGFuPiA8L2Rpdj5cclxuICAgICAgICA8ZGl2IGNsYXNzPVwic3ViLXR4dFwiPkZsb29yIGNhcGFjaXR5PC9kaXY+XHJcbiAgICAgIDwvZGl2PlxyXG4gICAgICA8ZGl2PlxyXG4gICAgICAgIDxzdmcgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIHdpZHRoPVwiMTAyXCIgaGVpZ2h0PVwiNThcIiB2aWV3Qm94PVwiMCAwIDEwMiA1OFwiIGZpbGw9XCJub25lXCI+XHJcbiAgICAgICAgICA8cGF0aCBkPVwiTTMuNTQzNTkgMzYuNDYwN0wyOS44OTI5IDIuMDY0MzJMOTguMDkzOSA2LjQ0MTkxTDk5LjkwOCA1NS41NDY4TDMuNTQzNTkgMzYuNDYwN1pcIiBzdHJva2U9XCIjNDc1NDY3XCJcclxuICAgICAgICAgICAgc3Ryb2tlLXdpZHRoPVwiNFwiIC8+XHJcbiAgICAgICAgPC9zdmc+XHJcbiAgICAgIDwvZGl2PlxyXG4gICAgPC9kaXY+XHJcbiAgPC9kaXY+XHJcbjwvZGl2PlxyXG5cclxuPGRpdiBjbGFzcz1cInJvd1wiPlxyXG4gIDxkaXYgY2xhc3M9XCJjb2wtNFwiPlxyXG4gICAgPGRpdiBjbGFzcz1cImMtY2FyZFwiIHN0eWxlPVwiaGVpZ2h0OiA3NWR2aDsgcG9zaXRpb246IHJlbGF0aXZlO1wiPlxyXG4gICAgICA8ZGl2IGNsYXNzPVwiZC1mbGV4IGFsaWduLWl0ZW1zLWNlbnRlciBqdXN0aWZ5LWNvbnRlbnQtYmV0d2VlbiBtYi01XCIgc3R5bGU9XCJoZWlnaHQ6IDglO1wiPlxyXG4gICAgICAgIDxkaXY+XHJcbiAgICAgICAgICA8ZGl2IGNsYXNzPVwibC1wYW5lLWhlYWRcIj5cclxuICAgICAgICAgICAgQ2FwYWNpdHkgZGV0YWlsc1xyXG4gICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICA8ZGl2IGNsYXNzPVwibC1wYW5lLWRlc2NcIj5cclxuICAgICAgICAgICAgQmVsb3cgYXJlIHRoZSBjYXBhY2l0eSBkZXRhaWxzIG9mIHRoZSBlbGVtZW50c1xyXG4gICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgPGRpdiBjbGFzcz1cImQtZmxleCBhbGlnbi1pdGVtcy1jZW50ZXJcIj5cclxuXHJcbiAgICAgICAgPC9kaXY+XHJcblxyXG4gICAgICA8L2Rpdj5cclxuXHJcbiAgICAgIDxkaXYgY2xhc3M9XCJ0YWJsZS1yZXNwb25zaXZlIGhpZGUtc2Nyb2xsYmFyIFwiIHN0eWxlPVwiaGVpZ2h0OiA5MiU7XCI+XHJcbiAgICAgICAgPHRhYmxlIGNsYXNzPVwidGFibGVcIj5cclxuICAgICAgICAgIDx0aGVhZCBjbGFzcz1cInRoZWFkLWxpZ2h0XCI+XHJcbiAgICAgICAgICAgIDx0cj5cclxuICAgICAgICAgICAgICA8dGg+IzwvdGg+XHJcbiAgICAgICAgICAgICAgPHRoPiA8c3ZnIGNsYXNzPVwibWUtMlwiIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIiB3aWR0aD1cIjIwXCIgaGVpZ2h0PVwiMjBcIiB2aWV3Qm94PVwiMCAwIDIwIDIwXCJcclxuICAgICAgICAgICAgICAgICAgZmlsbD1cIm5vbmVcIj5cclxuICAgICAgICAgICAgICAgICAgPHBhdGggZmlsbC1ydWxlPVwiZXZlbm9kZFwiIGNsaXAtcnVsZT1cImV2ZW5vZGRcIlxyXG4gICAgICAgICAgICAgICAgICAgIGQ9XCJNMS4zMzMzMyAxLjMzMzMzVjBMMi42NjY2NyAwVjEuMzMzMzNMNi42NjY2NyAxLjMzMzMzVjBMOCAwVjEuMzMzMzNMMTIgMS4zMzMzM1YwTDEzLjMzMzMgMFYxLjMzMzMzTDE3LjMzMzMgMS4zMzMzM1YwTDE4LjY2NjcgMFYxLjMzMzMzSDIwVjIuNjY2NjdIMTguNjY2N1Y2LjY2NjY3SDIwVjhIMTguNjY2N1YxMkgyMFYxMy4zMzMzSDE4LjY2NjdWMTcuMzMzM0gyMFYxOC42NjY3SDE4LjY2NjdWMjBIMTcuMzMzM1YxOC42NjY3SDEzLjMzMzNWMjBIMTJWMTguNjY2N0g4VjIwSDYuNjY2NjdWMTguNjY2N0gyLjY2NjY3VjIwSDEuMzMzMzNWMTguNjY2N0gwTDAgMTcuMzMzM0gxLjMzMzMzTDEuMzMzMzMgMTMuMzMzM0gwTDAgMTJIMS4zMzMzM0wxLjMzMzMzIDhIMEwwIDYuNjY2NjdIMS4zMzMzM0wxLjMzMzMzIDIuNjY2NjdIMEwwIDEuMzMzMzNIMS4zMzMzM1pNMi42NjY2NyAyLjY2NjY3TDIuNjY2NjcgNi42NjY2N0g2LjY2NjY3VjIuNjY2NjdMMi42NjY2NyAyLjY2NjY3Wk04IDIuNjY2NjdWNi42NjY2N0gxMlYyLjY2NjY3TDggMi42NjY2N1pNMTMuMzMzMyAyLjY2NjY3VjYuNjY2NjdIMTcuMzMzM1YyLjY2NjY3SDEzLjMzMzNaTTE3LjMzMzMgOEwxMy4zMzMzIDhWMTJMMTcuMzMzMyAxMlY4Wk0xNy4zMzMzIDEzLjMzMzNMMTMuMzMzMyAxMy4zMzMzTDEzLjMzMzMgMTcuMzMzM0gxNy4zMzMzVjEzLjMzMzNaTTEyIDE3LjMzMzNMMTIgMTMuMzMzM0g4TDggMTcuMzMzM0gxMlpNNi42NjY2NyAxNy4zMzMzVjEzLjMzMzNIMi42NjY2N1YxNy4zMzMzSDYuNjY2NjdaTTIuNjY2NjcgMTJINi42NjY2N1Y4SDIuNjY2NjdMMi42NjY2NyAxMlpNOCA4VjEySDEyVjhIOFpcIlxyXG4gICAgICAgICAgICAgICAgICAgIGZpbGw9XCIjMzQ0MDU0XCIgLz5cclxuICAgICAgICAgICAgICAgIDwvc3ZnPiA8c3Bhbj5XYWxsPC9zcGFuPiA8L3RoPlxyXG4gICAgICAgICAgICAgIDx0aD5SRlQgKHt7d2FsbENhcGFjaXR5IHx8IDB9fSk8L3RoPlxyXG5cclxuICAgICAgICAgICAgPC90cj5cclxuICAgICAgICAgIDwvdGhlYWQ+XHJcbiAgICAgICAgICA8dGJvZHk+XHJcbiAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nRm9yPVwibGV0IGl0ZW0gb2YgbGF5b3V0UG9seWdvbjsgbGV0IGkgPSBpbmRleFwiPlxyXG4gICAgICAgICAgICAgIDx0ciAqbmdJZj1cIml0ZW1bMl0gJiYgaXRlbVsyXS5lbGVtZW50VHlwZSA9PT0gJ3dhbGwnXCI+XHJcbiAgICAgICAgICAgICAgICA8dGQ+XHJcbiAgICAgICAgICAgICAgICAgIHt7MX19XHJcbiAgICAgICAgICAgICAgICA8L3RkPlxyXG4gICAgICAgICAgICAgICAgPHRkPlxyXG4gICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwidGFibGUtdGRcIj57e2l0ZW1bMl0uZWxlbWVudFR5cGV9fSB7e2l0ZW1bMl0uZWxlbWVudE51bWJlcn19PC9kaXY+XHJcbiAgICAgICAgICAgICAgICA8L3RkPlxyXG4gICAgICAgICAgICAgICAgPHRkPlxyXG4gICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwidGFibGUtdGRcIj57e2l0ZW1bMl0uZGlzdGFuY2V9fTwvZGl2PlxyXG5cclxuICAgICAgICAgICAgICAgIDwvdGQ+XHJcbiAgICAgICAgICAgICAgPC90cj5cclxuICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XHJcblxyXG4gICAgICAgICAgPC90Ym9keT5cclxuICAgICAgICA8L3RhYmxlPlxyXG4gICAgICAgIDx0YWJsZSBjbGFzcz1cInRhYmxlXCI+XHJcbiAgICAgICAgICA8dGhlYWQgY2xhc3M9XCJ0aGVhZC1saWdodFwiPlxyXG4gICAgICAgICAgICA8dHI+XHJcbiAgICAgICAgICAgICAgPHRoPiM8L3RoPlxyXG4gICAgICAgICAgICAgIDx0aD4gPHN2ZyBjbGFzcz1cIm1lLTJcIiB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCIgd2lkdGg9XCIyMlwiIGhlaWdodD1cIjIyXCIgdmlld0JveD1cIjAgMCAyMiAyMlwiXHJcbiAgICAgICAgICAgICAgICAgIGZpbGw9XCJub25lXCI+XHJcbiAgICAgICAgICAgICAgICAgIDxwYXRoXHJcbiAgICAgICAgICAgICAgICAgICAgZD1cIk0xIDExVjIuMjVDMSAxLjU2MjUgMS41NjI1IDEgMi4yNSAxSDE5Ljc1QzIwLjQzNzUgMSAyMSAxLjU2MjUgMjEgMi4yNVYxOS43NUMyMSAyMC40Mzc1IDIwLjQzNzUgMjEgMTkuNzUgMjFIMi4yNUMxLjU2MjUgMjEgMSAyMC40Mzc1IDEgMTkuNzVWMTFaXCJcclxuICAgICAgICAgICAgICAgICAgICBzdHJva2U9XCIjMzQ0MDU0XCIgc3Ryb2tlLWxpbmVjYXA9XCJyb3VuZFwiIHN0cm9rZS1saW5lam9pbj1cInJvdW5kXCIgLz5cclxuICAgICAgICAgICAgICAgIDwvc3ZnPiA8c3Bhbj5GYWNhZGU8L3NwYW4+IDwvdGg+XHJcbiAgICAgICAgICAgICAgPHRoPlJGVCAoe3tmYWNhZGVDYXBhY2l0eSB8fCAwfX0pPC90aD5cclxuXHJcbiAgICAgICAgICAgIDwvdHI+XHJcbiAgICAgICAgICA8L3RoZWFkPlxyXG4gICAgICAgICAgPHRib2R5PlxyXG4gICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0Zvcj1cImxldCBpdGVtIG9mIGxheW91dFBvbHlnb247IGxldCBpID0gaW5kZXhcIj5cclxuICAgICAgICAgICAgICA8dHIgKm5nSWY9XCJpdGVtWzJdICYmIGl0ZW1bMl0uZWxlbWVudFR5cGUgPT09ICdmYWNhZGUnXCI+XHJcbiAgICAgICAgICAgICAgICA8dGQ+XHJcbiAgICAgICAgICAgICAgICAgIHt7aX19XHJcbiAgICAgICAgICAgICAgICA8L3RkPlxyXG4gICAgICAgICAgICAgICAgPHRkPlxyXG4gICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwidGFibGUtdGRcIj57e2l0ZW1bMl0uZWxlbWVudFR5cGV9fSB7e2l0ZW1bMl0uZWxlbWVudE51bWJlcn19PC9kaXY+XHJcbiAgICAgICAgICAgICAgICA8L3RkPlxyXG4gICAgICAgICAgICAgICAgPHRkPlxyXG4gICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwidGFibGUtdGRcIj57e2l0ZW1bMl0uZGlzdGFuY2V9fTwvZGl2PlxyXG5cclxuICAgICAgICAgICAgICAgIDwvdGQ+XHJcbiAgICAgICAgICAgICAgPC90cj5cclxuICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XHJcblxyXG4gICAgICAgICAgPC90Ym9keT5cclxuICAgICAgICA8L3RhYmxlPlxyXG4gICAgICA8L2Rpdj5cclxuXHJcbiAgICA8L2Rpdj5cclxuICA8L2Rpdj5cclxuICA8ZGl2IGNsYXNzPVwiY29sLThcIj5cclxuICAgIDxkaXYgY2xhc3M9XCJjLWNhcmQgXCIgc3R5bGU9XCJoZWlnaHQ6IDc1ZHZoO1wiPlxyXG4gICAgICA8ZGl2IHN0eWxlPVwiaGVpZ2h0OiA4JTtcIiBjbGFzcz1cImQtZmxleCBhbGlnbi1pdGVtcy1jZW50ZXIganVzdGlmeS1jb250ZW50LWJldHdlZW5cIj5cclxuICAgICAgICA8ZGl2PlxyXG4gICAgICAgICAgPCEtLSA8bGliLXJlYWN0aXZlLXNlbGVjdCAqbmdJZj1cImZsb29yc0lucHV0LnZhbHVlXCIgW2Zvcm1Db250cm9sXT1cImZsb29yc0lucHV0XCIgW2lkRmllbGRdPVwiJ2lkJ1wiXHJcbiAgICAgICAgICAgIFtuYW1lRmllbGRdPVwiJ2Zsb29yTmFtZSdcIiBbZGF0YV09XCJzZWxlY3RlZFN0b3JlPy5mbG9vclwiPjwvbGliLXJlYWN0aXZlLXNlbGVjdD4gLS0+XHJcbiAgICAgICAgICA8ZGl2IChjbGljayk9XCJ0b2dnbGVGbG9vclNlbGVjdCgpXCIgY2xhc3M9XCJmbG9vci1zZWxlY3RcIj5cclxuICAgICAgICAgICAgPGRpdj57e3NlbGVjdGVkRmxvb3I/LmZsb29yTmFtZX19PC9kaXY+XHJcbiAgICAgICAgICAgIDxkaXY+PHN2ZyB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCIgd2lkdGg9XCIyMFwiIGhlaWdodD1cIjIwXCIgdmlld0JveD1cIjAgMCAyMCAyMFwiIGZpbGw9XCJub25lXCI+XHJcbiAgICAgICAgICAgICAgICA8cGF0aCBkPVwiTTUgNy41TDEwIDEyLjVMMTUgNy41XCIgc3Ryb2tlPVwiIzM0NDA1NFwiIHN0cm9rZS13aWR0aD1cIjEuNjdcIiBzdHJva2UtbGluZWNhcD1cInJvdW5kXCJcclxuICAgICAgICAgICAgICAgICAgc3Ryb2tlLWxpbmVqb2luPVwicm91bmRcIiAvPlxyXG4gICAgICAgICAgICAgIDwvc3ZnPjwvZGl2PlxyXG4gICAgICAgICAgICA8dWwgKm5nSWY9XCJmbG9vclNlbGVjdD8uc2hvd1wiIGNsYXNzPVwibGlzdC11bnN0eWxlZCBtYi0yXCI+XHJcbiAgICAgICAgICAgICAgPGxpIChjbGljayk9XCJvbkZsb29yU2VsZWN0KGZsb29yLmlkKVwiICpuZ0Zvcj1cImxldCBmbG9vciBvZiBzZWxlY3RlZFN0b3JlPy5mbG9vcjsgbGV0IGkgPSBpbmRleFwiXHJcbiAgICAgICAgICAgICAgICBbbmdDbGFzc109XCJmbG9vci5pZCA9PT0gc2VsZWN0ZWRGbG9vci5pZCA/ICdzZWxlY3RlZCc6ICcnXCI+XHJcbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZC1mbGV4IGp1c3RpZnktY29udGVudC1iZXR3ZWVuXCI+XHJcbiAgICAgICAgICAgICAgICAgIDxzcGFuPnt7Zmxvb3I/LmZsb29yTmFtZX19PC9zcGFuPlxyXG5cclxuICAgICAgICAgICAgICAgIDwvZGl2PlxyXG5cclxuICAgICAgICAgICAgICA8L2xpPlxyXG4gICAgICAgICAgICA8L3VsPlxyXG4gICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgPGJ1dHRvbiBjbGFzcz1cImJ0biBidG4tc20gYnRuLW91dGxpbmUgYmctd2hpdGVcIiAoY2xpY2spPVwicm90YXRlUG9seWdvbnMoKVwiPlxyXG4gICAgICAgICAgPHN2ZyB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCIgd2lkdGg9XCIyNlwiIGhlaWdodD1cIjI2XCIgdmlld0JveD1cIjAgMCAyNiAyNlwiIGZpbGw9XCJub25lXCI+XHJcbiAgICAgICAgICAgIDxwYXRoXHJcbiAgICAgICAgICAgICAgZD1cIk02LjM2MjY1IDcuMTc4MzhMNy4xNzYyNSA2LjM2MjM4TDUuOTA0MjUgNS4wOTE1OEw1LjA4OTQ1IDUuOTA1MThMNi4zNjI2NSA3LjE3ODM4Wk0xNS42NzEgNi4zNjM1OEwxOS42Mzc5IDEwLjMzMDRMMjAuOTA5OSA5LjA1NzJMMTYuOTQ0MiA1LjA5MDM4TDE1LjY3MSA2LjM2MzU4Wk0xOS42Mzc5IDE4LjgyNTJMMTguODI0MyAxOS42Mzg4TDIwLjA5NjMgMjAuOTA5NkwyMC45MDk5IDIwLjA5NzJMMTkuNjM3OSAxOC44MjUyWk0xMC4zMjk1IDE5LjYzODhMNi4zNjI2NSAxNS42NzJMNS4wOTA2NSAxNi45NDUyTDkuMDU2MjYgMjAuOTEwOEwxMC4zMjk1IDE5LjYzODhaTTE4LjgyNDMgMTkuNjM4OEMxNy42NTQzIDIwLjgwNzYgMTYuODQwNyAyMS42MTg4IDE2LjE0NTkgMjIuMTQ5MkMxNS40NzE1IDIyLjY2NCAxNS4wMTU1IDIyLjgyODQgMTQuNTc2MyAyMi44Mjg0VjI0LjYyODRDMTUuNTY3NSAyNC42Mjg0IDE2LjQwMjcgMjQuMjE2OCAxNy4yMzY3IDIzLjU4MDhDMTguMDUwMyAyMi45NjA0IDE4Ljk2MzUgMjIuMDQ0OCAyMC4wOTYzIDIwLjkxMkwxOC44MjQzIDE5LjYzODhaTTkuMDU2MjYgMjAuOTEwOEMxMC4xODkxIDIyLjA0NDggMTEuMTAyMyAyMi45NTkyIDExLjkxNTkgMjMuNTgwOEMxMi43NDk5IDI0LjIxNjggMTMuNTg1MSAyNC42Mjg0IDE0LjU3NjMgMjQuNjI4NFYyMi44Mjg0QzE0LjEzNzEgMjIuODI4NCAxMy42ODIzIDIyLjY2NCAxMy4wMDY3IDIyLjE0OTJDMTIuMzExOSAyMS42MTg4IDExLjQ5ODMgMjAuODA3NiAxMC4zMjk1IDE5LjYzODhMOS4wNTYyNiAyMC45MTA4Wk0xOS42Mzc5IDEwLjMzMDRDMjAuODA2NyAxMS40OTkyIDIxLjYxNzkgMTIuMzEyOCAyMi4xNDgzIDEzLjAwNzZDMjIuNjYzMSAxMy42ODMyIDIyLjgyNzUgMTQuMTM4IDIyLjgyNzUgMTQuNTc3MkgyNC42Mjc1QzI0LjYyNzUgMTMuNTg2IDI0LjIxNTkgMTIuNzUwOCAyMy41Nzk5IDExLjkxNjhDMjIuOTU5NSAxMS4xMDMyIDIyLjA0MjcgMTAuMTkgMjAuOTA5OSA5LjA1NzJMMTkuNjM3OSAxMC4zMzA0Wk0yMC45MDk5IDIwLjA5NzJDMjIuMDQzOSAxOC45NjMyIDIyLjk1ODMgMTguMDUxMiAyMy41Nzk5IDE3LjIzNzZDMjQuMjE1OSAxNi40MDM2IDI0LjYyNzUgMTUuNTY4NCAyNC42Mjc1IDE0LjU3NzJIMjIuODI3NUMyMi44Mjc1IDE1LjAxNjQgMjIuNjYzMSAxNS40NzI0IDIyLjE0ODMgMTYuMTQ2OEMyMS42MTc5IDE2Ljg0MTYgMjAuODA2NyAxNy42NTUyIDE5LjYzNzkgMTguODI1MkwyMC45MDk5IDIwLjA5NzJaTTcuMTc2MjUgNi4zNjIzOEM4LjM0NjI1IDUuMTkzNTggOS4xNTk4NSA0LjM4MTE4IDkuODU0NjUgMy44NTA3OEMxMC41MjkgMy4zMzU5OCAxMC45ODUgMy4xNzI3OCAxMS40MjQyIDMuMTcyNzhWMS4zNzE1OEMxMC40MzMgMS4zNzE1OCA5LjU5Nzg1IDEuNzgzMTggOC43NjM4NSAyLjQxOTE4QzcuOTQ5MDUgMy4wNDA3OCA3LjAzNzA1IDMuOTU1MTggNS45MDQyNSA1LjA4Nzk4TDcuMTc2MjUgNi4zNjIzOFpNMTYuOTQ0MiA1LjA5MDM4QzE1LjgxMTQgMy45NTYzOCAxNC44OTgyIDMuMDQwNzggMTQuMDg0NiAyLjQxOTE4QzEzLjI1MDYgMS43ODMxOCAxMi40MTU0IDEuMzcxNTggMTEuNDI0MiAxLjM3MTU4VjMuMTcyNzhDMTEuODYzNCAzLjE3Mjc4IDEyLjMxODIgMy4zMzU5OCAxMi45OTM4IDMuODUwNzhDMTMuNjg4NiA0LjM4MTE4IDE0LjUwMjIgNS4xOTIzOCAxNS42NzEgNi4zNjExOEwxNi45NDQyIDUuMDkwMzhaTTUuMDg5NDUgNS45MDI3OEMzLjk1NjY1IDcuMDM1NTggMy4wNDIyNSA3Ljk0NzU4IDIuNDIwNjUgOC43NjIzOEMxLjc4NDY1IDkuNTk2MzggMS4zNzMwNSAxMC40MzE2IDEuMzczMDUgMTEuNDIyOEgzLjE3MzA1QzMuMTczMDUgMTAuOTgzNiAzLjMzNzQ1IDEwLjUyNzYgMy44NTIyNSA5Ljg1MzE4QzQuMzgyNjUgOS4xNTgzOCA1LjE5Mzg1IDguMzQ0NzggNi4zNjI2NSA3LjE3NDc4TDUuMDg5NDUgNS45MDI3OFpNNi4zNjI2NSAxNS42NzA4QzUuMTkzODUgMTQuNTAwOCA0LjM4MjY1IDEzLjY4NzIgMy44NTIyNSAxMi45OTI0QzMuMzM3NDUgMTIuMzE4IDMuMTczMDUgMTEuODYyIDMuMTczMDUgMTEuNDIyOEgxLjM3MzA1QzEuMzczMDUgMTIuNDE0IDEuNzg0NjUgMTMuMjQ5MiAyLjQyMDY1IDE0LjA4MzJDMy4wNDIyNSAxNC44OTY4IDMuOTU2NjUgMTUuODEgNS4wODk0NSAxNi45NDI4TDYuMzYyNjUgMTUuNjcwOFpcIlxyXG4gICAgICAgICAgICAgIGZpbGw9XCIjMUQyOTM5XCIgLz5cclxuICAgICAgICAgICAgPHBhdGggZD1cIk0yMy4yIDYuOTgzMkwyNSA4LjJDMjUgNC41ODIgMjIuNDA1NiAxLjU3OTYgMTkgMU0yLjggMTkuMDE2OEwxIDE3LjhDMSAyMS40MTggMy41OTQ0IDI0LjQyMDQgNyAyNVwiXHJcbiAgICAgICAgICAgICAgc3Ryb2tlPVwiIzFEMjkzOVwiIHN0cm9rZS13aWR0aD1cIjJcIiBzdHJva2UtbGluZWNhcD1cInJvdW5kXCIgc3Ryb2tlLWxpbmVqb2luPVwicm91bmRcIiAvPlxyXG4gICAgICAgICAgPC9zdmc+XHJcbiAgICAgICAgPC9idXR0b24+XHJcbiAgICAgIDwvZGl2PlxyXG4gICAgICA8ZGl2IGNsYXNzPVwiaGlkZS1zY3JvbGxiYXJcIiBzdHlsZT1cImhlaWdodDogOTIlOyBvdmVyZmxvdzogc2Nyb2xsOyBwb3NpdGlvbjogcmVsYXRpdmU7XCIgI3Njcm9sbENvbnRhaW5lcj5cclxuICAgICAgICA8Y2FudmFzICNncmlkQ2FudmFzPlxyXG5cclxuICAgICAgICA8L2NhbnZhcz5cclxuICAgICAgPC9kaXY+XHJcblxyXG4gICAgPC9kaXY+XHJcbiAgPC9kaXY+XHJcblxyXG4gIDxkaXYgKm5nSWY9XCJwbGFub1N0b3JlTGlzdC5sZW5ndGggPiAxXCIgY2xhc3M9XCJjb2wtMTIgbXQtNlwiPlxyXG4gICAgPGRpdiBzdHlsZT1cInBhZGRpbmc6IDBweCAhaW1wb3J0YW50O1wiIGNsYXNzPVwiYy1jYXJkXCI+XHJcbiAgICAgICAgPGxpYi1wYWdpbmF0aW9uIFtpdGVtc1BlclBhZ2VdPVwiaXRlbXNQZXJQYWdlXCIgKHBhZ2VDaGFuZ2UpPVwib25QYWdlQ2hhbmdlKCRldmVudClcIiBbY3VycmVudFBhZ2VdPVwiY3VycmVudFBhZ2VcIiBbdG90YWxJdGVtc109XCJ0b3RhbEl0ZW1zXCJcclxuICAgICAgICAgICAgW3BhZ2luYXRpb25TaXplc109XCJwYWdpbmF0aW9uU2l6ZXNcIiBbcGFnZVNpemVdPVwicGFnZVNpemVcIj48L2xpYi1wYWdpbmF0aW9uPlxyXG4gICAgPC9kaXY+XHJcbjwvZGl2PlxyXG5cclxuPC9kaXY+XHJcblxyXG48bmctdGVtcGxhdGUgI2NvbXBsZXRlTGF5b3V0IGxldC1tb2RhbD5cclxuICA8ZGl2IGNsYXNzPVwiY2FyZFwiPlxyXG4gICAgPGRpdiBzdHlsZT1cIm1pbi1oZWlnaHQ6IHVuc2V0OyBib3JkZXItYm90dG9tOiB1bnNldDsgIHBhZGRpbmctdG9wOiAyLjI1cmVtO1wiIGNsYXNzPVwiY2FyZC1oZWFkZXJcIj5cclxuICAgICAgPGRpdiBjbGFzcz1cImNhcmQtdGl0bGVcIj5cclxuICAgICAgICA8c3BhbiBjbGFzcz1cIm1vZGFsLWhlYWRlci10eHRcIj5Db21wbGV0ZSBMYXlvdXQ8L3NwYW4+XHJcbiAgICAgIDwvZGl2PlxyXG4gICAgPC9kaXY+XHJcbiAgICA8ZGl2IHN0eWxlPVwicGFkZGluZy10b3A6IDFyZW07XCIgY2xhc3M9XCJjYXJkLWJvZHlcIj5cclxuICAgICAgPGRpdiBjbGFzcz1cImZvcm0tY2hlY2tcIj5cclxuICAgICAgICA8aW5wdXQgKG5nTW9kZWxDaGFuZ2UpPVwib25Nb2RhbFR5cGVDaGFuZ2UoJGV2ZW50KVwiIFsobmdNb2RlbCldPVwibWFya0FzQ29tcGxldGVUeXBlXCIgY2xhc3M9XCJmb3JtLWNoZWNrLWlucHV0XCIgdHlwZT1cInJhZGlvXCIgbmFtZT1cIm9uZVwiIGlkPVwic2luZ2xlXCJcclxuICAgICAgICAgIHZhbHVlPVwic2luZ2xlXCI+XHJcbiAgICAgICAgPGRpdiBjbGFzcz1cIm1zLTNcIj5cclxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJtb2RhbC1tYWluLXR4dFwiPk1hcmsgYXMgY29tcGxldGUgZm9yIG9ubHkgPHNwYW5cclxuICAgICAgICAgICAgICBjbGFzcz1cImhpZ2hsaWdodC10eHRcIj57e3NlbGVjdGVkU3RvcmU/LnN0b3JlTmFtZX19PC9zcGFuPjwvZGl2PlxyXG4gICAgICAgICAgPGRpdiBjbGFzcz1cIm1vZGFsLXN1Yi10eHRcIj5UaGlzIGFjdGlvbiB3aWxsIGNvbnNpZGVyZWQgYXMgbGF5b3V0IGNvbXBsZXRpb24gZm9yIHt7c2VsZWN0ZWRTdG9yZT8uc3RvcmVOYW1lfX1cclxuICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgIDwvZGl2PlxyXG4gICAgICA8L2Rpdj5cclxuICAgICAgPGRpdiBjbGFzcz1cInctMTAwIGgtMCBib3JkZXIgbXktNSBib3JkZXItYm90dG9tLWdyZXlcIj48L2Rpdj5cclxuICAgICAgPGRpdiBjbGFzcz1cImZvcm0tY2hlY2sgbWItNVwiPlxyXG4gICAgICAgIDxpbnB1dCAobmdNb2RlbENoYW5nZSk9XCJvbk1vZGFsVHlwZUNoYW5nZSgkZXZlbnQpXCIgWyhuZ01vZGVsKV09XCJtYXJrQXNDb21wbGV0ZVR5cGVcIiBjbGFzcz1cImZvcm0tY2hlY2staW5wdXRcIiB0eXBlPVwicmFkaW9cIiBuYW1lPVwib25lXCIgaWQ9XCJtdWx0aXBsZVwiXHJcbiAgICAgICAgICB2YWx1ZT1cIm11bHRpcGxlXCI+XHJcbiAgICAgICAgPGRpdiBjbGFzcz1cIm1zLTNcIj5cclxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJtb2RhbC1tYWluLXR4dFwiPk1hcmsgYXMgY29tcGxldGUgZm9yIGFsbCB7e3BsYW5vU3RvcmVMaXN0Lmxlbmd0aH19IHN0b3JlczwvZGl2PlxyXG4gICAgICAgIDwvZGl2PlxyXG4gICAgICA8L2Rpdj5cclxuICAgICAgPGRpdiAqbmdJZj1cIm1hcmtBc0NvbXBsZXRlVHlwZSA9PT0gJ211bHRpcGxlJ1wiIGNsYXNzPVwidGFibGUtcmVzcG9uc2l2ZVwiPlxyXG4gICAgICAgIDx0YWJsZSBjbGFzcz1cInRhYmxlXCI+XHJcbiAgICAgICAgICA8dGhlYWQ+XHJcbiAgICAgICAgICAgIDx0ciBzdHlsZT1cImJvcmRlci1ib3R0b206IDFweCBzb2xpZCAjRUFFQ0YwOyBiYWNrZ3JvdW5kOiAjRkNGQ0ZEO1wiPlxyXG4gICAgICAgICAgICAgIDx0aD5cclxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmb3JtLWNoZWNrXCI+XHJcbiAgICAgICAgICAgICAgICAgIDxpbnB1dCAoY2xpY2spPVwib25Nb2RhbFNlbGVjdEFsbCgkZXZlbnQpXCIgWyhuZ01vZGVsKV09XCJpc0FsbFN0b3JlU2VsZWN0ZWRcIiBjbGFzcz1cImZvcm0tY2hlY2staW5wdXQgYy1jaGVja2JveFwiIHR5cGU9XCJjaGVja2JveFwiPlxyXG4gICAgICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJmb3JtLWNoZWNrLWxhYmVsIGNoZWNrLWxhYmVsIG1vZGFsLXN0b3JlTmFtZVwiPlxyXG4gICAgICAgICAgICAgICAgICAgIFN0b3JlIE5hbWVcclxuICAgICAgICAgICAgICAgICAgPC9sYWJlbD5cclxuICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgIDwvdGg+XHJcbiAgICAgICAgICAgIDwvdHI+XHJcbiAgICAgICAgICA8L3RoZWFkPlxyXG4gICAgICAgICAgPHRib2R5PlxyXG4gICAgICAgICAgICA8dHIgc3R5bGU9XCJib3JkZXItYm90dG9tOiAxcHggc29saWQgI0VBRUNGMDtcIiAqbmdGb3I9XCJsZXQgc3RvcmUgb2YgcGxhbm9TdG9yZUxpc3RcIj5cclxuICAgICAgICAgICAgICA8dGQ+XHJcbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZm9ybS1jaGVja1wiPlxyXG4gICAgICAgICAgICAgICAgICA8aW5wdXQgWyhuZ01vZGVsKV09XCJzdG9yZS5zZWxlY3RlZFwiIGNsYXNzPVwiZm9ybS1jaGVjay1pbnB1dCBjLWNoZWNrYm94XCIgdHlwZT1cImNoZWNrYm94XCI+XHJcbiAgICAgICAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cImZvcm0tY2hlY2stbGFiZWwgY2hlY2stbGFiZWwgbW9kYWwtc3RvcmVOYW1lXCI+XHJcbiAgICAgICAgICAgICAgICAgICAge3tzdG9yZT8uc3RvcmVOYW1lfX1cclxuICAgICAgICAgICAgICAgICAgPC9sYWJlbD5cclxuICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgIDwvdGQ+XHJcbiAgICAgICAgICAgIDwvdHI+XHJcbiAgICAgICAgICA8L3Rib2R5PlxyXG4gICAgICAgIDwvdGFibGU+XHJcbiAgICAgIDwvZGl2PlxyXG4gICAgICA8ZGl2IGNsYXNzPVwiZC1mbGV4IGFsaWduLWl0ZW1zLWNlbnRlciBqdXN0aWZ5LWNvbnRlbnQtZW5kXCI+XHJcbiAgICAgICAgPGJ1dHRvbiAoY2xpY2spPVwibW9kYWwuZGlzbWlzcygpXCIgY2xhc3M9XCJidG4gYnRuLW91dGxpbmUgYmctd2hpdGUgbWUtNVwiPkNhbmNlbDwvYnV0dG9uPlxyXG4gICAgICAgIDxidXR0b24gKGNsaWNrKT1cInVwZGF0ZVBsYW5vU3RhdHVzKCk7IG1vZGFsLmRpc21pc3MoKVwiIGNsYXNzPVwiYnRuIGJ0bi1zbSBidG4tcHJpbWFyeSBcIj5Db21wbGV0ZTwvYnV0dG9uPlxyXG4gICAgICA8L2Rpdj5cclxuICAgIDwvZGl2PlxyXG4gIDwvZGl2PlxyXG5cclxuPC9uZy10ZW1wbGF0ZT4iXX0=
|