@libs-ui/components-draw-line 0.1.1-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.
@@ -0,0 +1,380 @@
1
+ import { cloneDeep } from '@libs-ui/utils';
2
+ import { MoCanvasCalculatorBranchUtil } from './calculator-branch.util';
3
+ import { MoCanvasCalculatorDirectionElementUtil } from './calculator-diretion-element.until';
4
+ import { MoCanvasConnectNavigationBottomLeftElementUtil } from './line-connect-bottom-left.until';
5
+ export class MoCanvasConnectNavigationNewElementUtil {
6
+ static ELEMENT_MARGIN_BETWEEN_BRANCH_DEFAULT = 32;
7
+ static START_MODE = 'right-left';
8
+ static setXYConnectElements(elementFrom, elementNext, obstacleRect, separatedPoints, curve) {
9
+ this.drawLineConnect(elementFrom, elementNext, obstacleRect, separatedPoints, curve);
10
+ }
11
+ static drawLineConnect(elementFrom, elementNext, obstacleRect, separatedPoints, curve) {
12
+ let start_x = (elementFrom.x ?? 0) + (elementFrom.width ?? 0); // điểm out luôn ở phía bên phải
13
+ let start_y = (elementFrom.y ?? 0) + (elementFrom.height ?? 0) / 2; // điểm out luôn ở phía bên phải
14
+ if (MoCanvasConnectNavigationNewElementUtil.START_MODE === 'bottom-top') {
15
+ // điểm out luôn ở phía bên dưới
16
+ start_x = (elementFrom.x ?? 0) + (elementFrom.width ?? 0) / 2;
17
+ start_y = (elementFrom.y ?? 0) + (elementFrom.height ?? 0);
18
+ }
19
+ if (MoCanvasConnectNavigationNewElementUtil.START_MODE === 'bottom-left') {
20
+ // điểm out luôn ở phía bên dưới
21
+ start_x = (elementFrom.x ?? 0) + (elementFrom.width ?? 0) / 2;
22
+ start_y = (elementFrom.y ?? 0) + (elementFrom.height ?? 0);
23
+ }
24
+ const M_start = { x: start_x, y: start_y };
25
+ const directionX = MoCanvasCalculatorDirectionElementUtil.checkUpDownLeftRight(start_x, elementNext.x, 'x');
26
+ switch (MoCanvasConnectNavigationNewElementUtil.START_MODE) {
27
+ case 'right-left':
28
+ if (directionX === 'left') {
29
+ this.lineConnectLeft(elementNext, elementFrom, M_start, curve, obstacleRect, separatedPoints);
30
+ return;
31
+ }
32
+ this.lineConnectRight(elementNext, M_start, curve, obstacleRect, separatedPoints);
33
+ break;
34
+ case 'bottom-top':
35
+ if (directionX === 'left') {
36
+ this.lineConnectLeftWithBottomStart(elementNext, elementFrom, M_start, curve, obstacleRect, separatedPoints);
37
+ return;
38
+ }
39
+ this.lineConnectRightWithBottomStart(elementNext, M_start, curve, obstacleRect, separatedPoints);
40
+ break;
41
+ case 'bottom-left':
42
+ console.log(directionX);
43
+ if (directionX === 'left') {
44
+ MoCanvasConnectNavigationBottomLeftElementUtil.lineLeft(elementNext, elementFrom, M_start, curve, obstacleRect, separatedPoints);
45
+ return;
46
+ }
47
+ MoCanvasConnectNavigationBottomLeftElementUtil.rightLeft(elementNext, M_start, curve, obstacleRect, separatedPoints);
48
+ break;
49
+ }
50
+ }
51
+ static lineConnectRight(elementNext, start, lineCurve, obstacleRect, separatedPoints) {
52
+ const endPosition = {
53
+ x: (elementNext.x ?? 0) - lineCurve * 3,
54
+ y: (elementNext.y ?? 0) + (elementNext.height ?? 0) / 2,
55
+ };
56
+ const endPositionX = cloneDeep(endPosition);
57
+ let separatedPointsCheckAndAvoidBlocks = [];
58
+ let { path, endPath } = MoCanvasCalculatorDirectionElementUtil.checkAndAvoidBlocks(start.x ?? 0, start.y ?? 0, lineCurve, endPositionX, obstacleRect, separatedPointsCheckAndAvoidBlocks);
59
+ if (Math.abs((start.x ?? 0) - endPosition.x) < 10) {
60
+ path = '';
61
+ endPath = {
62
+ x: start.x,
63
+ y: start.y,
64
+ };
65
+ separatedPointsCheckAndAvoidBlocks = [];
66
+ }
67
+ separatedPoints.splice(separatedPoints.length, 0, ...separatedPointsCheckAndAvoidBlocks);
68
+ // sau khi đã đi ngang và tránh các khối, tiếp theo là đi tiếp hướng lên xuống để về khối cần nối tới, cần check xem điểm end X nó đang ở hướng nào
69
+ const directionY = MoCanvasCalculatorDirectionElementUtil.checkUpDownLeftRight(endPath.y, endPosition.y, 'y');
70
+ if (directionY === 'center') {
71
+ const LEnd = { x: elementNext.x ?? 0, y: endPath.y };
72
+ separatedPoints.push({ start: endPath, end: LEnd, mode: 'horizontal', id: 'f' });
73
+ return {
74
+ dPath: `${path} L ${LEnd.x} ${LEnd.y}`,
75
+ endPath: LEnd,
76
+ };
77
+ }
78
+ let lineCurveSubY = lineCurve;
79
+ if (Math.abs((endPath.y ?? 0) - endPosition.y) < lineCurve * 2) {
80
+ lineCurveSubY = Math.abs((endPath.y ?? 0) - endPosition.y) / 2;
81
+ const coordQ1 = MoCanvasCalculatorDirectionElementUtil.drawLineQ({ x: endPath.x ?? 0, y: endPath.y ?? 0 }, `right-${directionY === 'above' ? 'above' : 'under'}`, lineCurveSubY * 2, lineCurveSubY); // tính đoạn cong từ đường ngang sang đường thẳng
82
+ const pathQ1 = `Q ${coordQ1.x1},${coordQ1.y1} ${coordQ1.x},${coordQ1.y}`; // từ ngang sang thẳng phải có đường cong
83
+ const coordQ2 = MoCanvasCalculatorDirectionElementUtil.drawLineQ({ x: coordQ1.x ?? 0, y: coordQ1.y ?? 0 }, `${directionY === 'above' ? 'above' : 'under'}-right`, lineCurveSubY * 2, lineCurveSubY); // tính đoạn cong từ đường thẳng sang ngang
84
+ const pathQ2 = `Q ${coordQ2.x1},${coordQ2.y1} ${coordQ2.x},${coordQ2.y}`;
85
+ separatedPoints.push({ start: endPath, end: { x: coordQ1.x ?? 0, y: coordQ1.y ?? 0 }, mode: 'horizontal-single-curve', id: 'g' });
86
+ separatedPoints.push({ start: { x: coordQ1.x ?? 0, y: coordQ1.y ?? 0 }, end: { x: coordQ2.x ?? 0, y: coordQ2.y ?? 0 }, mode: 'vertical-single-curve', id: 'j' });
87
+ const lineClose = this.closeLine({ x: coordQ2.x ?? 0, y: coordQ2.y ?? 0 }, endPosition, lineCurve, elementNext, separatedPoints);
88
+ return {
89
+ dPath: `${path} ${pathQ1} ${pathQ2} ${lineClose}`,
90
+ };
91
+ }
92
+ const coordQ1 = MoCanvasCalculatorDirectionElementUtil.drawLineQ({ x: endPath.x ?? 0, y: endPath.y ?? 0 }, `right-${directionY === 'above' ? 'above' : 'under'}`, lineCurve, lineCurve); // tính đoạn cong từ đường ngang sang đường thẳng
93
+ const pathQ1 = `Q ${coordQ1.x1},${coordQ1.y1} ${coordQ1.x},${coordQ1.y}`; // từ ngang sang thẳng phải có đường cong
94
+ const endPositionY = cloneDeep(endPosition);
95
+ endPositionY.y = MoCanvasCalculatorBranchUtil.mathOperatorsCalculation(directionY, endPosition.y, lineCurve);
96
+ const straightLine = MoCanvasCalculatorDirectionElementUtil.checkAndAvoidBlocksY(coordQ1.x ?? 0, coordQ1.y ?? 0, lineCurve, endPositionY, directionY, obstacleRect, separatedPoints);
97
+ const coordQ2 = MoCanvasCalculatorDirectionElementUtil.drawLineQ({ x: straightLine.endPath.x ?? 0, y: straightLine.endPath.y ?? 0 }, `${directionY === 'above' ? 'above' : 'under'}-right`, lineCurve, lineCurve); // tính đoạn cong từ đường thẳng sang ngang
98
+ const pathQ2 = `Q ${coordQ2.x1},${coordQ2.y1} ${coordQ2.x},${coordQ2.y}`; // từ ngang sang thẳng phải có đường cong
99
+ separatedPoints.push({ start: { x: endPath.x ?? 0, y: endPath.y }, end: { x: coordQ1.x ?? 0, y: coordQ1.y ?? 0 }, mode: 'horizontal-single-curve', id: 'g' });
100
+ separatedPoints.push({ start: { x: straightLine.endPath.x ?? 0, y: straightLine.endPath.y ?? 0 }, end: { x: coordQ2.x ?? 0, y: coordQ2.y ?? 0 }, mode: 'vertical-single-curve', id: 'j' });
101
+ const lineClose = this.closeLine({ x: coordQ2.x ?? 0, y: coordQ2.y ?? 0 }, endPosition, lineCurve, elementNext, separatedPoints);
102
+ return {
103
+ dPath: `${path} ${pathQ1} ${straightLine.path} ${pathQ2} ${lineClose}`,
104
+ endPath: straightLine.endPath,
105
+ };
106
+ }
107
+ static lineConnectLeft(elementNext, elementFrom, start, lineCurve, obstacleRect, separatedPoints) {
108
+ const endPositionOrigin = {
109
+ x: (elementNext.x ?? 0) - lineCurve * 1.5,
110
+ y: (elementNext.y ?? 0) + (elementNext.height ?? 0) / 2,
111
+ };
112
+ const endPosition = cloneDeep(endPositionOrigin);
113
+ const directionStartY = MoCanvasCalculatorDirectionElementUtil.checkUpDownLeftRight(start.y, endPositionOrigin.y, 'y');
114
+ const endY = directionStartY === 'under' || directionStartY === 'center' ? (elementNext.y ?? 0) : (elementNext.y ?? 0) + (elementNext.height ?? 0);
115
+ endPosition.y = MoCanvasCalculatorBranchUtil.mathOperatorsCalculation(directionStartY, endY, lineCurve * 2);
116
+ const pathQ = MoCanvasCalculatorDirectionElementUtil.drawLineQ({ x: (start.x ?? 0) + 10, y: start.y ?? 0 }, `right-${directionStartY === 'under' ? 'under' : 'above'}`, lineCurve, lineCurve);
117
+ const startQL = { lx: pathQ.x, ly: MoCanvasCalculatorBranchUtil.mathOperatorsCalculation(directionStartY, pathQ.y ?? 0, (elementFrom.height ?? 0) / 2, true) };
118
+ separatedPoints.push({ start: { x: start.x ?? 0, y: start.y ?? 0 }, end: { x: pathQ.x ?? 0, y: pathQ.y ?? 0 }, mode: 'horizontal-single-curve', id: '1' });
119
+ separatedPoints.push({ start: { x: pathQ.x ?? 0, y: pathQ.y ?? 0 }, end: { x: startQL.lx ?? 0, y: startQL.ly }, mode: 'horizontal', id: '2' });
120
+ if (directionStartY === 'center') {
121
+ const coordQ1 = MoCanvasCalculatorDirectionElementUtil.drawLineQ({ x: startQL.lx ?? 0, y: startQL.ly ?? 0 }, `above-left`, lineCurve, lineCurve); // tính đoạn cong từ đường ngang sang đường thẳng
122
+ separatedPoints.push({ start: { x: startQL.lx ?? 0, y: startQL.ly }, end: { x: coordQ1.x ?? 0, y: coordQ1.y ?? 0 }, mode: 'vertical-single-curve', id: '3' });
123
+ const endPath = MoCanvasCalculatorDirectionElementUtil.checkAndAvoidBlocksLeft(coordQ1.x ?? 0, coordQ1.y ?? 0, lineCurve, endPosition, obstacleRect, separatedPoints);
124
+ const directionStartY2 = MoCanvasCalculatorDirectionElementUtil.checkUpDownLeftRight(endPath.y, endPositionOrigin.y, 'y');
125
+ const coordQ2 = MoCanvasCalculatorDirectionElementUtil.drawLineQ({ x: endPath.x ?? 0, y: endPath.y ?? 0 }, `left-${directionStartY2 === 'above' ? 'above' : 'under'}`, lineCurve, lineCurve); // tính đoạn cong từ đường ngang sang đường thẳng
126
+ separatedPoints.push({ start: { x: endPath.x ?? 0, y: endPath.y ?? 0 }, end: { x: coordQ2.x ?? 0, y: coordQ2.y ?? 0 }, mode: 'horizontal-single-curve', id: '4' });
127
+ this.closeLine({ x: coordQ2.x ?? 0, y: coordQ2.y ?? 0 }, endPositionOrigin, lineCurve, elementNext, separatedPoints);
128
+ return {
129
+ dPath: ``,
130
+ };
131
+ }
132
+ const straightLine = MoCanvasCalculatorDirectionElementUtil.checkAndAvoidBlocksYLeft(startQL.lx ?? 0, startQL.ly ?? 0, lineCurve, endPosition, directionStartY, obstacleRect, separatedPoints);
133
+ if (Math.abs((endPosition.x ?? 0) - (straightLine.endPath.x ?? 0)) <= lineCurve * 2) {
134
+ endPosition.x = straightLine.endPath.x;
135
+ }
136
+ if ((directionStartY === 'under' && startQL.ly > endPosition.y) || (directionStartY === 'above' && startQL.ly < endPosition.y) || startQL.ly === endPosition.y) {
137
+ let condition = true;
138
+ while (condition) {
139
+ const checkAndAvoidBlocksYLeft = separatedPoints.findIndex((item) => item.id === 'checkAndAvoidBlocksYLeft');
140
+ if (checkAndAvoidBlocksYLeft !== -1) {
141
+ separatedPoints.splice(checkAndAvoidBlocksYLeft, 1);
142
+ }
143
+ if (checkAndAvoidBlocksYLeft === -1) {
144
+ condition = false;
145
+ }
146
+ }
147
+ straightLine.path = '';
148
+ straightLine.endPath = {
149
+ x: startQL.lx ?? 0,
150
+ y: startQL.ly ?? 0,
151
+ };
152
+ }
153
+ if (endPosition.x === straightLine.endPath.x) {
154
+ separatedPoints.push({ start: straightLine.endPath, end: endPositionOrigin, mode: 'vertical-single-curve', id: '6a ' + directionStartY });
155
+ this.closeLine({ x: endPositionOrigin.x ?? 0, y: endPositionOrigin.y ?? 0 }, endPositionOrigin, lineCurve, elementNext, separatedPoints);
156
+ return;
157
+ }
158
+ // kiểm tra ngay khi cua có vướng ai không rồi hẵng vẽ Q1,
159
+ const elementBlockRoad = MoCanvasCalculatorDirectionElementUtil.checkLinePassBlockHorizontal(straightLine.endPath.x ?? 0, endPosition.x, straightLine.endPath.y ?? 0, 'x', obstacleRect);
160
+ const directionNextX = MoCanvasCalculatorDirectionElementUtil.checkUpDownLeftRight(straightLine.endPath.x ?? 0, endPositionOrigin.x, 'x');
161
+ const coordQ1 = MoCanvasCalculatorDirectionElementUtil.drawLineQ({ x: straightLine.endPath.x ?? 0, y: straightLine.endPath.y ?? 0 }, `${directionStartY}-${directionNextX}`, lineCurve, lineCurve); // tính đoạn cong từ đường ngang sang đường thẳng
162
+ const elementBlockRoadX = (elementBlockRoad?.x ?? 0) + (elementBlockRoad?.width ?? 0);
163
+ if (elementBlockRoad && Math.abs(elementBlockRoadX - (straightLine.endPath.x ?? 0)) <= lineCurve * 2) {
164
+ coordQ1.x1 = straightLine.endPath.x ?? 0;
165
+ coordQ1.y1 = straightLine.endPath.y ?? 0;
166
+ coordQ1.x = straightLine.endPath.x ?? 0;
167
+ coordQ1.y = straightLine.endPath.y ?? 0;
168
+ }
169
+ separatedPoints.push({ start: straightLine.endPath, end: { x: coordQ1.x ?? 0, y: coordQ1.y ?? 0 }, mode: 'vertical-single-curve', id: '6a ' + directionStartY });
170
+ const endPath = MoCanvasCalculatorDirectionElementUtil.checkAndAvoidBlocksLeft(coordQ1.x ?? 0, coordQ1.y ?? 0, lineCurve, endPosition, obstacleRect, separatedPoints);
171
+ const directionStartY2 = MoCanvasCalculatorDirectionElementUtil.checkUpDownLeftRight(endPath.y, endPositionOrigin.y, 'y');
172
+ const directionNextY = MoCanvasCalculatorDirectionElementUtil.checkUpDownLeftRight(coordQ1.x ?? 0, endPath.x, 'x');
173
+ const coordQ2 = MoCanvasCalculatorDirectionElementUtil.drawLineQ({ x: endPath.x ?? 0, y: endPath.y ?? 0 }, `${directionNextY}-${directionStartY2 === 'above' ? 'above' : 'under'}`, lineCurve, lineCurve); // tính đoạn cong từ đường ngang sang đường thẳng
174
+ separatedPoints.push({ start: endPath, end: { x: coordQ2.x ?? 0, y: coordQ2.y ?? 0 }, mode: 'horizontal-single-curve', id: '6' });
175
+ this.closeLine({ x: coordQ2.x ?? 0, y: coordQ2.y ?? 0 }, endPositionOrigin, lineCurve, elementNext, separatedPoints);
176
+ return {
177
+ dPath: ``,
178
+ };
179
+ }
180
+ static closeLine(start, end, lineCurve, elementNext, separatedPoints) {
181
+ const directionY = MoCanvasCalculatorDirectionElementUtil.checkUpDownLeftRight(start.y, end.y, 'y');
182
+ if (start.y === end.y) {
183
+ separatedPoints.push({ start, end: { x: elementNext.x ?? 0, y: end.y ?? 0 }, mode: 'horizontal', id: '7' });
184
+ return `L ${elementNext.x} ${end.y}`;
185
+ }
186
+ const line = { x: start.x, y: start.y };
187
+ const endPoint = {
188
+ x: elementNext.x,
189
+ y: end.y,
190
+ };
191
+ let pathQ1 = '';
192
+ if (Math.abs(start.y - end.y) > lineCurve) {
193
+ const toY = MoCanvasCalculatorBranchUtil.mathOperatorsCalculation(directionY, end.y, lineCurve);
194
+ line.y = toY;
195
+ const directionX = MoCanvasCalculatorDirectionElementUtil.checkUpDownLeftRight(line.x, elementNext.x, 'x');
196
+ const coordQ1 = MoCanvasCalculatorDirectionElementUtil.drawLineQ({ x: line.x ?? 0, y: line.y ?? 0 }, `${directionY === 'above' ? 'above' : 'under'}-${directionX}`, lineCurve, lineCurve); // tính đoạn cong từ đường ngang sang đường thẳng
197
+ let lineL = '';
198
+ if (coordQ1.y === end.y) {
199
+ lineL = `L ${endPoint.x} ${endPoint.y}`;
200
+ }
201
+ pathQ1 = `Q ${coordQ1.x1},${coordQ1.y1} ${coordQ1.x},${coordQ1.y} ${lineL}`; // từ ngang sang thẳng phải có đường cong
202
+ }
203
+ separatedPoints.push({ start, end: line, mode: 'horizontal', id: '8' });
204
+ separatedPoints.push({ start: line, end: endPoint, mode: 'vertical-single-curve', id: '9' });
205
+ return `L ${line.x} ${line.y} ${pathQ1}`;
206
+ }
207
+ static lineConnectLeftWithBottomStart(elementNext, elementFrom, start, lineCurve, obstacleRect, separatedPoints) {
208
+ const endPositionOrigin = {
209
+ x: (elementNext.x ?? 0) + (elementNext.width ?? 0) / 2,
210
+ y: (elementNext.y ?? 0) - lineCurve,
211
+ };
212
+ const endPosition = cloneDeep(endPositionOrigin);
213
+ const directionStartY = MoCanvasCalculatorDirectionElementUtil.checkUpDownLeftRight(start.y, endPositionOrigin.y, 'y');
214
+ const endY = elementNext.y ?? 0;
215
+ console.log('directionStartY', directionStartY);
216
+ if (directionStartY === 'under') {
217
+ endPosition.y = endY - lineCurve * 3;
218
+ }
219
+ const startQL = { lx: start.x, ly: (start.y ?? 0) + lineCurve };
220
+ const line = {
221
+ start: { x: start.x ?? 0, y: start.y ?? 0 },
222
+ end: { x: startQL.lx ?? 0, y: startQL.ly ?? 0 },
223
+ };
224
+ const newEnd = { x: elementFrom.x - lineCurve * 2, y: line.end.y - lineCurve };
225
+ if (directionStartY === 'above') {
226
+ line.end = { x: (start.x ?? 0) - lineCurve, y: (start.y ?? 0) + lineCurve * 2 };
227
+ separatedPoints.push({ start: line.end, end: newEnd, mode: 'horizontal-single-curve', id: '1' });
228
+ }
229
+ separatedPoints.push({ start: line.start, end: line.end, mode: 'vertical-single-curve', id: '1' }); // line vẽ đi khỏi khối đầu tiên
230
+ const startNewLine = directionStartY === 'above' ? newEnd : line.end;
231
+ if (directionStartY === 'center') {
232
+ const coordQ1 = MoCanvasCalculatorDirectionElementUtil.drawLineQ({ x: startQL.lx ?? 0, y: startQL.ly ?? 0 }, `above-left`, lineCurve, lineCurve); // tính đoạn cong từ đường ngang sang đường thẳng
233
+ // từ ngang sang thẳng phải có đường cong
234
+ separatedPoints.push({ start: { x: startQL.lx ?? 0, y: startQL.ly }, end: { x: coordQ1.x ?? 0, y: coordQ1.y ?? 0 }, mode: 'vertical-single-curve', id: '3' });
235
+ const endPath = MoCanvasCalculatorDirectionElementUtil.checkAndAvoidBlocksLeft(coordQ1.x ?? 0, coordQ1.y ?? 0, lineCurve, endPosition, obstacleRect, separatedPoints);
236
+ const directionStartY2 = MoCanvasCalculatorDirectionElementUtil.checkUpDownLeftRight(endPath.y, endPositionOrigin.y, 'y');
237
+ const coordQ2 = MoCanvasCalculatorDirectionElementUtil.drawLineQ({ x: endPath.x ?? 0, y: endPath.y ?? 0 }, `left-${directionStartY2 === 'above' ? 'above' : 'under'}`, lineCurve, lineCurve); // tính đoạn cong từ đường ngang sang đường thẳng
238
+ // từ ngang sang thẳng phải có đường cong
239
+ separatedPoints.push({ start: { x: endPath.x ?? 0, y: endPath.y ?? 0 }, end: { x: coordQ2.x ?? 0, y: coordQ2.y ?? 0 }, mode: 'horizontal-single-curve', id: '4' });
240
+ this.closeLine({ x: coordQ2.x ?? 0, y: coordQ2.y ?? 0 }, endPositionOrigin, lineCurve, elementNext, separatedPoints);
241
+ return {
242
+ dPath: ``,
243
+ };
244
+ }
245
+ // kiểm tra hướng thẳng đến end, nếu có khối thì tránh
246
+ const straightLine = MoCanvasCalculatorDirectionElementUtil.checkAndAvoidBlocksYLeft(startNewLine.x ?? 0, startNewLine.y ?? 0, lineCurve, endPosition, directionStartY, obstacleRect, separatedPoints);
247
+ const directionStartX = MoCanvasCalculatorDirectionElementUtil.checkUpDownLeftRight(start.x, endPositionOrigin.x, 'x');
248
+ if (directionStartX === 'center' && directionStartY === 'under') {
249
+ this.closeLineWithLineTopBottom({ x: straightLine.endPath.x ?? 0, y: straightLine.endPath.y ?? 0 }, endPositionOrigin, lineCurve, elementNext, separatedPoints);
250
+ return {
251
+ dPath: ``,
252
+ };
253
+ }
254
+ if ((directionStartY === 'under' && startQL.ly > endPosition.y) || (directionStartY === 'above' && startQL.ly < endPosition.y) || startQL.ly === endPosition.y) {
255
+ let condition = true;
256
+ while (condition) {
257
+ const checkAndAvoidBlocksYLeft = separatedPoints.findIndex((item) => item.id === 'checkAndAvoidBlocksYLeft');
258
+ if (checkAndAvoidBlocksYLeft !== -1) {
259
+ separatedPoints.splice(checkAndAvoidBlocksYLeft, 1);
260
+ }
261
+ if (checkAndAvoidBlocksYLeft === -1) {
262
+ condition = false;
263
+ }
264
+ }
265
+ straightLine.path = '';
266
+ straightLine.endPath = {
267
+ x: startQL.lx ?? 0,
268
+ y: startQL.ly ?? 0,
269
+ };
270
+ }
271
+ // kiểm tra ngay khi cua có vướng ai không rồi hẵng vẽ Q1
272
+ const elementBlockRoad = MoCanvasCalculatorDirectionElementUtil.checkLinePassBlockHorizontal(straightLine.endPath.x ?? 0, endPosition.x, straightLine.endPath.y ?? 0, 'x', obstacleRect);
273
+ const directionNextX = MoCanvasCalculatorDirectionElementUtil.checkUpDownLeftRight(straightLine.endPath.x ?? 0, endPositionOrigin.x, 'x');
274
+ const coordQ1 = MoCanvasCalculatorDirectionElementUtil.drawLineQ({ x: straightLine.endPath.x ?? 0, y: straightLine.endPath.y ?? 0 }, `${directionStartY}-${directionNextX}`, lineCurve, lineCurve); // tính đoạn cong từ đường ngang sang đường thẳng
275
+ const elementBlockRoadX = (elementBlockRoad?.x ?? 0) + (elementBlockRoad?.width ?? 0);
276
+ if (elementBlockRoad && Math.abs(elementBlockRoadX - (straightLine.endPath.x ?? 0)) <= lineCurve * 2) {
277
+ coordQ1.x1 = straightLine.endPath.x ?? 0;
278
+ coordQ1.y1 = straightLine.endPath.y ?? 0;
279
+ coordQ1.x = straightLine.endPath.x ?? 0;
280
+ coordQ1.y = straightLine.endPath.y ?? 0;
281
+ }
282
+ // kiểm tra và vẽ hướng ngang
283
+ const directionXToEnd = MoCanvasCalculatorDirectionElementUtil.checkUpDownLeftRight(coordQ1.x ?? 0, endPositionOrigin.x, 'x');
284
+ endPosition.x = MoCanvasCalculatorBranchUtil.mathOperatorsCalculation(directionXToEnd, endPosition.x, lineCurve);
285
+ if (Math.abs((coordQ1.y ?? 0) - endPosition.y) <= lineCurve) {
286
+ endPosition.y -= lineCurve;
287
+ }
288
+ const pathHorizontal = [];
289
+ const endPath = MoCanvasCalculatorDirectionElementUtil.checkAndAvoidBlocksLeft(coordQ1.x ?? 0, coordQ1.y ?? 0, lineCurve, endPosition, obstacleRect, pathHorizontal);
290
+ if (directionXToEnd === 'left' && endPath.x > (coordQ1.x ?? 0)) {
291
+ separatedPoints.push({ start: straightLine.endPath, end: endPositionOrigin, mode: 'vertical', id: '6a ' + directionStartY });
292
+ this.closeLineWithLineTopBottom(endPositionOrigin, endPositionOrigin, lineCurve, elementNext, separatedPoints);
293
+ return;
294
+ }
295
+ separatedPoints.push(...pathHorizontal);
296
+ separatedPoints.push({ start: straightLine.endPath, end: { x: coordQ1.x ?? 0 - 10, y: coordQ1.y ?? 0 }, mode: 'vertical-single-curve', id: '6a ' + directionStartY });
297
+ this.closeLineWithLineTopBottom({ x: endPath.x ?? 0, y: endPath.y ?? 0 }, endPositionOrigin, lineCurve, elementNext, separatedPoints);
298
+ return {
299
+ dPath: ``,
300
+ };
301
+ }
302
+ static closeLineWithLineTopBottom(start, end, lineCurve, elementNext, separatedPoints) {
303
+ const directionX = MoCanvasCalculatorDirectionElementUtil.checkUpDownLeftRight(start.x, end.x, 'x');
304
+ if (start.x === end.x) {
305
+ separatedPoints.push({ start, end: { x: (elementNext.x ?? 0) + (elementNext.width ?? 0) / 2, y: elementNext.y ?? 0 }, mode: 'horizontal', id: '7' });
306
+ return `L ${elementNext.x} ${end.y}`;
307
+ }
308
+ const line = { x: start.x, y: start.y };
309
+ const endPoint = {
310
+ x: end.x,
311
+ y: elementNext.y,
312
+ };
313
+ const pathQ1 = '';
314
+ if (Math.abs(start.x - end.x) > lineCurve) {
315
+ const directionY = MoCanvasCalculatorDirectionElementUtil.checkUpDownLeftRight(start.y, endPoint.y, 'y');
316
+ const toX = MoCanvasCalculatorBranchUtil.mathOperatorsCalculation(directionX, end.x, lineCurve);
317
+ const toY = MoCanvasCalculatorBranchUtil.mathOperatorsCalculation(directionY, end.y, lineCurve);
318
+ line.x = toX;
319
+ line.y = toY;
320
+ separatedPoints.push({ start: start, end: line, mode: 'vertical-single-curve', id: '9' });
321
+ }
322
+ separatedPoints.push({ start: line, end: endPoint, mode: 'horizontal-single-curve', id: '9' });
323
+ return `L ${line.x} ${line.y} ${pathQ1}`;
324
+ }
325
+ static lineConnectRightWithBottomStart(elementNext, start, lineCurve, obstacleRect, separatedPoints) {
326
+ const endPosition = {
327
+ x: (elementNext.x ?? 0) + (elementNext.width ?? 0) / 2,
328
+ y: (elementNext.y ?? 0) - lineCurve,
329
+ };
330
+ // vẽ 1 đường thẳng từ điểm start ra ngoài đã
331
+ const end = { x: (start.x ?? 0) + 10, y: (start.y ?? 0) + 20 };
332
+ separatedPoints.push({ start: { x: start.x ?? 0, y: start.y ?? 0 }, end: end, mode: 'vertical-single-curve', id: '1' });
333
+ const endPositionX = cloneDeep(endPosition);
334
+ endPositionX.x -= 10;
335
+ let separatedPointsCheckAndAvoidBlocks = [];
336
+ let { path, endPath } = MoCanvasCalculatorDirectionElementUtil.checkAndAvoidBlocks(end.x ?? 0, end.y ?? 0, lineCurve, endPositionX, obstacleRect, separatedPointsCheckAndAvoidBlocks);
337
+ if (Math.abs((start.x ?? 0) - endPosition.x) < 10) {
338
+ path = '';
339
+ endPath = {
340
+ x: start.x,
341
+ y: start.y,
342
+ };
343
+ separatedPointsCheckAndAvoidBlocks = [];
344
+ }
345
+ separatedPoints.splice(separatedPoints.length, 0, ...separatedPointsCheckAndAvoidBlocks);
346
+ // sau khi đã đi ngang và tránh các khối, tiếp theo là đi tiếp hướng lên xuống để về khối cần nối tới, cần check xem điểm end X nó đang ở hướng nào
347
+ const directionY = MoCanvasCalculatorDirectionElementUtil.checkUpDownLeftRight(endPath.y, endPosition.y, 'y');
348
+ if (directionY === 'center') {
349
+ const LEnd = { x: elementNext.x ?? 0, y: endPath.y };
350
+ separatedPoints.push({ start: endPath, end: LEnd, mode: 'horizontal', id: 'f' });
351
+ // đoạn này chưa oce
352
+ this.closeLineWithLineTopBottom(LEnd, endPosition, lineCurve, elementNext, separatedPoints);
353
+ return {
354
+ dPath: `${path} L ${LEnd.x} ${LEnd.y}`,
355
+ endPath: LEnd,
356
+ };
357
+ }
358
+ const coordQ1 = MoCanvasCalculatorDirectionElementUtil.drawLineQ({ x: endPath.x ?? 0, y: endPath.y ?? 0 }, `right-${directionY === 'above' ? 'above' : 'under'}`, lineCurve, lineCurve); // tính đoạn cong từ đường ngang sang đường thẳng
359
+ const endPositionY = cloneDeep(endPosition);
360
+ endPositionY.y = MoCanvasCalculatorBranchUtil.mathOperatorsCalculation(directionY, endPosition.y, lineCurve) - 10;
361
+ // cần check khi đi thẳng lên có vướng khối nào không để tiến lên
362
+ const elementBlockRoadStraightLineY = MoCanvasCalculatorDirectionElementUtil.checkBlocksElementStraightY((endPath.x ?? 0) + 10, endPath.y ?? 0, endPositionY, obstacleRect);
363
+ if (elementBlockRoadStraightLineY) {
364
+ coordQ1.x = (elementBlockRoadStraightLineY.x ?? 0) + (elementBlockRoadStraightLineY.width ?? 0) + lineCurve;
365
+ }
366
+ separatedPoints.push({ start: { x: endPath.x ?? 0, y: endPath.y }, end: { x: coordQ1.x ?? 0, y: coordQ1.y ?? 0 }, mode: 'horizontal-single-curve', id: 'g' });
367
+ let avoidBlocksYLine = [];
368
+ const straightLine = MoCanvasCalculatorDirectionElementUtil.checkAndAvoidBlocksY(coordQ1.x ?? 0, coordQ1.y ?? 0, lineCurve, endPositionY, directionY, obstacleRect, avoidBlocksYLine);
369
+ if (directionY === 'under' && (coordQ1.y ?? 0) > endPositionY.y) {
370
+ avoidBlocksYLine = [];
371
+ straightLine.endPath = { x: coordQ1.x ?? 0, y: coordQ1.y ?? 0 };
372
+ }
373
+ separatedPoints.push(...avoidBlocksYLine);
374
+ this.closeLineWithLineTopBottom({ x: straightLine.endPath.x ?? 0, y: straightLine.endPath.y ?? 0 }, endPosition, lineCurve, elementNext, separatedPoints);
375
+ return {
376
+ dPath: ``,
377
+ };
378
+ }
379
+ }
380
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29ubmVjdC1uYXZpZ2F0aW9uLW5ldy1lbGVtZW50LnV0aWwuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9saWJzLXVpL2NvbXBvbmVudHMvZHJhdy1saW5lL3NyYy91dGlsL2Nvbm5lY3QtbmF2aWdhdGlvbi1uZXctZWxlbWVudC51dGlsLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUUzQyxPQUFPLEVBQUUsNEJBQTRCLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQUN4RSxPQUFPLEVBQUUsc0NBQXNDLEVBQUUsTUFBTSxxQ0FBcUMsQ0FBQztBQUM3RixPQUFPLEVBQUUsOENBQThDLEVBQUUsTUFBTSxrQ0FBa0MsQ0FBQztBQU1sRyxNQUFNLE9BQU8sdUNBQXVDO0lBQ2xELE1BQU0sQ0FBQyxxQ0FBcUMsR0FBRyxFQUFFLENBQUM7SUFDbEQsTUFBTSxDQUFDLFVBQVUsR0FBRyxZQUFZLENBQUM7SUFFakMsTUFBTSxDQUFDLG9CQUFvQixDQUFDLFdBQWtCLEVBQUUsV0FBa0IsRUFBRSxZQUFxQixFQUFFLGVBQStCLEVBQUUsS0FBYTtRQUN2SSxJQUFJLENBQUMsZUFBZSxDQUFDLFdBQVcsRUFBRSxXQUFXLEVBQUUsWUFBWSxFQUFFLGVBQWUsRUFBRSxLQUFLLENBQUMsQ0FBQztJQUN2RixDQUFDO0lBRUQsTUFBTSxDQUFDLGVBQWUsQ0FBQyxXQUFrQixFQUFFLFdBQWtCLEVBQUUsWUFBcUIsRUFBRSxlQUErQixFQUFFLEtBQWE7UUFDbEksSUFBSSxPQUFPLEdBQUcsQ0FBQyxXQUFXLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxHQUFHLENBQUMsV0FBVyxDQUFDLEtBQUssSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLGdDQUFnQztRQUMvRixJQUFJLE9BQU8sR0FBRyxDQUFDLFdBQVcsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLEdBQUcsQ0FBQyxXQUFXLENBQUMsTUFBTSxJQUFJLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLGdDQUFnQztRQUVwRyxJQUFJLHVDQUF1QyxDQUFDLFVBQVUsS0FBSyxZQUFZLEVBQUUsQ0FBQztZQUN4RSxnQ0FBZ0M7WUFDaEMsT0FBTyxHQUFHLENBQUMsV0FBVyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsR0FBRyxDQUFDLFdBQVcsQ0FBQyxLQUFLLElBQUksQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1lBQzlELE9BQU8sR0FBRyxDQUFDLFdBQVcsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLEdBQUcsQ0FBQyxXQUFXLENBQUMsTUFBTSxJQUFJLENBQUMsQ0FBQyxDQUFDO1FBQzdELENBQUM7UUFDRCxJQUFJLHVDQUF1QyxDQUFDLFVBQVUsS0FBSyxhQUFhLEVBQUUsQ0FBQztZQUN6RSxnQ0FBZ0M7WUFDaEMsT0FBTyxHQUFHLENBQUMsV0FBVyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsR0FBRyxDQUFDLFdBQVcsQ0FBQyxLQUFLLElBQUksQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1lBQzlELE9BQU8sR0FBRyxDQUFDLFdBQVcsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLEdBQUcsQ0FBQyxXQUFXLENBQUMsTUFBTSxJQUFJLENBQUMsQ0FBQyxDQUFDO1FBQzdELENBQUM7UUFDRCxNQUFNLE9BQU8sR0FBVyxFQUFFLENBQUMsRUFBRSxPQUFPLEVBQUUsQ0FBQyxFQUFFLE9BQU8sRUFBRSxDQUFDO1FBRW5ELE1BQU0sVUFBVSxHQUFHLHNDQUFzQyxDQUFDLG9CQUFvQixDQUFDLE9BQU8sRUFBRSxXQUFXLENBQUMsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDO1FBRTVHLFFBQVEsdUNBQXVDLENBQUMsVUFBVSxFQUFFLENBQUM7WUFDM0QsS0FBSyxZQUFZO2dCQUNmLElBQUksVUFBVSxLQUFLLE1BQU0sRUFBRSxDQUFDO29CQUMxQixJQUFJLENBQUMsZUFBZSxDQUFDLFdBQVcsRUFBRSxXQUFXLEVBQUUsT0FBTyxFQUFFLEtBQUssRUFBRSxZQUFZLEVBQUUsZUFBZSxDQUFDLENBQUM7b0JBRTlGLE9BQU87Z0JBQ1QsQ0FBQztnQkFDRCxJQUFJLENBQUMsZ0JBQWdCLENBQUMsV0FBVyxFQUFFLE9BQU8sRUFBRSxLQUFLLEVBQUUsWUFBWSxFQUFFLGVBQWUsQ0FBQyxDQUFDO2dCQUNsRixNQUFNO1lBRVIsS0FBSyxZQUFZO2dCQUNmLElBQUksVUFBVSxLQUFLLE1BQU0sRUFBRSxDQUFDO29CQUMxQixJQUFJLENBQUMsOEJBQThCLENBQUMsV0FBVyxFQUFFLFdBQVcsRUFBRSxPQUFPLEVBQUUsS0FBSyxFQUFFLFlBQVksRUFBRSxlQUFlLENBQUMsQ0FBQztvQkFFN0csT0FBTztnQkFDVCxDQUFDO2dCQUNELElBQUksQ0FBQywrQkFBK0IsQ0FBQyxXQUFXLEVBQUUsT0FBTyxFQUFFLEtBQUssRUFBRSxZQUFZLEVBQUUsZUFBZSxDQUFDLENBQUM7Z0JBQ2pHLE1BQU07WUFFUixLQUFLLGFBQWE7Z0JBQ2hCLE9BQU8sQ0FBQyxHQUFHLENBQUMsVUFBVSxDQUFDLENBQUM7Z0JBQ3hCLElBQUksVUFBVSxLQUFLLE1BQU0sRUFBRSxDQUFDO29CQUMxQiw4Q0FBOEMsQ0FBQyxRQUFRLENBQUMsV0FBVyxFQUFFLFdBQVcsRUFBRSxPQUFPLEVBQUUsS0FBSyxFQUFFLFlBQVksRUFBRSxlQUFlLENBQUMsQ0FBQztvQkFFakksT0FBTztnQkFDVCxDQUFDO2dCQUNELDhDQUE4QyxDQUFDLFNBQVMsQ0FBQyxXQUFXLEVBQUUsT0FBTyxFQUFFLEtBQUssRUFBRSxZQUFZLEVBQUUsZUFBZSxDQUFDLENBQUM7Z0JBQ3JILE1BQU07UUFDVixDQUFDO0lBQ0gsQ0FBQztJQUVPLE1BQU0sQ0FBQyxnQkFBZ0IsQ0FBQyxXQUFrQixFQUFFLEtBQWEsRUFBRSxTQUFpQixFQUFFLFlBQXFCLEVBQUUsZUFBK0I7UUFDMUksTUFBTSxXQUFXLEdBQUc7WUFDbEIsQ0FBQyxFQUFFLENBQUMsV0FBVyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsR0FBRyxTQUFTLEdBQUcsQ0FBQztZQUN2QyxDQUFDLEVBQUUsQ0FBQyxXQUFXLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxHQUFHLENBQUMsV0FBVyxDQUFDLE1BQU0sSUFBSSxDQUFDLENBQUMsR0FBRyxDQUFDO1NBQ3hELENBQUM7UUFFRixNQUFNLFlBQVksR0FBRyxTQUFTLENBQUMsV0FBVyxDQUFDLENBQUM7UUFFNUMsSUFBSSxrQ0FBa0MsR0FBbUIsRUFBRSxDQUFDO1FBQzVELElBQUksRUFBRSxJQUFJLEVBQUUsT0FBTyxFQUFFLEdBQUcsc0NBQXNDLENBQUMsbUJBQW1CLENBQUMsS0FBSyxDQUFDLENBQUMsSUFBSSxDQUFDLEVBQUUsS0FBSyxDQUFDLENBQUMsSUFBSSxDQUFDLEVBQUUsU0FBUyxFQUFFLFlBQVksRUFBRSxZQUFZLEVBQUUsa0NBQWtDLENBQUMsQ0FBQztRQUUxTCxJQUFJLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxHQUFHLFdBQVcsQ0FBQyxDQUFDLENBQUMsR0FBRyxFQUFFLEVBQUUsQ0FBQztZQUNsRCxJQUFJLEdBQUcsRUFBRSxDQUFDO1lBQ1YsT0FBTyxHQUFHO2dCQUNSLENBQUMsRUFBRSxLQUFLLENBQUMsQ0FBQztnQkFDVixDQUFDLEVBQUUsS0FBSyxDQUFDLENBQUM7YUFDWCxDQUFDO1lBRUYsa0NBQWtDLEdBQUcsRUFBRSxDQUFDO1FBQzFDLENBQUM7UUFFRCxlQUFlLENBQUMsTUFBTSxDQUFDLGVBQWUsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxFQUFFLEdBQUcsa0NBQWtDLENBQUMsQ0FBQztRQUV6RixtSkFBbUo7UUFDbkosTUFBTSxVQUFVLEdBQUcsc0NBQXNDLENBQUMsb0JBQW9CLENBQUMsT0FBTyxDQUFDLENBQUMsRUFBRSxXQUFXLENBQUMsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDO1FBRTlHLElBQUksVUFBVSxLQUFLLFFBQVEsRUFBRSxDQUFDO1lBQzVCLE1BQU0sSUFBSSxHQUFHLEVBQUUsQ0FBQyxFQUFFLFdBQVcsQ0FBQyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsRUFBRSxPQUFPLENBQUMsQ0FBQyxFQUFFLENBQUM7WUFFckQsZUFBZSxDQUFDLElBQUksQ0FBQyxFQUFFLEtBQUssRUFBRSxPQUFPLEVBQUUsR0FBRyxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsWUFBWSxFQUFFLEVBQUUsRUFBRSxHQUFHLEVBQUUsQ0FBQyxDQUFDO1lBRWpGLE9BQU87Z0JBQ0wsS0FBSyxFQUFFLEdBQUcsSUFBSSxNQUFNLElBQUksQ0FBQyxDQUFDLElBQUksSUFBSSxDQUFDLENBQUMsRUFBRTtnQkFDdEMsT0FBTyxFQUFFLElBQUk7YUFDZCxDQUFDO1FBQ0osQ0FBQztRQUVELElBQUksYUFBYSxHQUFHLFNBQVMsQ0FBQztRQUU5QixJQUFJLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxHQUFHLFdBQVcsQ0FBQyxDQUFDLENBQUMsR0FBRyxTQUFTLEdBQUcsQ0FBQyxFQUFFLENBQUM7WUFDL0QsYUFBYSxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxHQUFHLFdBQVcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7WUFFL0QsTUFBTSxPQUFPLEdBQUcsc0NBQXNDLENBQUMsU0FBUyxDQUFDLEVBQUUsQ0FBQyxFQUFFLE9BQU8sQ0FBQyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsRUFBRSxPQUFPLENBQUMsQ0FBQyxJQUFJLENBQUMsRUFBRSxFQUFFLFNBQVMsVUFBVSxLQUFLLE9BQU8sQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxPQUFPLEVBQUUsRUFBRSxhQUFhLEdBQUcsQ0FBQyxFQUFFLGFBQWEsQ0FBQyxDQUFDLENBQUMsaURBQWlEO1lBQ3RQLE1BQU0sTUFBTSxHQUFHLEtBQUssT0FBTyxDQUFDLEVBQUUsSUFBSSxPQUFPLENBQUMsRUFBRSxJQUFJLE9BQU8sQ0FBQyxDQUFDLElBQUksT0FBTyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMseUNBQXlDO1lBQ25ILE1BQU0sT0FBTyxHQUFHLHNDQUFzQyxDQUFDLFNBQVMsQ0FBQyxFQUFFLENBQUMsRUFBRSxPQUFPLENBQUMsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLEVBQUUsT0FBTyxDQUFDLENBQUMsSUFBSSxDQUFDLEVBQUUsRUFBRSxHQUFHLFVBQVUsS0FBSyxPQUFPLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsT0FBTyxRQUFRLEVBQUUsYUFBYSxHQUFHLENBQUMsRUFBRSxhQUFhLENBQUMsQ0FBQyxDQUFDLDJDQUEyQztZQUNoUCxNQUFNLE1BQU0sR0FBRyxLQUFLLE9BQU8sQ0FBQyxFQUFFLElBQUksT0FBTyxDQUFDLEVBQUUsSUFBSSxPQUFPLENBQUMsQ0FBQyxJQUFJLE9BQU8sQ0FBQyxDQUFDLEVBQUUsQ0FBQztZQUV6RSxlQUFlLENBQUMsSUFBSSxDQUFDLEVBQUUsS0FBSyxFQUFFLE9BQU8sRUFBRSxHQUFHLEVBQUUsRUFBRSxDQUFDLEVBQUUsT0FBTyxDQUFDLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxFQUFFLE9BQU8sQ0FBQyxDQUFDLElBQUksQ0FBQyxFQUFFLEVBQUUsSUFBSSxFQUFFLHlCQUF5QixFQUFFLEVBQUUsRUFBRSxHQUFHLEVBQUUsQ0FBQyxDQUFDO1lBQ2xJLGVBQWUsQ0FBQyxJQUFJLENBQUMsRUFBRSxLQUFLLEVBQUUsRUFBRSxDQUFDLEVBQUUsT0FBTyxDQUFDLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxFQUFFLE9BQU8sQ0FBQyxDQUFDLElBQUksQ0FBQyxFQUFFLEVBQUUsR0FBRyxFQUFFLEVBQUUsQ0FBQyxFQUFFLE9BQU8sQ0FBQyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsRUFBRSxPQUFPLENBQUMsQ0FBQyxJQUFJLENBQUMsRUFBRSxFQUFFLElBQUksRUFBRSx1QkFBdUIsRUFBRSxFQUFFLEVBQUUsR0FBRyxFQUFFLENBQUMsQ0FBQztZQUNqSyxNQUFNLFNBQVMsR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLEVBQUUsQ0FBQyxFQUFFLE9BQU8sQ0FBQyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsRUFBRSxPQUFPLENBQUMsQ0FBQyxJQUFJLENBQUMsRUFBRSxFQUFFLFdBQVcsRUFBRSxTQUFTLEVBQUUsV0FBVyxFQUFFLGVBQWUsQ0FBQyxDQUFDO1lBRWpJLE9BQU87Z0JBQ0wsS0FBSyxFQUFFLEdBQUcsSUFBSSxJQUFJLE1BQU0sSUFBSSxNQUFNLElBQUksU0FBUyxFQUFFO2FBQ2xELENBQUM7UUFDSixDQUFDO1FBRUQsTUFBTSxPQUFPLEdBQUcsc0NBQXNDLENBQUMsU0FBUyxDQUFDLEVBQUUsQ0FBQyxFQUFFLE9BQU8sQ0FBQyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsRUFBRSxPQUFPLENBQUMsQ0FBQyxJQUFJLENBQUMsRUFBRSxFQUFFLFNBQVMsVUFBVSxLQUFLLE9BQU8sQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxPQUFPLEVBQUUsRUFBRSxTQUFTLEVBQUUsU0FBUyxDQUFDLENBQUMsQ0FBQyxpREFBaUQ7UUFFMU8sTUFBTSxNQUFNLEdBQUcsS0FBSyxPQUFPLENBQUMsRUFBRSxJQUFJLE9BQU8sQ0FBQyxFQUFFLElBQUksT0FBTyxDQUFDLENBQUMsSUFBSSxPQUFPLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyx5Q0FBeUM7UUFDbkgsTUFBTSxZQUFZLEdBQUcsU0FBUyxDQUFDLFdBQVcsQ0FBQyxDQUFDO1FBRTVDLFlBQVksQ0FBQyxDQUFDLEdBQUcsNEJBQTRCLENBQUMsd0JBQXdCLENBQUMsVUFBVSxFQUFFLFdBQVcsQ0FBQyxDQUFDLEVBQUUsU0FBUyxDQUFDLENBQUM7UUFFN0csTUFBTSxZQUFZLEdBQUcsc0NBQXNDLENBQUMsb0JBQW9CLENBQUMsT0FBTyxDQUFDLENBQUMsSUFBSSxDQUFDLEVBQUUsT0FBTyxDQUFDLENBQUMsSUFBSSxDQUFDLEVBQUUsU0FBUyxFQUFFLFlBQVksRUFBRSxVQUFVLEVBQUUsWUFBWSxFQUFFLGVBQWUsQ0FBQyxDQUFDO1FBRXJMLE1BQU0sT0FBTyxHQUFHLHNDQUFzQyxDQUFDLFNBQVMsQ0FBQyxFQUFFLENBQUMsRUFBRSxZQUFZLENBQUMsT0FBTyxDQUFDLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxFQUFFLFlBQVksQ0FBQyxPQUFPLENBQUMsQ0FBQyxJQUFJLENBQUMsRUFBRSxFQUFFLEdBQUcsVUFBVSxLQUFLLE9BQU8sQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxPQUFPLFFBQVEsRUFBRSxTQUFTLEVBQUUsU0FBUyxDQUFDLENBQUMsQ0FBQywyQ0FBMkM7UUFDOVAsTUFBTSxNQUFNLEdBQUcsS0FBSyxPQUFPLENBQUMsRUFBRSxJQUFJLE9BQU8sQ0FBQyxFQUFFLElBQUksT0FBTyxDQUFDLENBQUMsSUFBSSxPQUFPLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyx5Q0FBeUM7UUFFbkgsZUFBZSxDQUFDLElBQUksQ0FBQyxFQUFFLEtBQUssRUFBRSxFQUFFLENBQUMsRUFBRSxPQUFPLENBQUMsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLEVBQUUsT0FBTyxDQUFDLENBQUMsRUFBRSxFQUFFLEdBQUcsRUFBRSxFQUFFLENBQUMsRUFBRSxPQUFPLENBQUMsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLEVBQUUsT0FBTyxDQUFDLENBQUMsSUFBSSxDQUFDLEVBQUUsRUFBRSxJQUFJLEVBQUUseUJBQXlCLEVBQUUsRUFBRSxFQUFFLEdBQUcsRUFBRSxDQUFDLENBQUM7UUFDOUosZUFBZSxDQUFDLElBQUksQ0FBQyxFQUFFLEtBQUssRUFBRSxFQUFFLENBQUMsRUFBRSxZQUFZLENBQUMsT0FBTyxDQUFDLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxFQUFFLFlBQVksQ0FBQyxPQUFPLENBQUMsQ0FBQyxJQUFJLENBQUMsRUFBRSxFQUFFLEdBQUcsRUFBRSxFQUFFLENBQUMsRUFBRSxPQUFPLENBQUMsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLEVBQUUsT0FBTyxDQUFDLENBQUMsSUFBSSxDQUFDLEVBQUUsRUFBRSxJQUFJLEVBQUUsdUJBQXVCLEVBQUUsRUFBRSxFQUFFLEdBQUcsRUFBRSxDQUFDLENBQUM7UUFDM0wsTUFBTSxTQUFTLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxFQUFFLENBQUMsRUFBRSxPQUFPLENBQUMsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLEVBQUUsT0FBTyxDQUFDLENBQUMsSUFBSSxDQUFDLEVBQUUsRUFBRSxXQUFXLEVBQUUsU0FBUyxFQUFFLFdBQVcsRUFBRSxlQUFlLENBQUMsQ0FBQztRQUVqSSxPQUFPO1lBQ0wsS0FBSyxFQUFFLEdBQUcsSUFBSSxJQUFJLE1BQU0sSUFBSSxZQUFZLENBQUMsSUFBSSxJQUFJLE1BQU0sSUFBSSxTQUFTLEVBQUU7WUFDdEUsT0FBTyxFQUFFLFlBQVksQ0FBQyxPQUFPO1NBQzlCLENBQUM7SUFDSixDQUFDO0lBRU8sTUFBTSxDQUFDLGVBQWUsQ0FBQyxXQUFrQixFQUFFLFdBQWtCLEVBQUUsS0FBYSxFQUFFLFNBQWlCLEVBQUUsWUFBcUIsRUFBRSxlQUErQjtRQUM3SixNQUFNLGlCQUFpQixHQUFHO1lBQ3hCLENBQUMsRUFBRSxDQUFDLFdBQVcsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLEdBQUcsU0FBUyxHQUFHLEdBQUc7WUFDekMsQ0FBQyxFQUFFLENBQUMsV0FBVyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsR0FBRyxDQUFDLFdBQVcsQ0FBQyxNQUFNLElBQUksQ0FBQyxDQUFDLEdBQUcsQ0FBQztTQUN4RCxDQUFDO1FBRUYsTUFBTSxXQUFXLEdBQUcsU0FBUyxDQUFDLGlCQUFpQixDQUFDLENBQUM7UUFDakQsTUFBTSxlQUFlLEdBQUcsc0NBQXNDLENBQUMsb0JBQW9CLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxpQkFBaUIsQ0FBQyxDQUFDLEVBQUUsR0FBRyxDQUFDLENBQUM7UUFFdkgsTUFBTSxJQUFJLEdBQUcsZUFBZSxLQUFLLE9BQU8sSUFBSSxlQUFlLEtBQUssUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFDLFdBQVcsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsV0FBVyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsR0FBRyxDQUFDLFdBQVcsQ0FBQyxNQUFNLElBQUksQ0FBQyxDQUFDLENBQUM7UUFFbkosV0FBVyxDQUFDLENBQUMsR0FBRyw0QkFBNEIsQ0FBQyx3QkFBd0IsQ0FBQyxlQUFlLEVBQUUsSUFBSSxFQUFFLFNBQVMsR0FBRyxDQUFDLENBQUMsQ0FBQztRQUU1RyxNQUFNLEtBQUssR0FBRyxzQ0FBc0MsQ0FBQyxTQUFTLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxLQUFLLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxHQUFHLEVBQUUsRUFBRSxDQUFDLEVBQUUsS0FBSyxDQUFDLENBQUMsSUFBSSxDQUFDLEVBQUUsRUFBRSxTQUFTLGVBQWUsS0FBSyxPQUFPLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsT0FBTyxFQUFFLEVBQUUsU0FBUyxFQUFFLFNBQVMsQ0FBQyxDQUFDO1FBQzlMLE1BQU0sT0FBTyxHQUFHLEVBQUUsRUFBRSxFQUFFLEtBQUssQ0FBQyxDQUFDLEVBQUUsRUFBRSxFQUFFLDRCQUE0QixDQUFDLHdCQUF3QixDQUFDLGVBQWUsRUFBRSxLQUFLLENBQUMsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLFdBQVcsQ0FBQyxNQUFNLElBQUksQ0FBQyxDQUFDLEdBQUcsQ0FBQyxFQUFFLElBQUksQ0FBQyxFQUFFLENBQUM7UUFFL0osZUFBZSxDQUFDLElBQUksQ0FBQyxFQUFFLEtBQUssRUFBRSxFQUFFLENBQUMsRUFBRSxLQUFLLENBQUMsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLEVBQUUsS0FBSyxDQUFDLENBQUMsSUFBSSxDQUFDLEVBQUUsRUFBRSxHQUFHLEVBQUUsRUFBRSxDQUFDLEVBQUUsS0FBSyxDQUFDLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxFQUFFLEtBQUssQ0FBQyxDQUFDLElBQUksQ0FBQyxFQUFFLEVBQUUsSUFBSSxFQUFFLHlCQUF5QixFQUFFLEVBQUUsRUFBRSxHQUFHLEVBQUUsQ0FBQyxDQUFDO1FBQzNKLGVBQWUsQ0FBQyxJQUFJLENBQUMsRUFBRSxLQUFLLEVBQUUsRUFBRSxDQUFDLEVBQUUsS0FBSyxDQUFDLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxFQUFFLEtBQUssQ0FBQyxDQUFDLElBQUksQ0FBQyxFQUFFLEVBQUUsR0FBRyxFQUFFLEVBQUUsQ0FBQyxFQUFFLE9BQU8sQ0FBQyxFQUFFLElBQUksQ0FBQyxFQUFFLENBQUMsRUFBRSxPQUFPLENBQUMsRUFBRSxFQUFFLEVBQUUsSUFBSSxFQUFFLFlBQVksRUFBRSxFQUFFLEVBQUUsR0FBRyxFQUFFLENBQUMsQ0FBQztRQUUvSSxJQUFJLGVBQWUsS0FBSyxRQUFRLEVBQUUsQ0FBQztZQUNqQyxNQUFNLE9BQU8sR0FBRyxzQ0FBc0MsQ0FBQyxTQUFTLENBQUMsRUFBRSxDQUFDLEVBQUUsT0FBTyxDQUFDLEVBQUUsSUFBSSxDQUFDLEVBQUUsQ0FBQyxFQUFFLE9BQU8sQ0FBQyxFQUFFLElBQUksQ0FBQyxFQUFFLEVBQUUsWUFBWSxFQUFFLFNBQVMsRUFBRSxTQUFTLENBQUMsQ0FBQyxDQUFDLGlEQUFpRDtZQUVuTSxlQUFlLENBQUMsSUFBSSxDQUFDLEVBQUUsS0FBSyxFQUFFLEVBQUUsQ0FBQyxFQUFFLE9BQU8sQ0FBQyxFQUFFLElBQUksQ0FBQyxFQUFFLENBQUMsRUFBRSxPQUFPLENBQUMsRUFBRSxFQUFFLEVBQUUsR0FBRyxFQUFFLEVBQUUsQ0FBQyxFQUFFLE9BQU8sQ0FBQyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsRUFBRSxPQUFPLENBQUMsQ0FBQyxJQUFJLENBQUMsRUFBRSxFQUFFLElBQUksRUFBRSx1QkFBdUIsRUFBRSxFQUFFLEVBQUUsR0FBRyxFQUFFLENBQUMsQ0FBQztZQUU5SixNQUFNLE9BQU8sR0FBRyxzQ0FBc0MsQ0FBQyx1QkFBdUIsQ0FBQyxPQUFPLENBQUMsQ0FBQyxJQUFJLENBQUMsRUFBRSxPQUFPLENBQUMsQ0FBQyxJQUFJLENBQUMsRUFBRSxTQUFTLEVBQUUsV0FBVyxFQUFFLFlBQVksRUFBRSxlQUFlLENBQUMsQ0FBQztZQUV0SyxNQUFNLGdCQUFnQixHQUFHLHNDQUFzQyxDQUFDLG9CQUFvQixDQUFDLE9BQU8sQ0FBQyxDQUFDLEVBQUUsaUJBQWlCLENBQUMsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDO1lBRTFILE1BQU0sT0FBTyxHQUFHLHNDQUFzQyxDQUFDLFNBQVMsQ0FBQyxFQUFFLENBQUMsRUFBRSxPQUFPLENBQUMsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLEVBQUUsT0FBTyxDQUFDLENBQUMsSUFBSSxDQUFDLEVBQUUsRUFBRSxRQUFRLGdCQUFnQixLQUFLLE9BQU8sQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxPQUFPLEVBQUUsRUFBRSxTQUFTLEVBQUUsU0FBUyxDQUFDLENBQUMsQ0FBQyxpREFBaUQ7WUFFL08sZUFBZSxDQUFDLElBQUksQ0FBQyxFQUFFLEtBQUssRUFBRSxFQUFFLENBQUMsRUFBRSxPQUFPLENBQUMsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLEVBQUUsT0FBTyxDQUFDLENBQUMsSUFBSSxDQUFDLEVBQUUsRUFBRSxHQUFHLEVBQUUsRUFBRSxDQUFDLEVBQUUsT0FBTyxDQUFDLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxFQUFFLE9BQU8sQ0FBQyxDQUFDLElBQUksQ0FBQyxFQUFFLEVBQUUsSUFBSSxFQUFFLHlCQUF5QixFQUFFLEVBQUUsRUFBRSxHQUFHLEVBQUUsQ0FBQyxDQUFDO1lBQ25LLElBQUksQ0FBQyxTQUFTLENBQUMsRUFBRSxDQUFDLEVBQUUsT0FBTyxDQUFDLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxFQUFFLE9BQU8sQ0FBQyxDQUFDLElBQUksQ0FBQyxFQUFFLEVBQUUsaUJBQWlCLEVBQUUsU0FBUyxFQUFFLFdBQVcsRUFBRSxlQUFlLENBQUMsQ0FBQztZQUVySCxPQUFPO2dCQUNMLEtBQUssRUFBRSxFQUFFO2FBQ1YsQ0FBQztRQUNKLENBQUM7UUFFRCxNQUFNLFlBQVksR0FBRyxzQ0FBc0MsQ0FBQyx3QkFBd0IsQ0FBQyxPQUFPLENBQUMsRUFBRSxJQUFJLENBQUMsRUFBRSxPQUFPLENBQUMsRUFBRSxJQUFJLENBQUMsRUFBRSxTQUFTLEVBQUUsV0FBVyxFQUFFLGVBQWUsRUFBRSxZQUFZLEVBQUUsZUFBZSxDQUFDLENBQUM7UUFFL0wsSUFBSSxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsV0FBVyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsR0FBRyxDQUFDLFlBQVksQ0FBQyxPQUFPLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLElBQUksU0FBUyxHQUFHLENBQUMsRUFBRSxDQUFDO1lBQ3BGLFdBQVcsQ0FBQyxDQUFDLEdBQUcsWUFBWSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUM7UUFDekMsQ0FBQztRQUVELElBQUksQ0FBQyxlQUFlLEtBQUssT0FBTyxJQUFJLE9BQU8sQ0FBQyxFQUFFLEdBQUcsV0FBVyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsZUFBZSxLQUFLLE9BQU8sSUFBSSxPQUFPLENBQUMsRUFBRSxHQUFHLFdBQVcsQ0FBQyxDQUFDLENBQUMsSUFBSSxPQUFPLENBQUMsRUFBRSxLQUFLLFdBQVcsQ0FBQyxDQUFDLEVBQUUsQ0FBQztZQUMvSixJQUFJLFNBQVMsR0FBRyxJQUFJLENBQUM7WUFFckIsT0FBTyxTQUFTLEVBQUUsQ0FBQztnQkFDakIsTUFBTSx3QkFBd0IsR0FBRyxlQUFlLENBQUMsU0FBUyxDQUFDLENBQUMsSUFBSSxFQUFFLEVBQUUsQ0FBQyxJQUFJLENBQUMsRUFBRSxLQUFLLDBCQUEwQixDQUFDLENBQUM7Z0JBRTdHLElBQUksd0JBQXdCLEtBQUssQ0FBQyxDQUFDLEVBQUUsQ0FBQztvQkFDcEMsZUFBZSxDQUFDLE1BQU0sQ0FBQyx3QkFBd0IsRUFBRSxDQUFDLENBQUMsQ0FBQztnQkFDdEQsQ0FBQztnQkFDRCxJQUFJLHdCQUF3QixLQUFLLENBQUMsQ0FBQyxFQUFFLENBQUM7b0JBQ3BDLFNBQVMsR0FBRyxLQUFLLENBQUM7Z0JBQ3BCLENBQUM7WUFDSCxDQUFDO1lBRUQsWUFBWSxDQUFDLElBQUksR0FBRyxFQUFFLENBQUM7WUFDdkIsWUFBWSxDQUFDLE9BQU8sR0FBRztnQkFDckIsQ0FBQyxFQUFFLE9BQU8sQ0FBQyxFQUFFLElBQUksQ0FBQztnQkFDbEIsQ0FBQyxFQUFFLE9BQU8sQ0FBQyxFQUFFLElBQUksQ0FBQzthQUNuQixDQUFDO1FBQ0osQ0FBQztRQUVELElBQUksV0FBVyxDQUFDLENBQUMsS0FBSyxZQUFZLENBQUMsT0FBTyxDQUFDLENBQUMsRUFBRSxDQUFDO1lBQzdDLGVBQWUsQ0FBQyxJQUFJLENBQUMsRUFBRSxLQUFLLEVBQUUsWUFBWSxDQUFDLE9BQU8sRUFBRSxHQUFHLEVBQUUsaUJBQWlCLEVBQUUsSUFBSSxFQUFFLHVCQUF1QixFQUFFLEVBQUUsRUFBRSxLQUFLLEdBQUcsZUFBZSxFQUFFLENBQUMsQ0FBQztZQUMxSSxJQUFJLENBQUMsU0FBUyxDQUFDLEVBQUUsQ0FBQyxFQUFFLGlCQUFpQixDQUFDLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxFQUFFLGlCQUFpQixDQUFDLENBQUMsSUFBSSxDQUFDLEVBQUUsRUFBRSxpQkFBaUIsRUFBRSxTQUFTLEVBQUUsV0FBVyxFQUFFLGVBQWUsQ0FBQyxDQUFDO1lBRXpJLE9BQU87UUFDVCxDQUFDO1FBRUQsMERBQTBEO1FBQzFELE1BQU0sZ0JBQWdCLEdBQUcsc0NBQXNDLENBQUMsNEJBQTRCLENBQUMsWUFBWSxDQUFDLE9BQU8sQ0FBQyxDQUFDLElBQUksQ0FBQyxFQUFFLFdBQVcsQ0FBQyxDQUFDLEVBQUUsWUFBWSxDQUFDLE9BQU8sQ0FBQyxDQUFDLElBQUksQ0FBQyxFQUFFLEdBQUcsRUFBRSxZQUFZLENBQVUsQ0FBQztRQUNsTSxNQUFNLGNBQWMsR0FBRyxzQ0FBc0MsQ0FBQyxvQkFBb0IsQ0FBQyxZQUFZLENBQUMsT0FBTyxDQUFDLENBQUMsSUFBSSxDQUFDLEVBQUUsaUJBQWlCLENBQUMsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDO1FBQzFJLE1BQU0sT0FBTyxHQUFHLHNDQUFzQyxDQUFDLFNBQVMsQ0FBQyxFQUFFLENBQUMsRUFBRSxZQUFZLENBQUMsT0FBTyxDQUFDLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxFQUFFLFlBQVksQ0FBQyxPQUFPLENBQUMsQ0FBQyxJQUFJLENBQUMsRUFBRSxFQUFFLEdBQUcsZUFBZSxJQUFJLGNBQWMsRUFBRSxFQUFFLFNBQVMsRUFBRSxTQUFTLENBQUMsQ0FBQyxDQUFDLGlEQUFpRDtRQUNyUCxNQUFNLGlCQUFpQixHQUFHLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQyxJQUFJLENBQUMsQ0FBQyxHQUFHLENBQUMsZ0JBQWdCLEVBQUUsS0FBSyxJQUFJLENBQUMsQ0FBQyxDQUFDO1FBRXRGLElBQUksZ0JBQWdCLElBQUksSUFBSSxDQUFDLEdBQUcsQ0FBQyxpQkFBaUIsR0FBRyxDQUFDLFlBQVksQ0FBQyxPQUFPLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLElBQUksU0FBUyxHQUFHLENBQUMsRUFBRSxDQUFDO1lBQ3JHLE9BQU8sQ0FBQyxFQUFFLEdBQUcsWUFBWSxDQUFDLE9BQU8sQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDO1lBQ3pDLE9BQU8sQ0FBQyxFQUFFLEdBQUcsWUFBWSxDQUFDLE9BQU8sQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDO1lBQ3pDLE9BQU8sQ0FBQyxDQUFDLEdBQUcsWUFBWSxDQUFDLE9BQU8sQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDO1lBQ3hDLE9BQU8sQ0FBQyxDQUFDLEdBQUcsWUFBWSxDQUFDLE9BQU8sQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQzFDLENBQUM7UUFFRCxlQUFlLENBQUMsSUFBSSxDQUFDLEVBQUUsS0FBSyxFQUFFLFlBQVksQ0FBQyxPQUFPLEVBQUUsR0FBRyxFQUFFLEVBQUUsQ0FBQyxFQUFFLE9BQU8sQ0FBQyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsRUFBRSxPQUFPLENBQUMsQ0FBQyxJQUFJLENBQUMsRUFBRSxFQUFFLElBQUksRUFBRSx1QkFBdUIsRUFBRSxFQUFFLEVBQUUsS0FBSyxHQUFHLGVBQWUsRUFBRSxDQUFDLENBQUM7UUFFakssTUFBTSxPQUFPLEdBQUcsc0NBQXNDLENBQUMsdUJBQXVCLENBQUMsT0FBTyxDQUFDLENBQUMsSUFBSSxDQUFDLEVBQUUsT0FBTyxDQUFDLENBQUMsSUFBSSxDQUFDLEVBQUUsU0FBUyxFQUFFLFdBQVcsRUFBRSxZQUFZLEVBQUUsZUFBZSxDQUFDLENBQUM7UUFDdEssTUFBTSxnQkFBZ0IsR0FBRyxzQ0FBc0MsQ0FBQyxvQkFBb0IsQ0FBQyxPQUFPLENBQUMsQ0FBQyxFQUFFLGlCQUFpQixDQUFDLENBQUMsRUFBRSxHQUFHLENBQUMsQ0FBQztRQUMxSCxNQUFNLGNBQWMsR0FBRyxzQ0FBc0MsQ0FBQyxvQkFBb0IsQ0FBQyxPQUFPLENBQUMsQ0FBQyxJQUFJLENBQUMsRUFBRSxPQUFPLENBQUMsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDO1FBQ25ILE1BQU0sT0FBTyxHQUFHLHNDQUFzQyxDQUFDLFNBQVMsQ0FBQyxFQUFFLENBQUMsRUFBRSxPQUFPLENBQUMsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLEVBQUUsT0FBTyxDQUFDLENBQUMsSUFBSSxDQUFDLEVBQUUsRUFBRSxHQUFHLGNBQWMsSUFBSSxnQkFBZ0IsS0FBSyxPQUFPLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsT0FBTyxFQUFFLEVBQUUsU0FBUyxFQUFFLFNBQVMsQ0FBQyxDQUFDLENBQUMsaURBQWlEO1FBRTVQLGVBQWUsQ0FBQyxJQUFJLENBQUMsRUFBRSxLQUFLLEVBQUUsT0FBTyxFQUFFLEdBQUcsRUFBRSxFQUFFLENBQUMsRUFBRSxPQUFPLENBQUMsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLEVBQUUsT0FBTyxDQUFDLENBQUMsSUFBSSxDQUFDLEVBQUUsRUFBRSxJQUFJLEVBQUUseUJBQXlCLEVBQUUsRUFBRSxFQUFFLEdBQUcsRUFBRSxDQUFDLENBQUM7UUFFbEksSUFBSSxDQUFDLFNBQVMsQ0FBQyxFQUFFLENBQUMsRUFBRSxPQUFPLENBQUMsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLEVBQUUsT0FBTyxDQUFDLENBQUMsSUFBSSxDQUFDLEVBQUUsRUFBRSxpQkFBaUIsRUFBRSxTQUFTLEVBQUUsV0FBVyxFQUFFLGVBQWUsQ0FBQyxDQUFDO1FBRXJILE9BQU87WUFDTCxLQUFLLEVBQUUsRUFBRTtTQUNWLENBQUM7SUFDSixDQUFDO0lBRU8sTUFBTSxDQUFDLFNBQVMsQ0FBQyxLQUFrQixFQUFFLEdBQWdCLEVBQUUsU0FBaUIsRUFBRSxXQUFrQixFQUFFLGVBQStCO1FBQ25JLE1BQU0sVUFBVSxHQUFHLHNDQUFzQyxDQUFDLG9CQUFvQixDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsR0FBRyxDQUFDLENBQUMsRUFBRSxHQUFHLENBQUMsQ0FBQztRQUVwRyxJQUFJLEtBQUssQ0FBQyxDQUFDLEtBQUssR0FBRyxDQUFDLENBQUMsRUFBRSxDQUFDO1lBQ3RCLGVBQWUsQ0FBQyxJQUFJLENBQUMsRUFBRSxLQUFLLEVBQUUsR0FBRyxFQUFFLEVBQUUsQ0FBQyxFQUFFLFdBQVcsQ0FBQyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsRUFBRSxHQUFHLENBQUMsQ0FBQyxJQUFJLENBQUMsRUFBRSxFQUFFLElBQUksRUFBRSxZQUFZLEVBQUUsRUFBRSxFQUFFLEdBQUcsRUFBRSxDQUFDLENBQUM7WUFFNUcsT0FBTyxLQUFLLFdBQVcsQ0FBQyxDQUFDLElBQUksR0FBRyxDQUFDLENBQUMsRUFBRSxDQUFDO1FBQ3ZDLENBQUM7UUFFRCxNQUFNLElBQUksR0FBRyxFQUFFLENBQUMsRUFBRSxLQUFLLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxLQUFLLENBQUMsQ0FBQyxFQUFFLENBQUM7UUFDeEMsTUFBTSxRQUFRLEdBQUc7WUFDZixDQUFDLEVBQUUsV0FBVyxDQUFDLENBQUM7WUFDaEIsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDO1NBQ1QsQ0FBQztRQUNGLElBQUksTUFBTSxHQUFHLEVBQUUsQ0FBQztRQUVoQixJQUFJLElBQUksQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLENBQUMsR0FBRyxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsU0FBUyxFQUFFLENBQUM7WUFDMUMsTUFBTSxHQUFHLEdBQUcsNEJBQTRCLENBQUMsd0JBQXdCLENBQUMsVUFBVSxFQUFFLEdBQUcsQ0FBQyxDQUFDLEVBQUUsU0FBUyxDQUFDLENBQUM7WUFFaEcsSUFBSSxDQUFDLENBQUMsR0FBRyxHQUFHLENBQUM7WUFFYixNQUFNLFVBQVUsR0FBRyxzQ0FBc0MsQ0FBQyxvQkFBb0IsQ0FBQyxJQUFJLENBQUMsQ0FBQyxFQUFFLFdBQVcsQ0FBQyxDQUFDLEVBQUUsR0FBRyxDQUFDLENBQUM7WUFDM0csTUFBTSxPQUFPLEdBQUcsc0NBQXNDLENBQUMsU0FBUyxDQUFDLEVBQUUsQ0FBQyxFQUFFLElBQUksQ0FBQyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQyxJQUFJLENBQUMsRUFBRSxFQUFFLEdBQUcsVUFBVSxLQUFLLE9BQU8sQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxPQUFPLElBQUksVUFBVSxFQUFFLEVBQUUsU0FBUyxFQUFFLFNBQVMsQ0FBQyxDQUFDLENBQUMsaURBQWlEO1lBRTVPLElBQUksS0FBSyxHQUFHLEVBQUUsQ0FBQztZQUVmLElBQUksT0FBTyxDQUFDLENBQUMsS0FBSyxHQUFHLENBQUMsQ0FBQyxFQUFFLENBQUM7Z0JBQ3hCLEtBQUssR0FBRyxLQUFLLFFBQVEsQ0FBQyxDQUFDLElBQUksUUFBUSxDQUFDLENBQUMsRUFBRSxDQUFDO1lBQzFDLENBQUM7WUFFRCxNQUFNLEdBQUcsS0FBSyxPQUFPLENBQUMsRUFBRSxJQUFJLE9BQU8sQ0FBQyxFQUFFLElBQUksT0FBTyxDQUFDLENBQUMsSUFBSSxPQUFPLENBQUMsQ0FBQyxJQUFJLEtBQUssRUFBRSxDQUFDLENBQUMseUNBQXlDO1FBQ3hILENBQUM7UUFFRCxlQUFlLENBQUMsSUFBSSxDQUFDLEVBQUUsS0FBSyxFQUFFLEdBQUcsRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLFlBQVksRUFBRSxFQUFFLEVBQUUsR0FBRyxFQUFFLENBQUMsQ0FBQztRQUN4RSxlQUFlLENBQUMsSUFBSSxDQUFDLEVBQUUsS0FBSyxFQUFFLElBQUksRUFBRSxHQUFHLEVBQUUsUUFBUSxFQUFFLElBQUksRUFBRSx1QkFBdUIsRUFBRSxFQUFFLEVBQUUsR0FBRyxFQUFFLENBQUMsQ0FBQztRQUU3RixPQUFPLEtBQUssSUFBSSxDQUFDLENBQUMsSUFBSSxJQUFJLENBQUMsQ0FBQyxJQUFJLE1BQU0sRUFBRSxDQUFDO0lBQzNDLENBQUM7SUFFTyxNQUFNLENBQUMsOEJBQThCLENBQUMsV0FBa0IsRUFBRSxXQUFrQixFQUFFLEtBQWEsRUFBRSxTQUFpQixFQUFFLFlBQXFCLEVBQUUsZUFBK0I7UUFDNUssTUFBTSxpQkFBaUIsR0FBRztZQUN4QixDQUFDLEVBQUUsQ0FBQyxXQUFXLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxHQUFHLENBQUMsV0FBVyxDQUFDLEtBQUssSUFBSSxDQUFDLENBQUMsR0FBRyxDQUFDO1lBQ3RELENBQUMsRUFBRSxDQUFDLFdBQVcsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLEdBQUcsU0FBUztTQUNwQyxDQUFDO1FBQ0YsTUFBTSxXQUFXLEdBQUcsU0FBUyxDQUFDLGlCQUFpQixDQUFDLENBQUM7UUFDakQsTUFBTSxlQUFlLEdBQUcsc0NBQXNDLENBQUMsb0JBQW9CLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxpQkFBaUIsQ0FBQyxDQUFDLEVBQUUsR0FBRyxDQUFDLENBQUM7UUFDdkgsTUFBTSxJQUFJLEdBQUcsV0FBVyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUM7UUFFaEMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxpQkFBaUIsRUFBRSxlQUFlLENBQUMsQ0FBQztRQUNoRCxJQUFJLGVBQWUsS0FBSyxPQUFPLEVBQUUsQ0FBQztZQUNoQyxXQUFXLENBQUMsQ0FBQyxHQUFHLElBQUksR0FBRyxTQUFTLEdBQUcsQ0FBQyxDQUFDO1FBQ3ZDLENBQUM7UUFFRCxNQUFNLE9BQU8sR0FBRyxFQUFFLEVBQUUsRUFBRSxLQUFLLENBQUMsQ0FBQyxFQUFFLEVBQUUsRUFBRSxDQUFDLEtBQUssQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLEdBQUcsU0FBUyxFQUFFLENBQUM7UUFDaEUsTUFBTSxJQUFJLEdBQUc7WUFDWCxLQUFLLEVBQUUsRUFBRSxDQUFDLEVBQUUsS0FBSyxDQUFDLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxFQUFFLEtBQUssQ0FBQyxDQUFDLElBQUksQ0FBQyxFQUFFO1lBQzNDLEdBQUcsRUFBRSxFQUFFLENBQUMsRUFBRSxPQUFPLENBQUMsRUFBRSxJQUFJLENBQUMsRUFBRSxDQUFDLEVBQUUsT0FBTyxDQUFDLEVBQUUsSUFBSSxDQUFDLEVBQUU7U0FDaEQsQ0FBQztRQUNGLE1BQU0sTUFBTSxHQUFHLEVBQUUsQ0FBQyxFQUFFLFdBQVcsQ0FBQyxDQUFDLEdBQUcsU0FBUyxHQUFHLENBQUMsRUFBRSxDQUFDLEVBQUUsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsU0FBUyxFQUFFLENBQUM7UUFFL0UsSUFBSSxlQUFlLEtBQUssT0FBTyxFQUFFLENBQUM7WUFDaEMsSUFBSSxDQUFDLEdBQUcsR0FBRyxFQUFFLENBQUMsRUFBRSxDQUFDLEtBQUssQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLEdBQUcsU0FBUyxFQUFFLENBQUMsRUFBRSxDQUFDLEtBQUssQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLEdBQUcsU0FBUyxHQUFHLENBQUMsRUFBRSxDQUFDO1lBRWhGLGVBQWUsQ0FBQyxJQUFJLENBQUMsRUFBRSxLQUFLLEVBQUUsSUFBSSxDQUFDLEdBQUcsRUFBRSxHQUFHLEVBQUUsTUFBTSxFQUFFLElBQUksRUFBRSx5QkFBeUIsRUFBRSxFQUFFLEVBQUUsR0FBRyxFQUFFLENBQUMsQ0FBQztRQUNuRyxDQUFDO1FBQ0QsZUFBZSxDQUFDLElBQUksQ0FBQyxFQUFFLEtBQUssRUFBRSxJQUFJLENBQUMsS0FBSyxFQUFFLEdBQUcsRUFBRSxJQUFJLENBQUMsR0FBRyxFQUFFLElBQUksRUFBRSx1QkFBdUIsRUFBRSxFQUFFLEVBQUUsR0FBRyxFQUFFLENBQUMsQ0FBQyxDQUFDLGdDQUFnQztRQUNwSSxNQUFNLFlBQVksR0FBRyxlQUFlLEtBQUssT0FBTyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUM7UUFFckUsSUFBSSxlQUFlLEtBQUssUUFBUSxFQUFFLENBQUM7WUFDakMsTUFBTSxPQUFPLEdBQUcsc0NBQXNDLENBQUMsU0FBUyxDQUFDLEVBQUUsQ0FBQyxFQUFFLE9BQU8sQ0FBQyxFQUFFLElBQUksQ0FBQyxFQUFFLENBQUMsRUFBRSxPQUFPLENBQUMsRUFBRSxJQUFJLENBQUMsRUFBRSxFQUFFLFlBQVksRUFBRSxTQUFTLEVBQUUsU0FBUyxDQUFDLENBQUMsQ0FBQyxpREFBaUQ7WUFFbk0seUNBQXlDO1lBQ3pDLGVBQWUsQ0FBQyxJQUFJLENBQUMsRUFBRSxLQUFLLEVBQUUsRUFBRSxDQUFDLEVBQUUsT0FBTyxDQUFDLEVBQUUsSUFBSSxDQUFDLEVBQUUsQ0FBQyxFQUFFLE9BQU8sQ0FBQyxFQUFFLEVBQUUsRUFBRSxHQUFHLEVBQUUsRUFBRSxDQUFDLEVBQUUsT0FBTyxDQUFDLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxFQUFFLE9BQU8sQ0FBQyxDQUFDLElBQUksQ0FBQyxFQUFFLEVBQUUsSUFBSSxFQUFFLHVCQUF1QixFQUFFLEVBQUUsRUFBRSxHQUFHLEVBQUUsQ0FBQyxDQUFDO1lBRTlKLE1BQU0sT0FBTyxHQUFHLHNDQUFzQyxDQUFDLHVCQUF1QixDQUFDLE9BQU8sQ0FBQyxDQUFDLElBQUksQ0FBQyxFQUFFLE9BQU8sQ0FBQyxDQUFDLElBQUksQ0FBQyxFQUFFLFNBQVMsRUFBRSxXQUFXLEVBQUUsWUFBWSxFQUFFLGVBQWUsQ0FBQyxDQUFDO1lBQ3RLLE1BQU0sZ0JBQWdCLEdBQUcsc0NBQXNDLENBQUMsb0JBQW9CLENBQUMsT0FBTyxDQUFDLENBQUMsRUFBRSxpQkFBaUIsQ0FBQyxDQUFDLEVBQUUsR0FBRyxDQUFDLENBQUM7WUFDMUgsTUFBTSxPQUFPLEdBQUcsc0NBQXNDLENBQUMsU0FBUyxDQUFDLEVBQUUsQ0FBQyxFQUFFLE9BQU8sQ0FBQyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsRUFBRSxPQUFPLENBQUMsQ0FBQyxJQUFJLENBQUMsRUFBRSxFQUFFLFFBQVEsZ0JBQWdCLEtBQUssT0FBTyxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLE9BQU8sRUFBRSxFQUFFLFNBQVMsRUFBRSxTQUFTLENBQUMsQ0FBQyxDQUFDLGlEQUFpRDtZQUUvTyx5Q0FBeUM7WUFDekMsZUFBZSxDQUFDLElBQUksQ0FBQyxFQUFFLEtBQUssRUFBRSxFQUFFLENBQUMsRUFBRSxPQUFPLENBQUMsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLEVBQUUsT0FBTyxDQUFDLENBQUMsSUFBSSxDQUFDLEVBQUUsRUFBRSxHQUFHLEVBQUUsRUFBRSxDQUFDLEVBQUUsT0FBTyxDQUFDLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxFQUFFLE9BQU8sQ0FBQyxDQUFDLElBQUksQ0FBQyxFQUFFLEVBQUUsSUFBSSxFQUFFLHlCQUF5QixFQUFFLEVBQUUsRUFBRSxHQUFHLEVBQUUsQ0FBQyxDQUFDO1lBQ25LLElBQUksQ0FBQyxTQUFTLENBQUMsRUFBRSxDQUFDLEVBQUUsT0FBTyxDQUFDLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxFQUFFLE9BQU8sQ0FBQyxDQUFDLElBQUksQ0FBQyxFQUFFLEVBQUUsaUJBQWlCLEVBQUUsU0FBUyxFQUFFLFdBQVcsRUFBRSxlQUFlLENBQUMsQ0FBQztZQUVySCxPQUFPO2dCQUNMLEtBQUssRUFBRSxFQUFFO2FBQ1YsQ0FBQztRQUNKLENBQUM7UUFFRCxzREFBc0Q7UUFDdEQsTUFBTSxZQUFZLEdBQUcsc0NBQXNDLENBQUMsd0JBQXdCLENBQUMsWUFBWSxDQUFDLENBQUMsSUFBSSxDQUFDLEVBQUUsWUFBWSxDQUFDLENBQUMsSUFBSSxDQUFDLEVBQUUsU0FBUyxFQUFFLFdBQVcsRUFBRSxlQUFlLEVBQUUsWUFBWSxFQUFFLGVBQWUsQ0FBQyxDQUFDO1FBRXZNLE1BQU0sZUFBZSxHQUFHLHNDQUFzQyxDQUFDLG9CQUFvQixDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsaUJBQWlCLENBQUMsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDO1FBRXZILElBQUksZUFBZSxLQUFLLFFBQVEsSUFBSSxlQUFlLEtBQUssT0FBTyxFQUFFLENBQUM7WUFDaEUsSUFBSSxDQUFDLDBCQUEwQixDQUFDLEVBQUUsQ0FBQyxFQUFFLFlBQVksQ0FBQyxPQUFPLENBQUMsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLEVBQUUsWUFBWSxDQUFDLE9BQU8sQ0FBQyxDQUFDLElBQUksQ0FBQyxFQUFFLEVBQUUsaUJBQWlCLEVBQUUsU0FBUyxFQUFFLFdBQVcsRUFBRSxlQUFlLENBQUMsQ0FBQztZQUVoSyxPQUFPO2dCQUNMLEtBQUssRUFBRSxFQUFFO2FBQ1YsQ0FBQztRQUNKLENBQUM7UUFFRCxJQUFJLENBQUMsZUFBZSxLQUFLLE9BQU8sSUFBSSxPQUFPLENBQUMsRUFBRSxHQUFHLFdBQVcsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLGVBQWUsS0FBSyxPQUFPLElBQUksT0FBTyxDQUFDLEVBQUUsR0FBRyxXQUFXLENBQUMsQ0FBQyxDQUFDLElBQUksT0FBTyxDQUFDLEVBQUUsS0FBSyxXQUFXLENBQUMsQ0FBQyxFQUFFLENBQUM7WUFDL0osSUFBSSxTQUFTLEdBQUcsSUFBSSxDQUFDO1lBRXJCLE9BQU8sU0FBUyxFQUFFLENBQUM7Z0JBQ2pCLE1BQU0sd0JBQXdCLEdBQUcsZUFBZSxDQUFDLFNBQVMsQ0FBQyxDQUFDLElBQUksRUFBRSxFQUFFLENBQUMsSUFBSSxDQUFDLEVBQUUsS0FBSywwQkFBMEIsQ0FBQyxDQUFDO2dCQUU3RyxJQUFJLHdCQUF3QixLQUFLLENBQUMsQ0FBQyxFQUFFLENBQUM7b0JBQ3BDLGVBQWUsQ0FBQyxNQUFNLENBQUMsd0JBQXdCLEVBQUUsQ0FBQyxDQUFDLENBQUM7Z0JBQ3RELENBQUM7Z0JBQ0QsSUFBSSx3QkFBd0IsS0FBSyxDQUFDLENBQUMsRUFBRSxDQUFDO29CQUNwQyxTQUFTLEdBQUcsS0FBSyxDQUFDO2dCQUNwQixDQUFDO1lBQ0gsQ0FBQztZQUVELFlBQVksQ0FBQyxJQUFJLEdBQUcsRUFBRSxDQUFDO1lBQ3ZCLFlBQVksQ0FBQyxPQUFPLEdBQUc7Z0JBQ3JCLENBQUMsRUFBRSxPQUFPLENBQUMsRUFBRSxJQUFJLENBQUM7Z0JBQ2xCLENBQUMsRUFBRSxPQUFPLENBQUMsRUFBRSxJQUFJLENBQUM7YUFDbkIsQ0FBQztRQUNKLENBQUM7UUFFRCx5REFBeUQ7UUFDekQsTUFBTSxnQkFBZ0IsR0FBRyxzQ0FBc0MsQ0FBQyw0QkFBNEIsQ0FBQyxZQUFZLENBQUMsT0FBTyxDQUFDLENBQUMsSUFBSSxDQUFDLEVBQUUsV0FBVyxDQUFDLENBQUMsRUFBRSxZQUFZLENBQUMsT0FBTyxDQUFDLENBQUMsSUFBSSxDQUFDLEVBQUUsR0FBRyxFQUFFLFlBQVksQ0FBVSxDQUFDO1FBQ2xNLE1BQU0sY0FBYyxHQUFHLHNDQUFzQyxDQUFDLG9CQUFvQixDQUFDLFlBQVksQ0FBQyxPQUFPLENBQUMsQ0FBQyxJQUFJLENBQUMsRUFBRSxpQkFBaUIsQ0FBQyxDQUFDLEVBQUUsR0FBRyxDQUFDLENBQUM7UUFDMUksTUFBTSxPQUFPLEdBQUcsc0NBQXNDLENBQUMsU0FBUyxDQUFDLEVBQUUsQ0FBQyxFQUFFLFlBQVksQ0FBQyxPQUFPLENBQUMsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLEVBQUUsWUFBWSxDQUFDLE9BQU8sQ0FBQyxDQUFDLElBQUksQ0FBQyxFQUFFLEVBQUUsR0FBRyxlQUFlLElBQUksY0FBYyxFQUFFLEVBQUUsU0FBUyxFQUFFLFNBQVMsQ0FBQyxDQUFDLENBQUMsaURBQWlEO1FBQ3JQLE1BQU0saUJBQWlCLEdBQUcsQ0FBQyxnQkFBZ0IsRUFBRSxDQUFDLElBQUksQ0FBQyxDQUFDLEdBQUcsQ0FBQyxnQkFBZ0IsRUFBRSxLQUFLLElBQUksQ0FBQyxDQUFDLENBQUM7UUFFdEYsSUFBSSxnQkFBZ0IsSUFBSSxJQUFJLENBQUMsR0FBRyxDQUFDLGlCQUFpQixHQUFHLENBQUMsWUFBWSxDQUFDLE9BQU8sQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsSUFBSSxTQUFTLEdBQUcsQ0FBQyxFQUFFLENBQUM7WUFDckcsT0FBTyxDQUFDLEVBQUUsR0FBRyxZQUFZLENBQUMsT0FBTyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUM7WUFDekMsT0FBTyxDQUFDLEVBQUUsR0FBRyxZQUFZLENBQUMsT0FBTyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUM7WUFDekMsT0FBTyxDQUFDLENBQUMsR0FBRyxZQUFZLENBQUMsT0FBTyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUM7WUFDeEMsT0FBTyxDQUFDLENBQUMsR0FBRyxZQUFZLENBQUMsT0FBTyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDMUMsQ0FBQztRQUVELDZCQUE2QjtRQUM3QixNQUFNLGVBQWUsR0FBRyxzQ0FBc0MsQ0FBQyxvQkFBb0IsQ0FBQyxPQUFPLENBQUMsQ0FBQyxJQUFJLENBQUMsRUFBRSxpQkFBaUIsQ0FBQyxDQUFDLEVBQUUsR0FBRyxDQUFDLENBQUM7UUFFOUgsV0FBVyxDQUFDLENBQUMsR0FBRyw0QkFBNEIsQ0FBQyx3QkFBd0IsQ0FBQyxlQUFlLEVBQUUsV0FBVyxDQUFDLENBQUMsRUFBRSxTQUFTLENBQUMsQ0FBQztRQUNqSCxJQUFJLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxHQUFHLFdBQVcsQ0FBQyxDQUFDLENBQUMsSUFBSSxTQUFTLEVBQUUsQ0FBQztZQUM1RCxXQUFXLENBQUMsQ0FBQyxJQUFJLFNBQVMsQ0FBQztRQUM3QixDQUFDO1FBQ0QsTUFBTSxjQUFjLEdBQWMsRUFBRSxDQUFDO1FBQ3JDLE1BQU0sT0FBTyxHQUFHLHNDQUFzQyxDQUFDLHVCQUF1QixDQUFDLE9BQU8sQ0FBQyxDQUFDLElBQUksQ0FBQyxFQUFFLE9BQU8sQ0FBQyxDQUFDLElBQUksQ0FBQyxFQUFFLFNBQVMsRUFBRSxXQUFXLEVBQUUsWUFBWSxFQUFFLGNBQWMsQ0FBQyxDQUFDO1FBRXJLLElBQUksZUFBZSxLQUFLLE1BQU0sSUFBSSxPQUFPLENBQUMsQ0FBQyxHQUFHLENBQUMsT0FBTyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsRUFBRSxDQUFDO1lBQy9ELGVBQWUsQ0FBQyxJQUFJLENBQUMsRUFBRSxLQUFLLEVBQUUsWUFBWSxDQUFDLE9BQU8sRUFBRSxHQUFHLEVBQUUsaUJBQWlCLEVBQUUsSUFBSSxFQUFFLFVBQVUsRUFBRSxFQUFFLEVBQUUsS0FBSyxHQUFHLGVBQWUsRUFBRSxDQUFDLENBQUM7WUFDN0gsSUFBSSxDQUFDLDBCQUEwQixDQUFDLGlCQUFpQixFQUFFLGlCQUFpQixFQUFFLFNBQVMsRUFBRSxXQUFXLEVBQUUsZUFBZSxDQUFDLENBQUM7WUFFL0csT0FBTztRQUNULENBQUM7UUFFRCxlQUFlLENBQUMsSUFBSSxDQUFDLEdBQUcsY0FBYyxDQUFDLENBQUM7UUFDeEMsZUFBZSxDQUFDLElBQUksQ0FBQyxFQUFFLEtBQUssRUFBRSxZQUFZLENBQUMsT0FBTyxFQUFFLEdBQUcsRUFBRSxFQUFFLENBQUMsRUFBRSxPQUFPLENBQUMsQ0FBQyxJQUFJLENBQUMsR0FBRyxFQUFFLEVBQUUsQ0FBQyxFQUFFLE9BQU8sQ0FBQyxDQUFDLElBQUksQ0FBQyxFQUFFLEVBQUUsSUFBSSxFQUFFLHVCQUF1QixFQUFFLEVBQUUsRUFBRSxLQUFLLEdBQUcsZUFBZSxFQUFFLENBQUMsQ0FBQztRQUN0SyxJQUFJLENBQUMsMEJBQTBCLENBQUMsRUFBRSxDQUFDLEVBQUUsT0FBTyxDQUFDLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxFQUFFLE9BQU8sQ0FBQyxDQUFDLElBQUksQ0FBQyxFQUFFLEVBQUUsaUJBQWlCLEVBQUUsU0FBUyxFQUFFLFdBQVcsRUFBRSxlQUFlLENBQUMsQ0FBQztRQUV0SSxPQUFPO1lBQ0wsS0FBSyxFQUFFLEVBQUU7U0FDVixDQUFDO0lBQ0osQ0FBQztJQUVPLE1BQU0sQ0FBQywwQkFBMEIsQ0FBQyxLQUFrQixFQUFFLEdBQWdCLEVBQUUsU0FBaUIsRUFBRSxXQUFrQixFQUFFLGVBQStCO1FBQ3BKLE1BQU0sVUFBVSxHQUFHLHNDQUFzQyxDQUFDLG9CQUFvQixDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsR0FBRyxDQUFDLENBQUMsRUFBRSxHQUFHLENBQUMsQ0FBQztRQUVwRyxJQUFJLEtBQUssQ0FBQyxDQUFDLEtBQUssR0FBRyxDQUFDLENBQUMsRUFBRSxDQUFDO1lBQ3RCLGVBQWUsQ0FBQyxJQUFJLENBQUMsRUFBRSxLQUFLLEVBQUUsR0FBRyxFQUFFLEVBQUUsQ0FBQyxFQUFFLENBQUMsV0FBVyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsR0FBRyxDQUFDLFdBQVcsQ0FBQyxLQUFLLElBQUksQ0FBQyxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsRUFBRSxXQUFXLENBQUMsQ0FBQyxJQUFJLENBQUMsRUFBRSxFQUFFLElBQUksRUFBRSxZQUFZLEVBQUUsRUFBRSxFQUFFLEdBQUcsRUFBRSxDQUFDLENBQUM7WUFFckosT0FBTyxLQUFLLFdBQVcsQ0FBQyxDQUFDLElBQUksR0FBRyxDQUFDLENBQUMsRUFBRSxDQUFDO1FBQ3ZDLENBQUM7UUFFRCxNQUFNLElBQUksR0FBRyxFQUFFLENBQUMsRUFBRSxLQUFLLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxLQUFLLENBQUMsQ0FBQyxFQUFFLENBQUM7UUFDeEMsTUFBTSxRQUFRLEdBQUc7WUFDZixDQUFDLEVBQUUsR0FBRyxDQUFDLENBQUM7WUFDUixDQUFDLEVBQUUsV0FBVyxDQUFDLENBQUM7U0FDakIsQ0FBQztRQUNGLE1BQU0sTUFBTSxHQUFHLEVBQUUsQ0FBQztRQUVsQixJQUFJLElBQUksQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLENBQUMsR0FBRyxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsU0FBUyxFQUFFLENBQUM7WUFDMUMsTUFBTSxVQUFVLEdBQUcsc0NBQXNDLENBQUMsb0JBQW9CLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxRQUFRLENBQUMsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDO1lBQ3pHLE1BQU0sR0FBRyxHQUFHLDRCQUE0QixDQUFDLHdCQUF3QixDQUFDLFVBQVUsRUFBRSxHQUFHLENBQUMsQ0FBQyxFQUFFLFNBQVMsQ0FBQyxDQUFDO1lBQ2hHLE1BQU0sR0FBRyxHQUFHLDRCQUE0QixDQUFDLHdCQUF3QixDQUFDLFVBQVUsRUFBRSxHQUFHLENBQUMsQ0FBQyxFQUFFLFNBQVMsQ0FBQyxDQUFDO1lBRWhHLElBQUksQ0FBQyxDQUFDLEdBQUcsR0FBRyxDQUFDO1lBQ2IsSUFBSSxDQUFDLENBQUMsR0FBRyxHQUFHLENBQUM7WUFDYixlQUFlLENBQUMsSUFBSSxDQUFDLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxHQUFHLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSx1QkFBdUIsRUFBRSxFQUFFLEVBQUUsR0FBRyxFQUFFLENBQUMsQ0FBQztRQUM1RixDQUFDO1FBRUQsZUFBZSxDQUFDLElBQUksQ0FBQyxFQUFFLEtBQUssRUFBRSxJQUFJLEVBQUUsR0FBRyxFQUFFLFFBQVEsRUFBRSxJQUFJLEVBQUUseUJBQXlCLEVBQUUsRUFBRSxFQUFFLEdBQUcsRUFBRSxDQUFDLENBQUM7UUFFL0YsT0FBTyxLQUFLLElBQUksQ0FBQyxDQUFDLElBQUksSUFBSSxDQUFDLENBQUMsSUFBSSxNQUFNLEVBQUUsQ0FBQztJQUMzQyxDQUFDO0lBRU8sTUFBTSxDQUFDLCtCQUErQixDQUFDLFdBQWtCLEVBQUUsS0FBYSxFQUFFLFNBQWlCLEVBQUUsWUFBcUIsRUFBRSxlQUErQjtRQUN6SixNQUFNLFdBQVcsR0FBRztZQUNsQixDQUFDLEVBQUUsQ0FBQyxXQUFXLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxHQUFHLENBQUMsV0FBVyxDQUFDLEtBQUssSUFBSSxDQUFDLENBQUMsR0FBRyxDQUFDO1lBQ3RELENBQUMsRUFBRSxDQUFDLFdBQVcsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLEdBQUcsU0FBUztTQUNwQyxDQUFDO1FBRUYsNkNBQTZDO1FBQzdDLE1BQU0sR0FBRyxHQUFHLEVBQUUsQ0FBQyxFQUFFLENBQUMsS0FBSyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsR0FBRyxFQUFFLEVBQUUsQ0FBQyxFQUFFLENBQUMsS0FBSyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsR0FBRyxFQUFFLEVBQUUsQ0FBQztRQUUvRCxlQUFlLENBQUMsSUFBSSxDQUFDLEVBQUUsS0FBSyxFQUFFLEVBQUUsQ0FBQyxFQUFFLEtBQUssQ0FBQyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsRUFBRSxLQUFLLENBQUMsQ0FBQyxJQUFJLENBQUMsRUFBRSxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsSUFBSSxFQUFFLHVCQUF1QixFQUFFLEVBQUUsRUFBRSxHQUFHLEVBQUUsQ0FBQyxDQUFDO1FBRXhILE1BQU0sWUFBWSxHQUFHLFNBQVMsQ0FBQyxXQUFXLENBQUMsQ0FBQztRQUU1QyxZQUFZLENBQUMsQ0FBQyxJQUFJLEVBQUUsQ0FBQztRQUVyQixJQUFJLGtDQUFrQyxHQUFtQixFQUFFLENBQUM7UUFDNUQsSUFBSSxFQUFFLElBQUksRUFBRSxPQUFPLEVBQUUsR0FBRyxzQ0FBc0MsQ0FBQyxtQkFBbUIsQ0FBQyxHQUFHLENBQUMsQ0FBQyxJQUFJLENBQUMsRUFBRSxHQUFHLENBQUMsQ0FBQyxJQUFJLENBQUMsRUFBRSxTQUFTLEVBQUUsWUFBWSxFQUFFLFlBQVksRUFBRSxrQ0FBa0MsQ0FBQyxDQUFDO1FBRXRMLElBQUksSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLEdBQUcsV0FBVyxDQUFDLENBQUMsQ0FBQyxHQUFHLEVBQUUsRUFBRSxDQUFDO1lBQ2xELElBQUksR0FBRyxFQUFFLENBQUM7WUFDVixPQUFPLEdBQUc7Z0JBQ1IsQ0FBQyxFQUFFLEtBQUssQ0FBQyxDQUFDO2dCQUNWLENBQUMsRUFBRSxLQUFLLENBQUMsQ0FBQzthQUNYLENBQUM7WUFFRixrQ0FBa0MsR0FBRyxFQUFFLENBQUM7UUFDMUMsQ0FBQztRQUVELGVBQWUsQ0FBQyxNQUFNLENBQUMsZUFBZSxDQUFDLE1BQU0sRUFBRSxDQUFDLEVBQUUsR0FBRyxrQ0FBa0MsQ0FBQyxDQUFDO1FBRXpGLG1KQUFtSjtRQUNuSixNQUFNLFVBQVUsR0FBRyxzQ0FBc0MsQ0FBQyxvQkFBb0IsQ0FBQyxPQUFPLENBQUMsQ0FBQyxFQUFFLFdBQVcsQ0FBQyxDQUFDLEVBQUUsR0FBRyxDQUFDLENBQUM7UUFFOUcsSUFBSSxVQUFVLEtBQUssUUFBUSxFQUFFLENBQUM7WUFDNUIsTUFBTSxJQUFJLEdBQUcsRUFBRSxDQUFDLEVBQUUsV0FBVyxDQUFDLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxFQUFFLE9BQU8sQ0FBQyxDQUFDLEVBQUUsQ0FBQztZQUVyRCxlQUFlLENBQUMsSUFBSSxDQUFDLEVBQUUsS0FBSyxFQUFFLE9BQU8sRUFBRSxHQUFHLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxZQUFZLEVBQUUsRUFBRSxFQUFFLEdBQUcsRUFBRSxDQUFDLENBQUM7WUFFakYsb0JBQW9CO1lBQ3BCLElBQUksQ0FBQywwQkFBMEIsQ0FBQyxJQUFJLEVBQUUsV0FBVyxFQUFFLFNBQVMsRUFBRSxXQUFXLEVBQUUsZUFBZSxDQUFDLENBQUM7WUFFNUYsT0FBTztnQkFDTCxLQUFLLEVBQUUsR0FBRyxJQUFJLE1BQU0sSUFBSSxDQUFDLENBQUMsSUFBSSxJQUFJLENBQUMsQ0FBQyxFQUFFO2dCQUN0QyxPQUFPLEVBQUUsSUFBSTthQUNkLENBQUM7UUFDSixDQUFDO1FBRUQsTUFBTSxPQUFPLEdBQUcsc0NBQXNDLENBQUMsU0FBUyxDQUFDLEVBQUUsQ0FBQyxFQUFFLE9BQU8sQ0FBQyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsRUFBRSxPQUFPLENBQUMsQ0FBQyxJQUFJLENBQUMsRUFBRSxFQUFFLFNBQVMsVUFBVSxLQUFLLE9BQU8sQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxPQUFPLEVBQUUsRUFBRSxTQUFTLEVBQUUsU0FBUyxDQUFDLENBQUMsQ0FBQyxpREFBaUQ7UUFDMU8sTUFBTSxZQUFZLEdBQUcsU0FBUyxDQUFDLFdBQVcsQ0FBQyxDQUFDO1FBRTVDLFlBQVksQ0FBQyxDQUFDLEdBQUcsNEJBQTRCLENBQUMsd0JBQXdCLENBQUMsVUFBVSxFQUFFLFdBQVcsQ0FBQyxDQUFDLEVBQUUsU0FBUyxDQUFDLEdBQUcsRUFBRSxDQUFDO1FBRWxILGlFQUFpRTtRQUNqRSxNQUFNLDZCQUE2QixHQUFHLHNDQUFzQyxDQUFDLDJCQUEyQixDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsR0FBRyxFQUFFLEVBQUUsT0FBTyxDQUFDLENBQUMsSUFBSSxDQUFDLEVBQUUsWUFBWSxFQUFFLFlBQVksQ0FBQyxDQUFDO1FBRTVLLElBQUksNkJBQTZCLEVBQUUsQ0FBQztZQUNsQyxPQUFPLENBQUMsQ0FBQyxHQUFHLENBQUMsNkJBQTZCLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxHQUFHLENBQUMsNkJBQTZCLENBQUMsS0FBSyxJQUFJLENBQUMsQ0FBQyxHQUFHLFNBQVMsQ0FBQztRQUM5RyxDQUFDO1FBQ0QsZUFBZSxDQUFDLElBQUksQ0FBQyxFQUFFLEtBQUssRUFBRSxFQUFFLENBQUMsRUFBRSxPQUFPLENBQUMsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLEVBQUUsT0FBTyxDQUFDLENBQUMsRUFBRSxFQUFFLEdBQUcsRUFBRSxFQUFFLENBQUMsRUFBRSxPQUFPLENBQUMsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLEVBQUUsT0FBTyxDQUFDLENBQUMsSUFBSSxDQUFDLEVBQUUsRUFBRSxJQUFJLEVBQUUseUJBQXlCLEVBQUUsRUFBRSxFQUFFLEdBQUcsRUFBRSxDQUFDLENBQUM7UUFFOUosSUFBSSxnQkFBZ0IsR0FBYyxFQUFFLENBQUM7UUFDckMsTUFBTSxZQUFZLEdBQUcsc0NBQXNDLENBQUMsb0JBQW9CLENBQUMsT0FBTyxDQUFDLENBQUMsSUFBSSxDQUFDLEVBQUUsT0FBTyxDQUFDLENBQUMsSUFBSSxDQUFDLEVBQUUsU0FBUyxFQUFFLFlBQVksRUFBRSxVQUFVLEVBQUUsWUFBWSxFQUFFLGdCQUFnQixDQUFDLENBQUM7UUFFdEwsSUFBSSxVQUFVLEtBQUssT0FBTyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsR0FBRyxZQUFZLENBQUMsQ0FBQyxFQUFFLENBQUM7WUFDaEUsZ0JBQWdCLEdBQUcsRUFBRSxDQUFDO1lBQ3RCLFlBQVksQ0FBQyxPQUFPLEdBQUcsRUFBRSxDQUFDLEVBQUUsT0FBTyxDQUFDLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxFQUFFLE9BQU8sQ0FBQyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUM7UUFDbEUsQ0FBQztRQUNELGVBQWUsQ0FBQyxJQUFJLENBQUMsR0FBRyxnQkFBZ0IsQ0FBQyxDQUFDO1FBQzFDLElBQUksQ0FBQywwQkFBMEIsQ0FBQyxFQUFFLENBQUMsRUFBRSxZQUFZLENBQUMsT0FBTyxDQUFDLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxFQUFFLFlBQVksQ0FBQyxPQUFPLENBQUMsQ0FBQyxJQUFJLENBQUMsRUFBRSxFQUFFLFdBQVcsRUFBRSxTQUFTLEVBQUUsV0FBVyxFQUFFLGVBQWUsQ0FBQyxDQUFDO1FBRTFKLE9BQU87WUFDTCxLQUFLLEVBQUUsRUFBRTtTQUNWLENBQUM7SUFDSixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgY2xvbmVEZWVwIH0gZnJvbSAnQGxpYnMtdWkvdXRpbHMnO1xuaW1wb3J0IHsgSVBvaW50LCBJUG9pbnRzLCBJUmVjdCB9IGZyb20gJy4uL2RyYXctbGluZS5pbnRlcmZhY2UnO1xuaW1wb3J0IHsgTW9DYW52YXNDYWxjdWxhdG9yQnJhbmNoVXRpbCB9IGZyb20gJy4vY2FsY3VsYXRvci1icmFuY2gudXRpbCc7XG5pbXBvcnQgeyBNb0NhbnZhc0NhbGN1bGF0b3JEaXJlY3Rpb25FbGVtZW50VXRpbCB9IGZyb20gJy4vY2FsY3VsYXRvci1kaXJldGlvbi1lbGVtZW50LnVudGlsJztcbmltcG9ydCB7IE1vQ2FudmFzQ29ubmVjdE5hdmlnYXRpb25Cb3R0b21MZWZ0RWxlbWVudFV0aWwgfSBmcm9tICcuL2xpbmUtY29ubmVjdC1ib3R0b20tbGVmdC51bnRpbCc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgSVBvc2l0aW9uWFkge1xuICB4OiBudW1iZXI7XG4gIHk6IG51bWJlcjtcbn1cbmV4cG9ydCBjbGFzcyBNb0NhbnZhc0Nvbm5lY3ROYXZpZ2F0aW9uTmV3RWxlbWVudFV0aWwge1xuICBzdGF0aWMgRUxFTUVOVF9NQVJHSU5fQkVUV0VFTl9CUkFOQ0hfREVGQVVMVCA9IDMyO1xuICBzdGF0aWMgU1RBUlRfTU9ERSA9ICdyaWdodC1sZWZ0JztcblxuICBzdGF0aWMgc2V0WFlDb25uZWN0RWxlbWVudHMoZWxlbWVudEZyb206IElSZWN0LCBlbGVtZW50TmV4dDogSVJlY3QsIG9ic3RhY2xlUmVjdDogSVJlY3RbXSwgc2VwYXJhdGVkUG9pbnRzOiBBcnJheTxJUG9pbnRzPiwgY3VydmU6IG51bWJlcikge1xuICAgIHRoaXMuZHJhd0xpbmVDb25uZWN0KGVsZW1lbnRGcm9tLCBlbGVtZW50TmV4dCwgb2JzdGFjbGVSZWN0LCBzZXBhcmF0ZWRQb2ludHMsIGN1cnZlKTtcbiAgfVxuXG4gIHN0YXRpYyBkcmF3TGluZUNvbm5lY3QoZWxlbWVudEZyb206IElSZWN0LCBlbGVtZW50TmV4dDogSVJlY3QsIG9ic3RhY2xlUmVjdDogSVJlY3RbXSwgc2VwYXJhdGVkUG9pbnRzOiBBcnJheTxJUG9pbnRzPiwgY3VydmU6IG51bWJlcikge1xuICAgIGxldCBzdGFydF94ID0gKGVsZW1lbnRGcm9tLnggPz8gMCkgKyAoZWxlbWVudEZyb20ud2lkdGggPz8gMCk7IC8vIMSRaeG7g20gb3V0IGx1w7RuIOG7nyBwaMOtYSBiw6puIHBo4bqjaVxuICAgIGxldCBzdGFydF95ID0gKGVsZW1lbnRGcm9tLnkgPz8gMCkgKyAoZWxlbWVudEZyb20uaGVpZ2h0ID8/IDApIC8gMjsgLy8gxJFp4buDbSBvdXQgbHXDtG4g4bufIHBow61hIGLDqm4gcGjhuqNpXG5cbiAgICBpZiAoTW9DYW52YXNDb25uZWN0TmF2aWdhdGlvbk5ld0VsZW1lbnRVdGlsLlNUQVJUX01PREUgPT09ICdib3R0b20tdG9wJykge1xuICAgICAgLy8gxJFp4buDbSBvdXQgbHXDtG4g4bufIHBow61hIGLDqm4gZMaw4bubaVxuICAgICAgc3RhcnRfeCA9IChlbGVtZW50RnJvbS54ID8/IDApICsgKGVsZW1lbnRGcm9tLndpZHRoID8/IDApIC8gMjtcbiAgICAgIHN0YXJ0X3kgPSAoZWxlbWVudEZyb20ueSA/PyAwKSArIChlbGVtZW50RnJvbS5oZWlnaHQgPz8gMCk7XG4gICAgfVxuICAgIGlmIChNb0NhbnZhc0Nvbm5lY3ROYXZpZ2F0aW9uTmV3RWxlbWVudFV0aWwuU1RBUlRfTU9ERSA9PT0gJ2JvdHRvbS1sZWZ0Jykge1xuICAgICAgLy8gxJFp4buDbSBvdXQgbHXDtG4g4bufIHBow61hIGLDqm4gZMaw4bubaVxuICAgICAgc3RhcnRfeCA9IChlbGVtZW50RnJvbS54ID8/IDApICsgKGVsZW1lbnRGcm9tLndpZHRoID8/IDApIC8gMjtcbiAgICAgIHN0YXJ0X3kgPSAoZWxlbWVudEZyb20ueSA/PyAwKSArIChlbGVtZW50RnJvbS5oZWlnaHQgPz8gMCk7XG4gICAgfVxuICAgIGNvbnN0IE1fc3RhcnQ6IElQb2ludCA9IHsgeDogc3RhcnRfeCwgeTogc3RhcnRfeSB9O1xuXG4gICAgY29uc3QgZGlyZWN0aW9uWCA9IE1vQ2FudmFzQ2FsY3VsYXRvckRpcmVjdGlvbkVsZW1lbnRVdGlsLmNoZWNrVXBEb3duTGVmdFJpZ2h0KHN0YXJ0X3gsIGVsZW1lbnROZXh0LngsICd4Jyk7XG5cbiAgICBzd2l0Y2ggKE1vQ2FudmFzQ29ubmVjdE5hdmlnYXRpb25OZXdFbGVtZW50VXRpbC5TVEFSVF9NT0RFKSB7XG4gICAgICBjYXNlICdyaWdodC1sZWZ0JzpcbiAgICAgICAgaWYgKGRpcmVjdGlvblggPT09ICdsZWZ0Jykge1xuICAgICAgICAgIHRoaXMubGluZUNvbm5lY3RMZWZ0KGVsZW1lbnROZXh0LCBlbGVtZW50RnJvbSwgTV9zdGFydCwgY3VydmUsIG9ic3RhY2xlUmVjdCwgc2VwYXJhdGVkUG9pbnRzKTtcblxuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmxpbmVDb25uZWN0UmlnaHQoZWxlbWVudE5leHQsIE1fc3RhcnQsIGN1cnZlLCBvYnN0YWNsZVJlY3QsIHNlcGFyYXRlZFBvaW50cyk7XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBjYXNlICdib3R0b20tdG9wJzpcbiAgICAgICAgaWYgKGRpcmVjdGlvblggPT09ICdsZWZ0Jykge1xuICAgICAgICAgIHRoaXMubGluZUNvbm5lY3RMZWZ0V2l0aEJvdHRvbVN0YXJ0KGVsZW1lbnROZXh0LCBlbGVtZW50RnJvbSwgTV9zdGFydCwgY3VydmUsIG9ic3RhY2xlUmVjdCwgc2VwYXJhdGVkUG9pbnRzKTtcblxuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmxpbmVDb25uZWN0UmlnaHRXaXRoQm90dG9tU3RhcnQoZWxlbWVudE5leHQsIE1fc3RhcnQsIGN1cnZlLCBvYnN0YWNsZVJlY3QsIHNlcGFyYXRlZFBvaW50cyk7XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBjYXNlICdib3R0b20tbGVmdCc6XG4gICAgICAgIGNvbnNvbGUubG9nKGRpcmVjdGlvblgpO1xuICAgICAgICBpZiAoZGlyZWN0aW9uWCA9PT0gJ2xlZnQnKSB7XG4gICAgICAgICAgTW9DYW52YXNDb25uZWN0TmF2aWdhdGlvbkJvdHRvbUxlZnRFbGVtZW50VXRpbC5saW5lTGVmdChlbGVtZW50TmV4dCwgZWxlbWVudEZyb20sIE1fc3RhcnQsIGN1cnZlLCBvYnN0YWNsZVJlY3QsIHNlcGFyYXRlZFBvaW50cyk7XG5cbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgTW9DYW52YXNDb25uZWN0TmF2aWdhdGlvbkJvdHRvbUxlZnRFbGVtZW50VXRpbC5yaWdodExlZnQoZWxlbWVudE5leHQsIE1fc3RhcnQsIGN1cnZlLCBvYnN0YWNsZVJlY3QsIHNlcGFyYXRlZFBvaW50cyk7XG4gICAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgc3RhdGljIGxpbmVDb25uZWN0UmlnaHQoZWxlbWVudE5leHQ6IElSZWN0LCBzdGFydDogSVBvaW50LCBsaW5lQ3VydmU6IG51bWJlciwgb2JzdGFjbGVSZWN0OiBJUmVjdFtdLCBzZXBhcmF0ZWRQb2ludHM6IEFycmF5PElQb2ludHM+KSB7XG4gICAgY29uc3QgZW5kUG9zaXRpb24gPSB7XG4gICAgICB4OiAoZWxlbWVudE5leHQueCA/PyAwKSAtIGxpbmVDdXJ2ZSAqIDMsXG4gICAgICB5OiAoZWxlbWVudE5leHQueSA/PyAwKSArIChlbGVtZW50TmV4dC5oZWlnaHQgPz8gMCkgLyAyLFxuICAgIH07XG5cbiAgICBjb25zdCBlbmRQb3NpdGlvblggPSBjbG9uZURlZXAoZW5kUG9zaXRpb24pO1xuXG4gICAgbGV0IHNlcGFyYXRlZFBvaW50c0NoZWNrQW5kQXZvaWRCbG9ja3M6IEFycmF5PElQb2ludHM+ID0gW107XG4gICAgbGV0IHsgcGF0aCwgZW5kUGF0aCB9ID0gTW9DYW52YXNDYWxjdWxhdG9yRGlyZWN0aW9uRWxlbWVudFV0aWwuY2hlY2tBbmRBdm9pZEJsb2NrcyhzdGFydC54ID8/IDAsIHN0YXJ0LnkgPz8gMCwgbGluZUN1cnZlLCBlbmRQb3NpdGlvblgsIG9ic3RhY2xlUmVjdCwgc2VwYXJhdGVkUG9pbnRzQ2hlY2tBbmRBdm9pZEJsb2Nrcyk7XG5cbiAgICBpZiAoTWF0aC5hYnMoKHN0YXJ0LnggPz8gMCkgLSBlbmRQb3NpdGlvbi54KSA8IDEwKSB7XG4gICAgICBwYXRoID0gJyc7XG4gICAgICBlbmRQYXRoID0ge1xuICAgICAgICB4OiBzdGFydC54LFxuICAgICAgICB5OiBzdGFydC55LFxuICAgICAgfTtcblxuICAgICAgc2VwYXJhdGVkUG9pbnRzQ2hlY2tBbmRBdm9pZEJsb2NrcyA9IFtdO1xuICAgIH1cblxuICAgIHNlcGFyYXRlZFBvaW50cy5zcGxpY2Uoc2VwYXJhdGVkUG9pbnRzLmxlbmd0aCwgMCwgLi4uc2VwYXJhdGVkUG9pbnRzQ2hlY2tBbmRBdm9pZEJsb2Nrcyk7XG5cbiAgICAvLyBzYXUga2hpIMSRw6MgxJFpIG5nYW5nIHbDoCB0csOhbmggY8OhYyBraOG7kWksIHRp4bq/cCB0aGVvIGzDoCDEkWkgdGnhur9wIGjGsOG7m25nIGzDqm4geHXhu5FuZyDEkeG7gyB24buBIGto4buRaSBj4bqnbiBu4buRaSB04bubaSwgY+G6p24gY2hlY2sgeGVtIMSRaeG7g20gZW5kIFggbsOzIMSRYW5nIOG7nyBoxrDhu5tuZyBuw6BvXG4gICAgY29uc3QgZGlyZWN0aW9uWSA9IE1vQ2FudmFzQ2FsY3VsYXRvckRpcmVjdGlvbkVsZW1lbnRVdGlsLmNoZWNrVXBEb3duTGVmdFJpZ2h0KGVuZFBhdGgueSwgZW5kUG9zaXRpb24ueSwgJ3knKTtcblxuICAgIGlmIChkaXJlY3Rpb25ZID09PSAnY2VudGVyJykge1xuICAgICAgY29uc3QgTEVuZCA9IHsgeDogZWxlbWVudE5leHQueCA/PyAwLCB5OiBlbmRQYXRoLnkgfTtcblxuICAgICAgc2VwYXJhdGVkUG9pbnRzLnB1c2goeyBzdGFydDogZW5kUGF0aCwgZW5kOiBMRW5kLCBtb2RlOiAnaG9yaXpvbnRhbCcsIGlkOiAnZicgfSk7XG5cbiAgICAgIHJldHVybiB7XG4gICAgICAgIGRQYXRoOiBgJHtwYXRofSBMICR7TEVuZC54fSAke0xFbmQueX1gLFxuICAgICAgICBlbmRQYXRoOiBMRW5kLFxuICAgICAgfTtcbiAgICB9XG5cbiAgICBsZXQgbGluZUN1cnZlU3ViWSA9IGxpbmVDdXJ2ZTtcblxuICAgIGlmIChNYXRoLmFicygoZW5kUGF0aC55ID8/IDApIC0gZW5kUG9zaXRpb24ueSkgPCBsaW5lQ3VydmUgKiAyKSB7XG4gICAgICBsaW5lQ3VydmVTdWJZID0gTWF0aC5hYnMoKGVuZFBhdGgueSA/PyAwKSAtIGVuZFBvc2l0aW9uLnkpIC8gMjtcblxuICAgICAgY29uc3QgY29vcmRRMSA9IE1vQ2FudmFzQ2FsY3VsYXRvckRpcmVjdGlvbkVsZW1lbnRVdGlsLmRyYXdMaW5lUSh7IHg6IGVuZFBhdGgueCA/PyAwLCB5OiBlbmRQYXRoLnkgPz8gMCB9LCBgcmlnaHQtJHtkaXJlY3Rpb25ZID09PSAnYWJvdmUnID8gJ2Fib3ZlJyA6ICd1bmRlcid9YCwgbGluZUN1cnZlU3ViWSAqIDIsIGxpbmVDdXJ2ZVN1YlkpOyAvLyB0w61uaCDEkW/huqFuIGNvbmcgdOG7qyDEkcaw4budbmcgbmdhbmcgc2FuZyDEkcaw4budbmcgdGjhurNuZ1xuICAgICAgY29uc3QgcGF0aFExID0gYFEgJHtjb29yZFExLngxfSwke2Nvb3JkUTEueTF9ICR7Y29vcmRRMS54fSwke2Nvb3JkUTEueX1gOyAvLyB04burIG5nYW5nIHNhbmcgdGjhurNuZyBwaOG6o2kgY8OzIMSRxrDhu51uZyBjb25nXG4gICAgICBjb25zdCBjb29yZFEyID0gTW9DYW52YXNDYWxjdWxhdG9yRGlyZWN0aW9uRWxlbWVudFV0aWwuZHJhd0xpbmVRKHsgeDogY29vcmRRMS54ID8/IDAsIHk6IGNvb3JkUTEueSA/PyAwIH0sIGAke2RpcmVjdGlvblkgPT09ICdhYm92ZScgPyAnYWJvdmUnIDogJ3VuZGVyJ30tcmlnaHRgLCBsaW5lQ3VydmVTdWJZICogMiwgbGluZUN1cnZlU3ViWSk7IC8vIHTDrW5oIMSRb+G6oW4gY29uZyB04burIMSRxrDhu51uZyB0aOG6s25nIHNhbmcgbmdhbmdcbiAgICAgIGNvbnN0IHBhdGhRMiA9IGBRICR7Y29vcmRRMi54MX0sJHtjb29yZFEyLnkxfSAke2Nvb3JkUTIueH0sJHtjb29yZFEyLnl9YDtcblxuICAgICAgc2VwYXJhdGVkUG9pbnRzLnB1c2goeyBzdGFydDogZW5kUGF0aCwgZW5kOiB7IHg6IGNvb3JkUTEueCA/PyAwLCB5OiBjb29yZFExLnkgPz8gMCB9LCBtb2RlOiAnaG9yaXpvbnRhbC1zaW5nbGUtY3VydmUnLCBpZDogJ2cnIH0pO1xuICAgICAgc2VwYXJhdGVkUG9pbnRzLnB1c2goeyBzdGFydDogeyB4OiBjb29yZFExLnggPz8gMCwgeTogY29vcmRRMS55ID8/IDAgfSwgZW5kOiB7IHg6IGNvb3JkUTIueCA/PyAwLCB5OiBjb29yZFEyLnkgPz8gMCB9LCBtb2RlOiAndmVydGljYWwtc2luZ2xlLWN1cnZlJywgaWQ6ICdqJyB9KTtcbiAgICAgIGNvbnN0IGxpbmVDbG9zZSA9IHRoaXMuY2xvc2VMaW5lKHsgeDogY29vcmRRMi54ID8/IDAsIHk6IGNvb3JkUTIueSA/PyAwIH0sIGVuZFBvc2l0aW9uLCBsaW5lQ3VydmUsIGVsZW1lbnROZXh0LCBzZXBhcmF0ZWRQb2ludHMpO1xuXG4gICAgICByZXR1cm4ge1xuICAgICAgICBkUGF0aDogYCR7cGF0aH0gJHtwYXRoUTF9ICR7cGF0aFEyfSAke2xpbmVDbG9zZX1gLFxuICAgICAgfTtcbiAgICB9XG5cbiAgICBjb25zdCBjb29yZFExID0gTW9DYW52YXNDYWxjdWxhdG9yRGlyZWN0aW9uRWxlbWVudFV0aWwuZHJhd0xpbmVRKHsgeDogZW5kUGF0aC54ID8/IDAsIHk6IGVuZFBhdGgueSA/PyAwIH0sIGByaWdodC0ke2RpcmVjdGlvblkgPT09ICdhYm92ZScgPyAnYWJvdmUnIDogJ3VuZGVyJ31gLCBsaW5lQ3VydmUsIGxpbmVDdXJ2ZSk7IC8vIHTDrW5oIMSRb+G6oW4gY29uZyB04burIMSRxrDhu51uZyBuZ2FuZyBzYW5nIMSRxrDhu51uZyB0aOG6s25nXG5cbiAgICBjb25zdCBwYXRoUTEgPSBgUSAke2Nvb3JkUTEueDF9LCR7Y29vcmRRMS55MX0gJHtjb29yZFExLnh9LCR7Y29vcmRRMS55fWA7IC8vIHThu6sgbmdhbmcgc2FuZyB0aOG6s25nIHBo4bqjaSBjw7MgxJHGsOG7nW5nIGNvbmdcbiAgICBjb25zdCBlbmRQb3NpdGlvblkgPSBjbG9uZURlZXAoZW5kUG9zaXRpb24pO1xuXG4gICAgZW5kUG9zaXRpb25ZLnkgPSBNb0NhbnZhc0NhbGN1bGF0b3JCcmFuY2hVdGlsLm1hdGhPcGVyYXRvcnNDYWxjdWxhdGlvbihkaXJlY3Rpb25ZLCBlbmRQb3NpdGlvbi55LCBsaW5lQ3VydmUpO1xuXG4gICAgY29uc3Qgc3RyYWlnaHRMaW5lID0gTW9DYW52YXNDYWxjdWxhdG9yRGlyZWN0aW9uRWxlbWVudFV0aWwuY2hlY2tBbmRBdm9pZEJsb2Nrc1koY29vcmRRMS54ID8/IDAsIGNvb3JkUTEueSA/PyAwLCBsaW5lQ3VydmUsIGVuZFBvc2l0aW9uWSwgZGlyZWN0aW9uWSwgb2JzdGFjbGVSZWN0LCBzZXBhcmF0ZWRQb2ludHMpO1xuXG4gICAgY29uc3QgY29vcmRRMiA9IE1vQ2FudmFzQ2FsY3VsYXRvckRpcmVjdGlvbkVsZW1lbnRVdGlsLmRyYXdMaW5lUSh7IHg6IHN0cmFpZ2h0TGluZS5lbmRQYXRoLnggPz8gMCwgeTogc3RyYWlnaHRMaW5lLmVuZFBhdGgueSA/PyAwIH0sIGAke2RpcmVjdGlvblkgPT09ICdhYm92ZScgPyAnYWJvdmUnIDogJ3VuZGVyJ30tcmlnaHRgLCBsaW5lQ3VydmUsIGxpbmVDdXJ2ZSk7IC8vIHTDrW5oIMSRb+G6oW4gY29uZyB04burIMSRxrDhu51uZyB0aOG6s25nIHNhbmcgbmdhbmdcbiAgICBjb25zdCBwYXRoUTIgPSBgUSAke2Nvb3JkUTIueDF9LCR7Y29vcmRRMi55MX0gJHtjb29yZFEyLnh9LCR7Y29vcmRRMi55fWA7IC8vIHThu6sgbmdhbmcgc2FuZyB0aOG6s25nIHBo4bqjaSBjw7MgxJHGsOG7nW5nIGNvbmdcblxuICAgIHNlcGFyYXRlZFBvaW50cy5wdXNoKHsgc3RhcnQ6IHsgeDogZW5kUGF0aC54ID8/IDAsIHk6IGVuZFBhdGgueSB9LCBlbmQ6IHsgeDogY29vcmRRMS54ID8/IDAsIHk6IGNvb3JkUTEueSA/PyAwIH0sIG1vZGU6ICdob3Jpem9udGFsLXNpbmdsZS1jdXJ2ZScsIGlkOiAnZycgfSk7XG4gICAgc2VwYXJhdGVkUG9pbnRzLnB1c2goeyBzdGFydDogeyB4OiBzdHJhaWdodExpbmUuZW5kUGF0aC54ID8/IDAsIHk6IHN0cmFpZ2h0TGluZS5lbmRQYXRoLnkgPz8gMCB9LCBlbmQ6IHsgeDogY29vcmRRMi54ID8/IDAsIHk6IGNvb3JkUTIueSA/PyAwIH0sIG1vZGU6ICd2ZXJ0aWNhbC1zaW5nbGUtY3VydmUnLCBpZDogJ2onIH0pO1xuICAgIGNvbnN0IGxpbmVDbG9zZSA9IHRoaXMuY2xvc2VMaW5lKHsgeDogY29vcmRRMi54ID8/IDAsIHk6IGNvb3JkUTIueSA/PyAwIH0sIGVuZFBvc2l0aW9uLCBsaW5lQ3VydmUsIGVsZW1lbnROZXh0LCBzZXBhcmF0ZWRQb2ludHMpO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIGRQYXRoOiBgJHtwYXRofSAke3BhdGhRMX0gJHtzdHJhaWdodExpbmUucGF0aH0gJHtwYXRoUTJ9ICR7bGluZUNsb3NlfWAsXG4gICAgICBlbmRQYXRoOiBzdHJhaWdodExpbmUuZW5kUGF0aCxcbiAgICB9O1xuICB9XG5cbiAgcHJpdmF0ZSBzdGF0aWMgbGluZUNvbm5lY3RMZWZ0KGVsZW1lbnROZXh0OiBJUmVjdCwgZWxlbWVudEZyb206IElSZWN0LCBzdGFydDogSVBvaW50LCBsaW5lQ3VydmU6IG51bWJlciwgb2JzdGFjbGVSZWN0OiBJUmVjdFtdLCBzZXBhcmF0ZWRQb2ludHM6IEFycmF5PElQb2ludHM+KSB7XG4gICAgY29uc3QgZW5kUG9zaXRpb25PcmlnaW4gPSB7XG4gICAgICB4OiAoZWxlbWVudE5leHQueCA/PyAwKSAtIGxpbmVDdXJ2ZSAqIDEuNSxcbiAgICAgIHk6IChlbGVtZW50TmV4dC55ID8/IDApICsgKGVsZW1lbnROZXh0LmhlaWdodCA/PyAwKSAvIDIsXG4gICAgfTtcblxuICAgIGNvbnN0IGVuZFBvc2l0aW9uID0gY2xvbmVEZWVwKGVuZFBvc2l0aW9uT3JpZ2luKTtcbiAgICBjb25zdCBkaXJlY3Rpb25TdGFydFkgPSBNb0NhbnZhc0NhbGN1bGF0b3JEaXJlY3Rpb25FbGVtZW50VXRpbC5jaGVja1VwRG93bkxlZnRSaWdodChzdGFydC55LCBlbmRQb3NpdGlvbk9yaWdpbi55LCAneScpO1xuXG4gICAgY29uc3QgZW5kWSA9IGRpcmVjdGlvblN0YXJ0WSA9PT0gJ3VuZGVyJyB8fCBkaXJlY3Rpb25TdGFydFkgPT09ICdjZW50ZXInID8gKGVsZW1lbnROZXh0LnkgPz8gMCkgOiAoZWxlbWVudE5leHQueSA/PyAwKSArIChlbGVtZW50TmV4dC5oZWlnaHQgPz8gMCk7XG5cbiAgICBlbmRQb3NpdGlvbi55ID0gTW9DYW52YXNDYWxjdWxhdG9yQnJhbmNoVXRpbC5tYXRoT3BlcmF0b3JzQ2FsY3VsYXRpb24oZGlyZWN0aW9uU3RhcnRZLCBlbmRZLCBsaW5lQ3VydmUgKiAyKTtcblxuICAgIGNvbnN0IHBhdGhRID0gTW9DYW52YXNDYWxjdWxhdG9yRGlyZWN0aW9uRWxlbWVudFV0aWwuZHJhd0xpbmVRKHsgeDogKHN0YXJ0LnggPz8gMCkgKyAxMCwgeTogc3RhcnQueSA/PyAwIH0sIGByaWdodC0ke2RpcmVjdGlvblN0YXJ0WSA9PT0gJ3VuZGVyJyA/ICd1bmRlcicgOiAnYWJvdmUnfWAsIGxpbmVDdXJ2ZSwgbGluZUN1cnZlKTtcbiAgICBjb25zdCBzdGFydFFMID0geyBseDogcGF0aFEueCwgbHk6IE1vQ2FudmFzQ2FsY3VsYXRvckJyYW5jaFV0aWwubWF0aE9wZXJhdG9yc0NhbGN1bGF0aW9uKGRpcmVjdGlvblN0YXJ0WSwgcGF0aFEueSA/PyAwLCAoZWxlbWVudEZyb20uaGVpZ2h0ID8/IDApIC8gMiwgdHJ1ZSkgfTtcblxuICAgIHNlcGFyYXRlZFBvaW50cy5wdXNoKHsgc3RhcnQ6IHsgeDogc3RhcnQueCA/PyAwLCB5OiBzdGFydC55ID8/IDAgfSwgZW5kOiB7IHg6IHBhdGhRLnggPz8gMCwgeTogcGF0aFEueSA/PyAwIH0sIG1vZGU6ICdob3Jpem9udGFsLXNpbmdsZS1jdXJ2ZScsIGlkOiAnMScgfSk7XG4gICAgc2VwYXJhdGVkUG9pbnRzLnB1c2goeyBzdGFydDogeyB4OiBwYXRoUS54ID8/IDAsIHk6IHBhdGhRLnkgPz8gMCB9LCBlbmQ6IHsgeDogc3RhcnRRTC5seCA/PyAwLCB5OiBzdGFydFFMLmx5IH0sIG1vZGU6ICdob3Jpem9udGFsJywgaWQ6ICcyJyB9KTtcblxuICAgIGlmIChkaXJlY3Rpb25TdGFydFkgPT09ICdjZW50ZXInKSB7XG4gICAgICBjb25zdCBjb29yZFExID0gTW9DYW52YXNDYWxjdWxhdG9yRGlyZWN0aW9uRWxlbWVudFV0aWwuZHJhd0xpbmVRKHsgeDogc3RhcnRRTC5seCA/PyAwLCB5OiBzdGFydFFMLmx5ID8/IDAgfSwgYGFib3ZlLWxlZnRgLCBsaW5lQ3VydmUsIGxpbmVDdXJ2ZSk7IC8vIHTDrW5oIMSRb+G6oW4gY29uZyB04burIMSRxrDhu51uZyBuZ2FuZyBzYW5nIMSRxrDhu51uZyB0aOG6s25nXG5cbiAgICAgIHNlcGFyYXRlZFBvaW50cy5wdXNoKHsgc3RhcnQ6IHsgeDogc3RhcnRRTC5seCA/PyAwLCB5OiBzdGFydFFMLmx5IH0sIGVuZDogeyB4OiBjb29yZFExLnggPz8gMCwgeTogY29vcmRRMS55ID8/IDAgfSwgbW9kZTogJ3ZlcnRpY2FsLXNpbmdsZS1jdXJ2ZScsIGlkOiAnMycgfSk7XG5cbiAgICAgIGNvbnN0IGVuZFBhdGggPSBNb0NhbnZhc0NhbGN1bGF0b3JEaXJlY3Rpb25FbGVtZW50VXRpbC5jaGVja0FuZEF2b2lkQmxvY2tzTGVmdChjb29yZFExLnggPz8gMCwgY29vcmRRMS55ID8/IDAsIGxpbmVDdXJ2ZSwgZW5kUG9zaXRpb24sIG9ic3RhY2xlUmVjdCwgc2VwYXJhdGVkUG9pbnRzKTtcblxuICAgICAgY29uc3QgZGlyZWN0aW9uU3RhcnRZMiA9IE1vQ2FudmFzQ2FsY3VsYXRvckRpcmVjdGlvbkVsZW1lbnRVdGlsLmNoZWNrVXBEb3duTGVmdFJpZ2h0KGVuZFBhdGgueSwgZW5kUG9zaXRpb25PcmlnaW4ueSwgJ3knKTtcblxuICAgICAgY29uc3QgY29vcmRRMiA9IE1vQ2FudmFzQ2FsY3VsYXRvckRpcmVjdGlvbkVsZW1lbnRVdGlsLmRyYXdMaW5lUSh7IHg6IGVuZFBhdGgueCA/PyAwLCB5OiBlbmRQYXRoLnkgPz8gMCB9LCBgbGVmdC0ke2RpcmVjdGlvblN0YXJ0WTIgPT09ICdhYm92ZScgPyAnYWJvdmUnIDogJ3VuZGVyJ31gLCBsaW5lQ3VydmUsIGxpbmVDdXJ2ZSk7IC8vIHTDrW5oIMSRb+G6oW4gY29uZyB04burIMSRxrDhu51uZyBuZ2FuZyBzYW5nIMSRxrDhu51uZyB0aOG6s25nXG5cbiAgICAgIHNlcGFyYXRlZFBvaW50cy5wdXNoKHsgc3RhcnQ6IHsgeDogZW5kUGF0aC54ID8/IDAsIHk6IGVuZFBhdGgueSA/PyAwIH0sIGVuZDogeyB4OiBjb29yZFEyLnggPz8gMCwgeTogY29vcmRRMi55ID8/IDAgfSwgbW9kZTogJ2hvcml6b250YWwtc2luZ2xlLWN1cnZlJywgaWQ6ICc0JyB9KTtcbiAgICAgIHRoaXMuY2xvc2VMaW5lKHsgeDogY29vcmRRMi54ID8/IDAsIHk6IGNvb3JkUTIueSA/PyAwIH0sIGVuZFBvc2l0aW9uT3JpZ2luLCBsaW5lQ3VydmUsIGVsZW1lbnROZXh0LCBzZXBhcmF0ZWRQb2ludHMpO1xuXG4gICAgICByZXR1cm4ge1xuICAgICAgICBkUGF0aDogYGAsXG4gICAgICB9O1xuICAgIH1cblxuICAgIGNvbnN0IHN0cmFpZ2h0TGluZSA9IE1vQ2FudmFzQ2FsY3VsYXRvckRpcmVjdGlvbkVsZW1lbnRVdGlsLmNoZWNrQW5kQXZvaWRCbG9ja3NZTGVmdChzdGFydFFMLmx4ID8/IDAsIHN0YXJ0UUwubHkgPz8gMCwgbGluZUN1cnZlLCBlbmRQb3NpdGlvbiwgZGlyZWN0aW9uU3RhcnRZLCBvYnN0YWNsZVJlY3QsIHNlcGFyYXRlZFBvaW50cyk7XG5cbiAgICBpZiAoTWF0aC5hYnMoKGVuZFBvc2l0aW9uLnggPz8gMCkgLSAoc3RyYWlnaHRMaW5lLmVuZFBhdGgueCA/PyAwKSkgPD0gbGluZUN1cnZlICogMikge1xuICAgICAgZW5kUG9zaXRpb24ueCA9IHN0cmFpZ2h0TGluZS5lbmRQYXRoLng7XG4gICAgfVxuXG4gICAgaWYgKChkaXJlY3Rpb25TdGFydFkgPT09ICd1bmRlcicgJiYgc3RhcnRRTC5seSA+IGVuZFBvc2l0aW9uLnkpIHx8IChkaXJlY3Rpb25TdGFydFkgPT09ICdhYm92ZScgJiYgc3RhcnRRTC5seSA8IGVuZFBvc2l0aW9uLnkpIHx8IHN0YXJ0UUwubHkgPT09IGVuZFBvc2l0aW9uLnkpIHtcbiAgICAgIGxldCBjb25kaXRpb24gPSB0cnVlO1xuXG4gICAgICB3aGlsZSAoY29uZGl0aW9uKSB7XG4gICAgICAgIGNvbnN0IGNoZWNrQW5kQXZvaWRCbG9ja3NZTGVmdCA9IHNlcGFyYXRlZFBvaW50cy5maW5kSW5kZXgoKGl0ZW0pID0+IGl0ZW0uaWQgPT09ICdjaGVja0FuZEF2b2lkQmxvY2tzWUxlZnQnKTtcblxuICAgICAgICBpZiAoY2hlY2tBbmRBdm9pZEJsb2Nrc1lMZWZ0ICE9PSAtMSkge1xuICAgICAgICAgIHNlcGFyYXRlZFBvaW50cy5zcGxpY2UoY2hlY2tBbmRBdm9pZEJsb2Nrc1lMZWZ0LCAxKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoY2hlY2tBbmRBdm9pZEJsb2Nrc1lMZWZ0ID09PSAtMSkge1xuICAgICAgICAgIGNvbmRpdGlvbiA9IGZhbHNlO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIHN0cmFpZ2h0TGluZS5wYXRoID0gJyc7XG4gICAgICBzdHJhaWdodExpbmUuZW5kUGF0aCA9IHtcbiAgICAgICAgeDogc3RhcnRRTC5seCA/PyAwLFxuICAgICAgICB5OiBzdGFydFFMLmx5ID8/IDAsXG4gICAgICB9O1xuICAgIH1cblxuICAgIGlmIChlbmRQb3NpdGlvbi54ID09PSBzdHJhaWdodExpbmUuZW5kUGF0aC54KSB7XG4gICAgICBzZXBhcmF0ZWRQb2ludHMucHVzaCh7IHN0YXJ0OiBzdHJhaWdodExpbmUuZW5kUGF0aCwgZW5kOiBlbmRQb3NpdGlvbk9yaWdpbiwgbW9kZTogJ3ZlcnRpY2FsLXNpbmdsZS1jdXJ2ZScsIGlkOiAnNmEgJyArIGRpcmVjdGlvblN0YXJ0WSB9KTtcbiAgICAgIHRoaXMuY2xvc2VMaW5lKHsgeDogZW5kUG9zaXRpb25PcmlnaW4ueCA/PyAwLCB5OiBlbmRQb3NpdGlvbk9yaWdpbi55ID8/IDAgfSwgZW5kUG9zaXRpb25PcmlnaW4sIGxpbmVDdXJ2ZSwgZWxlbWVudE5leHQsIHNlcGFyYXRlZFBvaW50cyk7XG5cbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyBraeG7g20gdHJhIG5nYXkga2hpIGN1YSBjw7Mgdsaw4bubbmcgYWkga2jDtG5nIHLhu5NpIGjhurVuZyB24bq9IFExLFxuICAgIGNvbnN0IGVsZW1lbnRCbG9ja1JvYWQgPSBNb0NhbnZhc0NhbGN1bGF0b3JEaXJlY3Rpb25FbGVtZW50VXRpbC5jaGVja0xpbmVQYXNzQmxvY2tIb3Jpem9udGFsKHN0cmFpZ2h0TGluZS5lbmRQYXRoLnggPz8gMCwgZW5kUG9zaXRpb24ueCwgc3RyYWlnaHRMaW5lLmVuZFBhdGgueSA/PyAwLCAneCcsIG9ic3RhY2xlUmVjdCkgYXMgSVJlY3Q7XG4gICAgY29uc3QgZGlyZWN0aW9uTmV4dFggPSBNb0NhbnZhc0NhbGN1bGF0b3JEaXJlY3Rpb25FbGVtZW50VXRpbC5jaGVja1VwRG93bkxlZnRSaWdodChzdHJhaWdodExpbmUuZW5kUGF0aC54ID8/IDAsIGVuZFBvc2l0aW9uT3JpZ2luLngsICd4Jyk7XG4gICAgY29uc3QgY29vcmRRMSA9IE1vQ2FudmFzQ2FsY3VsYXRvckRpcmVjdGlvbkVsZW1lbnRVdGlsLmRyYXdMaW5lUSh7IHg6IHN0cmFpZ2h0TGluZS5lbmRQYXRoLnggPz8gMCwgeTogc3RyYWlnaHRMaW5lLmVuZFBhdGgueSA/PyAwIH0sIGAke2RpcmVjdGlvblN0YXJ0WX0tJHtkaXJlY3Rpb25OZXh0WH1gLCBsaW5lQ3VydmUsIGxpbmVDdXJ2ZSk7IC8vIHTDrW5oIMSRb+G6oW4gY29uZyB04burIMSRxrDhu51uZyBuZ2FuZyBzYW5nIMSRxrDhu51uZyB0aOG6s25nXG4gICAgY29uc3QgZWxlbWVudEJsb2NrUm9hZFggPSAoZWxlbWVudEJsb2NrUm9hZD8ueCA/PyAwKSArIChlbGVtZW50QmxvY2tSb2FkPy53aWR0aCA/PyAwKTtcblxuICAgIGlmIChlbGVtZW50QmxvY2tSb2FkICYmIE1hdGguYWJzKGVsZW1lbnRCbG9ja1JvYWRYIC0gKHN0cmFpZ2h0TGluZS5lbmRQYXRoLnggPz8gMCkpIDw9IGxpbmVDdXJ2ZSAqIDIpIHtcbiAgICAgIGNvb3JkUTEueDEgPSBzdHJhaWdodExpbmUuZW5kUGF0aC54ID8/IDA7XG4gICAgICBjb29yZFExLnkxID0gc3RyYWlnaHRMaW5lLmVuZFBhdGgueSA/PyAwO1xuICAgICAgY29vcmRRMS54ID0gc3RyYWlnaHRMaW5lLmVuZFBhdGgueCA/PyAwO1xuICAgICAgY29vcmRRMS55ID0gc3RyYWlnaHRMaW5lLmVuZFBhdGgueSA/PyAwO1xuICAgIH1cblxuICAgIHNlcGFyYXRlZFBvaW50cy5wdXNoKHsgc3RhcnQ6IHN0cmFpZ2h0TGluZS5lbmRQYXRoLCBlbmQ6IHsgeDogY29vcmRRMS54ID8/IDAsIHk6IGNvb3JkUTEueSA/PyAwIH0sIG1vZGU6ICd2ZXJ0aWNhbC1zaW5nbGUtY3VydmUnLCBpZDogJzZhICcgKyBkaXJlY3Rpb25TdGFydFkgfSk7XG5cbiAgICBjb25zdCBlbmRQYXRoID0gTW9DYW52YXNDYWxjdWxhdG9yRGlyZWN0aW9uRWxlbWVudFV0aWwuY2hlY2tBbmRBdm9pZEJsb2Nrc0xlZnQoY29vcmRRMS54ID8/IDAsIGNvb3JkUTEueSA/PyAwLCBsaW5lQ3VydmUsIGVuZFBvc2l0aW9uLCBvYnN0YWNsZVJlY3QsIHNlcGFyYXRlZFBvaW50cyk7XG4gICAgY29uc3QgZGlyZWN0aW9uU3RhcnRZMiA9IE1vQ2FudmFzQ2FsY3VsYXRvckRpcmVjdGlvbkVsZW1lbnRVdGlsLmNoZWNrVXBEb3duTGVmdFJpZ2h0KGVuZFBhdGgueSwgZW5kUG9zaXRpb25PcmlnaW4ueSwgJ3knKTtcbiAgICBjb25zdCBkaXJlY3Rpb25OZXh0WSA9IE1vQ2FudmFzQ2FsY3VsYXRvckRpcmVjdGlvbkVsZW1lbnRVdGlsLmNoZWNrVXBEb3duTGVmdFJpZ2h0KGNvb3JkUTEueCA/PyAwLCBlbmRQYXRoLngsICd4Jyk7XG4gICAgY29uc3QgY29vcmRRMiA9IE1vQ2FudmFzQ2FsY3VsYXRvckRpcmVjdGlvbkVsZW1lbnRVdGlsLmRyYXdMaW5lUSh7IHg6IGVuZFBhdGgueCA/PyAwLCB5OiBlbmRQYXRoLnkgPz8gMCB9LCBgJHtkaXJlY3Rpb25OZXh0WX0tJHtkaXJlY3Rpb25TdGFydFkyID09PSAnYWJvdmUnID8gJ2Fib3ZlJyA6ICd1bmRlcid9YCwgbGluZUN1cnZlLCBsaW5lQ3VydmUpOyAvLyB0w61uaCDEkW/huqFuIGNvbmcgdOG7qyDEkcaw4budbmcgbmdhbmcgc2FuZyDEkcaw4budbmcgdGjhurNuZ1xuXG4gICAgc2VwYXJhdGVkUG9pbnRzLnB1c2goeyBzdGFydDogZW5kUGF0aCwgZW5kOiB7IHg6IGNvb3JkUTIueCA/PyAwLCB5OiBjb29yZFEyLnkgPz8gMCB9LCBtb2RlOiAnaG9yaXpvbnRhbC1zaW5nbGUtY3VydmUnLCBpZDogJzYnIH0pO1xuXG4gICAgdGhpcy5jbG9zZUxpbmUoeyB4OiBjb29yZFEyLnggPz8gMCwgeTogY29vcmRRMi55ID8/IDAgfSwgZW5kUG9zaXRpb25PcmlnaW4sIGxpbmVDdXJ2ZSwgZWxlbWVudE5leHQsIHNlcGFyYXRlZFBvaW50cyk7XG5cbiAgICByZXR1cm4ge1xuICAgICAgZFBhdGg6IGBgLFxuICAgIH07XG4gIH1cblxuICBwcml2YXRlIHN0YXRpYyBjbG9zZUxpbmUoc3RhcnQ6IElQb3NpdGlvblhZLCBlbmQ6IElQb3NpdGlvblhZLCBsaW5lQ3VydmU6IG51bWJlciwgZWxlbWVudE5leHQ6IElSZWN0LCBzZXBhcmF0ZWRQb2ludHM6IEFycmF5PElQb2ludHM+KSB7XG4gICAgY29uc3QgZGlyZWN0aW9uWSA9IE1vQ2FudmFzQ2FsY3VsYXRvckRpcmVjdGlvbkVsZW1lbnRVdGlsLmNoZWNrVXBEb3duTGVmdFJpZ2h0KHN0YXJ0LnksIGVuZC55LCAneScpO1xuXG4gICAgaWYgKHN0YXJ0LnkgPT09IGVuZC55KSB7XG4gICAgICBzZXBhcmF0ZWRQb2ludHMucHVzaCh7IHN0YXJ0LCBlbmQ6IHsgeDogZWxlbWVudE5leHQueCA/PyAwLCB5OiBlbmQueSA/PyAwIH0sIG1vZGU6ICdob3Jpem9udGFsJywgaWQ6ICc3JyB9KTtcblxuICAgICAgcmV0dXJuIGBMICR7ZWxlbWVudE5leHQueH0gJHtlbmQueX1gO1xuICAgIH1cblxuICAgIGNvbnN0IGxpbmUgPSB7IHg6IHN0YXJ0LngsIHk6IHN0YXJ0LnkgfTtcbiAgICBjb25zdCBlbmRQb2ludCA9IHtcbiAgICAgIHg6IGVsZW1lbnROZXh0LngsXG4gICAgICB5OiBlbmQueSxcbiAgICB9O1xuICAgIGxldCBwYXRoUTEgPSAnJztcblxuICAgIGlmIChNYXRoLmFicyhzdGFydC55IC0gZW5kLnkpID4gbGluZUN1cnZlKSB7XG4gICAgICBjb25zdCB0b1kgPSBNb0NhbnZhc0NhbGN1bGF0b3JCcmFuY2hVdGlsLm1hdGhPcGVyYXRvcnNDYWxjdWxhdGlvbihkaXJlY3Rpb25ZLCBlbmQueSwgbGluZUN1cnZlKTtcblxuICAgICAgbGluZS55ID0gdG9ZO1xuXG4gICAgICBjb25zdCBkaXJlY3Rpb25YID0gTW9DYW52YXNDYWxjdWxhdG9yRGlyZWN0aW9uRWxlbWVudFV0aWwuY2hlY2tVcERvd25MZWZ0UmlnaHQobGluZS54LCBlbGVtZW50TmV4dC54LCAneCcpO1xuICAgICAgY29uc3QgY29vcmRRMSA9IE1vQ2FudmFzQ2FsY3VsYXRvckRpcmVjdGlvbkVsZW1lbnRVdGlsLmRyYXdMaW5lUSh7IHg6IGxpbmUueCA/PyAwLCB5OiBsaW5lLnkgPz8gMCB9LCBgJHtkaXJlY3Rpb25ZID09PSAnYWJvdmUnID8gJ2Fib3ZlJyA6ICd1bmRlcid9LSR7ZGlyZWN0aW9uWH1gLCBsaW5lQ3VydmUsIGxpbmVDdXJ2ZSk7IC8vIHTDrW5oIMSRb+G6oW4gY29uZyB04burIMSRxrDhu51uZyBuZ2FuZyBzYW5nIMSRxrDhu51uZyB0aOG6s25nXG5cbiAgICAgIGxldCBsaW5lTCA9ICcnO1xuXG4gICAgICBpZiAoY29vcmRRMS55ID09PSBlbmQueSkge1xuICAgICAgICBsaW5lTCA9IGBMICR7ZW5kUG9pbnQueH0gJHtlbmRQb2ludC55fWA7XG4gICAgICB9XG5cbiAgICAgIHBhdGhRMSA9IGBRICR7Y29vcmRRMS54MX0sJHtjb29yZFExLnkxfSAke2Nvb3JkUTEueH0sJHtjb29yZFExLnl9ICR7bGluZUx9YDsgLy8gdOG7qyBuZ2FuZyBzYW5nIHRo4bqzbmcgcGjhuqNpIGPDsyDEkcaw4budbmcgY29uZ1xuICAgIH1cblxuICAgIHNlcGFyYXRlZFBvaW50cy5wdXNoKHsgc3RhcnQsIGVuZDogbGluZSwgbW9kZTogJ2hvcml6b250YWwnLCBpZDogJzgnIH0pO1xuICAgIHNlcGFyYXRlZFBvaW50cy5wdXNoKHsgc3RhcnQ6IGxpbmUsIGVuZDogZW5kUG9pbnQsIG1vZGU6ICd2ZXJ0aWNhbC1zaW5nbGUtY3VydmUnLCBpZDogJzknIH0pO1xuXG4gICAgcmV0dXJuIGBMICR7bGluZS54fSAke2xpbmUueX0gJHtwYXRoUTF9YDtcbiAgfVxuXG4gIHByaXZhdGUgc3RhdGljIGxpbmVDb25uZWN0TGVmdFdpdGhCb3R0b21TdGFydChlbGVtZW50TmV4dDogSVJlY3QsIGVsZW1lbnRGcm9tOiBJUmVjdCwgc3RhcnQ6IElQb2ludCwgbGluZUN1cnZlOiBudW1iZXIsIG9ic3RhY2xlUmVjdDogSVJlY3RbXSwgc2VwYXJhdGVkUG9pbnRzOiBBcnJheTxJUG9pbnRzPikge1xuICAgIGNvbnN0IGVuZFBvc2l0aW9uT3JpZ2luID0ge1xuICAgICAgeDogKGVsZW1lbnROZXh0LnggPz8gMCkgKyAoZWxlbWVudE5leHQud2lkdGggPz8gMCkgLyAyLFxuICAgICAgeTogKGVsZW1lbnROZXh0LnkgPz8gMCkgLSBsaW5lQ3VydmUsXG4gICAgfTtcbiAgICBjb25zdCBlbmRQb3NpdGlvbiA9IGNsb25lRGVlcChlbmRQb3NpdGlvbk9yaWdpbik7XG4gICAgY29uc3QgZGlyZWN0aW9uU3RhcnRZID0gTW9DYW52YXNDYWxjdWxhdG9yRGlyZWN0aW9uRWxlbWVudFV0aWwuY2hlY2tVcERvd25MZWZ0UmlnaHQoc3RhcnQueSwgZW5kUG9zaXRpb25PcmlnaW4ueSwgJ3knKTtcbiAgICBjb25zdCBlbmRZID0gZWxlbWVudE5leHQueSA/PyAwO1xuXG4gICAgY29uc29sZS5sb2coJ2RpcmVjdGlvblN0YXJ0WScsIGRpcmVjdGlvblN0YXJ0WSk7XG4gICAgaWYgKGRpcmVjdGlvblN0YXJ0WSA9PT0gJ3VuZGVyJykge1xuICAgICAgZW5kUG9zaXRpb24ueSA9IGVuZFkgLSBsaW5lQ3VydmUgKiAzO1xuICAgIH1cblxuICAgIGNvbnN0IHN0YXJ0UUwgPSB7IGx4OiBzdGFydC54LCBseTogKHN0YXJ0LnkgPz8gMCkgKyBsaW5lQ3VydmUgfTtcbiAgICBjb25zdCBsaW5lID0ge1xuICAgICAgc3RhcnQ6IHsgeDogc3RhcnQueCA/PyAwLCB5OiBzdGFydC55ID8/IDAgfSxcbiAgICAgIGVuZDogeyB4OiBzdGFydFFMLmx4ID8/IDAsIHk6IHN0YXJ0UUwubHkgPz8gMCB9LFxuICAgIH07XG4gICAgY29uc3QgbmV3RW5kID0geyB4OiBlbGVtZW50RnJvbS54IC0gbGluZUN1cnZlICogMiwgeTogbGluZS5lbmQueSAtIGxpbmVDdXJ2ZSB9O1xuXG4gICAgaWYgKGRpcmVjdGlvblN0YXJ0WSA9PT0gJ2Fib3ZlJykge1xuICAgICAgbGluZS5lbmQgPSB7IHg6IChzdGFydC54ID8/IDApIC0gbGluZUN1cnZlLCB5OiAoc3RhcnQueSA/PyAwKSArIGxpbmVDdXJ2ZSAqIDIgfTtcblxuICAgICAgc2VwYXJhdGVkUG9pbnRzLnB1c2goeyBzdGFydDogbGluZS5lbmQsIGVuZDogbmV3RW5kLCBtb2RlOiAnaG9yaXpvbnRhbC1zaW5nbGUtY3VydmUnLCBpZDogJzEnIH0pO1xuICAgIH1cbiAgICBzZXBhcmF0ZWRQb2ludHMucHVzaCh7IHN0YXJ0OiBsaW5lLnN0YXJ0LCBlbmQ6IGxpbmUuZW5kLCBtb2RlOiAndmVydGljYWwtc2luZ2xlLWN1cnZlJywgaWQ6ICcxJyB9KTsgLy8gbGluZSB24bq9IMSRaSBraOG7j2kga2jhu5FpIMSR4bqndSB0acOqblxuICAgIGNvbnN0IHN0YXJ0TmV3TGluZSA9IGRpcmVjdGlvblN0YXJ0WSA9PT0gJ2Fib3ZlJyA/IG5ld0VuZCA6IGxpbmUuZW5kO1xuXG4gICAgaWYgKGRpcmVjdGlvblN0YXJ0WSA9PT0gJ2NlbnRlcicpIHtcbiAgICAgIGNvbnN0IGNvb3JkUTEgPSBNb0NhbnZhc0NhbGN1bGF0b3JEaXJlY3Rpb25FbGVtZW50VXRpbC5kcmF3TGluZVEoeyB4OiBzdGFydFFMLmx4ID8/IDAsIHk6IHN0YXJ0UUwubHkgPz8gMCB9LCBgYWJvdmUtbGVmdGAsIGxpbmVDdXJ2ZSwgbGluZUN1cnZlKTsgLy8gdMOtbmggxJFv4bqhbiBjb25nIHThu6sgxJHGsOG7nW5nIG5nYW5nIHNhbmcgxJHGsOG7nW5nIHRo4bqzbmdcblxuICAgICAgLy8gdOG7qyBuZ2FuZyBzYW5nIHRo4bqzbmcgcGjhuqNpIGPDsyDEkcaw4budbmcgY29uZ1xuICAgICAgc2VwYXJhdGVkUG9pbnRzLnB1c2goeyBzdGFydDogeyB4OiBzdGFydFFMLmx4ID8/IDAsIHk6IHN0YXJ0UUwubHkgfSwgZW5kOiB7IHg6IGNvb3JkUTEueCA/PyAwLCB5OiBjb29yZFExLnkgPz8gMCB9LCBtb2RlOiAndmVydGljYWwtc2luZ2xlLWN1cnZlJywgaWQ6ICczJyB9KTtcblxuICAgICAgY29uc3QgZW5kUGF0aCA9IE1vQ2FudmFzQ2FsY3VsYXRvckRpcmVjdGlvbkVsZW1lbnRVdGlsLmNoZWNrQW5kQXZvaWRCbG9ja3NMZWZ0KGNvb3JkUTEueCA/PyAwLCBjb29yZFExLnkgPz8gMCwgbGluZUN1cnZlLCBlbmRQb3NpdGlvbiwgb2JzdGFjbGVSZWN0LCBzZXBhcmF0ZWRQb2ludHMpO1xuICAgICAgY29uc3QgZGlyZWN0aW9uU3RhcnRZMiA9IE1vQ2FudmFzQ2FsY3VsYXRvckRpcmVjdGlvbkVsZW1lbnRVdGlsLmNoZWNrVXBEb3duTGVmdFJpZ2h0KGVuZFBhdGgueSwgZW5kUG9zaXRpb25PcmlnaW4ueSwgJ3knKTtcbiAgICAgIGNvbnN0IGNvb3JkUTIgPSBNb0NhbnZhc0NhbGN1bGF0b3JEaXJlY3Rpb25FbGVtZW50VXRpbC5kcmF3TGluZVEoeyB4OiBlbmRQYXRoLnggPz8gMCwgeTogZW5kUGF0aC55ID8/IDAgfSwgYGxlZnQtJHtkaXJlY3Rpb25TdGFydFkyID09PSAnYWJvdmUnID8gJ2Fib3ZlJyA6ICd1bmRlcid9YCwgbGluZUN1cnZlLCBsaW5lQ3VydmUpOyAvLyB0w61uaCDEkW/huqFuIGNvbmcgdOG7qyDEkcaw4budbmcgbmdhbmcgc2FuZyDEkcaw4budbmcgdGjhurNuZ1xuXG4gICAgICAvLyB04burIG5nYW5nIHNhbmcgdGjhurNuZyBwaOG6o2kgY8OzIMSRxrDhu51uZyBjb25nXG4gICAgICBzZXBhcmF0ZWRQb2ludHMucHVzaCh7IHN0YXJ0OiB7IHg6IGVuZFBhdGgueCA/PyAwLCB5OiBlbmRQYXRoLnkgPz8gMCB9LCBlbmQ6IHsgeDogY29vcmRRMi54ID8/IDAsIHk6IGNvb3JkUTIueSA/PyAwIH0sIG1vZGU6ICdob3Jpem9udGFsLXNpbmdsZS1jdXJ2ZScsIGlkOiAnNCcgfSk7XG4gICAgICB0aGlzLmNsb3NlTGluZSh7IHg6IGNvb3JkUTIueCA/PyAwLCB5OiBjb29yZFEyLnkgPz8gMCB9LCBlbmRQb3NpdGlvbk9yaWdpbiwgbGluZUN1cnZlLCBlbGVtZW50TmV4dCwgc2VwYXJhdGVkUG9pbnRzKTtcblxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgZFBhdGg6IGBgLFxuICAgICAgfTtcbiAgICB9XG5cbiAgICAvLyBraeG7g20gdHJhIGjGsOG7m25nIHRo4bqzbmcgxJHhur9uIGVuZCwgbuG6v3UgY8OzIGto4buRaSB0aMOsIHRyw6FuaFxuICAgIGNvbnN0IHN0cmFpZ2h0TGluZSA9IE1vQ2FudmFzQ2FsY3VsYXRvckRpcmVjdGlvbkVsZW1lbnRVdGlsLmNoZWNrQW5kQXZvaWRCbG9ja3NZTGVmdChzdGFydE5ld0xpbmUueCA/PyAwLCBzdGFydE5ld0xpbmUueSA/PyAwLCBsaW5lQ3VydmUsIGVuZFBvc2l0aW9uLCBkaXJlY3Rpb25TdGFydFksIG9ic3RhY2xlUmVjdCwgc2VwYXJhdGVkUG9pbnRzKTtcblxuICAgIGNvbnN0IGRpcmVjdGlvblN0YXJ0WCA9IE1vQ2FudmFzQ2FsY3VsYXRvckRpcmVjdGlvbkVsZW1lbnRVdGlsLmNoZWNrVXBEb3duTGVmdFJpZ2h0KHN0YXJ0LngsIGVuZFBvc2l0aW9uT3JpZ2luLngsICd4Jyk7XG5cbiAgICBpZiAoZGlyZWN0aW9uU3RhcnRYID09PSAnY2VudGVyJyAmJiBkaXJlY3Rpb25TdGFydFkgPT09ICd1bmRlcicpIHtcbiAgICAgIHRoaXMuY2xvc2VMaW5lV2l0aExpbmVUb3BCb3R0b20oeyB4OiBzdHJhaWdodExpbmUuZW5kUGF0aC54ID8/IDAsIHk6IHN0cmFpZ2h0TGluZS5lbmRQYXRoLnkgPz8gMCB9LCBlbmRQb3NpdGlvbk9yaWdpbiwgbGluZUN1cnZlLCBlbGVtZW50TmV4dCwgc2VwYXJhdGVkUG9pbnRzKTtcblxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgZFBhdGg6IGBgLFxuICAgICAgfTtcbiAgICB9XG5cbiAgICBpZiAoKGRpcmVjdGlvblN0YXJ0WSA9PT0gJ3VuZGVyJyAmJiBzdGFydFFMLmx5ID4gZW5kUG9zaXRpb24ueSkgfHwgKGRpcmVjdGlvblN0YXJ0WSA9PT0gJ2Fib3ZlJyAmJiBzdGFydFFMLmx5IDwgZW5kUG9zaXRpb24ueSkgfHwgc3RhcnRRTC5seSA9PT0gZW5kUG9zaXRpb24ueSkge1xuICAgICAgbGV0IGNvbmRpdGlvbiA9IHRydWU7XG5cbiAgICAgIHdoaWxlIChjb25kaXRpb24pIHtcbiAgICAgICAgY29uc3QgY2hlY2tBbmRBdm9pZEJsb2Nrc1lMZWZ0ID0gc2VwYXJhdGVkUG9pbnRzLmZpbmRJbmRleCgoaXRlbSkgPT4gaXRlbS5pZCA9PT0gJ2NoZWNrQW5kQXZvaWRCbG9ja3NZTGVmdCcpO1xuXG4gICAgICAgIGlmIChjaGVja0FuZEF2b2lkQmxvY2tzWUxlZnQgIT09IC0xKSB7XG4gICAgICAgICAgc2VwYXJhdGVkUG9pbnRzLnNwbGljZShjaGVja0FuZEF2b2lkQmxvY2tzWUxlZnQsIDEpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChjaGVja0FuZEF2b2lkQmxvY2tzWUxlZnQgPT09IC0xKSB7XG4gICAgICAgICAgY29uZGl0aW9uID0gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgc3RyYWlnaHRMaW5lLnBhdGggPSAnJztcbiAgICAgIHN0cmFpZ2h0TGluZS5lbmRQYXRoID0ge1xuICAgICAgICB4OiBzdGFydFFMLmx4ID8/IDAsXG4gICAgICAgIHk6IHN0YXJ0UUwubHkgPz8gMCxcbiAgICAgIH07XG4gICAgfVxuXG4gICAgLy8ga2nhu4NtIHRyYSBuZ2F5IGtoaSBjdWEgY8OzIHbGsOG7m25nIGFpIGtow7RuZyBy4buTaSBo4bq1bmcgduG6vSBRMVxuICAgIGNvbnN0IGVsZW1lbnRCbG9ja1JvYWQgPSBNb0NhbnZhc0NhbGN1bGF0b3JEaXJlY3Rpb25FbGVtZW50VXRpbC5jaGVja0xpbmVQYXNzQmxvY2tIb3Jpem9udGFsKHN0cmFpZ2h0TGluZS5lbmRQYXRoLnggPz8gMCwgZW5kUG9zaXRpb24ueCwgc3RyYWlnaHRMaW5lLmVuZFBhdGgueSA/PyAwLCAneCcsIG9ic3RhY2xlUmVjdCkgYXMgSVJlY3Q7XG4gICAgY29uc3QgZGlyZWN0aW9uTmV4dFggPSBNb0NhbnZhc0NhbGN1bGF0b3JEaXJlY3Rpb25FbGVtZW50VXRpbC5jaGVja1VwRG93bkxlZnRSaWdodChzdHJhaWdodExpbmUuZW5kUGF0aC54ID8/IDAsIGVuZFBvc2l0aW9uT3JpZ2luLngsICd4Jyk7XG4gICAgY29uc3QgY29vcmRRMSA9IE1vQ2FudmFzQ2FsY3VsYXRvckRpcmVjdGlvbkVsZW1lbnRVdGlsLmRyYXdMaW5lUSh7IHg6IHN0cmFpZ2h0TGluZS5lbmRQYXRoLnggPz8gMCwgeTogc3RyYWlnaHRMaW5lLmVuZFBhdGgueSA/PyAwIH0sIGAke2RpcmVjdGlvblN0YXJ0WX0tJHtkaXJlY3Rpb25OZXh0WH1gLCBsaW5lQ3VydmUsIGxpbmVDdXJ2ZSk7IC8vIHTDrW5oIMSRb+G6oW4gY29uZyB04burIMSRxrDhu51uZyBuZ2FuZyBzYW5nIMSRxrDhu51uZyB0aOG6s25nXG4gICAgY29uc3QgZWxlbWVudEJsb2NrUm9hZFggPSAoZWxlbWVudEJsb2NrUm9hZD8ueCA/PyAwKSArIChlbGVtZW50QmxvY2tSb2FkPy53aWR0aCA/PyAwKTtcblxuICAgIGlmIChlbGVtZW50QmxvY2tSb2FkICYmIE1hdGguYWJzKGVsZW1lbnRCbG9ja1JvYWRYIC0gKHN0cmFpZ2h0TGluZS5lbmRQYXRoLnggPz8gMCkpIDw9IGxpbmVDdXJ2ZSAqIDIpIHtcbiAgICAgIGNvb3JkUTEueDEgPSBzdHJhaWdodExpbmUuZW5kUGF0aC54ID8/IDA7XG4gICAgICBjb29yZFExLnkxID0gc3RyYWlnaHRMaW5lLmVuZFBhdGgueSA/PyAwO1xuICAgICAgY29vcmRRMS54ID0gc3RyYWlnaHRMaW5lLmVuZFBhdGgueCA/PyAwO1xuICAgICAgY29vcmRRMS55ID0gc3RyYWlnaHRMaW5lLmVuZFBhdGgueSA/PyAwO1xuICAgIH1cblxuICAgIC8vIGtp4buDbSB0cmEgdsOgIHbhur0gaMaw4bubbmcgbmdhbmdcbiAgICBjb25zdCBkaXJlY3Rpb25YVG9FbmQgPSBNb0NhbnZhc0NhbGN1bGF0b3JEaXJlY3Rpb25FbGVtZW50VXRpbC5jaGVja1VwRG93bkxlZnRSaWdodChjb29yZFExLnggPz8gMCwgZW5kUG9zaXRpb25PcmlnaW4ueCwgJ3gnKTtcblxuICAgIGVuZFBvc2l0aW9uLnggPSBNb0NhbnZhc0NhbGN1bGF0b3JCcmFuY2hVdGlsLm1hdGhPcGVyYXRvcnNDYWxjdWxhdGlvbihkaXJlY3Rpb25YVG9FbmQsIGVuZFBvc2l0aW9uLngsIGxpbmVDdXJ2ZSk7XG4gICAgaWYgKE1hdGguYWJzKChjb29yZFExLnkgPz8gMCkgLSBlbmRQb3NpdGlvbi55KSA8PSBsaW5lQ3VydmUpIHtcbiAgICAgIGVuZFBvc2l0aW9uLnkgLT0gbGluZUN1cnZlO1xuICAgIH1cbiAgICBjb25zdCBwYXRoSG9yaXpvbnRhbDogSVBvaW50c1tdID0gW107XG4gICAgY29uc3QgZW5kUGF0aCA9IE1vQ2FudmFzQ2FsY3VsYXRvckRpcmVjdGlvbkVsZW1lbnRVdGlsLmNoZWNrQW5kQXZvaWRCbG9ja3NMZWZ0KGNvb3JkUTEueCA/PyAwLCBjb29yZFExLnkgPz8gMCwgbGluZUN1cnZlLCBlbmRQb3NpdGlvbiwgb2JzdGFjbGVSZWN0LCBwYXRoSG9yaXpvbnRhbCk7XG5cbiAgICBpZiAoZGlyZWN0aW9uWFRvRW5kID09PSAnbGVmdCcgJiYgZW5kUGF0aC54ID4gKGNvb3JkUTEueCA/PyAwKSkge1xuICAgICAgc2VwYXJhdGVkUG9pbnRzLnB1c2goeyBzdGFydDogc3RyYWlnaHRMaW5lLmVuZFBhdGgsIGVuZDogZW5kUG9zaXRpb25PcmlnaW4sIG1vZGU6ICd2ZXJ0aWNhbCcsIGlkOiAnNmEgJyArIGRpcmVjdGlvblN0YXJ0WSB9KTtcbiAgICAgIHRoaXMuY2xvc2VMaW5lV2l0aExpbmVUb3BCb3R0b20oZW5kUG9zaXRpb25PcmlnaW4sIGVuZFBvc2l0aW9uT3JpZ2luLCBsaW5lQ3VydmUsIGVsZW1lbnROZXh0LCBzZXBhcmF0ZWRQb2ludHMpO1xuXG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgc2VwYXJhdGVkUG9pbnRzLnB1c2goLi4ucGF0aEhvcml6b250YWwpO1xuICAgIHNlcGFyYXRlZFBvaW50cy5wdXNoKHsgc3RhcnQ6IHN0cmFpZ2h0TGluZS5lbmRQYXRoLCBlbmQ6IHsgeDogY29vcmRRMS54ID8/IDAgLSAxMCwgeTogY29vcmRRMS55ID8/IDAgfSwgbW9kZTogJ3ZlcnRpY2FsLXNpbmdsZS1jdXJ2ZScsIGlkOiAnNmEgJyArIGRpcmVjdGlvblN0YXJ0WSB9KTtcbiAgICB0aGlzLmNsb3NlTGluZVdpdGhMaW5lVG9wQm90dG9tKHsgeDogZW5kUGF0aC54ID8/IDAsIHk6IGVuZFBhdGgueSA/PyAwIH0sIGVuZFBvc2l0aW9uT3JpZ2luLCBsaW5lQ3VydmUsIGVsZW1lbnROZXh0LCBzZXBhcmF0ZWRQb2ludHMpO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIGRQYXRoOiBgYCxcbiAgICB9O1xuICB9XG5cbiAgcHJpdmF0ZSBzdGF0aWMgY2xvc2VMaW5lV2l0aExpbmVUb3BCb3R0b20oc3RhcnQ6IElQb3NpdGlvblhZLCBlbmQ6IElQb3NpdGlvblhZLCBsaW5lQ3VydmU6IG51bWJlciwgZWxlbWVudE5leHQ6IElSZWN0LCBzZXBhcmF0ZWRQb2ludHM6IEFycmF5PElQb2ludHM+KSB7XG4gICAgY29uc3QgZGlyZWN0aW9uWCA9IE1vQ2FudmFzQ2FsY3VsYXRvckRpcmVjdGlvbkVsZW1lbnRVdGlsLmNoZWNrVXBEb3duTGVmdFJpZ2h0KHN0YXJ0LngsIGVuZC54LCAneCcpO1xuXG4gICAgaWYgKHN0YXJ0LnggPT09IGVuZC54KSB7XG4gICAgICBzZXBhcmF0ZWRQb2ludHMucHVzaCh7IHN0YXJ0LCBlbmQ6IHsgeDogKGVsZW1lbnROZXh0LnggPz8gMCkgKyAoZWxlbWVudE5leHQud2lkdGggPz8gMCkgLyAyLCB5OiBlbGVtZW50TmV4dC55ID8/IDAgfSwgbW9kZTogJ2hvcml6b250YWwnLCBpZDogJzcnIH0pO1xuXG4gICAgICByZXR1cm4gYEwgJHtlbGVtZW50TmV4dC54fSAke2VuZC55fWA7XG4gICAgfVxuXG4gICAgY29uc3QgbGluZSA9IHsgeDogc3RhcnQueCwgeTogc3RhcnQueSB9O1xuICAgIGNvbnN0IGVuZFBvaW50ID0ge1xuICAgICAgeDogZW5kLngsXG4gICAgICB5OiBlbGVtZW50TmV4dC55LFxuICAgIH07XG4gICAgY29uc3QgcGF0aFExID0gJyc7XG5cbiAgICBpZiAoTWF0aC5hYnMoc3RhcnQueCAtIGVuZC54KSA+IGxpbmVDdXJ2ZSkge1xuICAgICAgY29uc3QgZGlyZWN0aW9uWSA9IE1vQ2FudmFzQ2FsY3VsYXRvckRpcmVjdGlvbkVsZW1lbnRVdGlsLmNoZWNrVXBEb3duTGVmdFJpZ2h0KHN0YXJ0LnksIGVuZFBvaW50LnksICd5Jyk7XG4gICAgICBjb25zdCB0b1ggPSBNb0NhbnZhc0NhbGN1bGF0b3JCcmFuY2hVdGlsLm1hdGhPcGVyYXRvcnNDYWxjdWxhdGlvbihkaXJlY3Rpb25YLCBlbmQueCwgbGluZUN1cnZlKTtcbiAgICAgIGNvbnN0IHRvWSA9IE1vQ2FudmFzQ2FsY3VsYXRvckJyYW5jaFV0aWwubWF0aE9wZXJhdG9yc0NhbGN1bGF0aW9uKGRpcmVjdGlvblksIGVuZC55LCBsaW5lQ3VydmUpO1xuXG4gICAgICBsaW5lLnggPSB0b1g7XG4gICAgICBsaW5lLnkgPSB0b1k7XG4gICAgICBzZXBhcmF0ZWRQb2ludHMucHVzaCh7IHN0YXJ0OiBzdGFydCwgZW5kOiBsaW5lLCBtb2RlOiAndmVydGljYWwtc2luZ2xlLWN1cnZlJywgaWQ6ICc5JyB9KTtcbiAgICB9XG5cbiAgICBzZXBhcmF0ZWRQb2ludHMucHVzaCh7IHN0YXJ0OiBsaW5lLCBlbmQ6IGVuZFBvaW50LCBtb2RlOiAnaG9yaXpvbnRhbC1zaW5nbGUtY3VydmUnLCBpZDogJzknIH0pO1xuXG4gICAgcmV0dXJuIGBMICR7bGluZS54fSAke2xpbmUueX0gJHtwYXRoUTF9YDtcbiAgfVxuXG4gIHByaXZhdGUgc3RhdGljIGxpbmVDb25uZWN0UmlnaHRXaXRoQm90dG9tU3RhcnQoZWxlbWVudE5leHQ6IElSZWN0LCBzdGFydDogSVBvaW50LCBsaW5lQ3VydmU6IG51bWJlciwgb2JzdGFjbGVSZWN0OiBJUmVjdFtdLCBzZXBhcmF0ZWRQb2ludHM6IEFycmF5PElQb2ludHM+KSB7XG4gICAgY29uc3QgZW5kUG9zaXRpb24gPSB7XG4gICAgICB4OiAoZWxlbWVudE5leHQueCA/PyAwKSArIChlbGVtZW50TmV4dC53aWR0aCA/PyAwKSAvIDIsXG4gICAgICB5OiAoZWxlbWVudE5leHQueSA/PyAwKSAtIGxpbmVDdXJ2ZSxcbiAgICB9O1xuXG4gICAgLy8gduG6vSAxIMSRxrDhu51uZyB0aOG6s25nIHThu6sgxJFp4buDbSBzdGFydCByYSBuZ2/DoGkgxJHDo1xuICAgIGNvbnN0IGVuZCA9IHsgeDogKHN0YXJ0LnggPz8gMCkgKyAxMCwgeTogKHN0YXJ0LnkgPz8gMCkgKyAyMCB9O1xuXG4gICAgc2VwYXJhdGVkUG9pbnRzLnB1c2goeyBzdGFydDogeyB4OiBzdGFydC54ID8/IDAsIHk6IHN0YXJ0LnkgPz8gMCB9LCBlbmQ6IGVuZCwgbW9kZTogJ3ZlcnRpY2FsLXNpbmdsZS1jdXJ2ZScsIGlkOiAnMScgfSk7XG5cbiAgICBjb25zdCBlbmRQb3NpdGlvblggPSBjbG9uZURlZXAoZW5kUG9zaXRpb24pO1xuXG4gICAgZW5kUG9zaXRpb25YLnggLT0gMTA7XG5cbiAgICBsZXQgc2VwYXJhdGVkUG9pbnRzQ2hlY2tBbmRBdm9pZEJsb2NrczogQXJyYXk8SVBvaW50cz4gPSBbXTtcbiAgICBsZXQgeyBwYXRoLCBlbmRQYXRoIH0gPSBNb0NhbnZhc0NhbGN1bGF0b3JEaXJlY3Rpb25FbGVtZW50VXRpbC5jaGVja0FuZEF2b2lkQmxvY2tzKGVuZC54ID8/IDAsIGVuZC55ID8/IDAsIGxpbmVDdXJ2ZSwgZW5kUG9zaXRpb25YLCBvYnN0YWNsZVJlY3QsIHNlcGFyYXRlZFBvaW50c0NoZWNrQW5kQXZvaWRCbG9ja3MpO1xuXG4gICAgaWYgKE1hdGguYWJzKChzdGFydC54ID8/IDApIC0gZW5kUG9zaXRpb24ueCkgPCAxMCkge1xuICAgICAgcGF0aCA9ICcnO1xuICAgICAgZW5kUGF0aCA9IHtcbiAgICAgICAgeDogc3RhcnQueCxcbiAgICAgICAgeTogc3RhcnQueSxcbiAgICAgIH07XG5cbiAgICAgIHNlcGFyYXRlZFBvaW50c0NoZWNrQW5kQXZvaWRCbG9ja3MgPSBbXTtcbiAgICB9XG5cbiAgICBzZXBhcmF0ZWRQb2ludHMuc3BsaWNlKHNlcGFyYXRlZFBvaW50cy5sZW5ndGgsIDAsIC4uLnNlcGFyYXRlZFBvaW50c0NoZWNrQW5kQXZvaWRCbG9ja3MpO1xuXG4gICAgLy8gc2F1IGtoaSDEkcOjIMSRaSBuZ2FuZyB2w6AgdHLDoW5oIGPDoWMga2jhu5FpLCB0aeG6v3AgdGhlbyBsw6AgxJFpIHRp4bq/cCBoxrDhu5tuZyBsw6puIHh14buRbmcgxJHhu4MgduG7gSBraOG7kWkgY+G6p24gbuG7kWkgdOG7m2ksIGPhuqduIGNoZWNrIHhlbSDEkWnhu4NtIGVuZCBYIG7DsyDEkWFuZyDhu58gaMaw4bubbmcgbsOgb1xuICAgIGNvbnN0IGRpcmVjdGlvblkgPSBNb0NhbnZhc0NhbGN1bGF0b3JEaXJlY3Rpb25FbGVtZW50VXRpbC5jaGVja1VwRG93bkxlZnRSaWdodChlbmRQYXRoLnksIGVuZFBvc2l0aW9uLnksICd5Jyk7XG5cbiAgICBpZiAoZGlyZWN0aW9uWSA9PT0gJ2NlbnRlcicpIHtcbiAgICAgIGNvbnN0IExFbmQgPSB7IHg6IGVsZW1lbnROZXh0LnggPz8gMCwgeTogZW5kUGF0aC55IH07XG5cbiAgICAgIHNlcGFyYXRlZFBvaW50cy5wdXNoKHsgc3RhcnQ6IGVuZFBhdGgsIGVuZDogTEVuZCwgbW9kZTogJ2hvcml6b250YWwnLCBpZDogJ2YnIH0pO1xuXG4gICAgICAvLyDEkW/huqFuIG7DoHkgY2jGsGEgb2NlXG4gICAgICB0aGlzLmNsb3NlTGluZVdpdGhMaW5lVG9wQm90dG9tKExFbmQsIGVuZFBvc2l0aW9uLCBsaW5lQ3VydmUsIGVsZW1lbnROZXh0LCBzZXBhcmF0ZWRQb2ludHMpO1xuXG4gICAgICByZXR1cm4ge1xuICAgICAgICBkUGF0aDogYCR7cGF0aH0gTCAke0xFbmQueH0gJHtMRW5kLnl9YCxcbiAgICAgICAgZW5kUGF0aDogTEVuZCxcbiAgICAgIH07XG4gICAgfVxuXG4gICAgY29uc3QgY29vcmRRMSA9IE1vQ2FudmFzQ2FsY3VsYXRvckRpcmVjdGlvbkVsZW1lbnRVdGlsLmRyYXdMaW5lUSh7IHg6IGVuZFBhdGgueCA/PyAwLCB5OiBlbmRQYXRoLnkgPz8gMCB9LCBgcmlnaHQtJHtkaXJlY3Rpb25ZID09PSAnYWJvdmUnID8gJ2Fib3ZlJyA6ICd1bmRlcid9YCwgbGluZUN1cnZlLCBsaW5lQ3VydmUpOyAvLyB0w61uaCDEkW/huqFuIGNvbmcgdOG7qyDEkcaw4budbmcgbmdhbmcgc2FuZyDEkcaw4budbmcgdGjhurNuZ1xuICAgIGNvbnN0IGVuZFBvc2l0aW9uWSA9IGNsb25lRGVlcChlbmRQb3NpdGlvbik7XG5cbiAgICBlbmRQb3NpdGlvblkueSA9IE1vQ2FudmFzQ2FsY3VsYXRvckJyYW5jaFV0aWwubWF0aE9wZXJhdG9yc0NhbGN1bGF0aW9uKGRpcmVjdGlvblksIGVuZFBvc2l0aW9uLnksIGxpbmVDdXJ2ZSkgLSAxMDtcblxuICAgIC8vIGPhuqduIGNoZWNrIGtoaSDEkWkgdGjhurNuZyBsw6puIGPDsyB2xrDhu5tuZyBraOG7kWkgbsOgbyBraMO0bmcgxJHhu4MgdGnhur9uIGzDqm5cbiAgICBjb25zdCBlbGVtZW50QmxvY2tSb2FkU3RyYWlnaHRMaW5lWSA9IE1vQ2FudmFzQ2FsY3VsYXRvckRpcmVjdGlvbkVsZW1lbnRVdGlsLmNoZWNrQmxvY2tzRWxlbWVudFN0cmFpZ2h0WSgoZW5kUGF0aC54ID8/IDApICsgMTAsIGVuZFBhdGgueSA/PyAwLCBlbmRQb3NpdGlvblksIG9ic3RhY2xlUmVjdCk7XG5cbiAgICBpZiAoZWxlbWVudEJsb2NrUm9hZFN0cmFpZ2h0TGluZVkpIHtcbiAgICAgIGNvb3JkUTEueCA9IChlbGVtZW50QmxvY2tSb2FkU3RyYWlnaHRMaW5lWS54ID8/IDApICsgKGVsZW1lbnRCbG9ja1JvYWRTdHJhaWdodExpbmVZLndpZHRoID8/IDApICsgbGluZUN1cnZlO1xuICAgIH1cbiAgICBzZXBhcmF0ZWRQb2ludHMucHVzaCh7IHN0YXJ0OiB7IHg6IGVuZFBhdGgueCA/PyAwLCB5OiBlbmRQYXRoLnkgfSwgZW5kOiB7IHg6IGNvb3JkUTEueCA/PyAwLCB5OiBjb29yZFExLnkgPz8gMCB9LCBtb2RlOiAnaG9yaXpvbnRhbC1zaW5nbGUtY3VydmUnLCBpZDogJ2cnIH0pO1xuXG4gICAgbGV0IGF2b2lkQmxvY2tzWUxpbmU6IElQb2ludHNbXSA9IFtdO1xuICAgIGNvbnN0IHN0cmFpZ2h0TGluZSA9IE1vQ2FudmFzQ2FsY3VsYXRvckRpcmVjdGlvbkVsZW1lbnRVdGlsLmNoZWNrQW5kQXZvaWRCbG9ja3NZKGNvb3JkUTEueCA/PyAwLCBjb29yZFExLnkgPz8gMCwgbGluZUN1cnZlLCBlbmRQb3NpdGlvblksIGRpcmVjdGlvblksIG9ic3RhY2xlUmVjdCwgYXZvaWRCbG9ja3NZTGluZSk7XG5cbiAgICBpZiAoZGlyZWN0aW9uWSA9PT0gJ3VuZGVyJyAmJiAoY29vcmRRMS55ID8/IDApID4gZW5kUG9zaXRpb25ZLnkpIHtcbiAgICAgIGF2b2lkQmxvY2tzWUxpbmUgPSBbXTtcbiAgICAgIHN0cmFpZ2h0TGluZS5lbmRQYXRoID0geyB4OiBjb29yZFExLnggPz8gMCwgeTogY29vcmRRMS55ID8/IDAgfTtcbiAgICB9XG4gICAgc2VwYXJhdGVkUG9pbnRzLnB1c2goLi4uYXZvaWRCbG9ja3NZTGluZSk7XG4gICAgdGhpcy5jbG9zZUxpbmVXaXRoTGluZVRvcEJvdHRvbSh7IHg6IHN0cmFpZ2h0TGluZS5lbmRQYXRoLnggPz8gMCwgeTogc3RyYWlnaHRMaW5lLmVuZFBhdGgueSA/PyAwIH0sIGVuZFBvc2l0aW9uLCBsaW5lQ3VydmUsIGVsZW1lbnROZXh0LCBzZXBhcmF0ZWRQb2ludHMpO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIGRQYXRoOiBgYCxcbiAgICB9O1xuICB9XG59XG4iXX0=