UNPKG

102 kBJavaScriptView Raw
1"use strict";
2
3Object.defineProperty(exports, "__esModule", {
4 value: true
5});
6exports.liftAction = liftAction;
7exports.liftReducerWith = liftReducerWith;
8exports.unliftState = unliftState;
9exports.unliftStore = unliftStore;
10exports["default"] = instrument;
11exports.INIT_ACTION = exports.ActionCreators = exports.ActionTypes = void 0;
12
13var _difference = _interopRequireDefault(require("lodash/difference"));
14
15var _union = _interopRequireDefault(require("lodash/union"));
16
17var _isPlainObject = _interopRequireDefault(require("lodash/isPlainObject"));
18
19var _symbolObservable = _interopRequireDefault(require("symbol-observable"));
20
21function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
22
23function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }
24
25function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
26
27function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
28
29function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && Symbol.iterator in Object(iter)) return Array.from(iter); }
30
31function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); }
32
33function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
34
35function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }
36
37function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
38
39function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
40
41function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
42
43var ActionTypes = {
44 PERFORM_ACTION: 'PERFORM_ACTION',
45 RESET: 'RESET',
46 ROLLBACK: 'ROLLBACK',
47 COMMIT: 'COMMIT',
48 SWEEP: 'SWEEP',
49 TOGGLE_ACTION: 'TOGGLE_ACTION',
50 SET_ACTIONS_ACTIVE: 'SET_ACTIONS_ACTIVE',
51 JUMP_TO_STATE: 'JUMP_TO_STATE',
52 JUMP_TO_ACTION: 'JUMP_TO_ACTION',
53 REORDER_ACTION: 'REORDER_ACTION',
54 IMPORT_STATE: 'IMPORT_STATE',
55 LOCK_CHANGES: 'LOCK_CHANGES',
56 PAUSE_RECORDING: 'PAUSE_RECORDING'
57};
58exports.ActionTypes = ActionTypes;
59var isChrome = (typeof window === "undefined" ? "undefined" : _typeof(window)) === 'object' && (typeof window.chrome !== 'undefined' || typeof window.process !== 'undefined' && window.process.type === 'renderer');
60var isChromeOrNode = isChrome || typeof process !== 'undefined' && process.release && process.release.name === 'node';
61
62/**
63 * Action creators to change the History state.
64 */
65var ActionCreators = {
66 performAction: function performAction(action, trace, traceLimit, // eslint-disable-next-line @typescript-eslint/ban-types
67 toExcludeFromTrace) {
68 if (!(0, _isPlainObject["default"])(action)) {
69 throw new Error('Actions must be plain objects. ' + 'Use custom middleware for async actions.');
70 }
71
72 if (typeof action.type === 'undefined') {
73 throw new Error('Actions may not have an undefined "type" property. ' + 'Have you misspelled a constant?');
74 }
75
76 var stack;
77
78 if (trace) {
79 var extraFrames = 0;
80
81 if (typeof trace === 'function') {
82 stack = trace(action);
83 } else {
84 var error = Error();
85 var prevStackTraceLimit;
86
87 if (Error.captureStackTrace && isChromeOrNode) {
88 // avoid error-polyfill
89 if (traceLimit && Error.stackTraceLimit < traceLimit) {
90 prevStackTraceLimit = Error.stackTraceLimit;
91 Error.stackTraceLimit = traceLimit;
92 }
93
94 Error.captureStackTrace(error, toExcludeFromTrace);
95 } else {
96 extraFrames = 3;
97 }
98
99 stack = error.stack;
100 if (prevStackTraceLimit) Error.stackTraceLimit = prevStackTraceLimit;
101
102 if (extraFrames || typeof Error.stackTraceLimit !== 'number' || traceLimit && Error.stackTraceLimit > traceLimit) {
103 if (stack != null) {
104 var frames = stack.split('\n');
105
106 if (traceLimit && frames.length > traceLimit) {
107 stack = frames.slice(0, traceLimit + extraFrames + (frames[0].startsWith('Error') ? 1 : 0)).join('\n');
108 }
109 }
110 }
111 }
112 }
113
114 return {
115 type: ActionTypes.PERFORM_ACTION,
116 action: action,
117 timestamp: Date.now(),
118 stack: stack
119 };
120 },
121 reset: function reset() {
122 return {
123 type: ActionTypes.RESET,
124 timestamp: Date.now()
125 };
126 },
127 rollback: function rollback() {
128 return {
129 type: ActionTypes.ROLLBACK,
130 timestamp: Date.now()
131 };
132 },
133 commit: function commit() {
134 return {
135 type: ActionTypes.COMMIT,
136 timestamp: Date.now()
137 };
138 },
139 sweep: function sweep() {
140 return {
141 type: ActionTypes.SWEEP
142 };
143 },
144 toggleAction: function toggleAction(id) {
145 return {
146 type: ActionTypes.TOGGLE_ACTION,
147 id: id
148 };
149 },
150 setActionsActive: function setActionsActive(start, end) {
151 var active = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true;
152 return {
153 type: ActionTypes.SET_ACTIONS_ACTIVE,
154 start: start,
155 end: end,
156 active: active
157 };
158 },
159 reorderAction: function reorderAction(actionId, beforeActionId) {
160 return {
161 type: ActionTypes.REORDER_ACTION,
162 actionId: actionId,
163 beforeActionId: beforeActionId
164 };
165 },
166 jumpToState: function jumpToState(index) {
167 return {
168 type: ActionTypes.JUMP_TO_STATE,
169 index: index
170 };
171 },
172 jumpToAction: function jumpToAction(actionId) {
173 return {
174 type: ActionTypes.JUMP_TO_ACTION,
175 actionId: actionId
176 };
177 },
178 importState: function importState(nextLiftedState, noRecompute) {
179 return {
180 type: ActionTypes.IMPORT_STATE,
181 nextLiftedState: nextLiftedState,
182 noRecompute: noRecompute
183 };
184 },
185 lockChanges: function lockChanges(status) {
186 return {
187 type: ActionTypes.LOCK_CHANGES,
188 status: status
189 };
190 },
191 pauseRecording: function pauseRecording(status) {
192 return {
193 type: ActionTypes.PAUSE_RECORDING,
194 status: status
195 };
196 }
197};
198exports.ActionCreators = ActionCreators;
199var INIT_ACTION = {
200 type: '@@INIT'
201};
202/**
203 * Computes the next entry with exceptions catching.
204 */
205
206exports.INIT_ACTION = INIT_ACTION;
207
208function computeWithTryCatch(reducer, action, state) {
209 var nextState = state;
210 var nextError;
211
212 try {
213 nextState = reducer(state, action);
214 } catch (err) {
215 nextError = err.toString();
216
217 if (isChrome) {
218 // In Chrome, rethrowing provides better source map support
219 setTimeout(function () {
220 throw err;
221 });
222 } else {
223 console.error(err); // eslint-disable-line no-console
224 }
225 }
226
227 return {
228 state: nextState,
229 error: nextError
230 };
231}
232/**
233 * Computes the next entry in the log by applying an action.
234 */
235
236
237function computeNextEntry(reducer, action, state, shouldCatchErrors) {
238 if (!shouldCatchErrors) {
239 return {
240 state: reducer(state, action)
241 };
242 }
243
244 return computeWithTryCatch(reducer, action, state);
245}
246/**
247 * Runs the reducer on invalidated actions to get a fresh computation log.
248 */
249
250
251function recomputeStates(computedStates, minInvalidatedStateIndex, reducer, committedState, actionsById, stagedActionIds, skippedActionIds, shouldCatchErrors) {
252 // Optimization: exit early and return the same reference
253 // if we know nothing could have changed.
254 if (!computedStates || minInvalidatedStateIndex === -1 || minInvalidatedStateIndex >= computedStates.length && computedStates.length === stagedActionIds.length) {
255 return computedStates;
256 }
257
258 var nextComputedStates = computedStates.slice(0, minInvalidatedStateIndex);
259
260 for (var i = minInvalidatedStateIndex; i < stagedActionIds.length; i++) {
261 var _actionId = stagedActionIds[i];
262 var _action = actionsById[_actionId].action;
263 var previousEntry = nextComputedStates[i - 1];
264 var previousState = previousEntry ? previousEntry.state : committedState;
265 var shouldSkip = skippedActionIds.indexOf(_actionId) > -1;
266 var entry = void 0;
267
268 if (shouldSkip) {
269 entry = previousEntry;
270 } else {
271 if (shouldCatchErrors && previousEntry && previousEntry.error) {
272 entry = {
273 state: previousState,
274 error: 'Interrupted by an error up the chain'
275 };
276 } else {
277 entry = computeNextEntry(reducer, _action, previousState, shouldCatchErrors);
278 }
279 }
280
281 nextComputedStates.push(entry);
282 }
283
284 return nextComputedStates;
285}
286/**
287 * Lifts an app's action into an action on the lifted store.
288 */
289
290
291function liftAction(action, trace, traceLimit, // eslint-disable-next-line @typescript-eslint/ban-types
292toExcludeFromTrace) {
293 return ActionCreators.performAction(action, trace, traceLimit, toExcludeFromTrace);
294}
295
296function isArray(nextLiftedState) {
297 return Array.isArray(nextLiftedState);
298}
299
300/**
301 * Creates a history state reducer from an app's reducer.
302 */
303function liftReducerWith(reducer, initialCommittedState, monitorReducer, options) {
304 var initialLiftedState = {
305 monitorState: monitorReducer(undefined, {}),
306 nextActionId: 1,
307 actionsById: {
308 0: liftAction(INIT_ACTION)
309 },
310 stagedActionIds: [0],
311 skippedActionIds: [],
312 committedState: initialCommittedState,
313 currentStateIndex: 0,
314 computedStates: [],
315 isLocked: options.shouldStartLocked === true,
316 isPaused: options.shouldRecordChanges === false
317 };
318 /**
319 * Manages how the history actions modify the history state.
320 */
321
322 return function (liftedState, liftedAction) {
323 var _ref = liftedState || initialLiftedState,
324 monitorState = _ref.monitorState,
325 actionsById = _ref.actionsById,
326 nextActionId = _ref.nextActionId,
327 stagedActionIds = _ref.stagedActionIds,
328 skippedActionIds = _ref.skippedActionIds,
329 committedState = _ref.committedState,
330 currentStateIndex = _ref.currentStateIndex,
331 computedStates = _ref.computedStates,
332 isLocked = _ref.isLocked,
333 isPaused = _ref.isPaused;
334
335 if (!liftedState) {
336 // Prevent mutating initialLiftedState
337 actionsById = _objectSpread({}, actionsById);
338 }
339
340 function commitExcessActions(n) {
341 // Auto-commits n-number of excess actions.
342 var excess = n;
343 var idsToDelete = stagedActionIds.slice(1, excess + 1);
344
345 for (var i = 0; i < idsToDelete.length; i++) {
346 if (computedStates[i + 1].error) {
347 // Stop if error is found. Commit actions up to error.
348 excess = i;
349 idsToDelete = stagedActionIds.slice(1, excess + 1);
350 break;
351 } else {
352 delete actionsById[idsToDelete[i]];
353 }
354 }
355
356 skippedActionIds = skippedActionIds.filter(function (id) {
357 return idsToDelete.indexOf(id) === -1;
358 });
359 stagedActionIds = [0].concat(_toConsumableArray(stagedActionIds.slice(excess + 1)));
360 committedState = computedStates[excess].state;
361 computedStates = computedStates.slice(excess);
362 currentStateIndex = currentStateIndex > excess ? currentStateIndex - excess : 0;
363 }
364
365 function computePausedAction(shouldInit) {
366 var computedState;
367
368 if (shouldInit) {
369 computedState = computedStates[currentStateIndex];
370 monitorState = monitorReducer(monitorState, liftedAction);
371 } else {
372 computedState = computeNextEntry(reducer, liftedAction.action, computedStates[currentStateIndex].state, false);
373 }
374
375 if (!options.pauseActionType || nextActionId === 1) {
376 return {
377 monitorState: monitorState,
378 actionsById: {
379 0: liftAction(INIT_ACTION)
380 },
381 nextActionId: 1,
382 stagedActionIds: [0],
383 skippedActionIds: [],
384 committedState: computedState.state,
385 currentStateIndex: 0,
386 computedStates: [computedState],
387 isLocked: isLocked,
388 isPaused: true
389 };
390 }
391
392 if (shouldInit) {
393 if (currentStateIndex === stagedActionIds.length - 1) {
394 currentStateIndex++;
395 }
396
397 stagedActionIds = [].concat(_toConsumableArray(stagedActionIds), [nextActionId]);
398 nextActionId++;
399 }
400
401 return {
402 monitorState: monitorState,
403 actionsById: _objectSpread(_objectSpread({}, actionsById), {}, _defineProperty({}, nextActionId - 1, liftAction({
404 type: options.pauseActionType
405 }))),
406 nextActionId: nextActionId,
407 stagedActionIds: stagedActionIds,
408 skippedActionIds: skippedActionIds,
409 committedState: committedState,
410 currentStateIndex: currentStateIndex,
411 computedStates: [].concat(_toConsumableArray(computedStates.slice(0, stagedActionIds.length - 1)), [computedState]),
412 isLocked: isLocked,
413 isPaused: true
414 };
415 } // By default, aggressively recompute every state whatever happens.
416 // This has O(n) performance, so we'll override this to a sensible
417 // value whenever we feel like we don't have to recompute the states.
418
419
420 var minInvalidatedStateIndex = 0; // maxAge number can be changed dynamically
421
422 var maxAge = options.maxAge;
423 if (typeof maxAge === 'function') maxAge = maxAge(liftedAction, liftedState);
424
425 if (/^@@redux\/(INIT|REPLACE)/.test(liftedAction.type)) {
426 if (options.shouldHotReload === false) {
427 actionsById = {
428 0: liftAction(INIT_ACTION)
429 };
430 nextActionId = 1;
431 stagedActionIds = [0];
432 skippedActionIds = [];
433 committedState = computedStates.length === 0 ? initialCommittedState : computedStates[currentStateIndex].state;
434 currentStateIndex = 0;
435 computedStates = [];
436 } // Recompute states on hot reload and init.
437
438
439 minInvalidatedStateIndex = 0;
440
441 if (maxAge && stagedActionIds.length > maxAge) {
442 // States must be recomputed before committing excess.
443 computedStates = recomputeStates(computedStates, minInvalidatedStateIndex, reducer, committedState, actionsById, stagedActionIds, skippedActionIds, options.shouldCatchErrors);
444 commitExcessActions(stagedActionIds.length - maxAge); // Avoid double computation.
445
446 minInvalidatedStateIndex = Infinity;
447 }
448 } else {
449 switch (liftedAction.type) {
450 case ActionTypes.PERFORM_ACTION:
451 {
452 if (isLocked) return liftedState || initialLiftedState;
453 if (isPaused) return computePausedAction(); // Auto-commit as new actions come in.
454
455 if (maxAge && stagedActionIds.length >= maxAge) {
456 commitExcessActions(stagedActionIds.length - maxAge + 1);
457 }
458
459 if (currentStateIndex === stagedActionIds.length - 1) {
460 currentStateIndex++;
461 }
462
463 var _actionId2 = nextActionId++; // Mutation! This is the hottest path, and we optimize on purpose.
464 // It is safe because we set a new key in a cache dictionary.
465
466
467 actionsById[_actionId2] = liftedAction;
468 stagedActionIds = [].concat(_toConsumableArray(stagedActionIds), [_actionId2]); // Optimization: we know that only the new action needs computing.
469
470 minInvalidatedStateIndex = stagedActionIds.length - 1;
471 break;
472 }
473
474 case ActionTypes.RESET:
475 {
476 // Get back to the state the store was created with.
477 actionsById = {
478 0: liftAction(INIT_ACTION)
479 };
480 nextActionId = 1;
481 stagedActionIds = [0];
482 skippedActionIds = [];
483 committedState = initialCommittedState;
484 currentStateIndex = 0;
485 computedStates = [];
486 break;
487 }
488
489 case ActionTypes.COMMIT:
490 {
491 // Consider the last committed state the new starting point.
492 // Squash any staged actions into a single committed state.
493 actionsById = {
494 0: liftAction(INIT_ACTION)
495 };
496 nextActionId = 1;
497 stagedActionIds = [0];
498 skippedActionIds = [];
499 committedState = computedStates[currentStateIndex].state;
500 currentStateIndex = 0;
501 computedStates = [];
502 break;
503 }
504
505 case ActionTypes.ROLLBACK:
506 {
507 // Forget about any staged actions.
508 // Start again from the last committed state.
509 actionsById = {
510 0: liftAction(INIT_ACTION)
511 };
512 nextActionId = 1;
513 stagedActionIds = [0];
514 skippedActionIds = [];
515 currentStateIndex = 0;
516 computedStates = [];
517 break;
518 }
519
520 case ActionTypes.TOGGLE_ACTION:
521 {
522 // Toggle whether an action with given ID is skipped.
523 // Being skipped means it is a no-op during the computation.
524 var _actionId3 = liftedAction.id;
525 var index = skippedActionIds.indexOf(_actionId3);
526
527 if (index === -1) {
528 skippedActionIds = [_actionId3].concat(_toConsumableArray(skippedActionIds));
529 } else {
530 skippedActionIds = skippedActionIds.filter(function (id) {
531 return id !== _actionId3;
532 });
533 } // Optimization: we know history before this action hasn't changed
534
535
536 minInvalidatedStateIndex = stagedActionIds.indexOf(_actionId3);
537 break;
538 }
539
540 case ActionTypes.SET_ACTIONS_ACTIVE:
541 {
542 // Toggle whether an action with given ID is skipped.
543 // Being skipped means it is a no-op during the computation.
544 var start = liftedAction.start,
545 end = liftedAction.end,
546 active = liftedAction.active;
547 var actionIds = [];
548
549 for (var i = start; i < end; i++) {
550 actionIds.push(i);
551 }
552
553 if (active) {
554 skippedActionIds = (0, _difference["default"])(skippedActionIds, actionIds);
555 } else {
556 skippedActionIds = (0, _union["default"])(skippedActionIds, actionIds);
557 } // Optimization: we know history before this action hasn't changed
558
559
560 minInvalidatedStateIndex = stagedActionIds.indexOf(start);
561 break;
562 }
563
564 case ActionTypes.JUMP_TO_STATE:
565 {
566 // Without recomputing anything, move the pointer that tell us
567 // which state is considered the current one. Useful for sliders.
568 currentStateIndex = liftedAction.index; // Optimization: we know the history has not changed.
569
570 minInvalidatedStateIndex = Infinity;
571 break;
572 }
573
574 case ActionTypes.JUMP_TO_ACTION:
575 {
576 // Jumps to a corresponding state to a specific action.
577 // Useful when filtering actions.
578 var _index = stagedActionIds.indexOf(liftedAction.actionId);
579
580 if (_index !== -1) currentStateIndex = _index;
581 minInvalidatedStateIndex = Infinity;
582 break;
583 }
584
585 case ActionTypes.SWEEP:
586 {
587 // Forget any actions that are currently being skipped.
588 stagedActionIds = (0, _difference["default"])(stagedActionIds, skippedActionIds);
589 skippedActionIds = [];
590 currentStateIndex = Math.min(currentStateIndex, stagedActionIds.length - 1);
591 break;
592 }
593
594 case ActionTypes.REORDER_ACTION:
595 {
596 // Recompute actions in a new order.
597 var _actionId4 = liftedAction.actionId;
598 var idx = stagedActionIds.indexOf(_actionId4); // do nothing in case the action is already removed or trying to move the first action
599
600 if (idx < 1) break;
601 var beforeActionId = liftedAction.beforeActionId;
602 var newIdx = stagedActionIds.indexOf(beforeActionId);
603
604 if (newIdx < 1) {
605 // move to the beginning or to the end
606 var count = stagedActionIds.length;
607 newIdx = beforeActionId > stagedActionIds[count - 1] ? count : 1;
608 }
609
610 var diff = idx - newIdx;
611
612 if (diff > 0) {
613 // move left
614 stagedActionIds = [].concat(_toConsumableArray(stagedActionIds.slice(0, newIdx)), [_actionId4], _toConsumableArray(stagedActionIds.slice(newIdx, idx)), _toConsumableArray(stagedActionIds.slice(idx + 1)));
615 minInvalidatedStateIndex = newIdx;
616 } else if (diff < 0) {
617 // move right
618 stagedActionIds = [].concat(_toConsumableArray(stagedActionIds.slice(0, idx)), _toConsumableArray(stagedActionIds.slice(idx + 1, newIdx)), [_actionId4], _toConsumableArray(stagedActionIds.slice(newIdx)));
619 minInvalidatedStateIndex = idx;
620 }
621
622 break;
623 }
624
625 case ActionTypes.IMPORT_STATE:
626 {
627 if (isArray(liftedAction.nextLiftedState)) {
628 // recompute array of actions
629 actionsById = {
630 0: liftAction(INIT_ACTION)
631 };
632 nextActionId = 1;
633 stagedActionIds = [0];
634 skippedActionIds = [];
635 currentStateIndex = liftedAction.nextLiftedState.length;
636 computedStates = [];
637 committedState = liftedAction.preloadedState;
638 minInvalidatedStateIndex = 0; // iterate through actions
639
640 liftedAction.nextLiftedState.forEach(function (action) {
641 actionsById[nextActionId] = liftAction(action, options.trace || options.shouldIncludeCallstack);
642 stagedActionIds.push(nextActionId);
643 nextActionId++;
644 });
645 } else {
646 // Completely replace everything.
647 var _liftedAction$nextLif = liftedAction.nextLiftedState;
648 monitorState = _liftedAction$nextLif.monitorState;
649 actionsById = _liftedAction$nextLif.actionsById;
650 nextActionId = _liftedAction$nextLif.nextActionId;
651 stagedActionIds = _liftedAction$nextLif.stagedActionIds;
652 skippedActionIds = _liftedAction$nextLif.skippedActionIds;
653 committedState = _liftedAction$nextLif.committedState;
654 currentStateIndex = _liftedAction$nextLif.currentStateIndex;
655 computedStates = _liftedAction$nextLif.computedStates;
656
657 if (liftedAction.noRecompute) {
658 minInvalidatedStateIndex = Infinity;
659 }
660 }
661
662 break;
663 }
664
665 case ActionTypes.LOCK_CHANGES:
666 {
667 isLocked = liftedAction.status;
668 minInvalidatedStateIndex = Infinity;
669 break;
670 }
671
672 case ActionTypes.PAUSE_RECORDING:
673 {
674 isPaused = liftedAction.status;
675
676 if (isPaused) {
677 return computePausedAction(true);
678 } // Commit when unpausing
679
680
681 actionsById = {
682 0: liftAction(INIT_ACTION)
683 };
684 nextActionId = 1;
685 stagedActionIds = [0];
686 skippedActionIds = [];
687 committedState = computedStates[currentStateIndex].state;
688 currentStateIndex = 0;
689 computedStates = [];
690 break;
691 }
692
693 default:
694 {
695 // If the action is not recognized, it's a monitor action.
696 // Optimization: a monitor action can't change history.
697 minInvalidatedStateIndex = Infinity;
698 break;
699 }
700 }
701 }
702
703 computedStates = recomputeStates(computedStates, minInvalidatedStateIndex, reducer, committedState, actionsById, stagedActionIds, skippedActionIds, options.shouldCatchErrors);
704 monitorState = monitorReducer(monitorState, liftedAction);
705 return {
706 monitorState: monitorState,
707 actionsById: actionsById,
708 nextActionId: nextActionId,
709 stagedActionIds: stagedActionIds,
710 skippedActionIds: skippedActionIds,
711 committedState: committedState,
712 currentStateIndex: currentStateIndex,
713 computedStates: computedStates,
714 isLocked: isLocked,
715 isPaused: isPaused
716 };
717 };
718}
719/**
720 * Provides an app's view into the state of the lifted store.
721 */
722
723
724function unliftState(liftedState) {
725 var computedStates = liftedState.computedStates,
726 currentStateIndex = liftedState.currentStateIndex;
727 var state = computedStates[currentStateIndex].state;
728 return state;
729}
730
731/**
732 * Provides an app's view into the lifted store.
733 */
734function unliftStore(liftedStore, liftReducer, options) {
735 var lastDefinedState;
736 var trace = options.trace || options.shouldIncludeCallstack;
737 var traceLimit = options.traceLimit || 10;
738
739 function getState() {
740 var state = unliftState(liftedStore.getState());
741
742 if (state !== undefined) {
743 lastDefinedState = state;
744 }
745
746 return lastDefinedState;
747 }
748
749 function dispatch(action) {
750 liftedStore.dispatch(liftAction(action, trace, traceLimit, dispatch));
751 return action;
752 }
753
754 return _objectSpread(_objectSpread({}, liftedStore), {}, _defineProperty({
755 liftedStore: liftedStore,
756 dispatch: dispatch,
757 getState: getState,
758 replaceReducer: function replaceReducer(nextReducer) {
759 liftedStore.replaceReducer(liftReducer(nextReducer));
760 }
761 }, _symbolObservable["default"], function () {
762 return _objectSpread(_objectSpread({}, liftedStore[_symbolObservable["default"]]()), {}, _defineProperty({
763 subscribe: function subscribe(observer) {
764 if (_typeof(observer) !== 'object') {
765 throw new TypeError('Expected the observer to be an object.');
766 }
767
768 function observeState() {
769 if (observer.next) {
770 observer.next(getState());
771 }
772 }
773
774 observeState();
775 var unsubscribe = liftedStore.subscribe(observeState);
776 return {
777 unsubscribe: unsubscribe
778 };
779 }
780 }, _symbolObservable["default"], function () {
781 return this;
782 }));
783 }));
784}
785
786/**
787 * Redux instrumentation store enhancer.
788 */
789function instrument() {
790 var monitorReducer = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : function () {
791 return null;
792 };
793 var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
794
795 if (typeof options.maxAge === 'number' && options.maxAge < 2) {
796 throw new Error('DevTools.instrument({ maxAge }) option, if specified, ' + 'may not be less than 2.');
797 }
798
799 return function (createStore) {
800 return function (reducer, initialState) {
801 function liftReducer(r) {
802 if (typeof r !== 'function') {
803 if (r && typeof r["default"] === 'function') {
804 throw new Error('Expected the reducer to be a function. ' + 'Instead got an object with a "default" field. ' + 'Did you pass a module instead of the default export? ' + 'Try passing require(...).default instead.');
805 }
806
807 throw new Error('Expected the reducer to be a function.');
808 }
809
810 return liftReducerWith(r, initialState, monitorReducer, options);
811 }
812
813 var liftedStore = createStore(liftReducer(reducer));
814
815 if (liftedStore.liftedStore) {
816 throw new Error('DevTools instrumentation should not be applied more than once. ' + 'Check your store configuration.');
817 }
818
819 return unliftStore(liftedStore, liftReducer, options);
820 };
821 };
822}
823//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9pbnN0cnVtZW50LnRzIl0sIm5hbWVzIjpbIkFjdGlvblR5cGVzIiwiUEVSRk9STV9BQ1RJT04iLCJSRVNFVCIsIlJPTExCQUNLIiwiQ09NTUlUIiwiU1dFRVAiLCJUT0dHTEVfQUNUSU9OIiwiU0VUX0FDVElPTlNfQUNUSVZFIiwiSlVNUF9UT19TVEFURSIsIkpVTVBfVE9fQUNUSU9OIiwiUkVPUkRFUl9BQ1RJT04iLCJJTVBPUlRfU1RBVEUiLCJMT0NLX0NIQU5HRVMiLCJQQVVTRV9SRUNPUkRJTkciLCJpc0Nocm9tZSIsIndpbmRvdyIsImNocm9tZSIsInByb2Nlc3MiLCJ0eXBlIiwiaXNDaHJvbWVPck5vZGUiLCJyZWxlYXNlIiwibmFtZSIsIkFjdGlvbkNyZWF0b3JzIiwicGVyZm9ybUFjdGlvbiIsImFjdGlvbiIsInRyYWNlIiwidHJhY2VMaW1pdCIsInRvRXhjbHVkZUZyb21UcmFjZSIsIkVycm9yIiwic3RhY2siLCJleHRyYUZyYW1lcyIsImVycm9yIiwicHJldlN0YWNrVHJhY2VMaW1pdCIsImNhcHR1cmVTdGFja1RyYWNlIiwic3RhY2tUcmFjZUxpbWl0IiwiZnJhbWVzIiwic3BsaXQiLCJsZW5ndGgiLCJzbGljZSIsInN0YXJ0c1dpdGgiLCJqb2luIiwidGltZXN0YW1wIiwiRGF0ZSIsIm5vdyIsInJlc2V0Iiwicm9sbGJhY2siLCJjb21taXQiLCJzd2VlcCIsInRvZ2dsZUFjdGlvbiIsImlkIiwic2V0QWN0aW9uc0FjdGl2ZSIsInN0YXJ0IiwiZW5kIiwiYWN0aXZlIiwicmVvcmRlckFjdGlvbiIsImFjdGlvbklkIiwiYmVmb3JlQWN0aW9uSWQiLCJqdW1wVG9TdGF0ZSIsImluZGV4IiwianVtcFRvQWN0aW9uIiwiaW1wb3J0U3RhdGUiLCJuZXh0TGlmdGVkU3RhdGUiLCJub1JlY29tcHV0ZSIsImxvY2tDaGFuZ2VzIiwic3RhdHVzIiwicGF1c2VSZWNvcmRpbmciLCJJTklUX0FDVElPTiIsImNvbXB1dGVXaXRoVHJ5Q2F0Y2giLCJyZWR1Y2VyIiwic3RhdGUiLCJuZXh0U3RhdGUiLCJuZXh0RXJyb3IiLCJlcnIiLCJ0b1N0cmluZyIsInNldFRpbWVvdXQiLCJjb25zb2xlIiwiY29tcHV0ZU5leHRFbnRyeSIsInNob3VsZENhdGNoRXJyb3JzIiwicmVjb21wdXRlU3RhdGVzIiwiY29tcHV0ZWRTdGF0ZXMiLCJtaW5JbnZhbGlkYXRlZFN0YXRlSW5kZXgiLCJjb21taXR0ZWRTdGF0ZSIsImFjdGlvbnNCeUlkIiwic3RhZ2VkQWN0aW9uSWRzIiwic2tpcHBlZEFjdGlvbklkcyIsIm5leHRDb21wdXRlZFN0YXRlcyIsImkiLCJwcmV2aW91c0VudHJ5IiwicHJldmlvdXNTdGF0ZSIsInNob3VsZFNraXAiLCJpbmRleE9mIiwiZW50cnkiLCJwdXNoIiwibGlmdEFjdGlvbiIsImlzQXJyYXkiLCJBcnJheSIsImxpZnRSZWR1Y2VyV2l0aCIsImluaXRpYWxDb21taXR0ZWRTdGF0ZSIsIm1vbml0b3JSZWR1Y2VyIiwib3B0aW9ucyIsImluaXRpYWxMaWZ0ZWRTdGF0ZSIsIm1vbml0b3JTdGF0ZSIsInVuZGVmaW5lZCIsIm5leHRBY3Rpb25JZCIsImN1cnJlbnRTdGF0ZUluZGV4IiwiaXNMb2NrZWQiLCJzaG91bGRTdGFydExvY2tlZCIsImlzUGF1c2VkIiwic2hvdWxkUmVjb3JkQ2hhbmdlcyIsImxpZnRlZFN0YXRlIiwibGlmdGVkQWN0aW9uIiwiY29tbWl0RXhjZXNzQWN0aW9ucyIsIm4iLCJleGNlc3MiLCJpZHNUb0RlbGV0ZSIsImZpbHRlciIsImNvbXB1dGVQYXVzZWRBY3Rpb24iLCJzaG91bGRJbml0IiwiY29tcHV0ZWRTdGF0ZSIsInBhdXNlQWN0aW9uVHlwZSIsIm1heEFnZSIsInRlc3QiLCJzaG91bGRIb3RSZWxvYWQiLCJJbmZpbml0eSIsImFjdGlvbklkcyIsIk1hdGgiLCJtaW4iLCJpZHgiLCJuZXdJZHgiLCJjb3VudCIsImRpZmYiLCJwcmVsb2FkZWRTdGF0ZSIsImZvckVhY2giLCJzaG91bGRJbmNsdWRlQ2FsbHN0YWNrIiwidW5saWZ0U3RhdGUiLCJ1bmxpZnRTdG9yZSIsImxpZnRlZFN0b3JlIiwibGlmdFJlZHVjZXIiLCJsYXN0RGVmaW5lZFN0YXRlIiwiZ2V0U3RhdGUiLCJkaXNwYXRjaCIsInJlcGxhY2VSZWR1Y2VyIiwibmV4dFJlZHVjZXIiLCIkJG9ic2VydmFibGUiLCJzdWJzY3JpYmUiLCJvYnNlcnZlciIsIlR5cGVFcnJvciIsIm9ic2VydmVTdGF0ZSIsIm5leHQiLCJ1bnN1YnNjcmliZSIsImluc3RydW1lbnQiLCJjcmVhdGVTdG9yZSIsImluaXRpYWxTdGF0ZSIsInIiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7OztBQUFBOztBQUNBOztBQUNBOztBQUNBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFXTyxJQUFNQSxXQUFXLEdBQUc7QUFDekJDLEVBQUFBLGNBQWMsRUFBRSxnQkFEUztBQUV6QkMsRUFBQUEsS0FBSyxFQUFFLE9BRmtCO0FBR3pCQyxFQUFBQSxRQUFRLEVBQUUsVUFIZTtBQUl6QkMsRUFBQUEsTUFBTSxFQUFFLFFBSmlCO0FBS3pCQyxFQUFBQSxLQUFLLEVBQUUsT0FMa0I7QUFNekJDLEVBQUFBLGFBQWEsRUFBRSxlQU5VO0FBT3pCQyxFQUFBQSxrQkFBa0IsRUFBRSxvQkFQSztBQVF6QkMsRUFBQUEsYUFBYSxFQUFFLGVBUlU7QUFTekJDLEVBQUFBLGNBQWMsRUFBRSxnQkFUUztBQVV6QkMsRUFBQUEsY0FBYyxFQUFFLGdCQVZTO0FBV3pCQyxFQUFBQSxZQUFZLEVBQUUsY0FYVztBQVl6QkMsRUFBQUEsWUFBWSxFQUFFLGNBWlc7QUFhekJDLEVBQUFBLGVBQWUsRUFBRTtBQWJRLENBQXBCOztBQWdCUCxJQUFNQyxRQUFRLEdBQ1osUUFBT0MsTUFBUCx5Q0FBT0EsTUFBUCxPQUFrQixRQUFsQixLQUNDLE9BQVFBLE1BQUQsQ0FBZ0RDLE1BQXZELEtBQ0MsV0FERCxJQUVFLE9BQU9ELE1BQU0sQ0FBQ0UsT0FBZCxLQUEwQixXQUExQixJQUNFRixNQUFNLENBQUNFLE9BQVIsQ0FBOERDLElB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bkJDLE9BSm1CLENBQXRCO0FBTUQ7O0FBRUQsVUFBTXFDLFdBQVcsR0FBR2UsV0FBVyxDQUFDZCxXQUFXLENBQUNyRSxPQUFELENBQVosQ0FBL0I7O0FBQ0EsVUFDR29FLFdBQUQsQ0FTS0EsV0FWUCxFQVdFO0FBQ0EsY0FBTSxJQUFJNUcsS0FBSixDQUNKLG9FQUNFLGlDQUZFLENBQU47QUFJRDs7QUFFRCxhQUFPMkcsV0FBVyxDQVFoQkMsV0FSZ0IsRUFTaEJDLFdBVGdCLEVBVWZ0QyxPQVZlLENBQWxCO0FBWUQsS0F6RE07QUFBQSxHQUFQO0FBMEREIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IGRpZmZlcmVuY2UgZnJvbSAnbG9kYXNoL2RpZmZlcmVuY2UnO1xuaW1wb3J0IHVuaW9uIGZyb20gJ2xvZGFzaC91bmlvbic7XG5pbXBvcnQgaXNQbGFpbk9iamVjdCBmcm9tICdsb2Rhc2gvaXNQbGFpbk9iamVjdCc7XG5pbXBvcnQgJCRvYnNlcnZhYmxlIGZyb20gJ3N5bWJvbC1vYnNlcnZhYmxlJztcbmltcG9ydCB7XG4gIEFjdGlvbixcbiAgT2JzZXJ2YWJsZSxcbiAgUHJlbG9hZGVkU3RhdGUsXG4gIFJlZHVjZXIsXG4gIFN0b3JlLFxuICBTdG9yZUVuaGFuY2VyLFxuICBTdG9yZUVuaGFuY2VyU3RvcmVDcmVhdG9yLFxufSBmcm9tICdyZWR1eCc7XG5cbmV4cG9ydCBjb25zdCBBY3Rpb25UeXBlcyA9IHtcbiAgUEVSRk9STV9BQ1RJT046ICdQRVJGT1JNX0FDVElPTicsXG4gIFJFU0VUOiAnUkVTRVQnLFxuICBST0xMQkFDSzogJ1JPTExCQUNLJyxcbiAgQ09NTUlUOiAnQ09NTUlUJyxcbiAgU1dFRVA6ICdTV0VFUCcsXG4gIFRPR0dMRV9BQ1RJT046ICdUT0dHTEVfQUNUSU9OJyxcbiAgU0VUX0FDVElPTlNfQUNUSVZFOiAnU0VUX0FDVElPTlNfQUNUSVZFJyxcbiAgSlVNUF9UT19TVEFURTogJ0pVTVBfVE9fU1RBVEUnLFxuICBKVU1QX1RPX0FDVElPTjogJ0pVTVBfVE9fQUNUSU9OJyxcbiAgUkVPUkRFUl9BQ1RJT046ICdSRU9SREVSX0FDVElPTicsXG4gIElNUE9SVF9TVEFURTogJ0lNUE9SVF9TVEFURScsXG4gIExPQ0tfQ0hBTkdFUzogJ0xPQ0tfQ0hBTkdFUycsXG4gIFBBVVNFX1JFQ09SRElORzogJ1BBVVNFX1JFQ09SRElORycsXG59IGFzIGNvbnN0O1xuXG5jb25zdCBpc0Nocm9tZSA9XG4gIHR5cGVvZiB3aW5kb3cgPT09ICdvYmplY3QnICYmXG4gICh0eXBlb2YgKHdpbmRvdyBhcyB0eXBlb2Ygd2luZG93ICYgeyBjaHJvbWU6IHVua25vd24gfSkuY2hyb21lICE9PVxuICAgICd1bmRlZmluZWQnIHx8XG4gICAgKHR5cGVvZiB3aW5kb3cucHJvY2VzcyAhPT0gJ3VuZGVmaW5lZCcgJiZcbiAgICAgICh3aW5kb3cucHJvY2VzcyBhcyB0eXBlb2Ygd2luZG93LnByb2Nlc3MgJiB7IHR5cGU6IHVua25vd24gfSkudHlwZSA9PT1cbiAgICAgICAgJ3JlbmRlcmVyJykpO1xuXG5jb25zdCBpc0Nocm9tZU9yTm9kZSA9XG4gIGlzQ2hyb21lIHx8XG4gICh0eXBlb2YgcHJvY2VzcyAhPT0gJ3VuZGVmaW5lZCcgJiZcbiAgICBwcm9jZXNzLnJlbGVhc2UgJiZcbiAgICBwcm9jZXNzLnJlbGVhc2UubmFtZSA9PT0gJ25vZGUnKTtcblxuZXhwb3J0IGludGVyZmFjZSBQZXJmb3JtQWN0aW9uPEEgZXh0ZW5kcyBBY3Rpb248dW5rbm93bj4+IHtcbiAgdHlwZTogdHlwZW9mIEFjdGlvblR5cGVzLlBFUkZPUk1fQUNUSU9OO1xuICBhY3Rpb246IEE7XG4gIHRpbWVzdGFtcDogbnVtYmVyO1xuICBzdGFjazogc3RyaW5nIHwgdW5kZWZpbmVkO1xufVxuXG5pbnRlcmZhY2UgUmVzZXRBY3Rpb24ge1xuICB0eXBlOiB0eXBlb2YgQWN0aW9uVHlwZXMuUkVTRVQ7XG4gIHRpbWVzdGFtcDogbnVtYmVyO1xufVxuXG5pbnRlcmZhY2UgUm9sbGJhY2tBY3Rpb24ge1xuICB0eXBlOiB0eXBlb2YgQWN0aW9uVHlwZXMuUk9MTEJBQ0s7XG4gIHRpbWVzdGFtcDogbnVtYmVyO1xufVxuXG5pbnRlcmZhY2UgQ29tbWl0QWN0aW9uIHtcbiAgdHlwZTogdHlwZW9mIEFjdGlvblR5cGVzLkNPTU1JVDtcbiAgdGltZXN0YW1wOiBudW1iZXI7XG59XG5cbmludGVyZmFjZSBTd2VlcEFjdGlvbiB7XG4gIHR5cGU6IHR5cGVvZiBBY3Rpb25UeXBlcy5TV0VFUDtcbn1cblxuaW50ZXJmYWNlIFRvZ2dsZUFjdGlvbiB7XG4gIHR5cGU6IHR5cGVvZiBBY3Rpb25UeXBlcy5UT0dHTEVfQUNUSU9OO1xuICBpZDogbnVtYmVyO1xufVxuXG5pbnRlcmZhY2UgU2V0QWN0aW9uc0FjdGl2ZUFjdGlvbiB7XG4gIHR5cGU6IHR5cGVvZiBBY3Rpb25UeXBlcy5TRVRfQUNUSU9OU19BQ1RJVkU7XG4gIHN0YXJ0OiBudW1iZXI7XG4gIGVuZDogbnVtYmVyO1xuICBhY3RpdmU6IGJvb2xlYW47XG59XG5cbmludGVyZmFjZSBSZW9yZGVyQWN0aW9uIHtcbiAgdHlwZTogdHlwZW9mIEFjdGlvblR5cGVzLlJFT1JERVJfQUNUSU9OO1xuICBhY3Rpb25JZDogbnVtYmVyO1xuICBiZWZvcmVBY3Rpb25JZDogbnVtYmVyO1xufVxuXG5pbnRlcmZhY2UgSnVtcFRvU3RhdGVBY3Rpb24ge1xuICB0eXBlOiB0eXBlb2YgQWN0aW9uVHlwZXMuSlVNUF9UT19TVEFURTtcbiAgaW5kZXg6IG51bWJlcjtcbn1cblxuaW50ZXJmYWNlIEp1bXBUb0FjdGlvbkFjdGlvbiB7XG4gIHR5cGU6IHR5cGVvZiBBY3Rpb25UeXBlcy5KVU1QX1RPX0FDVElPTjtcbiAgYWN0aW9uSWQ6IG51bWJlcjtcbn1cblxuaW50ZXJmYWNlIEltcG9ydFN0YXRlQWN0aW9uPFMsIEEgZXh0ZW5kcyBBY3Rpb248dW5rbm93bj4sIE1vbml0b3JTdGF0ZT4ge1xuICB0eXBlOiB0eXBlb2YgQWN0aW9uVHlwZXMuSU1QT1JUX1NUQVRFO1xuICBuZXh0TGlmdGVkU3RhdGU6IExpZnRlZFN0YXRlPFMsIEEsIE1vbml0b3JTdGF0ZT4gfCByZWFkb25seSBBW107XG4gIHByZWxvYWRlZFN0YXRlPzogUztcbiAgbm9SZWNvbXB1dGU6IGJvb2xlYW4gfCB1bmRlZmluZWQ7XG59XG5cbmludGVyZmFjZSBMb2NrQ2hhbmdlc0FjdGlvbiB7XG4gIHR5cGU6IHR5cGVvZiBBY3Rpb25UeXBlcy5MT0NLX0NIQU5HRVM7XG4gIHN0YXR1czogYm9vbGVhbjtcbn1cblxuaW50ZXJmYWNlIFBhdXNlUmVjb3JkaW5nQWN0aW9uIHtcbiAgdHlwZTogdHlwZW9mIEFjdGlvblR5cGVzLlBBVVNFX1JFQ09SRElORztcbiAgc3RhdHVzOiBib29sZWFuO1xufVxuXG5leHBvcnQgdHlwZSBMaWZ0ZWRBY3Rpb248UywgQSBleHRlbmRzIEFjdGlvbjx1bmtub3duPiwgTW9uaXRvclN0YXRlPiA9XG4gIHwgUGVyZm9ybUFjdGlvbjxBPlxuICB8IFJlc2V0QWN0aW9uXG4gIHwgUm9sbGJhY2tBY3Rpb25cbiAgfCBDb21taXRBY3Rpb25cbiAgfCBTd2VlcEFjdGlvblxuICB8IFRvZ2dsZUFjdGlvblxuICB8IFNldEFjdGlvbnNBY3RpdmVBY3Rpb25cbiAgfCBSZW9yZGVyQWN0aW9uXG4gIHwgSnVtcFRvU3RhdGVBY3Rpb25cbiAgfCBKdW1wVG9BY3Rpb25BY3Rpb25cbiAgfCBJbXBvcnRTdGF0ZUFjdGlvbjxTLCBBLCBNb25pdG9yU3RhdGU+XG4gIHwgTG9ja0NoYW5nZXNBY3Rpb25cbiAgfCBQYXVzZVJlY29yZGluZ0FjdGlvbjtcblxuLyoqXG4gKiBBY3Rpb24gY3JlYXRvcnMgdG8gY2hhbmdlIHRoZSBIaXN0b3J5IHN0YXRlLlxuICovXG5leHBvcnQgY29uc3QgQWN0aW9uQ3JlYXRvcnMgPSB7XG4gIHBlcmZvcm1BY3Rpb248QSBleHRlbmRzIEFjdGlvbjx1bmtub3duPj4oXG4gICAgYWN0aW9uOiBBLFxuICAgIHRyYWNlPzogKChhY3Rpb246IEEpID0+IHN0cmluZyB8IHVuZGVmaW5lZCkgfCBib29sZWFuLFxuICAgIHRyYWNlTGltaXQ/OiBudW1iZXIsXG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9iYW4tdHlwZXNcbiAgICB0b0V4Y2x1ZGVGcm9tVHJhY2U/OiBGdW5jdGlvblxuICApIHtcbiAgICBpZiAoIWlzUGxhaW5PYmplY3QoYWN0aW9uKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAnQWN0aW9ucyBtdXN0IGJlIHBsYWluIG9iamVjdHMuICcgK1xuICAgICAgICAgICdVc2UgY3VzdG9tIG1pZGRsZXdhcmUgZm9yIGFzeW5jIGFjdGlvbnMuJ1xuICAgICAgKTtcbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIGFjdGlvbi50eXBlID09PSAndW5kZWZpbmVkJykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAnQWN0aW9ucyBtYXkgbm90IGhhdmUgYW4gdW5kZWZpbmVkIFwidHlwZVwiIHByb3BlcnR5LiAnICtcbiAgICAgICAgICAnSGF2ZSB5b3UgbWlzc3BlbGxlZCBhIGNvbnN0YW50PydcbiAgICAgICk7XG4gICAgfVxuXG4gICAgbGV0IHN0YWNrO1xuICAgIGlmICh0cmFjZSkge1xuICAgICAgbGV0IGV4dHJhRnJhbWVzID0gMDtcbiAgICAgIGlmICh0eXBlb2YgdHJhY2UgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgc3RhY2sgPSB0cmFjZShhY3Rpb24pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29uc3QgZXJyb3IgPSBFcnJvcigpO1xuICAgICAgICBsZXQgcHJldlN0YWNrVHJhY2VMaW1pdDtcbiAgICAgICAgaWYgKEVycm9yLmNhcHR1cmVTdGFja1RyYWNlICYmIGlzQ2hyb21lT3JOb2RlKSB7XG4gICAgICAgICAgLy8gYXZvaWQgZXJyb3ItcG9seWZpbGxcbiAgICAgICAgICBpZiAodHJhY2VMaW1pdCAmJiBFcnJvci5zdGFja1RyYWNlTGltaXQgPCB0cmFjZUxpbWl0KSB7XG4gICAgICAgICAgICBwcmV2U3RhY2tUcmFjZUxpbWl0ID0gRXJyb3Iuc3RhY2tUcmFjZUxpbWl0O1xuICAgICAgICAgICAgRXJyb3Iuc3RhY2tUcmFjZUxpbWl0ID0gdHJhY2VMaW1pdDtcbiAgICAgICAgICB9XG4gICAgICAgICAgRXJyb3IuY2FwdHVyZVN0YWNrVHJhY2UoZXJyb3IsIHRvRXhjbHVkZUZyb21UcmFjZSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgZXh0cmFGcmFtZXMgPSAzO1xuICAgICAgICB9XG4gICAgICAgIHN0YWNrID0gZXJyb3Iuc3RhY2s7XG4gICAgICAgIGlmIChwcmV2U3RhY2tUcmFjZUxpbWl0KSBFcnJvci5zdGFja1RyYWNlTGltaXQgPSBwcmV2U3RhY2tUcmFjZUxpbWl0O1xuICAgICAgICBpZiAoXG4gICAgICAgICAgZXh0cmFGcmFtZXMgfHxcbiAgICAgICAgICB0eXBlb2YgRXJyb3Iuc3RhY2tUcmFjZUxpbWl0ICE9PSAnbnVtYmVyJyB8fFxuICAgICAgICAgICh0cmFjZUxpbWl0ICYmIEVycm9yLnN0YWNrVHJhY2VMaW1pdCA+IHRyYWNlTGltaXQpXG4gICAgICAgICkge1xuICAgICAgICAgIGlmIChzdGFjayAhPSBudWxsKSB7XG4gICAgICAgICAgICBjb25zdCBmcmFtZXMgPSBzdGFjay5zcGxpdCgnXFxuJyk7XG4gICAgICAgICAgICBpZiAodHJhY2VMaW1pdCAmJiBmcmFtZXMubGVuZ3RoID4gdHJhY2VMaW1pdCkge1xuICAgICAgICAgICAgICBzdGFjayA9IGZyYW1lc1xuICAgICAgICAgICAgICAgIC5zbGljZShcbiAgICAgICAgICAgICAgICAgIDAsXG4gICAgICAgICAgICAgICAgICB0cmFjZUxpbWl0ICtcbiAgICAgICAgICAgICAgICAgICAgZXh0cmFGcmFtZXMgK1xuICAgICAgICAgICAgICAgICAgICAoZnJhbWVzWzBdLnN0YXJ0c1dpdGgoJ0Vycm9yJykgPyAxIDogMClcbiAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICAgICAgLmpvaW4oJ1xcbicpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiB7XG4gICAgICB0eXBlOiBBY3Rpb25UeXBlcy5QRVJGT1JNX0FDVElPTixcbiAgICAgIGFjdGlvbixcbiAgICAgIHRpbWVzdGFtcDogRGF0ZS5ub3coKSxcbiAgICAgIHN0YWNrLFxuICAgIH07XG4gIH0sXG5cbiAgcmVzZXQoKTogUmVzZXRBY3Rpb24ge1xuICAgIHJldHVybiB7IHR5cGU6IEFjdGlvblR5cGVzLlJFU0VULCB0aW1lc3RhbXA6IERhdGUubm93KCkgfTtcbiAgfSxcblxuICByb2xsYmFjaygpOiBSb2xsYmFja0FjdGlvbiB7XG4gICAgcmV0dXJuIHsgdHlwZTogQWN0aW9uVHlwZXMuUk9MTEJBQ0ssIHRpbWVzdGFtcDogRGF0ZS5ub3coKSB9O1xuICB9LFxuXG4gIGNvbW1pdCgpOiBDb21taXRBY3Rpb24ge1xuICAgIHJldHVybiB7IHR5cGU6IEFjdGlvblR5cGVzLkNPTU1JVCwgdGltZXN0YW1wOiBEYXRlLm5vdygpIH07XG4gIH0sXG5cbiAgc3dlZXAoKTogU3dlZXBBY3Rpb24ge1xuICAgIHJldHVybiB7IHR5cGU6IEFjdGlvblR5cGVzLlNXRUVQIH07XG4gIH0sXG5cbiAgdG9nZ2xlQWN0aW9uKGlkOiBudW1iZXIpOiBUb2dnbGVBY3Rpb24ge1xuICAgIHJldHVybiB7IHR5cGU6IEFjdGlvblR5cGVzLlRPR0dMRV9BQ1RJT04sIGlkIH07XG4gIH0sXG5cbiAgc2V0QWN0aW9uc0FjdGl2ZShcbiAgICBzdGFydDogbnVtYmVyLFxuICAgIGVuZDogbnVtYmVyLFxuICAgIGFjdGl2ZSA9IHRydWVcbiAgKTogU2V0QWN0aW9uc0FjdGl2ZUFjdGlvbiB7XG4gICAgcmV0dXJuIHsgdHlwZTogQWN0aW9uVHlwZXMuU0VUX0FDVElPTlNfQUNUSVZFLCBzdGFydCwgZW5kLCBhY3RpdmUgfTtcbiAgfSxcblxuICByZW9yZGVyQWN0aW9uKGFjdGlvbklkOiBudW1iZXIsIGJlZm9yZUFjdGlvbklkOiBudW1iZXIpOiBSZW9yZGVyQWN0aW9uIHtcbiAgICByZXR1cm4geyB0eXBlOiBBY3Rpb25UeXBlcy5SRU9SREVSX0FDVElPTiwgYWN0aW9uSWQsIGJlZm9yZUFjdGlvbklkIH07XG4gIH0sXG5cbiAganVtcFRvU3RhdGUoaW5kZXg6IG51bWJlcik6IEp1bXBUb1N0YXRlQWN0aW9uIHtcbiAgICByZXR1cm4geyB0eXBlOiBBY3Rpb25UeXBlcy5KVU1QX1RPX1NUQVRFLCBpbmRleCB9O1xuICB9LFxuXG4gIGp1bXBUb0FjdGlvbihhY3Rpb25JZDogbnVtYmVyKTogSnVtcFRvQWN0aW9uQWN0aW9uIHtcbiAgICByZXR1cm4geyB0eXBlOiBBY3Rpb25UeXBlcy5KVU1QX1RPX0FDVElPTiwgYWN0aW9uSWQgfTtcbiAgfSxcblxuICBpbXBvcnRTdGF0ZTxTLCBBIGV4dGVuZHMgQWN0aW9uPHVua25vd24+LCBNb25pdG9yU3RhdGUgPSBudWxsPihcbiAgICBuZXh0TGlmdGVkU3RhdGU6IExpZnRlZFN0YXRlPFMsIEEsIE1vbml0b3JTdGF0ZT4gfCByZWFkb25seSBBW10sXG4gICAgbm9SZWNvbXB1dGU/OiBib29sZWFuXG4gICk6IEltcG9ydFN0YXRlQWN0aW9uPFMsIEEsIE1vbml0b3JTdGF0ZT4ge1xuICAgIHJldHVybiB7IHR5cGU6IEFjdGlvblR5cGVzLklNUE9SVF9TVEFURSwgbmV4dExpZnRlZFN0YXRlLCBub1JlY29tcHV0ZSB9O1xuICB9LFxuXG4gIGxvY2tDaGFuZ2VzKHN0YXR1czogYm9vbGVhbik6IExvY2tDaGFuZ2VzQWN0aW9uIHtcbiAgICByZXR1cm4geyB0eXBlOiBBY3Rpb25UeXBlcy5MT0NLX0NIQU5HRVMsIHN0YXR1cyB9O1xuICB9LFxuXG4gIHBhdXNlUmVjb3JkaW5nKHN0YXR1czogYm9vbGVhbik6IFBhdXNlUmVjb3JkaW5nQWN0aW9uIHtcbiAgICByZXR1cm4geyB0eXBlOiBBY3Rpb25UeXBlcy5QQVVTRV9SRUNPUkRJTkcsIHN0YXR1cyB9O1xuICB9LFxufTtcblxuZXhwb3J0IGNvbnN0IElOSVRfQUNUSU9OID0geyB0eXBlOiAnQEBJTklUJyB9O1xuXG4vKipcbiAqIENvbXB1dGVzIHRoZSBuZXh0IGVudHJ5IHdpdGggZXhjZXB0aW9ucyBjYXRjaGluZy5cbiAqL1xuZnVuY3Rpb24gY29tcHV0ZVdpdGhUcnlDYXRjaDxTLCBBIGV4dGVuZHMgQWN0aW9uPHVua25vd24+PihcbiAgcmVkdWNlcjogUmVkdWNlcjxTLCBBPixcbiAgYWN0aW9uOiBBLFxuICBzdGF0ZTogU1xuKSB7XG4gIGxldCBuZXh0U3RhdGUgPSBzdGF0ZTtcbiAgbGV0IG5leHRFcnJvcjtcbiAgdHJ5IHtcbiAgICBuZXh0U3RhdGUgPSByZWR1Y2VyKHN0YXRlLCBhY3Rpb24pO1xuICB9IGNhdGNoIChlcnIpIHtcbiAgICBuZXh0RXJyb3IgPSBlcnIudG9TdHJpbmcoKTtcbiAgICBpZiAoaXNDaHJvbWUpIHtcbiAgICAgIC8vIEluIENocm9tZSwgcmV0aHJvd2luZyBwcm92aWRlcyBiZXR0ZXIgc291cmNlIG1hcCBzdXBwb3J0XG4gICAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgdGhyb3cgZXJyO1xuICAgICAgfSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnNvbGUuZXJyb3IoZXJyKTsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby1jb25zb2xlXG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHtcbiAgICBzdGF0ZTogbmV4dFN0YXRlLFxuICAgIGVycm9yOiBuZXh0RXJyb3IsXG4gIH07XG59XG5cbi8qKlxuICogQ29tcHV0ZXMgdGhlIG5leHQgZW50cnkgaW4gdGhlIGxvZyBieSBhcHBseWluZyBhbiBhY3Rpb24uXG4gKi9cbmZ1bmN0aW9uIGNvbXB1dGVOZXh0RW50cnk8UywgQSBleHRlbmRzIEFjdGlvbjx1bmtub3duPj4oXG4gIHJlZHVjZXI6IFJlZHVjZXI8UywgQT4sXG4gIGFjdGlvbjogQSxcbiAgc3RhdGU6IFMsXG4gIHNob3VsZENhdGNoRXJyb3JzOiBib29sZWFuIHwgdW5kZWZpbmVkXG4pIHtcbiAgaWYgKCFzaG91bGRDYXRjaEVycm9ycykge1xuICAgIHJldHVybiB7IHN0YXRlOiByZWR1Y2VyKHN0YXRlLCBhY3Rpb24pIH07XG4gIH1cbiAgcmV0dXJuIGNvbXB1dGVXaXRoVHJ5Q2F0Y2gocmVkdWNlciwgYWN0aW9uLCBzdGF0ZSk7XG59XG5cbi8qKlxuICogUnVucyB0aGUgcmVkdWNlciBvbiBpbnZhbGlkYXRlZCBhY3Rpb25zIHRvIGdldCBhIGZyZXNoIGNvbXB1dGF0aW9uIGxvZy5cbiAqL1xuZnVuY3Rpb24gcmVjb21wdXRlU3RhdGVzPFMsIEEgZXh0ZW5kcyBBY3Rpb248dW5rbm93bj4+KFxuICBjb21wdXRlZFN0YXRlczogeyBzdGF0ZTogUzsgZXJyb3I/OiBzdHJpbmcgfVtdLFxuICBtaW5JbnZhbGlkYXRlZFN0YXRlSW5kZXg6IG51bWJlcixcbiAgcmVkdWNlcjogUmVkdWNlcjxTLCBBPixcbiAgY29tbWl0dGVkU3RhdGU6IFMsXG4gIGFjdGlvbnNCeUlkOiB7IFthY3Rpb25JZDogbnVtYmVyXTogUGVyZm9ybUFjdGlvbjxBPiB9LFxuICBzdGFnZWRBY3Rpb25JZHM6IG51bWJlcltdLFxuICBza2lwcGVkQWN0aW9uSWRzOiBudW1iZXJbXSxcbiAgc2hvdWxkQ2F0Y2hFcnJvcnM6IGJvb2xlYW4gfCB1bmRlZmluZWRcbikge1xuICAvLyBPcHRpbWl6YXRpb246IGV4aXQgZWFybHkgYW5kIHJldHVybiB0aGUgc2FtZSByZWZlcmVuY2VcbiAgLy8gaWYgd2Uga25vdyBub3RoaW5nIGNvdWxkIGhhdmUgY2hhbmdlZC5cbiAgaWYgKFxuICAgICFjb21wdXRlZFN0YXRlcyB8fFxuICAgIG1pbkludmFsaWRhdGVkU3RhdGVJbmRleCA9PT0gLTEgfHxcbiAgICAobWluSW52YWxpZGF0ZWRTdGF0ZUluZGV4ID49IGNvbXB1dGVkU3RhdGVzLmxlbmd0aCAmJlxuICAgICAgY29tcHV0ZWRTdGF0ZXMubGVuZ3RoID09PSBzdGFnZWRBY3Rpb25JZHMubGVuZ3RoKVxuICApIHtcbiAgICByZXR1cm4gY29tcHV0ZWRTdGF0ZXM7XG4gIH1cblxuICBjb25zdCBuZXh0Q29tcHV0ZWRTdGF0ZXMgPSBjb21wdXRlZFN0YXRlcy5zbGljZSgwLCBtaW5JbnZhbGlkYXRlZFN0YXRlSW5kZXgpO1xuICBmb3IgKGxldCBpID0gbWluSW52YWxpZGF0ZWRTdGF0ZUluZGV4OyBpIDwgc3RhZ2VkQWN0aW9uSWRzLmxlbmd0aDsgaSsrKSB7XG4gICAgY29uc3QgYWN0aW9uSWQgPSBzdGFnZWRBY3Rpb25JZHNbaV07XG4gICAgY29uc3QgYWN0aW9uID0gYWN0aW9uc0J5SWRbYWN0aW9uSWRdLmFjdGlvbjtcblxuICAgIGNvbnN0IHByZXZpb3VzRW50cnkgPSBuZXh0Q29tcHV0ZWRTdGF0ZXNbaSAtIDFdO1xuICAgIGNvbnN0IHByZXZpb3VzU3RhdGUgPSBwcmV2aW91c0VudHJ5ID8gcHJldmlvdXNFbnRyeS5zdGF0ZSA6IGNvbW1pdHRlZFN0YXRlO1xuXG4gICAgY29uc3Qgc2hvdWxkU2tpcCA9IHNraXBwZWRBY3Rpb25JZHMuaW5kZXhPZihhY3Rpb25JZCkgPiAtMTtcbiAgICBsZXQgZW50cnk7XG4gICAgaWYgKHNob3VsZFNraXApIHtcbiAgICAgIGVudHJ5ID0gcHJldmlvdXNFbnRyeTtcbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKHNob3VsZENhdGNoRXJyb3JzICYmIHByZXZpb3VzRW50cnkgJiYgcHJldmlvdXNFbnRyeS5lcnJvcikge1xuICAgICAgICBlbnRyeSA9IHtcbiAgICAgICAgICBzdGF0ZTogcHJldmlvdXNTdGF0ZSxcbiAgICAgICAgICBlcnJvcjogJ0ludGVycnVwdGVkIGJ5IGFuIGVycm9yIHVwIHRoZSBjaGFpbicsXG4gICAgICAgIH07XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBlbnRyeSA9IGNvbXB1dGVOZXh0RW50cnkoXG4gICAgICAgICAgcmVkdWNlcixcbiAgICAgICAgICBhY3Rpb24sXG4gICAgICAgICAgcHJldmlvdXNTdGF0ZSxcbiAgICAgICAgICBzaG91bGRDYXRjaEVycm9yc1xuICAgICAgICApO1xuICAgICAgfVxuICAgIH1cbiAgICBuZXh0Q29tcHV0ZWRTdGF0ZXMucHVzaChlbnRyeSk7XG4gIH1cblxuICByZXR1cm4gbmV4dENvbXB1dGVkU3RhdGVzO1xufVxuXG4vKipcbiAqIExpZnRzIGFuIGFwcCdzIGFjdGlvbiBpbnRvIGFuIGFjdGlvbiBvbiB0aGUgbGlmdGVkIHN0b3JlLlxuICovXG5leHBvcnQgZnVuY3Rpb24gbGlmdEFjdGlvbjxBIGV4dGVuZHMgQWN0aW9uPHVua25vd24+PihcbiAgYWN0aW9uOiBBLFxuICB0cmFjZT86ICgoYWN0aW9uOiBBKSA9PiBzdHJpbmcgfCB1bmRlZmluZWQpIHwgYm9vbGVhbixcbiAgdHJhY2VMaW1pdD86IG51bWJlcixcbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9iYW4tdHlwZXNcbiAgdG9FeGNsdWRlRnJvbVRyYWNlPzogRnVuY3Rpb25cbikge1xuICByZXR1cm4gQWN0aW9uQ3JlYXRvcnMucGVyZm9ybUFjdGlvbihcbiAgICBhY3Rpb24sXG4gICAgdHJhY2UsXG4gICAgdHJhY2VMaW1pdCxcbiAgICB0b0V4Y2x1ZGVGcm9tVHJhY2VcbiAgKTtcbn1cblxuZnVuY3Rpb24gaXNBcnJheTxTLCBBIGV4dGVuZHMgQWN0aW9uPHVua25vd24+LCBNb25pdG9yU3RhdGU+KFxuICBuZXh0TGlmdGVkU3RhdGU6IExpZnRlZFN0YXRlPFMsIEEsIE1vbml0b3JTdGF0ZT4gfCByZWFkb25seSBBW11cbik6IG5leHRMaWZ0ZWRTdGF0ZSBpcyByZWFkb25seSBBW10ge1xuICByZXR1cm4gQXJyYXkuaXNBcnJheShuZXh0TGlmdGVkU3RhdGUpO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIExpZnRlZFN0YXRlPFMsIEEgZXh0ZW5kcyBBY3Rpb248dW5rbm93bj4sIE1vbml0b3JTdGF0ZT4ge1xuICBtb25pdG9yU3RhdGU6IE1vbml0b3JTdGF0ZTtcbiAgbmV4dEFjdGlvbklkOiBudW1iZXI7XG4gIGFjdGlvbnNCeUlkOiB7IFthY3Rpb25JZDogbnVtYmVyXTogUGVyZm9ybUFjdGlvbjxBPiB9O1xuICBzdGFnZWRBY3Rpb25JZHM6IG51bWJlcltdO1xuICBza2lwcGVkQWN0aW9uSWRzOiBudW1iZXJbXTtcbiAgY29tbWl0dGVkU3RhdGU6IFM7XG4gIGN1cnJlbnRTdGF0ZUluZGV4OiBudW1iZXI7XG4gIGNvbXB1dGVkU3RhdGVzOiB7IHN0YXRlOiBTOyBlcnJvcj86IHN0cmluZyB9W107XG4gIGlzTG9ja2VkOiBib29sZWFuO1xuICBpc1BhdXNlZDogYm9vbGVhbjtcbn1cblxuLyoqXG4gKiBDcmVhdGVzIGEgaGlzdG9yeSBzdGF0ZSByZWR1Y2VyIGZyb20gYW4gYXBwJ3MgcmVkdWNlci5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGxpZnRSZWR1Y2VyV2l0aDxcbiAgUyxcbiAgQSBleHRlbmRzIEFjdGlvbjx1bmtub3duPixcbiAgTW9uaXRvclN0YXRlLFxuICBNb25pdG9yQWN0aW9uIGV4dGVuZHMgQWN0aW9uPHVua25vd24+XG4+KFxuICByZWR1Y2VyOiBSZWR1Y2VyPFMsIEE+LFxuICBpbml0aWFsQ29tbWl0dGVkU3RhdGU6IFByZWxvYWRlZFN0YXRlPFM+IHwgdW5kZWZpbmVkLFxuICBtb25pdG9yUmVkdWNlcjogUmVkdWNlcjxNb25pdG9yU3RhdGUsIE1vbml0b3JBY3Rpb24+LFxuICBvcHRpb25zOiBPcHRpb25zPFMsIEEsIE1vbml0b3JTdGF0ZSwgTW9uaXRvckFjdGlvbj5cbik6IFJlZHVjZXI8TGlmdGVkU3RhdGU8UywgQSwgTW9uaXRvclN0YXRlPiwgTGlmdGVkQWN0aW9uPFMsIEEsIE1vbml0b3JTdGF0ZT4+IHtcbiAgY29uc3QgaW5pdGlhbExpZnRlZFN0YXRlOiBMaWZ0ZWRTdGF0ZTxTLCBBLCBNb25pdG9yU3RhdGU+ID0ge1xuICAgIG1vbml0b3JTdGF0ZTogbW9uaXRvclJlZHVjZXIodW5kZWZpbmVkLCB7fSBhcyBNb25pdG9yQWN0aW9uKSxcbiAgICBuZXh0QWN0aW9uSWQ6IDEsXG4gICAgYWN0aW9uc0J5SWQ6IHsgMDogbGlmdEFjdGlvbihJTklUX0FDVElPTiBhcyBBKSB9LFxuICAgIHN0YWdlZEFjdGlvbklkczogWzBdLFxuICAgIHNraXBwZWRBY3Rpb25JZHM6IFtdLFxuICAgIGNvbW1pdHRlZFN0YXRlOiBpbml0aWFsQ29tbWl0dGVkU3RhdGUgYXMgUyxcbiAgICBjdXJyZW50U3RhdGVJbmRleDogMCxcbiAgICBjb21wdXRlZFN0YXRlczogW10sXG4gICAgaXNMb2NrZWQ6IG9wdGlvbnMuc2hvdWxkU3RhcnRMb2NrZWQgPT09IHRydWUsXG4gICAgaXNQYXVzZWQ6IG9wdGlvbnMuc2hvdWxkUmVjb3JkQ2hhbmdlcyA9PT0gZmFsc2UsXG4gIH07XG5cbiAgLyoqXG4gICAqIE1hbmFnZXMgaG93IHRoZSBoaXN0b3J5IGFjdGlvbnMgbW9kaWZ5IHRoZSBoaXN0b3J5IHN0YXRlLlxuICAgKi9cbiAgcmV0dXJuIChcbiAgICBsaWZ0ZWRTdGF0ZTogTGlmdGVkU3RhdGU8UywgQSwgTW9uaXRvclN0YXRlPiB8IHVuZGVmaW5lZCxcbiAgICBsaWZ0ZWRBY3Rpb246IExpZnRlZEFjdGlvbjxTLCBBLCBNb25pdG9yU3RhdGU+XG4gICk6IExpZnRlZFN0YXRlPFMsIEEsIE1vbml0b3JTdGF0ZT4gPT4ge1xuICAgIGxldCB7XG4gICAgICBtb25pdG9yU3RhdGUsXG4gICAgICBhY3Rpb25zQnlJZCxcbiAgICAgIG5leHRBY3Rpb25JZCxcbiAgICAgIHN0YWdlZEFjdGlvbklkcyxcbiAgICAgIHNraXBwZWRBY3Rpb25JZHMsXG4gICAgICBjb21taXR0ZWRTdGF0ZSxcbiAgICAgIGN1cnJlbnRTdGF0ZUluZGV4LFxuICAgICAgY29tcHV0ZWRTdGF0ZXMsXG4gICAgICBpc0xvY2tlZCxcbiAgICAgIGlzUGF1c2VkLFxuICAgIH0gPSBsaWZ0ZWRTdGF0ZSB8fCBpbml0aWFsTGlmdGVkU3RhdGU7XG5cbiAgICBpZiAoIWxpZnRlZFN0YXRlKSB7XG4gICAgICAvLyBQcmV2ZW50IG11dGF0aW5nIGluaXRpYWxMaWZ0ZWRTdGF0ZVxuICAgICAgYWN0aW9uc0J5SWQgPSB7IC4uLmFjdGlvbnNCeUlkIH07XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gY29tbWl0RXhjZXNzQWN0aW9ucyhuOiBudW1iZXIpIHtcbiAgICAgIC8vIEF1dG8tY29tbWl0cyBuLW51bWJlciBvZiBleGNlc3MgYWN0aW9ucy5cbiAgICAgIGxldCBleGNlc3MgPSBuO1xuICAgICAgbGV0IGlkc1RvRGVsZXRlID0gc3RhZ2VkQWN0aW9uSWRzLnNsaWNlKDEsIGV4Y2VzcyArIDEpO1xuXG4gICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGlkc1RvRGVsZXRlLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGlmIChjb21wdXRlZFN0YXRlc1tpICsgMV0uZXJyb3IpIHtcbiAgICAgICAgICAvLyBTdG9wIGlmIGVycm9yIGlzIGZvdW5kLiBDb21taXQgYWN0aW9ucyB1cCB0byBlcnJvci5cbiAgICAgICAgICBleGNlc3MgPSBpO1xuICAgICAgICAgIGlkc1RvRGVsZXRlID0gc3RhZ2VkQWN0aW9uSWRzLnNsaWNlKDEsIGV4Y2VzcyArIDEpO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGRlbGV0ZSBhY3Rpb25zQnlJZFtpZHNUb0RlbGV0ZVtpXV07XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgc2tpcHBlZEFjdGlvbklkcyA9IHNraXBwZWRBY3Rpb25JZHMuZmlsdGVyKFxuICAgICAgICAoaWQpID0+IGlkc1RvRGVsZXRlLmluZGV4T2YoaWQpID09PSAtMVxuICAgICAgKTtcbiAgICAgIHN0YWdlZEFjdGlvbklkcyA9IFswLCAuLi5zdGFnZWRBY3Rpb25JZHMuc2xpY2UoZXhjZXNzICsgMSldO1xuICAgICAgY29tbWl0dGVkU3RhdGUgPSBjb21wdXRlZFN0YXRlc1tleGNlc3NdLnN0YXRlO1xuICAgICAgY29tcHV0ZWRTdGF0ZXMgPSBjb21wdXRlZFN0YXRlcy5zbGljZShleGNlc3MpO1xuICAgICAgY3VycmVudFN0YXRlSW5kZXggPVxuICAgICAgICBjdXJyZW50U3RhdGVJbmRleCA+IGV4Y2VzcyA/IGN1cnJlbnRTdGF0ZUluZGV4IC0gZXhjZXNzIDogMDtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBjb21wdXRlUGF1c2VkQWN0aW9uKFxuICAgICAgc2hvdWxkSW5pdD86IGJvb2xlYW5cbiAgICApOiBMaWZ0ZWRTdGF0ZTxTLCBBLCBNb25pdG9yU3RhdGU+IHtcbiAgICAgIGxldCBjb21wdXRlZFN0YXRlO1xuICAgICAgaWYgKHNob3VsZEluaXQpIHtcbiAgICAgICAgY29tcHV0ZWRTdGF0ZSA9IGNvbXB1dGVkU3RhdGVzW2N1cnJlbnRTdGF0ZUluZGV4XTtcbiAgICAgICAgbW9uaXRvclN0YXRlID0gbW9uaXRvclJlZHVjZXIoXG4gICAgICAgICAgbW9uaXRvclN0YXRlLFxuICAgICAgICAgIGxpZnRlZEFjdGlvbiBhcyBNb25pdG9yQWN0aW9uXG4gICAgICAgICk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjb21wdXRlZFN0YXRlID0gY29tcHV0ZU5leHRFbnRyeShcbiAgICAgICAgICByZWR1Y2VyLFxuICAgICAgICAgIChsaWZ0ZWRBY3Rpb24gYXMgUGVyZm9ybUFjdGlvbjxBPikuYWN0aW9uLFxuICAgICAgICAgIGNvbXB1dGVkU3RhdGVzW2N1cnJlbnRTdGF0ZUluZGV4XS5zdGF0ZSxcbiAgICAgICAgICBmYWxzZVxuICAgICAgICApO1xuICAgICAgfVxuICAgICAgaWYgKCFvcHRpb25zLnBhdXNlQWN0aW9uVHlwZSB8fCBuZXh0QWN0aW9uSWQgPT09IDEpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICBtb25pdG9yU3RhdGUsXG4gICAgICAgICAgYWN0aW9uc0J5SWQ6IHsgMDogbGlmdEFjdGlvbihJTklUX0FDVElPTiBhcyBBKSB9LFxuICAgICAgICAgIG5leHRBY3Rpb25JZDogMSxcbiAgICAgICAgICBzdGFnZWRBY3Rpb25JZHM6IFswXSxcbiAgICAgICAgICBza2lwcGVkQWN0aW9uSWRzOiBbXSxcbiAgICAgICAgICBjb21taXR0ZWRTdGF0ZTogY29tcHV0ZWRTdGF0ZS5zdGF0ZSxcbiAgICAgICAgICBjdXJyZW50U3RhdGVJbmRleDogMCxcbiAgICAgICAgICBjb21wdXRlZFN0YXRlczogW2NvbXB1dGVkU3RhdGVdLFxuICAgICAgICAgIGlzTG9ja2VkLFxuICAgICAgICAgIGlzUGF1c2VkOiB0cnVlLFxuICAgICAgICB9O1xuICAgICAgfVxuICAgICAgaWYgKHNob3VsZEluaXQpIHtcbiAgICAgICAgaWYgKGN1cnJlbnRTdGF0ZUluZGV4ID09PSBzdGFnZWRBY3Rpb25JZHMubGVuZ3RoIC0gMSkge1xuICAgICAgICAgIGN1cnJlbnRTdGF0ZUluZGV4Kys7XG4gICAgICAgIH1cbiAgICAgICAgc3RhZ2VkQWN0aW9uSWRzID0gWy4uLnN0YWdlZEFjdGlvbklkcywgbmV4dEFjdGlvbklkXTtcbiAgICAgICAgbmV4dEFjdGlvbklkKys7XG4gICAgICB9XG4gICAgICByZXR1cm4ge1xuICAgICAgICBtb25pdG9yU3RhdGUsXG4gICAgICAgIGFjdGlvbnNCeUlkOiB7XG4gICAgICAgICAgLi4uYWN0aW9uc0J5SWQsXG4gICAgICAgICAgW25leHRBY3Rpb25JZCAtIDFdOiBsaWZ0QWN0aW9uKHtcbiAgICAgICAgICAgIHR5cGU6IG9wdGlvbnMucGF1c2VBY3Rpb25UeXBlLFxuICAgICAgICAgIH0gYXMgQSksXG4gICAgICAgIH0sXG4gICAgICAgIG5leHRBY3Rpb25JZCxcbiAgICAgICAgc3RhZ2VkQWN0aW9uSWRzLFxuICAgICAgICBza2lwcGVkQWN0aW9uSWRzLFxuICAgICAgICBjb21taXR0ZWRTdGF0ZSxcbiAgICAgICAgY3VycmVudFN0YXRlSW5kZXgsXG4gICAgICAgIGNvbXB1dGVkU3RhdGVzOiBbXG4gICAgICAgICAgLi4uY29tcHV0ZWRTdGF0ZXMuc2xpY2UoMCwgc3RhZ2VkQWN0aW9uSWRzLmxlbmd0aCAtIDEpLFxuICAgICAgICAgIGNvbXB1dGVkU3RhdGUsXG4gICAgICAgIF0sXG4gICAgICAgIGlzTG9ja2VkLFxuICAgICAgICBpc1BhdXNlZDogdHJ1ZSxcbiAgICAgIH07XG4gICAgfVxuXG4gICAgLy8gQnkgZGVmYXVsdCwgYWdncmVzc2l2ZWx5IHJlY29tcHV0ZSBldmVyeSBzdGF0ZSB3aGF0ZXZlciBoYXBwZW5zLlxuICAgIC8vIFRoaXMgaGFzIE8obikgcGVyZm9ybWFuY2UsIHNvIHdlJ2xsIG92ZXJyaWRlIHRoaXMgdG8gYSBzZW5zaWJsZVxuICAgIC8vIHZhbHVlIHdoZW5ldmVyIHdlIGZlZWwgbGlrZSB3ZSBkb24ndCBoYXZlIHRvIHJlY29tcHV0ZSB0aGUgc3RhdGVzLlxuICAgIGxldCBtaW5JbnZhbGlkYXRlZFN0YXRlSW5kZXggPSAwO1xuXG4gICAgLy8gbWF4QWdlIG51bWJlciBjYW4gYmUgY2hhbmdlZCBkeW5hbWljYWxseVxuICAgIGxldCBtYXhBZ2UgPSBvcHRpb25zLm1heEFnZTtcbiAgICBpZiAodHlwZW9mIG1heEFnZSA9PT0gJ2Z1bmN0aW9uJylcbiAgICAgIG1heEFnZSA9IG1heEFnZShsaWZ0ZWRBY3Rpb24sIGxpZnRlZFN0YXRlKTtcblxuICAgIGlmICgvXkBAcmVkdXhcXC8oSU5JVHxSRVBMQUNFKS8udGVzdChsaWZ0ZWRBY3Rpb24udHlwZSkpIHtcbiAgICAgIGlmIChvcHRpb25zLnNob3VsZEhvdFJlbG9hZCA9PT0gZmFsc2UpIHtcbiAgICAgICAgYWN0aW9uc0J5SWQgPSB7IDA6IGxpZnRBY3Rpb24oSU5JVF9BQ1RJT04gYXMgQSkgfTtcbiAgICAgICAgbmV4dEFjdGlvbklkID0gMTtcbiAgICAgICAgc3RhZ2VkQWN0aW9uSWRzID0gWzBdO1xuICAgICAgICBza2lwcGVkQWN0aW9uSWRzID0gW107XG4gICAgICAgIGNvbW1pdHRlZFN0YXRlID1cbiAgICAgICAgICBjb21wdXRlZFN0YXRlcy5sZW5ndGggPT09IDBcbiAgICAgICAgICAgID8gKGluaXRpYWxDb21taXR0ZWRTdGF0ZSBhcyBTKVxuICAgICAgICAgICAgOiBjb21wdXRlZFN0YXRlc1tjdXJyZW50U3RhdGVJbmRleF0uc3RhdGU7XG4gICAgICAgIGN1cnJlbnRTdGF0ZUluZGV4ID0gMDtcbiAgICAgICAgY29tcHV0ZWRTdGF0ZXMgPSBbXTtcbiAgICAgIH1cblxuICAgICAgLy8gUmVjb21wdXRlIHN0YXRlcyBvbiBob3QgcmVsb2FkIGFuZCBpbml0LlxuICAgICAgbWluSW52YWxpZGF0ZWRTdGF0ZUluZGV4ID0gMDtcblxuICAgICAgaWYgKG1heEFnZSAmJiBzdGFnZWRBY3Rpb25JZHMubGVuZ3RoID4gbWF4QWdlKSB7XG4gICAgICAgIC8vIFN0YXRlcyBtdXN0IGJlIHJlY29tcHV0ZWQgYmVmb3JlIGNvbW1pdHRpbmcgZXhjZXNzLlxuICAgICAgICBjb21wdXRlZFN0YXRlcyA9IHJlY29tcHV0ZVN0YXRlczxTLCBBPihcbiAgICAgICAgICBjb21wdXRlZFN0YXRlcyxcbiAgICAgICAgICBtaW5JbnZhbGlkYXRlZFN0YXRlSW5kZXgsXG4gICAgICAgICAgcmVkdWNlcixcbiAgICAgICAgICBjb21taXR0ZWRTdGF0ZSxcbiAgICAgICAgICBhY3Rpb25zQnlJZCxcbiAgICAgICAgICBzdGFnZWRBY3Rpb25JZHMsXG4gICAgICAgICAgc2tpcHBlZEFjdGlvbklkcyxcbiAgICAgICAgICBvcHRpb25zLnNob3VsZENhdGNoRXJyb3JzXG4gICAgICAgICk7XG5cbiAgICAgICAgY29tbWl0RXhjZXNzQWN0aW9ucyhzdGFnZWRBY3Rpb25JZHMubGVuZ3RoIC0gbWF4QWdlKTtcblxuICAgICAgICAvLyBBdm9pZCBkb3VibGUgY29tcHV0YXRpb24uXG4gICAgICAgIG1pbkludmFsaWRhdGVkU3RhdGVJbmRleCA9IEluZmluaXR5O1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBzd2l0Y2ggKGxpZnRlZEFjdGlvbi50eXBlKSB7XG4gICAgICAgIGNhc2UgQWN0aW9uVHlwZXMuUEVSRk9STV9BQ1RJT046IHtcbiAgICAgICAgICBpZiAoaXNMb2NrZWQpIHJldHVybiBsaWZ0ZWRTdGF0ZSB8fCBpbml0aWFsTGlmdGVkU3RhdGU7XG4gICAgICAgICAgaWYgKGlzUGF1c2VkKSByZXR1cm4gY29tcHV0ZVBhdXNlZEFjdGlvbigpO1xuXG4gICAgICAgICAgLy8gQXV0by1jb21taXQgYXMgbmV3IGFjdGlvbnMgY29tZSBpbi5cbiAgICAgICAgICBpZiAobWF4QWdlICYmIHN0YWdlZEFjdGlvbklkcy5sZW5ndGggPj0gbWF4QWdlKSB7XG4gICAgICAgICAgICBjb21taXRFeGNlc3NBY3Rpb25zKHN0YWdlZEFjdGlvbklkcy5sZW5ndGggLSBtYXhBZ2UgKyAxKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAoY3VycmVudFN0YXRlSW5kZXggPT09IHN0YWdlZEFjdGlvbklkcy5sZW5ndGggLSAxKSB7XG4gICAgICAgICAgICBjdXJyZW50U3RhdGVJbmRleCsrO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjb25zdCBhY3Rpb25JZCA9IG5leHRBY3Rpb25JZCsrO1xuICAgICAgICAgIC8vIE11dGF0aW9uISBUaGlzIGlzIHRoZSBob3R0ZXN0IHBhdGgsIGFuZCB3ZSBvcHRpbWl6ZSBvbiBwdXJwb3NlLlxuICAgICAgICAgIC8vIEl0IGlzIHNhZmUgYmVjYXVzZSB3ZSBzZXQgYSBuZXcga2V5IGluIGEgY2FjaGUgZGljdGlvbmFyeS5cbiAgICAgICAgICBhY3Rpb25zQnlJZFthY3Rpb25JZF0gPSBsaWZ0ZWRBY3Rpb247XG4gICAgICAgICAgc3RhZ2VkQWN0aW9uSWRzID0gWy4uLnN0YWdlZEFjdGlvbklkcywgYWN0aW9uSWRdO1xuICAgICAgICAgIC8vIE9wdGltaXphdGlvbjogd2Uga25vdyB0aGF0IG9ubHkgdGhlIG5ldyBhY3Rpb24gbmVlZHMgY29tcHV0aW5nLlxuICAgICAgICAgIG1pbkludmFsaWRhdGVkU3RhdGVJbmRleCA9IHN0YWdlZEFjdGlvbklkcy5sZW5ndGggLSAxO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICAgIGNhc2UgQWN0aW9uVHlwZXMuUkVTRVQ6IHtcbiAgICAgICAgICAvLyBHZXQgYmFjayB0byB0aGUgc3RhdGUgdGhlIHN0b3JlIHdhcyBjcmVhdGVkIHdpdGguXG4gICAgICAgICAgYWN0aW9uc0J5SWQgPSB7IDA6IGxpZnRBY3Rpb24oSU5JVF9BQ1RJT04gYXMgQSkgfTtcbiAgICAgICAgICBuZXh0QWN0aW9uSWQgPSAxO1xuICAgICAgICAgIHN0YWdlZEFjdGlvbklkcyA9IFswXTtcbiAgICAgICAgICBza2lwcGVkQWN0aW9uSWRzID0gW107XG4gICAgICAgICAgY29tbWl0dGVkU3RhdGUgPSBpbml0aWFsQ29tbWl0dGVkU3RhdGUgYXMgUztcbiAgICAgICAgICBjdXJyZW50U3RhdGVJbmRleCA9IDA7XG4gICAgICAgICAgY29tcHV0ZWRTdGF0ZXMgPSBbXTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgICBjYXNlIEFjdGlvblR5cGVzLkNPTU1JVDoge1xuICAgICAgICAgIC8vIENvbnNpZGVyIHRoZSBsYXN0IGNvbW1pdHRlZCBzdGF0ZSB0aGUgbmV3IHN0YXJ0aW5nIHBvaW50LlxuICAgICAgICAgIC8vIFNxdWFzaCBhbnkgc3RhZ2VkIGFjdGlvbnMgaW50byBhIHNpbmdsZSBjb21taXR0ZWQgc3RhdGUuXG4gICAgICAgICAgYWN0aW9uc0J5SWQgPSB7IDA6IGxpZnRBY3Rpb24oSU5JVF9BQ1RJT04gYXMgQSkgfTtcbiAgICAgICAgICBuZXh0QWN0aW9uSWQgPSAxO1xuICAgICAgICAgIHN0YWdlZEFjdGlvbklkcyA9IFswXTtcbiAgICAgICAgICBza2lwcGVkQWN0aW9uSWRzID0gW107XG4gICAgICAgICAgY29tbWl0dGVkU3RhdGUgPSBjb21wdXRlZFN0YXRlc1tjdXJyZW50U3RhdGVJbmRleF0uc3RhdGU7XG4gICAgICAgICAgY3VycmVudFN0YXRlSW5kZXggPSAwO1xuICAgICAgICAgIGNvbXB1dGVkU3RhdGVzID0gW107XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgICAgY2FzZSBBY3Rpb25UeXBlcy5ST0xMQkFDSzoge1xuICAgICAgICAgIC8vIEZvcmdldCBhYm91dCBhbnkgc3RhZ2VkIGFjdGlvbnMuXG4gICAgICAgICAgLy8gU3RhcnQgYWdhaW4gZnJvbSB0aGUgbGFzdCBjb21taXR0ZWQgc3RhdGUuXG4gICAgICAgICAgYWN0aW9uc0J5SWQgPSB7IDA6IGxpZnRBY3Rpb24oSU5JVF9BQ1RJT04gYXMgQSkgfTtcbiAgICAgICAgICBuZXh0QWN0aW9uSWQgPSAxO1xuICAgICAgICAgIHN0YWdlZEFjdGlvbklkcyA9IFswXTtcbiAgICAgICAgICBza2lwcGVkQWN0aW9uSWRzID0gW107XG4gICAgICAgICAgY3VycmVudFN0YXRlSW5kZXggPSAwO1xuICAgICAgICAgIGNvbXB1dGVkU3RhdGVzID0gW107XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgICAgY2FzZSBBY3Rpb25UeXBlcy5UT0dHTEVfQUNUSU9OOiB7XG4gICAgICAgICAgLy8gVG9nZ2xlIHdoZXRoZXIgYW4gYWN0aW9uIHdpdGggZ2l2ZW4gSUQgaXMgc2tpcHBlZC5cbiAgICAgICAgICAvLyBCZWluZyBza2lwcGVkIG1lYW5zIGl0IGlzIGEgbm8tb3AgZHVyaW5nIHRoZSBjb21wdXRhdGlvbi5cbiAgICAgICAgICBjb25zdCB7IGlkOiBhY3Rpb25JZCB9ID0gbGlmdGVkQWN0aW9uO1xuICAgICAgICAgIGNvbnN0IGluZGV4ID0gc2tpcHBlZEFjdGlvbklkcy5pbmRleE9mKGFjdGlvbklkKTtcbiAgICAgICAgICBpZiAoaW5kZXggPT09IC0xKSB7XG4gICAgICAgICAgICBza2lwcGVkQWN0aW9uSWRzID0gW2FjdGlvbklkLCAuLi5za2lwcGVkQWN0aW9uSWRzXTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgc2tpcHBlZEFjdGlvbklkcyA9IHNraXBwZWRBY3Rpb25JZHMuZmlsdGVyKChpZCkgPT4gaWQgIT09IGFjdGlvbklkKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgLy8gT3B0aW1pemF0aW9uOiB3ZSBrbm93IGhpc3RvcnkgYmVmb3JlIHRoaXMgYWN0aW9uIGhhc24ndCBjaGFuZ2VkXG4gICAgICAgICAgbWluSW52YWxpZGF0ZWRTdGF0ZUluZGV4ID0gc3RhZ2VkQWN0aW9uSWRzLmluZGV4T2YoYWN0aW9uSWQpO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICAgIGNhc2UgQWN0aW9uVHlwZXMuU0VUX0FDVElPTlNfQUNUSVZFOiB7XG4gICAgICAgICAgLy8gVG9nZ2xlIHdoZXRoZXIgYW4gYWN0aW9uIHdpdGggZ2l2ZW4gSUQgaXMgc2tpcHBlZC5cbiAgICAgICAgICAvLyBCZWluZyBza2lwcGVkIG1lYW5zIGl0IGlzIGEgbm8tb3AgZHVyaW5nIHRoZSBjb21wdXRhdGlvbi5cbiAgICAgICAgICBjb25zdCB7IHN0YXJ0LCBlbmQsIGFjdGl2ZSB9ID0gbGlmdGVkQWN0aW9uO1xuICAgICAgICAgIGNvbnN0IGFjdGlvbklkcyA9IFtdO1xuICAgICAgICAgIGZvciAobGV0IGkgPSBzdGFydDsgaSA8IGVuZDsgaSsrKSBhY3Rpb25JZHMucHVzaChpKTtcbiAgICAgICAgICBpZiAoYWN0aXZlKSB7XG4gICAgICAgICAgICBza2lwcGVkQWN0aW9uSWRzID0gZGlmZmVyZW5jZShza2lwcGVkQWN0aW9uSWRzLCBhY3Rpb25JZHMpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBza2lwcGVkQWN0aW9uSWRzID0gdW5pb24oc2tpcHBlZEFjdGlvbklkcywgYWN0aW9uSWRzKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICAvLyBPcHRpbWl6YXRpb246IHdlIGtub3cgaGlzdG9yeSBiZWZvcmUgdGhpcyBhY3Rpb24gaGFzbid0IGNoYW5nZWRcbiAgICAgICAgICBtaW5JbnZhbGlkYXRlZFN0YXRlSW5kZXggPSBzdGFnZWRBY3Rpb25JZHMuaW5kZXhPZihzdGFydCk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgICAgY2FzZSBBY3Rpb25UeXBlcy5KVU1QX1RPX1NUQVRFOiB7XG4gICAgICAgICAgLy8gV2l0aG91dCByZWNvbXB1dGluZyBhbnl0aGluZywgbW92ZSB0aGUgcG9pbnRlciB0aGF0IHRlbGwgdXNcbiAgICAgICAgICAvLyB3aGljaCBzdGF0ZSBpcyBjb25zaWRlcmVkIHRoZSBjdXJyZW50IG9uZS4gVXNlZnVsIGZvciBzbGlkZXJzLlxuICAgICAgICAgIGN1cnJlbnRTdGF0ZUluZGV4ID0gbGlmdGVkQWN0aW9uLmluZGV4O1xuICAgICAgICAgIC8vIE9wdGltaXphdGlvbjogd2Uga25vdyB0aGUgaGlzdG9yeSBoYXMgbm90IGNoYW5nZWQuXG4gICAgICAgICAgbWluSW52YWxpZGF0ZWRTdGF0ZUluZGV4ID0gSW5maW5pdHk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgICAgY2FzZSBBY3Rpb25UeXBlcy5KVU1QX1RPX0FDVElPTjoge1xuICAgICAgICAgIC8vIEp1bXBzIHRvIGEgY29ycmVzcG9uZGluZyBzdGF0ZSB0byBhIHNwZWNpZmljIGFjdGlvbi5cbiAgICAgICAgICAvLyBVc2VmdWwgd2hlbiBmaWx0ZXJpbmcgYWN0aW9ucy5cbiAgICAgICAgICBjb25zdCBpbmRleCA9IHN0YWdlZEFjdGlvbklkcy5pbmRleE9mKGxpZnRlZEFjdGlvbi5hY3Rpb25JZCk7XG4gICAgICAgICAgaWYgKGluZGV4ICE9PSAtMSkgY3VycmVudFN0YXRlSW5kZXggPSBpbmRleDtcbiAgICAgICAgICBtaW5JbnZhbGlkYXRlZFN0YXRlSW5kZXggPSBJbmZpbml0eTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgICBjYXNlIEFjdGlvblR5cGVzLlNXRUVQOiB7XG4gICAgICAgICAgLy8gRm9yZ2V0IGFueSBhY3Rpb25zIHRoYXQgYXJlIGN1cnJlbnRseSBiZWluZyBza2lwcGVkLlxuICAgICAgICAgIHN0YWdlZEFjdGlvbklkcyA9IGRpZmZlcmVuY2Uoc3RhZ2VkQWN0aW9uSWRzLCBza2lwcGVkQWN0aW9uSWRzKTtcbiAgICAgICAgICBza2lwcGVkQWN0aW9uSWRzID0gW107XG4gICAgICAgICAgY3VycmVudFN0YXRlSW5kZXggPSBNYXRoLm1pbihcbiAgICAgICAgICAgIGN1cnJlbnRTdGF0ZUluZGV4LFxuICAgICAgICAgICAgc3RhZ2VkQWN0aW9uSWRzLmxlbmd0aCAtIDFcbiAgICAgICAgICApO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICAgIGNhc2UgQWN0aW9uVHlwZXMuUkVPUkRFUl9BQ1RJT046IHtcbiAgICAgICAgICAvLyBSZWNvbXB1dGUgYWN0aW9ucyBpbiBhIG5ldyBvcmRlci5cbiAgICAgICAgICBjb25zdCBhY3Rpb25JZCA9IGxpZnRlZEFjdGlvbi5hY3Rpb25JZDtcbiAgICAgICAgICBjb25zdCBpZHggPSBzdGFnZWRBY3Rpb25JZHMuaW5kZXhPZihhY3Rpb25JZCk7XG4gICAgICAgICAgLy8gZG8gbm90aGluZyBpbiBjYXNlIHRoZSBhY3Rpb24gaXMgYWxyZWFkeSByZW1vdmVkIG9yIHRyeWluZyB0byBtb3ZlIHRoZSBmaXJzdCBhY3Rpb25cbiAgICAgICAgICBpZiAoaWR4IDwgMSkgYnJlYWs7XG4gICAgICAgICAgY29uc3QgYmVmb3JlQWN0aW9uSWQgPSBsaWZ0ZWRBY3Rpb24uYmVmb3JlQWN0aW9uSWQ7XG4gICAgICAgICAgbGV0IG5ld0lkeCA9IHN0YWdlZEFjdGlvbklkcy5pbmRleE9mKGJlZm9yZUFjdGlvbklkKTtcbiAgICAgICAgICBpZiAobmV3SWR4IDwgMSkge1xuICAgICAgICAgICAgLy8gbW92ZSB0byB0aGUgYmVnaW5uaW5nIG9yIHRvIHRoZSBlbmRcbiAgICAgICAgICAgIGNvbnN0IGNvdW50ID0gc3RhZ2VkQWN0aW9uSWRzLmxlbmd0aDtcbiAgICAgICAgICAgIG5ld0lkeCA9IGJlZm9yZUFjdGlvbklkID4gc3RhZ2VkQWN0aW9uSWRzW2NvdW50IC0gMV0gPyBjb3VudCA6IDE7XG4gICAgICAgICAgfVxuICAgICAgICAgIGNvbnN0IGRpZmYgPSBpZHggLSBuZXdJZHg7XG5cbiAgICAgICAgICBpZiAoZGlmZiA+IDApIHtcbiAgICAgICAgICAgIC8vIG1vdmUgbGVmdFxuICAgICAgICAgICAgc3RhZ2VkQWN0aW9uSWRzID0gW1xuICAgICAgICAgICAgICAuLi5zdGFnZWRBY3Rpb25JZHMuc2xpY2UoMCwgbmV3SWR4KSxcbiAgICAgICAgICAgICAgYWN0aW9uSWQsXG4gICAgICAgICAgICAgIC4uLnN0YWdlZEFjdGlvbklkcy5zbGljZShuZXdJZHgsIGlkeCksXG4gICAgICAgICAgICAgIC4uLnN0YWdlZEFjdGlvbklkcy5zbGljZShpZHggKyAxKSxcbiAgICAgICAgICAgIF07XG4gICAgICAgICAgICBtaW5JbnZhbGlkYXRlZFN0YXRlSW5kZXggPSBuZXdJZHg7XG4gICAgICAgICAgfSBlbHNlIGlmIChkaWZmIDwgMCkge1xuICAgICAgICAgICAgLy8gbW92ZSByaWdodFxuICAgICAgICAgICAgc3RhZ2VkQWN0aW9uSWRzID0gW1xuICAgICAgICAgICAgICAuLi5zdGFnZWRBY3Rpb25JZHMuc2xpY2UoMCwgaWR4KSxcbiAgICAgICAgICAgICAgLi4uc3RhZ2VkQWN0aW9uSWRzLnNsaWNlKGlkeCArIDEsIG5ld0lkeCksXG4gICAgICAgICAgICAgIGFjdGlvbklkLFxuICAgICAgICAgICAgICAuLi5zdGFnZWRBY3Rpb25JZHMuc2xpY2UobmV3SWR4KSxcbiAgICAgICAgICAgIF07XG4gICAgICAgICAgICBtaW5JbnZhbGlkYXRlZFN0YXRlSW5kZXggPSBpZHg7XG4gICAgICAgICAgfVxuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICAgIGNhc2UgQWN0aW9uVHlwZXMuSU1QT1JUX1NUQVRFOiB7XG4gICAgICAgICAgaWYgKGlzQXJyYXkobGlmdGVkQWN0aW9uLm5leHRMaWZ0ZWRTdGF0ZSkpIHtcbiAgICAgICAgICAgIC8vIHJlY29tcHV0ZSBhcnJheSBvZiBhY3Rpb25zXG4gICAgICAgICAgICBhY3Rpb25zQnlJZCA9IHsgMDogbGlmdEFjdGlvbihJTklUX0FDVElPTiBhcyBBKSB9O1xuICAgICAgICAgICAgbmV4dEFjdGlvbklkID0gMTtcbiAgICAgICAgICAgIHN0YWdlZEFjdGlvbklkcyA9IFswXTtcbiAgICAgICAgICAgIHNraXBwZWRBY3Rpb25JZHMgPSBbXTtcbiAgICAgICAgICAgIGN1cnJlbnRTdGF0ZUluZGV4ID0gbGlmdGVkQWN0aW9uLm5leHRMaWZ0ZWRTdGF0ZS5sZW5ndGg7XG4gICAgICAgICAgICBjb21wdXRlZFN0YXRlcyA9IFtdO1xuICAgICAgICAgICAgY29tbWl0dGVkU3RhdGUgPSBsaWZ0ZWRBY3Rpb24ucHJlbG9hZGVkU3RhdGUgYXMgUztcbiAgICAgICAgICAgIG1pbkludmFsaWRhdGVkU3RhdGVJbmRleCA9IDA7XG4gICAgICAgICAgICAvLyBpdGVyYXRlIHRocm91Z2ggYWN0aW9uc1xuICAgICAgICAgICAgbGlmdGVkQWN0aW9uLm5leHRMaWZ0ZWRTdGF0ZS5mb3JFYWNoKChhY3Rpb24pID0+IHtcbiAgICAgICAgICAgICAgYWN0aW9uc0J5SWRbbmV4dEFjdGlvbklkXSA9IGxpZnRBY3Rpb24oXG4gICAgICAgICAgICAgICAgYWN0aW9uLFxuICAgICAgICAgICAgICAgIG9wdGlvbnMudHJhY2UgfHwgb3B0aW9ucy5zaG91bGRJbmNsdWRlQ2FsbHN0YWNrXG4gICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgIHN0YWdlZEFjdGlvbklkcy5wdXNoKG5leHRBY3Rpb25JZCk7XG4gICAgICAgICAgICAgIG5leHRBY3Rpb25JZCsrO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIC8vIENvbXBsZXRlbHkgcmVwbGFjZSBldmVyeXRoaW5nLlxuICAgICAgICAgICAgKHtcbiAgICAgICAgICAgICAgbW9uaXRvclN0YXRlLFxuICAgICAgICAgICAgICBhY3Rpb25zQnlJZCxcbiAgICAgICAgICAgICAgbmV4dEFjdGlvbklkLFxuICAgICAgICAgICAgICBzdGFnZWRBY3Rpb25JZHMsXG4gICAgICAgICAgICAgIHNraXBwZWRBY3Rpb25JZHMsXG4gICAgICAgICAgICAgIGNvbW1pdHRlZFN0YXRlLFxuICAgICAgICAgICAgICBjdXJyZW50U3RhdGVJbmRleCxcbiAgICAgICAgICAgICAgY29tcHV0ZWRTdGF0ZXMsXG4gICAgICAgICAgICB9ID0gbGlmdGVkQWN0aW9uLm5leHRMaWZ0ZWRTdGF0ZSk7XG5cbiAgICAgICAgICAgIGlmIChsaWZ0ZWRBY3Rpb24ubm9SZWNvbXB1dGUpIHtcbiAgICAgICAgICAgICAgbWluSW52YWxpZGF0ZWRTdGF0ZUluZGV4ID0gSW5maW5pdHk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgICAgY2FzZSBBY3Rpb25UeXBlcy5MT0NLX0NIQU5HRVM6IHtcbiAgICAgICAgICBpc0xvY2tlZCA9IGxpZnRlZEFjdGlvbi5zdGF0dXM7XG4gICAgICAgICAgbWluSW52YWxpZGF0ZWRTdGF0ZUluZGV4ID0gSW5maW5pdHk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgICAgY2FzZSBBY3Rpb25UeXBlcy5QQVVTRV9SRUNPUkRJTkc6IHtcbiAgICAgICAgICBpc1BhdXNlZCA9IGxpZnRlZEFjdGlvbi5zdGF0dXM7XG4gICAgICAgICAgaWYgKGlzUGF1c2VkKSB7XG4gICAgICAgICAgICByZXR1cm4gY29tcHV0ZVBhdXNlZEFjdGlvbih0cnVlKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgLy8gQ29tbWl0IHdoZW4gdW5wYXVzaW5nXG4gICAgICAgICAgYWN0aW9uc0J5SWQgPSB7IDA6IGxpZnRBY3Rpb24oSU5JVF9BQ1RJT04gYXMgQSkgfTtcbiAgICAgICAgICBuZXh0QWN0aW9uSWQgPSAxO1xuICAgICAgICAgIHN0YWdlZEFjdGlvbklkcyA9IFswXTtcbiAgICAgICAgICBza2lwcGVkQWN0aW9uSWRzID0gW107XG4gICAgICAgICAgY29tbWl0dGVkU3RhdGUgPSBjb21wdXRlZFN0YXRlc1tjdXJyZW50U3RhdGVJbmRleF0uc3RhdGU7XG4gICAgICAgICAgY3VycmVudFN0YXRlSW5kZXggPSAwO1xuICAgICAgICAgIGNvbXB1dGVkU3RhdGVzID0gW107XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgICAgZGVmYXVsdDoge1xuICAgICAgICAgIC8vIElmIHRoZSBhY3Rpb24gaXMgbm90IHJlY29nbml6ZWQsIGl0J3MgYSBtb25pdG9yIGFjdGlvbi5cbiAgICAgICAgICAvLyBPcHRpbWl6YXRpb246IGEgbW9uaXRvciBhY3Rpb24gY2FuJ3QgY2hhbmdlIGhpc3RvcnkuXG4gICAgICAgICAgbWluSW52YWxpZGF0ZWRTdGF0ZUluZGV4ID0gSW5maW5pdHk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBjb21wdXRlZFN0YXRlcyA9IHJlY29tcHV0ZVN0YXRlcyhcbiAgICAgIGNvbXB1dGVkU3RhdGVzLFxuICAgICAgbWluSW52YWxpZGF0ZWRTdGF0ZUluZGV4LFxuICAgICAgcmVkdWNlcixcbiAgICAgIGNvbW1pdHRlZFN0YXRlLFxuICAgICAgYWN0aW9uc0J5SWQsXG4gICAgICBzdGFnZWRBY3Rpb25JZHMsXG4gICAgICBza2lwcGVkQWN0aW9uSWRzLFxuICAgICAgb3B0aW9ucy5zaG91bGRDYXRjaEVycm9yc1xuICAgICk7XG4gICAgbW9uaXRvclN0YXRlID0gbW9uaXRvclJlZHVjZXIobW9uaXRvclN0YXRlLCBsaWZ0ZWRBY3Rpb24gYXMgTW9uaXRvckFjdGlvbik7XG4gICAgcmV0dXJuIHtcbiAgICAgIG1vbml0b3JTdGF0ZSxcbiAgICAgIGFjdGlvbnNCeUlkLFxuICAgICAgbmV4dEFjdGlvbklkLFxuICAgICAgc3RhZ2VkQWN0aW9uSWRzLFxuICAgICAgc2tpcHBlZEFjdGlvbklkcyxcbiAgICAgIGNvbW1pdHRlZFN0YXRlLFxuICAgICAgY3VycmVudFN0YXRlSW5kZXgsXG4gICAgICBjb21wdXRlZFN0YXRlcyxcbiAgICAgIGlzTG9ja2VkLFxuICAgICAgaXNQYXVzZWQsXG4gICAgfTtcbiAgfTtcbn1cblxuLyoqXG4gKiBQcm92aWRlcyBhbiBhcHAncyB2aWV3IGludG8gdGhlIHN0YXRlIG9mIHRoZSBsaWZ0ZWQgc3RvcmUuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB1bmxpZnRTdGF0ZTxcbiAgUyxcbiAgQSBleHRlbmRzIEFjdGlvbjx1bmtub3duPixcbiAgTW9uaXRvclN0YXRlLFxuICBOZXh0U3RhdGVFeHRcbj4oXG4gIGxpZnRlZFN0YXRlOiBMaWZ0ZWRTdGF0ZTxTLCBBLCBNb25pdG9yU3RhdGU+ICYgTmV4dFN0YXRlRXh0XG4pOiBTICYgTmV4dFN0YXRlRXh0IHtcbiAgY29uc3QgeyBjb21wdXRlZFN0YXRlcywgY3VycmVudFN0YXRlSW5kZXggfSA9IGxpZnRlZFN0YXRlO1xuICBjb25zdCB7IHN0YXRlIH0gPSBjb21wdXRlZFN0YXRlc1tjdXJyZW50U3RhdGVJbmRleF07XG4gIHJldHVybiBzdGF0ZSBhcyBTICYgTmV4dFN0YXRlRXh0O1xufVxuXG5leHBvcnQgdHlwZSBMaWZ0ZWRSZWR1Y2VyPFMsIEEgZXh0ZW5kcyBBY3Rpb248dW5rbm93bj4sIE1vbml0b3JTdGF0ZT4gPSBSZWR1Y2VyPFxuICBMaWZ0ZWRTdGF0ZTxTLCBBLCBNb25pdG9yU3RhdGU+LFxuICBMaWZ0ZWRBY3Rpb248UywgQSwgTW9uaXRvclN0YXRlPlxuPjtcblxuZXhwb3J0IHR5cGUgTGlmdGVkU3RvcmU8UywgQSBleHRlbmRzIEFjdGlvbjx1bmtub3duPiwgTW9uaXRvclN0YXRlPiA9IFN0b3JlPFxuICBMaWZ0ZWRTdGF0ZTxTLCBBLCBNb25pdG9yU3RhdGU+LFxuICBMaWZ0ZWRBY3Rpb248UywgQSwgTW9uaXRvclN0YXRlPlxuPjtcblxuZXhwb3J0IHR5cGUgSW5zdHJ1bWVudEV4dDxTLCBBIGV4dGVuZHMgQWN0aW9uPHVua25vd24+LCBNb25pdG9yU3RhdGU+ID0ge1xuICBsaWZ0ZWRTdG9yZTogTGlmdGVkU3RvcmU8UywgQSwgTW9uaXRvclN0YXRlPjtcbn07XG5cbmV4cG9ydCB0eXBlIEVuaGFuY2VkU3RvcmU8UywgQSBleHRlbmRzIEFjdGlvbjx1bmtub3duPiwgTW9uaXRvclN0YXRlPiA9IFN0b3JlPFxuICBTLFxuICBBXG4+ICZcbiAgSW5zdHJ1bWVudEV4dDxTLCBBLCBNb25pdG9yU3RhdGU+O1xuXG4vKipcbiAqIFByb3ZpZGVzIGFuIGFwcCdzIHZpZXcgaW50byB0aGUgbGlmdGVkIHN0b3JlLlxuICovXG5leHBvcnQgZnVuY3Rpb24gdW5saWZ0U3RvcmU8XG4gIFMsXG4gIEEgZXh0ZW5kcyBBY3Rpb248dW5rbm93bj4sXG4gIE1vbml0b3JTdGF0ZSxcbiAgTW9uaXRvckFjdGlvbiBleHRlbmRzIEFjdGlvbjx1bmtub3duPixcbiAgTmV4dEV4dCxcbiAgTmV4dFN0YXRlRXh0XG4+KFxuICBsaWZ0ZWRTdG9yZTogU3RvcmU8XG4gICAgTGlmdGVkU3RhdGU8UywgQSwgTW9uaXRvclN0YXRlPiAmIE5leHRTdGF0ZUV4dCxcbiAgICBMaWZ0ZWRBY3Rpb248UywgQSwgTW9uaXRvclN0YXRlPlxuICA+ICZcbiAgICBOZXh0RXh0LFxuICBsaWZ0UmVkdWNlcjogKHI6IFJlZHVjZXI8UywgQT4pID0+IExpZnRlZFJlZHVjZXI8UywgQSwgTW9uaXRvclN0YXRlPixcbiAgb3B0aW9uczogT3B0aW9uczxTLCBBLCBNb25pdG9yU3RhdGUsIE1vbml0b3JBY3Rpb24+XG4pIHtcbiAgbGV0IGxhc3REZWZpbmVkU3RhdGU6IFMgJiBOZXh0U3RhdGVFeHQ7XG4gIGNvbnN0IHRyYWNlID0gb3B0aW9ucy50cmFjZSB8fCBvcHRpb25zLnNob3VsZEluY2x1ZGVDYWxsc3RhY2s7XG4gIGNvbnN0IHRyYWNlTGltaXQgPSBvcHRpb25zLnRyYWNlTGltaXQgfHwgMTA7XG5cbiAgZnVuY3Rpb24gZ2V0U3RhdGUoKTogUyAmIE5leHRTdGF0ZUV4dCB7XG4gICAgY29uc3Qgc3RhdGUgPSB1bmxpZnRTdGF0ZTxTLCBBLCBNb25pdG9yU3RhdGUsIE5leHRTdGF0ZUV4dD4oXG4gICAgICBsaWZ0ZWRTdG9yZS5nZXRTdGF0ZSgpXG4gICAgKTtcbiAgICBpZiAoc3RhdGUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgbGFzdERlZmluZWRTdGF0ZSA9IHN0YXRlO1xuICAgIH1cbiAgICByZXR1cm4gbGFzdERlZmluZWRTdGF0ZTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGRpc3BhdGNoPFQgZXh0ZW5kcyBBPihhY3Rpb246IFQpOiBUIHtcbiAgICBsaWZ0ZWRTdG9yZS5kaXNwYXRjaChsaWZ0QWN0aW9uPEE+KGFjdGlvbiwgdHJhY2UsIHRyYWNlTGltaXQsIGRpc3BhdGNoKSk7XG4gICAgcmV0dXJuIGFjdGlvbjtcbiAgfVxuXG4gIHJldHVybiAoe1xuICAgIC4uLmxpZnRlZFN0b3JlLFxuXG4gICAgbGlmdGVkU3RvcmUsXG5cbiAgICBkaXNwYXRjaCxcblxuICAgIGdldFN0YXRlLFxuXG4gICAgcmVwbGFjZVJlZHVjZXIobmV4dFJlZHVjZXI6IFJlZHVjZXI8UyAmIE5leHRTdGF0ZUV4dCwgQT4pIHtcbiAgICAgIGxpZnRlZFN0b3JlLnJlcGxhY2VSZWR1Y2VyKFxuICAgICAgICAobGlmdFJlZHVjZXIoXG4gICAgICAgICAgKG5leHRSZWR1Y2VyIGFzIHVua25vd24pIGFzIFJlZHVjZXI8UywgQT5cbiAgICAgICAgKSBhcyB1bmtub3duKSBhcyBSZWR1Y2VyPFxuICAgICAgICAgIExpZnRlZFN0YXRlPFMsIEEsIE1vbml0b3JTdGF0ZT4gJiBOZXh0U3RhdGVFeHQsXG4gICAgICAgICAgTGlmdGVkQWN0aW9uPFMsIEEsIE1vbml0b3JTdGF0ZT5cbiAgICAgICAgPlxuICAgICAgKTtcbiAgICB9LFxuXG4gICAgWyQkb2JzZXJ2YWJsZV0oKTogT2JzZXJ2YWJsZTxTPiB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICAuLi4obGlmdGVkU3RvcmUgYXMgYW55KVskJG9ic2VydmFibGVdKCksXG4gICAgICAgIHN1YnNjcmliZShvYnNlcnZlcikge1xuICAgICAgICAgIGlmICh0eXBlb2Ygb2JzZXJ2ZXIgIT09ICdvYmplY3QnKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdFeHBlY3RlZCB0aGUgb2JzZXJ2ZXIgdG8gYmUgYW4gb2JqZWN0LicpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGZ1bmN0aW9uIG9ic2VydmVTdGF0ZSgpIHtcbiAgICAgICAgICAgIGlmIChvYnNlcnZlci5uZXh0KSB7XG4gICAgICAgICAgICAgIG9ic2VydmVyLm5leHQoZ2V0U3RhdGUoKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgb2JzZXJ2ZVN0YXRlKCk7XG4gICAgICAgICAgY29uc3QgdW5zdWJzY3JpYmUgPSBsaWZ0ZWRTdG9yZS5zdWJzY3JpYmUob2JzZXJ2ZVN0YXRlKTtcbiAgICAgICAgICByZXR1cm4geyB1bnN1YnNjcmliZSB9O1xuICAgICAgICB9LFxuXG4gICAgICAgIFskJG9ic2VydmFibGVdKCkge1xuICAgICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgICB9LFxuICAgICAgfTtcbiAgICB9LFxuICB9IGFzIHVua25vd24pIGFzIFN0b3JlPFMgJiBOZXh0U3RhdGVFeHQsIEE+ICZcbiAgICBOZXh0RXh0ICYge1xuICAgICAgbGlmdGVkU3RvcmU6IFN0b3JlPFxuICAgICAgICBMaWZ0ZWRTdGF0ZTxTLCBBLCBNb25pdG9yU3RhdGU+ICYgTmV4dFN0YXRlRXh0LFxuICAgICAgICBMaWZ0ZWRBY3Rpb248UywgQSwgTW9uaXRvclN0YXRlPlxuICAgICAgPjtcbiAgICB9O1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIE9wdGlvbnM8XG4gIFMsXG4gIEEgZXh0ZW5kcyBBY3Rpb248dW5rbm93bj4sXG4gIE1vbml0b3JTdGF0ZSxcbiAgTW9uaXRvckFjdGlvbiBleHRlbmRzIEFjdGlvbjx1bmtub3duPlxuPiB7XG4gIG1heEFnZT86XG4gICAgfCBudW1iZXJcbiAgICB8ICgoXG4gICAgICAgIGN1cnJlbnRMaWZ0ZWRBY3Rpb246IExpZnRlZEFjdGlvbjxTLCBBLCBNb25pdG9yU3RhdGU+LFxuICAgICAgICBwcmV2aW91c0xpZnRlZFN0YXRlOiBMaWZ0ZWRTdGF0ZTxTLCBBLCBNb25pdG9yU3RhdGU+IHwgdW5kZWZpbmVkXG4gICAgICApID0+IG51bWJlcik7XG4gIHNob3VsZENhdGNoRXJyb3JzPzogYm9vbGVhbjtcbiAgc2hvdWxkUmVjb3JkQ2hhbmdlcz86IGJvb2xlYW47XG4gIHBhdXNlQWN0aW9uVHlwZT86IHVua25vd247XG4gIHNob3VsZFN0YXJ0TG9ja2VkPzogYm9vbGVhbjtcbiAgc2hvdWxkSG90UmVsb2FkPzogYm9vbGVhbjtcbiAgdHJhY2U/OiBib29sZWFuIHwgKChhY3Rpb246IEEpID0+IHN0cmluZyB8IHVuZGVmaW5lZCk7XG4gIHRyYWNlTGltaXQ/OiBudW1iZXI7XG4gIHNob3VsZEluY2x1ZGVDYWxsc3RhY2s/OiBib29sZWFuO1xufVxuXG4vKipcbiAqIFJlZHV4IGluc3RydW1lbnRhdGlvbiBzdG9yZSBlbmhhbmNlci5cbiAqL1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gaW5zdHJ1bWVudDxcbiAgT3B0aW9uc1MsXG4gIE9wdGlvbnNBIGV4dGVuZHMgQWN0aW9uPHVua25vd24+LFxuICBNb25pdG9yU3RhdGUgPSBudWxsLFxuICBNb25pdG9yQWN0aW9uIGV4dGVuZHMgQWN0aW9uPHVua25vd24+ID0gbmV2ZXJcbj4oXG4gIG1vbml0b3JSZWR1Y2VyOiBSZWR1Y2VyPE1vbml0b3JTdGF0ZSwgTW9uaXRvckFjdGlvbj4gPSAoKCgpID0+XG4gICAgbnVsbCkgYXMgdW5rbm93bikgYXMgUmVkdWNlcjxNb25pdG9yU3RhdGUsIE1vbml0b3JBY3Rpb24+LFxuICBvcHRpb25zOiBPcHRpb25zPE9wdGlvbnNTLCBPcHRpb25zQSwgTW9uaXRvclN0YXRlLCBNb25pdG9yQWN0aW9uPiA9IHt9XG4pOiBTdG9yZUVuaGFuY2VyPEluc3RydW1lbnRFeHQ8YW55LCBhbnksIE1vbml0b3JTdGF0ZT4+IHtcbiAgaWYgKHR5cGVvZiBvcHRpb25zLm1heEFnZSA9PT0gJ251bWJlcicgJiYgb3B0aW9ucy5tYXhBZ2UgPCAyKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgJ0RldlRvb2xzLmluc3RydW1lbnQoeyBtYXhBZ2UgfSkgb3B0aW9uLCBpZiBzcGVjaWZpZWQsICcgK1xuICAgICAgICAnbWF5IG5vdCBiZSBsZXNzIHRoYW4gMi4nXG4gICAgKTtcbiAgfVxuXG4gIHJldHVybiA8TmV4dEV4dCwgTmV4dFN0YXRlRXh0PihcbiAgICBjcmVhdGVTdG9yZTogU3RvcmVFbmhhbmNlclN0b3JlQ3JlYXRvcjxOZXh0RXh0LCBOZXh0U3RhdGVFeHQ+XG4gICkgPT4gPFMsIEEgZXh0ZW5kcyBBY3Rpb248dW5rbm93bj4+KFxuICAgIHJlZHVjZXI6IFJlZHVjZXI8UywgQT4sXG4gICAgaW5pdGlhbFN0YXRlPzogUHJlbG9hZGVkU3RhdGU8Uz5cbiAgKSA9PiB7XG4gICAgZnVuY3Rpb24gbGlmdFJlZHVjZXIocjogUmVkdWNlcjxTLCBBPikge1xuICAgICAgaWYgKHR5cGVvZiByICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIGlmIChyICYmIHR5cGVvZiAociBhcyB7IGRlZmF1bHQ6IHVua25vd24gfSkuZGVmYXVsdCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgICAgICdFeHBlY3RlZCB0aGUgcmVkdWNlciB0byBiZSBhIGZ1bmN0aW9uLiAnICtcbiAgICAgICAgICAgICAgJ0luc3RlYWQgZ290IGFuIG9iamVjdCB3aXRoIGEgXCJkZWZhdWx0XCIgZmllbGQuICcgK1xuICAgICAgICAgICAgICAnRGlkIHlvdSBwYXNzIGEgbW9kdWxlIGluc3RlYWQgb2YgdGhlIGRlZmF1bHQgZXhwb3J0PyAnICtcbiAgICAgICAgICAgICAgJ1RyeSBwYXNzaW5nIHJlcXVpcmUoLi4uKS5kZWZhdWx0IGluc3RlYWQuJ1xuICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdFeHBlY3RlZCB0aGUgcmVkdWNlciB0byBiZSBhIGZ1bmN0aW9uLicpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGxpZnRSZWR1Y2VyV2l0aDxTLCBBLCBNb25pdG9yU3RhdGUsIE1vbml0b3JBY3Rpb24+KFxuICAgICAgICByLFxuICAgICAgICBpbml0aWFsU3RhdGUsXG4gICAgICAgIG1vbml0b3JSZWR1Y2VyLFxuICAgICAgICAob3B0aW9ucyBhcyB1bmtub3duKSBhcyBPcHRpb25zPFMsIEEsIE1vbml0b3JTdGF0ZSwgTW9uaXRvckFjdGlvbj5cbiAgICAgICk7XG4gICAgfVxuXG4gICAgY29uc3QgbGlmdGVkU3RvcmUgPSBjcmVhdGVTdG9yZShsaWZ0UmVkdWNlcihyZWR1Y2VyKSk7XG4gICAgaWYgKFxuICAgICAgKGxpZnRlZFN0b3JlIGFzIFN0b3JlPFxuICAgICAgICBMaWZ0ZWRTdGF0ZTxTLCBBLCBNb25pdG9yU3RhdGU+ICYgTmV4dFN0YXRlRXh0LFxuICAgICAgICBMaWZ0ZWRBY3Rpb248UywgQSwgTW9uaXRvclN0YXRlPlxuICAgICAgPiAmXG4gICAgICAgIE5leHRFeHQgJiB7XG4gICAgICAgICAgbGlmdGVkU3RvcmU6IFN0b3JlPFxuICAgICAgICAgICAgTGlmdGVkU3RhdGU8UywgQSwgTW9uaXRvclN0YXRlPixcbiAgICAgICAgICAgIExpZnRlZEFjdGlvbjxTLCBBLCBNb25pdG9yU3RhdGU+XG4gICAgICAgICAgPjtcbiAgICAgICAgfSkubGlmdGVkU3RvcmVcbiAgICApIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgJ0RldlRvb2xzIGluc3RydW1lbnRhdGlvbiBzaG91bGQgbm90IGJlIGFwcGxpZWQgbW9yZSB0aGFuIG9uY2UuICcgK1xuICAgICAgICAgICdDaGVjayB5b3VyIHN0b3JlIGNvbmZpZ3VyYXRpb24uJ1xuICAgICAgKTtcbiAgICB9XG5cbiAgICByZXR1cm4gdW5saWZ0U3RvcmU8XG4gICAgICBTLFxuICAgICAgQSxcbiAgICAgIE1vbml0b3JTdGF0ZSxcbiAgICAgIE1vbml0b3JBY3Rpb24sXG4gICAgICBOZXh0RXh0LFxuICAgICAgTmV4dFN0YXRlRXh0XG4gICAgPihcbiAgICAgIGxpZnRlZFN0b3JlLFxuICAgICAgbGlmdFJlZHVjZXIsXG4gICAgICAob3B0aW9ucyBhcyB1bmtub3duKSBhcyBPcHRpb25zPFMsIEEsIE1vbml0b3JTdGF0ZSwgTW9uaXRvckFjdGlvbj5cbiAgICApO1xuICB9O1xufVxuIl19
\No newline at end of file