mtrl-addons 0.5.6 → 0.7.0

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.
@@ -429,6 +429,13 @@ export interface ListAPI<T extends ListItem = ListItem> {
429
429
  * @returns Set of pending removal IDs
430
430
  */
431
431
  getPendingRemovals(): Set<string | number>;
432
+ /**
433
+ * Mark an item as pending removal without removing it
434
+ * Use this to prevent race conditions when the removal will happen later
435
+ * @param id - The item ID to mark as pending removal
436
+ * @param timeout - Optional timeout in ms to auto-clear (default: 10000)
437
+ */
438
+ markPendingRemoval(id: string | number, timeout?: number): void;
432
439
  /**
433
440
  * Clear a specific pending removal
434
441
  * @param id - The item ID to clear from pending removals
@@ -0,0 +1,508 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __getOwnPropNames = Object.getOwnPropertyNames;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
5
+ var __moduleCache = /* @__PURE__ */ new WeakMap;
6
+ var __toCommonJS = (from) => {
7
+ var entry = __moduleCache.get(from), desc;
8
+ if (entry)
9
+ return entry;
10
+ entry = __defProp({}, "__esModule", { value: true });
11
+ if (from && typeof from === "object" || typeof from === "function")
12
+ __getOwnPropNames(from).map((key) => !__hasOwnProp.call(entry, key) && __defProp(entry, key, {
13
+ get: () => from[key],
14
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
15
+ }));
16
+ __moduleCache.set(from, entry);
17
+ return entry;
18
+ };
19
+ var __export = (target, all) => {
20
+ for (var name in all)
21
+ __defProp(target, name, {
22
+ get: all[name],
23
+ enumerable: true,
24
+ configurable: true,
25
+ set: (newValue) => all[name] = () => newValue
26
+ });
27
+ };
28
+
29
+ // src/core/gestures/index.ts
30
+ var exports_gestures = {};
31
+ __export(exports_gestures, {
32
+ detectTap: () => detectTap,
33
+ detectSwipe: () => detectSwipe,
34
+ detectRotate: () => detectRotate,
35
+ detectPinch: () => detectPinch,
36
+ detectPan: () => detectPan,
37
+ detectLongPress: () => detectLongPress,
38
+ createGestureManager: () => createGestureManager,
39
+ SWIPE_DIRECTIONS: () => SWIPE_DIRECTIONS,
40
+ GESTURE_TYPES: () => GESTURE_TYPES
41
+ });
42
+ module.exports = __toCommonJS(exports_gestures);
43
+
44
+ // src/core/gestures/types.ts
45
+ var GESTURE_TYPES;
46
+ ((GESTURE_TYPES2) => {
47
+ GESTURE_TYPES2["TAP"] = "tap";
48
+ GESTURE_TYPES2["SWIPE"] = "swipe";
49
+ GESTURE_TYPES2["SWIPE_LEFT"] = "swipeleft";
50
+ GESTURE_TYPES2["SWIPE_RIGHT"] = "swiperight";
51
+ GESTURE_TYPES2["SWIPE_UP"] = "swipeup";
52
+ GESTURE_TYPES2["SWIPE_DOWN"] = "swipedown";
53
+ GESTURE_TYPES2["PINCH"] = "pinch";
54
+ GESTURE_TYPES2["ROTATE"] = "rotate";
55
+ GESTURE_TYPES2["LONG_PRESS"] = "longpress";
56
+ GESTURE_TYPES2["PAN"] = "pan";
57
+ })(GESTURE_TYPES ||= {});
58
+ var SWIPE_DIRECTIONS;
59
+ ((SWIPE_DIRECTIONS2) => {
60
+ SWIPE_DIRECTIONS2["UP"] = "up";
61
+ SWIPE_DIRECTIONS2["DOWN"] = "down";
62
+ SWIPE_DIRECTIONS2["LEFT"] = "left";
63
+ SWIPE_DIRECTIONS2["RIGHT"] = "right";
64
+ })(SWIPE_DIRECTIONS ||= {});
65
+
66
+ // src/core/gestures/utils.ts
67
+ function getDistance(x1, y1, x2, y2) {
68
+ return Math.sqrt(Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2));
69
+ }
70
+ function getAngle(x1, y1, x2, y2) {
71
+ const angle = Math.atan2(y2 - y1, x2 - x1) * 180 / Math.PI;
72
+ return angle < 0 ? angle + 360 : angle;
73
+ }
74
+ function createGestureEvent(type, originalEvent, state) {
75
+ const endTime = Date.now();
76
+ let defaultPrevented = false;
77
+ const event = {
78
+ type,
79
+ originalEvent,
80
+ target: state.target || originalEvent.target,
81
+ startTime: state.startTime,
82
+ endTime,
83
+ duration: endTime - state.startTime,
84
+ defaultPrevented,
85
+ preventDefault: () => {
86
+ defaultPrevented = true;
87
+ event.defaultPrevented = true;
88
+ if (originalEvent.cancelable) {
89
+ originalEvent.preventDefault();
90
+ }
91
+ },
92
+ stopPropagation: () => {
93
+ originalEvent.stopPropagation();
94
+ }
95
+ };
96
+ return event;
97
+ }
98
+ function hasTouchSupport() {
99
+ const maxPoints = navigator.maxTouchPoints;
100
+ return "ontouchstart" in window || typeof maxPoints === "number" && maxPoints > 0;
101
+ }
102
+ function hasPointerSupport() {
103
+ return !!window.PointerEvent;
104
+ }
105
+ function getTouchCoordinates(e) {
106
+ if ("touches" in e && Array.isArray(e.touches) && e.touches.length > 0) {
107
+ return {
108
+ clientX: e.touches[0].clientX,
109
+ clientY: e.touches[0].clientY
110
+ };
111
+ }
112
+ return {
113
+ clientX: e.clientX,
114
+ clientY: e.clientY
115
+ };
116
+ }
117
+
118
+ // src/core/gestures/tap.ts
119
+ function detectTap(context) {
120
+ const { state, options, originalEvent } = context;
121
+ const deltaX = state.currentX - state.startX;
122
+ const deltaY = state.currentY - state.startY;
123
+ const distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY);
124
+ if (distance < options.tapDistanceThreshold) {
125
+ const now = Date.now();
126
+ const isDoubleTap = now - state.lastTapTime < 300;
127
+ const tapCount = isDoubleTap ? state.tapCount + 1 : 1;
128
+ const tapEvent = {
129
+ ...createGestureEvent("tap", originalEvent, state),
130
+ type: "tap",
131
+ count: tapCount,
132
+ x: state.currentX,
133
+ y: state.currentY
134
+ };
135
+ return tapEvent;
136
+ }
137
+ return null;
138
+ }
139
+
140
+ // src/core/gestures/swipe.ts
141
+ function getSwipeDirection(deltaX, deltaY) {
142
+ if (Math.abs(deltaX) > Math.abs(deltaY)) {
143
+ return deltaX > 0 ? "right" /* RIGHT */ : "left" /* LEFT */;
144
+ }
145
+ return deltaY > 0 ? "down" /* DOWN */ : "up" /* UP */;
146
+ }
147
+ function detectSwipe(context) {
148
+ const { state, options, originalEvent } = context;
149
+ const deltaX = state.currentX - state.startX;
150
+ const deltaY = state.currentY - state.startY;
151
+ const distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY);
152
+ const endTime = Date.now();
153
+ const deltaTime = endTime - state.startTime;
154
+ const velocity = distance / deltaTime;
155
+ if (distance >= options.swipeThreshold && deltaTime <= options.swipeTimeThreshold) {
156
+ const direction = getSwipeDirection(deltaX, deltaY);
157
+ const swipeEvent = {
158
+ ...createGestureEvent("swipe", originalEvent, state),
159
+ type: "swipe",
160
+ direction,
161
+ deltaX,
162
+ deltaY,
163
+ distance,
164
+ velocity,
165
+ startX: state.startX,
166
+ startY: state.startY,
167
+ endX: state.currentX,
168
+ endY: state.currentY
169
+ };
170
+ return swipeEvent;
171
+ }
172
+ return null;
173
+ }
174
+
175
+ // src/core/gestures/longpress.ts
176
+ function detectLongPress(context, callback) {
177
+ const { state, options, originalEvent } = context;
178
+ const timer = window.setTimeout(() => {
179
+ if (state.active) {
180
+ const diffX = Math.abs(state.currentX - state.startX);
181
+ const diffY = Math.abs(state.currentY - state.startY);
182
+ if (diffX < options.tapDistanceThreshold && diffY < options.tapDistanceThreshold) {
183
+ const longPressEvent = {
184
+ ...createGestureEvent("longpress", originalEvent, state),
185
+ type: "longpress",
186
+ x: state.currentX,
187
+ y: state.currentY
188
+ };
189
+ callback(longPressEvent);
190
+ }
191
+ }
192
+ }, options.longPressTime);
193
+ return () => {
194
+ clearTimeout(timer);
195
+ };
196
+ }
197
+ function shouldCancelLongPress(context) {
198
+ const { state, options } = context;
199
+ const diffX = Math.abs(state.currentX - state.startX);
200
+ const diffY = Math.abs(state.currentY - state.startY);
201
+ return diffX > options.tapDistanceThreshold || diffY > options.tapDistanceThreshold;
202
+ }
203
+
204
+ // src/core/gestures/pan.ts
205
+ function detectPan(context) {
206
+ const { state, originalEvent } = context;
207
+ const deltaX = state.currentX - state.startX;
208
+ const deltaY = state.currentY - state.startY;
209
+ const moveDeltaX = state.currentX - state.lastX;
210
+ const moveDeltaY = state.currentY - state.lastY;
211
+ const moveDelta = Math.sqrt(moveDeltaX * moveDeltaX + moveDeltaY * moveDeltaY);
212
+ if (moveDelta > 0) {
213
+ const panEvent = {
214
+ ...createGestureEvent("pan", originalEvent, state),
215
+ type: "pan",
216
+ deltaX,
217
+ deltaY,
218
+ startX: state.startX,
219
+ startY: state.startY,
220
+ currentX: state.currentX,
221
+ currentY: state.currentY
222
+ };
223
+ return panEvent;
224
+ }
225
+ return null;
226
+ }
227
+
228
+ // src/core/gestures/pinch.ts
229
+ function detectPinch(context, touch1, touch2) {
230
+ const { state, originalEvent } = context;
231
+ const currentDistance = getDistance(touch1.clientX, touch1.clientY, touch2.clientX, touch2.clientY);
232
+ const PINCH_THRESHOLD = 10;
233
+ if (Math.abs(currentDistance - state.startDistance) > PINCH_THRESHOLD) {
234
+ const scale = currentDistance / state.startDistance;
235
+ const centerX = (touch1.clientX + touch2.clientX) / 2;
236
+ const centerY = (touch1.clientY + touch2.clientY) / 2;
237
+ const pinchEvent = {
238
+ ...createGestureEvent("pinch", originalEvent, state),
239
+ type: "pinch",
240
+ scale,
241
+ centerX,
242
+ centerY
243
+ };
244
+ return pinchEvent;
245
+ }
246
+ return null;
247
+ }
248
+
249
+ // src/core/gestures/rotate.ts
250
+ function detectRotate(context, touch1, touch2) {
251
+ const { state, originalEvent } = context;
252
+ const currentAngle = getAngle(touch1.clientX, touch1.clientY, touch2.clientX, touch2.clientY);
253
+ const ROTATION_THRESHOLD = 10;
254
+ const rotationDiff = currentAngle - state.startAngle;
255
+ if (Math.abs(rotationDiff) > ROTATION_THRESHOLD) {
256
+ const centerX = (touch1.clientX + touch2.clientX) / 2;
257
+ const centerY = (touch1.clientY + touch2.clientY) / 2;
258
+ const rotateEvent = {
259
+ ...createGestureEvent("rotate", originalEvent, state),
260
+ type: "rotate",
261
+ rotation: rotationDiff,
262
+ centerX,
263
+ centerY
264
+ };
265
+ return rotateEvent;
266
+ }
267
+ return null;
268
+ }
269
+
270
+ // src/core/gestures/manager.ts
271
+ var createGestureManager = (element, config = {}) => {
272
+ const options = {
273
+ swipeThreshold: 30,
274
+ swipeTimeThreshold: 300,
275
+ longPressTime: 500,
276
+ tapDistanceThreshold: 10,
277
+ preventDefault: true,
278
+ stopPropagation: false,
279
+ ...config
280
+ };
281
+ const handlers = new Map;
282
+ const state = {
283
+ active: false,
284
+ startTime: 0,
285
+ startX: 0,
286
+ startY: 0,
287
+ lastX: 0,
288
+ lastY: 0,
289
+ currentX: 0,
290
+ currentY: 0,
291
+ touchCount: 0,
292
+ longPressTimer: null,
293
+ startDistance: 0,
294
+ startAngle: 0,
295
+ lastTapTime: 0,
296
+ tapCount: 0,
297
+ target: null
298
+ };
299
+ const supportTouch = hasTouchSupport();
300
+ const supportPointer = hasPointerSupport();
301
+ const gestureSupport = {
302
+ tap: true,
303
+ swipe: true,
304
+ swipeleft: true,
305
+ swiperight: true,
306
+ swipeup: true,
307
+ swipedown: true,
308
+ longpress: true,
309
+ pan: true,
310
+ pinch: supportTouch || supportPointer,
311
+ rotate: supportTouch || supportPointer
312
+ };
313
+ const dispatchGesture = (event) => {
314
+ const eventHandlers = handlers.get(event.type);
315
+ if (!eventHandlers)
316
+ return;
317
+ eventHandlers.forEach((handler) => {
318
+ try {
319
+ handler(event);
320
+ } catch (error) {
321
+ console.error(`Error in gesture handler for ${event.type}:`, error);
322
+ }
323
+ });
324
+ if (event.type === "swipe" && "direction" in event) {
325
+ const directionEvent = { ...event, type: `swipe${event.direction}` };
326
+ dispatchGesture(directionEvent);
327
+ }
328
+ if (options.preventDefault && !event.defaultPrevented) {
329
+ event.preventDefault();
330
+ }
331
+ if (options.stopPropagation) {
332
+ event.stopPropagation();
333
+ }
334
+ };
335
+ let longPressCleanup = null;
336
+ const handleStart = (e) => {
337
+ const touch = getTouchCoordinates(e);
338
+ const touchCount = "touches" in e ? e.touches.length : 1;
339
+ state.active = true;
340
+ state.startTime = Date.now();
341
+ state.startX = state.lastX = state.currentX = touch.clientX;
342
+ state.startY = state.lastY = state.currentY = touch.clientY;
343
+ state.touchCount = touchCount;
344
+ state.target = e.target;
345
+ if (touchCount === 2 && "touches" in e) {
346
+ const touch1 = e.touches[0];
347
+ const touch2 = e.touches[1];
348
+ state.startDistance = Math.sqrt(Math.pow(touch2.clientX - touch1.clientX, 2) + Math.pow(touch2.clientY - touch1.clientY, 2));
349
+ state.startAngle = Math.atan2(touch2.clientY - touch1.clientY, touch2.clientX - touch1.clientX) * 180 / Math.PI;
350
+ if (state.startAngle < 0)
351
+ state.startAngle += 360;
352
+ }
353
+ const context = {
354
+ state,
355
+ options,
356
+ originalEvent: e
357
+ };
358
+ if (longPressCleanup) {
359
+ longPressCleanup();
360
+ }
361
+ longPressCleanup = detectLongPress(context, (longPressEvent) => {
362
+ dispatchGesture(longPressEvent);
363
+ });
364
+ };
365
+ const handleMove = (e) => {
366
+ if (!state.active)
367
+ return;
368
+ const touch = getTouchCoordinates(e);
369
+ const touchCount = "touches" in e ? e.touches.length : 1;
370
+ state.lastX = state.currentX;
371
+ state.lastY = state.currentY;
372
+ state.currentX = touch.clientX;
373
+ state.currentY = touch.clientY;
374
+ const context = {
375
+ state,
376
+ options,
377
+ originalEvent: e
378
+ };
379
+ if (shouldCancelLongPress(context) && longPressCleanup) {
380
+ longPressCleanup();
381
+ longPressCleanup = null;
382
+ }
383
+ const panEvent = detectPan(context);
384
+ if (panEvent) {
385
+ dispatchGesture(panEvent);
386
+ }
387
+ if (touchCount === 2 && "touches" in e) {
388
+ const touch1 = e.touches[0];
389
+ const touch2 = e.touches[1];
390
+ const pinchEvent = detectPinch(context, touch1, touch2);
391
+ if (pinchEvent) {
392
+ dispatchGesture(pinchEvent);
393
+ }
394
+ const rotateEvent = detectRotate(context, touch1, touch2);
395
+ if (rotateEvent) {
396
+ dispatchGesture(rotateEvent);
397
+ }
398
+ }
399
+ };
400
+ const handleEnd = (e) => {
401
+ if (!state.active)
402
+ return;
403
+ if (longPressCleanup) {
404
+ longPressCleanup();
405
+ longPressCleanup = null;
406
+ }
407
+ const context = {
408
+ state,
409
+ options,
410
+ originalEvent: e
411
+ };
412
+ const tapEvent = detectTap(context);
413
+ if (tapEvent) {
414
+ state.lastTapTime = Date.now();
415
+ state.tapCount = tapEvent.count;
416
+ dispatchGesture(tapEvent);
417
+ } else {
418
+ const swipeEvent = detectSwipe(context);
419
+ if (swipeEvent) {
420
+ dispatchGesture(swipeEvent);
421
+ }
422
+ }
423
+ state.active = false;
424
+ };
425
+ const handleCancel = () => {
426
+ if (longPressCleanup) {
427
+ longPressCleanup();
428
+ longPressCleanup = null;
429
+ }
430
+ state.active = false;
431
+ };
432
+ let eventListeners = {};
433
+ const setupEventListeners = () => {
434
+ if (supportPointer) {
435
+ eventListeners = {
436
+ pointerdown: handleStart,
437
+ pointermove: handleMove,
438
+ pointerup: handleEnd,
439
+ pointercancel: handleCancel
440
+ };
441
+ } else if (supportTouch) {
442
+ eventListeners = {
443
+ touchstart: handleStart,
444
+ touchmove: handleMove,
445
+ touchend: handleEnd,
446
+ touchcancel: handleCancel
447
+ };
448
+ } else {
449
+ eventListeners = {
450
+ mousedown: handleStart,
451
+ mousemove: handleMove,
452
+ mouseup: handleEnd,
453
+ mouseleave: handleCancel
454
+ };
455
+ }
456
+ Object.entries(eventListeners).forEach(([event, listener]) => {
457
+ element.addEventListener(event, listener, { passive: !options.preventDefault });
458
+ });
459
+ };
460
+ const removeEventListeners = () => {
461
+ Object.entries(eventListeners).forEach(([event, listener]) => {
462
+ element.removeEventListener(event, listener);
463
+ });
464
+ eventListeners = {};
465
+ };
466
+ setupEventListeners();
467
+ return {
468
+ on(eventType, handler) {
469
+ if (!handlers.has(eventType)) {
470
+ handlers.set(eventType, new Set);
471
+ }
472
+ handlers.get(eventType).add(handler);
473
+ return this;
474
+ },
475
+ off(eventType, handler) {
476
+ const eventHandlers = handlers.get(eventType);
477
+ if (eventHandlers) {
478
+ eventHandlers.delete(handler);
479
+ if (eventHandlers.size === 0) {
480
+ handlers.delete(eventType);
481
+ }
482
+ }
483
+ return this;
484
+ },
485
+ isSupported(gestureType) {
486
+ return gestureType in gestureSupport && gestureSupport[gestureType];
487
+ },
488
+ enable() {
489
+ setupEventListeners();
490
+ return this;
491
+ },
492
+ disable() {
493
+ removeEventListeners();
494
+ return this;
495
+ },
496
+ destroy() {
497
+ removeEventListeners();
498
+ if (longPressCleanup) {
499
+ longPressCleanup();
500
+ longPressCleanup = null;
501
+ }
502
+ handlers.clear();
503
+ }
504
+ };
505
+ };
506
+
507
+ //# debugId=34D8A19FC9E7DD6764756E2164756E21
508
+ //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vc3JjL2NvcmUvZ2VzdHVyZXMvdHlwZXMudHMiLCAiLi4vLi4vLi4vc3JjL2NvcmUvZ2VzdHVyZXMvdXRpbHMudHMiLCAiLi4vLi4vLi4vc3JjL2NvcmUvZ2VzdHVyZXMvdGFwLnRzIiwgIi4uLy4uLy4uL3NyYy9jb3JlL2dlc3R1cmVzL3N3aXBlLnRzIiwgIi4uLy4uLy4uL3NyYy9jb3JlL2dlc3R1cmVzL2xvbmdwcmVzcy50cyIsICIuLi8uLi8uLi9zcmMvY29yZS9nZXN0dXJlcy9wYW4udHMiLCAiLi4vLi4vLi4vc3JjL2NvcmUvZ2VzdHVyZXMvcGluY2gudHMiLCAiLi4vLi4vLi4vc3JjL2NvcmUvZ2VzdHVyZXMvcm90YXRlLnRzIiwgIi4uLy4uLy4uL3NyYy9jb3JlL2dlc3R1cmVzL21hbmFnZXIudHMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbCiAgICAiLy8gc3JjL2NvcmUvZ2VzdHVyZXMvdHlwZXMudHNcbi8qKlxuICogQG1vZHVsZSBjb3JlL2dlc3R1cmVzXG4gKiBAZGVzY3JpcHRpb24gVHlwZSBkZWZpbml0aW9ucyBmb3IgdGhlIGdlc3R1cmUgc3lzdGVtXG4gKi9cblxuLyoqXG4gKiBUeXBlcyBvZiBnZXN0dXJlcyBzdXBwb3J0ZWQgYnkgdGhlIHN5c3RlbVxuICovXG5leHBvcnQgZW51bSBHRVNUVVJFX1RZUEVTIHtcbiAgVEFQID0gJ3RhcCcsXG4gIFNXSVBFID0gJ3N3aXBlJyxcbiAgU1dJUEVfTEVGVCA9ICdzd2lwZWxlZnQnLFxuICBTV0lQRV9SSUdIVCA9ICdzd2lwZXJpZ2h0JyxcbiAgU1dJUEVfVVAgPSAnc3dpcGV1cCcsXG4gIFNXSVBFX0RPV04gPSAnc3dpcGVkb3duJyxcbiAgUElOQ0ggPSAncGluY2gnLFxuICBST1RBVEUgPSAncm90YXRlJyxcbiAgTE9OR19QUkVTUyA9ICdsb25ncHJlc3MnLFxuICBQQU4gPSAncGFuJ1xufVxuXG4vKipcbiAqIERpcmVjdGlvbiBvZiBzd2lwZSBnZXN0dXJlc1xuICovXG5leHBvcnQgZW51bSBTV0lQRV9ESVJFQ1RJT05TIHtcbiAgVVAgPSAndXAnLFxuICBET1dOID0gJ2Rvd24nLFxuICBMRUZUID0gJ2xlZnQnLFxuICBSSUdIVCA9ICdyaWdodCdcbn1cblxuLyoqXG4gKiBDb25maWd1cmF0aW9uIG9wdGlvbnMgZm9yIGdlc3R1cmUgcmVjb2duaXRpb25cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBHZXN0dXJlQ29uZmlnIHtcbiAgLyoqXG4gICAqIE1pbmltdW0gZGlzdGFuY2UgKGluIHBpeGVscykgdG8gcmVjb2duaXplIGEgc3dpcGVcbiAgICogQGRlZmF1bHQgMzBcbiAgICovXG4gIHN3aXBlVGhyZXNob2xkPzogbnVtYmVyO1xuICBcbiAgLyoqXG4gICAqIE1heGltdW0gdGltZSAoaW4gbXMpIGluIHdoaWNoIGEgc3dpcGUgbXVzdCBiZSBjb21wbGV0ZWRcbiAgICogQGRlZmF1bHQgMzAwXG4gICAqL1xuICBzd2lwZVRpbWVUaHJlc2hvbGQ/OiBudW1iZXI7XG4gIFxuICAvKipcbiAgICogVGltZSAoaW4gbXMpIHRvIHJlY29nbml6ZSBhIGxvbmcgcHJlc3NcbiAgICogQGRlZmF1bHQgNTAwXG4gICAqL1xuICBsb25nUHJlc3NUaW1lPzogbnVtYmVyO1xuICBcbiAgLyoqXG4gICAqIERpc3RhbmNlIHRocmVzaG9sZCAoaW4gcGl4ZWxzKSBmb3IgdGFwIHJlY29nbml0aW9uXG4gICAqIEBkZWZhdWx0IDEwXG4gICAqL1xuICB0YXBEaXN0YW5jZVRocmVzaG9sZD86IG51bWJlcjtcbiAgXG4gIC8qKlxuICAgKiBXaGV0aGVyIHRvIHByZXZlbnQgZGVmYXVsdCBiZWhhdmlvcnMgb24gdG91Y2ggZXZlbnRzXG4gICAqIEBkZWZhdWx0IHRydWVcbiAgICovXG4gIHByZXZlbnREZWZhdWx0PzogYm9vbGVhbjtcbiAgXG4gIC8qKlxuICAgKiBXaGV0aGVyIHRvIHN0b3AgZXZlbnQgcHJvcGFnYXRpb25cbiAgICogQGRlZmF1bHQgZmFsc2VcbiAgICovXG4gIHN0b3BQcm9wYWdhdGlvbj86IGJvb2xlYW47XG4gIFxuICBba2V5OiBzdHJpbmddOiBhbnk7XG59XG5cbi8qKlxuICogQmFzZSBnZXN0dXJlIGV2ZW50IGRhdGFcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBHZXN0dXJlRXZlbnQge1xuICAvKipcbiAgICogVHlwZSBvZiB0aGUgZ2VzdHVyZVxuICAgKi9cbiAgdHlwZTogc3RyaW5nO1xuICBcbiAgLyoqXG4gICAqIE9yaWdpbmFsIERPTSBldmVudFxuICAgKi9cbiAgb3JpZ2luYWxFdmVudDogRXZlbnQ7XG4gIFxuICAvKipcbiAgICogRWxlbWVudCB0aGUgZ2VzdHVyZSB3YXMgdHJpZ2dlcmVkIG9uXG4gICAqL1xuICB0YXJnZXQ6IEV2ZW50VGFyZ2V0O1xuICBcbiAgLyoqXG4gICAqIFRpbWVzdGFtcCB3aGVuIHRoZSBnZXN0dXJlIHN0YXJ0ZWRcbiAgICovXG4gIHN0YXJ0VGltZTogbnVtYmVyO1xuICBcbiAgLyoqXG4gICAqIFRpbWVzdGFtcCB3aGVuIHRoZSBnZXN0dXJlIGVuZGVkXG4gICAqL1xuICBlbmRUaW1lOiBudW1iZXI7XG4gIFxuICAvKipcbiAgICogR2VzdHVyZSBkdXJhdGlvbiBpbiBtaWxsaXNlY29uZHNcbiAgICovXG4gIGR1cmF0aW9uOiBudW1iZXI7XG4gIFxuICAvKipcbiAgICogV2hldGhlciBkZWZhdWx0IGJlaGF2aW9yIHdhcyBwcmV2ZW50ZWRcbiAgICovXG4gIGRlZmF1bHRQcmV2ZW50ZWQ6IGJvb2xlYW47XG4gIFxuICAvKipcbiAgICogUHJldmVudCBkZWZhdWx0IGJlaGF2aW9yXG4gICAqL1xuICBwcmV2ZW50RGVmYXVsdDogKCkgPT4gdm9pZDtcbiAgXG4gIC8qKlxuICAgKiBTdG9wIGV2ZW50IHByb3BhZ2F0aW9uXG4gICAqL1xuICBzdG9wUHJvcGFnYXRpb246ICgpID0+IHZvaWQ7XG59XG5cbi8qKlxuICogVGFwIGdlc3R1cmUgZXZlbnQgZGF0YVxuICovXG5leHBvcnQgaW50ZXJmYWNlIFRhcEV2ZW50IGV4dGVuZHMgR2VzdHVyZUV2ZW50IHtcbiAgdHlwZTogJ3RhcCc7XG4gIFxuICAvKipcbiAgICogTnVtYmVyIG9mIHRhcHMgKGZvciBkb3VibGUgdGFwIGRldGVjdGlvbilcbiAgICovXG4gIGNvdW50OiBudW1iZXI7XG4gIFxuICAvKipcbiAgICogWCBwb3NpdGlvbiBvZiB0aGUgdGFwXG4gICAqL1xuICB4OiBudW1iZXI7XG4gIFxuICAvKipcbiAgICogWSBwb3NpdGlvbiBvZiB0aGUgdGFwXG4gICAqL1xuICB5OiBudW1iZXI7XG59XG5cbi8qKlxuICogU3dpcGUgZ2VzdHVyZSBldmVudCBkYXRhXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgU3dpcGVFdmVudCBleHRlbmRzIEdlc3R1cmVFdmVudCB7XG4gIHR5cGU6ICdzd2lwZScgfCAnc3dpcGVsZWZ0JyB8ICdzd2lwZXJpZ2h0JyB8ICdzd2lwZXVwJyB8ICdzd2lwZWRvd24nO1xuICBcbiAgLyoqXG4gICAqIERpcmVjdGlvbiBvZiB0aGUgc3dpcGVcbiAgICovXG4gIGRpcmVjdGlvbjogJ3VwJyB8ICdkb3duJyB8ICdsZWZ0JyB8ICdyaWdodCc7XG4gIFxuICAvKipcbiAgICogRGlzdGFuY2Ugc3dpcGVkIGluIHRoZSBYIGRpcmVjdGlvblxuICAgKi9cbiAgZGVsdGFYOiBudW1iZXI7XG4gIFxuICAvKipcbiAgICogRGlzdGFuY2Ugc3dpcGVkIGluIHRoZSBZIGRpcmVjdGlvblxuICAgKi9cbiAgZGVsdGFZOiBudW1iZXI7XG4gIFxuICAvKipcbiAgICogVG90YWwgZGlzdGFuY2Ugc3dpcGVkXG4gICAqL1xuICBkaXN0YW5jZTogbnVtYmVyO1xuICBcbiAgLyoqXG4gICAqIFZlbG9jaXR5IG9mIHRoZSBzd2lwZSBpbiBwaXhlbHMgcGVyIG1pbGxpc2Vjb25kXG4gICAqL1xuICB2ZWxvY2l0eTogbnVtYmVyO1xuICBcbiAgLyoqXG4gICAqIFN0YXJ0IFggcG9zaXRpb25cbiAgICovXG4gIHN0YXJ0WDogbnVtYmVyO1xuICBcbiAgLyoqXG4gICAqIFN0YXJ0IFkgcG9zaXRpb25cbiAgICovXG4gIHN0YXJ0WTogbnVtYmVyO1xuICBcbiAgLyoqXG4gICAqIEVuZCBYIHBvc2l0aW9uXG4gICAqL1xuICBlbmRYOiBudW1iZXI7XG4gIFxuICAvKipcbiAgICogRW5kIFkgcG9zaXRpb25cbiAgICovXG4gIGVuZFk6IG51bWJlcjtcbn1cblxuLyoqXG4gKiBMb25nIHByZXNzIGdlc3R1cmUgZXZlbnQgZGF0YVxuICovXG5leHBvcnQgaW50ZXJmYWNlIExvbmdQcmVzc0V2ZW50IGV4dGVuZHMgR2VzdHVyZUV2ZW50IHtcbiAgdHlwZTogJ2xvbmdwcmVzcyc7XG4gIFxuICAvKipcbiAgICogWCBwb3NpdGlvbiBvZiB0aGUgbG9uZyBwcmVzc1xuICAgKi9cbiAgeDogbnVtYmVyO1xuICBcbiAgLyoqXG4gICAqIFkgcG9zaXRpb24gb2YgdGhlIGxvbmcgcHJlc3NcbiAgICovXG4gIHk6IG51bWJlcjtcbn1cblxuLyoqXG4gKiBQaW5jaCBnZXN0dXJlIGV2ZW50IGRhdGFcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBQaW5jaEV2ZW50IGV4dGVuZHMgR2VzdHVyZUV2ZW50IHtcbiAgdHlwZTogJ3BpbmNoJztcbiAgXG4gIC8qKlxuICAgKiBTY2FsZSBmYWN0b3Igb2YgdGhlIHBpbmNoICg+MSBmb3Igem9vbSBpbiwgPDEgZm9yIHpvb20gb3V0KVxuICAgKi9cbiAgc2NhbGU6IG51bWJlcjtcbiAgXG4gIC8qKlxuICAgKiBDZW50ZXIgWCBwb3NpdGlvbiBvZiB0aGUgcGluY2hcbiAgICovXG4gIGNlbnRlclg6IG51bWJlcjtcbiAgXG4gIC8qKlxuICAgKiBDZW50ZXIgWSBwb3NpdGlvbiBvZiB0aGUgcGluY2hcbiAgICovXG4gIGNlbnRlclk6IG51bWJlcjtcbn1cblxuLyoqXG4gKiBSb3RhdGUgZ2VzdHVyZSBldmVudCBkYXRhXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgUm90YXRlRXZlbnQgZXh0ZW5kcyBHZXN0dXJlRXZlbnQge1xuICB0eXBlOiAncm90YXRlJztcbiAgXG4gIC8qKlxuICAgKiBSb3RhdGlvbiBhbmdsZSBpbiBkZWdyZWVzXG4gICAqL1xuICByb3RhdGlvbjogbnVtYmVyO1xuICBcbiAgLyoqXG4gICAqIENlbnRlciBYIHBvc2l0aW9uIG9mIHRoZSByb3RhdGlvblxuICAgKi9cbiAgY2VudGVyWDogbnVtYmVyO1xuICBcbiAgLyoqXG4gICAqIENlbnRlciBZIHBvc2l0aW9uIG9mIHRoZSByb3RhdGlvblxuICAgKi9cbiAgY2VudGVyWTogbnVtYmVyO1xufVxuXG4vKipcbiAqIFBhbiBnZXN0dXJlIGV2ZW50IGRhdGFcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBQYW5FdmVudCBleHRlbmRzIEdlc3R1cmVFdmVudCB7XG4gIHR5cGU6ICdwYW4nO1xuICBcbiAgLyoqXG4gICAqIERpc3RhbmNlIHBhbm5lZCBpbiB0aGUgWCBkaXJlY3Rpb25cbiAgICovXG4gIGRlbHRhWDogbnVtYmVyO1xuICBcbiAgLyoqXG4gICAqIERpc3RhbmNlIHBhbm5lZCBpbiB0aGUgWSBkaXJlY3Rpb25cbiAgICovXG4gIGRlbHRhWTogbnVtYmVyO1xuICBcbiAgLyoqXG4gICAqIFN0YXJ0IFggcG9zaXRpb25cbiAgICovXG4gIHN0YXJ0WDogbnVtYmVyO1xuICBcbiAgLyoqXG4gICAqIFN0YXJ0IFkgcG9zaXRpb25cbiAgICovXG4gIHN0YXJ0WTogbnVtYmVyO1xuICBcbiAgLyoqXG4gICAqIEN1cnJlbnQgWCBwb3NpdGlvblxuICAgKi9cbiAgY3VycmVudFg6IG51bWJlcjtcbiAgXG4gIC8qKlxuICAgKiBDdXJyZW50IFkgcG9zaXRpb25cbiAgICovXG4gIGN1cnJlbnRZOiBudW1iZXI7XG59XG5cbi8qKlxuICogVW5pb24gdHlwZSBvZiBhbGwgZ2VzdHVyZSBldmVudHNcbiAqL1xuZXhwb3J0IHR5cGUgQW55R2VzdHVyZUV2ZW50ID0gXG4gIHwgVGFwRXZlbnRcbiAgfCBTd2lwZUV2ZW50IFxuICB8IExvbmdQcmVzc0V2ZW50IFxuICB8IFBpbmNoRXZlbnQgXG4gIHwgUm90YXRlRXZlbnQgXG4gIHwgUGFuRXZlbnQ7XG5cbi8qKlxuICogSGFuZGxlciBmb3IgZ2VzdHVyZSBldmVudHNcbiAqL1xuZXhwb3J0IHR5cGUgR2VzdHVyZUhhbmRsZXIgPSAoZXZlbnQ6IEFueUdlc3R1cmVFdmVudCkgPT4gdm9pZDtcblxuLyoqXG4gKiBHZXN0dXJlIHN0YXRlIGZvciB0cmFja2luZyB0b3VjaCBpbnRlcmFjdGlvbnNcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBHZXN0dXJlU3RhdGUge1xuICBhY3RpdmU6IGJvb2xlYW47XG4gIHN0YXJ0VGltZTogbnVtYmVyO1xuICBzdGFydFg6IG51bWJlcjtcbiAgc3RhcnRZOiBudW1iZXI7XG4gIGxhc3RYOiBudW1iZXI7XG4gIGxhc3RZOiBudW1iZXI7XG4gIGN1cnJlbnRYOiBudW1iZXI7XG4gIGN1cnJlbnRZOiBudW1iZXI7XG4gIHRvdWNoQ291bnQ6IG51bWJlcjtcbiAgbG9uZ1ByZXNzVGltZXI6IG51bWJlciB8IG51bGw7XG4gIHN0YXJ0RGlzdGFuY2U6IG51bWJlcjtcbiAgc3RhcnRBbmdsZTogbnVtYmVyO1xuICBsYXN0VGFwVGltZTogbnVtYmVyO1xuICB0YXBDb3VudDogbnVtYmVyO1xuICB0YXJnZXQ6IEV2ZW50VGFyZ2V0IHwgbnVsbDtcbn1cblxuLyoqXG4gKiBDb250ZXh0IGZvciBnZXN0dXJlIGRldGVjdGlvblxuICovXG5leHBvcnQgaW50ZXJmYWNlIEdlc3R1cmVEZXRlY3Rpb25Db250ZXh0IHtcbiAgc3RhdGU6IEdlc3R1cmVTdGF0ZTtcbiAgb3B0aW9uczogUmVxdWlyZWQ8R2VzdHVyZUNvbmZpZz47XG4gIG9yaWdpbmFsRXZlbnQ6IEV2ZW50O1xufVxuXG4vKipcbiAqIEdlc3R1cmUgbWFuYWdlciBpbnRlcmZhY2VcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBHZXN0dXJlTWFuYWdlciB7XG4gIC8qKlxuICAgKiBBZGQgYW4gZXZlbnQgbGlzdGVuZXIgZm9yIGEgZ2VzdHVyZVxuICAgKiBAcGFyYW0gZXZlbnRUeXBlIC0gR2VzdHVyZSB0eXBlXG4gICAqIEBwYXJhbSBoYW5kbGVyIC0gRXZlbnQgaGFuZGxlclxuICAgKiBAcmV0dXJucyBHZXN0dXJlIG1hbmFnZXIgZm9yIGNoYWluaW5nXG4gICAqL1xuICBvbjogKGV2ZW50VHlwZTogc3RyaW5nLCBoYW5kbGVyOiBHZXN0dXJlSGFuZGxlcikgPT4gR2VzdHVyZU1hbmFnZXI7XG4gIFxuICAvKipcbiAgICogUmVtb3ZlIGFuIGV2ZW50IGxpc3RlbmVyIGZvciBhIGdlc3R1cmVcbiAgICogQHBhcmFtIGV2ZW50VHlwZSAtIEdlc3R1cmUgdHlwZVxuICAgKiBAcGFyYW0gaGFuZGxlciAtIEV2ZW50IGhhbmRsZXJcbiAgICogQHJldHVybnMgR2VzdHVyZSBtYW5hZ2VyIGZvciBjaGFpbmluZ1xuICAgKi9cbiAgb2ZmOiAoZXZlbnRUeXBlOiBzdHJpbmcsIGhhbmRsZXI6IEdlc3R1cmVIYW5kbGVyKSA9PiBHZXN0dXJlTWFuYWdlcjtcbiAgXG4gIC8qKlxuICAgKiBDaGVjayBpZiBhIGdlc3R1cmUgaXMgc3VwcG9ydGVkIG9uIHRoZSBjdXJyZW50IGRldmljZVxuICAgKiBAcGFyYW0gZ2VzdHVyZVR5cGUgLSBUeXBlIG9mIGdlc3R1cmUgdG8gY2hlY2tcbiAgICogQHJldHVybnMgV2hldGhlciB0aGUgZ2VzdHVyZSBpcyBzdXBwb3J0ZWRcbiAgICovXG4gIGlzU3VwcG9ydGVkOiAoZ2VzdHVyZVR5cGU6IHN0cmluZykgPT4gYm9vbGVhbjtcbiAgXG4gIC8qKlxuICAgKiBFbmFibGUgZ2VzdHVyZSByZWNvZ25pdGlvblxuICAgKiBAcmV0dXJucyBHZXN0dXJlIG1hbmFnZXIgZm9yIGNoYWluaW5nXG4gICAqL1xuICBlbmFibGU6ICgpID0+IEdlc3R1cmVNYW5hZ2VyO1xuICBcbiAgLyoqXG4gICAqIERpc2FibGUgZ2VzdHVyZSByZWNvZ25pdGlvblxuICAgKiBAcmV0dXJucyBHZXN0dXJlIG1hbmFnZXIgZm9yIGNoYWluaW5nXG4gICAqL1xuICBkaXNhYmxlOiAoKSA9PiBHZXN0dXJlTWFuYWdlcjtcbiAgXG4gIC8qKlxuICAgKiBDbGVhbiB1cCBldmVudCBsaXN0ZW5lcnNcbiAgICovXG4gIGRlc3Ryb3k6ICgpID0+IHZvaWQ7XG59IiwKICAgICIvLyBzcmMvY29yZS9nZXN0dXJlcy91dGlscy50c1xuLyoqXG4gKiBAbW9kdWxlIGNvcmUvZ2VzdHVyZXNcbiAqIEBkZXNjcmlwdGlvbiBVdGlsaXR5IGZ1bmN0aW9ucyBmb3IgZ2VzdHVyZSBkZXRlY3Rpb25cbiAqL1xuXG5pbXBvcnQgeyBHZXN0dXJlRXZlbnQsIEdlc3R1cmVTdGF0ZSB9IGZyb20gXCIuL3R5cGVzXCI7XG5cbi8qKlxuICogQ2FsY3VsYXRlIGRpc3RhbmNlIGJldHdlZW4gdHdvIHBvaW50c1xuICpcbiAqIEBwYXJhbSB4MSAtIFggY29vcmRpbmF0ZSBvZiBmaXJzdCBwb2ludFxuICogQHBhcmFtIHkxIC0gWSBjb29yZGluYXRlIG9mIGZpcnN0IHBvaW50XG4gKiBAcGFyYW0geDIgLSBYIGNvb3JkaW5hdGUgb2Ygc2Vjb25kIHBvaW50XG4gKiBAcGFyYW0geTIgLSBZIGNvb3JkaW5hdGUgb2Ygc2Vjb25kIHBvaW50XG4gKiBAcmV0dXJucyBEaXN0YW5jZSBiZXR3ZWVuIHRoZSBwb2ludHNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldERpc3RhbmNlKFxuICB4MTogbnVtYmVyLFxuICB5MTogbnVtYmVyLFxuICB4MjogbnVtYmVyLFxuICB5MjogbnVtYmVyXG4pOiBudW1iZXIge1xuICByZXR1cm4gTWF0aC5zcXJ0KE1hdGgucG93KHgyIC0geDEsIDIpICsgTWF0aC5wb3coeTIgLSB5MSwgMikpO1xufVxuXG4vKipcbiAqIENhbGN1bGF0ZSBhbmdsZSBiZXR3ZWVuIHR3byBwb2ludHMgaW4gZGVncmVlcyAoMC0zNjApXG4gKlxuICogQHBhcmFtIHgxIC0gWCBjb29yZGluYXRlIG9mIGZpcnN0IHBvaW50XG4gKiBAcGFyYW0geTEgLSBZIGNvb3JkaW5hdGUgb2YgZmlyc3QgcG9pbnRcbiAqIEBwYXJhbSB4MiAtIFggY29vcmRpbmF0ZSBvZiBzZWNvbmQgcG9pbnRcbiAqIEBwYXJhbSB5MiAtIFkgY29vcmRpbmF0ZSBvZiBzZWNvbmQgcG9pbnRcbiAqIEByZXR1cm5zIEFuZ2xlIGluIGRlZ3JlZXNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldEFuZ2xlKFxuICB4MTogbnVtYmVyLFxuICB5MTogbnVtYmVyLFxuICB4MjogbnVtYmVyLFxuICB5MjogbnVtYmVyXG4pOiBudW1iZXIge1xuICBjb25zdCBhbmdsZSA9IChNYXRoLmF0YW4yKHkyIC0geTEsIHgyIC0geDEpICogMTgwKSAvIE1hdGguUEk7XG4gIHJldHVybiBhbmdsZSA8IDAgPyBhbmdsZSArIDM2MCA6IGFuZ2xlO1xufVxuXG4vKipcbiAqIENyZWF0ZSBhIGJhc2UgZ2VzdHVyZSBldmVudFxuICpcbiAqIEBwYXJhbSB0eXBlIC0gVHlwZSBvZiBnZXN0dXJlXG4gKiBAcGFyYW0gb3JpZ2luYWxFdmVudCAtIE9yaWdpbmFsIERPTSBldmVudFxuICogQHBhcmFtIHN0YXRlIC0gQ3VycmVudCBnZXN0dXJlIHN0YXRlXG4gKiBAcmV0dXJucyBCYXNlIGdlc3R1cmUgZXZlbnQgb2JqZWN0XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVHZXN0dXJlRXZlbnQoXG4gIHR5cGU6IHN0cmluZyxcbiAgb3JpZ2luYWxFdmVudDogRXZlbnQsXG4gIHN0YXRlOiBHZXN0dXJlU3RhdGVcbik6IEdlc3R1cmVFdmVudCB7XG4gIGNvbnN0IGVuZFRpbWUgPSBEYXRlLm5vdygpO1xuICBsZXQgZGVmYXVsdFByZXZlbnRlZCA9IGZhbHNlO1xuXG4gIGNvbnN0IGV2ZW50OiBHZXN0dXJlRXZlbnQgPSB7XG4gICAgdHlwZSxcbiAgICBvcmlnaW5hbEV2ZW50LFxuICAgIHRhcmdldDpcbiAgICAgIChzdGF0ZS50YXJnZXQgYXMgRXZlbnRUYXJnZXQpIHx8IChvcmlnaW5hbEV2ZW50LnRhcmdldCBhcyBFdmVudFRhcmdldCksXG4gICAgc3RhcnRUaW1lOiBzdGF0ZS5zdGFydFRpbWUsXG4gICAgZW5kVGltZSxcbiAgICBkdXJhdGlvbjogZW5kVGltZSAtIHN0YXRlLnN0YXJ0VGltZSxcbiAgICBkZWZhdWx0UHJldmVudGVkLFxuICAgIHByZXZlbnREZWZhdWx0OiAoKSA9PiB7XG4gICAgICBkZWZhdWx0UHJldmVudGVkID0gdHJ1ZTtcbiAgICAgIGV2ZW50LmRlZmF1bHRQcmV2ZW50ZWQgPSB0cnVlO1xuICAgICAgaWYgKG9yaWdpbmFsRXZlbnQuY2FuY2VsYWJsZSkge1xuICAgICAgICBvcmlnaW5hbEV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICB9XG4gICAgfSxcbiAgICBzdG9wUHJvcGFnYXRpb246ICgpID0+IHtcbiAgICAgIG9yaWdpbmFsRXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgfSxcbiAgfTtcblxuICByZXR1cm4gZXZlbnQ7XG59XG5cbi8qKlxuICogRGV0ZWN0IGlmIHRoZSBkZXZpY2Ugc3VwcG9ydHMgdG91Y2ggZXZlbnRzXG4gKlxuICogQHJldHVybnMgV2hldGhlciB0b3VjaCBpcyBzdXBwb3J0ZWRcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGhhc1RvdWNoU3VwcG9ydCgpOiBib29sZWFuIHtcbiAgY29uc3QgbWF4UG9pbnRzID0gKG5hdmlnYXRvciBhcyBhbnkpLm1heFRvdWNoUG9pbnRzO1xuICByZXR1cm4gKFxuICAgIFwib250b3VjaHN0YXJ0XCIgaW4gd2luZG93IHx8ICh0eXBlb2YgbWF4UG9pbnRzID09PSBcIm51bWJlclwiICYmIG1heFBvaW50cyA+IDApXG4gICk7XG59XG5cbi8qKlxuICogRGV0ZWN0IGlmIHRoZSBkZXZpY2Ugc3VwcG9ydHMgcG9pbnRlciBldmVudHNcbiAqXG4gKiBAcmV0dXJucyBXaGV0aGVyIHBvaW50ZXIgZXZlbnRzIGFyZSBzdXBwb3J0ZWRcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGhhc1BvaW50ZXJTdXBwb3J0KCk6IGJvb2xlYW4ge1xuICByZXR1cm4gISF3aW5kb3cuUG9pbnRlckV2ZW50O1xufVxuXG4vKipcbiAqIEV4dHJhY3Qgbm9ybWFsaXplZCB0b3VjaCBjb29yZGluYXRlcyBmcm9tIGFuIGV2ZW50XG4gKiBXb3JrcyB3aXRoIG1vdXNlIGV2ZW50cywgdG91Y2ggZXZlbnRzIGFuZCBwb2ludGVyIGV2ZW50c1xuICpcbiAqIEBwYXJhbSBlIC0gRE9NIGV2ZW50XG4gKiBAcmV0dXJucyBPYmplY3Qgd2l0aCBjbGllbnRYIGFuZCBjbGllbnRZIGNvb3JkaW5hdGVzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRUb3VjaENvb3JkaW5hdGVzKFxuICBlOiBNb3VzZUV2ZW50IHwgVG91Y2hFdmVudCB8IFBvaW50ZXJFdmVudFxuKTogeyBjbGllbnRYOiBudW1iZXI7IGNsaWVudFk6IG51bWJlciB9IHtcbiAgaWYgKFwidG91Y2hlc1wiIGluIGUgJiYgQXJyYXkuaXNBcnJheShlLnRvdWNoZXMpICYmIGUudG91Y2hlcy5sZW5ndGggPiAwKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIGNsaWVudFg6IGUudG91Y2hlc1swXS5jbGllbnRYLFxuICAgICAgY2xpZW50WTogZS50b3VjaGVzWzBdLmNsaWVudFksXG4gICAgfTtcbiAgfVxuXG4gIHJldHVybiB7XG4gICAgY2xpZW50WDogKGUgYXMgTW91c2VFdmVudCB8IFBvaW50ZXJFdmVudCkuY2xpZW50WCxcbiAgICBjbGllbnRZOiAoZSBhcyBNb3VzZUV2ZW50IHwgUG9pbnRlckV2ZW50KS5jbGllbnRZLFxuICB9O1xufVxuIiwKICAgICIvLyBzcmMvY29yZS9nZXN0dXJlcy90YXAudHNcbi8qKlxuICogQG1vZHVsZSBjb3JlL2dlc3R1cmVzXG4gKiBAZGVzY3JpcHRpb24gVGFwIGdlc3R1cmUgZGV0ZWN0aW9uXG4gKi9cblxuaW1wb3J0IHsgVGFwRXZlbnQsIEdlc3R1cmVEZXRlY3Rpb25Db250ZXh0IH0gZnJvbSAnLi90eXBlcyc7XG5pbXBvcnQgeyBjcmVhdGVHZXN0dXJlRXZlbnQgfSBmcm9tICcuL3V0aWxzJztcblxuLyoqXG4gKiBEZXRlY3QgdGFwIGdlc3R1cmVcbiAqIFxuICogQHBhcmFtIGNvbnRleHQgLSBHZXN0dXJlIGRldGVjdGlvbiBjb250ZXh0XG4gKiBAcmV0dXJucyBUYXAgZXZlbnQgb3IgbnVsbCBpZiBubyB0YXAgZGV0ZWN0ZWRcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGRldGVjdFRhcChjb250ZXh0OiBHZXN0dXJlRGV0ZWN0aW9uQ29udGV4dCk6IFRhcEV2ZW50IHwgbnVsbCB7XG4gIGNvbnN0IHsgc3RhdGUsIG9wdGlvbnMsIG9yaWdpbmFsRXZlbnQgfSA9IGNvbnRleHQ7XG4gIFxuICAvLyBDYWxjdWxhdGUgZGlzdGFuY2UgYmV0d2VlbiBzdGFydCBhbmQgY3VycmVudCBwb3NpdGlvblxuICBjb25zdCBkZWx0YVggPSBzdGF0ZS5jdXJyZW50WCAtIHN0YXRlLnN0YXJ0WDtcbiAgY29uc3QgZGVsdGFZID0gc3RhdGUuY3VycmVudFkgLSBzdGF0ZS5zdGFydFk7XG4gIGNvbnN0IGRpc3RhbmNlID0gTWF0aC5zcXJ0KGRlbHRhWCAqIGRlbHRhWCArIGRlbHRhWSAqIGRlbHRhWSk7XG4gIFxuICAvLyBDaGVjayBpZiBtb3ZlbWVudCBpcyB3aXRoaW4gdGhyZXNob2xkXG4gIGlmIChkaXN0YW5jZSA8IG9wdGlvbnMudGFwRGlzdGFuY2VUaHJlc2hvbGQpIHtcbiAgICAvLyBDaGVjayBmb3IgZG91YmxlIHRhcFxuICAgIGNvbnN0IG5vdyA9IERhdGUubm93KCk7XG4gICAgY29uc3QgaXNEb3VibGVUYXAgPSBub3cgLSBzdGF0ZS5sYXN0VGFwVGltZSA8IDMwMDtcbiAgICBcbiAgICBjb25zdCB0YXBDb3VudCA9IGlzRG91YmxlVGFwID8gc3RhdGUudGFwQ291bnQgKyAxIDogMTtcbiAgICBcbiAgICAvLyBDcmVhdGUgdGFwIGV2ZW50XG4gICAgY29uc3QgdGFwRXZlbnQ6IFRhcEV2ZW50ID0ge1xuICAgICAgLi4uY3JlYXRlR2VzdHVyZUV2ZW50KCd0YXAnLCBvcmlnaW5hbEV2ZW50LCBzdGF0ZSksXG4gICAgICB0eXBlOiAndGFwJyxcbiAgICAgIGNvdW50OiB0YXBDb3VudCxcbiAgICAgIHg6IHN0YXRlLmN1cnJlbnRYLFxuICAgICAgeTogc3RhdGUuY3VycmVudFlcbiAgICB9O1xuICAgIFxuICAgIHJldHVybiB0YXBFdmVudDtcbiAgfVxuICBcbiAgcmV0dXJuIG51bGw7XG59IiwKICAgICIvLyBzcmMvY29yZS9nZXN0dXJlcy9zd2lwZS50c1xuLyoqXG4gKiBAbW9kdWxlIGNvcmUvZ2VzdHVyZXNcbiAqIEBkZXNjcmlwdGlvbiBTd2lwZSBnZXN0dXJlIGRldGVjdGlvblxuICovXG5cbmltcG9ydCB7IFN3aXBlRXZlbnQsIEdlc3R1cmVEZXRlY3Rpb25Db250ZXh0LCBTV0lQRV9ESVJFQ1RJT05TIH0gZnJvbSAnLi90eXBlcyc7XG5pbXBvcnQgeyBjcmVhdGVHZXN0dXJlRXZlbnQgfSBmcm9tICcuL3V0aWxzJztcblxuLyoqXG4gKiBEZXRlcm1pbmUgc3dpcGUgZGlyZWN0aW9uIGJhc2VkIG9uIGRlbHRhIFggYW5kIFlcbiAqIFxuICogQHBhcmFtIGRlbHRhWCAtIERpc3RhbmNlIG1vdmVkIGluIFggZGlyZWN0aW9uXG4gKiBAcGFyYW0gZGVsdGFZIC0gRGlzdGFuY2UgbW92ZWQgaW4gWSBkaXJlY3Rpb25cbiAqIEByZXR1cm5zIERpcmVjdGlvbiBvZiB0aGUgc3dpcGVcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldFN3aXBlRGlyZWN0aW9uKGRlbHRhWDogbnVtYmVyLCBkZWx0YVk6IG51bWJlcik6IFNXSVBFX0RJUkVDVElPTlMge1xuICBpZiAoTWF0aC5hYnMoZGVsdGFYKSA+IE1hdGguYWJzKGRlbHRhWSkpIHtcbiAgICByZXR1cm4gZGVsdGFYID4gMCA/IFNXSVBFX0RJUkVDVElPTlMuUklHSFQgOiBTV0lQRV9ESVJFQ1RJT05TLkxFRlQ7XG4gIH1cbiAgcmV0dXJuIGRlbHRhWSA+IDAgPyBTV0lQRV9ESVJFQ1RJT05TLkRPV04gOiBTV0lQRV9ESVJFQ1RJT05TLlVQO1xufVxuXG4vKipcbiAqIERldGVjdCBzd2lwZSBnZXN0dXJlXG4gKiBcbiAqIEBwYXJhbSBjb250ZXh0IC0gR2VzdHVyZSBkZXRlY3Rpb24gY29udGV4dFxuICogQHJldHVybnMgU3dpcGUgZXZlbnQgb3IgbnVsbCBpZiBubyBzd2lwZSBkZXRlY3RlZFxuICovXG5leHBvcnQgZnVuY3Rpb24gZGV0ZWN0U3dpcGUoY29udGV4dDogR2VzdHVyZURldGVjdGlvbkNvbnRleHQpOiBTd2lwZUV2ZW50IHwgbnVsbCB7XG4gIGNvbnN0IHsgc3RhdGUsIG9wdGlvbnMsIG9yaWdpbmFsRXZlbnQgfSA9IGNvbnRleHQ7XG4gIFxuICAvLyBDYWxjdWxhdGUgZGVsdGFzIGFuZCBkaXN0YW5jZVxuICBjb25zdCBkZWx0YVggPSBzdGF0ZS5jdXJyZW50WCAtIHN0YXRlLnN0YXJ0WDtcbiAgY29uc3QgZGVsdGFZID0gc3RhdGUuY3VycmVudFkgLSBzdGF0ZS5zdGFydFk7XG4gIGNvbnN0IGRpc3RhbmNlID0gTWF0aC5zcXJ0KGRlbHRhWCAqIGRlbHRhWCArIGRlbHRhWSAqIGRlbHRhWSk7XG4gIFxuICAvLyBDYWxjdWxhdGUgdGltZSBhbmQgdmVsb2NpdHlcbiAgY29uc3QgZW5kVGltZSA9IERhdGUubm93KCk7XG4gIGNvbnN0IGRlbHRhVGltZSA9IGVuZFRpbWUgLSBzdGF0ZS5zdGFydFRpbWU7XG4gIGNvbnN0IHZlbG9jaXR5ID0gZGlzdGFuY2UgLyBkZWx0YVRpbWU7XG4gIFxuICAvLyBDaGVjayBpZiBpdCdzIGEgc3dpcGVcbiAgaWYgKGRpc3RhbmNlID49IG9wdGlvbnMuc3dpcGVUaHJlc2hvbGQgJiYgZGVsdGFUaW1lIDw9IG9wdGlvbnMuc3dpcGVUaW1lVGhyZXNob2xkKSB7XG4gICAgY29uc3QgZGlyZWN0aW9uID0gZ2V0U3dpcGVEaXJlY3Rpb24oZGVsdGFYLCBkZWx0YVkpO1xuICAgIFxuICAgIC8vIENyZWF0ZSBzd2lwZSBldmVudFxuICAgIGNvbnN0IHN3aXBlRXZlbnQ6IFN3aXBlRXZlbnQgPSB7XG4gICAgICAuLi5jcmVhdGVHZXN0dXJlRXZlbnQoJ3N3aXBlJywgb3JpZ2luYWxFdmVudCwgc3RhdGUpLFxuICAgICAgdHlwZTogJ3N3aXBlJyxcbiAgICAgIGRpcmVjdGlvbixcbiAgICAgIGRlbHRhWCxcbiAgICAgIGRlbHRhWSxcbiAgICAgIGRpc3RhbmNlLFxuICAgICAgdmVsb2NpdHksXG4gICAgICBzdGFydFg6IHN0YXRlLnN0YXJ0WCxcbiAgICAgIHN0YXJ0WTogc3RhdGUuc3RhcnRZLFxuICAgICAgZW5kWDogc3RhdGUuY3VycmVudFgsXG4gICAgICBlbmRZOiBzdGF0ZS5jdXJyZW50WVxuICAgIH07XG4gICAgXG4gICAgcmV0dXJuIHN3aXBlRXZlbnQ7XG4gIH1cbiAgXG4gIHJldHVybiBudWxsO1xufSIsCiAgICAiLy8gc3JjL2NvcmUvZ2VzdHVyZXMvbG9uZ3ByZXNzLnRzXG4vKipcbiAqIEBtb2R1bGUgY29yZS9nZXN0dXJlc1xuICogQGRlc2NyaXB0aW9uIExvbmcgcHJlc3MgZ2VzdHVyZSBkZXRlY3Rpb25cbiAqL1xuXG5pbXBvcnQgeyBMb25nUHJlc3NFdmVudCwgR2VzdHVyZURldGVjdGlvbkNvbnRleHQgfSBmcm9tICcuL3R5cGVzJztcbmltcG9ydCB7IGNyZWF0ZUdlc3R1cmVFdmVudCB9IGZyb20gJy4vdXRpbHMnO1xuXG4vKipcbiAqIERldGVjdCBsb25nIHByZXNzIGdlc3R1cmVcbiAqIFxuICogVGhpcyBpcyBzbGlnaHRseSBkaWZmZXJlbnQgZnJvbSBvdGhlciBnZXN0dXJlIGRldGVjdG9ycyBhcyBpdCBzZXRzIHVwIGEgdGltZXJcbiAqIGFuZCByZXR1cm5zIGEgY2FsbGJhY2sgZnVuY3Rpb24gdGhhdCB3aWxsIGJlIHRyaWdnZXJlZCB3aGVuIHRoZSB0aW1lciBjb21wbGV0ZXMuXG4gKiBcbiAqIEBwYXJhbSBjb250ZXh0IC0gR2VzdHVyZSBkZXRlY3Rpb24gY29udGV4dFxuICogQHBhcmFtIGNhbGxiYWNrIC0gRnVuY3Rpb24gdG8gY2FsbCB3aGVuIGxvbmcgcHJlc3MgaXMgZGV0ZWN0ZWRcbiAqIEByZXR1cm5zIENsZWFudXAgZnVuY3Rpb24gdG8gY2FuY2VsIHRoZSBsb25nIHByZXNzIGRldGVjdGlvblxuICovXG5leHBvcnQgZnVuY3Rpb24gZGV0ZWN0TG9uZ1ByZXNzKFxuICBjb250ZXh0OiBHZXN0dXJlRGV0ZWN0aW9uQ29udGV4dCxcbiAgY2FsbGJhY2s6IChldmVudDogTG9uZ1ByZXNzRXZlbnQpID0+IHZvaWRcbik6ICgpID0+IHZvaWQge1xuICBjb25zdCB7IHN0YXRlLCBvcHRpb25zLCBvcmlnaW5hbEV2ZW50IH0gPSBjb250ZXh0O1xuICBcbiAgLy8gU2V0IGEgdGltZXIgZm9yIGxvbmcgcHJlc3MgZGV0ZWN0aW9uXG4gIGNvbnN0IHRpbWVyID0gd2luZG93LnNldFRpbWVvdXQoKCkgPT4ge1xuICAgIC8vIE9ubHkgdHJpZ2dlciBpZiBnZXN0dXJlIGlzIHN0aWxsIGFjdGl2ZVxuICAgIGlmIChzdGF0ZS5hY3RpdmUpIHtcbiAgICAgIC8vIENoZWNrIGlmIG1vdmVtZW50IGlzIHdpdGhpbiB0aHJlc2hvbGRcbiAgICAgIGNvbnN0IGRpZmZYID0gTWF0aC5hYnMoc3RhdGUuY3VycmVudFggLSBzdGF0ZS5zdGFydFgpO1xuICAgICAgY29uc3QgZGlmZlkgPSBNYXRoLmFicyhzdGF0ZS5jdXJyZW50WSAtIHN0YXRlLnN0YXJ0WSk7XG4gICAgICBcbiAgICAgIGlmIChkaWZmWCA8IG9wdGlvbnMudGFwRGlzdGFuY2VUaHJlc2hvbGQgJiYgZGlmZlkgPCBvcHRpb25zLnRhcERpc3RhbmNlVGhyZXNob2xkKSB7XG4gICAgICAgIC8vIENyZWF0ZSBsb25nIHByZXNzIGV2ZW50XG4gICAgICAgIGNvbnN0IGxvbmdQcmVzc0V2ZW50OiBMb25nUHJlc3NFdmVudCA9IHtcbiAgICAgICAgICAuLi5jcmVhdGVHZXN0dXJlRXZlbnQoJ2xvbmdwcmVzcycsIG9yaWdpbmFsRXZlbnQsIHN0YXRlKSxcbiAgICAgICAgICB0eXBlOiAnbG9uZ3ByZXNzJyxcbiAgICAgICAgICB4OiBzdGF0ZS5jdXJyZW50WCxcbiAgICAgICAgICB5OiBzdGF0ZS5jdXJyZW50WVxuICAgICAgICB9O1xuICAgICAgICBcbiAgICAgICAgLy8gVHJpZ2dlciBjYWxsYmFja1xuICAgICAgICBjYWxsYmFjayhsb25nUHJlc3NFdmVudCk7XG4gICAgICB9XG4gICAgfVxuICB9LCBvcHRpb25zLmxvbmdQcmVzc1RpbWUpO1xuICBcbiAgLy8gUmV0dXJuIGNsZWFudXAgZnVuY3Rpb25cbiAgcmV0dXJuICgpID0+IHtcbiAgICBjbGVhclRpbWVvdXQodGltZXIpO1xuICB9O1xufVxuXG4vKipcbiAqIENoZWNrIGlmIG1vdmVtZW50IHdvdWxkIGNhbmNlbCBhIGxvbmcgcHJlc3NcbiAqIFxuICogQHBhcmFtIGNvbnRleHQgLSBHZXN0dXJlIGRldGVjdGlvbiBjb250ZXh0XG4gKiBAcmV0dXJucyBXaGV0aGVyIHRoZSBsb25nIHByZXNzIHNob3VsZCBiZSBjYW5jZWxlZFxuICovXG5leHBvcnQgZnVuY3Rpb24gc2hvdWxkQ2FuY2VsTG9uZ1ByZXNzKGNvbnRleHQ6IEdlc3R1cmVEZXRlY3Rpb25Db250ZXh0KTogYm9vbGVhbiB7XG4gIGNvbnN0IHsgc3RhdGUsIG9wdGlvbnMgfSA9IGNvbnRleHQ7XG4gIFxuICBjb25zdCBkaWZmWCA9IE1hdGguYWJzKHN0YXRlLmN1cnJlbnRYIC0gc3RhdGUuc3RhcnRYKTtcbiAgY29uc3QgZGlmZlkgPSBNYXRoLmFicyhzdGF0ZS5jdXJyZW50WSAtIHN0YXRlLnN0YXJ0WSk7XG4gIFxuICByZXR1cm4gZGlmZlggPiBvcHRpb25zLnRhcERpc3RhbmNlVGhyZXNob2xkIHx8IGRpZmZZID4gb3B0aW9ucy50YXBEaXN0YW5jZVRocmVzaG9sZDtcbn0iLAogICAgIi8vIHNyYy9jb3JlL2dlc3R1cmVzL3Bhbi50c1xuLyoqXG4gKiBAbW9kdWxlIGNvcmUvZ2VzdHVyZXNcbiAqIEBkZXNjcmlwdGlvbiBQYW4gZ2VzdHVyZSBkZXRlY3Rpb25cbiAqL1xuXG5pbXBvcnQgeyBQYW5FdmVudCwgR2VzdHVyZURldGVjdGlvbkNvbnRleHQgfSBmcm9tIFwiLi90eXBlc1wiO1xuaW1wb3J0IHsgY3JlYXRlR2VzdHVyZUV2ZW50IH0gZnJvbSBcIi4vdXRpbHNcIjtcblxuLyoqXG4gKiBEZXRlY3QgcGFuIGdlc3R1cmVcbiAqXG4gKiBAcGFyYW0gY29udGV4dCAtIEdlc3R1cmUgZGV0ZWN0aW9uIGNvbnRleHRcbiAqIEByZXR1cm5zIFBhbiBldmVudCBvciBudWxsIGlmIG5vIHNpZ25pZmljYW50IG1vdmVtZW50XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBkZXRlY3RQYW4oY29udGV4dDogR2VzdHVyZURldGVjdGlvbkNvbnRleHQpOiBQYW5FdmVudCB8IG51bGwge1xuICBjb25zdCB7IHN0YXRlLCBvcmlnaW5hbEV2ZW50IH0gPSBjb250ZXh0O1xuXG4gIC8vIENhbGN1bGF0ZSBkZWx0YSBmcm9tIHN0YXJ0IHBvc2l0aW9uXG4gIGNvbnN0IGRlbHRhWCA9IHN0YXRlLmN1cnJlbnRYIC0gc3RhdGUuc3RhcnRYO1xuICBjb25zdCBkZWx0YVkgPSBzdGF0ZS5jdXJyZW50WSAtIHN0YXRlLnN0YXJ0WTtcblxuICAvLyBDYWxjdWxhdGUgZGVsdGEgZnJvbSBsYXN0IHBvc2l0aW9uIHRvIGRldGVybWluZSBpZiB0aGVyZSdzIHNpZ25pZmljYW50IG1vdmVtZW50XG4gIGNvbnN0IG1vdmVEZWx0YVggPSBzdGF0ZS5jdXJyZW50WCAtIHN0YXRlLmxhc3RYO1xuICBjb25zdCBtb3ZlRGVsdGFZID0gc3RhdGUuY3VycmVudFkgLSBzdGF0ZS5sYXN0WTtcbiAgY29uc3QgbW92ZURlbHRhID0gTWF0aC5zcXJ0KFxuICAgIG1vdmVEZWx0YVggKiBtb3ZlRGVsdGFYICsgbW92ZURlbHRhWSAqIG1vdmVEZWx0YVlcbiAgKTtcblxuICAvLyBDaGVjayBpZiBtb3ZlbWVudCBpcyBzaWduaWZpY2FudFxuICBpZiAobW92ZURlbHRhID4gMCkge1xuICAgIC8vIENyZWF0ZSBwYW4gZXZlbnRcbiAgICBjb25zdCBwYW5FdmVudDogUGFuRXZlbnQgPSB7XG4gICAgICAuLi5jcmVhdGVHZXN0dXJlRXZlbnQoXCJwYW5cIiwgb3JpZ2luYWxFdmVudCwgc3RhdGUpLFxuICAgICAgdHlwZTogXCJwYW5cIixcbiAgICAgIGRlbHRhWCxcbiAgICAgIGRlbHRhWSxcbiAgICAgIHN0YXJ0WDogc3RhdGUuc3RhcnRYLFxuICAgICAgc3RhcnRZOiBzdGF0ZS5zdGFydFksXG4gICAgICBjdXJyZW50WDogc3RhdGUuY3VycmVudFgsXG4gICAgICBjdXJyZW50WTogc3RhdGUuY3VycmVudFksXG4gICAgfTtcblxuICAgIHJldHVybiBwYW5FdmVudDtcbiAgfVxuXG4gIHJldHVybiBudWxsO1xufVxuIiwKICAgICIvLyBzcmMvY29yZS9nZXN0dXJlcy9waW5jaC50c1xuLyoqXG4gKiBAbW9kdWxlIGNvcmUvZ2VzdHVyZXNcbiAqIEBkZXNjcmlwdGlvbiBQaW5jaCBnZXN0dXJlIGRldGVjdGlvblxuICovXG5cbmltcG9ydCB7IFBpbmNoRXZlbnQsIEdlc3R1cmVEZXRlY3Rpb25Db250ZXh0IH0gZnJvbSBcIi4vdHlwZXNcIjtcbmltcG9ydCB7IGNyZWF0ZUdlc3R1cmVFdmVudCwgZ2V0RGlzdGFuY2UgfSBmcm9tIFwiLi91dGlsc1wiO1xuXG4vKipcbiAqIERldGVjdCBwaW5jaCBnZXN0dXJlXG4gKlxuICogQHBhcmFtIGNvbnRleHQgLSBHZXN0dXJlIGRldGVjdGlvbiBjb250ZXh0XG4gKiBAcGFyYW0gdG91Y2gxIC0gRmlyc3QgdG91Y2ggcG9pbnRcbiAqIEBwYXJhbSB0b3VjaDIgLSBTZWNvbmQgdG91Y2ggcG9pbnRcbiAqIEByZXR1cm5zIFBpbmNoIGV2ZW50IG9yIG51bGwgaWYgbm8gcGluY2ggZGV0ZWN0ZWRcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGRldGVjdFBpbmNoKFxuICBjb250ZXh0OiBHZXN0dXJlRGV0ZWN0aW9uQ29udGV4dCxcbiAgdG91Y2gxOiBUb3VjaCxcbiAgdG91Y2gyOiBUb3VjaFxuKTogUGluY2hFdmVudCB8IG51bGwge1xuICBjb25zdCB7IHN0YXRlLCBvcmlnaW5hbEV2ZW50IH0gPSBjb250ZXh0O1xuXG4gIC8vIENhbGN1bGF0ZSBjdXJyZW50IGRpc3RhbmNlIGJldHdlZW4gdG91Y2ggcG9pbnRzXG4gIGNvbnN0IGN1cnJlbnREaXN0YW5jZSA9IGdldERpc3RhbmNlKFxuICAgIHRvdWNoMS5jbGllbnRYLFxuICAgIHRvdWNoMS5jbGllbnRZLFxuICAgIHRvdWNoMi5jbGllbnRYLFxuICAgIHRvdWNoMi5jbGllbnRZXG4gICk7XG5cbiAgLy8gTWluaW11bSBtb3ZlbWVudCB0aHJlc2hvbGQgZm9yIHBpbmNoIGRldGVjdGlvblxuICBjb25zdCBQSU5DSF9USFJFU0hPTEQgPSAxMDtcblxuICAvLyBDaGVjayBpZiB0aGUgZGlzdGFuY2UgY2hhbmdlIGlzIHNpZ25pZmljYW50XG4gIGlmIChNYXRoLmFicyhjdXJyZW50RGlzdGFuY2UgLSBzdGF0ZS5zdGFydERpc3RhbmNlKSA+IFBJTkNIX1RIUkVTSE9MRCkge1xuICAgIC8vIENhbGN1bGF0ZSBzY2FsZSBmYWN0b3JcbiAgICBjb25zdCBzY2FsZSA9IGN1cnJlbnREaXN0YW5jZSAvIHN0YXRlLnN0YXJ0RGlzdGFuY2U7XG5cbiAgICAvLyBDYWxjdWxhdGUgY2VudGVyIHBvaW50XG4gICAgY29uc3QgY2VudGVyWCA9ICh0b3VjaDEuY2xpZW50WCArIHRvdWNoMi5jbGllbnRYKSAvIDI7XG4gICAgY29uc3QgY2VudGVyWSA9ICh0b3VjaDEuY2xpZW50WSArIHRvdWNoMi5jbGllbnRZKSAvIDI7XG5cbiAgICAvLyBDcmVhdGUgcGluY2ggZXZlbnRcbiAgICBjb25zdCBwaW5jaEV2ZW50OiBQaW5jaEV2ZW50ID0ge1xuICAgICAgLi4uY3JlYXRlR2VzdHVyZUV2ZW50KFwicGluY2hcIiwgb3JpZ2luYWxFdmVudCwgc3RhdGUpLFxuICAgICAgdHlwZTogXCJwaW5jaFwiLFxuICAgICAgc2NhbGUsXG4gICAgICBjZW50ZXJYLFxuICAgICAgY2VudGVyWSxcbiAgICB9O1xuXG4gICAgcmV0dXJuIHBpbmNoRXZlbnQ7XG4gIH1cblxuICByZXR1cm4gbnVsbDtcbn1cbiIsCiAgICAiLy8gc3JjL2NvcmUvZ2VzdHVyZXMvcm90YXRlLnRzXG4vKipcbiAqIEBtb2R1bGUgY29yZS9nZXN0dXJlc1xuICogQGRlc2NyaXB0aW9uIFJvdGF0ZSBnZXN0dXJlIGRldGVjdGlvblxuICovXG5cbmltcG9ydCB7IFJvdGF0ZUV2ZW50LCBHZXN0dXJlRGV0ZWN0aW9uQ29udGV4dCB9IGZyb20gXCIuL3R5cGVzXCI7XG5pbXBvcnQgeyBjcmVhdGVHZXN0dXJlRXZlbnQsIGdldEFuZ2xlIH0gZnJvbSBcIi4vdXRpbHNcIjtcblxuLyoqXG4gKiBEZXRlY3Qgcm90YXRlIGdlc3R1cmVcbiAqXG4gKiBAcGFyYW0gY29udGV4dCAtIEdlc3R1cmUgZGV0ZWN0aW9uIGNvbnRleHRcbiAqIEBwYXJhbSB0b3VjaDEgLSBGaXJzdCB0b3VjaCBwb2ludFxuICogQHBhcmFtIHRvdWNoMiAtIFNlY29uZCB0b3VjaCBwb2ludFxuICogQHJldHVybnMgUm90YXRlIGV2ZW50IG9yIG51bGwgaWYgbm8gcm90YXRpb24gZGV0ZWN0ZWRcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGRldGVjdFJvdGF0ZShcbiAgY29udGV4dDogR2VzdHVyZURldGVjdGlvbkNvbnRleHQsXG4gIHRvdWNoMTogVG91Y2gsXG4gIHRvdWNoMjogVG91Y2hcbik6IFJvdGF0ZUV2ZW50IHwgbnVsbCB7XG4gIGNvbnN0IHsgc3RhdGUsIG9yaWdpbmFsRXZlbnQgfSA9IGNvbnRleHQ7XG5cbiAgLy8gQ2FsY3VsYXRlIGN1cnJlbnQgYW5nbGUgYmV0d2VlbiB0b3VjaCBwb2ludHNcbiAgY29uc3QgY3VycmVudEFuZ2xlID0gZ2V0QW5nbGUoXG4gICAgdG91Y2gxLmNsaWVudFgsXG4gICAgdG91Y2gxLmNsaWVudFksXG4gICAgdG91Y2gyLmNsaWVudFgsXG4gICAgdG91Y2gyLmNsaWVudFlcbiAgKTtcblxuICAvLyBNaW5pbXVtIHJvdGF0aW9uIHRocmVzaG9sZCBmb3IgZGV0ZWN0aW9uXG4gIGNvbnN0IFJPVEFUSU9OX1RIUkVTSE9MRCA9IDEwO1xuXG4gIC8vIENhbGN1bGF0ZSByb3RhdGlvbiBkaWZmZXJlbmNlXG4gIGNvbnN0IHJvdGF0aW9uRGlmZiA9IGN1cnJlbnRBbmdsZSAtIHN0YXRlLnN0YXJ0QW5nbGU7XG5cbiAgLy8gQ2hlY2sgaWYgcm90YXRpb24gaXMgc2lnbmlmaWNhbnRcbiAgaWYgKE1hdGguYWJzKHJvdGF0aW9uRGlmZikgPiBST1RBVElPTl9USFJFU0hPTEQpIHtcbiAgICAvLyBDYWxjdWxhdGUgY2VudGVyIHBvaW50XG4gICAgY29uc3QgY2VudGVyWCA9ICh0b3VjaDEuY2xpZW50WCArIHRvdWNoMi5jbGllbnRYKSAvIDI7XG4gICAgY29uc3QgY2VudGVyWSA9ICh0b3VjaDEuY2xpZW50WSArIHRvdWNoMi5jbGllbnRZKSAvIDI7XG5cbiAgICAvLyBDcmVhdGUgcm90YXRlIGV2ZW50XG4gICAgY29uc3Qgcm90YXRlRXZlbnQ6IFJvdGF0ZUV2ZW50ID0ge1xuICAgICAgLi4uY3JlYXRlR2VzdHVyZUV2ZW50KFwicm90YXRlXCIsIG9yaWdpbmFsRXZlbnQsIHN0YXRlKSxcbiAgICAgIHR5cGU6IFwicm90YXRlXCIsXG4gICAgICByb3RhdGlvbjogcm90YXRpb25EaWZmLFxuICAgICAgY2VudGVyWCxcbiAgICAgIGNlbnRlclksXG4gICAgfTtcblxuICAgIHJldHVybiByb3RhdGVFdmVudDtcbiAgfVxuXG4gIHJldHVybiBudWxsO1xufVxuIiwKICAgICIvLyBzcmMvY29yZS9nZXN0dXJlcy9tYW5hZ2VyLnRzXG4vKipcbiAqIEBtb2R1bGUgY29yZS9nZXN0dXJlc1xuICogQGRlc2NyaXB0aW9uIEdlc3R1cmUgbWFuYWdlbWVudCBzeXN0ZW0gZm9yIGhhbmRsaW5nIHRvdWNoIGFuZCBtb3VzZSBpbnRlcmFjdGlvbnNcbiAqL1xuXG5pbXBvcnQgeyBcbiAgR2VzdHVyZUNvbmZpZyxcbiAgR2VzdHVyZU1hbmFnZXIsXG4gIEdlc3R1cmVTdGF0ZSxcbiAgR2VzdHVyZUhhbmRsZXIsXG4gIEdlc3R1cmVEZXRlY3Rpb25Db250ZXh0LFxuICBBbnlHZXN0dXJlRXZlbnQsXG4gIEdFU1RVUkVfVFlQRVMsXG4gIFNXSVBFX0RJUkVDVElPTlNcbn0gZnJvbSAnLi90eXBlcyc7XG5cbmltcG9ydCB7IGRldGVjdFRhcCB9IGZyb20gJy4vdGFwJztcbmltcG9ydCB7IGRldGVjdFN3aXBlIH0gZnJvbSAnLi9zd2lwZSc7XG5pbXBvcnQgeyBkZXRlY3RMb25nUHJlc3MsIHNob3VsZENhbmNlbExvbmdQcmVzcyB9IGZyb20gJy4vbG9uZ3ByZXNzJztcbmltcG9ydCB7IGRldGVjdFBhbiB9IGZyb20gJy4vcGFuJztcbmltcG9ydCB7IGRldGVjdFBpbmNoIH0gZnJvbSAnLi9waW5jaCc7XG5pbXBvcnQgeyBkZXRlY3RSb3RhdGUgfSBmcm9tICcuL3JvdGF0ZSc7XG5pbXBvcnQgeyBoYXNUb3VjaFN1cHBvcnQsIGhhc1BvaW50ZXJTdXBwb3J0LCBnZXRUb3VjaENvb3JkaW5hdGVzIH0gZnJvbSAnLi91dGlscyc7XG5cbi8vIFJlLWV4cG9ydCB0eXBlcyBhbmQgY29uc3RhbnRzXG5leHBvcnQgeyBHRVNUVVJFX1RZUEVTLCBTV0lQRV9ESVJFQ1RJT05TIH07XG5cbi8qKlxuICogQ3JlYXRlcyBhIGdlc3R1cmUgbWFuYWdlciBmb3IgaGFuZGxpbmcgdG91Y2ggYW5kIG1vdXNlIGludGVyYWN0aW9uc1xuICogXG4gKiBAcGFyYW0gZWxlbWVudCAtIERPTSBlbGVtZW50IHRvIGF0dGFjaCBnZXN0dXJlIHJlY29nbml0aW9uIHRvXG4gKiBAcGFyYW0gY29uZmlnIC0gQ29uZmlndXJhdGlvbiBvcHRpb25zXG4gKiBAcmV0dXJucyBHZXN0dXJlIG1hbmFnZXIgaW5zdGFuY2VcbiAqL1xuZXhwb3J0IGNvbnN0IGNyZWF0ZUdlc3R1cmVNYW5hZ2VyID0gKFxuICBlbGVtZW50OiBIVE1MRWxlbWVudCxcbiAgY29uZmlnOiBHZXN0dXJlQ29uZmlnID0ge31cbik6IEdlc3R1cmVNYW5hZ2VyID0+IHtcbiAgLy8gRGVmYXVsdCBjb25maWd1cmF0aW9uXG4gIGNvbnN0IG9wdGlvbnM6IFJlcXVpcmVkPEdlc3R1cmVDb25maWc+ID0ge1xuICAgIHN3aXBlVGhyZXNob2xkOiAzMCxcbiAgICBzd2lwZVRpbWVUaHJlc2hvbGQ6IDMwMCxcbiAgICBsb25nUHJlc3NUaW1lOiA1MDAsXG4gICAgdGFwRGlzdGFuY2VUaHJlc2hvbGQ6IDEwLFxuICAgIHByZXZlbnREZWZhdWx0OiB0cnVlLFxuICAgIHN0b3BQcm9wYWdhdGlvbjogZmFsc2UsXG4gICAgLi4uY29uZmlnXG4gIH07XG4gIFxuICAvLyBFdmVudCBoYW5kbGVycyBzdG9yYWdlXG4gIGNvbnN0IGhhbmRsZXJzOiBNYXA8c3RyaW5nLCBTZXQ8R2VzdHVyZUhhbmRsZXI+PiA9IG5ldyBNYXAoKTtcbiAgXG4gIC8vIEdlc3R1cmUgc3RhdGVcbiAgY29uc3Qgc3RhdGU6IEdlc3R1cmVTdGF0ZSA9IHtcbiAgICBhY3RpdmU6IGZhbHNlLFxuICAgIHN0YXJ0VGltZTogMCxcbiAgICBzdGFydFg6IDAsXG4gICAgc3RhcnRZOiAwLFxuICAgIGxhc3RYOiAwLFxuICAgIGxhc3RZOiAwLFxuICAgIGN1cnJlbnRYOiAwLFxuICAgIGN1cnJlbnRZOiAwLFxuICAgIHRvdWNoQ291bnQ6IDAsXG4gICAgbG9uZ1ByZXNzVGltZXI6IG51bGwsXG4gICAgc3RhcnREaXN0YW5jZTogMCxcbiAgICBzdGFydEFuZ2xlOiAwLFxuICAgIGxhc3RUYXBUaW1lOiAwLFxuICAgIHRhcENvdW50OiAwLFxuICAgIHRhcmdldDogbnVsbFxuICB9O1xuICBcbiAgLy8gRGV0ZWN0IGZlYXR1cmUgc3VwcG9ydFxuICBjb25zdCBzdXBwb3J0VG91Y2ggPSBoYXNUb3VjaFN1cHBvcnQoKTtcbiAgY29uc3Qgc3VwcG9ydFBvaW50ZXIgPSBoYXNQb2ludGVyU3VwcG9ydCgpO1xuICAgIFxuICBjb25zdCBnZXN0dXJlU3VwcG9ydCA9IHtcbiAgICB0YXA6IHRydWUsXG4gICAgc3dpcGU6IHRydWUsXG4gICAgc3dpcGVsZWZ0OiB0cnVlLFxuICAgIHN3aXBlcmlnaHQ6IHRydWUsXG4gICAgc3dpcGV1cDogdHJ1ZSxcbiAgICBzd2lwZWRvd246IHRydWUsXG4gICAgbG9uZ3ByZXNzOiB0cnVlLFxuICAgIHBhbjogdHJ1ZSxcbiAgICBwaW5jaDogc3VwcG9ydFRvdWNoIHx8IHN1cHBvcnRQb2ludGVyLFxuICAgIHJvdGF0ZTogc3VwcG9ydFRvdWNoIHx8IHN1cHBvcnRQb2ludGVyXG4gIH07XG4gIFxuICAvKipcbiAgICogRGlzcGF0Y2ggYSBnZXN0dXJlIGV2ZW50XG4gICAqL1xuICBjb25zdCBkaXNwYXRjaEdlc3R1cmUgPSAoZXZlbnQ6IEFueUdlc3R1cmVFdmVudCk6IHZvaWQgPT4ge1xuICAgIC8vIEdldCBoYW5kbGVycyBmb3IgdGhpcyBldmVudCB0eXBlXG4gICAgY29uc3QgZXZlbnRIYW5kbGVycyA9IGhhbmRsZXJzLmdldChldmVudC50eXBlKTtcbiAgICBpZiAoIWV2ZW50SGFuZGxlcnMpIHJldHVybjtcbiAgICBcbiAgICAvLyBDYWxsIGVhY2ggaGFuZGxlclxuICAgIGV2ZW50SGFuZGxlcnMuZm9yRWFjaChoYW5kbGVyID0+IHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGhhbmRsZXIoZXZlbnQpO1xuICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgY29uc29sZS5lcnJvcihgRXJyb3IgaW4gZ2VzdHVyZSBoYW5kbGVyIGZvciAke2V2ZW50LnR5cGV9OmAsIGVycm9yKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICBcbiAgICAvLyBGb3Igc3dpcGUsIGFsc28gZGlzcGF0Y2ggZGlyZWN0aW9uLXNwZWNpZmljIGV2ZW50c1xuICAgIGlmIChldmVudC50eXBlID09PSAnc3dpcGUnICYmICdkaXJlY3Rpb24nIGluIGV2ZW50KSB7XG4gICAgICBjb25zdCBkaXJlY3Rpb25FdmVudCA9IHsgLi4uZXZlbnQsIHR5cGU6IGBzd2lwZSR7ZXZlbnQuZGlyZWN0aW9ufWAgYXMgYW55IH07XG4gICAgICBkaXNwYXRjaEdlc3R1cmUoZGlyZWN0aW9uRXZlbnQgYXMgYW55KTtcbiAgICB9XG4gICAgXG4gICAgLy8gQXBwbHkgZGVmYXVsdCBjb25maWd1cmF0aW9uIGZvciBwcmV2ZW50RGVmYXVsdCBhbmQgc3RvcFByb3BhZ2F0aW9uXG4gICAgaWYgKG9wdGlvbnMucHJldmVudERlZmF1bHQgJiYgIWV2ZW50LmRlZmF1bHRQcmV2ZW50ZWQpIHtcbiAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgfVxuICAgIFxuICAgIGlmIChvcHRpb25zLnN0b3BQcm9wYWdhdGlvbikge1xuICAgICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgfVxuICB9O1xuICBcbiAgLy8gUmVmZXJlbmNlIHRvIHRoZSBsb25ncHJlc3MgY2xlYW51cCBmdW5jdGlvblxuICBsZXQgbG9uZ1ByZXNzQ2xlYW51cDogKCgpID0+IHZvaWQpIHwgbnVsbCA9IG51bGw7XG4gIFxuICAvKipcbiAgICogSGFuZGxlIHRvdWNoL21vdXNlIHN0YXJ0XG4gICAqL1xuICBjb25zdCBoYW5kbGVTdGFydCA9IChlOiBUb3VjaEV2ZW50IHwgTW91c2VFdmVudCB8IFBvaW50ZXJFdmVudCk6IHZvaWQgPT4ge1xuICAgIGNvbnN0IHRvdWNoID0gZ2V0VG91Y2hDb29yZGluYXRlcyhlKTtcbiAgICBjb25zdCB0b3VjaENvdW50ID0gJ3RvdWNoZXMnIGluIGUgPyBlLnRvdWNoZXMubGVuZ3RoIDogMTtcbiAgICBcbiAgICAvLyBTdG9yZSBnZXN0dXJlIHN0YXRlXG4gICAgc3RhdGUuYWN0aXZlID0gdHJ1ZTtcbiAgICBzdGF0ZS5zdGFydFRpbWUgPSBEYXRlLm5vdygpO1xuICAgIHN0YXRlLnN0YXJ0WCA9IHN0YXRlLmxhc3RYID0gc3RhdGUuY3VycmVudFggPSB0b3VjaC5jbGllbnRYO1xuICAgIHN0YXRlLnN0YXJ0WSA9IHN0YXRlLmxhc3RZID0gc3RhdGUuY3VycmVudFkgPSB0b3VjaC5jbGllbnRZO1xuICAgIHN0YXRlLnRvdWNoQ291bnQgPSB0b3VjaENvdW50O1xuICAgIHN0YXRlLnRhcmdldCA9IGUudGFyZ2V0O1xuICAgIFxuICAgIC8vIEhhbmRsZSBtdWx0aS10b3VjaCBnZXN0dXJlc1xuICAgIGlmICh0b3VjaENvdW50ID09PSAyICYmICd0b3VjaGVzJyBpbiBlKSB7XG4gICAgICBjb25zdCB0b3VjaDEgPSBlLnRvdWNoZXNbMF07XG4gICAgICBjb25zdCB0b3VjaDIgPSBlLnRvdWNoZXNbMV07XG4gICAgICBcbiAgICAgIC8vIFNldCBpbml0aWFsIHZhbHVlcyBmb3IgcGluY2ggYW5kIHJvdGF0ZVxuICAgICAgc3RhdGUuc3RhcnREaXN0YW5jZSA9IE1hdGguc3FydChcbiAgICAgICAgTWF0aC5wb3codG91Y2gyLmNsaWVudFggLSB0b3VjaDEuY2xpZW50WCwgMikgKyBcbiAgICAgICAgTWF0aC5wb3codG91Y2gyLmNsaWVudFkgLSB0b3VjaDEuY2xpZW50WSwgMilcbiAgICAgICk7XG4gICAgICBcbiAgICAgIHN0YXRlLnN0YXJ0QW5nbGUgPSBNYXRoLmF0YW4yKFxuICAgICAgICB0b3VjaDIuY2xpZW50WSAtIHRvdWNoMS5jbGllbnRZLFxuICAgICAgICB0b3VjaDIuY2xpZW50WCAtIHRvdWNoMS5jbGllbnRYXG4gICAgICApICogMTgwIC8gTWF0aC5QSTtcbiAgICAgIFxuICAgICAgaWYgKHN0YXRlLnN0YXJ0QW5nbGUgPCAwKSBzdGF0ZS5zdGFydEFuZ2xlICs9IDM2MDtcbiAgICB9XG4gICAgXG4gICAgLy8gU2V0dXAgY29udGV4dCBmb3IgZ2VzdHVyZSBkZXRlY3Rpb25cbiAgICBjb25zdCBjb250ZXh0OiBHZXN0dXJlRGV0ZWN0aW9uQ29udGV4dCA9IHtcbiAgICAgIHN0YXRlLFxuICAgICAgb3B0aW9ucyxcbiAgICAgIG9yaWdpbmFsRXZlbnQ6IGVcbiAgICB9O1xuICAgIFxuICAgIC8vIFN0YXJ0IGxvbmcgcHJlc3MgZGV0ZWN0aW9uXG4gICAgaWYgKGxvbmdQcmVzc0NsZWFudXApIHtcbiAgICAgIGxvbmdQcmVzc0NsZWFudXAoKTtcbiAgICB9XG4gICAgXG4gICAgbG9uZ1ByZXNzQ2xlYW51cCA9IGRldGVjdExvbmdQcmVzcyhjb250ZXh0LCAobG9uZ1ByZXNzRXZlbnQpID0+IHtcbiAgICAgIGRpc3BhdGNoR2VzdHVyZShsb25nUHJlc3NFdmVudCk7XG4gICAgfSk7XG4gIH07XG4gIFxuICAvKipcbiAgICogSGFuZGxlIHRvdWNoL21vdXNlIG1vdmVcbiAgICovXG4gIGNvbnN0IGhhbmRsZU1vdmUgPSAoZTogVG91Y2hFdmVudCB8IE1vdXNlRXZlbnQgfCBQb2ludGVyRXZlbnQpOiB2b2lkID0+IHtcbiAgICBpZiAoIXN0YXRlLmFjdGl2ZSkgcmV0dXJuO1xuICAgIFxuICAgIGNvbnN0IHRvdWNoID0gZ2V0VG91Y2hDb29yZGluYXRlcyhlKTtcbiAgICBjb25zdCB0b3VjaENvdW50ID0gJ3RvdWNoZXMnIGluIGUgPyBlLnRvdWNoZXMubGVuZ3RoIDogMTtcbiAgICBcbiAgICAvLyBVcGRhdGUgcG9zaXRpb25zXG4gICAgc3RhdGUubGFzdFggPSBzdGF0ZS5jdXJyZW50WDtcbiAgICBzdGF0ZS5sYXN0WSA9IHN0YXRlLmN1cnJlbnRZO1xuICAgIHN0YXRlLmN1cnJlbnRYID0gdG91Y2guY2xpZW50WDtcbiAgICBzdGF0ZS5jdXJyZW50WSA9IHRvdWNoLmNsaWVudFk7XG4gICAgXG4gICAgLy8gU2V0dXAgY29udGV4dCBmb3IgZ2VzdHVyZSBkZXRlY3Rpb25cbiAgICBjb25zdCBjb250ZXh0OiBHZXN0dXJlRGV0ZWN0aW9uQ29udGV4dCA9IHtcbiAgICAgIHN0YXRlLFxuICAgICAgb3B0aW9ucyxcbiAgICAgIG9yaWdpbmFsRXZlbnQ6IGVcbiAgICB9O1xuICAgIFxuICAgIC8vIENoZWNrIGlmIHdlIHNob3VsZCBjYW5jZWwgbG9uZ3ByZXNzXG4gICAgaWYgKHNob3VsZENhbmNlbExvbmdQcmVzcyhjb250ZXh0KSAmJiBsb25nUHJlc3NDbGVhbnVwKSB7XG4gICAgICBsb25nUHJlc3NDbGVhbnVwKCk7XG4gICAgICBsb25nUHJlc3NDbGVhbnVwID0gbnVsbDtcbiAgICB9XG4gICAgXG4gICAgLy8gRGV0ZWN0IHBhbiBnZXN0dXJlXG4gICAgY29uc3QgcGFuRXZlbnQgPSBkZXRlY3RQYW4oY29udGV4dCk7XG4gICAgaWYgKHBhbkV2ZW50KSB7XG4gICAgICBkaXNwYXRjaEdlc3R1cmUocGFuRXZlbnQpO1xuICAgIH1cbiAgICBcbiAgICAvLyBNdWx0aS10b3VjaCBnZXN0dXJlc1xuICAgIGlmICh0b3VjaENvdW50ID09PSAyICYmICd0b3VjaGVzJyBpbiBlKSB7XG4gICAgICBjb25zdCB0b3VjaDEgPSBlLnRvdWNoZXNbMF07XG4gICAgICBjb25zdCB0b3VjaDIgPSBlLnRvdWNoZXNbMV07XG4gICAgICBcbiAgICAgIC8vIERldGVjdCBwaW5jaFxuICAgICAgY29uc3QgcGluY2hFdmVudCA9IGRldGVjdFBpbmNoKGNvbnRleHQsIHRvdWNoMSwgdG91Y2gyKTtcbiAgICAgIGlmIChwaW5jaEV2ZW50KSB7XG4gICAgICAgIGRpc3BhdGNoR2VzdHVyZShwaW5jaEV2ZW50KTtcbiAgICAgIH1cbiAgICAgIFxuICAgICAgLy8gRGV0ZWN0IHJvdGF0ZVxuICAgICAgY29uc3Qgcm90YXRlRXZlbnQgPSBkZXRlY3RSb3RhdGUoY29udGV4dCwgdG91Y2gxLCB0b3VjaDIpO1xuICAgICAgaWYgKHJvdGF0ZUV2ZW50KSB7XG4gICAgICAgIGRpc3BhdGNoR2VzdHVyZShyb3RhdGVFdmVudCk7XG4gICAgICB9XG4gICAgfVxuICB9O1xuICBcbiAgLyoqXG4gICAqIEhhbmRsZSB0b3VjaC9tb3VzZSBlbmRcbiAgICovXG4gIGNvbnN0IGhhbmRsZUVuZCA9IChlOiBUb3VjaEV2ZW50IHwgTW91c2VFdmVudCB8IFBvaW50ZXJFdmVudCk6IHZvaWQgPT4ge1xuICAgIGlmICghc3RhdGUuYWN0aXZlKSByZXR1cm47XG4gICAgXG4gICAgLy8gQ2FuY2VsIGFueSBvbmdvaW5nIGxvbmcgcHJlc3MgZGV0ZWN0aW9uXG4gICAgaWYgKGxvbmdQcmVzc0NsZWFudXApIHtcbiAgICAgIGxvbmdQcmVzc0NsZWFudXAoKTtcbiAgICAgIGxvbmdQcmVzc0NsZWFudXAgPSBudWxsO1xuICAgIH1cbiAgICBcbiAgICAvLyBTZXR1cCBjb250ZXh0IGZvciBnZXN0dXJlIGRldGVjdGlvblxuICAgIGNvbnN0IGNvbnRleHQ6IEdlc3R1cmVEZXRlY3Rpb25Db250ZXh0ID0ge1xuICAgICAgc3RhdGUsXG4gICAgICBvcHRpb25zLFxuICAgICAgb3JpZ2luYWxFdmVudDogZVxuICAgIH07XG4gICAgXG4gICAgLy8gRGV0ZWN0IHRhcFxuICAgIGNvbnN0IHRhcEV2ZW50ID0gZGV0ZWN0VGFwKGNvbnRleHQpO1xuICAgIGlmICh0YXBFdmVudCkge1xuICAgICAgLy8gVXBkYXRlIHRhcCBjb3VudCBmb3IgbmV4dCB0YXBcbiAgICAgIHN0YXRlLmxhc3RUYXBUaW1lID0gRGF0ZS5ub3coKTtcbiAgICAgIHN0YXRlLnRhcENvdW50ID0gdGFwRXZlbnQuY291bnQ7XG4gICAgICBcbiAgICAgIGRpc3BhdGNoR2VzdHVyZSh0YXBFdmVudCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIERldGVjdCBzd2lwZVxuICAgICAgY29uc3Qgc3dpcGVFdmVudCA9IGRldGVjdFN3aXBlKGNvbnRleHQpO1xuICAgICAgaWYgKHN3aXBlRXZlbnQpIHtcbiAgICAgICAgZGlzcGF0Y2hHZXN0dXJlKHN3aXBlRXZlbnQpO1xuICAgICAgfVxuICAgIH1cbiAgICBcbiAgICAvLyBSZXNldCBzdGF0ZVxuICAgIHN0YXRlLmFjdGl2ZSA9IGZhbHNlO1xuICB9O1xuICBcbiAgLyoqXG4gICAqIEhhbmRsZSB0b3VjaC9tb3VzZSBjYW5jZWxcbiAgICovXG4gIGNvbnN0IGhhbmRsZUNhbmNlbCA9ICgpOiB2b2lkID0+IHtcbiAgICAvLyBDYW5jZWwgbG9uZyBwcmVzcyBkZXRlY3Rpb25cbiAgICBpZiAobG9uZ1ByZXNzQ2xlYW51cCkge1xuICAgICAgbG9uZ1ByZXNzQ2xlYW51cCgpO1xuICAgICAgbG9uZ1ByZXNzQ2xlYW51cCA9IG51bGw7XG4gICAgfVxuICAgIFxuICAgIC8vIFJlc2V0IHN0YXRlXG4gICAgc3RhdGUuYWN0aXZlID0gZmFsc2U7XG4gIH07XG4gIFxuICAvLyBFdmVudCBsaXN0ZW5lciByZWZlcmVuY2VzXG4gIGxldCBldmVudExpc3RlbmVyczogeyBcbiAgICBbZXZlbnQ6IHN0cmluZ106IEV2ZW50TGlzdGVuZXIgXG4gIH0gPSB7fTtcbiAgXG4gIC8qKlxuICAgKiBTZXQgdXAgZXZlbnQgbGlzdGVuZXJzIGJhc2VkIG9uIGF2YWlsYWJsZSBBUElzXG4gICAqL1xuICBjb25zdCBzZXR1cEV2ZW50TGlzdGVuZXJzID0gKCk6IHZvaWQgPT4ge1xuICAgIGlmIChzdXBwb3J0UG9pbnRlcikge1xuICAgICAgLy8gVXNlIFBvaW50ZXIgRXZlbnRzIEFQSVxuICAgICAgZXZlbnRMaXN0ZW5lcnMgPSB7XG4gICAgICAgIHBvaW50ZXJkb3duOiBoYW5kbGVTdGFydCBhcyBFdmVudExpc3RlbmVyLFxuICAgICAgICBwb2ludGVybW92ZTogaGFuZGxlTW92ZSBhcyBFdmVudExpc3RlbmVyLFxuICAgICAgICBwb2ludGVydXA6IGhhbmRsZUVuZCBhcyBFdmVudExpc3RlbmVyLFxuICAgICAgICBwb2ludGVyY2FuY2VsOiBoYW5kbGVDYW5jZWwgYXMgRXZlbnRMaXN0ZW5lclxuICAgICAgfTtcbiAgICB9IGVsc2UgaWYgKHN1cHBvcnRUb3VjaCkge1xuICAgICAgLy8gVXNlIFRvdWNoIEV2ZW50cyBBUElcbiAgICAgIGV2ZW50TGlzdGVuZXJzID0ge1xuICAgICAgICB0b3VjaHN0YXJ0OiBoYW5kbGVTdGFydCBhcyBFdmVudExpc3RlbmVyLFxuICAgICAgICB0b3VjaG1vdmU6IGhhbmRsZU1vdmUgYXMgRXZlbnRMaXN0ZW5lcixcbiAgICAgICAgdG91Y2hlbmQ6IGhhbmRsZUVuZCBhcyBFdmVudExpc3RlbmVyLFxuICAgICAgICB0b3VjaGNhbmNlbDogaGFuZGxlQ2FuY2VsIGFzIEV2ZW50TGlzdGVuZXJcbiAgICAgIH07XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIEZhbGwgYmFjayB0byBNb3VzZSBFdmVudHMgQVBJXG4gICAgICBldmVudExpc3RlbmVycyA9IHtcbiAgICAgICAgbW91c2Vkb3duOiBoYW5kbGVTdGFydCBhcyBFdmVudExpc3RlbmVyLFxuICAgICAgICBtb3VzZW1vdmU6IGhhbmRsZU1vdmUgYXMgRXZlbnRMaXN0ZW5lcixcbiAgICAgICAgbW91c2V1cDogaGFuZGxlRW5kIGFzIEV2ZW50TGlzdGVuZXIsXG4gICAgICAgIG1vdXNlbGVhdmU6IGhhbmRsZUNhbmNlbCBhcyBFdmVudExpc3RlbmVyXG4gICAgICB9O1xuICAgIH1cbiAgICBcbiAgICAvLyBBZGQgbGlzdGVuZXJzIHRvIGVsZW1lbnRcbiAgICBPYmplY3QuZW50cmllcyhldmVudExpc3RlbmVycykuZm9yRWFjaCgoW2V2ZW50LCBsaXN0ZW5lcl0pID0+IHtcbiAgICAgIGVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihldmVudCwgbGlzdGVuZXIsIHsgcGFzc2l2ZTogIW9wdGlvbnMucHJldmVudERlZmF1bHQgfSk7XG4gICAgfSk7XG4gIH07XG4gIFxuICAvKipcbiAgICogUmVtb3ZlIGFsbCBldmVudCBsaXN0ZW5lcnNcbiAgICovXG4gIGNvbnN0IHJlbW92ZUV2ZW50TGlzdGVuZXJzID0gKCk6IHZvaWQgPT4ge1xuICAgIC8vIFJlbW92ZSBhbGwgbGlzdGVuZXJzIGZyb20gZWxlbWVudFxuICAgIE9iamVjdC5lbnRyaWVzKGV2ZW50TGlzdGVuZXJzKS5mb3JFYWNoKChbZXZlbnQsIGxpc3RlbmVyXSkgPT4ge1xuICAgICAgZWxlbWVudC5yZW1vdmVFdmVudExpc3RlbmVyKGV2ZW50LCBsaXN0ZW5lcik7XG4gICAgfSk7XG4gICAgXG4gICAgLy8gQ2xlYXIgZXZlbnRMaXN0ZW5lcnMgb2JqZWN0XG4gICAgZXZlbnRMaXN0ZW5lcnMgPSB7fTtcbiAgfTtcbiAgXG4gIC8vIEluaXRpYWxpemUgZXZlbnQgbGlzdGVuZXJzXG4gIHNldHVwRXZlbnRMaXN0ZW5lcnMoKTtcbiAgXG4gIHJldHVybiB7XG4gICAgLyoqXG4gICAgICogQWRkIGEgZ2VzdHVyZSBldmVudCBsaXN0ZW5lclxuICAgICAqIEBwYXJhbSBldmVudFR5cGUgLSBUeXBlIG9mIGdlc3R1cmUgdG8gbGlzdGVuIGZvclxuICAgICAqIEBwYXJhbSBoYW5kbGVyIC0gRXZlbnQgaGFuZGxlciBmdW5jdGlvblxuICAgICAqIEByZXR1cm5zIEdlc3R1cmUgbWFuYWdlciBmb3IgY2hhaW5pbmdcbiAgICAgKi9cbiAgICBvbihldmVudFR5cGU6IHN0cmluZywgaGFuZGxlcjogR2VzdHVyZUhhbmRsZXIpOiBHZXN0dXJlTWFuYWdlciB7XG4gICAgICBpZiAoIWhhbmRsZXJzLmhhcyhldmVudFR5cGUpKSB7XG4gICAgICAgIGhhbmRsZXJzLnNldChldmVudFR5cGUsIG5ldyBTZXQoKSk7XG4gICAgICB9XG4gICAgICBcbiAgICAgIGhhbmRsZXJzLmdldChldmVudFR5cGUpIS5hZGQoaGFuZGxlcik7XG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9LFxuICAgIFxuICAgIC8qKlxuICAgICAqIFJlbW92ZSBhIGdlc3R1cmUgZXZlbnQgbGlzdGVuZXJcbiAgICAgKiBAcGFyYW0gZXZlbnRUeXBlIC0gVHlwZSBvZiBnZXN0dXJlXG4gICAgICogQHBhcmFtIGhhbmRsZXIgLSBFdmVudCBoYW5kbGVyIHRvIHJlbW92ZVxuICAgICAqIEByZXR1cm5zIEdlc3R1cmUgbWFuYWdlciBmb3IgY2hhaW5pbmdcbiAgICAgKi9cbiAgICBvZmYoZXZlbnRUeXBlOiBzdHJpbmcsIGhhbmRsZXI6IEdlc3R1cmVIYW5kbGVyKTogR2VzdHVyZU1hbmFnZXIge1xuICAgICAgY29uc3QgZXZlbnRIYW5kbGVycyA9IGhhbmRsZXJzLmdldChldmVudFR5cGUpO1xuICAgICAgaWYgKGV2ZW50SGFuZGxlcnMpIHtcbiAgICAgICAgZXZlbnRIYW5kbGVycy5kZWxldGUoaGFuZGxlcik7XG4gICAgICAgIFxuICAgICAgICBpZiAoZXZlbnRIYW5kbGVycy5zaXplID09PSAwKSB7XG4gICAgICAgICAgaGFuZGxlcnMuZGVsZXRlKGV2ZW50VHlwZSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiB0aGlzO1xuICAgIH0sXG4gICAgXG4gICAgLyoqXG4gICAgICogQ2hlY2sgaWYgYSBnZXN0dXJlIGlzIHN1cHBvcnRlZCBvbiB0aGUgY3VycmVudCBkZXZpY2VcbiAgICAgKiBAcGFyYW0gZ2VzdHVyZVR5cGUgLSBUeXBlIG9mIGdlc3R1cmUgdG8gY2hlY2tcbiAgICAgKiBAcmV0dXJucyBXaGV0aGVyIHRoZSBnZXN0dXJlIGlzIHN1cHBvcnRlZFxuICAgICAqL1xuICAgIGlzU3VwcG9ydGVkKGdlc3R1cmVUeXBlOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICAgIHJldHVybiBnZXN0dXJlVHlwZSBpbiBnZXN0dXJlU3VwcG9ydCAmJiBnZXN0dXJlU3VwcG9ydFtnZXN0dXJlVHlwZSBhcyBrZXlvZiB0eXBlb2YgZ2VzdHVyZVN1cHBvcnRdO1xuICAgIH0sXG4gICAgXG4gICAgLyoqXG4gICAgICogRW5hYmxlIGdlc3R1cmUgcmVjb2duaXRpb24gYnkgYWRkaW5nIGV2ZW50IGxpc3RlbmVyc1xuICAgICAqIEByZXR1cm5zIEdlc3R1cmUgbWFuYWdlciBmb3IgY2hhaW5pbmdcbiAgICAgKi9cbiAgICBlbmFibGUoKTogR2VzdHVyZU1hbmFnZXIge1xuICAgICAgc2V0dXBFdmVudExpc3RlbmVycygpO1xuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfSxcbiAgICBcbiAgICAvKipcbiAgICAgKiBEaXNhYmxlIGdlc3R1cmUgcmVjb2duaXRpb24gYnkgcmVtb3ZpbmcgZXZlbnQgbGlzdGVuZXJzXG4gICAgICogQHJldHVybnMgR2VzdHVyZSBtYW5hZ2VyIGZvciBjaGFpbmluZ1xuICAgICAqL1xuICAgIGRpc2FibGUoKTogR2VzdHVyZU1hbmFnZXIge1xuICAgICAgcmVtb3ZlRXZlbnRMaXN0ZW5lcnMoKTtcbiAgICAgIHJldHVybiB0aGlzO1xuICAgIH0sXG4gICAgXG4gICAgLyoqXG4gICAgICogQ2xlYW4gdXAgZXZlbnQgbGlzdGVuZXJzIGFuZCB0aW1lcnNcbiAgICAgKi9cbiAgICBkZXN0cm95KCk6IHZvaWQge1xuICAgICAgLy8gQ2xlYW4gdXAgbGlzdGVuZXJzXG4gICAgICByZW1vdmVFdmVudExpc3RlbmVycygpO1xuICAgICAgXG4gICAgICAvLyBDbGVhciBsb25nIHByZXNzIHRpbWVyXG4gICAgICBpZiAobG9uZ1ByZXNzQ2xlYW51cCkge1xuICAgICAgICBsb25nUHJlc3NDbGVhbnVwKCk7XG4gICAgICAgIGxvbmdQcmVzc0NsZWFudXAgPSBudWxsO1xuICAgICAgfVxuICAgICAgXG4gICAgICAvLyBDbGVhciBoYW5kbGVyIHJlZmVyZW5jZXNcbiAgICAgIGhhbmRsZXJzLmNsZWFyKCk7XG4gICAgfVxuICB9O1xufTsiCiAgXSwKICAibWFwcGluZ3MiOiAiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQVNPLElBQUs7QUFBQSxDQUFMLENBQUssbUJBQUw7QUFBQSxFQUNMLHdCQUFNO0FBQUEsRUFDTiwwQkFBUTtBQUFBLEVBQ1IsK0JBQWE7QUFBQSxFQUNiLGdDQUFjO0FBQUEsRUFDZCw2QkFBVztBQUFBLEVBQ1gsK0JBQWE7QUFBQSxFQUNiLDBCQUFRO0FBQUEsRUFDUiwyQkFBUztBQUFBLEVBQ1QsK0JBQWE7QUFBQSxFQUNiLHdCQUFNO0FBQUEsR0FWSTtBQWdCTCxJQUFLO0FBQUEsQ0FBTCxDQUFLLHNCQUFMO0FBQUEsRUFDTCwwQkFBSztBQUFBLEVBQ0wsNEJBQU87QUFBQSxFQUNQLDRCQUFPO0FBQUEsRUFDUCw2QkFBUTtBQUFBLEdBSkU7OztBQ1JMLFNBQVMsV0FBVyxDQUN6QixJQUNBLElBQ0EsSUFDQSxJQUNRO0FBQUEsRUFDUixPQUFPLEtBQUssS0FBSyxLQUFLLElBQUksS0FBSyxJQUFJLENBQUMsSUFBSSxLQUFLLElBQUksS0FBSyxJQUFJLENBQUMsQ0FBQztBQUFBO0FBWXZELFNBQVMsUUFBUSxD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QUEsVUFDNUIsU0FBUyxPQUFPLFNBQVM7QUFBQSxRQUMzQjtBQUFBLE1BQ0Y7QUFBQSxNQUNBLE9BQU87QUFBQTtBQUFBLElBUVQsV0FBVyxDQUFDLGFBQThCO0FBQUEsTUFDeEMsT0FBTyxlQUFlLGtCQUFrQixlQUFlO0FBQUE7QUFBQSxJQU96RCxNQUFNLEdBQW1CO0FBQUEsTUFDdkIsb0JBQW9CO0FBQUEsTUFDcEIsT0FBTztBQUFBO0FBQUEsSUFPVCxPQUFPLEdBQW1CO0FBQUEsTUFDeEIscUJBQXFCO0FBQUEsTUFDckIsT0FBTztBQUFBO0FBQUEsSUFNVCxPQUFPLEdBQVM7QUFBQSxNQUVkLHFCQUFxQjtBQUFBLE1BR3JCLElBQUksa0JBQWtCO0FBQUEsUUFDcEIsaUJBQWlCO0FBQUEsUUFDakIsbUJBQW1CO0FBQUEsTUFDckI7QUFBQSxNQUdBLFNBQVMsTUFBTTtBQUFBO0FBQUEsRUFFbkI7QUFBQTsiLAogICJkZWJ1Z0lkIjogIjM0RDhBMTlGQzlFN0RENjc2NDc1NkUyMTY0NzU2RTIxIiwKICAibmFtZXMiOiBbXQp9