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.
Files changed (41) hide show
  1. package/README.md +24 -0
  2. package/esm2022/lib/components/create-layout/create-layout.component.mjs +1815 -0
  3. package/esm2022/lib/components/create-layout/popups/add-floor/add-floor.component.mjs +40 -0
  4. package/esm2022/lib/components/create-layout/popups/clear-all-steps/clear-all-steps.component.mjs +16 -0
  5. package/esm2022/lib/components/create-layout/popups/delete-layout/delete-layout.component.mjs +16 -0
  6. package/esm2022/lib/components/custom-select/custom-select.component.mjs +155 -0
  7. package/esm2022/lib/components/layout-builder/layout-builder.component.mjs +56 -0
  8. package/esm2022/lib/components/layout-summary/layout-summary.component.mjs +809 -0
  9. package/esm2022/lib/components/layout-summary/popups/complete-layout/complete-layout.component.mjs +16 -0
  10. package/esm2022/lib/components/reactive-select/reactive-select.component.mjs +87 -0
  11. package/esm2022/lib/components/store-layout-table/store-layout-table.component.mjs +709 -0
  12. package/esm2022/lib/components/store-offcanvas-component/store-offcanvas-component.component.mjs +99 -0
  13. package/esm2022/lib/interfaces/layout-builder.interface.mjs +2 -0
  14. package/esm2022/lib/services/store-builder.service.mjs +99 -0
  15. package/esm2022/lib/tango-store-builder-routing.module.mjs +41 -0
  16. package/esm2022/lib/tango-store-builder.module.mjs +71 -0
  17. package/esm2022/public-api.mjs +5 -0
  18. package/esm2022/tango-app-ui-store-builder.mjs +5 -0
  19. package/esm2022/tango-store-builder.mjs +5 -0
  20. package/fesm2022/tango-app-ui-store-builder.mjs +3947 -0
  21. package/fesm2022/tango-app-ui-store-builder.mjs.map +1 -0
  22. package/fesm2022/tango-store-builder.mjs +3947 -0
  23. package/fesm2022/tango-store-builder.mjs.map +1 -0
  24. package/index.d.ts +5 -0
  25. package/lib/components/create-layout/create-layout.component.d.ts +197 -0
  26. package/lib/components/create-layout/popups/add-floor/add-floor.component.d.ts +16 -0
  27. package/lib/components/create-layout/popups/clear-all-steps/clear-all-steps.component.d.ts +8 -0
  28. package/lib/components/create-layout/popups/delete-layout/delete-layout.component.d.ts +8 -0
  29. package/lib/components/custom-select/custom-select.component.d.ts +33 -0
  30. package/lib/components/layout-builder/layout-builder.component.d.ts +18 -0
  31. package/lib/components/layout-summary/layout-summary.component.d.ts +92 -0
  32. package/lib/components/layout-summary/popups/complete-layout/complete-layout.component.d.ts +8 -0
  33. package/lib/components/reactive-select/reactive-select.component.d.ts +26 -0
  34. package/lib/components/store-layout-table/store-layout-table.component.d.ts +73 -0
  35. package/lib/components/store-offcanvas-component/store-offcanvas-component.component.d.ts +26 -0
  36. package/lib/interfaces/layout-builder.interface.d.ts +23 -0
  37. package/lib/services/store-builder.service.d.ts +33 -0
  38. package/lib/tango-store-builder-routing.module.d.ts +7 -0
  39. package/lib/tango-store-builder.module.d.ts +22 -0
  40. package/package.json +25 -0
  41. 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=