barsa-user-workspace 0.0.0-watch
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +24 -0
- package/esm2022/barsa-user-workspace.mjs +5 -0
- package/esm2022/lib/barsa-user-workspace.module.mjs +82 -0
- package/esm2022/lib/coercion/boolean-property.mjs +5 -0
- package/esm2022/lib/coercion/number-property.mjs +14 -0
- package/esm2022/lib/directives/drag-handle.mjs +29 -0
- package/esm2022/lib/directives/placeholder.mjs +31 -0
- package/esm2022/lib/directives/resize-handle.mjs +29 -0
- package/esm2022/lib/grid/grid.component.mjs +609 -0
- package/esm2022/lib/grid-item/grid-item.component.mjs +196 -0
- package/esm2022/lib/grid.definitions.mjs +3 -0
- package/esm2022/lib/grid.service.mjs +49 -0
- package/esm2022/lib/layout-container/layout-container.component.mjs +213 -0
- package/esm2022/lib/layout-grid-mapper.pipe.mjs +29 -0
- package/esm2022/lib/nav-container/nav-container.component.mjs +27 -0
- package/esm2022/lib/report-grid-layout/report-grid-layout.component.mjs +15 -0
- package/esm2022/lib/utils/client-rect.mjs +57 -0
- package/esm2022/lib/utils/grid.utils.mjs +225 -0
- package/esm2022/lib/utils/operators.mjs +17 -0
- package/esm2022/lib/utils/passive-listeners.mjs +29 -0
- package/esm2022/lib/utils/pointer.utils.mjs +110 -0
- package/esm2022/lib/utils/react-grid-layout.utils.mjs +493 -0
- package/esm2022/lib/utils/scroll.mjs +233 -0
- package/esm2022/lib/utils/transition-duration.mjs +34 -0
- package/esm2022/lib/utils.mjs +14 -0
- package/esm2022/public-api.mjs +15 -0
- package/esm2022/types.mjs +2 -0
- package/fesm2022/barsa-user-workspace.mjs +2469 -0
- package/fesm2022/barsa-user-workspace.mjs.map +1 -0
- package/index.d.ts +5 -0
- package/lib/barsa-user-workspace.module.d.ts +34 -0
- package/lib/coercion/boolean-property.d.ts +7 -0
- package/lib/coercion/number-property.d.ts +9 -0
- package/lib/directives/drag-handle.d.ts +15 -0
- package/lib/directives/placeholder.d.ts +17 -0
- package/lib/directives/resize-handle.d.ts +15 -0
- package/lib/grid/grid.component.d.ts +147 -0
- package/lib/grid-item/grid-item.component.d.ts +83 -0
- package/lib/grid.definitions.d.ts +61 -0
- package/lib/grid.service.d.ts +15 -0
- package/lib/layout-container/layout-container.component.d.ts +79 -0
- package/lib/layout-grid-mapper.pipe.d.ts +9 -0
- package/lib/nav-container/nav-container.component.d.ts +10 -0
- package/lib/report-grid-layout/report-grid-layout.component.d.ts +7 -0
- package/lib/utils/client-rect.d.ts +36 -0
- package/lib/utils/grid.utils.d.ts +45 -0
- package/lib/utils/operators.d.ts +6 -0
- package/lib/utils/passive-listeners.d.ts +12 -0
- package/lib/utils/pointer.utils.d.ts +29 -0
- package/lib/utils/react-grid-layout.utils.d.ts +177 -0
- package/lib/utils/scroll.d.ts +28 -0
- package/lib/utils/transition-duration.d.ts +6 -0
- package/lib/utils.d.ts +6 -0
- package/package.json +25 -0
- package/public-api.d.ts +12 -0
- package/types.d.ts +3 -0
|
@@ -0,0 +1,493 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* IMPORTANT:
|
|
3
|
+
* This utils are taken from the project: https://github.com/STRML/react-grid-layout.
|
|
4
|
+
* The code should be as less modified as possible for easy maintenance.
|
|
5
|
+
*/
|
|
6
|
+
const DEBUG = false;
|
|
7
|
+
/**
|
|
8
|
+
* Return the bottom coordinate of the layout.
|
|
9
|
+
*
|
|
10
|
+
* @param {Array} layout Layout array.
|
|
11
|
+
* @return {Number} Bottom coordinate.
|
|
12
|
+
*/
|
|
13
|
+
export function bottom(layout) {
|
|
14
|
+
let max = 0, bottomY;
|
|
15
|
+
for (let i = 0, len = layout.length; i < len; i++) {
|
|
16
|
+
bottomY = layout[i].y + layout[i].h;
|
|
17
|
+
if (bottomY > max) {
|
|
18
|
+
max = bottomY;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
return max;
|
|
22
|
+
}
|
|
23
|
+
export function cloneLayout(layout) {
|
|
24
|
+
const newLayout = Array(layout.length);
|
|
25
|
+
for (let i = 0, len = layout.length; i < len; i++) {
|
|
26
|
+
newLayout[i] = cloneLayoutItem(layout[i]);
|
|
27
|
+
}
|
|
28
|
+
return newLayout;
|
|
29
|
+
}
|
|
30
|
+
// Fast path to cloning, since this is monomorphic
|
|
31
|
+
/** NOTE: This code has been modified from the original source */
|
|
32
|
+
export function cloneLayoutItem(layoutItem) {
|
|
33
|
+
const clonedLayoutItem = {
|
|
34
|
+
w: layoutItem.w,
|
|
35
|
+
h: layoutItem.h,
|
|
36
|
+
x: layoutItem.x,
|
|
37
|
+
y: layoutItem.y,
|
|
38
|
+
id: layoutItem.id,
|
|
39
|
+
moved: !!layoutItem.moved,
|
|
40
|
+
static: !!layoutItem.static,
|
|
41
|
+
};
|
|
42
|
+
if (layoutItem.minW !== undefined) {
|
|
43
|
+
clonedLayoutItem.minW = layoutItem.minW;
|
|
44
|
+
}
|
|
45
|
+
if (layoutItem.maxW !== undefined) {
|
|
46
|
+
clonedLayoutItem.maxW = layoutItem.maxW;
|
|
47
|
+
}
|
|
48
|
+
if (layoutItem.minH !== undefined) {
|
|
49
|
+
clonedLayoutItem.minH = layoutItem.minH;
|
|
50
|
+
}
|
|
51
|
+
if (layoutItem.maxH !== undefined) {
|
|
52
|
+
clonedLayoutItem.maxH = layoutItem.maxH;
|
|
53
|
+
}
|
|
54
|
+
// These can be null
|
|
55
|
+
if (layoutItem.isDraggable !== undefined) {
|
|
56
|
+
clonedLayoutItem.isDraggable = layoutItem.isDraggable;
|
|
57
|
+
}
|
|
58
|
+
if (layoutItem.isResizable !== undefined) {
|
|
59
|
+
clonedLayoutItem.isResizable = layoutItem.isResizable;
|
|
60
|
+
}
|
|
61
|
+
return clonedLayoutItem;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Given two layoutitems, check if they collide.
|
|
65
|
+
*/
|
|
66
|
+
export function collides(l1, l2) {
|
|
67
|
+
if (l1.id === l2.id) {
|
|
68
|
+
return false;
|
|
69
|
+
} // same element
|
|
70
|
+
if (l1.x + l1.w <= l2.x) {
|
|
71
|
+
return false;
|
|
72
|
+
} // l1 is left of l2
|
|
73
|
+
if (l1.x >= l2.x + l2.w) {
|
|
74
|
+
return false;
|
|
75
|
+
} // l1 is right of l2
|
|
76
|
+
if (l1.y + l1.h <= l2.y) {
|
|
77
|
+
return false;
|
|
78
|
+
} // l1 is above l2
|
|
79
|
+
if (l1.y >= l2.y + l2.h) {
|
|
80
|
+
return false;
|
|
81
|
+
} // l1 is below l2
|
|
82
|
+
return true; // boxes overlap
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Given a layout, compact it. This involves going down each y coordinate and removing gaps
|
|
86
|
+
* between items.
|
|
87
|
+
*
|
|
88
|
+
* @param {Array} layout Layout.
|
|
89
|
+
* @param {Boolean} verticalCompact Whether or not to compact the layout
|
|
90
|
+
* vertically.
|
|
91
|
+
* @return {Array} Compacted Layout.
|
|
92
|
+
*/
|
|
93
|
+
export function compact(layout, compactType, cols) {
|
|
94
|
+
// Statics go in the compareWith array right away so items flow around them.
|
|
95
|
+
const compareWith = getStatics(layout);
|
|
96
|
+
// We go through the items by row and column.
|
|
97
|
+
const sorted = sortLayoutItems(layout, compactType);
|
|
98
|
+
// Holding for new items.
|
|
99
|
+
const out = Array(layout.length);
|
|
100
|
+
for (let i = 0, len = sorted.length; i < len; i++) {
|
|
101
|
+
let l = cloneLayoutItem(sorted[i]);
|
|
102
|
+
// Don't move static elements
|
|
103
|
+
if (!l.static) {
|
|
104
|
+
l = compactItem(compareWith, l, compactType, cols, sorted);
|
|
105
|
+
// Add to comparison array. We only collide with items before this one.
|
|
106
|
+
// Statics are already in this array.
|
|
107
|
+
compareWith.push(l);
|
|
108
|
+
}
|
|
109
|
+
// Add to output array to make sure they still come out in the right order.
|
|
110
|
+
out[layout.indexOf(sorted[i])] = l;
|
|
111
|
+
// Clear moved flag, if it exists.
|
|
112
|
+
l.moved = false;
|
|
113
|
+
}
|
|
114
|
+
return out;
|
|
115
|
+
}
|
|
116
|
+
const heightWidth = { x: 'w', y: 'h' };
|
|
117
|
+
/**
|
|
118
|
+
* Before moving item down, it will check if the movement will cause collisions and move those items down before.
|
|
119
|
+
*/
|
|
120
|
+
function resolveCompactionCollision(layout, item, moveToCoord, axis) {
|
|
121
|
+
const sizeProp = heightWidth[axis];
|
|
122
|
+
item[axis] += 1;
|
|
123
|
+
const itemIndex = layout
|
|
124
|
+
.map(layoutItem => {
|
|
125
|
+
return layoutItem.id;
|
|
126
|
+
})
|
|
127
|
+
.indexOf(item.id);
|
|
128
|
+
// Go through each item we collide with.
|
|
129
|
+
for (let i = itemIndex + 1; i < layout.length; i++) {
|
|
130
|
+
const otherItem = layout[i];
|
|
131
|
+
// Ignore static items
|
|
132
|
+
if (otherItem.static) {
|
|
133
|
+
continue;
|
|
134
|
+
}
|
|
135
|
+
// Optimization: we can break early if we know we're past this el
|
|
136
|
+
// We can do this b/c it's a sorted layout
|
|
137
|
+
if (otherItem.y > item.y + item.h) {
|
|
138
|
+
break;
|
|
139
|
+
}
|
|
140
|
+
if (collides(item, otherItem)) {
|
|
141
|
+
resolveCompactionCollision(layout, otherItem, moveToCoord + item[sizeProp], axis);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
item[axis] = moveToCoord;
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Compact an item in the layout.
|
|
148
|
+
*/
|
|
149
|
+
export function compactItem(compareWith, l, compactType, cols, fullLayout) {
|
|
150
|
+
const compactV = compactType === 'vertical';
|
|
151
|
+
const compactH = compactType === 'horizontal';
|
|
152
|
+
if (compactV) {
|
|
153
|
+
// Bottom 'y' possible is the bottom of the layout.
|
|
154
|
+
// This allows you to do nice stuff like specify {y: Infinity}
|
|
155
|
+
// This is here because the layout must be sorted in order to get the correct bottom `y`.
|
|
156
|
+
l.y = Math.min(bottom(compareWith), l.y);
|
|
157
|
+
// Move the element up as far as it can go without colliding.
|
|
158
|
+
while (l.y > 0 && !getFirstCollision(compareWith, l)) {
|
|
159
|
+
l.y--;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
else if (compactH) {
|
|
163
|
+
// Move the element left as far as it can go without colliding.
|
|
164
|
+
while (l.x > 0 && !getFirstCollision(compareWith, l)) {
|
|
165
|
+
l.x--;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
// Move it down, and keep moving it down if it's colliding.
|
|
169
|
+
let collides;
|
|
170
|
+
while ((collides = getFirstCollision(compareWith, l))) {
|
|
171
|
+
if (compactH) {
|
|
172
|
+
resolveCompactionCollision(fullLayout, l, collides.x + collides.w, 'x');
|
|
173
|
+
}
|
|
174
|
+
else {
|
|
175
|
+
resolveCompactionCollision(fullLayout, l, collides.y + collides.h, 'y');
|
|
176
|
+
}
|
|
177
|
+
// Since we can't grow without bounds horizontally, if we've overflown, let's move it down and try again.
|
|
178
|
+
if (compactH && l.x + l.w > cols) {
|
|
179
|
+
l.x = cols - l.w;
|
|
180
|
+
l.y++;
|
|
181
|
+
// ALso move element as left as much as we can (buw-custom-change)
|
|
182
|
+
while (l.x > 0 && !getFirstCollision(compareWith, l)) {
|
|
183
|
+
l.x--;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
// Ensure that there are no negative positions
|
|
188
|
+
l.y = Math.max(l.y, 0);
|
|
189
|
+
l.x = Math.max(l.x, 0);
|
|
190
|
+
return l;
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* Given a layout, make sure all elements fit within its bounds.
|
|
194
|
+
*
|
|
195
|
+
* @param {Array} layout Layout array.
|
|
196
|
+
* @param {Number} bounds Number of columns.
|
|
197
|
+
*/
|
|
198
|
+
export function correctBounds(layout, bounds) {
|
|
199
|
+
const collidesWith = getStatics(layout);
|
|
200
|
+
for (let i = 0, len = layout.length; i < len; i++) {
|
|
201
|
+
const l = layout[i];
|
|
202
|
+
// Overflows right
|
|
203
|
+
if (l.x + l.w > bounds.cols) {
|
|
204
|
+
l.x = bounds.cols - l.w;
|
|
205
|
+
}
|
|
206
|
+
// Overflows left
|
|
207
|
+
if (l.x < 0) {
|
|
208
|
+
l.x = 0;
|
|
209
|
+
l.w = bounds.cols;
|
|
210
|
+
}
|
|
211
|
+
if (!l.static) {
|
|
212
|
+
collidesWith.push(l);
|
|
213
|
+
}
|
|
214
|
+
else {
|
|
215
|
+
// If this is static and collides with other statics, we must move it down.
|
|
216
|
+
// We have to do something nicer than just letting them overlap.
|
|
217
|
+
while (getFirstCollision(collidesWith, l)) {
|
|
218
|
+
l.y++;
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
return layout;
|
|
223
|
+
}
|
|
224
|
+
/**
|
|
225
|
+
* Get a layout item by ID. Used so we can override later on if necessary.
|
|
226
|
+
*
|
|
227
|
+
* @param {Array} layout Layout array.
|
|
228
|
+
* @param {String} id ID
|
|
229
|
+
* @return {LayoutItem} Item at ID.
|
|
230
|
+
*/
|
|
231
|
+
export function getLayoutItem(layout, id) {
|
|
232
|
+
for (let i = 0, len = layout.length; i < len; i++) {
|
|
233
|
+
if (layout[i].id === id) {
|
|
234
|
+
return layout[i];
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
return null;
|
|
238
|
+
}
|
|
239
|
+
/**
|
|
240
|
+
* Returns the first item this layout collides with.
|
|
241
|
+
* It doesn't appear to matter which order we approach this from, although
|
|
242
|
+
* perhaps that is the wrong thing to do.
|
|
243
|
+
*
|
|
244
|
+
* @param {Object} layoutItem Layout item.
|
|
245
|
+
* @return {Object|undefined} A colliding layout item, or undefined.
|
|
246
|
+
*/
|
|
247
|
+
export function getFirstCollision(layout, layoutItem) {
|
|
248
|
+
for (let i = 0, len = layout.length; i < len; i++) {
|
|
249
|
+
if (collides(layout[i], layoutItem)) {
|
|
250
|
+
return layout[i];
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
return null;
|
|
254
|
+
}
|
|
255
|
+
export function getAllCollisions(layout, layoutItem) {
|
|
256
|
+
return layout.filter(l => collides(l, layoutItem));
|
|
257
|
+
}
|
|
258
|
+
/**
|
|
259
|
+
* Get all static elements.
|
|
260
|
+
* @param {Array} layout Array of layout objects.
|
|
261
|
+
* @return {Array} Array of static layout items..
|
|
262
|
+
*/
|
|
263
|
+
export function getStatics(layout) {
|
|
264
|
+
return layout.filter(l => l.static);
|
|
265
|
+
}
|
|
266
|
+
/**
|
|
267
|
+
* Move an element. Responsible for doing cascading movements of other elements.
|
|
268
|
+
*
|
|
269
|
+
* @param {Array} layout Full layout to modify.
|
|
270
|
+
* @param {LayoutItem} l element to move.
|
|
271
|
+
* @param {Number} [x] X position in grid units.
|
|
272
|
+
* @param {Number} [y] Y position in grid units.
|
|
273
|
+
*/
|
|
274
|
+
export function moveElement(layout, l, x, y, isUserAction, preventCollision, compactType, cols) {
|
|
275
|
+
// If this is static and not explicitly enabled as draggable,
|
|
276
|
+
// no move is possible, so we can short-circuit this immediately.
|
|
277
|
+
if (l.static && l.isDraggable !== true) {
|
|
278
|
+
return layout;
|
|
279
|
+
}
|
|
280
|
+
// Short-circuit if nothing to do.
|
|
281
|
+
if (l.y === y && l.x === x) {
|
|
282
|
+
return layout;
|
|
283
|
+
}
|
|
284
|
+
log(`Moving element ${l.id} to [${String(x)},${String(y)}] from [${l.x},${l.y}]`);
|
|
285
|
+
const oldX = l.x;
|
|
286
|
+
const oldY = l.y;
|
|
287
|
+
// This is quite a bit faster than extending the object
|
|
288
|
+
if (typeof x === 'number') {
|
|
289
|
+
l.x = x;
|
|
290
|
+
}
|
|
291
|
+
if (typeof y === 'number') {
|
|
292
|
+
l.y = y;
|
|
293
|
+
}
|
|
294
|
+
l.moved = true;
|
|
295
|
+
// If this collides with anything, move it.
|
|
296
|
+
// When doing this comparison, we have to sort the items we compare with
|
|
297
|
+
// to ensure, in the case of multiple collisions, that we're getting the
|
|
298
|
+
// nearest collision.
|
|
299
|
+
let sorted = sortLayoutItems(layout, compactType);
|
|
300
|
+
const movingUp = compactType === 'vertical' && typeof y === 'number'
|
|
301
|
+
? oldY >= y
|
|
302
|
+
: compactType === 'horizontal' && typeof x === 'number'
|
|
303
|
+
? oldX >= x
|
|
304
|
+
: false;
|
|
305
|
+
if (movingUp) {
|
|
306
|
+
sorted = sorted.reverse();
|
|
307
|
+
}
|
|
308
|
+
const collisions = getAllCollisions(sorted, l);
|
|
309
|
+
// There was a collision; abort
|
|
310
|
+
if (preventCollision && collisions.length) {
|
|
311
|
+
log(`Collision prevented on ${l.id}, reverting.`);
|
|
312
|
+
l.x = oldX;
|
|
313
|
+
l.y = oldY;
|
|
314
|
+
l.moved = false;
|
|
315
|
+
return layout;
|
|
316
|
+
}
|
|
317
|
+
// Move each item that collides away from this element.
|
|
318
|
+
for (let i = 0, len = collisions.length; i < len; i++) {
|
|
319
|
+
const collision = collisions[i];
|
|
320
|
+
log(`Resolving collision between ${l.id} at [${l.x},${l.y}] and ${collision.id} at [${collision.x},${collision.y}]`);
|
|
321
|
+
// Short circuit so we can't infinite loop
|
|
322
|
+
if (collision.moved) {
|
|
323
|
+
continue;
|
|
324
|
+
}
|
|
325
|
+
// Don't move static items - we have to move *this* element away
|
|
326
|
+
if (collision.static) {
|
|
327
|
+
layout = moveElementAwayFromCollision(layout, collision, l, isUserAction, compactType, cols);
|
|
328
|
+
}
|
|
329
|
+
else {
|
|
330
|
+
layout = moveElementAwayFromCollision(layout, l, collision, isUserAction, compactType, cols);
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
return layout;
|
|
334
|
+
}
|
|
335
|
+
/**
|
|
336
|
+
* This is where the magic needs to happen - given a collision, move an element away from the collision.
|
|
337
|
+
* We attempt to move it up if there's room, otherwise it goes below.
|
|
338
|
+
*
|
|
339
|
+
* @param {Array} layout Full layout to modify.
|
|
340
|
+
* @param {LayoutItem} collidesWith Layout item we're colliding with.
|
|
341
|
+
* @param {LayoutItem} itemToMove Layout item we're moving.
|
|
342
|
+
*/
|
|
343
|
+
export function moveElementAwayFromCollision(layout, collidesWith, itemToMove, isUserAction, compactType, cols) {
|
|
344
|
+
const compactH = compactType === 'horizontal';
|
|
345
|
+
// Compact vertically if not set to horizontal
|
|
346
|
+
const compactV = compactType !== 'horizontal';
|
|
347
|
+
const preventCollision = collidesWith.static; // we're already colliding (not for static items)
|
|
348
|
+
// If there is enough space above the collision to put this element, move it there.
|
|
349
|
+
// We only do this on the main collision as this can get funky in cascades and cause
|
|
350
|
+
// unwanted swapping behavior.
|
|
351
|
+
if (isUserAction) {
|
|
352
|
+
// Reset isUserAction flag because we're not in the main collision anymore.
|
|
353
|
+
isUserAction = false;
|
|
354
|
+
// Make a mock item so we don't modify the item here, only modify in moveElement.
|
|
355
|
+
const fakeItem = {
|
|
356
|
+
x: compactH
|
|
357
|
+
? Math.max(collidesWith.x - itemToMove.w, 0)
|
|
358
|
+
: itemToMove.x,
|
|
359
|
+
y: compactV
|
|
360
|
+
? Math.max(collidesWith.y - itemToMove.h, 0)
|
|
361
|
+
: itemToMove.y,
|
|
362
|
+
w: itemToMove.w,
|
|
363
|
+
h: itemToMove.h,
|
|
364
|
+
id: '-1',
|
|
365
|
+
};
|
|
366
|
+
// No collision? If so, we can go up there; otherwise, we'll end up moving down as normal
|
|
367
|
+
if (!getFirstCollision(layout, fakeItem)) {
|
|
368
|
+
log(`Doing reverse collision on ${itemToMove.id} up to [${fakeItem.x},${fakeItem.y}].`);
|
|
369
|
+
return moveElement(layout, itemToMove, compactH ? fakeItem.x : undefined, compactV ? fakeItem.y : undefined, isUserAction, preventCollision, compactType, cols);
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
return moveElement(layout, itemToMove, compactH ? itemToMove.x + 1 : undefined, compactV ? itemToMove.y + 1 : undefined, isUserAction, preventCollision, compactType, cols);
|
|
373
|
+
}
|
|
374
|
+
/**
|
|
375
|
+
* Helper to convert a number to a percentage string.
|
|
376
|
+
*
|
|
377
|
+
* @param {Number} num Any number
|
|
378
|
+
* @return {String} That number as a percentage.
|
|
379
|
+
*/
|
|
380
|
+
export function perc(num) {
|
|
381
|
+
return num * 100 + '%';
|
|
382
|
+
}
|
|
383
|
+
export function setTransform({ top, left, width, height }) {
|
|
384
|
+
// Replace unitless items with px
|
|
385
|
+
const translate = `translate(${left}px,${top}px)`;
|
|
386
|
+
return {
|
|
387
|
+
transform: translate,
|
|
388
|
+
WebkitTransform: translate,
|
|
389
|
+
MozTransform: translate,
|
|
390
|
+
msTransform: translate,
|
|
391
|
+
OTransform: translate,
|
|
392
|
+
width: `${width}px`,
|
|
393
|
+
height: `${height}px`,
|
|
394
|
+
position: 'absolute',
|
|
395
|
+
};
|
|
396
|
+
}
|
|
397
|
+
export function setTopLeft({ top, left, width, height }) {
|
|
398
|
+
return {
|
|
399
|
+
top: `${top}px`,
|
|
400
|
+
left: `${left}px`,
|
|
401
|
+
width: `${width}px`,
|
|
402
|
+
height: `${height}px`,
|
|
403
|
+
position: 'absolute',
|
|
404
|
+
};
|
|
405
|
+
}
|
|
406
|
+
/**
|
|
407
|
+
* Get layout items sorted from top left to right and down.
|
|
408
|
+
*
|
|
409
|
+
* @return {Array} Array of layout objects.
|
|
410
|
+
* @return {Array} Layout, sorted static items first.
|
|
411
|
+
*/
|
|
412
|
+
export function sortLayoutItems(layout, compactType) {
|
|
413
|
+
if (compactType === 'horizontal') {
|
|
414
|
+
return sortLayoutItemsByColRow(layout);
|
|
415
|
+
}
|
|
416
|
+
else {
|
|
417
|
+
return sortLayoutItemsByRowCol(layout);
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
export function sortLayoutItemsByRowCol(layout) {
|
|
421
|
+
return [].concat(layout).sort(function (a, b) {
|
|
422
|
+
if (a.y > b.y || (a.y === b.y && a.x > b.x)) {
|
|
423
|
+
return 1;
|
|
424
|
+
}
|
|
425
|
+
else if (a.y === b.y && a.x === b.x) {
|
|
426
|
+
// Without this, we can get different sort results in IE vs. Chrome/FF
|
|
427
|
+
return 0;
|
|
428
|
+
}
|
|
429
|
+
return -1;
|
|
430
|
+
});
|
|
431
|
+
}
|
|
432
|
+
export function sortLayoutItemsByColRow(layout) {
|
|
433
|
+
return [].concat(layout).sort(function (a, b) {
|
|
434
|
+
if (a.x > b.x || (a.x === b.x && a.y > b.y)) {
|
|
435
|
+
return 1;
|
|
436
|
+
}
|
|
437
|
+
return -1;
|
|
438
|
+
});
|
|
439
|
+
}
|
|
440
|
+
/**
|
|
441
|
+
* Validate a layout. Throws errors.
|
|
442
|
+
*
|
|
443
|
+
* @param {Array} layout Array of layout items.
|
|
444
|
+
* @param {String} [contextName] Context name for errors.
|
|
445
|
+
* @throw {Error} Validation error.
|
|
446
|
+
*/
|
|
447
|
+
export function validateLayout(layout, contextName = 'Layout') {
|
|
448
|
+
const subProps = ['x', 'y', 'w', 'h'];
|
|
449
|
+
if (!Array.isArray(layout)) {
|
|
450
|
+
throw new Error(contextName + ' must be an array!');
|
|
451
|
+
}
|
|
452
|
+
for (let i = 0, len = layout.length; i < len; i++) {
|
|
453
|
+
const item = layout[i];
|
|
454
|
+
for (let j = 0; j < subProps.length; j++) {
|
|
455
|
+
if (typeof item[subProps[j]] !== 'number') {
|
|
456
|
+
throw new Error('ReactGridLayout: ' +
|
|
457
|
+
contextName +
|
|
458
|
+
'[' +
|
|
459
|
+
i +
|
|
460
|
+
'].' +
|
|
461
|
+
subProps[j] +
|
|
462
|
+
' must be a number!');
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
if (item.id && typeof item.id !== 'string') {
|
|
466
|
+
throw new Error('ReactGridLayout: ' +
|
|
467
|
+
contextName +
|
|
468
|
+
'[' +
|
|
469
|
+
i +
|
|
470
|
+
'].i must be a string!');
|
|
471
|
+
}
|
|
472
|
+
if (item.static !== undefined && typeof item.static !== 'boolean') {
|
|
473
|
+
throw new Error('ReactGridLayout: ' +
|
|
474
|
+
contextName +
|
|
475
|
+
'[' +
|
|
476
|
+
i +
|
|
477
|
+
'].static must be a boolean!');
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
// Flow can't really figure this out, so we just use Object
|
|
482
|
+
export function autoBindHandlers(el, fns) {
|
|
483
|
+
fns.forEach(key => (el[key] = el[key].bind(el)));
|
|
484
|
+
}
|
|
485
|
+
function log(...args) {
|
|
486
|
+
if (!DEBUG) {
|
|
487
|
+
return;
|
|
488
|
+
}
|
|
489
|
+
// eslint-disable-next-line no-console
|
|
490
|
+
console.log(...args);
|
|
491
|
+
}
|
|
492
|
+
export const noop = () => { };
|
|
493
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVhY3QtZ3JpZC1sYXlvdXQudXRpbHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9iYXJzYS11c2VyLXdvcmtzcGFjZS9zcmMvbGliL3V0aWxzL3JlYWN0LWdyaWQtbGF5b3V0LnV0aWxzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7O0dBSUc7QUFxRUgsTUFBTSxLQUFLLEdBQUcsS0FBSyxDQUFDO0FBRXBCOzs7OztHQUtHO0FBQ0gsTUFBTSxVQUFVLE1BQU0sQ0FBQyxNQUFjO0lBQ2pDLElBQUksR0FBRyxHQUFHLENBQUMsRUFDUCxPQUFPLENBQUM7SUFDWixLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxHQUFHLEdBQUcsTUFBTSxDQUFDLE1BQU0sRUFBRSxDQUFDLEdBQUcsR0FBRyxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUM7UUFDaEQsT0FBTyxHQUFHLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUNwQyxJQUFJLE9BQU8sR0FBRyxHQUFHLEVBQUUsQ0FBQztZQUNoQixHQUFHLEdBQUcsT0FBTyxDQUFDO1FBQ2xCLENBQUM7SUFDTCxDQUFDO0lBQ0QsT0FBTyxHQUFHLENBQUM7QUFDZixDQUFDO0FBRUQsTUFBTSxVQUFVLFdBQVcsQ0FBQyxNQUFjO0lBQ3RDLE1BQU0sU0FBUyxHQUFHLEtBQUssQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUM7SUFDdkMsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsR0FBRyxHQUFHLE1BQU0sQ0FBQyxNQUFNLEVBQUUsQ0FBQyxHQUFHLEdBQUcsRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDO1FBQ2hELFNBQVMsQ0FBQyxDQUFDLENBQUMsR0FBRyxlQUFlLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDOUMsQ0FBQztJQUNE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QUFFRCxNQUFNLENBQUMsTUFBTSxJQUFJLEdBQUcsR0FBRyxFQUFFLEdBQUUsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBJTVBPUlRBTlQ6XG4gKiBUaGlzIHV0aWxzIGFyZSB0YWtlbiBmcm9tIHRoZSBwcm9qZWN0OiBodHRwczovL2dpdGh1Yi5jb20vU1RSTUwvcmVhY3QtZ3JpZC1sYXlvdXQuXG4gKiBUaGUgY29kZSBzaG91bGQgYmUgYXMgbGVzcyBtb2RpZmllZCBhcyBwb3NzaWJsZSBmb3IgZWFzeSBtYWludGVuYW5jZS5cbiAqL1xuXG4vLyBEaXNhYmxlIGxpbnQgc2luY2Ugd2UgZG9uJ3Qgd2FudCB0byBtb2RpZnkgdGhpcyBjb2RlXG4vKiBlc2xpbnQtZGlzYWJsZSAqL1xuZXhwb3J0IHR5cGUgTGF5b3V0SXRlbSA9IHtcbiAgICB3OiBudW1iZXI7XG4gICAgaDogbnVtYmVyO1xuICAgIHg6IG51bWJlcjtcbiAgICB5OiBudW1iZXI7XG4gICAgaWQ6IHN0cmluZztcbiAgICBtaW5XPzogbnVtYmVyO1xuICAgIG1pbkg/OiBudW1iZXI7XG4gICAgbWF4Vz86IG51bWJlcjtcbiAgICBtYXhIPzogbnVtYmVyO1xuICAgIG1vdmVkPzogYm9vbGVhbjtcbiAgICBzdGF0aWM/OiBib29sZWFuO1xuICAgIGlzRHJhZ2dhYmxlPzogYm9vbGVhbiB8IG51bGwgfCB1bmRlZmluZWQ7XG4gICAgaXNSZXNpemFibGU/OiBib29sZWFuIHwgbnVsbCB8IHVuZGVmaW5lZDtcbn07XG5leHBvcnQgdHlwZSBMYXlvdXQgPSBBcnJheTxMYXlvdXRJdGVtPjtcbmV4cG9ydCB0eXBlIFBvc2l0aW9uID0ge1xuICAgIGxlZnQ6IG51bWJlcjtcbiAgICB0b3A6IG51bWJlcjtcbiAgICB3aWR0aDogbnVtYmVyO1xuICAgIGhlaWdodDogbnVtYmVyO1xufTtcbmV4cG9ydCB0eXBlIFJlYWN0RHJhZ2dhYmxlQ2FsbGJhY2tEYXRhID0ge1xuICAgIG5vZGU6IEhUTUxFbGVtZW50O1xuICAgIHg/OiBudW1iZXI7XG4gICAgeT86IG51bWJlcjtcbiAgICBkZWx0YVg6IG51bWJlcjtcbiAgICBkZWx0YVk6IG51bWJlcjtcbiAgICBsYXN0WD86IG51bWJlcjtcbiAgICBsYXN0WT86IG51bWJlcjtcbn07XG5cbmV4cG9ydCB0eXBlIFBhcnRpYWxQb3NpdGlvbiA9IHsgbGVmdDogbnVtYmVyOyB0b3A6IG51bWJlciB9O1xuZXhwb3J0IHR5cGUgRHJvcHBpbmdQb3NpdGlvbiA9IHsgeDogbnVtYmVyOyB5OiBudW1iZXI7IGU6IEV2ZW50IH07XG5leHBvcnQgdHlwZSBTaXplID0geyB3aWR0aDogbnVtYmVyOyBoZWlnaHQ6IG51bWJlciB9O1xuZXhwb3J0IHR5cGUgR3JpZERyYWdFdmVudCA9IHtcbiAgICBlOiBFdmVudDtcbiAgICBub2RlOiBIVE1MRWxlbWVudDtcbiAgICBuZXdQb3NpdGlvbjogUGFydGlhbFBvc2l0aW9uO1xufTtcbmV4cG9ydCB0eXBlIEdyaWRSZXNpemVFdmVudCA9IHsgZTogRXZlbnQ7IG5vZGU6IEhUTUxFbGVtZW50OyBzaXplOiBTaXplIH07XG5leHBvcnQgdHlwZSBEcmFnT3ZlckV2ZW50ID0gTW91c2VFdmVudCAmIHtcbiAgICBuYXRpdmVFdmVudDoge1xuICAgICAgICBsYXllclg6IG51bWJlcjtcbiAgICAgICAgbGF5ZXJZOiBudW1iZXI7XG4gICAgICAgIHRhcmdldDoge1xuICAgICAgICAgICAgY2xhc3NOYW1lOiBTdHJpbmc7XG4gICAgICAgIH07XG4gICAgfTtcbn07XG5cbi8vdHlwZSBSRWwgPSBSZWFjdEVsZW1lbnQ8YW55Pjtcbi8vZXhwb3J0IHR5cGUgUmVhY3RDaGlsZHJlbiA9IFJlYWN0Q2hpbGRyZW5BcnJheTxSRWw+O1xuXG4vLyBBbGwgY2FsbGJhY2tzIGFyZSBvZiB0aGUgc2lnbmF0dXJlIChsYXlvdXQsIG9sZEl0ZW0sIG5ld0l0ZW0sIHBsYWNlaG9sZGVyLCBlKS5cbmV4cG9ydCB0eXBlIEV2ZW50Q2FsbGJhY2sgPSAoXG4gICAgYXJnMDogTGF5b3V0LFxuICAgIG9sZEl0ZW06IExheW91dEl0ZW0gfCBudWxsIHwgdW5kZWZpbmVkLFxuICAgIG5ld0l0ZW06IExheW91dEl0ZW0gfCBudWxsIHwgdW5kZWZpbmVkLFxuICAgIHBsYWNlaG9sZGVyOiBMYXlvdXRJdGVtIHwgbnVsbCB8IHVuZGVmaW5lZCxcbiAgICBhcmc0OiBFdmVudCxcbiAgICBhcmc1OiBIVE1MRWxlbWVudCB8IG51bGwgfCB1bmRlZmluZWQsXG4pID0+IHZvaWQ7XG5leHBvcnQgdHlwZSBDb21wYWN0VHlwZSA9ICgnaG9yaXpvbnRhbCcgfCAndmVydGljYWwnKSB8IG51bGwgfCB1bmRlZmluZWQ7XG5cbmNvbnN0IERFQlVHID0gZmFsc2U7XG5cbi8qKlxuICogUmV0dXJuIHRoZSBib3R0b20gY29vcmRpbmF0ZSBvZiB0aGUgbGF5b3V0LlxuICpcbiAqIEBwYXJhbSAge0FycmF5fSBsYXlvdXQgTGF5b3V0IGFycmF5LlxuICogQHJldHVybiB7TnVtYmVyfSAgICAgICBCb3R0b20gY29vcmRpbmF0ZS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGJvdHRvbShsYXlvdXQ6IExheW91dCk6IG51bWJlciB7XG4gICAgbGV0IG1heCA9IDAsXG4gICAgICAgIGJvdHRvbVk7XG4gICAgZm9yIChsZXQgaSA9IDAsIGxlbiA9IGxheW91dC5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xuICAgICAgICBib3R0b21ZID0gbGF5b3V0W2ldLnkgKyBsYXlvdXRbaV0uaDtcbiAgICAgICAgaWYgKGJvdHRvbVkgPiBtYXgpIHtcbiAgICAgICAgICAgIG1heCA9IGJvdHRvbVk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIG1heDtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGNsb25lTGF5b3V0KGxheW91dDogTGF5b3V0KTogTGF5b3V0IHtcbiAgICBjb25zdCBuZXdMYXlvdXQgPSBBcnJheShsYXlvdXQubGVuZ3RoKTtcbiAgICBmb3IgKGxldCBpID0gMCwgbGVuID0gbGF5b3V0Lmxlbmd0aDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgICAgIG5ld0xheW91dFtpXSA9IGNsb25lTGF5b3V0SXRlbShsYXlvdXRbaV0pO1xuICAgIH1cbiAgICByZXR1cm4gbmV3TGF5b3V0O1xufVxuXG4vLyBGYXN0IHBhdGggdG8gY2xvbmluZywgc2luY2UgdGhpcyBpcyBtb25vbW9ycGhpY1xuLyoqIE5PVEU6IFRoaXMgY29kZSBoYXMgYmVlbiBtb2RpZmllZCBmcm9tIHRoZSBvcmlnaW5hbCBzb3VyY2UgKi9cbmV4cG9ydCBmdW5jdGlvbiBjbG9uZUxheW91dEl0ZW0obGF5b3V0SXRlbTogTGF5b3V0SXRlbSk6IExheW91dEl0ZW0ge1xuICAgIGNvbnN0IGNsb25lZExheW91dEl0ZW06IExheW91dEl0ZW0gPSB7XG4gICAgICAgIHc6IGxheW91dEl0ZW0udyxcbiAgICAgICAgaDogbGF5b3V0SXRlbS5oLFxuICAgICAgICB4OiBsYXlvdXRJdGVtLngsXG4gICAgICAgIHk6IGxheW91dEl0ZW0ueSxcbiAgICAgICAgaWQ6IGxheW91dEl0ZW0uaWQsXG4gICAgICAgIG1vdmVkOiAhIWxheW91dEl0ZW0ubW92ZWQsXG4gICAgICAgIHN0YXRpYzogISFsYXlvdXRJdGVtLnN0YXRpYyxcbiAgICB9O1xuXG4gICAgaWYgKGxheW91dEl0ZW0ubWluVyAhPT0gdW5kZWZpbmVkKSB7IGNsb25lZExheW91dEl0ZW0ubWluVyA9IGxheW91dEl0ZW0ubWluVzt9XG4gICAgaWYgKGxheW91dEl0ZW0ubWF4VyAhPT0gdW5kZWZpbmVkKSB7IGNsb25lZExheW91dEl0ZW0ubWF4VyA9IGxheW91dEl0ZW0ubWF4Vzt9XG4gICAgaWYgKGxheW91dEl0ZW0ubWluSCAhPT0gdW5kZWZpbmVkKSB7IGNsb25lZExheW91dEl0ZW0ubWluSCA9IGxheW91dEl0ZW0ubWluSDt9XG4gICAgaWYgKGxheW91dEl0ZW0ubWF4SCAhPT0gdW5kZWZpbmVkKSB7IGNsb25lZExheW91dEl0ZW0ubWF4SCA9IGxheW91dEl0ZW0ubWF4SDt9XG4gICAgLy8gVGhlc2UgY2FuIGJlIG51bGxcbiAgICBpZiAobGF5b3V0SXRlbS5pc0RyYWdnYWJsZSAhPT0gdW5kZWZpbmVkKSB7IGNsb25lZExheW91dEl0ZW0uaXNEcmFnZ2FibGUgPSBsYXlvdXRJdGVtLmlzRHJhZ2dhYmxlO31cbiAgICBpZiAobGF5b3V0SXRlbS5pc1Jlc2l6YWJsZSAhPT0gdW5kZWZpbmVkKSB7IGNsb25lZExheW91dEl0ZW0uaXNSZXNpemFibGUgPSBsYXlvdXRJdGVtLmlzUmVzaXphYmxlO31cblxuICAgIHJldHVybiBjbG9uZWRMYXlvdXRJdGVtO1xufVxuXG4vKipcbiAqIEdpdmVuIHR3byBsYXlvdXRpdGVtcywgY2hlY2sgaWYgdGhleSBjb2xsaWRlLlxuICovXG5leHBvcnQgZnVuY3Rpb24gY29sbGlkZXMobDE6IExheW91dEl0ZW0sIGwyOiBMYXlvdXRJdGVtKTogYm9vbGVhbiB7XG4gICAgaWYgKGwxLmlkID09PSBsMi5pZCkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfSAvLyBzYW1lIGVsZW1lbnRcbiAgICBpZiAobDEueCArIGwxLncgPD0gbDIueCkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfSAvLyBsMSBpcyBsZWZ0IG9mIGwyXG4gICAgaWYgKGwxLnggPj0gbDIueCArIGwyLncpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH0gLy8gbDEgaXMgcmlnaHQgb2YgbDJcbiAgICBpZiAobDEueSArIGwxLmggPD0gbDIueSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfSAvLyBsMSBpcyBhYm92ZSBsMlxuICAgIGlmIChsMS55ID49IGwyLnkgKyBsMi5oKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9IC8vIGwxIGlzIGJlbG93IGwyXG4gICAgcmV0dXJuIHRydWU7IC8vIGJveGVzIG92ZXJsYXBcbn1cblxuLyoqXG4gKiBHaXZlbiBhIGxheW91dCwgY29tcGFjdCBpdC4gVGhpcyBpbnZvbHZlcyBnb2luZyBkb3duIGVhY2ggeSBjb29yZGluYXRlIGFuZCByZW1vdmluZyBnYXBzXG4gKiBiZXR3ZWVuIGl0ZW1zLlxuICpcbiAqIEBwYXJhbSAge0FycmF5fSBsYXlvdXQgTGF5b3V0LlxuICogQHBhcmFtICB7Qm9vbGVhbn0gdmVydGljYWxDb21wYWN0IFdoZXRoZXIgb3Igbm90IHRvIGNvbXBhY3QgdGhlIGxheW91dFxuICogICB2ZXJ0aWNhbGx5LlxuICogQHJldHVybiB7QXJyYXl9ICAgICAgIENvbXBhY3RlZCBMYXlvdXQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjb21wYWN0KFxuICAgIGxheW91dDogTGF5b3V0LFxuICAgIGNvbXBhY3RUeXBlOiBDb21wYWN0VHlwZSxcbiAgICBjb2xzOiBudW1iZXIsXG4pOiBMYXlvdXQge1xuICAgIC8vIFN0YXRpY3MgZ28gaW4gdGhlIGNvbXBhcmVXaXRoIGFycmF5IHJpZ2h0IGF3YXkgc28gaXRlbXMgZmxvdyBhcm91bmQgdGhlbS5cbiAgICBjb25zdCBjb21wYXJlV2l0aCA9IGdldFN0YXRpY3MobGF5b3V0KTtcbiAgICAvLyBXZSBnbyB0aHJvdWdoIHRoZSBpdGVtcyBieSByb3cgYW5kIGNvbHVtbi5cbiAgICBjb25zdCBzb3J0ZWQgPSBzb3J0TGF5b3V0SXRlbXMobGF5b3V0LCBjb21wYWN0VHlwZSk7XG4gICAgLy8gSG9sZGluZyBmb3IgbmV3IGl0ZW1zLlxuICAgIGNvbnN0IG91dCA9IEFycmF5KGxheW91dC5sZW5ndGgpO1xuXG4gICAgZm9yIChsZXQgaSA9IDAsIGxlbiA9IHNvcnRlZC5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xuICAgICAgICBsZXQgbCA9IGNsb25lTGF5b3V0SXRlbShzb3J0ZWRbaV0pO1xuXG4gICAgICAgIC8vIERvbid0IG1vdmUgc3RhdGljIGVsZW1lbnRzXG4gICAgICAgIGlmICghbC5zdGF0aWMpIHtcbiAgICAgICAgICAgIGwgPSBjb21wYWN0SXRlbShjb21wYXJlV2l0aCwgbCwgY29tcGFjdFR5cGUsIGNvbHMsIHNvcnRlZCk7XG5cbiAgICAgICAgICAgIC8vIEFkZCB0byBjb21wYXJpc29uIGFycmF5LiBXZSBvbmx5IGNvbGxpZGUgd2l0aCBpdGVtcyBiZWZvcmUgdGhpcyBvbmUuXG4gICAgICAgICAgICAvLyBTdGF0aWNzIGFyZSBhbHJlYWR5IGluIHRoaXMgYXJyYXkuXG4gICAgICAgICAgICBjb21wYXJlV2l0aC5wdXNoKGwpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gQWRkIHRvIG91dHB1dCBhcnJheSB0byBtYWtlIHN1cmUgdGhleSBzdGlsbCBjb21lIG91dCBpbiB0aGUgcmlnaHQgb3JkZXIuXG4gICAgICAgIG91dFtsYXlvdXQuaW5kZXhPZihzb3J0ZWRbaV0pXSA9IGw7XG5cbiAgICAgICAgLy8gQ2xlYXIgbW92ZWQgZmxhZywgaWYgaXQgZXhpc3RzLlxuICAgICAgICBsLm1vdmVkID0gZmFsc2U7XG4gICAgfVxuXG4gICAgcmV0dXJuIG91dDtcbn1cblxuY29uc3QgaGVpZ2h0V2lkdGggPSB7eDogJ3cnLCB5OiAnaCd9O1xuXG4vKipcbiAqIEJlZm9yZSBtb3ZpbmcgaXRlbSBkb3duLCBpdCB3aWxsIGNoZWNrIGlmIHRoZSBtb3ZlbWVudCB3aWxsIGNhdXNlIGNvbGxpc2lvbnMgYW5kIG1vdmUgdGhvc2UgaXRlbXMgZG93biBiZWZvcmUuXG4gKi9cbmZ1bmN0aW9uIHJlc29sdmVDb21wYWN0aW9uQ29sbGlzaW9uKFxuICAgIGxheW91dDogTGF5b3V0LFxuICAgIGl0ZW06IExheW91dEl0ZW0sXG4gICAgbW92ZVRvQ29vcmQ6IG51bWJlcixcbiAgICBheGlzOiAneCcgfCAneScsXG4pIHtcbiAgICBjb25zdCBzaXplUHJvcCA9IGhlaWdodFdpZHRoW2F4aXNdO1xuICAgIGl0ZW1bYXhpc10gKz0gMTtcbiAgICBjb25zdCBpdGVtSW5kZXggPSBsYXlvdXRcbiAgICAgICAgLm1hcChsYXlvdXRJdGVtID0+IHtcbiAgICAgICAgICAgIHJldHVybiBsYXlvdXRJdGVtLmlkO1xuICAgICAgICB9KVxuICAgICAgICAuaW5kZXhPZihpdGVtLmlkKTtcblxuICAgIC8vIEdvIHRocm91Z2ggZWFjaCBpdGVtIHdlIGNvbGxpZGUgd2l0aC5cbiAgICBmb3IgKGxldCBpID0gaXRlbUluZGV4ICsgMTsgaSA8IGxheW91dC5sZW5ndGg7IGkrKykge1xuICAgICAgICBjb25zdCBvdGhlckl0ZW0gPSBsYXlvdXRbaV07XG4gICAgICAgIC8vIElnbm9yZSBzdGF0aWMgaXRlbXNcbiAgICAgICAgaWYgKG90aGVySXRlbS5zdGF0aWMpIHtcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gT3B0aW1pemF0aW9uOiB3ZSBjYW4gYnJlYWsgZWFybHkgaWYgd2Uga25vdyB3ZSdyZSBwYXN0IHRoaXMgZWxcbiAgICAgICAgLy8gV2UgY2FuIGRvIHRoaXMgYi9jIGl0J3MgYSBzb3J0ZWQgbGF5b3V0XG4gICAgICAgIGlmIChvdGhlckl0ZW0ueSA+IGl0ZW0ueSArIGl0ZW0uaCkge1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoY29sbGlkZXMoaXRlbSwgb3RoZXJJdGVtKSkge1xuICAgICAgICAgICAgcmVzb2x2ZUNvbXBhY3Rpb25Db2xsaXNpb24oXG4gICAgICAgICAgICAgICAgbGF5b3V0LFxuICAgICAgICAgICAgICAgIG90aGVySXRlbSxcbiAgICAgICAgICAgICAgICBtb3ZlVG9Db29yZCArIGl0ZW1bc2l6ZVByb3BdLFxuICAgICAgICAgICAgICAgIGF4aXMsXG4gICAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgaXRlbVtheGlzXSA9IG1vdmVUb0Nvb3JkO1xufVxuXG4vKipcbiAqIENvbXBhY3QgYW4gaXRlbSBpbiB0aGUgbGF5b3V0LlxuICovXG5leHBvcnQgZnVuY3Rpb24gY29tcGFjdEl0ZW0oXG4gICAgY29tcGFyZVdpdGg6IExheW91dCxcbiAgICBsOiBMYXlvdXRJdGVtLFxuICAgIGNvbXBhY3RUeXBlOiBDb21wYWN0VHlwZSxcbiAgICBjb2xzOiBudW1iZXIsXG4gICAgZnVsbExheW91dDogTGF5b3V0LFxuKTogTGF5b3V0SXRlbSB7XG4gICAgY29uc3QgY29tcGFjdFYgPSBjb21wYWN0VHlwZSA9PT0gJ3ZlcnRpY2FsJztcbiAgICBjb25zdCBjb21wYWN0SCA9IGNvbXBhY3RUeXBlID09PSAnaG9yaXpvbnRhbCc7XG4gICAgaWYgKGNvbXBhY3RWKSB7XG4gICAgICAgIC8vIEJvdHRvbSAneScgcG9zc2libGUgaXMgdGhlIGJvdHRvbSBvZiB0aGUgbGF5b3V0LlxuICAgICAgICAvLyBUaGlzIGFsbG93cyB5b3UgdG8gZG8gbmljZSBzdHVmZiBsaWtlIHNwZWNpZnkge3k6IEluZmluaXR5fVxuICAgICAgICAvLyBUaGlzIGlzIGhlcmUgYmVjYXVzZSB0aGUgbGF5b3V0IG11c3QgYmUgc29ydGVkIGluIG9yZGVyIHRvIGdldCB0aGUgY29ycmVjdCBib3R0b20gYHlgLlxuICAgICAgICBsLnkgPSBNYXRoLm1pbihib3R0b20oY29tcGFyZVdpdGgpLCBsLnkpO1xuICAgICAgICAvLyBNb3ZlIHRoZSBlbGVtZW50IHVwIGFzIGZhciBhcyBpdCBjYW4gZ28gd2l0aG91dCBjb2xsaWRpbmcuXG4gICAgICAgIHdoaWxlIChsLnkgPiAwICYmICFnZXRGaXJzdENvbGxpc2lvbihjb21wYXJlV2l0aCwgbCkpIHtcbiAgICAgICAgICAgIGwueS0tO1xuICAgICAgICB9XG4gICAgfSBlbHNlIGlmIChjb21wYWN0SCkge1xuICAgICAgICAvLyBNb3ZlIHRoZSBlbGVtZW50IGxlZnQgYXMgZmFyIGFzIGl0IGNhbiBnbyB3aXRob3V0IGNvbGxpZGluZy5cbiAgICAgICAgd2hpbGUgKGwueCA+IDAgJiYgIWdldEZpcnN0Q29sbGlzaW9uKGNvbXBhcmVXaXRoLCBsKSkge1xuICAgICAgICAgICAgbC54LS07XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBNb3ZlIGl0IGRvd24sIGFuZCBrZWVwIG1vdmluZyBpdCBkb3duIGlmIGl0J3MgY29sbGlkaW5nLlxuICAgIGxldCBjb2xsaWRlcztcbiAgICB3aGlsZSAoKGNvbGxpZGVzID0gZ2V0Rmlyc3RDb2xsaXNpb24oY29tcGFyZVdpdGgsIGwpKSkge1xuICAgICAgICBpZiAoY29tcGFjdEgpIHtcbiAgICAgICAgICAgIHJlc29sdmVDb21wYWN0aW9uQ29sbGlzaW9uKGZ1bGxMYXlvdXQsIGwsIGNvbGxpZGVzLnggKyBjb2xsaWRlcy53LCAneCcpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmVzb2x2ZUNvbXBhY3Rpb25Db2xsaXNpb24oZnVsbExheW91dCwgbCwgY29sbGlkZXMueSArIGNvbGxpZGVzLmgsICd5JywpO1xuICAgICAgICB9XG4gICAgICAgIC8vIFNpbmNlIHdlIGNhbid0IGdyb3cgd2l0aG91dCBib3VuZHMgaG9yaXpvbnRhbGx5LCBpZiB3ZSd2ZSBvdmVyZmxvd24sIGxldCdzIG1vdmUgaXQgZG93biBhbmQgdHJ5IGFnYWluLlxuICAgICAgICBpZiAoY29tcGFjdEggJiYgbC54ICsgbC53ID4gY29scykge1xuICAgICAgICAgICAgbC54ID0gY29scyAtIGwudztcbiAgICAgICAgICAgIGwueSsrO1xuXG4gICAgICAgICAgICAvLyBBTHNvIG1vdmUgZWxlbWVudCBhcyBsZWZ0IGFzIG11Y2ggYXMgd2UgY2FuIChidXctY3VzdG9tLWNoYW5nZSlcbiAgICAgICAgICAgIHdoaWxlIChsLnggPiAwICYmICFnZXRGaXJzdENvbGxpc2lvbihjb21wYXJlV2l0aCwgbCkpIHtcbiAgICAgICAgICAgICAgICBsLngtLTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8vIEVuc3VyZSB0aGF0IHRoZXJlIGFyZSBubyBuZWdhdGl2ZSBwb3NpdGlvbnNcbiAgICBsLnkgPSBNYXRoLm1heChsLnksIDApO1xuICAgIGwueCA9IE1hdGgubWF4KGwueCwgMCk7XG5cbiAgICByZXR1cm4gbDtcbn1cblxuLyoqXG4gKiBHaXZlbiBhIGxheW91dCwgbWFrZSBzdXJlIGFsbCBlbGVtZW50cyBmaXQgd2l0aGluIGl0cyBib3VuZHMuXG4gKlxuICogQHBhcmFtICB7QXJyYXl9IGxheW91dCBMYXlvdXQgYXJyYXkuXG4gKiBAcGFyYW0gIHtOdW1iZXJ9IGJvdW5kcyBOdW1iZXIgb2YgY29sdW1ucy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNvcnJlY3RCb3VuZHMobGF5b3V0OiBMYXlvdXQsIGJvdW5kczogeyBjb2xzOiBudW1iZXIgfSk6IExheW91dCB7XG4gICAgY29uc3QgY29sbGlkZXNXaXRoID0gZ2V0U3RhdGljcyhsYXlvdXQpO1xuICAgIGZvciAobGV0IGkgPSAwLCBsZW4gPSBsYXlvdXQubGVuZ3RoOyBpIDwgbGVuOyBpKyspIHtcbiAgICAgICAgY29uc3QgbCA9IGxheW91dFtpXTtcbiAgICAgICAgLy8gT3ZlcmZsb3dzIHJpZ2h0XG4gICAgICAgIGlmIChsLnggKyBsLncgPiBib3VuZHMuY29scykge1xuICAgICAgICAgICAgbC54ID0gYm91bmRzLmNvbHMgLSBsLnc7XG4gICAgICAgIH1cbiAgICAgICAgLy8gT3ZlcmZsb3dzIGxlZnRcbiAgICAgICAgaWYgKGwueCA8IDApIHtcbiAgICAgICAgICAgIGwueCA9IDA7XG4gICAgICAgICAgICBsLncgPSBib3VuZHMuY29scztcbiAgICAgICAgfVxuICAgICAgICBpZiAoIWwuc3RhdGljKSB7XG4gICAgICAgICAgICBjb2xsaWRlc1dpdGgucHVzaChsKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIC8vIElmIHRoaXMgaXMgc3RhdGljIGFuZCBjb2xsaWRlcyB3aXRoIG90aGVyIHN0YXRpY3MsIHdlIG11c3QgbW92ZSBpdCBkb3duLlxuICAgICAgICAgICAgLy8gV2UgaGF2ZSB0byBkbyBzb21ldGhpbmcgbmljZXIgdGhhbiBqdXN0IGxldHRpbmcgdGhlbSBvdmVybGFwLlxuICAgICAgICAgICAgd2hpbGUgKGdldEZpcnN0Q29sbGlzaW9uKGNvbGxpZGVzV2l0aCwgbCkpIHtcbiAgICAgICAgICAgICAgICBsLnkrKztcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gbGF5b3V0O1xufVxuXG4vKipcbiAqIEdldCBhIGxheW91dCBpdGVtIGJ5IElELiBVc2VkIHNvIHdlIGNhbiBvdmVycmlkZSBsYXRlciBvbiBpZiBuZWNlc3NhcnkuXG4gKlxuICogQHBhcmFtICB7QXJyYXl9ICBsYXlvdXQgTGF5b3V0IGFycmF5LlxuICogQHBhcmFtICB7U3RyaW5nfSBpZCAgICAgSURcbiAqIEByZXR1cm4ge0xheW91dEl0ZW19ICAgIEl0ZW0gYXQgSUQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRMYXlvdXRJdGVtKFxuICAgIGxheW91dDogTGF5b3V0LFxuICAgIGlkOiBzdHJpbmcsXG4pOiBMYXlvdXRJdGVtIHwgbnVsbCB8IHVuZGVmaW5lZCB7XG4gICAgZm9yIChsZXQgaSA9IDAsIGxlbiA9IGxheW91dC5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xuICAgICAgICBpZiAobGF5b3V0W2ldLmlkID09PSBpZCkge1xuICAgICAgICAgICAgcmV0dXJuIGxheW91dFtpXTtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gbnVsbDtcbn1cblxuLyoqXG4gKiBSZXR1cm5zIHRoZSBmaXJzdCBpdGVtIHRoaXMgbGF5b3V0IGNvbGxpZGVzIHdpdGguXG4gKiBJdCBkb2Vzbid0IGFwcGVhciB0byBtYXR0ZXIgd2hpY2ggb3JkZXIgd2UgYXBwcm9hY2ggdGhpcyBmcm9tLCBhbHRob3VnaFxuICogcGVyaGFwcyB0aGF0IGlzIHRoZSB3cm9uZyB0aGluZyB0byBkby5cbiAqXG4gKiBAcGFyYW0gIHtPYmplY3R9IGxheW91dEl0ZW0gTGF5b3V0IGl0ZW0uXG4gKiBAcmV0dXJuIHtPYmplY3R8dW5kZWZpbmVkfSAgQSBjb2xsaWRpbmcgbGF5b3V0IGl0ZW0sIG9yIHVuZGVmaW5lZC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldEZpcnN0Q29sbGlzaW9uKFxuICAgIGxheW91dDogTGF5b3V0LFxuICAgIGxheW91dEl0ZW06IExheW91dEl0ZW0sXG4pOiBMYXlvdXRJdGVtIHwgbnVsbCB8IHVuZGVmaW5lZCB7XG4gICAgZm9yIChsZXQgaSA9IDAsIGxlbiA9IGxheW91dC5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xuICAgICAgICBpZiAoY29sbGlkZXMobGF5b3V0W2ldLCBsYXlvdXRJdGVtKSkge1xuICAgICAgICAgICAgcmV0dXJuIGxheW91dFtpXTtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gbnVsbDtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldEFsbENvbGxpc2lvbnMoXG4gICAgbGF5b3V0OiBMYXlvdXQsXG4gICAgbGF5b3V0SXRlbTogTGF5b3V0SXRlbSxcbik6IEFycmF5PExheW91dEl0ZW0+IHtcbiAgICByZXR1cm4gbGF5b3V0LmZpbHRlcihsID0+IGNvbGxpZGVzKGwsIGxheW91dEl0ZW0pKTtcbn1cblxuLyoqXG4gKiBHZXQgYWxsIHN0YXRpYyBlbGVtZW50cy5cbiAqIEBwYXJhbSAge0FycmF5fSBsYXlvdXQgQXJyYXkgb2YgbGF5b3V0IG9iamVjdHMuXG4gKiBAcmV0dXJuIHtBcnJheX0gICAgICAgIEFycmF5IG9mIHN0YXRpYyBsYXlvdXQgaXRlbXMuLlxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0U3RhdGljcyhsYXlvdXQ6IExheW91dCk6IEFycmF5PExheW91dEl0ZW0+IHtcbiAgICByZXR1cm4gbGF5b3V0LmZpbHRlcihsID0+IGwuc3RhdGljKTtcbn1cblxuLyoqXG4gKiBNb3ZlIGFuIGVsZW1lbnQuIFJlc3BvbnNpYmxlIGZvciBkb2luZyBjYXNjYWRpbmcgbW92ZW1lbnRzIG9mIG90aGVyIGVsZW1lbnRzLlxuICpcbiAqIEBwYXJhbSAge0FycmF5fSAgICAgIGxheW91dCAgICAgICAgICAgIEZ1bGwgbGF5b3V0IHRvIG1vZGlmeS5cbiAqIEBwYXJhbSAge0xheW91dEl0ZW19IGwgICAgICAgICAgICAgICAgIGVsZW1lbnQgdG8gbW92ZS5cbiAqIEBwYXJhbSAge051bWJlcn0gICAgIFt4XSAgICAgICAgICAgICAgIFggcG9zaXRpb24gaW4gZ3JpZCB1bml0cy5cbiAqIEBwYXJhbSAge051bWJlcn0gICAgIFt5XSAgICAgICAgICAgICAgIFkgcG9zaXRpb24gaW4gZ3JpZCB1bml0cy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG1vdmVFbGVtZW50KFxuICAgIGxheW91dDogTGF5b3V0LFxuICAgIGw6IExheW91dEl0ZW0sXG4gICAgeDogbnVtYmVyIHwgbnVsbCB8IHVuZGVmaW5lZCxcbiAgICB5OiBudW1iZXIgfCBudWxsIHwgdW5kZWZpbmVkLFxuICAgIGlzVXNlckFjdGlvbjogYm9vbGVhbiB8IG51bGwgfCB1bmRlZmluZWQsXG4gICAgcHJldmVudENvbGxpc2lvbjogYm9vbGVhbiB8IG51bGwgfCB1bmRlZmluZWQsXG4gICAgY29tcGFjdFR5cGU6IENvbXBhY3RUeXBlLFxuICAgIGNvbHM6IG51bWJlcixcbik6IExheW91dCB7XG4gICAgLy8gSWYgdGhpcyBpcyBzdGF0aWMgYW5kIG5vdCBleHBsaWNpdGx5IGVuYWJsZWQgYXMgZHJhZ2dhYmxlLFxuICAgIC8vIG5vIG1vdmUgaXMgcG9zc2libGUsIHNvIHdlIGNhbiBzaG9ydC1jaXJjdWl0IHRoaXMgaW1tZWRpYXRlbHkuXG4gICAgaWYgKGwuc3RhdGljICYmIGwuaXNEcmFnZ2FibGUgIT09IHRydWUpIHtcbiAgICAgICAgcmV0dXJuIGxheW91dDtcbiAgICB9XG5cbiAgICAvLyBTaG9ydC1jaXJjdWl0IGlmIG5vdGhpbmcgdG8gZG8uXG4gICAgaWYgKGwueSA9PT0geSAmJiBsLnggPT09IHgpIHtcbiAgICAgICAgcmV0dXJuIGxheW91dDtcbiAgICB9XG5cbiAgICBsb2coXG4gICAgICAgIGBNb3ZpbmcgZWxlbWVudCAke2wuaWR9IHRvIFske1N0cmluZyh4KX0sJHtTdHJpbmcoeSl9XSBmcm9tIFske2wueH0sJHtcbiAgICAgICAgICAgIGwueVxuICAgICAgICB9XWAsXG4gICAgKTtcbiAgICBjb25zdCBvbGRYID0gbC54O1xuICAgIGNvbnN0IG9sZFkgPSBsLnk7XG5cbiAgICAvLyBUaGlzIGlzIHF1aXRlIGEgYml0IGZhc3RlciB0aGFuIGV4dGVuZGluZyB0aGUgb2JqZWN0XG4gICAgaWYgKHR5cGVvZiB4ID09PSAnbnVtYmVyJykge1xuICAgICAgICBsLnggPSB4O1xuICAgIH1cbiAgICBpZiAodHlwZW9mIHkgPT09ICdudW1iZXInKSB7XG4gICAgICAgIGwueSA9IHk7XG4gICAgfVxuICAgIGwubW92ZWQgPSB0cnVlO1xuXG4gICAgLy8gSWYgdGhpcyBjb2xsaWRlcyB3aXRoIGFueXRoaW5nLCBtb3ZlIGl0LlxuICAgIC8vIFdoZW4gZG9pbmcgdGhpcyBjb21wYXJpc29uLCB3ZSBoYXZlIHRvIHNvcnQgdGhlIGl0ZW1zIHdlIGNvbXBhcmUgd2l0aFxuICAgIC8vIHRvIGVuc3VyZSwgaW4gdGhlIGNhc2Ugb2YgbXVsdGlwbGUgY29sbGlzaW9ucywgdGhhdCB3ZSdyZSBnZXR0aW5nIHRoZVxuICAgIC8vIG5lYXJlc3QgY29sbGlzaW9uLlxuICAgIGxldCBzb3J0ZWQgPSBzb3J0TGF5b3V0SXRlbXMobGF5b3V0LCBjb21wYWN0VHlwZSk7XG4gICAgY29uc3QgbW92aW5nVXAgPVxuICAgICAgICBjb21wYWN0VHlwZSA9PT0gJ3ZlcnRpY2FsJyAmJiB0eXBlb2YgeSA9PT0gJ251bWJlcidcbiAgICAgICAgICAgID8gb2xkWSA+PSB5XG4gICAgICAgICAgICA6IGNvbXBhY3RUeXBlID09PSAnaG9yaXpvbnRhbCcgJiYgdHlwZW9mIHggPT09ICdudW1iZXInXG4gICAgICAgICAgICAgICAgPyBvbGRYID49IHhcbiAgICAgICAgICAgICAgICA6IGZhbHNlO1xuICAgIGlmIChtb3ZpbmdVcCkge1xuICAgICAgICBzb3J0ZWQgPSBzb3J0ZWQucmV2ZXJzZSgpO1xuICAgIH1cbiAgICBjb25zdCBjb2xsaXNpb25zID0gZ2V0QWxsQ29sbGlzaW9ucyhzb3J0ZWQsIGwpO1xuXG4gICAgLy8gVGhlcmUgd2FzIGEgY29sbGlzaW9uOyBhYm9ydFxuICAgIGlmIChwcmV2ZW50Q29sbGlzaW9uICYmIGNvbGxpc2lvbnMubGVuZ3RoKSB7XG4gICAgICAgIGxvZyhgQ29sbGlzaW9uIHByZXZlbnRlZCBvbiAke2wuaWR9LCByZXZlcnRpbmcuYCk7XG4gICAgICAgIGwueCA9IG9sZFg7XG4gICAgICAgIGwueSA9IG9sZFk7XG4gICAgICAgIGwubW92ZWQgPSBmYWxzZTtcbiAgICAgICAgcmV0dXJuIGxheW91dDtcbiAgICB9XG5cbiAgICAvLyBNb3ZlIGVhY2ggaXRlbSB0aGF0IGNvbGxpZGVzIGF3YXkgZnJvbSB0aGlzIGVsZW1lbnQuXG4gICAgZm9yIChsZXQgaSA9IDAsIGxlbiA9IGNvbGxpc2lvbnMubGVuZ3RoOyBpIDwgbGVuOyBpKyspIHtcbiAgICAgICAgY29uc3QgY29sbGlzaW9uID0gY29sbGlzaW9uc1tpXTtcbiAgICAgICAgbG9nKFxuICAgICAgICAgICAgYFJlc29sdmluZyBjb2xsaXNpb24gYmV0d2VlbiAke2wuaWR9IGF0IFske2wueH0sJHtsLnl9XSBhbmQgJHtcbiAgICAgICAgICAgICAgICBjb2xsaXNpb24uaWRcbiAgICAgICAgICAgIH0gYXQgWyR7Y29sbGlzaW9uLnh9LCR7Y29sbGlzaW9uLnl9XWAsXG4gICAgICAgICk7XG5cbiAgICAgICAgLy8gU2hvcnQgY2lyY3VpdCBzbyB3ZSBjYW4ndCBpbmZpbml0ZSBsb29wXG4gICAgICAgIGlmIChjb2xsaXNpb24ubW92ZWQpIHtcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gRG9uJ3QgbW92ZSBzdGF0aWMgaXRlbXMgLSB3ZSBoYXZlIHRvIG1vdmUgKnRoaXMqIGVsZW1lbnQgYXdheVxuICAgICAgICBpZiAoY29sbGlzaW9uLnN0YXRpYykge1xuICAgICAgICAgICAgbGF5b3V0ID0gbW92ZUVsZW1lbnRBd2F5RnJvbUNvbGxpc2lvbihcbiAgICAgICAgICAgICAgICBsYXlvdXQsXG4gICAgICAgICAgICAgICAgY29sbGlzaW9uLFxuICAgICAgICAgICAgICAgIGwsXG4gICAgICAgICAgICAgICAgaXNVc2VyQWN0aW9uLFxuICAgICAgICAgICAgICAgIGNvbXBhY3RUeXBlLFxuICAgICAgICAgICAgICAgIGNvbHMsXG4gICAgICAgICAgICApO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgbGF5b3V0ID0gbW92ZUVsZW1lbnRBd2F5RnJvbUNvbGxpc2lvbihcbiAgICAgICAgICAgICAgICBsYXlvdXQsXG4gICAgICAgICAgICAgICAgbCxcbiAgICAgICAgICAgICAgICBjb2xsaXNpb24sXG4gICAgICAgICAgICAgICAgaXNVc2VyQWN0aW9uLFxuICAgICAgICAgICAgICAgIGNvbXBhY3RUeXBlLFxuICAgICAgICAgICAgICAgIGNvbHMsXG4gICAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIGxheW91dDtcbn1cblxuLyoqXG4gKiBUaGlzIGlzIHdoZXJlIHRoZSBtYWdpYyBuZWVkcyB0byBoYXBwZW4gLSBnaXZlbiBhIGNvbGxpc2lvbiwgbW92ZSBhbiBlbGVtZW50IGF3YXkgZnJvbSB0aGUgY29sbGlzaW9uLlxuICogV2UgYXR0ZW1wdCB0byBtb3ZlIGl0IHVwIGlmIHRoZXJlJ3Mgcm9vbSwgb3RoZXJ3aXNlIGl0IGdvZXMgYmVsb3cuXG4gKlxuICogQHBhcmFtICB7QXJyYXl9IGxheW91dCAgICAgICAgICAgIEZ1bGwgbGF5b3V0IHRvIG1vZGlmeS5cbiAqIEBwYXJhbSAge0xheW91dEl0ZW19IGNvbGxpZGVzV2l0aCBMYXlvdXQgaXRlbSB3ZSdyZSBjb2xsaWRpbmcgd2l0aC5cbiAqIEBwYXJhbSAge0xheW91dEl0ZW19IGl0ZW1Ub01vdmUgICBMYXlvdXQgaXRlbSB3ZSdyZSBtb3ZpbmcuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBtb3ZlRWxlbWVudEF3YXlGcm9tQ29sbGlzaW9uKFxuICAgIGxheW91dDogTGF5b3V0LFxuICAgIGNvbGxpZGVzV2l0aDogTGF5b3V0SXRlbSxcbiAgICBpdGVtVG9Nb3ZlOiBMYXlvdXRJdGVtLFxuICAgIGlzVXNlckFjdGlvbjogYm9vbGVhbiB8IG51bGwgfCB1bmRlZmluZWQsXG4gICAgY29tcGFjdFR5cGU6IENvbXBhY3RUeXBlLFxuICAgIGNvbHM6IG51bWJlcixcbik6IExheW91dCB7XG4gICAgY29uc3QgY29tcGFjdEggPSBjb21wYWN0VHlwZSA9PT0gJ2hvcml6b250YWwnO1xuICAgIC8vIENvbXBhY3QgdmVydGljYWxseSBpZiBub3Qgc2V0IHRvIGhvcml6b250YWxcbiAgICBjb25zdCBjb21wYWN0ViA9IGNvbXBhY3RUeXBlICE9PSAnaG9yaXpvbnRhbCc7XG4gICAgY29uc3QgcHJldmVudENvbGxpc2lvbiA9IGNvbGxpZGVzV2l0aC5zdGF0aWM7IC8vIHdlJ3JlIGFscmVhZHkgY29sbGlkaW5nIChub3QgZm9yIHN0YXRpYyBpdGVtcylcblxuICAgIC8vIElmIHRoZXJlIGlzIGVub3VnaCBzcGFjZSBhYm92ZSB0aGUgY29sbGlzaW9uIHRvIHB1dCB0aGlzIGVsZW1lbnQsIG1vdmUgaXQgdGhlcmUuXG4gICAgLy8gV2Ugb25seSBkbyB0aGlzIG9uIHRoZSBtYWluIGNvbGxpc2lvbiBhcyB0aGlzIGNhbiBnZXQgZnVua3kgaW4gY2FzY2FkZXMgYW5kIGNhdXNlXG4gICAgLy8gdW53YW50ZWQgc3dhcHBpbmcgYmVoYXZpb3IuXG4gICAgaWYgKGlzVXNlckFjdGlvbikge1xuICAgICAgICAvLyBSZXNldCBpc1VzZXJBY3Rpb24gZmxhZyBiZWNhdXNlIHdlJ3JlIG5vdCBpbiB0aGUgbWFpbiBjb2xsaXNpb24gYW55bW9yZS5cbiAgICAgICAgaXNVc2VyQWN0aW9uID0gZmFsc2U7XG5cbiAgICAgICAgLy8gTWFrZSBhIG1vY2sgaXRlbSBzbyB3ZSBkb24ndCBtb2RpZnkgdGhlIGl0ZW0gaGVyZSwgb25seSBtb2RpZnkgaW4gbW92ZUVsZW1lbnQuXG4gICAgICAgIGNvbnN0IGZha2VJdGVtOiBMYXlvdXRJdGVtID0ge1xuICAgICAgICAgICAgeDogY29tcGFjdEhcbiAgICAgICAgICAgICAgICA/IE1hdGgubWF4KGNvbGxpZGVzV2l0aC54IC0gaXRlbVRvTW92ZS53LCAwKVxuICAgICAgICAgICAgICAgIDogaXRlbVRvTW92ZS54LFxuICAgICAgICAgICAgeTogY29tcGFjdFZcbiAgICAgICAgICAgICAgICA/IE1hdGgubWF4KGNvbGxpZGVzV2l0aC55IC0gaXRlbVRvTW92ZS5oLCAwKVxuICAgICAgICAgICAgICAgIDogaXRlbVRvTW92ZS55LFxuICAgICAgICAgICAgdzogaXRlbVRvTW92ZS53LFxuICAgICAgICAgICAgaDogaXRlbVRvTW92ZS5oLFxuICAgICAgICAgICAgaWQ6ICctMScsXG4gICAgICAgIH07XG5cbiAgICAgICAgLy8gTm8gY29sbGlzaW9uPyBJZiBzbywgd2UgY2FuIGdvIHVwIHRoZXJlOyBvdGhlcndpc2UsIHdlJ2xsIGVuZCB1cCBtb3ZpbmcgZG93biBhcyBub3JtYWxcbiAgICAgICAgaWYgKCFnZXRGaXJzdENvbGxpc2lvbihsYXlvdXQsIGZha2VJdGVtKSkge1xuICAgICAgICAgICAgbG9nKFxuICAgICAgICAgICAgICAgIGBEb2luZyByZXZlcnNlIGNvbGxpc2lvbiBvbiAke2l0ZW1Ub01vdmUuaWR9IHVwIHRvIFske1xuICAgICAgICAgICAgICAgICAgICBmYWtlSXRlbS54XG4gICAgICAgICAgICAgICAgfSwke2Zha2VJdGVtLnl9XS5gLFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIHJldHVybiBtb3ZlRWxlbWVudChcbiAgICAgICAgICAgICAgICBsYXlvdXQsXG4gICAgICAgICAgICAgICAgaXRlbVRvTW92ZSxcbiAgICAgICAgICAgICAgICBjb21wYWN0SCA/IGZha2VJdGVtLnggOiB1bmRlZmluZWQsXG4gICAgICAgICAgICAgICAgY29tcGFjdFYgPyBmYWtlSXRlbS55IDogdW5kZWZpbmVkLFxuICAgICAgICAgICAgICAgIGlzVXNlckFjdGlvbixcbiAgICAgICAgICAgICAgICBwcmV2ZW50Q29sbGlzaW9uLFxuICAgICAgICAgICAgICAgIGNvbXBhY3RUeXBlLFxuICAgICAgICAgICAgICAgIGNvbHMsXG4gICAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIG1vdmVFbGVtZW50KFxuICAgICAgICBsYXlvdXQsXG4gICAgICAgIGl0ZW1Ub01vdmUsXG4gICAgICAgIGNvbXBhY3RIID8gaXRlbVRvTW92ZS54ICsgMSA6IHVuZGVmaW5lZCxcbiAgICAgICAgY29tcGFjdFYgPyBpdGVtVG9Nb3ZlLnkgKyAxIDogdW5kZWZpbmVkLFxuICAgICAgICBpc1VzZXJBY3Rpb24sXG4gICAgICAgIHByZXZlbnRDb2xsaXNpb24sXG4gICAgICAgIGNvbXBhY3RUeXBlLFxuICAgICAgICBjb2xzLFxuICAgICk7XG59XG5cbi8qKlxuICogSGVscGVyIHRvIGNvbnZlcnQgYSBudW1iZXIgdG8gYSBwZXJjZW50YWdlIHN0cmluZy5cbiAqXG4gKiBAcGFyYW0gIHtOdW1iZXJ9IG51bSBBbnkgbnVtYmVyXG4gKiBAcmV0dXJuIHtTdHJpbmd9ICAgICBUaGF0IG51bWJlciBhcyBhIHBlcmNlbnRhZ2UuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBwZXJjKG51bTogbnVtYmVyKTogc3RyaW5nIHtcbiAgICByZXR1cm4gbnVtICogMTAwICsgJyUnO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gc2V0VHJhbnNmb3JtKHt0b3AsIGxlZnQsIHdpZHRoLCBoZWlnaHR9OiBQb3NpdGlvbik6IE9iamVjdCB7XG4gICAgLy8gUmVwbGFjZSB1bml0bGVzcyBpdGVtcyB3aXRoIHB4XG4gICAgY29uc3QgdHJhbnNsYXRlID0gYHRyYW5zbGF0ZSgke2xlZnR9cHgsJHt0b3B9cHgpYDtcbiAgICByZXR1cm4ge1xuICAgICAgICB0cmFuc2Zvcm06IHRyYW5zbGF0ZSxcbiAgICAgICAgV2Via2l0VHJhbnNmb3JtOiB0cmFuc2xhdGUsXG4gICAgICAgIE1velRyYW5zZm9ybTogdHJhbnNsYXRlLFxuICAgICAgICBtc1RyYW5zZm9ybTogdHJhbnNsYXRlLFxuICAgICAgICBPVHJhbnNmb3JtOiB0cmFuc2xhdGUsXG4gICAgICAgIHdpZHRoOiBgJHt3aWR0aH1weGAsXG4gICAgICAgIGhlaWdodDogYCR7aGVpZ2h0fXB4YCxcbiAgICAgICAgcG9zaXRpb246ICdhYnNvbHV0ZScsXG4gICAgfTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHNldFRvcExlZnQoe3RvcCwgbGVmdCwgd2lkdGgsIGhlaWdodH06IFBvc2l0aW9uKTogT2JqZWN0IHtcbiAgICByZXR1cm4ge1xuICAgICAgICB0b3A6IGAke3RvcH1weGAsXG4gICAgICAgIGxlZnQ6IGAke2xlZnR9cHhgLFxuICAgICAgICB3aWR0aDogYCR7d2lkdGh9cHhgLFxuICAgICAgICBoZWlnaHQ6IGAke2hlaWdodH1weGAsXG4gICAgICAgIHBvc2l0aW9uOiAnYWJzb2x1dGUnLFxuICAgIH07XG59XG5cbi8qKlxuICogR2V0IGxheW91dCBpdGVtcyBzb3J0ZWQgZnJvbSB0b3AgbGVmdCB0byByaWdodCBhbmQgZG93bi5cbiAqXG4gKiBAcmV0dXJuIHtBcnJheX0gQXJyYXkgb2YgbGF5b3V0IG9iamVjdHMuXG4gKiBAcmV0dXJuIHtBcnJheX0gICAgICAgIExheW91dCwgc29ydGVkIHN0YXRpYyBpdGVtcyBmaXJzdC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHNvcnRMYXlvdXRJdGVtcyhcbiAgICBsYXlvdXQ6IExheW91dCxcbiAgICBjb21wYWN0VHlwZTogQ29tcGFjdFR5cGUsXG4pOiBMYXlvdXQge1xuICAgIGlmIChjb21wYWN0VHlwZSA9PT0gJ2hvcml6b250YWwnKSB7XG4gICAgICAgIHJldHVybiBzb3J0TGF5b3V0SXRlbXNCeUNvbFJvdyhsYXlvdXQpO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBzb3J0TGF5b3V0SXRlbXNCeVJvd0NvbChsYXlvdXQpO1xuICAgIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHNvcnRMYXlvdXRJdGVtc0J5Um93Q29sKGxheW91dDogTGF5b3V0KTogTGF5b3V0IHtcbiAgICByZXR1cm4gKFtdIGFzIGFueVtdKS5jb25jYXQobGF5b3V0KS5zb3J0KGZ1bmN0aW9uKGEsIGIpIHtcbiAgICAgICAgaWYgKGEueSA+IGIueSB8fCAoYS55ID09PSBiLnkgJiYgYS54ID4gYi54KSkge1xuICAgICAgICAgICAgcmV0dXJuIDE7XG4gICAgICAgIH0gZWxzZSBpZiAoYS55ID09PSBiLnkgJiYgYS54ID09PSBiLngpIHtcbiAgICAgICAgICAgIC8vIFdpdGhvdXQgdGhpcywgd2UgY2FuIGdldCBkaWZmZXJlbnQgc29ydCByZXN1bHRzIGluIElFIHZzLiBDaHJvbWUvRkZcbiAgICAgICAgICAgIHJldHVybiAwO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiAtMTtcbiAgICB9KTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHNvcnRMYXlvdXRJdGVtc0J5Q29sUm93KGxheW91dDogTGF5b3V0KTogTGF5b3V0IHtcbiAgICByZXR1cm4gKFtdIGFzIGFueVtdKS5jb25jYXQobGF5b3V0KS5zb3J0KGZ1bmN0aW9uKGEsIGIpIHtcbiAgICAgICAgaWYgKGEueCA+IGIueCB8fCAoYS54ID09PSBiLnggJiYgYS55ID4gYi55KSkge1xuICAgICAgICAgICAgcmV0dXJuIDE7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIC0xO1xuICAgIH0pO1xufVxuXG4vKipcbiAqIFZhbGlkYXRlIGEgbGF5b3V0LiBUaHJvd3MgZXJyb3JzLlxuICpcbiAqIEBwYXJhbSAge0FycmF5fSAgbGF5b3V0ICAgICAgICBBcnJheSBvZiBsYXlvdXQgaXRlbXMuXG4gKiBAcGFyYW0gIHtTdHJpbmd9IFtjb250ZXh0TmFtZV0gQ29udGV4dCBuYW1lIGZvciBlcnJvcnMuXG4gKiBAdGhyb3cgIHtFcnJvcn0gICAgICAgICAgICAgICAgVmFsaWRhdGlvbiBlcnJvci5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHZhbGlkYXRlTGF5b3V0KFxuICAgIGxheW91dDogTGF5b3V0LFxuICAgIGNvbnRleHROYW1lOiBzdHJpbmcgPSAnTGF5b3V0Jyxcbik6IHZvaWQge1xuICAgIGNvbnN0IHN1YlByb3BzID0gWyd4JywgJ3knLCAndycsICdoJ107XG4gICAgaWYgKCFBcnJheS5pc0FycmF5KGxheW91dCkpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGNvbnRleHROYW1lICsgJyBtdXN0IGJlIGFuIGFycmF5IScpO1xuICAgIH1cbiAgICBmb3IgKGxldCBpID0gMCwgbGVuID0gbGF5b3V0Lmxlbmd0aDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgICAgIGNvbnN0IGl0ZW0gPSBsYXlvdXRbaV07XG4gICAgICAgIGZvciAobGV0IGogPSAwOyBqIDwgc3ViUHJvcHMubGVuZ3RoOyBqKyspIHtcbiAgICAgICAgICAgIGlmICh0eXBlb2YgaXRlbVtzdWJQcm9wc1tqXV0gIT09ICdudW1iZXInKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAgICAgICAgICAgICAnUmVhY3RHcmlkTGF5b3V0OiAnICtcbiAgICAgICAgICAgICAgICAgICAgY29udGV4dE5hbWUgK1xuICAgICAgICAgICAgICAgICAgICAnWycgK1xuICAgICAgICAgICAgICAgICAgICBpICtcbiAgICAgICAgICAgICAgICAgICAgJ10uJyArXG4gICAgICAgICAgICAgICAgICAgIHN1YlByb3BzW2pdICtcbiAgICAgICAgICAgICAgICAgICAgJyBtdXN0IGJlIGEgbnVtYmVyIScsXG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAoaXRlbS5pZCAmJiB0eXBlb2YgaXRlbS5pZCAhPT0gJ3N0cmluZycpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgICAgICAgICAnUmVhY3RHcmlkTGF5b3V0OiAnICtcbiAgICAgICAgICAgICAgICBjb250ZXh0TmFtZSArXG4gICAgICAgICAgICAgICAgJ1snICtcbiAgICAgICAgICAgICAgICBpICtcbiAgICAgICAgICAgICAgICAnXS5pIG11c3QgYmUgYSBzdHJpbmchJyxcbiAgICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGl0ZW0uc3RhdGljICE9PSB1bmRlZmluZWQgJiYgdHlwZW9mIGl0ZW0uc3RhdGljICE9PSAnYm9vbGVhbicpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgICAgICAgICAnUmVhY3RHcmlkTGF5b3V0OiAnICtcbiAgICAgICAgICAgICAgICBjb250ZXh0TmFtZSArXG4gICAgICAgICAgICAgICAgJ1snICtcbiAgICAgICAgICAgICAgICBpICtcbiAgICAgICAgICAgICAgICAnXS5zdGF0aWMgbXVzdCBiZSBhIGJvb2xlYW4hJyxcbiAgICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICB9XG59XG5cbi8vIEZsb3cgY2FuJ3QgcmVhbGx5IGZpZ3VyZSB0aGlzIG91dCwgc28gd2UganVzdCB1c2UgT2JqZWN0XG5leHBvcnQgZnVuY3Rpb24gYXV0b0JpbmRIYW5kbGVycyhlbDogT2JqZWN0LCBmbnM6IEFycmF5PHN0cmluZz4pOiB2b2lkIHtcbiAgICBmbnMuZm9yRWFjaChrZXkgPT4gKGVsW2tleV0gPSBlbFtrZXldLmJpbmQoZWwpKSk7XG59XG5cbmZ1bmN0aW9uIGxvZyguLi5hcmdzKSB7XG4gICAgaWYgKCFERUJVRykge1xuICAgICAgICByZXR1cm47XG4gICAgfVxuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1jb25zb2xlXG4gICAgY29uc29sZS5sb2coLi4uYXJncyk7XG59XG5cbmV4cG9ydCBjb25zdCBub29wID0gKCkgPT4ge307XG4iXX0=
|