1 /******/ (() => { // webpackBootstrap
2 /******/ var __webpack_modules__ = ({
4 /***/ "./node_modules/keyboardjs/dist/keyboard.js":
5 /*!**************************************************!*\
6 !*** ./node_modules/keyboardjs/dist/keyboard.js ***!
7 \**************************************************/
8 /***/ (function(module, __unused_webpack_exports, __webpack_require__) {
10 (function (global, factory) {
11 true ? module.exports = factory() :
13 }(this, (function () { 'use strict';
15 function _typeof(obj) {
16 "@babel/helpers - typeof";
18 if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") {
19 _typeof = function (obj) {
23 _typeof = function (obj) {
24 return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
31 function _classCallCheck(instance, Constructor) {
32 if (!(instance instanceof Constructor)) {
33 throw new TypeError("Cannot call a class as a function");
37 function _defineProperties(target, props) {
38 for (var i = 0; i < props.length; i++) {
39 var descriptor = props[i];
40 descriptor.enumerable = descriptor.enumerable || false;
41 descriptor.configurable = true;
42 if ("value" in descriptor) descriptor.writable = true;
43 Object.defineProperty(target, descriptor.key, descriptor);
47 function _createClass(Constructor, protoProps, staticProps) {
48 if (protoProps) _defineProperties(Constructor.prototype, protoProps);
49 if (staticProps) _defineProperties(Constructor, staticProps);
53 function _toConsumableArray(arr) {
54 return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread();
57 function _arrayWithoutHoles(arr) {
58 if (Array.isArray(arr)) return _arrayLikeToArray(arr);
61 function _iterableToArray(iter) {
62 if (typeof Symbol !== "undefined" && Symbol.iterator in Object(iter)) return Array.from(iter);
65 function _unsupportedIterableToArray(o, minLen) {
67 if (typeof o === "string") return _arrayLikeToArray(o, minLen);
68 var n = Object.prototype.toString.call(o).slice(8, -1);
69 if (n === "Object" && o.constructor) n = o.constructor.name;
70 if (n === "Map" || n === "Set") return Array.from(o);
71 if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen);
74 function _arrayLikeToArray(arr, len) {
75 if (len == null || len > arr.length) len = arr.length;
77 for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i];
82 function _nonIterableSpread() {
83 throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
86 var KeyCombo = /*#__PURE__*/function () {
87 function KeyCombo(keyComboStr) {
88 _classCallCheck(this, KeyCombo);
90 this.sourceStr = keyComboStr;
91 this.subCombos = KeyCombo.parseComboStr(keyComboStr);
92 this.keyNames = this.subCombos.reduce(function (memo, nextSubCombo) {
93 return memo.concat(nextSubCombo);
97 _createClass(KeyCombo, [{
99 value: function check(pressedKeyNames) {
100 var startingKeyNameIndex = 0;
102 for (var i = 0; i < this.subCombos.length; i += 1) {
103 startingKeyNameIndex = this._checkSubCombo(this.subCombos[i], startingKeyNameIndex, pressedKeyNames);
105 if (startingKeyNameIndex === -1) {
114 value: function isEqual(otherKeyCombo) {
115 if (!otherKeyCombo || typeof otherKeyCombo !== 'string' && _typeof(otherKeyCombo) !== 'object') {
119 if (typeof otherKeyCombo === 'string') {
120 otherKeyCombo = new KeyCombo(otherKeyCombo);
123 if (this.subCombos.length !== otherKeyCombo.subCombos.length) {
127 for (var i = 0; i < this.subCombos.length; i += 1) {
128 if (this.subCombos[i].length !== otherKeyCombo.subCombos[i].length) {
133 for (var _i = 0; _i < this.subCombos.length; _i += 1) {
134 var subCombo = this.subCombos[_i];
136 var otherSubCombo = otherKeyCombo.subCombos[_i].slice(0);
138 for (var j = 0; j < subCombo.length; j += 1) {
139 var keyName = subCombo[j];
140 var index = otherSubCombo.indexOf(keyName);
143 otherSubCombo.splice(index, 1);
147 if (otherSubCombo.length !== 0) {
155 key: "_checkSubCombo",
156 value: function _checkSubCombo(subCombo, startingKeyNameIndex, pressedKeyNames) {
157 subCombo = subCombo.slice(0);
158 pressedKeyNames = pressedKeyNames.slice(startingKeyNameIndex);
159 var endIndex = startingKeyNameIndex;
161 for (var i = 0; i < subCombo.length; i += 1) {
162 var keyName = subCombo[i];
164 if (keyName[0] === '\\') {
165 var escapedKeyName = keyName.slice(1);
167 if (escapedKeyName === KeyCombo.comboDeliminator || escapedKeyName === KeyCombo.keyDeliminator) {
168 keyName = escapedKeyName;
172 var index = pressedKeyNames.indexOf(keyName);
175 subCombo.splice(i, 1);
178 if (index > endIndex) {
182 if (subCombo.length === 0) {
194 KeyCombo.comboDeliminator = '>';
195 KeyCombo.keyDeliminator = '+';
197 KeyCombo.parseComboStr = function (keyComboStr) {
198 var subComboStrs = KeyCombo._splitStr(keyComboStr, KeyCombo.comboDeliminator);
202 for (var i = 0; i < subComboStrs.length; i += 1) {
203 combo.push(KeyCombo._splitStr(subComboStrs[i], KeyCombo.keyDeliminator));
209 KeyCombo._splitStr = function (str, deliminator) {
215 for (var ci = 0; ci < s.length; ci += 1) {
216 if (ci > 0 && s[ci] === d && s[ci - 1] !== '\\') {
232 var Locale = /*#__PURE__*/function () {
233 function Locale(name) {
234 _classCallCheck(this, Locale);
236 this.localeName = name;
237 this.activeTargetKeys = [];
238 this.pressedKeys = [];
239 this._appliedMacros = [];
241 this._killKeyCodes = [];
245 _createClass(Locale, [{
247 value: function bindKeyCode(keyCode, keyNames) {
248 if (typeof keyNames === 'string') {
249 keyNames = [keyNames];
252 this._keyMap[keyCode] = keyNames;
256 value: function bindMacro(keyComboStr, keyNames) {
257 if (typeof keyNames === 'string') {
258 keyNames = [keyNames];
263 if (typeof keyNames === 'function') {
269 keyCombo: new KeyCombo(keyComboStr),
274 this._macros.push(macro);
278 value: function getKeyCodes(keyName) {
281 for (var keyCode in this._keyMap) {
282 var index = this._keyMap[keyCode].indexOf(keyName);
285 keyCodes.push(keyCode | 0);
293 value: function getKeyNames(keyCode) {
294 return this._keyMap[keyCode] || [];
298 value: function setKillKey(keyCode) {
299 if (typeof keyCode === 'string') {
300 var keyCodes = this.getKeyCodes(keyCode);
302 for (var i = 0; i < keyCodes.length; i += 1) {
303 this.setKillKey(keyCodes[i]);
309 this._killKeyCodes.push(keyCode);
313 value: function pressKey(keyCode) {
314 if (typeof keyCode === 'string') {
315 var keyCodes = this.getKeyCodes(keyCode);
317 for (var i = 0; i < keyCodes.length; i += 1) {
318 this.pressKey(keyCodes[i]);
324 this.activeTargetKeys.length = 0;
325 var keyNames = this.getKeyNames(keyCode);
327 for (var _i = 0; _i < keyNames.length; _i += 1) {
328 this.activeTargetKeys.push(keyNames[_i]);
330 if (this.pressedKeys.indexOf(keyNames[_i]) === -1) {
331 this.pressedKeys.push(keyNames[_i]);
339 value: function releaseKey(keyCode) {
340 if (typeof keyCode === 'string') {
341 var keyCodes = this.getKeyCodes(keyCode);
343 for (var i = 0; i < keyCodes.length; i += 1) {
344 this.releaseKey(keyCodes[i]);
347 var keyNames = this.getKeyNames(keyCode);
349 var killKeyCodeIndex = this._killKeyCodes.indexOf(keyCode);
351 if (killKeyCodeIndex !== -1) {
352 this.pressedKeys.length = 0;
354 for (var _i2 = 0; _i2 < keyNames.length; _i2 += 1) {
355 var index = this.pressedKeys.indexOf(keyNames[_i2]);
358 this.pressedKeys.splice(index, 1);
363 this.activeTargetKeys.length = 0;
370 value: function _applyMacros() {
371 var macros = this._macros.slice(0);
373 for (var i = 0; i < macros.length; i += 1) {
374 var macro = macros[i];
376 if (macro.keyCombo.check(this.pressedKeys)) {
378 macro.keyNames = macro.handler(this.pressedKeys);
381 for (var j = 0; j < macro.keyNames.length; j += 1) {
382 if (this.pressedKeys.indexOf(macro.keyNames[j]) === -1) {
383 this.pressedKeys.push(macro.keyNames[j]);
387 this._appliedMacros.push(macro);
393 value: function _clearMacros() {
394 for (var i = 0; i < this._appliedMacros.length; i += 1) {
395 var macro = this._appliedMacros[i];
397 if (!macro.keyCombo.check(this.pressedKeys)) {
398 for (var j = 0; j < macro.keyNames.length; j += 1) {
399 var index = this.pressedKeys.indexOf(macro.keyNames[j]);
402 this.pressedKeys.splice(index, 1);
407 macro.keyNames = null;
410 this._appliedMacros.splice(i, 1);
421 var Keyboard = /*#__PURE__*/function () {
422 function Keyboard(targetWindow, targetElement, targetPlatform, targetUserAgent) {
423 _classCallCheck(this, Keyboard);
426 this._currentContext = '';
428 this._listeners = [];
429 this._appliedListeners = [];
431 this._targetElement = null;
432 this._targetWindow = null;
433 this._targetPlatform = '';
434 this._targetUserAgent = '';
435 this._isModernBrowser = false;
436 this._targetKeyDownBinding = null;
437 this._targetKeyUpBinding = null;
438 this._targetResetBinding = null;
439 this._paused = false;
440 this._contexts.global = {
441 listeners: this._listeners,
442 targetWindow: targetWindow,
443 targetElement: targetElement,
444 targetPlatform: targetPlatform,
445 targetUserAgent: targetUserAgent
447 this.setContext('global');
450 _createClass(Keyboard, [{
452 value: function setLocale(localeName, localeBuilder) {
455 if (typeof localeName === 'string') {
457 locale = new Locale(localeName);
458 localeBuilder(locale, this._targetPlatform, this._targetUserAgent);
460 locale = this._locales[localeName] || null;
464 localeName = locale._localeName;
467 this._locale = locale;
468 this._locales[localeName] = locale;
471 this._locale.pressedKeys = locale.pressedKeys;
478 value: function getLocale(localName) {
479 localName || (localName = this._locale.localeName);
480 return this._locales[localName] || null;
484 value: function bind(keyComboStr, pressHandler, releaseHandler, preventRepeatByDefault) {
485 if (keyComboStr === null || typeof keyComboStr === 'function') {
486 preventRepeatByDefault = releaseHandler;
487 releaseHandler = pressHandler;
488 pressHandler = keyComboStr;
492 if (keyComboStr && _typeof(keyComboStr) === 'object' && typeof keyComboStr.length === 'number') {
493 for (var i = 0; i < keyComboStr.length; i += 1) {
494 this.bind(keyComboStr[i], pressHandler, releaseHandler);
500 this._listeners.push({
501 keyCombo: keyComboStr ? new KeyCombo(keyComboStr) : null,
502 pressHandler: pressHandler || null,
503 releaseHandler: releaseHandler || null,
504 preventRepeat: false,
505 preventRepeatByDefault: preventRepeatByDefault || false,
506 executingHandler: false
513 value: function addListener(keyComboStr, pressHandler, releaseHandler, preventRepeatByDefault) {
514 return this.bind(keyComboStr, pressHandler, releaseHandler, preventRepeatByDefault);
518 value: function on(keyComboStr, pressHandler, releaseHandler, preventRepeatByDefault) {
519 return this.bind(keyComboStr, pressHandler, releaseHandler, preventRepeatByDefault);
523 value: function bindPress(keyComboStr, pressHandler, preventRepeatByDefault) {
524 return this.bind(keyComboStr, pressHandler, null, preventRepeatByDefault);
528 value: function bindRelease(keyComboStr, releaseHandler) {
529 return this.bind(keyComboStr, null, releaseHandler, preventRepeatByDefault);
533 value: function unbind(keyComboStr, pressHandler, releaseHandler) {
534 if (keyComboStr === null || typeof keyComboStr === 'function') {
535 releaseHandler = pressHandler;
536 pressHandler = keyComboStr;
540 if (keyComboStr && _typeof(keyComboStr) === 'object' && typeof keyComboStr.length === 'number') {
541 for (var i = 0; i < keyComboStr.length; i += 1) {
542 this.unbind(keyComboStr[i], pressHandler, releaseHandler);
548 for (var _i = 0; _i < this._listeners.length; _i += 1) {
549 var listener = this._listeners[_i];
550 var comboMatches = !keyComboStr && !listener.keyCombo || listener.keyCombo && listener.keyCombo.isEqual(keyComboStr);
551 var pressHandlerMatches = !pressHandler && !releaseHandler || !pressHandler && !listener.pressHandler || pressHandler === listener.pressHandler;
552 var releaseHandlerMatches = !pressHandler && !releaseHandler || !releaseHandler && !listener.releaseHandler || releaseHandler === listener.releaseHandler;
554 if (comboMatches && pressHandlerMatches && releaseHandlerMatches) {
555 this._listeners.splice(_i, 1);
564 key: "removeListener",
565 value: function removeListener(keyComboStr, pressHandler, releaseHandler) {
566 return this.unbind(keyComboStr, pressHandler, releaseHandler);
570 value: function off(keyComboStr, pressHandler, releaseHandler) {
571 return this.unbind(keyComboStr, pressHandler, releaseHandler);
575 value: function setContext(contextName) {
577 this.releaseAllKeys();
580 if (!this._contexts[contextName]) {
581 var globalContext = this._contexts.global;
582 this._contexts[contextName] = {
584 targetWindow: globalContext.targetWindow,
585 targetElement: globalContext.targetElement,
586 targetPlatform: globalContext.targetPlatform,
587 targetUserAgent: globalContext.targetUserAgent
591 var context = this._contexts[contextName];
592 this._currentContext = contextName;
593 this._listeners = context.listeners;
595 this.watch(context.targetWindow, context.targetElement, context.targetPlatform, context.targetUserAgent);
600 value: function getContext() {
601 return this._currentContext;
605 value: function withContext(contextName, callback) {
606 var previousContextName = this.getContext();
607 this.setContext(contextName);
609 this.setContext(previousContextName);
614 value: function watch(targetWindow, targetElement, targetPlatform, targetUserAgent) {
618 var win = typeof globalThis !== 'undefined' ? globalThis : typeof __webpack_require__.g !== 'undefined' ? __webpack_require__.g : typeof window !== 'undefined' ? window : {};
621 if (!win.addEventListener && !win.attachEvent) {
622 // This was added so when using things like JSDOM watch can be used to configure watch
623 // for the global namespace manually.
624 if (this._currentContext === 'global') {
628 throw new Error('Cannot find window functions addEventListener or attachEvent.');
632 } // Handle element bindings where a target window is not passed
635 if (typeof targetWindow.nodeType === 'number') {
636 targetUserAgent = targetPlatform;
637 targetPlatform = targetElement;
638 targetElement = targetWindow;
642 if (!targetWindow.addEventListener && !targetWindow.attachEvent) {
643 throw new Error('Cannot find addEventListener or attachEvent methods on targetWindow.');
646 this._isModernBrowser = !!targetWindow.addEventListener;
647 var userAgent = targetWindow.navigator && targetWindow.navigator.userAgent || '';
648 var platform = targetWindow.navigator && targetWindow.navigator.platform || '';
649 targetElement && targetElement !== null || (targetElement = targetWindow.document);
650 targetPlatform && targetPlatform !== null || (targetPlatform = platform);
651 targetUserAgent && targetUserAgent !== null || (targetUserAgent = userAgent);
653 this._targetKeyDownBinding = function (event) {
654 _this.pressKey(event.keyCode, event);
656 _this._handleCommandBug(event, platform);
659 this._targetKeyUpBinding = function (event) {
660 _this.releaseKey(event.keyCode, event);
663 this._targetResetBinding = function (event) {
664 _this.releaseAllKeys(event);
667 this._bindEvent(targetElement, 'keydown', this._targetKeyDownBinding);
669 this._bindEvent(targetElement, 'keyup', this._targetKeyUpBinding);
671 this._bindEvent(targetWindow, 'focus', this._targetResetBinding);
673 this._bindEvent(targetWindow, 'blur', this._targetResetBinding);
675 this._targetElement = targetElement;
676 this._targetWindow = targetWindow;
677 this._targetPlatform = targetPlatform;
678 this._targetUserAgent = targetUserAgent;
679 var currentContext = this._contexts[this._currentContext];
680 currentContext.targetWindow = this._targetWindow;
681 currentContext.targetElement = this._targetElement;
682 currentContext.targetPlatform = this._targetPlatform;
683 currentContext.targetUserAgent = this._targetUserAgent;
688 value: function stop() {
689 if (!this._targetElement || !this._targetWindow) {
693 this._unbindEvent(this._targetElement, 'keydown', this._targetKeyDownBinding);
695 this._unbindEvent(this._targetElement, 'keyup', this._targetKeyUpBinding);
697 this._unbindEvent(this._targetWindow, 'focus', this._targetResetBinding);
699 this._unbindEvent(this._targetWindow, 'blur', this._targetResetBinding);
701 this._targetWindow = null;
702 this._targetElement = null;
707 value: function pressKey(keyCode, event) {
713 throw new Error('Locale not set');
716 this._locale.pressKey(keyCode);
718 this._applyBindings(event);
724 value: function releaseKey(keyCode, event) {
730 throw new Error('Locale not set');
733 this._locale.releaseKey(keyCode);
735 this._clearBindings(event);
740 key: "releaseAllKeys",
741 value: function releaseAllKeys(event) {
747 throw new Error('Locale not set');
750 this._locale.pressedKeys.length = 0;
752 this._clearBindings(event);
758 value: function pause() {
764 this.releaseAllKeys();
772 value: function resume() {
773 this._paused = false;
778 value: function reset() {
779 this.releaseAllKeys();
780 this._listeners.length = 0;
785 value: function _bindEvent(targetElement, eventName, handler) {
786 return this._isModernBrowser ? targetElement.addEventListener(eventName, handler, false) : targetElement.attachEvent('on' + eventName, handler);
790 value: function _unbindEvent(targetElement, eventName, handler) {
791 return this._isModernBrowser ? targetElement.removeEventListener(eventName, handler, false) : targetElement.detachEvent('on' + eventName, handler);
794 key: "_getGroupedListeners",
795 value: function _getGroupedListeners() {
796 var listenerGroups = [];
797 var listenerGroupMap = [];
798 var listeners = this._listeners;
800 if (this._currentContext !== 'global') {
801 listeners = [].concat(_toConsumableArray(listeners), _toConsumableArray(this._contexts.global.listeners));
804 listeners.sort(function (a, b) {
805 return (b.keyCombo ? b.keyCombo.keyNames.length : 0) - (a.keyCombo ? a.keyCombo.keyNames.length : 0);
806 }).forEach(function (l) {
809 for (var i = 0; i < listenerGroupMap.length; i += 1) {
810 if (listenerGroupMap[i] === null && l.keyCombo === null || listenerGroupMap[i] !== null && listenerGroupMap[i].isEqual(l.keyCombo)) {
815 if (mapIndex === -1) {
816 mapIndex = listenerGroupMap.length;
817 listenerGroupMap.push(l.keyCombo);
820 if (!listenerGroups[mapIndex]) {
821 listenerGroups[mapIndex] = [];
824 listenerGroups[mapIndex].push(l);
826 return listenerGroups;
829 key: "_applyBindings",
830 value: function _applyBindings(event) {
833 var preventRepeat = false;
834 event || (event = {});
836 event.preventRepeat = function () {
837 preventRepeat = true;
840 event.pressedKeys = this._locale.pressedKeys.slice(0);
841 var activeTargetKeys = this._locale.activeTargetKeys;
843 var pressedKeys = this._locale.pressedKeys.slice(0);
845 var listenerGroups = this._getGroupedListeners();
847 var _loop = function _loop(i) {
848 var listeners = listenerGroups[i];
849 var keyCombo = listeners[0].keyCombo;
851 if (keyCombo === null || keyCombo.check(pressedKeys) && activeTargetKeys.some(function (k) {
852 return keyCombo.keyNames.includes(k);
854 for (var j = 0; j < listeners.length; j += 1) {
855 var listener = listeners[j];
857 if (!listener.executingHandler && listener.pressHandler && !listener.preventRepeat) {
858 listener.executingHandler = true;
859 listener.pressHandler.call(_this2, event);
860 listener.executingHandler = false;
862 if (preventRepeat || listener.preventRepeatByDefault) {
863 listener.preventRepeat = true;
864 preventRepeat = false;
868 if (_this2._appliedListeners.indexOf(listener) === -1) {
869 _this2._appliedListeners.push(listener);
874 for (var _j = 0; _j < keyCombo.keyNames.length; _j += 1) {
875 var index = pressedKeys.indexOf(keyCombo.keyNames[_j]);
878 pressedKeys.splice(index, 1);
886 for (var i = 0; i < listenerGroups.length; i += 1) {
891 key: "_clearBindings",
892 value: function _clearBindings(event) {
893 event || (event = {});
894 event.pressedKeys = this._locale.pressedKeys.slice(0);
896 for (var i = 0; i < this._appliedListeners.length; i += 1) {
897 var listener = this._appliedListeners[i];
898 var keyCombo = listener.keyCombo;
900 if (keyCombo === null || !keyCombo.check(this._locale.pressedKeys)) {
901 listener.preventRepeat = false;
903 if (keyCombo !== null || event.pressedKeys.length === 0) {
904 this._appliedListeners.splice(i, 1);
909 if (!listener.executingHandler && listener.releaseHandler) {
910 listener.executingHandler = true;
911 listener.releaseHandler.call(this, event);
912 listener.executingHandler = false;
918 key: "_handleCommandBug",
919 value: function _handleCommandBug(event, platform) {
920 // On Mac when the command key is kept pressed, keyup is not triggered for any other key.
921 // In this case force a keyup for non-modifier keys directly after the keypress.
922 var modifierKeys = ["shift", "ctrl", "alt", "capslock", "tab", "command"];
924 if (platform.match("Mac") && this._locale.pressedKeys.includes("command") && !modifierKeys.includes(this._locale.getKeyNames(event.keyCode)[0])) {
925 this._targetKeyUpBinding(event);
933 function us(locale, platform, userAgent) {
935 locale.bindKeyCode(3, ['cancel']);
936 locale.bindKeyCode(8, ['backspace']);
937 locale.bindKeyCode(9, ['tab']);
938 locale.bindKeyCode(12, ['clear']);
939 locale.bindKeyCode(13, ['enter']);
940 locale.bindKeyCode(16, ['shift']);
941 locale.bindKeyCode(17, ['ctrl']);
942 locale.bindKeyCode(18, ['alt', 'menu']);
943 locale.bindKeyCode(19, ['pause', 'break']);
944 locale.bindKeyCode(20, ['capslock']);
945 locale.bindKeyCode(27, ['escape', 'esc']);
946 locale.bindKeyCode(32, ['space', 'spacebar']);
947 locale.bindKeyCode(33, ['pageup']);
948 locale.bindKeyCode(34, ['pagedown']);
949 locale.bindKeyCode(35, ['end']);
950 locale.bindKeyCode(36, ['home']);
951 locale.bindKeyCode(37, ['left']);
952 locale.bindKeyCode(38, ['up']);
953 locale.bindKeyCode(39, ['right']);
954 locale.bindKeyCode(40, ['down']);
955 locale.bindKeyCode(41, ['select']);
956 locale.bindKeyCode(42, ['printscreen']);
957 locale.bindKeyCode(43, ['execute']);
958 locale.bindKeyCode(44, ['snapshot']);
959 locale.bindKeyCode(45, ['insert', 'ins']);
960 locale.bindKeyCode(46, ['delete', 'del']);
961 locale.bindKeyCode(47, ['help']);
962 locale.bindKeyCode(145, ['scrolllock', 'scroll']);
963 locale.bindKeyCode(188, ['comma', ',']);
964 locale.bindKeyCode(190, ['period', '.']);
965 locale.bindKeyCode(191, ['slash', 'forwardslash', '/']);
966 locale.bindKeyCode(192, ['graveaccent', '`']);
967 locale.bindKeyCode(219, ['openbracket', '[']);
968 locale.bindKeyCode(220, ['backslash', '\\']);
969 locale.bindKeyCode(221, ['closebracket', ']']);
970 locale.bindKeyCode(222, ['apostrophe', '\'']); // 0-9
972 locale.bindKeyCode(48, ['zero', '0']);
973 locale.bindKeyCode(49, ['one', '1']);
974 locale.bindKeyCode(50, ['two', '2']);
975 locale.bindKeyCode(51, ['three', '3']);
976 locale.bindKeyCode(52, ['four', '4']);
977 locale.bindKeyCode(53, ['five', '5']);
978 locale.bindKeyCode(54, ['six', '6']);
979 locale.bindKeyCode(55, ['seven', '7']);
980 locale.bindKeyCode(56, ['eight', '8']);
981 locale.bindKeyCode(57, ['nine', '9']); // numpad
983 locale.bindKeyCode(96, ['numzero', 'num0']);
984 locale.bindKeyCode(97, ['numone', 'num1']);
985 locale.bindKeyCode(98, ['numtwo', 'num2']);
986 locale.bindKeyCode(99, ['numthree', 'num3']);
987 locale.bindKeyCode(100, ['numfour', 'num4']);
988 locale.bindKeyCode(101, ['numfive', 'num5']);
989 locale.bindKeyCode(102, ['numsix', 'num6']);
990 locale.bindKeyCode(103, ['numseven', 'num7']);
991 locale.bindKeyCode(104, ['numeight', 'num8']);
992 locale.bindKeyCode(105, ['numnine', 'num9']);
993 locale.bindKeyCode(106, ['nummultiply', 'num*']);
994 locale.bindKeyCode(107, ['numadd', 'num+']);
995 locale.bindKeyCode(108, ['numenter']);
996 locale.bindKeyCode(109, ['numsubtract', 'num-']);
997 locale.bindKeyCode(110, ['numdecimal', 'num.']);
998 locale.bindKeyCode(111, ['numdivide', 'num/']);
999 locale.bindKeyCode(144, ['numlock', 'num']); // function keys
1001 locale.bindKeyCode(112, ['f1']);
1002 locale.bindKeyCode(113, ['f2']);
1003 locale.bindKeyCode(114, ['f3']);
1004 locale.bindKeyCode(115, ['f4']);
1005 locale.bindKeyCode(116, ['f5']);
1006 locale.bindKeyCode(117, ['f6']);
1007 locale.bindKeyCode(118, ['f7']);
1008 locale.bindKeyCode(119, ['f8']);
1009 locale.bindKeyCode(120, ['f9']);
1010 locale.bindKeyCode(121, ['f10']);
1011 locale.bindKeyCode(122, ['f11']);
1012 locale.bindKeyCode(123, ['f12']);
1013 locale.bindKeyCode(124, ['f13']);
1014 locale.bindKeyCode(125, ['f14']);
1015 locale.bindKeyCode(126, ['f15']);
1016 locale.bindKeyCode(127, ['f16']);
1017 locale.bindKeyCode(128, ['f17']);
1018 locale.bindKeyCode(129, ['f18']);
1019 locale.bindKeyCode(130, ['f19']);
1020 locale.bindKeyCode(131, ['f20']);
1021 locale.bindKeyCode(132, ['f21']);
1022 locale.bindKeyCode(133, ['f22']);
1023 locale.bindKeyCode(134, ['f23']);
1024 locale.bindKeyCode(135, ['f24']); // secondary key symbols
1026 locale.bindMacro('shift + `', ['tilde', '~']);
1027 locale.bindMacro('shift + 1', ['exclamation', 'exclamationpoint', '!']);
1028 locale.bindMacro('shift + 2', ['at', '@']);
1029 locale.bindMacro('shift + 3', ['number', '#']);
1030 locale.bindMacro('shift + 4', ['dollar', 'dollars', 'dollarsign', '$']);
1031 locale.bindMacro('shift + 5', ['percent', '%']);
1032 locale.bindMacro('shift + 6', ['caret', '^']);
1033 locale.bindMacro('shift + 7', ['ampersand', 'and', '&']);
1034 locale.bindMacro('shift + 8', ['asterisk', '*']);
1035 locale.bindMacro('shift + 9', ['openparen', '(']);
1036 locale.bindMacro('shift + 0', ['closeparen', ')']);
1037 locale.bindMacro('shift + -', ['underscore', '_']);
1038 locale.bindMacro('shift + =', ['plus', '+']);
1039 locale.bindMacro('shift + [', ['opencurlybrace', 'opencurlybracket', '{']);
1040 locale.bindMacro('shift + ]', ['closecurlybrace', 'closecurlybracket', '}']);
1041 locale.bindMacro('shift + \\', ['verticalbar', '|']);
1042 locale.bindMacro('shift + ;', ['colon', ':']);
1043 locale.bindMacro('shift + \'', ['quotationmark', '\'']);
1044 locale.bindMacro('shift + !,', ['openanglebracket', '<']);
1045 locale.bindMacro('shift + .', ['closeanglebracket', '>']);
1046 locale.bindMacro('shift + /', ['questionmark', '?']);
1048 if (platform.match('Mac')) {
1049 locale.bindMacro('command', ['mod', 'modifier']);
1051 locale.bindMacro('ctrl', ['mod', 'modifier']);
1055 for (var keyCode = 65; keyCode <= 90; keyCode += 1) {
1056 var keyName = String.fromCharCode(keyCode + 32);
1057 var capitalKeyName = String.fromCharCode(keyCode);
1058 locale.bindKeyCode(keyCode, keyName);
1059 locale.bindMacro('shift + ' + keyName, capitalKeyName);
1060 locale.bindMacro('capslock + ' + keyName, capitalKeyName);
1061 } // browser caveats
1064 var semicolonKeyCode = userAgent.match('Firefox') ? 59 : 186;
1065 var dashKeyCode = userAgent.match('Firefox') ? 173 : 189;
1066 var equalKeyCode = userAgent.match('Firefox') ? 61 : 187;
1067 var leftCommandKeyCode;
1068 var rightCommandKeyCode;
1070 if (platform.match('Mac') && (userAgent.match('Safari') || userAgent.match('Chrome'))) {
1071 leftCommandKeyCode = 91;
1072 rightCommandKeyCode = 93;
1073 } else if (platform.match('Mac') && userAgent.match('Opera')) {
1074 leftCommandKeyCode = 17;
1075 rightCommandKeyCode = 17;
1076 } else if (platform.match('Mac') && userAgent.match('Firefox')) {
1077 leftCommandKeyCode = 224;
1078 rightCommandKeyCode = 224;
1081 locale.bindKeyCode(semicolonKeyCode, ['semicolon', ';']);
1082 locale.bindKeyCode(dashKeyCode, ['dash', '-']);
1083 locale.bindKeyCode(equalKeyCode, ['equal', 'equalsign', '=']);
1084 locale.bindKeyCode(leftCommandKeyCode, ['command', 'windows', 'win', 'super', 'leftcommand', 'leftwindows', 'leftwin', 'leftsuper']);
1085 locale.bindKeyCode(rightCommandKeyCode, ['command', 'windows', 'win', 'super', 'rightcommand', 'rightwindows', 'rightwin', 'rightsuper']); // kill keys
1087 locale.setKillKey('command');
1090 var keyboard = new Keyboard();
1091 keyboard.setLocale('us', us);
1092 keyboard.Keyboard = Keyboard;
1093 keyboard.Locale = Locale;
1094 keyboard.KeyCombo = KeyCombo;
1099 //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoia2V5Ym9hcmQuanMiLCJzb3VyY2VzIjpbIi4uL2xpYi9rZXktY29tYm8uanMiLCIuLi9saWIvbG9jYWxlLmpzIiwiLi4vbGliL2tleWJvYXJkLmpzIiwiLi4vbG9jYWxlcy91cy5qcyIsIi4uL2luZGV4LmpzIl0sInNvdXJjZXNDb250ZW50IjpbIlxuZXhwb3J0IGNsYXNzIEtleUNvbWJvIHtcbiAgY29uc3RydWN0b3Ioa2V5Q29tYm9TdHIpIHtcbiAgICB0aGlzLnNvdXJjZVN0ciA9IGtleUNvbWJvU3RyO1xuICAgIHRoaXMuc3ViQ29tYm9zID0gS2V5Q29tYm8ucGFyc2VDb21ib1N0cihrZXlDb21ib1N0cik7XG4gICAgdGhpcy5rZXlOYW1lcyAgPSB0aGlzLnN1YkNvbWJvcy5yZWR1Y2UoKG1lbW8sIG5leHRTdWJDb21ibykgPT5cbiAgICAgIG1lbW8uY29uY2F0KG5leHRTdWJDb21ibyksIFtdKTtcbiAgfVxuXG4gIGNoZWNrKHByZXNzZWRLZXlOYW1lcykge1xuICAgIGxldCBzdGFydGluZ0tleU5hbWVJbmRleCA9IDA7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLnN1YkNvbWJvcy5sZW5ndGg7IGkgKz0gMSkge1xuICAgICAgc3RhcnRpbmdLZXlOYW1lSW5kZXggPSB0aGlzLl9jaGVja1N1YkNvbWJvKFxuICAgICAgICB0aGlzLnN1YkNvbWJvc1tpXSxcbiAgICAgICAgc3RhcnRpbmdLZXlOYW1lSW5kZXgsXG4gICAgICAgIHByZXNzZWRLZXlOYW1lc1xuICAgICAgKTtcbiAgICAgIGlmIChzdGFydGluZ0tleU5hbWVJbmRleCA9PT0gLTEpIHsgcmV0dXJuIGZhbHNlOyB9XG4gICAgfVxuICAgIHJldHVybiB0cnVlO1xuICB9O1xuXG4gIGlzRXF1YWwob3RoZXJLZXlDb21ibykge1xuICAgIGlmIChcbiAgICAgICFvdGhlcktleUNvbWJvIHx8XG4gICAgICB0eXBlb2Ygb3RoZXJLZXlDb21ibyAhPT0gJ3N0cmluZycgJiZcbiAgICAgIHR5cGVvZiBvdGhlcktleUNvbWJvICE9PSAnb2JqZWN0J1xuICAgICkgeyByZXR1cm4gZmFsc2U7IH1cblxuICAgIGlmICh0eXBlb2Ygb3RoZXJLZXlDb21ibyA9PT0gJ3N0cmluZycpIHtcbiAgICAgIG90aGVyS2V5Q29tYm8gPSBuZXcgS2V5Q29tYm8ob3RoZXJLZXlDb21ibyk7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuc3ViQ29tYm9zLmxlbmd0aCAhPT0gb3RoZXJLZXlDb21iby5zdWJDb21ib3MubGVuZ3RoKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5zdWJDb21ib3MubGVuZ3RoOyBpICs9IDEpIHtcbiAgICAgIGlmICh0aGlzLnN1YkNvbWJvc1tpXS5sZW5ndGggIT09IG90aGVyS2V5Q29tYm8uc3ViQ29tYm9zW2ldLmxlbmd0aCkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgfVxuXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLnN1YkNvbWJvcy5sZW5ndGg7IGkgKz0gMSkge1xuICAgICAgY29uc3Qgc3ViQ29tYm8gICAgICA9IHRoaXMuc3ViQ29tYm9zW2ldO1xuICAgICAgY29uc3Qgb3RoZXJTdWJDb21ibyA9IG90aGVyS2V5Q29tYm8uc3ViQ29tYm9zW2ldLnNsaWNlKDApO1xuXG4gICAgICBmb3IgKGxldCBqID0gMDsgaiA8IHN1YkNvbWJvLmxlbmd0aDsgaiArPSAxKSB7XG4gICAgICAgIGNvbnN0IGtleU5hbWUgPSBzdWJDb21ib1tqXTtcbiAgICAgICAgY29uc3QgaW5kZXggICA9IG90aGVyU3ViQ29tYm8uaW5kZXhPZihrZXlOYW1lKTtcblxuICAgICAgICBpZiAoaW5kZXggPiAtMSkge1xuICAgICAgICAgIG90aGVyU3ViQ29tYm8uc3BsaWNlKGluZGV4LCAxKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKG90aGVyU3ViQ29tYm8ubGVuZ3RoICE9PSAwKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gdHJ1ZTtcbiAgfTtcblxuICBfY2hlY2tTdWJDb21ibyhzdWJDb21ibywgc3RhcnRpbmdLZXlOYW1lSW5kZXgsIHByZXNzZWRLZXlOYW1lcykge1xuICAgIHN1YkNvbWJvID0gc3ViQ29tYm8uc2xpY2UoMCk7XG4gICAgcHJlc3NlZEtleU5hbWVzID0gcHJlc3NlZEtleU5hbWVzLnNsaWNlKHN0YXJ0aW5nS2V5TmFtZUluZGV4KTtcblxuICAgIGxldCBlbmRJbmRleCA9IHN0YXJ0aW5nS2V5TmFtZUluZGV4O1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgc3ViQ29tYm8ubGVuZ3RoOyBpICs9IDEpIHtcblxuICAgICAgbGV0IGtleU5hbWUgPSBzdWJDb21ib1tpXTtcbiAgICAgIGlmIChrZXlOYW1lWzBdID09PSAnXFxcXCcpIHtcbiAgICAgICAgY29uc3QgZXNjYXBlZEtleU5hbWUgPSBrZXlOYW1lLnNsaWNlKDEpO1xuICAgICAgICBpZiAoXG4gICAgICAgICAgZXNjYXBlZEtleU5hbWUgPT09IEtleUNvbWJvLmNvbWJvRGVsaW1pbmF0b3IgfHxcbiAgICAgICAgICBlc2NhcGVkS2V5TmFtZSA9PT0gS2V5Q29tYm8ua2V5RGVsaW1pbmF0b3JcbiAgICAgICAgKSB7XG4gICAgICAgICAga2V5TmFtZSA9IGVzY2FwZWRLZXlOYW1lO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGluZGV4ID0gcHJlc3NlZEtleU5hbWVzLmluZGV4T2Yoa2V5TmFtZSk7XG4gICAgICBpZiAoaW5kZXggPiAtMSkge1xuICAgICAgICBzdWJDb21iby5zcGxpY2UoaSwgMSk7XG4gICAgICAgIGkgLT0gMTtcbiAgICAgICAgaWYgKGluZGV4ID4gZW5kSW5kZXgpIHtcbiAgICAgICAgICBlbmRJbmRleCA9IGluZGV4O1xuICAgICAgICB9XG4gICAgICAgIGlmIChzdWJDb21iby5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICByZXR1cm4gZW5kSW5kZXg7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIC0xO1xuICB9O1xufVxuXG5LZXlDb21iby5jb21ib0RlbGltaW5hdG9yID0gJz4nO1xuS2V5Q29tYm8ua2V5RGVsaW1pbmF0b3IgICA9ICcrJztcblxuS2V5Q29tYm8ucGFyc2VDb21ib1N0ciA9IGZ1bmN0aW9uKGtleUNvbWJvU3RyKSB7XG4gIGNvbnN0IHN1YkNvbWJvU3RycyA9IEtleUNvbWJvLl9zcGxpdFN0cihrZXlDb21ib1N0ciwgS2V5Q29tYm8uY29tYm9EZWxpbWluYXRvcik7XG4gIGNvbnN0IGNvbWJvICAgICAgICA9IFtdO1xuXG4gIGZvciAobGV0IGkgPSAwIDsgaSA8IHN1YkNvbWJvU3Rycy5sZW5ndGg7IGkgKz0gMSkge1xuICAgIGNvbWJvLnB1c2goS2V5Q29tYm8uX3NwbGl0U3RyKHN1YkNvbWJvU3Ryc1tpXSwgS2V5Q29tYm8ua2V5RGVsaW1pbmF0b3IpKTtcbiAgfVxuICByZXR1cm4gY29tYm87XG59XG5cbktleUNvbWJvLl9zcGxpdFN0ciA9IGZ1bmN0aW9uKHN0ciwgZGVsaW1pbmF0b3IpIHtcbiAgY29uc3QgcyAgPSBzdHI7XG4gIGNvbnN0IGQgID0gZGVsaW1pbmF0b3I7XG4gIGxldCBjICA9ICcnO1xuICBjb25zdCBjYSA9IFtdO1xuXG4gIGZvciAobGV0IGNpID0gMDsgY2kgPCBzLmxlbmd0aDsgY2kgKz0gMSkge1xuICAgIGlmIChjaSA+IDAgJiYgc1tjaV0gPT09IGQgJiYgc1tjaSAtIDFdICE9PSAnXFxcXCcpIHtcbiAgICAgIGNhLnB1c2goYy50cmltKCkpO1xuICAgICAgYyA9ICcnO1xuICAgICAgY2kgKz0gMTtcbiAgICB9XG4gICAgYyArPSBzW2NpXTtcbiAgfVxuICBpZiAoYykgeyBjYS5wdXNoKGMudHJpbSgpKTsgfVxuXG4gIHJldHVybiBjYTtcbn07XG4iLCJpbXBvcnQgeyBLZXlDb21ibyB9IGZyb20gJy4va2V5LWNvbWJvJztcblxuXG5leHBvcnQgY2xhc3MgTG9jYWxlIHtcbiAgY29uc3RydWN0b3IobmFtZSkge1xuICAgIHRoaXMubG9jYWxlTmFtZSAgICAgICAgICA9IG5hbWU7XG4gICAgdGhpcy5hY3RpdmVUYXJnZXRLZXlzID0gW107XG4gICAgdGhpcy5wcmVzc2VkS2V5cyAgICAgICAgID0gW107XG4gICAgdGhpcy5fYXBwbGllZE1hY3JvcyAgICAgID0gW107XG4gICAgdGhpcy5fa2V5TWFwICAgICAgICAgICAgID0ge307XG4gICAgdGhpcy5fa2lsbEtleUNvZGVzICAgICAgID0gW107XG4gICAgdGhpcy5fbWFjcm9zICAgICAgICAgICAgID0gW107XG4gIH1cblxuICBiaW5kS2V5Q29kZShrZXlDb2RlLCBrZXlOYW1lcykge1xuICAgIGlmICh0eXBlb2Yga2V5TmFtZXMgPT09ICdzdHJpbmcnKSB7XG4gICAgICBrZXlOYW1lcyA9IFtrZXlOYW1lc107XG4gICAgfVxuXG4gICAgdGhpcy5fa2V5TWFwW2tleUNvZGVdID0ga2V5TmFtZXM7XG4gIH07XG5cbiAgYmluZE1hY3JvKGtleUNvbWJvU3RyLCBrZXlOYW1lcykge1xuICAgIGlmICh0eXBlb2Yga2V5TmFtZXMgPT09ICdzdHJpbmcnKSB7XG4gICAgICBrZXlOYW1lcyA9IFsga2V5TmFtZXMgXTtcbiAgICB9XG5cbiAgICBsZXQgaGFuZGxlciA9IG51bGw7XG4gICAgaWYgKHR5cGVvZiBrZXlOYW1lcyA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgaGFuZGxlciA9IGtleU5hbWVzO1xuICAgICAga2V5TmFtZXMgPSBudWxsO1xuICAgIH1cblxuICAgIGNvbnN0IG1hY3JvID0ge1xuICAgICAga2V5Q29tYm8gOiBuZXcgS2V5Q29tYm8oa2V5Q29tYm9TdHIpLFxuICAgICAga2V5TmFtZXMgOiBrZXlOYW1lcyxcbiAgICAgIGhhbmRsZXIgIDogaGFuZGxlclxuICAgIH07XG5cbiAgICB0aGlzLl9tYWNyb3MucHVzaChtYWNybyk7XG4gIH07XG5cbiAgZ2V0S2V5Q29kZXMoa2V5TmFtZSkge1xuICAgIGNvbnN0IGtleUNvZGVzID0gW107XG4gICAgZm9yIChjb25zdCBrZXlDb2RlIGluIHRoaXMuX2tleU1hcCkge1xuICAgICAgY29uc3QgaW5kZXggPSB0aGlzLl9rZXlNYXBba2V5Q29kZV0uaW5kZXhPZihrZXlOYW1lKTtcbiAgICAgIGlmIChpbmRleCA+IC0xKSB7IGtleUNvZGVzLnB1c2goa2V5Q29kZXwwKTsgfVxuICAgIH1cbiAgICByZXR1cm4ga2V5Q29kZXM7XG4gIH07XG5cbiAgZ2V0S2V5TmFtZXMoa2V5Q29kZSkge1xuICAgIHJldHVybiB0aGlzLl9rZXlNYXBba2V5Q29kZV0gfHwgW107XG4gIH07XG5cbiAgc2V0S2lsbEtleShrZXlDb2RlKSB7XG4gICAgaWYgKHR5cGVvZiBrZXlDb2RlID09PSAnc3RyaW5nJykge1xuICAgICAgY29uc3Qga2V5Q29kZXMgPSB0aGlzLmdldEtleUNvZGVzKGtleUNvZGUpO1xuICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBrZXlDb2Rlcy5sZW5ndGg7IGkgKz0gMSkge1xuICAgICAgICB0aGlzLnNldEtpbGxLZXkoa2V5Q29kZXNbaV0pO1xuICAgICAgfVxuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRoaXMuX2tpbGxLZXlDb2Rlcy5wdXNoKGtleUNvZGUpO1xuICB9O1xuXG4gIHByZXNzS2V5KGtleUNvZGUpIHtcbiAgICBpZiAodHlwZW9mIGtleUNvZGUgPT09ICdzdHJpbmcnKSB7XG4gICAgICBjb25zdCBrZXlDb2RlcyA9IHRoaXMuZ2V0S2V5Q29kZXMoa2V5Q29kZSk7XG4gICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGtleUNvZGVzLmxlbmd0aDsgaSArPSAxKSB7XG4gICAgICAgIHRoaXMucHJlc3NLZXkoa2V5Q29kZXNbaV0pO1xuICAgICAgfVxuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRoaXMuYWN0aXZlVGFyZ2V0S2V5cy5sZW5ndGggPSAwO1xuICAgIGNvbnN0IGtleU5hbWVzID0gdGhpcy5nZXRLZXlOYW1lcyhrZXlDb2RlKTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGtleU5hbWVzLmxlbmd0aDsgaSArPSAxKSB7XG4gICAgICB0aGlzLmFjdGl2ZVRhcmdldEtleXMucHVzaChrZXlOYW1lc1tpXSk7XG4gICAgICBpZiAodGhpcy5wcmVzc2VkS2V5cy5pbmRleE9mKGtleU5hbWVzW2ldKSA9PT0gLTEpIHtcbiAgICAgICAgdGhpcy5wcmVzc2VkS2V5cy5wdXNoKGtleU5hbWVzW2ldKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB0aGlzLl9hcHBseU1hY3JvcygpO1xuICB9O1xuXG4gIHJlbGVhc2VLZXkoa2V5Q29kZSkge1xuICAgIGlmICh0eXBlb2Yga2V5Q29kZSA9PT0gJ3N0cmluZycpIHtcbiAgICAgIGNvbnN0IGtleUNvZGVzID0gdGhpcy5nZXRLZXlDb2RlcyhrZXlDb2RlKTtcbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwga2V5Q29kZXMubGVuZ3RoOyBpICs9IDEpIHtcbiAgICAgICAgdGhpcy5yZWxlYXNlS2V5KGtleUNvZGVzW2ldKTtcbiAgICAgIH1cblxuICAgIH0gZWxzZSB7XG4gICAgICBjb25zdCBrZXlOYW1lcyAgICAgICAgID0gdGhpcy5nZXRLZXlOYW1lcyhrZXlDb2RlKTtcbiAgICAgIGNvbnN0IGtpbGxLZXlDb2RlSW5kZXggPSB0aGlzLl9raWxsS2V5Q29kZXMuaW5kZXhPZihrZXlDb2RlKTtcblxuICAgICAgaWYgKGtpbGxLZXlDb2RlSW5kZXggIT09IC0xKSB7XG4gICAgICAgIHRoaXMucHJlc3NlZEtleXMubGVuZ3RoID0gMDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwga2V5TmFtZXMubGVuZ3RoOyBpICs9IDEpIHtcbiAgICAgICAgICBjb25zdCBpbmRleCA9IHRoaXMucHJlc3NlZEtleXMuaW5kZXhPZihrZXlOYW1lc1tpXSk7XG4gICAgICAgICAgaWYgKGluZGV4ID4gLTEpIHtcbiAgICAgICAgICAgIHRoaXMucHJlc3NlZEtleXMuc3BsaWNlKGluZGV4LCAxKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgdGhpcy5hY3RpdmVUYXJnZXRLZXlzLmxlbmd0aCA9IDA7XG4gICAgICB0aGlzLl9jbGVhck1hY3JvcygpO1xuICAgIH1cbiAgfTtcblxuICBfYXBwbHlNYWNyb3MoKSB7XG4gICAgY29uc3QgbWFjcm9zID0gdGhpcy5fbWFjcm9zLnNsaWNlKDApO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbWFjcm9zLmxlbmd0aDsgaSArPSAxKSB7XG4gICAgICBjb25zdCBtYWNybyA9IG1hY3Jvc1tpXTtcbiAgICAgIGlmIChtYWNyby5rZXlDb21iby5jaGVjayh0aGlzLnByZXNzZWRLZXlzKSkge1xuICAgICAgICBpZiAobWFjcm8uaGFuZGxlcikge1xuICAgICAgICAgIG1hY3JvLmtleU5hbWVzID0gbWFjcm8uaGFuZGxlcih0aGlzLnByZXNzZWRLZXlzKTtcbiAgICAgICAgfVxuICAgICAgICBmb3IgKGxldCBqID0gMDsgaiA8IG1hY3JvLmtleU5hbWVzLmxlbmd0aDsgaiArPSAxKSB7XG4gICAgICAgICAgaWYgKHRoaXMucHJlc3NlZEtleXMuaW5kZXhPZihtYWNyby5rZXlOYW1lc1tqXSkgPT09IC0xKSB7XG4gICAgICAgICAgICB0aGlzLnByZXNzZWRLZXlzLnB1c2gobWFjcm8ua2V5TmFtZXNbal0pO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICB0aGlzLl9hcHBsaWVkTWFjcm9zLnB1c2gobWFjcm8pO1xuICAgICAgfVxuICAgIH1cbiAgfTtcblxuICBfY2xlYXJNYWNyb3MoKSB7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLl9hcHBsaWVkTWFjcm9zLmxlbmd0aDsgaSArPSAxKSB7XG4gICAgICBjb25zdCBtYWNybyA9IHRoaXMuX2FwcGxpZWRNYWNyb3NbaV07XG4gICAgICBpZiAoIW1hY3JvLmtleUNvbWJvLmNoZWNrKHRoaXMucHJlc3NlZEtleXMpKSB7XG4gICAgICAgIGZvciAobGV0IGogPSAwOyBqIDwgbWFjcm8ua2V5TmFtZXMubGVuZ3RoOyBqICs9IDEpIHtcbiAgICAgICAgICBjb25zdCBpbmRleCA9IHRoaXMucHJlc3NlZEtleXMuaW5kZXhPZihtYWNyby5rZXlOYW1lc1tqXSk7XG4gICAgICAgICAgaWYgKGluZGV4ID4gLTEpIHtcbiAgICAgICAgICAgIHRoaXMucHJlc3NlZEtleXMuc3BsaWNlKGluZGV4LCAxKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKG1hY3JvLmhhbmRsZXIpIHtcbiAgICAgICAgICBtYWNyby5rZXlOYW1lcyA9IG51bGw7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5fYXBwbGllZE1hY3Jvcy5zcGxpY2UoaSwgMSk7XG4gICAgICAgIGkgLT0gMTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cbiIsImltcG9ydCB7IExvY2FsZSB9IGZyb20gJy4vbG9jYWxlJztcbmltcG9ydCB7IEtleUNvbWJvIH0gZnJvbSAnLi9rZXktY29tYm8nO1xuXG5cbmV4cG9ydCBjbGFzcyBLZXlib2FyZCB7XG4gIGNvbnN0cnVjdG9yKHRhcmdldFdpbmRvdywgdGFyZ2V0RWxlbWVudCwgdGFyZ2V0UGxhdGZvcm0sIHRhcmdldFVzZXJBZ2VudCkge1xuICAgIHRoaXMuX2xvY2FsZSAgICAgICAgICAgICAgID0gbnVsbDtcbiAgICB0aGlzLl9jdXJyZW50Q29udGV4dCAgICAgICA9ICcnO1xuICAgIHRoaXMuX2NvbnRleHRzICAgICAgICAgICAgID0ge307XG4gICAgdGhpcy5fbGlzdGVuZXJzICAgICAgICAgICAgPSBbXTtcbiAgICB0aGlzLl9hcHBsaWVkTGlzdGVuZXJzICAgICA9IFtdO1xuICAgIHRoaXMuX2xvY2FsZXMgICAgICAgICAgICAgID0ge307XG4gICAgdGhpcy5fdGFyZ2V0RWxlbWVudCAgICAgICAgPSBudWxsO1xuICAgIHRoaXMuX3RhcmdldFdpbmRvdyAgICAgICAgID0gbnVsbDtcbiAgICB0aGlzLl90YXJnZXRQbGF0Zm9ybSAgICAgICA9ICcnO1xuICAgIHRoaXMuX3RhcmdldFVzZXJBZ2VudCAgICAgID0gJyc7XG4gICAgdGhpcy5faXNNb2Rlcm5Ccm93c2VyICAgICAgPSBmYWxzZTtcbiAgICB0aGlzLl90YXJnZXRLZXlEb3duQmluZGluZyA9IG51bGw7XG4gICAgdGhpcy5fdGFyZ2V0S2V5VXBCaW5kaW5nICAgPSBudWxsO1xuICAgIHRoaXMuX3RhcmdldFJlc2V0QmluZGluZyAgID0gbnVsbDtcbiAgICB0aGlzLl9wYXVzZWQgICAgICAgICAgICAgICA9IGZhbHNlO1xuXG4gICAgdGhpcy5fY29udGV4dHMuZ2xvYmFsID0ge1xuICAgICAgbGlzdGVuZXJzOiB0aGlzLl9saXN0ZW5lcnMsXG4gICAgICB0YXJnZXRXaW5kb3csXG4gICAgICB0YXJnZXRFbGVtZW50LFxuICAgICAgdGFyZ2V0UGxhdGZvcm0sXG4gICAgICB0YXJnZXRVc2VyQWdlbnRcbiAgICB9O1xuXG4gICAgdGhpcy5zZXRDb250ZXh0KCdnbG9iYWwnKTtcbiAgfVxuXG4gIHNldExvY2FsZShsb2NhbGVOYW1lLCBsb2NhbGVCdWlsZGVyKSB7XG4gICAgbGV0IGxvY2FsZSA9IG51bGw7XG4gICAgaWYgKHR5cGVvZiBsb2NhbGVOYW1lID09PSAnc3RyaW5nJykge1xuXG4gICAgICBpZiAobG9jYWxlQnVpbGRlcikge1xuICAgICAgICBsb2NhbGUgPSBuZXcgTG9jYWxlKGxvY2FsZU5hbWUpO1xuICAgICAgICBsb2NhbGVCdWlsZGVyKGxvY2FsZSwgdGhpcy5fdGFyZ2V0UGxhdGZvcm0sIHRoaXMuX3RhcmdldFVzZXJBZ2VudCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBsb2NhbGUgPSB0aGlzLl9sb2NhbGVzW2xvY2FsZU5hbWVdIHx8IG51bGw7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGxvY2FsZSAgICAgPSBsb2NhbGVOYW1lO1xuICAgICAgbG9jYWxlTmFtZSA9IGxvY2FsZS5fbG9jYWxlTmFtZTtcbiAgICB9XG5cbiAgICB0aGlzLl9sb2NhbGUgICAgICAgICAgICAgID0gbG9jYWxlO1xuICAgIHRoaXMuX2xvY2FsZXNbbG9jYWxlTmFtZV0gPSBsb2NhbGU7XG4gICAgaWYgKGxvY2FsZSkge1xuICAgICAgdGhpcy5fbG9jYWxlLnByZXNzZWRLZXlzID0gbG9jYWxlLnByZXNzZWRLZXlzO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgZ2V0TG9jYWxlKGxvY2FsTmFtZSkge1xuICAgIGxvY2FsTmFtZSB8fCAobG9jYWxOYW1lID0gdGhpcy5fbG9jYWxlLmxvY2FsZU5hbWUpO1xuICAgIHJldHVybiB0aGlzLl9sb2NhbGVzW2xvY2FsTmFtZV0gfHwgbnVsbDtcbiAgfVxuXG4gIGJpbmQoa2V5Q29tYm9TdHIsIHByZXNzSGFuZGxlciwgcmVsZWFzZUhhbmRsZXIsIHByZXZlbnRSZXBlYXRCeURlZmF1bHQpIHtcbiAgICBpZiAoa2V5Q29tYm9TdHIgPT09IG51bGwgfHwgdHlwZW9mIGtleUNvbWJvU3RyID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICBwcmV2ZW50UmVwZWF0QnlEZWZhdWx0ID0gcmVsZWFzZUhhbmRsZXI7XG4gICAgICByZWxlYXNlSGFuZGxlciAgICAgICAgID0gcHJlc3NIYW5kbGVyO1xuICAgICAgcHJlc3NIYW5kbGVyICAgICAgICAgICA9IGtleUNvbWJvU3RyO1xuICAgICAga2V5Q29tYm9TdHIgICAgICAgICAgICA9IG51bGw7XG4gICAgfVxuXG4gICAgaWYgKFxuICAgICAga2V5Q29tYm9TdHIgJiZcbiAgICAgIHR5cGVvZiBrZXlDb21ib1N0ciA9PT0gJ29iamVjdCcgJiZcbiAgICAgIHR5cGVvZiBrZXlDb21ib1N0ci5sZW5ndGggPT09ICdudW1iZXInXG4gICAgKSB7XG4gICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGtleUNvbWJvU3RyLmxlbmd0aDsgaSArPSAxKSB7XG4gICAgICAgIHRoaXMuYmluZChrZXlDb21ib1N0cltpXSwgcHJlc3NIYW5kbGVyLCByZWxlYXNlSGFuZGxlcik7XG4gICAgICB9XG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICB0aGlzLl9saXN0ZW5lcnMucHVzaCh7XG4gICAgICBrZXlDb21ibyAgICAgICAgICAgICAgOiBrZXlDb21ib1N0ciA/IG5ldyBLZXlDb21ibyhrZXlDb21ib1N0cikgOiBudWxsLFxuICAgICAgcHJlc3NIYW5kbGVyICAgICAgICAgIDogcHJlc3NIYW5kbGVyICAgICAgICAgICB8fCBudWxsLFxuICAgICAgcmVsZWFzZUhhbmRsZXIgICAgICAgIDogcmVsZWFzZUhhbmRsZXIgICAgICAgICB8fCBudWxsLFxuICAgICAgcHJldmVudFJlcGVhdCAgICAgICAgIDogZmFsc2UsXG4gICAgICBwcmV2ZW50UmVwZWF0QnlEZWZhdWx0OiBwcmV2ZW50UmVwZWF0QnlEZWZhdWx0IHx8IGZhbHNlLFxuICAgICAgZXhlY3V0aW5nSGFuZGxlciAgICAgIDogZmFsc2VcbiAgICB9KTtcblxuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgYWRkTGlzdGVuZXIoa2V5Q29tYm9TdHIsIHByZXNzSGFuZGxlciwgcmVsZWFzZUhhbmRsZXIsIHByZXZlbnRSZXBlYXRCeURlZmF1bHQpIHtcbiAgICByZXR1cm4gdGhpcy5iaW5kKGtleUNvbWJvU3RyLCBwcmVzc0hhbmRsZXIsIHJlbGVhc2VIYW5kbGVyLCBwcmV2ZW50UmVwZWF0QnlEZWZhdWx0KTtcbiAgfVxuXG4gIG9uKGtleUNvbWJvU3RyLCBwcmVzc0hhbmRsZXIsIHJlbGVhc2VIYW5kbGVyLCBwcmV2ZW50UmVwZWF0QnlEZWZhdWx0KSB7XG4gICAgcmV0dXJuIHRoaXMuYmluZChrZXlDb21ib1N0ciwgcHJlc3NIYW5kbGVyLCByZWxlYXNlSGFuZGxlciwgcHJldmVudFJlcGVhdEJ5RGVmYXVsdCk7XG4gIH1cblxuICBiaW5kUHJlc3Moa2V5Q29tYm9TdHIsIHByZXNzSGFuZGxlciwgcHJldmVudFJlcGVhdEJ5RGVmYXVsdCkge1xuICAgIHJldHVybiB0aGlzLmJpbmQoa2V5Q29tYm9TdHIsIHByZXNzSGFuZGxlciwgbnVsbCwgcHJldmVudFJlcGVhdEJ5RGVmYXVsdCk7XG4gIH1cblxuICBiaW5kUmVsZWFzZShrZXlDb21ib1N0ciwgcmVsZWFzZUhhbmRsZXIpIHtcbiAgICByZXR1cm4gdGhpcy5iaW5kKGtleUNvbWJvU3RyLCBudWxsLCByZWxlYXNlSGFuZGxlciwgcHJldmVudFJlcGVhdEJ5RGVmYXVsdCk7XG4gIH1cblxuICB1bmJpbmQoa2V5Q29tYm9TdHIsIHByZXNzSGFuZGxlciwgcmVsZWFzZUhhbmRsZXIpIHtcbiAgICBpZiAoa2V5Q29tYm9TdHIgPT09IG51bGwgfHwgdHlwZW9mIGtleUNvbWJvU3RyID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICByZWxlYXNlSGFuZGxlciA9IHByZXNzSGFuZGxlcjtcbiAgICAgIHByZXNzSGFuZGxlciAgID0ga2V5Q29tYm9TdHI7XG4gICAgICBrZXlDb21ib1N0ciA9IG51bGw7XG4gICAgfVxuXG4gICAgaWYgKFxuICAgICAga2V5Q29tYm9TdHIgJiZcbiAgICAgIHR5cGVvZiBrZXlDb21ib1N0ciA9PT0gJ29iamVjdCcgJiZcbiAgICAgIHR5cGVvZiBrZXlDb21ib1N0ci5sZW5ndGggPT09ICdudW1iZXInXG4gICAgKSB7XG4gICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGtleUNvbWJvU3RyLmxlbmd0aDsgaSArPSAxKSB7XG4gICAgICAgIHRoaXMudW5iaW5kKGtleUNvbWJvU3RyW2ldLCBwcmVzc0hhbmRsZXIsIHJlbGVhc2VIYW5kbGVyKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5fbGlzdGVuZXJzLmxlbmd0aDsgaSArPSAxKSB7XG4gICAgICBjb25zdCBsaXN0ZW5lciA9IHRoaXMuX2xpc3RlbmVyc1tpXTtcblxuICAgICAgY29uc3QgY29tYm9NYXRjaGVzICAgICAgICAgID0gIWtleUNvbWJvU3RyICYmICFsaXN0ZW5lci5rZXlDb21ibyB8fFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxpc3RlbmVyLmtleUNvbWJvICYmIGxpc3RlbmVyLmtleUNvbWJvLmlzRXF1YWwoa2V5Q29tYm9TdHIpO1xuICAgICAgY29uc3QgcHJlc3NIYW5kbGVyTWF0Y2hlcyAgID0gIXByZXNzSGFuZGxlciAmJiAhcmVsZWFzZUhhbmRsZXIgfHxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAhcHJlc3NIYW5kbGVyICYmICFsaXN0ZW5lci5wcmVzc0hhbmRsZXIgfHxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcmVzc0hhbmRsZXIgPT09IGxpc3RlbmVyLnByZXNzSGFuZGxlcjtcbiAgICAgIGNvbnN0IHJlbGVhc2VIYW5kbGVyTWF0Y2hlcyA9ICFwcmVzc0hhbmRsZXIgJiYgIXJlbGVhc2VIYW5kbGVyIHx8XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIXJlbGVhc2VIYW5kbGVyICYmICFsaXN0ZW5lci5yZWxlYXNlSGFuZGxlciB8fFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlbGVhc2VIYW5kbGVyID09PSBsaXN0ZW5lci5yZWxlYXNlSGFuZGxlcjtcblxuICAgICAgaWYgKGNvbWJvTWF0Y2hlcyAmJiBwcmVzc0hhbmRsZXJNYXRjaGVzICYmIHJlbGVhc2VIYW5kbGVyTWF0Y2hlcykge1xuICAgICAgICB0aGlzLl9saXN0ZW5lcnMuc3BsaWNlKGksIDEpO1xuICAgICAgICBpIC09IDE7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICByZW1vdmVMaXN0ZW5lcihrZXlDb21ib1N0ciwgcHJlc3NIYW5kbGVyLCByZWxlYXNlSGFuZGxlcikge1xuICAgIHJldHVybiB0aGlzLnVuYmluZChrZXlDb21ib1N0ciwgcHJlc3NIYW5kbGVyLCByZWxlYXNlSGFuZGxlcik7XG4gIH1cblxuICBvZmYoa2V5Q29tYm9TdHIsIHByZXNzSGFuZGxlciwgcmVsZWFzZUhhbmRsZXIpIHtcbiAgICByZXR1cm4gdGhpcy51bmJpbmQoa2V5Q29tYm9TdHIsIHByZXNzSGFuZGxlciwgcmVsZWFzZUhhbmRsZXIpO1xuICB9XG5cbiAgc2V0Q29udGV4dChjb250ZXh0TmFtZSkge1xuICAgIGlmKHRoaXMuX2xvY2FsZSkgeyB0aGlzLnJlbGVhc2VBbGxLZXlzKCk7IH1cblxuICAgIGlmICghdGhpcy5fY29udGV4dHNbY29udGV4dE5hbWVdKSB7XG4gICAgICBjb25zdCBnbG9iYWxDb250ZXh0ID0gdGhpcy5fY29udGV4dHMuZ2xvYmFsO1xuICAgICAgdGhpcy5fY29udGV4dHNbY29udGV4dE5hbWVdID0ge1xuICAgICAgICBsaXN0ZW5lcnMgICAgICA6IFtdLFxuICAgICAgICB0YXJnZXRXaW5kb3cgICA6IGdsb2JhbENvbnRleHQudGFyZ2V0V2luZG93LFxuICAgICAgICB0YXJnZXRFbGVtZW50ICA6IGdsb2JhbENvbnRleHQudGFyZ2V0RWxlbWVudCxcbiAgICAgICAgdGFyZ2V0UGxhdGZvcm0gOiBnbG9iYWxDb250ZXh0LnRhcmdldFBsYXRmb3JtLFxuICAgICAgICB0YXJnZXRVc2VyQWdlbnQ6IGdsb2JhbENvbnRleHQudGFyZ2V0VXNlckFnZW50XG4gICAgICB9O1xuICAgIH1cblxuICAgIGNvbnN0IGNvbnRleHQgICAgICAgID0gdGhpcy5fY29udGV4dHNbY29udGV4dE5hbWVdO1xuICAgIHRoaXMuX2N1cnJlbnRDb250ZXh0ID0gY29udGV4dE5hbWU7XG4gICAgdGhpcy5fbGlzdGVuZXJzICAgICAgPSBjb250ZXh0Lmxpc3RlbmVycztcblxuICAgIHRoaXMuc3RvcCgpO1xuICAgIHRoaXMud2F0Y2goXG4gICAgICBjb250ZXh0LnRhcmdldFdpbmRvdyxcbiAgICAgIGNvbnRleHQudGFyZ2V0RWxlbWVudCxcbiAgICAgIGNvbnRleHQudGFyZ2V0UGxhdGZvcm0sXG4gICAgICBjb250ZXh0LnRhcmdldFVzZXJBZ2VudFxuICAgICk7XG5cbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIGdldENvbnRleHQoKSB7XG4gICAgcmV0dXJuIHRoaXMuX2N1cnJlbnRDb250ZXh0O1xuICB9XG5cbiAgd2l0aENvbnRleHQoY29udGV4dE5hbWUsIGNhbGxiYWNrKSB7XG4gICAgY29uc3QgcHJldmlvdXNDb250ZXh0TmFtZSA9IHRoaXMuZ2V0Q29udGV4dCgpO1xuICAgIHRoaXMuc2V0Q29udGV4dChjb250ZXh0TmFtZSk7XG5cbiAgICBjYWxsYmFjaygpO1xuXG4gICAgdGhpcy5zZXRDb250ZXh0KHByZXZpb3VzQ29udGV4dE5hbWUpO1xuXG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICB3YXRjaCh0YXJnZXRXaW5kb3csIHRhcmdldEVsZW1lbnQsIHRhcmdldFBsYXRmb3JtLCB0YXJnZXRVc2VyQWdlbnQpIHtcbiAgICB0aGlzLnN0b3AoKTtcblxuICAgIGNvbnN0IHdpbiA9IHR5cGVvZiBnbG9iYWxUaGlzICE9PSAndW5kZWZpbmVkJyA/IGdsb2JhbFRoaXMgOlxuICAgICAgICAgICAgICAgIHR5cGVvZiBnbG9iYWwgIT09ICd1bmRlZmluZWQnID8gZ2xvYmFsIDpcbiAgICAgICAgICAgICAgICB0eXBlb2Ygd2luZG93ICE9PSAndW5kZWZpbmVkJyA/IHdpbmRvdyA6XG4gICAgICAgICAgICAgICAge307XG5cbiAgICBpZiAoIXRhcmdldFdpbmRvdykge1xuICAgICAgaWYgKCF3aW4uYWRkRXZlbnRMaXN0ZW5lciAmJiAhd2luLmF0dGFjaEV2ZW50KSB7XG4gICAgICAgIC8vIFRoaXMgd2FzIGFkZGVkIHNvIHdoZW4gdXNpbmcgdGhpbmdzIGxpa2UgSlNET00gd2F0Y2ggY2FuIGJlIHVzZWQgdG8gY29uZmlndXJlIHdhdGNoXG4gICAgICAgIC8vIGZvciB0aGUgZ2xvYmFsIG5hbWVzcGFjZSBtYW51YWxseS5cbiAgICAgICAgaWYgKHRoaXMuX2N1cnJlbnRDb250ZXh0ID09PSAnZ2xvYmFsJykge1xuICAgICAgICAgIHJldHVyblxuICAgICAgICB9XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignQ2Fubm90IGZpbmQgd2luZG93IGZ1bmN0aW9ucyBhZGRFdmVudExpc3RlbmVyIG9yIGF0dGFjaEV2ZW50LicpO1xuICAgICAgfVxuICAgICAgdGFyZ2V0V2luZG93ID0gd2luO1xuICAgIH1cblxuICAgIC8vIEhhbmRsZSBlbGVtZW50IGJpbmRpbmdzIHdoZXJlIGEgdGFyZ2V0IHdpbmRvdyBpcyBub3QgcGFzc2VkXG4gICAgaWYgKHR5cGVvZiB0YXJnZXRXaW5kb3cubm9kZVR5cGUgPT09ICdudW1iZXInKSB7XG4gICAgICB0YXJnZXRVc2VyQWdlbnQgPSB0YXJnZXRQbGF0Zm9ybTtcbiAgICAgIHRhcmdldFBsYXRmb3JtICA9IHRhcmdldEVsZW1lbnQ7XG4gICAgICB0YXJnZXRFbGVtZW50ICAgPSB0YXJnZXRXaW5kb3c7XG4gICAgICB0YXJnZXRXaW5kb3cgICAgPSB3aW47XG4gICAgfVxuXG4gICAgaWYgKCF0YXJnZXRXaW5kb3cuYWRkRXZlbnRMaXN0ZW5lciAmJiAhdGFyZ2V0V2luZG93LmF0dGFjaEV2ZW50KSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0Nhbm5vdCBmaW5kIGFkZEV2ZW50TGlzdGVuZXIgb3IgYXR0YWNoRXZlbnQgbWV0aG9kcyBvbiB0YXJnZXRXaW5kb3cuJyk7XG4gICAgfVxuXG4gICAgdGhpcy5faXNNb2Rlcm5Ccm93c2VyID0gISF0YXJnZXRXaW5kb3cuYWRkRXZlbnRMaXN0ZW5lcjtcblxuICAgIGNvbnN0IHVzZXJBZ2VudCA9IHRhcmdldFdpbmRvdy5uYXZpZ2F0b3IgJiYgdGFyZ2V0V2luZG93Lm5hdmlnYXRvci51c2VyQWdlbnQgfHwgJyc7XG4gICAgY29uc3QgcGxhdGZvcm0gID0gdGFyZ2V0V2luZG93Lm5hdmlnYXRvciAmJiB0YXJnZXRXaW5kb3cubmF2aWdhdG9yLnBsYXRmb3JtICB8fCAnJztcblxuICAgIHRhcmdldEVsZW1lbnQgICAmJiB0YXJnZXRFbGVtZW50ICAgIT09IG51bGwgfHwgKHRhcmdldEVsZW1lbnQgICA9IHRhcmdldFdpbmRvdy5kb2N1bWVudCk7XG4gICAgdGFyZ2V0UGxhdGZvcm0gICYmIHRhcmdldFBsYXRmb3JtICAhPT0gbnVsbCB8fCAodGFyZ2V0UGxhdGZvcm0gID0gcGxhdGZvcm0pO1xuICAgIHRhcmdldFVzZXJBZ2VudCAmJiB0YXJnZXRVc2VyQWdlbnQgIT09IG51bGwgfHwgKHRhcmdldFVzZXJBZ2VudCA9IHVzZXJBZ2VudCk7XG5cbiAgICB0aGlzLl90YXJnZXRLZXlEb3duQmluZGluZyA9IChldmVudCkgPT4ge1xuICAgICAgdGhpcy5wcmVzc0tleShldmVudC5rZXlDb2RlLCBldmVudCk7XG4gICAgICB0aGlzLl9oYW5kbGVDb21tYW5kQnVnKGV2ZW50LCBwbGF0Zm9ybSk7XG4gICAgfTtcbiAgICB0aGlzLl90YXJnZXRLZXlVcEJpbmRpbmcgPSAoZXZlbnQpID0+IHtcbiAgICAgIHRoaXMucmVsZWFzZUtleShldmVudC5rZXlDb2RlLCBldmVudCk7XG4gICAgfTtcbiAgICB0aGlzLl90YXJnZXRSZXNldEJpbmRpbmcgPSAoZXZlbnQpID0+IHtcbiAgICAgIHRoaXMucmVsZWFzZUFsbEtleXMoZXZlbnQpO1xuICAgIH07XG5cbiAgICB0aGlzLl9iaW5kRXZlbnQodGFyZ2V0RWxlbWVudCwgJ2tleWRvd24nLCB0aGlzLl90YXJnZXRLZXlEb3duQmluZGluZyk7XG4gICAgdGhpcy5fYmluZEV2ZW50KHRhcmdldEVsZW1lbnQsICdrZXl1cCcsICAgdGhpcy5fdGFyZ2V0S2V5VXBCaW5kaW5nKTtcbiAgICB0aGlzLl9iaW5kRXZlbnQodGFyZ2V0V2luZG93LCAgJ2ZvY3VzJywgICB0aGlzLl90YXJnZXRSZXNldEJpbmRpbmcpO1xuICAgIHRoaXMuX2JpbmRFdmVudCh0YXJnZXRXaW5kb3csICAnYmx1cicsICAgIHRoaXMuX3RhcmdldFJlc2V0QmluZGluZyk7XG5cbiAgICB0aGlzLl90YXJnZXRFbGVtZW50ICAgPSB0YXJnZXRFbGVtZW50O1xuICAgIHRoaXMuX3RhcmdldFdpbmRvdyAgICA9IHRhcmdldFdpbmRvdztcbiAgICB0aGlzLl90YXJnZXRQbGF0Zm9ybSAgPSB0YXJnZXRQbGF0Zm9ybTtcbiAgICB0aGlzLl90YXJnZXRVc2VyQWdlbnQgPSB0YXJnZXRVc2VyQWdlbnQ7XG5cbiAgICBjb25zdCBjdXJyZW50Q29udGV4dCAgICAgICAgICAgPSB0aGlzLl9jb250ZXh0c1t0aGlzLl9jdXJyZW50Q29udGV4dF07XG4gICAgY3VycmVudENvbnRleHQudGFyZ2V0V2luZG93ICAgID0gdGhpcy5fdGFyZ2V0V2luZG93O1xuICAgIGN1cnJlbnRDb250ZXh0LnRhcmdldEVsZW1lbnQgICA9IHRoaXMuX3RhcmdldEVsZW1lbnQ7XG4gICAgY3VycmVudENvbnRleHQudGFyZ2V0UGxhdGZvcm0gID0gdGhpcy5fdGFyZ2V0UGxhdGZvcm07XG4gICAgY3VycmVudENvbnRleHQudGFyZ2V0VXNlckFnZW50ID0gdGhpcy5fdGFyZ2V0VXNlckFnZW50O1xuXG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICBzdG9wKCkge1xuICAgIGlmICghdGhpcy5fdGFyZ2V0RWxlbWVudCB8fCAhdGhpcy5fdGFyZ2V0V2luZG93KSB7IHJldHVybjsgfVxuXG4gICAgdGhpcy5fdW5iaW5kRXZlbnQodGhpcy5fdGFyZ2V0RWxlbWVudCwgJ2tleWRvd24nLCB0aGlzLl90YXJnZXRLZXlEb3duQmluZGluZyk7XG4gICAgdGhpcy5fdW5iaW5kRXZlbnQodGhpcy5fdGFyZ2V0RWxlbWVudCwgJ2tleXVwJywgICB0aGlzLl90YXJnZXRLZXlVcEJpbmRpbmcpO1xuICAgIHRoaXMuX3VuYmluZEV2ZW50KHRoaXMuX3RhcmdldFdpbmRvdywgICdmb2N1cycsICAgdGhpcy5fdGFyZ2V0UmVzZXRCaW5kaW5nKTtcbiAgICB0aGlzLl91bmJpbmRFdmVudCh0aGlzLl90YXJnZXRXaW5kb3csICAnYmx1cicsICAgIHRoaXMuX3RhcmdldFJlc2V0QmluZGluZyk7XG5cbiAgICB0aGlzLl90YXJnZXRXaW5kb3cgID0gbnVsbDtcbiAgICB0aGlzLl90YXJnZXRFbGVtZW50ID0gbnVsbDtcblxuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgcHJlc3NLZXkoa2V5Q29kZSwgZXZlbnQpIHtcbiAgICBpZiAodGhpcy5fcGF1c2VkKSB7IHJldHVybiB0aGlzOyB9XG4gICAgaWYgKCF0aGlzLl9sb2NhbGUpIHsgdGhyb3cgbmV3IEVycm9yKCdMb2NhbGUgbm90IHNldCcpOyB9XG5cbiAgICB0aGlzLl9sb2NhbGUucHJlc3NLZXkoa2V5Q29kZSk7XG4gICAgdGhpcy5fYXBwbHlCaW5kaW5ncyhldmVudCk7XG5cbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIHJlbGVhc2VLZXkoa2V5Q29kZSwgZXZlbnQpIHtcbiAgICBpZiAodGhpcy5fcGF1c2VkKSB7IHJldHVybiB0aGlzOyB9XG4gICAgaWYgKCF0aGlzLl9sb2NhbGUpIHsgdGhyb3cgbmV3IEVycm9yKCdMb2NhbGUgbm90IHNldCcpOyB9XG5cbiAgICB0aGlzLl9sb2NhbGUucmVsZWFzZUtleShrZXlDb2RlKTtcbiAgICB0aGlzLl9jbGVhckJpbmRpbmdzKGV2ZW50KTtcblxuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgcmVsZWFzZUFsbEtleXMoZXZlbnQpIHtcbiAgICBpZiAodGhpcy5fcGF1c2VkKSB7IHJldHVybiB0aGlzOyB9XG4gICAgaWYgKCF0aGlzLl9sb2NhbGUpIHsgdGhyb3cgbmV3IEVycm9yKCdMb2NhbGUgbm90IHNldCcpOyB9XG5cbiAgICB0aGlzLl9sb2NhbGUucHJlc3NlZEtleXMubGVuZ3RoID0gMDtcbiAgICB0aGlzLl9jbGVhckJpbmRpbmdzKGV2ZW50KTtcblxuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgcGF1c2UoKSB7XG4gICAgaWYgKHRoaXMuX3BhdXNlZCkgeyByZXR1cm4gdGhpczsgfVxuICAgIGlmICh0aGlzLl9sb2NhbGUpIHsgdGhpcy5yZWxlYXNlQWxsS2V5cygpOyB9XG4gICAgdGhpcy5fcGF1c2VkID0gdHJ1ZTtcblxuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgcmVzdW1lKCkge1xuICAgIHRoaXMuX3BhdXNlZCA9IGZhbHNlO1xuXG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICByZXNldCgpIHtcbiAgICB0aGlzLnJlbGVhc2VBbGxLZXlzKCk7XG4gICAgdGhpcy5fbGlzdGVuZXJzLmxlbmd0aCA9IDA7XG5cbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIF9iaW5kRXZlbnQodGFyZ2V0RWxlbWVudCwgZXZlbnROYW1lLCBoYW5kbGVyKSB7XG4gICAgcmV0dXJuIHRoaXMuX2lzTW9kZXJuQnJvd3NlciA/XG4gICAgICB0YXJnZXRFbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoZXZlbnROYW1lLCBoYW5kbGVyLCBmYWxzZSkgOlxuICAgICAgdGFyZ2V0RWxlbWVudC5hdHRhY2hFdmVudCgnb24nICsgZXZlbnROYW1lLCBoYW5kbGVyKTtcbiAgfVxuXG4gIF91bmJpbmRFdmVudCh0YXJnZXRFbGVtZW50LCBldmVudE5hbWUsIGhhbmRsZXIpIHtcbiAgICByZXR1cm4gdGhpcy5faXNNb2Rlcm5Ccm93c2VyID9cbiAgICAgIHRhcmdldEVsZW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcihldmVudE5hbWUsIGhhbmRsZXIsIGZhbHNlKSA6XG4gICAgICB0YXJnZXRFbGVtZW50LmRldGFjaEV2ZW50KCdvbicgKyBldmVudE5hbWUsIGhhbmRsZXIpO1xuICB9XG5cbiAgX2dldEdyb3VwZWRMaXN0ZW5lcnMoKSB7XG4gICAgY29uc3QgbGlzdGVuZXJHcm91cHMgICA9IFtdO1xuICAgIGNvbnN0IGxpc3RlbmVyR3JvdXBNYXAgPSBbXTtcblxuICAgIGxldCBsaXN0ZW5lcnMgPSB0aGlzLl9saXN0ZW5lcnM7XG4gICAgaWYgKHRoaXMuX2N1cnJlbnRDb250ZXh0ICE9PSAnZ2xvYmFsJykge1xuICAgICAgbGlzdGVuZXJzID0gWy4uLmxpc3RlbmVycywgLi4udGhpcy5fY29udGV4dHMuZ2xvYmFsLmxpc3RlbmVyc107XG4gICAgfVxuXG4gICAgbGlzdGVuZXJzLnNvcnQoXG4gICAgICAoYSwgYikgPT5cbiAgICAgICAgKGIua2V5Q29tYm8gPyBiLmtleUNvbWJvLmtleU5hbWVzLmxlbmd0aCA6IDApIC1cbiAgICAgICAgKGEua2V5Q29tYm8gPyBhLmtleUNvbWJvLmtleU5hbWVzLmxlbmd0aCA6IDApXG4gICAgKS5mb3JFYWNoKChsKSA9PiB7XG4gICAgICBsZXQgbWFwSW5kZXggPSAtMTtcbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbGlzdGVuZXJHcm91cE1hcC5sZW5ndGg7IGkgKz0gMSkge1xuICAgICAgICBpZiAobGlzdGVuZXJHcm91cE1hcFtpXSA9PT0gbnVsbCAmJiBsLmtleUNvbWJvID09PSBudWxsIHx8XG4gICAgICAgICAgICBsaXN0ZW5lckdyb3VwTWFwW2ldICE9PSBudWxsICYmIGxpc3RlbmVyR3JvdXBNYXBbaV0uaXNFcXVhbChsLmtleUNvbWJvKSkge1xuICAgICAgICAgIG1hcEluZGV4ID0gaTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKG1hcEluZGV4ID09PSAtMSkge1xuICAgICAgICBtYXBJbmRleCA9IGxpc3RlbmVyR3JvdXBNYXAubGVuZ3RoO1xuICAgICAgICBsaXN0ZW5lckdyb3VwTWFwLnB1c2gobC5rZXlDb21ibyk7XG4gICAgICB9XG4gICAgICBpZiAoIWxpc3RlbmVyR3JvdXBzW21hcEluZGV4XSkge1xuICAgICAgICBsaXN0ZW5lckdyb3Vwc1ttYXBJbmRleF0gPSBbXTtcbiAgICAgIH1cbiAgICAgIGxpc3RlbmVyR3JvdXBzW21hcEluZGV4XS5wdXNoKGwpO1xuICAgIH0pO1xuXG4gICAgcmV0dXJuIGxpc3RlbmVyR3JvdXBzO1xuICB9XG5cbiAgX2FwcGx5QmluZGluZ3MoZXZlbnQpIHtcbiAgICBsZXQgcHJldmVudFJlcGVhdCA9IGZhbHNlO1xuXG4gICAgZXZlbnQgfHwgKGV2ZW50ID0ge30pO1xuICAgIGV2ZW50LnByZXZlbnRSZXBlYXQgPSAoKSA9PiB7IHByZXZlbnRSZXBlYXQgPSB0cnVlOyB9O1xuICAgIGV2ZW50LnByZXNzZWRLZXlzICAgPSB0aGlzLl9sb2NhbGUucHJlc3NlZEtleXMuc2xpY2UoMCk7XG5cbiAgICBjb25zdCBhY3RpdmVUYXJnZXRLZXlzID0gdGhpcy5fbG9jYWxlLmFjdGl2ZVRhcmdldEtleXM7XG4gICAgY29uc3QgcHJlc3NlZEtleXMgICAgICA9IHRoaXMuX2xvY2FsZS5wcmVzc2VkS2V5cy5zbGljZSgwKTtcbiAgICBjb25zdCBsaXN0ZW5lckdyb3VwcyAgID0gdGhpcy5fZ2V0R3JvdXBlZExpc3RlbmVycygpO1xuXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBsaXN0ZW5lckdyb3Vwcy5sZW5ndGg7IGkgKz0gMSkge1xuICAgICAgY29uc3QgbGlzdGVuZXJzID0gbGlzdGVuZXJHcm91cHNbaV07XG4gICAgICBjb25zdCBrZXlDb21ibyAgPSBsaXN0ZW5lcnNbMF0ua2V5Q29tYm87XG5cbiAgICAgIGlmIChcbiAgICAgICAga2V5Q29tYm8gPT09IG51bGwgfHxcbiAgICAgICAga2V5Q29tYm8uY2hlY2socHJlc3NlZEtleXMpICYmXG4gICAgICAgIGFjdGl2ZVRhcmdldEtleXMuc29tZShrID0+IGtleUNvbWJvLmtleU5hbWVzLmluY2x1ZGVzKGspKVxuICAgICAgKSB7XG4gICAgICAgIGZvciAobGV0IGogPSAwOyBqIDwgbGlzdGVuZXJzLmxlbmd0aDsgaiArPSAxKSB7XG4gICAgICAgICAgbGV0IGxpc3RlbmVyID0gbGlzdGVuZXJzW2pdO1xuXG4gICAgICAgICAgaWYgKCFsaXN0ZW5lci5leGVjdXRpbmdIYW5kbGVyICYmIGxpc3RlbmVyLnByZXNzSGFuZGxlciAmJiAhbGlzdGVuZXIucHJldmVudFJlcGVhdCkge1xuICAgICAgICAgICAgbGlzdGVuZXIuZXhlY3V0aW5nSGFuZGxlciA9IHRydWU7XG4gICAgICAgICAgICBsaXN0ZW5lci5wcmVzc0hhbmRsZXIuY2FsbCh0aGlzLCBldmVudCk7XG4gICAgICAgICAgICBsaXN0ZW5lci5leGVjdXRpbmdIYW5kbGVyID0gZmFsc2U7XG5cbiAgICAgICAgICAgIGlmIChwcmV2ZW50UmVwZWF0IHx8IGxpc3RlbmVyLnByZXZlbnRSZXBlYXRCeURlZmF1bHQpIHtcbiAgICAgICAgICAgICAgbGlzdGVuZXIucHJldmVudFJlcGVhdCA9IHRydWU7XG4gICAgICAgICAgICAgIHByZXZlbnRSZXBlYXQgICAgICAgICAgPSBmYWxzZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAodGhpcy5fYXBwbGllZExpc3RlbmVycy5pbmRleE9mKGxpc3RlbmVyKSA9PT0gLTEpIHtcbiAgICAgICAgICAgIHRoaXMuX2FwcGxpZWRMaXN0ZW5lcnMucHVzaChsaXN0ZW5lcik7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGtleUNvbWJvKSB7XG4gICAgICAgICAgZm9yIChsZXQgaiA9IDA7IGogPCBrZXlDb21iby5rZXlOYW1lcy5sZW5ndGg7IGogKz0gMSkge1xuICAgICAgICAgICAgY29uc3QgaW5kZXggPSBwcmVzc2VkS2V5cy5pbmRleE9mKGtleUNvbWJvLmtleU5hbWVzW2pdKTtcbiAgICAgICAgICAgIGlmIChpbmRleCAhPT0gLTEpIHtcbiAgICAgICAgICAgICAgcHJlc3NlZEtleXMuc3BsaWNlKGluZGV4LCAxKTtcbiAgICAgICAgICAgICAgaiAtPSAxO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIF9jbGVhckJpbmRpbmdzKGV2ZW50KSB7XG4gICAgZXZlbnQgfHwgKGV2ZW50ID0ge30pO1xuICAgIGV2ZW50LnByZXNzZWRLZXlzID0gdGhpcy5fbG9jYWxlLnByZXNzZWRLZXlzLnNsaWNlKDApO1xuXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLl9hcHBsaWVkTGlzdGVuZXJzLmxlbmd0aDsgaSArPSAxKSB7XG4gICAgICBjb25zdCBsaXN0ZW5lciA9IHRoaXMuX2FwcGxpZWRMaXN0ZW5lcnNbaV07XG4gICAgICBjb25zdCBrZXlDb21ibyA9IGxpc3RlbmVyLmtleUNvbWJvO1xuICAgICAgaWYgKGtleUNvbWJvID09PSBudWxsIHx8ICFrZXlDb21iby5jaGVjayh0aGlzLl9sb2NhbGUucHJlc3NlZEtleXMpKSB7XG4gICAgICAgIGxpc3RlbmVyLnByZXZlbnRSZXBlYXQgPSBmYWxzZTtcbiAgICAgICAgaWYgKGtleUNvbWJvICE9PSBudWxsIHx8IGV2ZW50LnByZXNzZWRLZXlzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgIHRoaXMuX2FwcGxpZWRMaXN0ZW5lcnMuc3BsaWNlKGksIDEpO1xuICAgICAgICAgIGkgLT0gMTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoIWxpc3RlbmVyLmV4ZWN1dGluZ0hhbmRsZXIgJiYgbGlzdGVuZXIucmVsZWFzZUhhbmRsZXIpIHtcbiAgICAgICAgICBsaXN0ZW5lci5leGVjdXRpbmdIYW5kbGVyID0gdHJ1ZTtcbiAgICAgICAgICBsaXN0ZW5lci5yZWxlYXNlSGFuZGxlci5jYWxsKHRoaXMsIGV2ZW50KTtcbiAgICAgICAgICBsaXN0ZW5lci5leGVjdXRpbmdIYW5kbGVyID0gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBfaGFuZGxlQ29tbWFuZEJ1ZyhldmVudCwgcGxhdGZvcm0pIHtcbiAgICAvLyBPbiBNYWMgd2hlbiB0aGUgY29tbWFuZCBrZXkgaXMga2VwdCBwcmVzc2VkLCBrZXl1cCBpcyBub3QgdHJpZ2dlcmVkIGZvciBhbnkgb3RoZXIga2V5LlxuICAgIC8vIEluIHRoaXMgY2FzZSBmb3JjZSBhIGtleXVwIGZvciBub24tbW9kaWZpZXIga2V5cyBkaXJlY3RseSBhZnRlciB0aGUga2V5cHJlc3MuXG4gICAgY29uc3QgbW9kaWZpZXJLZXlzID0gW1wic2hpZnRcIiwgXCJjdHJsXCIsIFwiYWx0XCIsIFwiY2Fwc2xvY2tcIiwgXCJ0YWJcIiwgXCJjb21tYW5kXCJdO1xuICAgIGlmIChwbGF0Zm9ybS5tYXRjaChcIk1hY1wiKSAmJiB0aGlzLl9sb2NhbGUucHJlc3NlZEtleXMuaW5jbHVkZXMoXCJjb21tYW5kXCIpICYmXG4gICAgICAgICFtb2RpZmllcktleXMuaW5jbHVkZXModGhpcy5fbG9jYWxlLmdldEtleU5hbWVzKGV2ZW50LmtleUNvZGUpWzBdKSkge1xuICAgICAgdGhpcy5fdGFyZ2V0S2V5VXBCaW5kaW5nKGV2ZW50KTtcbiAgICB9XG4gIH1cbn1cbiIsIlxuZXhwb3J0IGZ1bmN0aW9uIHVzKGxvY2FsZSwgcGxhdGZvcm0sIHVzZXJBZ2VudCkge1xuXG4gIC8vIGdlbmVyYWxcbiAgbG9jYWxlLmJpbmRLZXlDb2RlKDMsICAgWydjYW5jZWwnXSk7XG4gIGxvY2FsZS5iaW5kS2V5Q29kZSg4LCAgIFsnYmFja3NwYWNlJ10pO1xuICBsb2NhbGUuYmluZEtleUNvZGUoOSwgICBbJ3RhYiddKTtcbiAgbG9jYWxlLmJpbmRLZXlDb2RlKDEyLCAgWydjbGVhciddKTtcbiAgbG9jYWxlLmJpbmRLZXlDb2RlKDEzLCAgWydlbnRlciddKTtcbiAgbG9jYWxlLmJpbmRLZXlDb2RlKDE2LCAgWydzaGlmdCddKTtcbiAgbG9jYWxlLmJpbmRLZXlDb2RlKDE3LCAgWydjdHJsJ10pO1xuICBsb2NhbGUuYmluZEtleUNvZGUoMTgsICBbJ2FsdCcsICdtZW51J10pO1xuICBsb2NhbGUuYmluZEtleUNvZGUoMTksICBbJ3BhdXNlJywgJ2JyZWFrJ10pO1xuICBsb2NhbGUuYmluZEtleUNvZGUoMjAsICBbJ2NhcHNsb2NrJ10pO1xuICBsb2NhbGUuYmluZEtleUNvZGUoMjcsICBbJ2VzY2FwZScsICdlc2MnXSk7XG4gIGxvY2FsZS5iaW5kS2V5Q29kZSgzMiwgIFsnc3BhY2UnLCAnc3BhY2ViYXInXSk7XG4gIGxvY2FsZS5iaW5kS2V5Q29kZSgzMywgIFsncGFnZXVwJ10pO1xuICBsb2NhbGUuYmluZEtleUNvZGUoMzQsICBbJ3BhZ2Vkb3duJ10pO1xuICBsb2NhbGUuYmluZEtleUNvZGUoMzUsICBbJ2VuZCddKTtcbiAgbG9jYWxlLmJpbmRLZXlDb2RlKDM2LCAgWydob21lJ10pO1xuICBsb2NhbGUuYmluZEtleUNvZGUoMzcsICBbJ2xlZnQnXSk7XG4gIGxvY2FsZS5iaW5kS2V5Q29kZSgzOCwgIFsndXAnXSk7XG4gIGxvY2FsZS5iaW5kS2V5Q29kZSgzOSwgIFsncmlnaHQnXSk7XG4gIGxvY2FsZS5iaW5kS2V5Q29kZSg0MCwgIFsnZG93biddKTtcbiAgbG9jYWxlLmJpbmRLZXlDb2RlKDQxLCAgWydzZWxlY3QnXSk7XG4gIGxvY2FsZS5iaW5kS2V5Q29kZSg0MiwgIFsncHJpbnRzY3JlZW4nXSk7XG4gIGxvY2FsZS5iaW5kS2V5Q29kZSg0MywgIFsnZXhlY3V0ZSddKTtcbiAgbG9jYWxlLmJpbmRLZXlDb2RlKDQ0LCAgWydzbmFwc2hvdCddKTtcbiAgbG9jYWxlLmJpbmRLZXlDb2RlKDQ1LCAgWydpbnNlcnQnLCAnaW5zJ10pO1xuICBsb2NhbGUuYmluZEtleUNvZGUoNDYsICBbJ2RlbGV0ZScsICdkZWwnXSk7XG4gIGxvY2FsZS5iaW5kS2V5Q29kZSg0NywgIFsnaGVscCddKTtcbiAgbG9jYWxlLmJpbmRLZXlDb2RlKDE0NSwgWydzY3JvbGxsb2NrJywgJ3Njcm9sbCddKTtcbiAgbG9jYWxlLmJpbmRLZXlDb2RlKDE4OCwgWydjb21tYScsICcsJ10pO1xuICBsb2NhbGUuYmluZEtleUNvZGUoMTkwLCBbJ3BlcmlvZCcsICcuJ10pO1xuICBsb2NhbGUuYmluZEtleUNvZGUoMTkxLCBbJ3NsYXNoJywgJ2ZvcndhcmRzbGFzaCcsICcvJ10pO1xuICBsb2NhbGUuYmluZEtleUNvZGUoMTkyLCBbJ2dyYXZlYWNjZW50JywgJ2AnXSk7XG4gIGxvY2FsZS5iaW5kS2V5Q29kZSgyMTksIFsnb3BlbmJyYWNrZXQnLCAnWyddKTtcbiAgbG9jYWxlLmJpbmRLZXlDb2RlKDIyMCwgWydiYWNrc2xhc2gnLCAnXFxcXCddKTtcbiAgbG9jYWxlLmJpbmRLZXlDb2RlKDIyMSwgWydjbG9zZWJyYWNrZXQnLCAnXSddKTtcbiAgbG9jYWxlLmJpbmRLZXlDb2RlKDIyMiwgWydhcG9zdHJvcGhlJywgJ1xcJyddKTtcblxuICAvLyAwLTlcbiAgbG9jYWxlLmJpbmRLZXlDb2RlKDQ4LCBbJ3plcm8nLCAnMCddKTtcbiAgbG9jYWxlLmJpbmRLZXlDb2RlKDQ5LCBbJ29uZScsICcxJ10pO1xuICBsb2NhbGUuYmluZEtleUNvZGUoNTAsIFsndHdvJywgJzInXSk7XG4gIGxvY2FsZS5iaW5kS2V5Q29kZSg1MSwgWyd0aHJlZScsICczJ10pO1xuICBsb2NhbGUuYmluZEtleUNvZGUoNTIsIFsnZm91cicsICc0J10pO1xuICBsb2NhbGUuYmluZEtleUNvZGUoNTMsIFsnZml2ZScsICc1J10pO1xuICBsb2NhbGUuYmluZEtleUNvZGUoNTQsIFsnc2l4JywgJzYnXSk7XG4gIGxvY2FsZS5iaW5kS2V5Q29kZSg1NSwgWydzZXZlbicsICc3J10pO1xuICBsb2NhbGUuYmluZEtleUNvZGUoNTYsIFsnZWlnaHQnLCAnOCddKTtcbiAgbG9jYWxlLmJpbmRLZXlDb2RlKDU3LCBbJ25pbmUnLCAnOSddKTtcblxuICAvLyBudW1wYWRcbiAgbG9jYWxlLmJpbmRLZXlDb2RlKDk2LCBbJ251bXplcm8nLCAnbnVtMCddKTtcbiAgbG9jYWxlLmJpbmRLZXlDb2RlKDk3LCBbJ251bW9uZScsICdudW0xJ10pO1xuICBsb2NhbGUuYmluZEtleUNvZGUoOTgsIFsnbnVtdHdvJywgJ251bTInXSk7XG4gIGxvY2FsZS5iaW5kS2V5Q29kZSg5OSwgWydudW10aHJlZScsICdudW0zJ10pO1xuICBsb2NhbGUuYmluZEtleUNvZGUoMTAwLCBbJ251bWZvdXInLCAnbnVtNCddKTtcbiAgbG9jYWxlLmJpbmRLZXlDb2RlKDEwMSwgWydudW1maXZlJywgJ251bTUnXSk7XG4gIGxvY2FsZS5iaW5kS2V5Q29kZSgxMDIsIFsnbnVtc2l4JywgJ251bTYnXSk7XG4gIGxvY2FsZS5iaW5kS2V5Q29kZSgxMDMsIFsnbnVtc2V2ZW4nLCAnbnVtNyddKTtcbiAgbG9jYWxlLmJpbmRLZXlDb2RlKDEwNCwgWydudW1laWdodCcsICdudW04J10pO1xuICBsb2NhbGUuYmluZEtleUNvZGUoMTA1LCBbJ251bW5pbmUnLCAnbnVtOSddKTtcbiAgbG9jYWxlLmJpbmRLZXlDb2RlKDEwNiwgWydudW1tdWx0aXBseScsICdudW0qJ10pO1xuICBsb2NhbGUuYmluZEtleUNvZGUoMTA3LCBbJ251bWFkZCcsICdudW0rJ10pO1xuICBsb2NhbGUuYmluZEtleUNvZGUoMTA4LCBbJ251bWVudGVyJ10pO1xuICBsb2NhbGUuYmluZEtleUNvZGUoMTA5LCBbJ251bXN1YnRyYWN0JywgJ251bS0nXSk7XG4gIGxvY2FsZS5iaW5kS2V5Q29kZSgxMTAsIFsnbnVtZGVjaW1hbCcsICdudW0uJ10pO1xuICBsb2NhbGUuYmluZEtleUNvZGUoMTExLCBbJ251bWRpdmlkZScsICdudW0vJ10pO1xuICBsb2NhbGUuYmluZEtleUNvZGUoMTQ0LCBbJ251bWxvY2snLCAnbnVtJ10pO1xuXG4gIC8vIGZ1bmN0aW9uIGtleXNcbiAgbG9jYWxlLmJpbmRLZXlDb2RlKDExMiwgWydmMSddKTtcbiAgbG9jYWxlLmJpbmRLZXlDb2RlKDExMywgWydmMiddKTtcbiAgbG9jYWxlLmJpbmRLZXlDb2RlKDExNCwgWydmMyddKTtcbiAgbG9jYWxlLmJpbmRLZXlDb2RlKDExNSwgWydmNCddKTtcbiAgbG9jYWxlLmJpbmRLZXlDb2RlKDExNiwgWydmNSddKTtcbiAgbG9jYWxlLmJpbmRLZXlDb2RlKDExNywgWydmNiddKTtcbiAgbG9jYWxlLmJpbmRLZXlDb2RlKDExOCwgWydmNyddKTtcbiAgbG9jYWxlLmJpbmRLZXlDb2RlKDExOSwgWydmOCddKTtcbiAgbG9jYWxlLmJpbmRLZXlDb2RlKDEyMCwgWydmOSddKTtcbiAgbG9jYWxlLmJpbmRLZXlDb2RlKDEyMSwgWydmMTAnXSk7XG4gIGxvY2FsZS5iaW5kS2V5Q29kZSgxMjIsIFsnZjExJ10pO1xuICBsb2NhbGUuYmluZEtleUNvZGUoMTIzLCBbJ2YxMiddKTtcbiAgbG9jYWxlLmJpbmRLZXlDb2RlKDEyNCwgWydmMTMnXSk7XG4gIGxvY2FsZS5iaW5kS2V5Q29kZSgxMjUsIFsnZjE0J10pO1xuICBsb2NhbGUuYmluZEtleUNvZGUoMTI2LCBbJ2YxNSddKTtcbiAgbG9jYWxlLmJpbmRLZXlDb2RlKDEyNywgWydmMTYnXSk7XG4gIGxvY2FsZS5iaW5kS2V5Q29kZSgxMjgsIFsnZjE3J10pO1xuICBsb2NhbGUuYmluZEtleUNvZGUoMTI5LCBbJ2YxOCddKTtcbiAgbG9jYWxlLmJpbmRLZXlDb2RlKDEzMCwgWydmMTknXSk7XG4gIGxvY2FsZS5iaW5kS2V5Q29kZSgxMzEsIFsnZjIwJ10pO1xuICBsb2NhbGUuYmluZEtleUNvZGUoMTMyLCBbJ2YyMSddKTtcbiAgbG9jYWxlLmJpbmRLZXlDb2RlKDEzMywgWydmMjInXSk7XG4gIGxvY2FsZS5iaW5kS2V5Q29kZSgxMzQsIFsnZjIzJ10pO1xuICBsb2NhbGUuYmluZEtleUNvZGUoMTM1LCBbJ2YyNCddKTtcblxuICAvLyBzZWNvbmRhcnkga2V5IHN5bWJvbHNcbiAgbG9jYWxlLmJpbmRNYWNybygnc2hpZnQgKyBgJywgWyd0aWxkZScsICd+J10pO1xuICBsb2NhbGUuYmluZE1hY3JvKCdzaGlmdCArIDEnLCBbJ2V4Y2xhbWF0aW9uJywgJ2V4Y2xhbWF0aW9ucG9pbnQnLCAnISddKTtcbiAgbG9jYWxlLmJpbmRNYWNybygnc2hpZnQgKyAyJywgWydhdCcsICdAJ10pO1xuICBsb2NhbGUuYmluZE1hY3JvKCdzaGlmdCArIDMnLCBbJ251bWJlcicsICcjJ10pO1xuICBsb2NhbGUuYmluZE1hY3JvKCdzaGlmdCArIDQnLCBbJ2RvbGxhcicsICdkb2xsYXJzJywgJ2RvbGxhcnNpZ24nLCAnJCddKTtcbiAgbG9jYWxlLmJpbmRNYWNybygnc2hpZnQgKyA1JywgWydwZXJjZW50JywgJyUnXSk7XG4gIGxvY2FsZS5iaW5kTWFjcm8oJ3NoaWZ0ICsgNicsIFsnY2FyZXQnLCAnXiddKTtcbiAgbG9jYWxlLmJpbmRNYWNybygnc2hpZnQgKyA3JywgWydhbXBlcnNhbmQnLCAnYW5kJywgJyYnXSk7XG4gIGxvY2FsZS5iaW5kTWFjcm8oJ3NoaWZ0ICsgOCcsIFsnYXN0ZXJpc2snLCAnKiddKTtcbiAgbG9jYWxlLmJpbmRNYWNybygnc2hpZnQgKyA5JywgWydvcGVucGFyZW4nLCAnKCddKTtcbiAgbG9jYWxlLmJpbmRNYWNybygnc2hpZnQgKyAwJywgWydjbG9zZXBhcmVuJywgJyknXSk7XG4gIGxvY2FsZS5iaW5kTWFjcm8oJ3NoaWZ0ICsgLScsIFsndW5kZXJzY29yZScsICdfJ10pO1xuICBsb2NhbGUuYmluZE1hY3JvKCdzaGlmdCArID0nLCBbJ3BsdXMnLCAnKyddKTtcbiAgbG9jYWxlLmJpbmRNYWNybygnc2hpZnQgKyBbJywgWydvcGVuY3VybHlicmFjZScsICdvcGVuY3VybHlicmFja2V0JywgJ3snXSk7XG4gIGxvY2FsZS5iaW5kTWFjcm8oJ3NoaWZ0ICsgXScsIFsnY2xvc2VjdXJseWJyYWNlJywgJ2Nsb3NlY3VybHlicmFja2V0JywgJ30nXSk7XG4gIGxvY2FsZS5iaW5kTWFjcm8oJ3NoaWZ0ICsgXFxcXCcsIFsndmVydGljYWxiYXInLCAnfCddKTtcbiAgbG9jYWxlLmJpbmRNYWNybygnc2hpZnQgKyA7JywgWydjb2xvbicsICc6J10pO1xuICBsb2NhbGUuYmluZE1hY3JvKCdzaGlmdCArIFxcJycsIFsncXVvdGF0aW9ubWFyaycsICdcXCcnXSk7XG4gIGxvY2FsZS5iaW5kTWFjcm8oJ3NoaWZ0ICsgISwnLCBbJ29wZW5hbmdsZWJyYWNrZXQnLCAnPCddKTtcbiAgbG9jYWxlLmJpbmRNYWNybygnc2hpZnQgKyAuJywgWydjbG9zZWFuZ2xlYnJhY2tldCcsICc+J10pO1xuICBsb2NhbGUuYmluZE1hY3JvKCdzaGlmdCArIC8nLCBbJ3F1ZXN0aW9ubWFyaycsICc/J10pO1xuXG4gIGlmIChwbGF0Zm9ybS5tYXRjaCgnTWFjJykpIHtcbiAgICBsb2NhbGUuYmluZE1hY3JvKCdjb21tYW5kJywgWydtb2QnLCAnbW9kaWZpZXInXSk7XG4gIH0gZWxzZSB7XG4gICAgbG9jYWxlLmJpbmRNYWNybygnY3RybCcsIFsnbW9kJywgJ21vZGlmaWVyJ10pO1xuICB9XG5cbiAgLy9hLXogYW5kIEEtWlxuICBmb3IgKGxldCBrZXlDb2RlID0gNjU7IGtleUNvZGUgPD0gOTA7IGtleUNvZGUgKz0gMSkge1xuICAgIHZhciBrZXlOYW1lID0gU3RyaW5nLmZyb21DaGFyQ29kZShrZXlDb2RlICsgMzIpO1xuICAgIHZhciBjYXBpdGFsS2V5TmFtZSA9IFN0cmluZy5mcm9tQ2hhckNvZGUoa2V5Q29kZSk7XG4gIFx0bG9jYWxlLmJpbmRLZXlDb2RlKGtleUNvZGUsIGtleU5hbWUpO1xuICBcdGxvY2FsZS5iaW5kTWFjcm8oJ3NoaWZ0ICsgJyArIGtleU5hbWUsIGNhcGl0YWxLZXlOYW1lKTtcbiAgXHRsb2NhbGUuYmluZE1hY3JvKCdjYXBzbG9jayArICcgKyBrZXlOYW1lLCBjYXBpdGFsS2V5TmFtZSk7XG4gIH1cblxuICAvLyBicm93c2VyIGNhdmVhdHNcbiAgY29uc3Qgc2VtaWNvbG9uS2V5Q29kZSA9IHVzZXJBZ2VudC5tYXRjaCgnRmlyZWZveCcpID8gNTkgIDogMTg2O1xuICBjb25zdCBkYXNoS2V5Q29kZSAgICAgID0gdXNlckFnZW50Lm1hdGNoKCdGaXJlZm94JykgPyAxNzMgOiAxODk7XG4gIGNvbnN0IGVxdWFsS2V5Q29kZSAgICAgPSB1c2VyQWdlbnQubWF0Y2goJ0ZpcmVmb3gnKSA/IDYxICA6IDE4NztcbiAgbGV0IGxlZnRDb21tYW5kS2V5Q29kZTtcbiAgbGV0IHJpZ2h0Q29tbWFuZEtleUNvZGU7XG4gIGlmIChwbGF0Zm9ybS5tYXRjaCgnTWFjJykgJiYgKHVzZXJBZ2VudC5tYXRjaCgnU2FmYXJpJykgfHwgdXNlckFnZW50Lm1hdGNoKCdDaHJvbWUnKSkpIHtcbiAgICBsZWZ0Q29tbWFuZEtleUNvZGUgID0gOTE7XG4gICAgcmlnaHRDb21tYW5kS2V5Q29kZSA9IDkzO1xuICB9IGVsc2UgaWYocGxhdGZvcm0ubWF0Y2goJ01hYycpICYmIHVzZXJBZ2VudC5tYXRjaCgnT3BlcmEnKSkge1xuICAgIGxlZnRDb21tYW5kS2V5Q29kZSAgPSAxNztcbiAgICByaWdodENvbW1hbmRLZXlDb2RlID0gMTc7XG4gIH0gZWxzZSBpZihwbGF0Zm9ybS5tYXRjaCgnTWFjJykgJiYgdXNlckFnZW50Lm1hdGNoKCdGaXJlZm94JykpIHtcbiAgICBsZWZ0Q29tbWFuZEtleUNvZGUgID0gMjI0O1xuICAgIHJpZ2h0Q29tbWFuZEtleUNvZGUgPSAyMjQ7XG4gIH1cbiAgbG9jYWxlLmJpbmRLZXlDb2RlKHNlbWljb2xvbktleUNvZGUsICAgIFsnc2VtaWNvbG9uJywgJzsnXSk7XG4gIGxvY2FsZS5iaW5kS2V5Q29kZShkYXNoS2V5Q29kZSwgICAgICAgICBbJ2Rhc2gnLCAnLSddKTtcbiAgbG9jYWxlLmJpbmRLZXlDb2RlKGVxdWFsS2V5Q29kZSwgICAgICAgIFsnZXF1YWwnLCAnZXF1YWxzaWduJywgJz0nXSk7XG4gIGxvY2FsZS5iaW5kS2V5Q29kZShsZWZ0Q29tbWFuZEtleUNvZGUsICBbJ2NvbW1hbmQnLCAnd2luZG93cycsICd3aW4nLCAnc3VwZXInLCAnbGVmdGNvbW1hbmQnLCAnbGVmdHdpbmRvd3MnLCAnbGVmdHdpbicsICdsZWZ0c3VwZXInXSk7XG4gIGxvY2FsZS5iaW5kS2V5Q29kZShyaWdodENvbW1hbmRLZXlDb2RlLCBbJ2NvbW1hbmQnLCAnd2luZG93cycsICd3aW4nLCAnc3VwZXInLCAncmlnaHRjb21tYW5kJywgJ3JpZ2h0d2luZG93cycsICdyaWdodHdpbicsICdyaWdodHN1cGVyJ10pO1xuXG4gIC8vIGtpbGwga2V5c1xuICBsb2NhbGUuc2V0S2lsbEtleSgnY29tbWFuZCcpO1xufTtcbiIsImltcG9ydCB7IEtleWJvYXJkIH0gZnJvbSAnLi9saWIva2V5Ym9hcmQnO1xuaW1wb3J0IHsgTG9jYWxlIH0gZnJvbSAnLi9saWIvbG9jYWxlJztcbmltcG9ydCB7IEtleUNvbWJvIH0gZnJvbSAnLi9saWIva2V5LWNvbWJvJztcbmltcG9ydCB7IHVzIH0gZnJvbSAnLi9sb2NhbGVzL3VzJztcblxuY29uc3Qga2V5Ym9hcmQgPSBuZXcgS2V5Ym9hcmQoKTtcblxua2V5Ym9hcmQuc2V0TG9jYWxlKCd1cycsIHVzKTtcblxua2V5Ym9hcmQuS2V5Ym9hcmQgPSBLZXlib2FyZDtcbmtleWJvYXJkLkxvY2FsZSA9IExvY2FsZTtcbmtleWJvYXJkLktleUNvbWJvID0gS2V5Q29tYm87XG5cbmV4cG9ydCBkZWZhdWx0IGtleWJvYXJkO1xuIl0sIm5hbWVzIjpbIktleUNvbWJvIiwia2V5Q29tYm9TdHIiLCJzb3VyY2VTdHIiLCJzdWJDb21ib3MiLCJwYXJzZUNvbWJvU3RyIiwia2V5TmFtZXMiLCJyZWR1Y2UiLCJtZW1vIiwibmV4dFN1YkNvbWJvIiwiY29uY2F0IiwicHJlc3NlZEtleU5hbWVzIiwic3RhcnRpbmdLZXlOYW1lSW5kZXgiLCJpIiwibGVuZ3RoIiwiX2NoZWNrU3ViQ29tYm8iLCJvdGhlcktleUNvbWJvIiwic3ViQ29tYm8iLCJvdGhlclN1YkNvbWJvIiwic2xpY2UiLCJqIiwia2V5TmFtZSIsImluZGV4IiwiaW5kZXhPZiIsInNwbGljZSIsImVuZEluZGV4IiwiZXNjYXBlZEtleU5hbWUiLCJjb21ib0RlbGltaW5hdG9yIiwia2V5RGVsaW1pbmF0b3IiLCJzdWJDb21ib1N0cnMiLCJfc3BsaXRTdHIiLCJjb21ibyIsInB1c2giLCJzdHIiLCJkZWxpbWluYXRvciIsInMiLCJkIiwiYyIsImNhIiwiY2kiLCJ0cmltIiwiTG9jYWxlIiwibmFtZSIsImxvY2FsZU5hbWUiLCJhY3RpdmVUYXJnZXRLZXlzIiwicHJlc3NlZEtleXMiLCJfYXBwbGllZE1hY3JvcyIsIl9rZXlNYXAiLCJfa2lsbEtleUNvZGVzIiwiX21hY3JvcyIsImtleUNvZGUiLCJoYW5kbGVyIiwibWFjcm8iLCJrZXlDb21ibyIsImtleUNvZGVzIiwiZ2V0S2V5Q29kZXMiLCJzZXRLaWxsS2V5IiwicHJlc3NLZXkiLCJnZXRLZXlOYW1lcyIsIl9hcHBseU1hY3JvcyIsInJlbGVhc2VLZXkiLCJraWxsS2V5Q29kZUluZGV4IiwiX2NsZWFyTWFjcm9zIiwibWFjcm9zIiwiY2hlY2siLCJLZXlib2FyZCIsInRhcmdldFdpbmRvdyIsInRhcmdldEVsZW1lbnQiLCJ0YXJnZXRQbGF0Zm9ybSIsInRhcmdldFVzZXJBZ2VudCIsIl9sb2NhbGUiLCJfY3VycmVudENvbnRleHQiLCJfY29udGV4dHMiLCJfbGlzdGVuZXJzIiwiX2FwcGxpZWRMaXN0ZW5lcnMiLCJfbG9jYWxlcyIsIl90YXJnZXRFbGVtZW50IiwiX3RhcmdldFdpbmRvdyIsIl90YXJnZXRQbGF0Zm9ybSIsIl90YXJnZXRVc2VyQWdlbnQiLCJfaXNNb2Rlcm5Ccm93c2VyIiwiX3RhcmdldEtleURvd25CaW5kaW5nIiwiX3RhcmdldEtleVVwQmluZGluZyIsIl90YXJnZXRSZXNldEJpbmRpbmciLCJfcGF1c2VkIiwiZ2xvYmFsIiwibGlzdGVuZXJzIiwic2V0Q29udGV4dCIsImxvY2FsZUJ1aWxkZXIiLCJsb2NhbGUiLCJfbG9jYWxlTmFtZSIsImxvY2FsTmFtZSIsInByZXNzSGFuZGxlciIsInJlbGVhc2VIYW5kbGVyIiwicHJldmVudFJlcGVhdEJ5RGVmYXVsdCIsImJpbmQiLCJwcmV2ZW50UmVwZWF0IiwiZXhlY3V0aW5nSGFuZGxlciIsInVuYmluZCIsImxpc3RlbmVyIiwiY29tYm9NYXRjaGVzIiwiaXNFcXVhbCIsInByZXNzSGFuZGxlck1hdGNoZXMiLCJyZWxlYXNlSGFuZGxlck1hdGNoZXMiLCJjb250ZXh0TmFtZSIsInJlbGVhc2VBbGxLZXlzIiwiZ2xvYmFsQ29udGV4dCIsImNvbnRleHQiLCJzdG9wIiwid2F0Y2giLCJjYWxsYmFjayIsInByZXZpb3VzQ29udGV4dE5hbWUiLCJnZXRDb250ZXh0Iiwid2luIiwiZ2xvYmFsVGhpcyIsIndpbmRvdyIsImFkZEV2ZW50TGlzdGVuZXIiLCJhdHRhY2hFdmVudCIsIkVycm9yIiwibm9kZVR5cGUiLCJ1c2VyQWdlbnQiLCJuYXZpZ2F0b3IiLCJwbGF0Zm9ybSIsImRvY3VtZW50IiwiZXZlbnQiLCJfaGFuZGxlQ29tbWFuZEJ1ZyIsIl9iaW5kRXZlbnQiLCJjdXJyZW50Q29udGV4dCIsIl91bmJpbmRFdmVudCIsIl9hcHBseUJpbmRpbmdzIiwiX2NsZWFyQmluZGluZ3MiLCJldmVudE5hbWUiLCJyZW1vdmVFdmVudExpc3RlbmVyIiwiZGV0YWNoRXZlbnQiLCJsaXN0ZW5lckdyb3VwcyIsImxpc3RlbmVyR3JvdXBNYXAiLCJzb3J0IiwiYSIsImIiLCJmb3JFYWNoIiwibCIsIm1hcEluZGV4IiwiX2dldEdyb3VwZWRMaXN0ZW5lcnMiLCJzb21lIiwiayIsImluY2x1ZGVzIiwiY2FsbCIsIm1vZGlmaWVyS2V5cyIsIm1hdGNoIiwidXMiLCJiaW5kS2V5Q29kZSIsImJpbmRNYWNybyIsIlN0cmluZyIsImZyb21DaGFyQ29kZSIsImNhcGl0YWxLZXlOYW1lIiwic2VtaWNvbG9uS2V5Q29kZSIsImRhc2hLZXlDb2RlIiwiZXF1YWxLZXlDb2RlIiwibGVmdENvbW1hbmRLZXlDb2RlIiwicmlnaHRDb21tYW5kS2V5Q29kZSIsImtleWJvYXJkIiwic2V0TG9jYWxlIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztNQUNhQSxRQUFiO0VBQ0Usb0JBQVlDLFdBQVosRUFBeUI7RUFBQTs7RUFDdkIsU0FBS0MsU0FBTCxHQUFpQkQsV0FBakI7RUFDQSxTQUFLRSxTQUFMLEdBQWlCSCxRQUFRLENBQUNJLGFBQVQsQ0FBdUJILFdBQXZCLENBQWpCO0VBQ0EsU0FBS0ksUUFBTCxHQUFpQixLQUFLRixTQUFMLENBQWVHLE1BQWYsQ0FBc0IsVUFBQ0MsSUFBRCxFQUFPQyxZQUFQO0VBQUEsYUFDckNELElBQUksQ0FBQ0UsTUFBTCxDQUFZRCxZQUFaLENBRHFDO0VBQUEsS0FBdEIsRUFDWSxFQURaLENBQWpCO0VBRUQ7O0VBTkg7RUFBQTtFQUFBLDBCQVFRRSxlQVJSLEVBUXlCO0VB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
1104 /***/ "./node_modules/lodash/lodash.js":
1105 /*!***************************************!*\
1106 !*** ./node_modules/lodash/lodash.js ***!
1107 \***************************************/
1108 /***/ (function(module, exports, __webpack_require__) {
1110 /* module decorator */ module = __webpack_require__.nmd(module);
1111 var __WEBPACK_AMD_DEFINE_RESULT__;/**
1113 * Lodash <https://lodash.com/>
1114 * Copyright OpenJS Foundation and other contributors <https://openjsf.org/>
1115 * Released under MIT license <https://lodash.com/license>
1116 * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>
1117 * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
1121 /** Used as a safe reference for `undefined` in pre-ES5 environments. */
1124 /** Used as the semantic version number. */
1125 var VERSION = '4.17.21';
1127 /** Used as the size to enable large array optimizations. */
1128 var LARGE_ARRAY_SIZE = 200;
1130 /** Error message constants. */
1131 var CORE_ERROR_TEXT = 'Unsupported core-js use. Try https://npms.io/search?q=ponyfill.',
1132 FUNC_ERROR_TEXT = 'Expected a function',
1133 INVALID_TEMPL_VAR_ERROR_TEXT = 'Invalid `variable` option passed into `_.template`';
1135 /** Used to stand-in for `undefined` hash values. */
1136 var HASH_UNDEFINED = '__lodash_hash_undefined__';
1138 /** Used as the maximum memoize cache size. */
1139 var MAX_MEMOIZE_SIZE = 500;
1141 /** Used as the internal argument placeholder. */
1142 var PLACEHOLDER = '__lodash_placeholder__';
1144 /** Used to compose bitmasks for cloning. */
1145 var CLONE_DEEP_FLAG = 1,
1146 CLONE_FLAT_FLAG = 2,
1147 CLONE_SYMBOLS_FLAG = 4;
1149 /** Used to compose bitmasks for value comparisons. */
1150 var COMPARE_PARTIAL_FLAG = 1,
1151 COMPARE_UNORDERED_FLAG = 2;
1153 /** Used to compose bitmasks for function metadata. */
1154 var WRAP_BIND_FLAG = 1,
1155 WRAP_BIND_KEY_FLAG = 2,
1156 WRAP_CURRY_BOUND_FLAG = 4,
1157 WRAP_CURRY_FLAG = 8,
1158 WRAP_CURRY_RIGHT_FLAG = 16,
1159 WRAP_PARTIAL_FLAG = 32,
1160 WRAP_PARTIAL_RIGHT_FLAG = 64,
1161 WRAP_ARY_FLAG = 128,
1162 WRAP_REARG_FLAG = 256,
1163 WRAP_FLIP_FLAG = 512;
1165 /** Used as default options for `_.truncate`. */
1166 var DEFAULT_TRUNC_LENGTH = 30,
1167 DEFAULT_TRUNC_OMISSION = '...';
1169 /** Used to detect hot functions by number of calls within a span of milliseconds. */
1170 var HOT_COUNT = 800,
1173 /** Used to indicate the type of lazy iteratees. */
1174 var LAZY_FILTER_FLAG = 1,
1176 LAZY_WHILE_FLAG = 3;
1178 /** Used as references for various `Number` constants. */
1179 var INFINITY = 1 / 0,
1180 MAX_SAFE_INTEGER = 9007199254740991,
1181 MAX_INTEGER = 1.7976931348623157e+308,
1184 /** Used as references for the maximum length and index of an array. */
1185 var MAX_ARRAY_LENGTH = 4294967295,
1186 MAX_ARRAY_INDEX = MAX_ARRAY_LENGTH - 1,
1187 HALF_MAX_ARRAY_LENGTH = MAX_ARRAY_LENGTH >>> 1;
1189 /** Used to associate wrap methods with their bit flags. */
1191 ['ary', WRAP_ARY_FLAG],
1192 ['bind', WRAP_BIND_FLAG],
1193 ['bindKey', WRAP_BIND_KEY_FLAG],
1194 ['curry', WRAP_CURRY_FLAG],
1195 ['curryRight', WRAP_CURRY_RIGHT_FLAG],
1196 ['flip', WRAP_FLIP_FLAG],
1197 ['partial', WRAP_PARTIAL_FLAG],
1198 ['partialRight', WRAP_PARTIAL_RIGHT_FLAG],
1199 ['rearg', WRAP_REARG_FLAG]
1202 /** `Object#toString` result references. */
1203 var argsTag = '[object Arguments]',
1204 arrayTag = '[object Array]',
1205 asyncTag = '[object AsyncFunction]',
1206 boolTag = '[object Boolean]',
1207 dateTag = '[object Date]',
1208 domExcTag = '[object DOMException]',
1209 errorTag = '[object Error]',
1210 funcTag = '[object Function]',
1211 genTag = '[object GeneratorFunction]',
1212 mapTag = '[object Map]',
1213 numberTag = '[object Number]',
1214 nullTag = '[object Null]',
1215 objectTag = '[object Object]',
1216 promiseTag = '[object Promise]',
1217 proxyTag = '[object Proxy]',
1218 regexpTag = '[object RegExp]',
1219 setTag = '[object Set]',
1220 stringTag = '[object String]',
1221 symbolTag = '[object Symbol]',
1222 undefinedTag = '[object Undefined]',
1223 weakMapTag = '[object WeakMap]',
1224 weakSetTag = '[object WeakSet]';
1226 var arrayBufferTag = '[object ArrayBuffer]',
1227 dataViewTag = '[object DataView]',
1228 float32Tag = '[object Float32Array]',
1229 float64Tag = '[object Float64Array]',
1230 int8Tag = '[object Int8Array]',
1231 int16Tag = '[object Int16Array]',
1232 int32Tag = '[object Int32Array]',
1233 uint8Tag = '[object Uint8Array]',
1234 uint8ClampedTag = '[object Uint8ClampedArray]',
1235 uint16Tag = '[object Uint16Array]',
1236 uint32Tag = '[object Uint32Array]';
1238 /** Used to match empty string literals in compiled template source. */
1239 var reEmptyStringLeading = /\b__p \+= '';/g,
1240 reEmptyStringMiddle = /\b(__p \+=) '' \+/g,
1241 reEmptyStringTrailing = /(__e\(.*?\)|\b__t\)) \+\n'';/g;
1243 /** Used to match HTML entities and HTML characters. */
1244 var reEscapedHtml = /&(?:amp|lt|gt|quot|#39);/g,
1245 reUnescapedHtml = /[&<>"']/g,
1246 reHasEscapedHtml = RegExp(reEscapedHtml.source),
1247 reHasUnescapedHtml = RegExp(reUnescapedHtml.source);
1249 /** Used to match template delimiters. */
1250 var reEscape = /<%-([\s\S]+?)%>/g,
1251 reEvaluate = /<%([\s\S]+?)%>/g,
1252 reInterpolate = /<%=([\s\S]+?)%>/g;
1254 /** Used to match property names within property paths. */
1255 var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,
1256 reIsPlainProp = /^\w*$/,
1257 rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g;
1260 * Used to match `RegExp`
1261 * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns).
1263 var reRegExpChar = /[\\^$.*+?()[\]{}|]/g,
1264 reHasRegExpChar = RegExp(reRegExpChar.source);
1266 /** Used to match leading whitespace. */
1267 var reTrimStart = /^\s+/;
1269 /** Used to match a single whitespace character. */
1270 var reWhitespace = /\s/;
1272 /** Used to match wrap detail comments. */
1273 var reWrapComment = /\{(?:\n\/\* \[wrapped with .+\] \*\/)?\n?/,
1274 reWrapDetails = /\{\n\/\* \[wrapped with (.+)\] \*/,
1275 reSplitDetails = /,? & /;
1277 /** Used to match words composed of alphanumeric characters. */
1278 var reAsciiWord = /[^\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\x7f]+/g;
1281 * Used to validate the `validate` option in `_.template` variable.
1283 * Forbids characters which could potentially change the meaning of the function argument definition:
1284 * - "()," (modification of function parameters)
1285 * - "=" (default value)
1286 * - "[]{}" (destructuring of function parameters)
1287 * - "/" (beginning of a comment)
1290 var reForbiddenIdentifierChars = /[()=,{}\[\]\/\s]/;
1292 /** Used to match backslashes in property paths. */
1293 var reEscapeChar = /\\(\\)?/g;
1297 * [ES template delimiters](http://ecma-international.org/ecma-262/7.0/#sec-template-literal-lexical-components).
1299 var reEsTemplate = /\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g;
1301 /** Used to match `RegExp` flags from their coerced string values. */
1302 var reFlags = /\w*$/;
1304 /** Used to detect bad signed hexadecimal string values. */
1305 var reIsBadHex = /^[-+]0x[0-9a-f]+$/i;
1307 /** Used to detect binary string values. */
1308 var reIsBinary = /^0b[01]+$/i;
1310 /** Used to detect host constructors (Safari). */
1311 var reIsHostCtor = /^\[object .+?Constructor\]$/;
1313 /** Used to detect octal string values. */
1314 var reIsOctal = /^0o[0-7]+$/i;
1316 /** Used to detect unsigned integer values. */
1317 var reIsUint = /^(?:0|[1-9]\d*)$/;
1319 /** Used to match Latin Unicode letters (excluding mathematical operators). */
1320 var reLatin = /[\xc0-\xd6\xd8-\xf6\xf8-\xff\u0100-\u017f]/g;
1322 /** Used to ensure capturing order of template delimiters. */
1323 var reNoMatch = /($^)/;
1325 /** Used to match unescaped characters in compiled string literals. */
1326 var reUnescapedString = /['\n\r\u2028\u2029\\]/g;
1328 /** Used to compose unicode character classes. */
1329 var rsAstralRange = '\\ud800-\\udfff',
1330 rsComboMarksRange = '\\u0300-\\u036f',
1331 reComboHalfMarksRange = '\\ufe20-\\ufe2f',
1332 rsComboSymbolsRange = '\\u20d0-\\u20ff',
1333 rsComboRange = rsComboMarksRange + reComboHalfMarksRange + rsComboSymbolsRange,
1334 rsDingbatRange = '\\u2700-\\u27bf',
1335 rsLowerRange = 'a-z\\xdf-\\xf6\\xf8-\\xff',
1336 rsMathOpRange = '\\xac\\xb1\\xd7\\xf7',
1337 rsNonCharRange = '\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf',
1338 rsPunctuationRange = '\\u2000-\\u206f',
1339 rsSpaceRange = ' \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000',
1340 rsUpperRange = 'A-Z\\xc0-\\xd6\\xd8-\\xde',
1341 rsVarRange = '\\ufe0e\\ufe0f',
1342 rsBreakRange = rsMathOpRange + rsNonCharRange + rsPunctuationRange + rsSpaceRange;
1344 /** Used to compose unicode capture groups. */
1345 var rsApos = "['\u2019]",
1346 rsAstral = '[' + rsAstralRange + ']',
1347 rsBreak = '[' + rsBreakRange + ']',
1348 rsCombo = '[' + rsComboRange + ']',
1350 rsDingbat = '[' + rsDingbatRange + ']',
1351 rsLower = '[' + rsLowerRange + ']',
1352 rsMisc = '[^' + rsAstralRange + rsBreakRange + rsDigits + rsDingbatRange + rsLowerRange + rsUpperRange + ']',
1353 rsFitz = '\\ud83c[\\udffb-\\udfff]',
1354 rsModifier = '(?:' + rsCombo + '|' + rsFitz + ')',
1355 rsNonAstral = '[^' + rsAstralRange + ']',
1356 rsRegional = '(?:\\ud83c[\\udde6-\\uddff]){2}',
1357 rsSurrPair = '[\\ud800-\\udbff][\\udc00-\\udfff]',
1358 rsUpper = '[' + rsUpperRange + ']',
1361 /** Used to compose unicode regexes. */
1362 var rsMiscLower = '(?:' + rsLower + '|' + rsMisc + ')',
1363 rsMiscUpper = '(?:' + rsUpper + '|' + rsMisc + ')',
1364 rsOptContrLower = '(?:' + rsApos + '(?:d|ll|m|re|s|t|ve))?',
1365 rsOptContrUpper = '(?:' + rsApos + '(?:D|LL|M|RE|S|T|VE))?',
1366 reOptMod = rsModifier + '?',
1367 rsOptVar = '[' + rsVarRange + ']?',
1368 rsOptJoin = '(?:' + rsZWJ + '(?:' + [rsNonAstral, rsRegional, rsSurrPair].join('|') + ')' + rsOptVar + reOptMod + ')*',
1369 rsOrdLower = '\\d*(?:1st|2nd|3rd|(?![123])\\dth)(?=\\b|[A-Z_])',
1370 rsOrdUpper = '\\d*(?:1ST|2ND|3RD|(?![123])\\dTH)(?=\\b|[a-z_])',
1371 rsSeq = rsOptVar + reOptMod + rsOptJoin,
1372 rsEmoji = '(?:' + [rsDingbat, rsRegional, rsSurrPair].join('|') + ')' + rsSeq,
1373 rsSymbol = '(?:' + [rsNonAstral + rsCombo + '?', rsCombo, rsRegional, rsSurrPair, rsAstral].join('|') + ')';
1375 /** Used to match apostrophes. */
1376 var reApos = RegExp(rsApos, 'g');
1379 * Used to match [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks) and
1380 * [combining diacritical marks for symbols](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks_for_Symbols).
1382 var reComboMark = RegExp(rsCombo, 'g');
1384 /** Used to match [string symbols](https://mathiasbynens.be/notes/javascript-unicode). */
1385 var reUnicode = RegExp(rsFitz + '(?=' + rsFitz + ')|' + rsSymbol + rsSeq, 'g');
1387 /** Used to match complex or compound words. */
1388 var reUnicodeWord = RegExp([
1389 rsUpper + '?' + rsLower + '+' + rsOptContrLower + '(?=' + [rsBreak, rsUpper, '$'].join('|') + ')',
1390 rsMiscUpper + '+' + rsOptContrUpper + '(?=' + [rsBreak, rsUpper + rsMiscLower, '$'].join('|') + ')',
1391 rsUpper + '?' + rsMiscLower + '+' + rsOptContrLower,
1392 rsUpper + '+' + rsOptContrUpper,
1399 /** Used to detect strings with [zero-width joiners or code points from the astral planes](http://eev.ee/blog/2015/09/12/dark-corners-of-unicode/). */
1400 var reHasUnicode = RegExp('[' + rsZWJ + rsAstralRange + rsComboRange + rsVarRange + ']');
1402 /** Used to detect strings that need a more robust regexp to match words. */
1403 var reHasUnicodeWord = /[a-z][A-Z]|[A-Z]{2}[a-z]|[0-9][a-zA-Z]|[a-zA-Z][0-9]|[^a-zA-Z0-9 ]/;
1405 /** Used to assign default `context` object properties. */
1406 var contextProps = [
1407 'Array', 'Buffer', 'DataView', 'Date', 'Error', 'Float32Array', 'Float64Array',
1408 'Function', 'Int8Array', 'Int16Array', 'Int32Array', 'Map', 'Math', 'Object',
1409 'Promise', 'RegExp', 'Set', 'String', 'Symbol', 'TypeError', 'Uint8Array',
1410 'Uint8ClampedArray', 'Uint16Array', 'Uint32Array', 'WeakMap',
1411 '_', 'clearTimeout', 'isFinite', 'parseInt', 'setTimeout'
1414 /** Used to make template sourceURLs easier to identify. */
1415 var templateCounter = -1;
1417 /** Used to identify `toStringTag` values of typed arrays. */
1418 var typedArrayTags = {};
1419 typedArrayTags[float32Tag] = typedArrayTags[float64Tag] =
1420 typedArrayTags[int8Tag] = typedArrayTags[int16Tag] =
1421 typedArrayTags[int32Tag] = typedArrayTags[uint8Tag] =
1422 typedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] =
1423 typedArrayTags[uint32Tag] = true;
1424 typedArrayTags[argsTag] = typedArrayTags[arrayTag] =
1425 typedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] =
1426 typedArrayTags[dataViewTag] = typedArrayTags[dateTag] =
1427 typedArrayTags[errorTag] = typedArrayTags[funcTag] =
1428 typedArrayTags[mapTag] = typedArrayTags[numberTag] =
1429 typedArrayTags[objectTag] = typedArrayTags[regexpTag] =
1430 typedArrayTags[setTag] = typedArrayTags[stringTag] =
1431 typedArrayTags[weakMapTag] = false;
1433 /** Used to identify `toStringTag` values supported by `_.clone`. */
1434 var cloneableTags = {};
1435 cloneableTags[argsTag] = cloneableTags[arrayTag] =
1436 cloneableTags[arrayBufferTag] = cloneableTags[dataViewTag] =
1437 cloneableTags[boolTag] = cloneableTags[dateTag] =
1438 cloneableTags[float32Tag] = cloneableTags[float64Tag] =
1439 cloneableTags[int8Tag] = cloneableTags[int16Tag] =
1440 cloneableTags[int32Tag] = cloneableTags[mapTag] =
1441 cloneableTags[numberTag] = cloneableTags[objectTag] =
1442 cloneableTags[regexpTag] = cloneableTags[setTag] =
1443 cloneableTags[stringTag] = cloneableTags[symbolTag] =
1444 cloneableTags[uint8Tag] = cloneableTags[uint8ClampedTag] =
1445 cloneableTags[uint16Tag] = cloneableTags[uint32Tag] = true;
1446 cloneableTags[errorTag] = cloneableTags[funcTag] =
1447 cloneableTags[weakMapTag] = false;
1449 /** Used to map Latin Unicode letters to basic Latin letters. */
1450 var deburredLetters = {
1451 // Latin-1 Supplement block.
1452 '\xc0': 'A', '\xc1': 'A', '\xc2': 'A', '\xc3': 'A', '\xc4': 'A', '\xc5': 'A',
1453 '\xe0': 'a', '\xe1': 'a', '\xe2': 'a', '\xe3': 'a', '\xe4': 'a', '\xe5': 'a',
1454 '\xc7': 'C', '\xe7': 'c',
1455 '\xd0': 'D', '\xf0': 'd',
1456 '\xc8': 'E', '\xc9': 'E', '\xca': 'E', '\xcb': 'E',
1457 '\xe8': 'e', '\xe9': 'e', '\xea': 'e', '\xeb': 'e',
1458 '\xcc': 'I', '\xcd': 'I', '\xce': 'I', '\xcf': 'I',
1459 '\xec': 'i', '\xed': 'i', '\xee': 'i', '\xef': 'i',
1460 '\xd1': 'N', '\xf1': 'n',
1461 '\xd2': 'O', '\xd3': 'O', '\xd4': 'O', '\xd5': 'O', '\xd6': 'O', '\xd8': 'O',
1462 '\xf2': 'o', '\xf3': 'o', '\xf4': 'o', '\xf5': 'o', '\xf6': 'o', '\xf8': 'o',
1463 '\xd9': 'U', '\xda': 'U', '\xdb': 'U', '\xdc': 'U',
1464 '\xf9': 'u', '\xfa': 'u', '\xfb': 'u', '\xfc': 'u',
1465 '\xdd': 'Y', '\xfd': 'y', '\xff': 'y',
1466 '\xc6': 'Ae', '\xe6': 'ae',
1467 '\xde': 'Th', '\xfe': 'th',
1469 // Latin Extended-A block.
1470 '\u0100': 'A', '\u0102': 'A', '\u0104': 'A',
1471 '\u0101': 'a', '\u0103': 'a', '\u0105': 'a',
1472 '\u0106': 'C', '\u0108': 'C', '\u010a': 'C', '\u010c': 'C',
1473 '\u0107': 'c', '\u0109': 'c', '\u010b': 'c', '\u010d': 'c',
1474 '\u010e': 'D', '\u0110': 'D', '\u010f': 'd', '\u0111': 'd',
1475 '\u0112': 'E', '\u0114': 'E', '\u0116': 'E', '\u0118': 'E', '\u011a': 'E',
1476 '\u0113': 'e', '\u0115': 'e', '\u0117': 'e', '\u0119': 'e', '\u011b': 'e',
1477 '\u011c': 'G', '\u011e': 'G', '\u0120': 'G', '\u0122': 'G',
1478 '\u011d': 'g', '\u011f': 'g', '\u0121': 'g', '\u0123': 'g',
1479 '\u0124': 'H', '\u0126': 'H', '\u0125': 'h', '\u0127': 'h',
1480 '\u0128': 'I', '\u012a': 'I', '\u012c': 'I', '\u012e': 'I', '\u0130': 'I',
1481 '\u0129': 'i', '\u012b': 'i', '\u012d': 'i', '\u012f': 'i', '\u0131': 'i',
1482 '\u0134': 'J', '\u0135': 'j',
1483 '\u0136': 'K', '\u0137': 'k', '\u0138': 'k',
1484 '\u0139': 'L', '\u013b': 'L', '\u013d': 'L', '\u013f': 'L', '\u0141': 'L',
1485 '\u013a': 'l', '\u013c': 'l', '\u013e': 'l', '\u0140': 'l', '\u0142': 'l',
1486 '\u0143': 'N', '\u0145': 'N', '\u0147': 'N', '\u014a': 'N',
1487 '\u0144': 'n', '\u0146': 'n', '\u0148': 'n', '\u014b': 'n',
1488 '\u014c': 'O', '\u014e': 'O', '\u0150': 'O',
1489 '\u014d': 'o', '\u014f': 'o', '\u0151': 'o',
1490 '\u0154': 'R', '\u0156': 'R', '\u0158': 'R',
1491 '\u0155': 'r', '\u0157': 'r', '\u0159': 'r',
1492 '\u015a': 'S', '\u015c': 'S', '\u015e': 'S', '\u0160': 'S',
1493 '\u015b': 's', '\u015d': 's', '\u015f': 's', '\u0161': 's',
1494 '\u0162': 'T', '\u0164': 'T', '\u0166': 'T',
1495 '\u0163': 't', '\u0165': 't', '\u0167': 't',
1496 '\u0168': 'U', '\u016a': 'U', '\u016c': 'U', '\u016e': 'U', '\u0170': 'U', '\u0172': 'U',
1497 '\u0169': 'u', '\u016b': 'u', '\u016d': 'u', '\u016f': 'u', '\u0171': 'u', '\u0173': 'u',
1498 '\u0174': 'W', '\u0175': 'w',
1499 '\u0176': 'Y', '\u0177': 'y', '\u0178': 'Y',
1500 '\u0179': 'Z', '\u017b': 'Z', '\u017d': 'Z',
1501 '\u017a': 'z', '\u017c': 'z', '\u017e': 'z',
1502 '\u0132': 'IJ', '\u0133': 'ij',
1503 '\u0152': 'Oe', '\u0153': 'oe',
1504 '\u0149': "'n", '\u017f': 's'
1507 /** Used to map characters to HTML entities. */
1516 /** Used to map HTML entities to characters. */
1517 var htmlUnescapes = {
1525 /** Used to escape characters for inclusion in compiled string literals. */
1526 var stringEscapes = {
1535 /** Built-in method references without a dependency on `root`. */
1536 var freeParseFloat = parseFloat,
1537 freeParseInt = parseInt;
1539 /** Detect free variable `global` from Node.js. */
1540 var freeGlobal = typeof __webpack_require__.g == 'object' && __webpack_require__.g && __webpack_require__.g.Object === Object && __webpack_require__.g;
1542 /** Detect free variable `self`. */
1543 var freeSelf = typeof self == 'object' && self && self.Object === Object && self;
1545 /** Used as a reference to the global object. */
1546 var root = freeGlobal || freeSelf || Function('return this')();
1548 /** Detect free variable `exports`. */
1549 var freeExports = true && exports && !exports.nodeType && exports;
1551 /** Detect free variable `module`. */
1552 var freeModule = freeExports && "object" == 'object' && module && !module.nodeType && module;
1554 /** Detect the popular CommonJS extension `module.exports`. */
1555 var moduleExports = freeModule && freeModule.exports === freeExports;
1557 /** Detect free variable `process` from Node.js. */
1558 var freeProcess = moduleExports && freeGlobal.process;
1560 /** Used to access faster Node.js helpers. */
1561 var nodeUtil = (function() {
1563 // Use `util.types` for Node.js 10+.
1564 var types = freeModule && freeModule.require && freeModule.require('util').types;
1570 // Legacy `process.binding('util')` for Node.js < 10.
1571 return freeProcess && freeProcess.binding && freeProcess.binding('util');
1575 /* Node.js helper references. */
1576 var nodeIsArrayBuffer = nodeUtil && nodeUtil.isArrayBuffer,
1577 nodeIsDate = nodeUtil && nodeUtil.isDate,
1578 nodeIsMap = nodeUtil && nodeUtil.isMap,
1579 nodeIsRegExp = nodeUtil && nodeUtil.isRegExp,
1580 nodeIsSet = nodeUtil && nodeUtil.isSet,
1581 nodeIsTypedArray = nodeUtil && nodeUtil.isTypedArray;
1583 /*--------------------------------------------------------------------------*/
1586 * A faster alternative to `Function#apply`, this function invokes `func`
1587 * with the `this` binding of `thisArg` and the arguments of `args`.
1590 * @param {Function} func The function to invoke.
1591 * @param {*} thisArg The `this` binding of `func`.
1592 * @param {Array} args The arguments to invoke `func` with.
1593 * @returns {*} Returns the result of `func`.
1595 function apply(func, thisArg, args) {
1596 switch (args.length) {
1597 case 0: return func.call(thisArg);
1598 case 1: return func.call(thisArg, args[0]);
1599 case 2: return func.call(thisArg, args[0], args[1]);
1600 case 3: return func.call(thisArg, args[0], args[1], args[2]);
1602 return func.apply(thisArg, args);
1606 * A specialized version of `baseAggregator` for arrays.
1609 * @param {Array} [array] The array to iterate over.
1610 * @param {Function} setter The function to set `accumulator` values.
1611 * @param {Function} iteratee The iteratee to transform keys.
1612 * @param {Object} accumulator The initial aggregated object.
1613 * @returns {Function} Returns `accumulator`.
1615 function arrayAggregator(array, setter, iteratee, accumulator) {
1617 length = array == null ? 0 : array.length;
1619 while (++index < length) {
1620 var value = array[index];
1621 setter(accumulator, value, iteratee(value), array);
1627 * A specialized version of `_.forEach` for arrays without support for
1628 * iteratee shorthands.
1631 * @param {Array} [array] The array to iterate over.
1632 * @param {Function} iteratee The function invoked per iteration.
1633 * @returns {Array} Returns `array`.
1635 function arrayEach(array, iteratee) {
1637 length = array == null ? 0 : array.length;
1639 while (++index < length) {
1640 if (iteratee(array[index], index, array) === false) {
1648 * A specialized version of `_.forEachRight` for arrays without support for
1649 * iteratee shorthands.
1652 * @param {Array} [array] The array to iterate over.
1653 * @param {Function} iteratee The function invoked per iteration.
1654 * @returns {Array} Returns `array`.
1656 function arrayEachRight(array, iteratee) {
1657 var length = array == null ? 0 : array.length;
1660 if (iteratee(array[length], length, array) === false) {
1668 * A specialized version of `_.every` for arrays without support for
1669 * iteratee shorthands.
1672 * @param {Array} [array] The array to iterate over.
1673 * @param {Function} predicate The function invoked per iteration.
1674 * @returns {boolean} Returns `true` if all elements pass the predicate check,
1677 function arrayEvery(array, predicate) {
1679 length = array == null ? 0 : array.length;
1681 while (++index < length) {
1682 if (!predicate(array[index], index, array)) {
1690 * A specialized version of `_.filter` for arrays without support for
1691 * iteratee shorthands.
1694 * @param {Array} [array] The array to iterate over.
1695 * @param {Function} predicate The function invoked per iteration.
1696 * @returns {Array} Returns the new filtered array.
1698 function arrayFilter(array, predicate) {
1700 length = array == null ? 0 : array.length,
1704 while (++index < length) {
1705 var value = array[index];
1706 if (predicate(value, index, array)) {
1707 result[resIndex++] = value;
1714 * A specialized version of `_.includes` for arrays without support for
1715 * specifying an index to search from.
1718 * @param {Array} [array] The array to inspect.
1719 * @param {*} target The value to search for.
1720 * @returns {boolean} Returns `true` if `target` is found, else `false`.
1722 function arrayIncludes(array, value) {
1723 var length = array == null ? 0 : array.length;
1724 return !!length && baseIndexOf(array, value, 0) > -1;
1728 * This function is like `arrayIncludes` except that it accepts a comparator.
1731 * @param {Array} [array] The array to inspect.
1732 * @param {*} target The value to search for.
1733 * @param {Function} comparator The comparator invoked per element.
1734 * @returns {boolean} Returns `true` if `target` is found, else `false`.
1736 function arrayIncludesWith(array, value, comparator) {
1738 length = array == null ? 0 : array.length;
1740 while (++index < length) {
1741 if (comparator(value, array[index])) {
1749 * A specialized version of `_.map` for arrays without support for iteratee
1753 * @param {Array} [array] The array to iterate over.
1754 * @param {Function} iteratee The function invoked per iteration.
1755 * @returns {Array} Returns the new mapped array.
1757 function arrayMap(array, iteratee) {
1759 length = array == null ? 0 : array.length,
1760 result = Array(length);
1762 while (++index < length) {
1763 result[index] = iteratee(array[index], index, array);
1769 * Appends the elements of `values` to `array`.
1772 * @param {Array} array The array to modify.
1773 * @param {Array} values The values to append.
1774 * @returns {Array} Returns `array`.
1776 function arrayPush(array, values) {
1778 length = values.length,
1779 offset = array.length;
1781 while (++index < length) {
1782 array[offset + index] = values[index];
1788 * A specialized version of `_.reduce` for arrays without support for
1789 * iteratee shorthands.
1792 * @param {Array} [array] The array to iterate over.
1793 * @param {Function} iteratee The function invoked per iteration.
1794 * @param {*} [accumulator] The initial value.
1795 * @param {boolean} [initAccum] Specify using the first element of `array` as
1796 * the initial value.
1797 * @returns {*} Returns the accumulated value.
1799 function arrayReduce(array, iteratee, accumulator, initAccum) {
1801 length = array == null ? 0 : array.length;
1803 if (initAccum && length) {
1804 accumulator = array[++index];
1806 while (++index < length) {
1807 accumulator = iteratee(accumulator, array[index], index, array);
1813 * A specialized version of `_.reduceRight` for arrays without support for
1814 * iteratee shorthands.
1817 * @param {Array} [array] The array to iterate over.
1818 * @param {Function} iteratee The function invoked per iteration.
1819 * @param {*} [accumulator] The initial value.
1820 * @param {boolean} [initAccum] Specify using the last element of `array` as
1821 * the initial value.
1822 * @returns {*} Returns the accumulated value.
1824 function arrayReduceRight(array, iteratee, accumulator, initAccum) {
1825 var length = array == null ? 0 : array.length;
1826 if (initAccum && length) {
1827 accumulator = array[--length];
1830 accumulator = iteratee(accumulator, array[length], length, array);
1836 * A specialized version of `_.some` for arrays without support for iteratee
1840 * @param {Array} [array] The array to iterate over.
1841 * @param {Function} predicate The function invoked per iteration.
1842 * @returns {boolean} Returns `true` if any element passes the predicate check,
1845 function arraySome(array, predicate) {
1847 length = array == null ? 0 : array.length;
1849 while (++index < length) {
1850 if (predicate(array[index], index, array)) {
1858 * Gets the size of an ASCII `string`.
1861 * @param {string} string The string inspect.
1862 * @returns {number} Returns the string size.
1864 var asciiSize = baseProperty('length');
1867 * Converts an ASCII `string` to an array.
1870 * @param {string} string The string to convert.
1871 * @returns {Array} Returns the converted array.
1873 function asciiToArray(string) {
1874 return string.split('');
1878 * Splits an ASCII `string` into an array of its words.
1881 * @param {string} The string to inspect.
1882 * @returns {Array} Returns the words of `string`.
1884 function asciiWords(string) {
1885 return string.match(reAsciiWord) || [];
1889 * The base implementation of methods like `_.findKey` and `_.findLastKey`,
1890 * without support for iteratee shorthands, which iterates over `collection`
1894 * @param {Array|Object} collection The collection to inspect.
1895 * @param {Function} predicate The function invoked per iteration.
1896 * @param {Function} eachFunc The function to iterate over `collection`.
1897 * @returns {*} Returns the found element or its key, else `undefined`.
1899 function baseFindKey(collection, predicate, eachFunc) {
1901 eachFunc(collection, function(value, key, collection) {
1902 if (predicate(value, key, collection)) {
1911 * The base implementation of `_.findIndex` and `_.findLastIndex` without
1912 * support for iteratee shorthands.
1915 * @param {Array} array The array to inspect.
1916 * @param {Function} predicate The function invoked per iteration.
1917 * @param {number} fromIndex The index to search from.
1918 * @param {boolean} [fromRight] Specify iterating from right to left.
1919 * @returns {number} Returns the index of the matched value, else `-1`.
1921 function baseFindIndex(array, predicate, fromIndex, fromRight) {
1922 var length = array.length,
1923 index = fromIndex + (fromRight ? 1 : -1);
1925 while ((fromRight ? index-- : ++index < length)) {
1926 if (predicate(array[index], index, array)) {
1934 * The base implementation of `_.indexOf` without `fromIndex` bounds checks.
1937 * @param {Array} array The array to inspect.
1938 * @param {*} value The value to search for.
1939 * @param {number} fromIndex The index to search from.
1940 * @returns {number} Returns the index of the matched value, else `-1`.
1942 function baseIndexOf(array, value, fromIndex) {
1943 return value === value
1944 ? strictIndexOf(array, value, fromIndex)
1945 : baseFindIndex(array, baseIsNaN, fromIndex);
1949 * This function is like `baseIndexOf` except that it accepts a comparator.
1952 * @param {Array} array The array to inspect.
1953 * @param {*} value The value to search for.
1954 * @param {number} fromIndex The index to search from.
1955 * @param {Function} comparator The comparator invoked per element.
1956 * @returns {number} Returns the index of the matched value, else `-1`.
1958 function baseIndexOfWith(array, value, fromIndex, comparator) {
1959 var index = fromIndex - 1,
1960 length = array.length;
1962 while (++index < length) {
1963 if (comparator(array[index], value)) {
1971 * The base implementation of `_.isNaN` without support for number objects.
1974 * @param {*} value The value to check.
1975 * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`.
1977 function baseIsNaN(value) {
1978 return value !== value;
1982 * The base implementation of `_.mean` and `_.meanBy` without support for
1983 * iteratee shorthands.
1986 * @param {Array} array The array to iterate over.
1987 * @param {Function} iteratee The function invoked per iteration.
1988 * @returns {number} Returns the mean.
1990 function baseMean(array, iteratee) {
1991 var length = array == null ? 0 : array.length;
1992 return length ? (baseSum(array, iteratee) / length) : NAN;
1996 * The base implementation of `_.property` without support for deep paths.
1999 * @param {string} key The key of the property to get.
2000 * @returns {Function} Returns the new accessor function.
2002 function baseProperty(key) {
2003 return function(object) {
2004 return object == null ? undefined : object[key];
2009 * The base implementation of `_.propertyOf` without support for deep paths.
2012 * @param {Object} object The object to query.
2013 * @returns {Function} Returns the new accessor function.
2015 function basePropertyOf(object) {
2016 return function(key) {
2017 return object == null ? undefined : object[key];
2022 * The base implementation of `_.reduce` and `_.reduceRight`, without support
2023 * for iteratee shorthands, which iterates over `collection` using `eachFunc`.
2026 * @param {Array|Object} collection The collection to iterate over.
2027 * @param {Function} iteratee The function invoked per iteration.
2028 * @param {*} accumulator The initial value.
2029 * @param {boolean} initAccum Specify using the first or last element of
2030 * `collection` as the initial value.
2031 * @param {Function} eachFunc The function to iterate over `collection`.
2032 * @returns {*} Returns the accumulated value.
2034 function baseReduce(collection, iteratee, accumulator, initAccum, eachFunc) {
2035 eachFunc(collection, function(value, index, collection) {
2036 accumulator = initAccum
2037 ? (initAccum = false, value)
2038 : iteratee(accumulator, value, index, collection);
2044 * The base implementation of `_.sortBy` which uses `comparer` to define the
2045 * sort order of `array` and replaces criteria objects with their corresponding
2049 * @param {Array} array The array to sort.
2050 * @param {Function} comparer The function to define sort order.
2051 * @returns {Array} Returns `array`.
2053 function baseSortBy(array, comparer) {
2054 var length = array.length;
2056 array.sort(comparer);
2058 array[length] = array[length].value;
2064 * The base implementation of `_.sum` and `_.sumBy` without support for
2065 * iteratee shorthands.
2068 * @param {Array} array The array to iterate over.
2069 * @param {Function} iteratee The function invoked per iteration.
2070 * @returns {number} Returns the sum.
2072 function baseSum(array, iteratee) {
2075 length = array.length;
2077 while (++index < length) {
2078 var current = iteratee(array[index]);
2079 if (current !== undefined) {
2080 result = result === undefined ? current : (result + current);
2087 * The base implementation of `_.times` without support for iteratee shorthands
2088 * or max array length checks.
2091 * @param {number} n The number of times to invoke `iteratee`.
2092 * @param {Function} iteratee The function invoked per iteration.
2093 * @returns {Array} Returns the array of results.
2095 function baseTimes(n, iteratee) {
2099 while (++index < n) {
2100 result[index] = iteratee(index);
2106 * The base implementation of `_.toPairs` and `_.toPairsIn` which creates an array
2107 * of key-value pairs for `object` corresponding to the property names of `props`.
2110 * @param {Object} object The object to query.
2111 * @param {Array} props The property names to get values for.
2112 * @returns {Object} Returns the key-value pairs.
2114 function baseToPairs(object, props) {
2115 return arrayMap(props, function(key) {
2116 return [key, object[key]];
2121 * The base implementation of `_.trim`.
2124 * @param {string} string The string to trim.
2125 * @returns {string} Returns the trimmed string.
2127 function baseTrim(string) {
2129 ? string.slice(0, trimmedEndIndex(string) + 1).replace(reTrimStart, '')
2134 * The base implementation of `_.unary` without support for storing metadata.
2137 * @param {Function} func The function to cap arguments for.
2138 * @returns {Function} Returns the new capped function.
2140 function baseUnary(func) {
2141 return function(value) {
2147 * The base implementation of `_.values` and `_.valuesIn` which creates an
2148 * array of `object` property values corresponding to the property names
2152 * @param {Object} object The object to query.
2153 * @param {Array} props The property names to get values for.
2154 * @returns {Object} Returns the array of property values.
2156 function baseValues(object, props) {
2157 return arrayMap(props, function(key) {
2163 * Checks if a `cache` value for `key` exists.
2166 * @param {Object} cache The cache to query.
2167 * @param {string} key The key of the entry to check.
2168 * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
2170 function cacheHas(cache, key) {
2171 return cache.has(key);
2175 * Used by `_.trim` and `_.trimStart` to get the index of the first string symbol
2176 * that is not found in the character symbols.
2179 * @param {Array} strSymbols The string symbols to inspect.
2180 * @param {Array} chrSymbols The character symbols to find.
2181 * @returns {number} Returns the index of the first unmatched string symbol.
2183 function charsStartIndex(strSymbols, chrSymbols) {
2185 length = strSymbols.length;
2187 while (++index < length && baseIndexOf(chrSymbols, strSymbols[index], 0) > -1) {}
2192 * Used by `_.trim` and `_.trimEnd` to get the index of the last string symbol
2193 * that is not found in the character symbols.
2196 * @param {Array} strSymbols The string symbols to inspect.
2197 * @param {Array} chrSymbols The character symbols to find.
2198 * @returns {number} Returns the index of the last unmatched string symbol.
2200 function charsEndIndex(strSymbols, chrSymbols) {
2201 var index = strSymbols.length;
2203 while (index-- && baseIndexOf(chrSymbols, strSymbols[index], 0) > -1) {}
2208 * Gets the number of `placeholder` occurrences in `array`.
2211 * @param {Array} array The array to inspect.
2212 * @param {*} placeholder The placeholder to search for.
2213 * @returns {number} Returns the placeholder count.
2215 function countHolders(array, placeholder) {
2216 var length = array.length,
2220 if (array[length] === placeholder) {
2228 * Used by `_.deburr` to convert Latin-1 Supplement and Latin Extended-A
2229 * letters to basic Latin letters.
2232 * @param {string} letter The matched letter to deburr.
2233 * @returns {string} Returns the deburred letter.
2235 var deburrLetter = basePropertyOf(deburredLetters);
2238 * Used by `_.escape` to convert characters to HTML entities.
2241 * @param {string} chr The matched character to escape.
2242 * @returns {string} Returns the escaped character.
2244 var escapeHtmlChar = basePropertyOf(htmlEscapes);
2247 * Used by `_.template` to escape characters for inclusion in compiled string literals.
2250 * @param {string} chr The matched character to escape.
2251 * @returns {string} Returns the escaped character.
2253 function escapeStringChar(chr) {
2254 return '\\' + stringEscapes[chr];
2258 * Gets the value at `key` of `object`.
2261 * @param {Object} [object] The object to query.
2262 * @param {string} key The key of the property to get.
2263 * @returns {*} Returns the property value.
2265 function getValue(object, key) {
2266 return object == null ? undefined : object[key];
2270 * Checks if `string` contains Unicode symbols.
2273 * @param {string} string The string to inspect.
2274 * @returns {boolean} Returns `true` if a symbol is found, else `false`.
2276 function hasUnicode(string) {
2277 return reHasUnicode.test(string);
2281 * Checks if `string` contains a word composed of Unicode symbols.
2284 * @param {string} string The string to inspect.
2285 * @returns {boolean} Returns `true` if a word is found, else `false`.
2287 function hasUnicodeWord(string) {
2288 return reHasUnicodeWord.test(string);
2292 * Converts `iterator` to an array.
2295 * @param {Object} iterator The iterator to convert.
2296 * @returns {Array} Returns the converted array.
2298 function iteratorToArray(iterator) {
2302 while (!(data = iterator.next()).done) {
2303 result.push(data.value);
2309 * Converts `map` to its key-value pairs.
2312 * @param {Object} map The map to convert.
2313 * @returns {Array} Returns the key-value pairs.
2315 function mapToArray(map) {
2317 result = Array(map.size);
2319 map.forEach(function(value, key) {
2320 result[++index] = [key, value];
2326 * Creates a unary function that invokes `func` with its argument transformed.
2329 * @param {Function} func The function to wrap.
2330 * @param {Function} transform The argument transform.
2331 * @returns {Function} Returns the new function.
2333 function overArg(func, transform) {
2334 return function(arg) {
2335 return func(transform(arg));
2340 * Replaces all `placeholder` elements in `array` with an internal placeholder
2341 * and returns an array of their indexes.
2344 * @param {Array} array The array to modify.
2345 * @param {*} placeholder The placeholder to replace.
2346 * @returns {Array} Returns the new array of placeholder indexes.
2348 function replaceHolders(array, placeholder) {
2350 length = array.length,
2354 while (++index < length) {
2355 var value = array[index];
2356 if (value === placeholder || value === PLACEHOLDER) {
2357 array[index] = PLACEHOLDER;
2358 result[resIndex++] = index;
2365 * Converts `set` to an array of its values.
2368 * @param {Object} set The set to convert.
2369 * @returns {Array} Returns the values.
2371 function setToArray(set) {
2373 result = Array(set.size);
2375 set.forEach(function(value) {
2376 result[++index] = value;
2382 * Converts `set` to its value-value pairs.
2385 * @param {Object} set The set to convert.
2386 * @returns {Array} Returns the value-value pairs.
2388 function setToPairs(set) {
2390 result = Array(set.size);
2392 set.forEach(function(value) {
2393 result[++index] = [value, value];
2399 * A specialized version of `_.indexOf` which performs strict equality
2400 * comparisons of values, i.e. `===`.
2403 * @param {Array} array The array to inspect.
2404 * @param {*} value The value to search for.
2405 * @param {number} fromIndex The index to search from.
2406 * @returns {number} Returns the index of the matched value, else `-1`.
2408 function strictIndexOf(array, value, fromIndex) {
2409 var index = fromIndex - 1,
2410 length = array.length;
2412 while (++index < length) {
2413 if (array[index] === value) {
2421 * A specialized version of `_.lastIndexOf` which performs strict equality
2422 * comparisons of values, i.e. `===`.
2425 * @param {Array} array The array to inspect.
2426 * @param {*} value The value to search for.
2427 * @param {number} fromIndex The index to search from.
2428 * @returns {number} Returns the index of the matched value, else `-1`.
2430 function strictLastIndexOf(array, value, fromIndex) {
2431 var index = fromIndex + 1;
2433 if (array[index] === value) {
2441 * Gets the number of symbols in `string`.
2444 * @param {string} string The string to inspect.
2445 * @returns {number} Returns the string size.
2447 function stringSize(string) {
2448 return hasUnicode(string)
2449 ? unicodeSize(string)
2450 : asciiSize(string);
2454 * Converts `string` to an array.
2457 * @param {string} string The string to convert.
2458 * @returns {Array} Returns the converted array.
2460 function stringToArray(string) {
2461 return hasUnicode(string)
2462 ? unicodeToArray(string)
2463 : asciiToArray(string);
2467 * Used by `_.trim` and `_.trimEnd` to get the index of the last non-whitespace
2468 * character of `string`.
2471 * @param {string} string The string to inspect.
2472 * @returns {number} Returns the index of the last non-whitespace character.
2474 function trimmedEndIndex(string) {
2475 var index = string.length;
2477 while (index-- && reWhitespace.test(string.charAt(index))) {}
2482 * Used by `_.unescape` to convert HTML entities to characters.
2485 * @param {string} chr The matched character to unescape.
2486 * @returns {string} Returns the unescaped character.
2488 var unescapeHtmlChar = basePropertyOf(htmlUnescapes);
2491 * Gets the size of a Unicode `string`.
2494 * @param {string} string The string inspect.
2495 * @returns {number} Returns the string size.
2497 function unicodeSize(string) {
2498 var result = reUnicode.lastIndex = 0;
2499 while (reUnicode.test(string)) {
2506 * Converts a Unicode `string` to an array.
2509 * @param {string} string The string to convert.
2510 * @returns {Array} Returns the converted array.
2512 function unicodeToArray(string) {
2513 return string.match(reUnicode) || [];
2517 * Splits a Unicode `string` into an array of its words.
2520 * @param {string} The string to inspect.
2521 * @returns {Array} Returns the words of `string`.
2523 function unicodeWords(string) {
2524 return string.match(reUnicodeWord) || [];
2527 /*--------------------------------------------------------------------------*/
2530 * Create a new pristine `lodash` function using the `context` object.
2536 * @param {Object} [context=root] The context object.
2537 * @returns {Function} Returns a new `lodash` function.
2540 * _.mixin({ 'foo': _.constant('foo') });
2542 * var lodash = _.runInContext();
2543 * lodash.mixin({ 'bar': lodash.constant('bar') });
2545 * _.isFunction(_.foo);
2547 * _.isFunction(_.bar);
2550 * lodash.isFunction(lodash.foo);
2552 * lodash.isFunction(lodash.bar);
2555 * // Create a suped-up `defer` in Node.js.
2556 * var defer = _.runInContext({ 'setTimeout': setImmediate }).defer;
2558 var runInContext = (function runInContext(context) {
2559 context = context == null ? root : _.defaults(root.Object(), context, _.pick(root, contextProps));
2561 /** Built-in constructor references. */
2562 var Array = context.Array,
2563 Date = context.Date,
2564 Error = context.Error,
2565 Function = context.Function,
2566 Math = context.Math,
2567 Object = context.Object,
2568 RegExp = context.RegExp,
2569 String = context.String,
2570 TypeError = context.TypeError;
2572 /** Used for built-in method references. */
2573 var arrayProto = Array.prototype,
2574 funcProto = Function.prototype,
2575 objectProto = Object.prototype;
2577 /** Used to detect overreaching core-js shims. */
2578 var coreJsData = context['__core-js_shared__'];
2580 /** Used to resolve the decompiled source of functions. */
2581 var funcToString = funcProto.toString;
2583 /** Used to check objects for own properties. */
2584 var hasOwnProperty = objectProto.hasOwnProperty;
2586 /** Used to generate unique IDs. */
2589 /** Used to detect methods masquerading as native. */
2590 var maskSrcKey = (function() {
2591 var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || '');
2592 return uid ? ('Symbol(src)_1.' + uid) : '';
2596 * Used to resolve the
2597 * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
2600 var nativeObjectToString = objectProto.toString;
2602 /** Used to infer the `Object` constructor. */
2603 var objectCtorString = funcToString.call(Object);
2605 /** Used to restore the original `_` reference in `_.noConflict`. */
2606 var oldDash = root._;
2608 /** Used to detect if a method is native. */
2609 var reIsNative = RegExp('^' +
2610 funcToString.call(hasOwnProperty).replace(reRegExpChar, '\\$&')
2611 .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$'
2614 /** Built-in value references. */
2615 var Buffer = moduleExports ? context.Buffer : undefined,
2616 Symbol = context.Symbol,
2617 Uint8Array = context.Uint8Array,
2618 allocUnsafe = Buffer ? Buffer.allocUnsafe : undefined,
2619 getPrototype = overArg(Object.getPrototypeOf, Object),
2620 objectCreate = Object.create,
2621 propertyIsEnumerable = objectProto.propertyIsEnumerable,
2622 splice = arrayProto.splice,
2623 spreadableSymbol = Symbol ? Symbol.isConcatSpreadable : undefined,
2624 symIterator = Symbol ? Symbol.iterator : undefined,
2625 symToStringTag = Symbol ? Symbol.toStringTag : undefined;
2627 var defineProperty = (function() {
2629 var func = getNative(Object, 'defineProperty');
2635 /** Mocked built-ins. */
2636 var ctxClearTimeout = context.clearTimeout !== root.clearTimeout && context.clearTimeout,
2637 ctxNow = Date && Date.now !== root.Date.now && Date.now,
2638 ctxSetTimeout = context.setTimeout !== root.setTimeout && context.setTimeout;
2640 /* Built-in method references for those with the same name as other `lodash` methods. */
2641 var nativeCeil = Math.ceil,
2642 nativeFloor = Math.floor,
2643 nativeGetSymbols = Object.getOwnPropertySymbols,
2644 nativeIsBuffer = Buffer ? Buffer.isBuffer : undefined,
2645 nativeIsFinite = context.isFinite,
2646 nativeJoin = arrayProto.join,
2647 nativeKeys = overArg(Object.keys, Object),
2648 nativeMax = Math.max,
2649 nativeMin = Math.min,
2650 nativeNow = Date.now,
2651 nativeParseInt = context.parseInt,
2652 nativeRandom = Math.random,
2653 nativeReverse = arrayProto.reverse;
2655 /* Built-in method references that are verified to be native. */
2656 var DataView = getNative(context, 'DataView'),
2657 Map = getNative(context, 'Map'),
2658 Promise = getNative(context, 'Promise'),
2659 Set = getNative(context, 'Set'),
2660 WeakMap = getNative(context, 'WeakMap'),
2661 nativeCreate = getNative(Object, 'create');
2663 /** Used to store function metadata. */
2664 var metaMap = WeakMap && new WeakMap;
2666 /** Used to lookup unminified function names. */
2669 /** Used to detect maps, sets, and weakmaps. */
2670 var dataViewCtorString = toSource(DataView),
2671 mapCtorString = toSource(Map),
2672 promiseCtorString = toSource(Promise),
2673 setCtorString = toSource(Set),
2674 weakMapCtorString = toSource(WeakMap);
2676 /** Used to convert symbols to primitives and strings. */
2677 var symbolProto = Symbol ? Symbol.prototype : undefined,
2678 symbolValueOf = symbolProto ? symbolProto.valueOf : undefined,
2679 symbolToString = symbolProto ? symbolProto.toString : undefined;
2681 /*------------------------------------------------------------------------*/
2684 * Creates a `lodash` object which wraps `value` to enable implicit method
2685 * chain sequences. Methods that operate on and return arrays, collections,
2686 * and functions can be chained together. Methods that retrieve a single value
2687 * or may return a primitive value will automatically end the chain sequence
2688 * and return the unwrapped value. Otherwise, the value must be unwrapped
2691 * Explicit chain sequences, which must be unwrapped with `_#value`, may be
2692 * enabled using `_.chain`.
2694 * The execution of chained methods is lazy, that is, it's deferred until
2695 * `_#value` is implicitly or explicitly called.
2697 * Lazy evaluation allows several methods to support shortcut fusion.
2698 * Shortcut fusion is an optimization to merge iteratee calls; this avoids
2699 * the creation of intermediate arrays and can greatly reduce the number of
2700 * iteratee executions. Sections of a chain sequence qualify for shortcut
2701 * fusion if the section is applied to an array and iteratees accept only
2702 * one argument. The heuristic for whether a section qualifies for shortcut
2703 * fusion is subject to change.
2705 * Chaining is supported in custom builds as long as the `_#value` method is
2706 * directly or indirectly included in the build.
2708 * In addition to lodash methods, wrappers have `Array` and `String` methods.
2710 * The wrapper `Array` methods are:
2711 * `concat`, `join`, `pop`, `push`, `shift`, `sort`, `splice`, and `unshift`
2713 * The wrapper `String` methods are:
2714 * `replace` and `split`
2716 * The wrapper methods that support shortcut fusion are:
2717 * `at`, `compact`, `drop`, `dropRight`, `dropWhile`, `filter`, `find`,
2718 * `findLast`, `head`, `initial`, `last`, `map`, `reject`, `reverse`, `slice`,
2719 * `tail`, `take`, `takeRight`, `takeRightWhile`, `takeWhile`, and `toArray`
2721 * The chainable wrapper methods are:
2722 * `after`, `ary`, `assign`, `assignIn`, `assignInWith`, `assignWith`, `at`,
2723 * `before`, `bind`, `bindAll`, `bindKey`, `castArray`, `chain`, `chunk`,
2724 * `commit`, `compact`, `concat`, `conforms`, `constant`, `countBy`, `create`,
2725 * `curry`, `debounce`, `defaults`, `defaultsDeep`, `defer`, `delay`,
2726 * `difference`, `differenceBy`, `differenceWith`, `drop`, `dropRight`,
2727 * `dropRightWhile`, `dropWhile`, `extend`, `extendWith`, `fill`, `filter`,
2728 * `flatMap`, `flatMapDeep`, `flatMapDepth`, `flatten`, `flattenDeep`,
2729 * `flattenDepth`, `flip`, `flow`, `flowRight`, `fromPairs`, `functions`,
2730 * `functionsIn`, `groupBy`, `initial`, `intersection`, `intersectionBy`,
2731 * `intersectionWith`, `invert`, `invertBy`, `invokeMap`, `iteratee`, `keyBy`,
2732 * `keys`, `keysIn`, `map`, `mapKeys`, `mapValues`, `matches`, `matchesProperty`,
2733 * `memoize`, `merge`, `mergeWith`, `method`, `methodOf`, `mixin`, `negate`,
2734 * `nthArg`, `omit`, `omitBy`, `once`, `orderBy`, `over`, `overArgs`,
2735 * `overEvery`, `overSome`, `partial`, `partialRight`, `partition`, `pick`,
2736 * `pickBy`, `plant`, `property`, `propertyOf`, `pull`, `pullAll`, `pullAllBy`,
2737 * `pullAllWith`, `pullAt`, `push`, `range`, `rangeRight`, `rearg`, `reject`,
2738 * `remove`, `rest`, `reverse`, `sampleSize`, `set`, `setWith`, `shuffle`,
2739 * `slice`, `sort`, `sortBy`, `splice`, `spread`, `tail`, `take`, `takeRight`,
2740 * `takeRightWhile`, `takeWhile`, `tap`, `throttle`, `thru`, `toArray`,
2741 * `toPairs`, `toPairsIn`, `toPath`, `toPlainObject`, `transform`, `unary`,
2742 * `union`, `unionBy`, `unionWith`, `uniq`, `uniqBy`, `uniqWith`, `unset`,
2743 * `unshift`, `unzip`, `unzipWith`, `update`, `updateWith`, `values`,
2744 * `valuesIn`, `without`, `wrap`, `xor`, `xorBy`, `xorWith`, `zip`,
2745 * `zipObject`, `zipObjectDeep`, and `zipWith`
2747 * The wrapper methods that are **not** chainable by default are:
2748 * `add`, `attempt`, `camelCase`, `capitalize`, `ceil`, `clamp`, `clone`,
2749 * `cloneDeep`, `cloneDeepWith`, `cloneWith`, `conformsTo`, `deburr`,
2750 * `defaultTo`, `divide`, `each`, `eachRight`, `endsWith`, `eq`, `escape`,
2751 * `escapeRegExp`, `every`, `find`, `findIndex`, `findKey`, `findLast`,
2752 * `findLastIndex`, `findLastKey`, `first`, `floor`, `forEach`, `forEachRight`,
2753 * `forIn`, `forInRight`, `forOwn`, `forOwnRight`, `get`, `gt`, `gte`, `has`,
2754 * `hasIn`, `head`, `identity`, `includes`, `indexOf`, `inRange`, `invoke`,
2755 * `isArguments`, `isArray`, `isArrayBuffer`, `isArrayLike`, `isArrayLikeObject`,
2756 * `isBoolean`, `isBuffer`, `isDate`, `isElement`, `isEmpty`, `isEqual`,
2757 * `isEqualWith`, `isError`, `isFinite`, `isFunction`, `isInteger`, `isLength`,
2758 * `isMap`, `isMatch`, `isMatchWith`, `isNaN`, `isNative`, `isNil`, `isNull`,
2759 * `isNumber`, `isObject`, `isObjectLike`, `isPlainObject`, `isRegExp`,
2760 * `isSafeInteger`, `isSet`, `isString`, `isUndefined`, `isTypedArray`,
2761 * `isWeakMap`, `isWeakSet`, `join`, `kebabCase`, `last`, `lastIndexOf`,
2762 * `lowerCase`, `lowerFirst`, `lt`, `lte`, `max`, `maxBy`, `mean`, `meanBy`,
2763 * `min`, `minBy`, `multiply`, `noConflict`, `noop`, `now`, `nth`, `pad`,
2764 * `padEnd`, `padStart`, `parseInt`, `pop`, `random`, `reduce`, `reduceRight`,
2765 * `repeat`, `result`, `round`, `runInContext`, `sample`, `shift`, `size`,
2766 * `snakeCase`, `some`, `sortedIndex`, `sortedIndexBy`, `sortedLastIndex`,
2767 * `sortedLastIndexBy`, `startCase`, `startsWith`, `stubArray`, `stubFalse`,
2768 * `stubObject`, `stubString`, `stubTrue`, `subtract`, `sum`, `sumBy`,
2769 * `template`, `times`, `toFinite`, `toInteger`, `toJSON`, `toLength`,
2770 * `toLower`, `toNumber`, `toSafeInteger`, `toString`, `toUpper`, `trim`,
2771 * `trimEnd`, `trimStart`, `truncate`, `unescape`, `uniqueId`, `upperCase`,
2772 * `upperFirst`, `value`, and `words`
2777 * @param {*} value The value to wrap in a `lodash` instance.
2778 * @returns {Object} Returns the new `lodash` wrapper instance.
2781 * function square(n) {
2785 * var wrapped = _([1, 2, 3]);
2787 * // Returns an unwrapped value.
2788 * wrapped.reduce(_.add);
2791 * // Returns a wrapped value.
2792 * var squares = wrapped.map(square);
2794 * _.isArray(squares);
2797 * _.isArray(squares.value());
2800 function lodash(value) {
2801 if (isObjectLike(value) && !isArray(value) && !(value instanceof LazyWrapper)) {
2802 if (value instanceof LodashWrapper) {
2805 if (hasOwnProperty.call(value, '__wrapped__')) {
2806 return wrapperClone(value);
2809 return new LodashWrapper(value);
2813 * The base implementation of `_.create` without support for assigning
2814 * properties to the created object.
2817 * @param {Object} proto The object to inherit from.
2818 * @returns {Object} Returns the new object.
2820 var baseCreate = (function() {
2821 function object() {}
2822 return function(proto) {
2823 if (!isObject(proto)) {
2827 return objectCreate(proto);
2829 object.prototype = proto;
2830 var result = new object;
2831 object.prototype = undefined;
2837 * The function whose prototype chain sequence wrappers inherit from.
2841 function baseLodash() {
2842 // No operation performed.
2846 * The base constructor for creating `lodash` wrapper objects.
2849 * @param {*} value The value to wrap.
2850 * @param {boolean} [chainAll] Enable explicit method chain sequences.
2852 function LodashWrapper(value, chainAll) {
2853 this.__wrapped__ = value;
2854 this.__actions__ = [];
2855 this.__chain__ = !!chainAll;
2857 this.__values__ = undefined;
2861 * By default, the template delimiters used by lodash are like those in
2862 * embedded Ruby (ERB) as well as ES2015 template strings. Change the
2863 * following template settings to use alternative delimiters.
2869 lodash.templateSettings = {
2872 * Used to detect `data` property values to be HTML-escaped.
2874 * @memberOf _.templateSettings
2880 * Used to detect code to be evaluated.
2882 * @memberOf _.templateSettings
2885 'evaluate': reEvaluate,
2888 * Used to detect `data` property values to inject.
2890 * @memberOf _.templateSettings
2893 'interpolate': reInterpolate,
2896 * Used to reference the data object in the template text.
2898 * @memberOf _.templateSettings
2904 * Used to import variables into the compiled template.
2906 * @memberOf _.templateSettings
2912 * A reference to the `lodash` function.
2914 * @memberOf _.templateSettings.imports
2921 // Ensure wrappers are instances of `baseLodash`.
2922 lodash.prototype = baseLodash.prototype;
2923 lodash.prototype.constructor = lodash;
2925 LodashWrapper.prototype = baseCreate(baseLodash.prototype);
2926 LodashWrapper.prototype.constructor = LodashWrapper;
2928 /*------------------------------------------------------------------------*/
2931 * Creates a lazy wrapper object which wraps `value` to enable lazy evaluation.
2935 * @param {*} value The value to wrap.
2937 function LazyWrapper(value) {
2938 this.__wrapped__ = value;
2939 this.__actions__ = [];
2941 this.__filtered__ = false;
2942 this.__iteratees__ = [];
2943 this.__takeCount__ = MAX_ARRAY_LENGTH;
2944 this.__views__ = [];
2948 * Creates a clone of the lazy wrapper object.
2952 * @memberOf LazyWrapper
2953 * @returns {Object} Returns the cloned `LazyWrapper` object.
2955 function lazyClone() {
2956 var result = new LazyWrapper(this.__wrapped__);
2957 result.__actions__ = copyArray(this.__actions__);
2958 result.__dir__ = this.__dir__;
2959 result.__filtered__ = this.__filtered__;
2960 result.__iteratees__ = copyArray(this.__iteratees__);
2961 result.__takeCount__ = this.__takeCount__;
2962 result.__views__ = copyArray(this.__views__);
2967 * Reverses the direction of lazy iteration.
2971 * @memberOf LazyWrapper
2972 * @returns {Object} Returns the new reversed `LazyWrapper` object.
2974 function lazyReverse() {
2975 if (this.__filtered__) {
2976 var result = new LazyWrapper(this);
2977 result.__dir__ = -1;
2978 result.__filtered__ = true;
2980 result = this.clone();
2981 result.__dir__ *= -1;
2987 * Extracts the unwrapped value from its lazy wrapper.
2991 * @memberOf LazyWrapper
2992 * @returns {*} Returns the unwrapped value.
2994 function lazyValue() {
2995 var array = this.__wrapped__.value(),
2997 isArr = isArray(array),
2999 arrLength = isArr ? array.length : 0,
3000 view = getView(0, arrLength, this.__views__),
3003 length = end - start,
3004 index = isRight ? end : (start - 1),
3005 iteratees = this.__iteratees__,
3006 iterLength = iteratees.length,
3008 takeCount = nativeMin(length, this.__takeCount__);
3010 if (!isArr || (!isRight && arrLength == length && takeCount == length)) {
3011 return baseWrapperValue(array, this.__actions__);
3016 while (length-- && resIndex < takeCount) {
3020 value = array[index];
3022 while (++iterIndex < iterLength) {
3023 var data = iteratees[iterIndex],
3024 iteratee = data.iteratee,
3026 computed = iteratee(value);
3028 if (type == LAZY_MAP_FLAG) {
3030 } else if (!computed) {
3031 if (type == LAZY_FILTER_FLAG) {
3038 result[resIndex++] = value;
3043 // Ensure `LazyWrapper` is an instance of `baseLodash`.
3044 LazyWrapper.prototype = baseCreate(baseLodash.prototype);
3045 LazyWrapper.prototype.constructor = LazyWrapper;
3047 /*------------------------------------------------------------------------*/
3050 * Creates a hash object.
3054 * @param {Array} [entries] The key-value pairs to cache.
3056 function Hash(entries) {
3058 length = entries == null ? 0 : entries.length;
3061 while (++index < length) {
3062 var entry = entries[index];
3063 this.set(entry[0], entry[1]);
3068 * Removes all key-value entries from the hash.
3074 function hashClear() {
3075 this.__data__ = nativeCreate ? nativeCreate(null) : {};
3080 * Removes `key` and its value from the hash.
3085 * @param {Object} hash The hash to modify.
3086 * @param {string} key The key of the value to remove.
3087 * @returns {boolean} Returns `true` if the entry was removed, else `false`.
3089 function hashDelete(key) {
3090 var result = this.has(key) && delete this.__data__[key];
3091 this.size -= result ? 1 : 0;
3096 * Gets the hash value for `key`.
3101 * @param {string} key The key of the value to get.
3102 * @returns {*} Returns the entry value.
3104 function hashGet(key) {
3105 var data = this.__data__;
3107 var result = data[key];
3108 return result === HASH_UNDEFINED ? undefined : result;
3110 return hasOwnProperty.call(data, key) ? data[key] : undefined;
3114 * Checks if a hash value for `key` exists.
3119 * @param {string} key The key of the entry to check.
3120 * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
3122 function hashHas(key) {
3123 var data = this.__data__;
3124 return nativeCreate ? (data[key] !== undefined) : hasOwnProperty.call(data, key);
3128 * Sets the hash `key` to `value`.
3133 * @param {string} key The key of the value to set.
3134 * @param {*} value The value to set.
3135 * @returns {Object} Returns the hash instance.
3137 function hashSet(key, value) {
3138 var data = this.__data__;
3139 this.size += this.has(key) ? 0 : 1;
3140 data[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED : value;
3144 // Add methods to `Hash`.
3145 Hash.prototype.clear = hashClear;
3146 Hash.prototype['delete'] = hashDelete;
3147 Hash.prototype.get = hashGet;
3148 Hash.prototype.has = hashHas;
3149 Hash.prototype.set = hashSet;
3151 /*------------------------------------------------------------------------*/
3154 * Creates an list cache object.
3158 * @param {Array} [entries] The key-value pairs to cache.
3160 function ListCache(entries) {
3162 length = entries == null ? 0 : entries.length;
3165 while (++index < length) {
3166 var entry = entries[index];
3167 this.set(entry[0], entry[1]);
3172 * Removes all key-value entries from the list cache.
3176 * @memberOf ListCache
3178 function listCacheClear() {
3184 * Removes `key` and its value from the list cache.
3188 * @memberOf ListCache
3189 * @param {string} key The key of the value to remove.
3190 * @returns {boolean} Returns `true` if the entry was removed, else `false`.
3192 function listCacheDelete(key) {
3193 var data = this.__data__,
3194 index = assocIndexOf(data, key);
3199 var lastIndex = data.length - 1;
3200 if (index == lastIndex) {
3203 splice.call(data, index, 1);
3210 * Gets the list cache value for `key`.
3214 * @memberOf ListCache
3215 * @param {string} key The key of the value to get.
3216 * @returns {*} Returns the entry value.
3218 function listCacheGet(key) {
3219 var data = this.__data__,
3220 index = assocIndexOf(data, key);
3222 return index < 0 ? undefined : data[index][1];
3226 * Checks if a list cache value for `key` exists.
3230 * @memberOf ListCache
3231 * @param {string} key The key of the entry to check.
3232 * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
3234 function listCacheHas(key) {
3235 return assocIndexOf(this.__data__, key) > -1;
3239 * Sets the list cache `key` to `value`.
3243 * @memberOf ListCache
3244 * @param {string} key The key of the value to set.
3245 * @param {*} value The value to set.
3246 * @returns {Object} Returns the list cache instance.
3248 function listCacheSet(key, value) {
3249 var data = this.__data__,
3250 index = assocIndexOf(data, key);
3254 data.push([key, value]);
3256 data[index][1] = value;
3261 // Add methods to `ListCache`.
3262 ListCache.prototype.clear = listCacheClear;
3263 ListCache.prototype['delete'] = listCacheDelete;
3264 ListCache.prototype.get = listCacheGet;
3265 ListCache.prototype.has = listCacheHas;
3266 ListCache.prototype.set = listCacheSet;
3268 /*------------------------------------------------------------------------*/
3271 * Creates a map cache object to store key-value pairs.
3275 * @param {Array} [entries] The key-value pairs to cache.
3277 function MapCache(entries) {
3279 length = entries == null ? 0 : entries.length;
3282 while (++index < length) {
3283 var entry = entries[index];
3284 this.set(entry[0], entry[1]);
3289 * Removes all key-value entries from the map.
3293 * @memberOf MapCache
3295 function mapCacheClear() {
3299 'map': new (Map || ListCache),
3305 * Removes `key` and its value from the map.
3309 * @memberOf MapCache
3310 * @param {string} key The key of the value to remove.
3311 * @returns {boolean} Returns `true` if the entry was removed, else `false`.
3313 function mapCacheDelete(key) {
3314 var result = getMapData(this, key)['delete'](key);
3315 this.size -= result ? 1 : 0;
3320 * Gets the map value for `key`.
3324 * @memberOf MapCache
3325 * @param {string} key The key of the value to get.
3326 * @returns {*} Returns the entry value.
3328 function mapCacheGet(key) {
3329 return getMapData(this, key).get(key);
3333 * Checks if a map value for `key` exists.
3337 * @memberOf MapCache
3338 * @param {string} key The key of the entry to check.
3339 * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
3341 function mapCacheHas(key) {
3342 return getMapData(this, key).has(key);
3346 * Sets the map `key` to `value`.
3350 * @memberOf MapCache
3351 * @param {string} key The key of the value to set.
3352 * @param {*} value The value to set.
3353 * @returns {Object} Returns the map cache instance.
3355 function mapCacheSet(key, value) {
3356 var data = getMapData(this, key),
3359 data.set(key, value);
3360 this.size += data.size == size ? 0 : 1;
3364 // Add methods to `MapCache`.
3365 MapCache.prototype.clear = mapCacheClear;
3366 MapCache.prototype['delete'] = mapCacheDelete;
3367 MapCache.prototype.get = mapCacheGet;
3368 MapCache.prototype.has = mapCacheHas;
3369 MapCache.prototype.set = mapCacheSet;
3371 /*------------------------------------------------------------------------*/
3375 * Creates an array cache object to store unique values.
3379 * @param {Array} [values] The values to cache.
3381 function SetCache(values) {
3383 length = values == null ? 0 : values.length;
3385 this.__data__ = new MapCache;
3386 while (++index < length) {
3387 this.add(values[index]);
3392 * Adds `value` to the array cache.
3396 * @memberOf SetCache
3398 * @param {*} value The value to cache.
3399 * @returns {Object} Returns the cache instance.
3401 function setCacheAdd(value) {
3402 this.__data__.set(value, HASH_UNDEFINED);
3407 * Checks if `value` is in the array cache.
3411 * @memberOf SetCache
3412 * @param {*} value The value to search for.
3413 * @returns {number} Returns `true` if `value` is found, else `false`.
3415 function setCacheHas(value) {
3416 return this.__data__.has(value);
3419 // Add methods to `SetCache`.
3420 SetCache.prototype.add = SetCache.prototype.push = setCacheAdd;
3421 SetCache.prototype.has = setCacheHas;
3423 /*------------------------------------------------------------------------*/
3426 * Creates a stack cache object to store key-value pairs.
3430 * @param {Array} [entries] The key-value pairs to cache.
3432 function Stack(entries) {
3433 var data = this.__data__ = new ListCache(entries);
3434 this.size = data.size;
3438 * Removes all key-value entries from the stack.
3444 function stackClear() {
3445 this.__data__ = new ListCache;
3450 * Removes `key` and its value from the stack.
3455 * @param {string} key The key of the value to remove.
3456 * @returns {boolean} Returns `true` if the entry was removed, else `false`.
3458 function stackDelete(key) {
3459 var data = this.__data__,
3460 result = data['delete'](key);
3462 this.size = data.size;
3467 * Gets the stack value for `key`.
3472 * @param {string} key The key of the value to get.
3473 * @returns {*} Returns the entry value.
3475 function stackGet(key) {
3476 return this.__data__.get(key);
3480 * Checks if a stack value for `key` exists.
3485 * @param {string} key The key of the entry to check.
3486 * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
3488 function stackHas(key) {
3489 return this.__data__.has(key);
3493 * Sets the stack `key` to `value`.
3498 * @param {string} key The key of the value to set.
3499 * @param {*} value The value to set.
3500 * @returns {Object} Returns the stack cache instance.
3502 function stackSet(key, value) {
3503 var data = this.__data__;
3504 if (data instanceof ListCache) {
3505 var pairs = data.__data__;
3506 if (!Map || (pairs.length < LARGE_ARRAY_SIZE - 1)) {
3507 pairs.push([key, value]);
3508 this.size = ++data.size;
3511 data = this.__data__ = new MapCache(pairs);
3513 data.set(key, value);
3514 this.size = data.size;
3518 // Add methods to `Stack`.
3519 Stack.prototype.clear = stackClear;
3520 Stack.prototype['delete'] = stackDelete;
3521 Stack.prototype.get = stackGet;
3522 Stack.prototype.has = stackHas;
3523 Stack.prototype.set = stackSet;
3525 /*------------------------------------------------------------------------*/
3528 * Creates an array of the enumerable property names of the array-like `value`.
3531 * @param {*} value The value to query.
3532 * @param {boolean} inherited Specify returning inherited property names.
3533 * @returns {Array} Returns the array of property names.
3535 function arrayLikeKeys(value, inherited) {
3536 var isArr = isArray(value),
3537 isArg = !isArr && isArguments(value),
3538 isBuff = !isArr && !isArg && isBuffer(value),
3539 isType = !isArr && !isArg && !isBuff && isTypedArray(value),
3540 skipIndexes = isArr || isArg || isBuff || isType,
3541 result = skipIndexes ? baseTimes(value.length, String) : [],
3542 length = result.length;
3544 for (var key in value) {
3545 if ((inherited || hasOwnProperty.call(value, key)) &&
3547 // Safari 9 has enumerable `arguments.length` in strict mode.
3549 // Node.js 0.10 has enumerable non-index properties on buffers.
3550 (isBuff && (key == 'offset' || key == 'parent')) ||
3551 // PhantomJS 2 has enumerable non-index properties on typed arrays.
3552 (isType && (key == 'buffer' || key == 'byteLength' || key == 'byteOffset')) ||
3553 // Skip index properties.
3554 isIndex(key, length)
3563 * A specialized version of `_.sample` for arrays.
3566 * @param {Array} array The array to sample.
3567 * @returns {*} Returns the random element.
3569 function arraySample(array) {
3570 var length = array.length;
3571 return length ? array[baseRandom(0, length - 1)] : undefined;
3575 * A specialized version of `_.sampleSize` for arrays.
3578 * @param {Array} array The array to sample.
3579 * @param {number} n The number of elements to sample.
3580 * @returns {Array} Returns the random elements.
3582 function arraySampleSize(array, n) {
3583 return shuffleSelf(copyArray(array), baseClamp(n, 0, array.length));
3587 * A specialized version of `_.shuffle` for arrays.
3590 * @param {Array} array The array to shuffle.
3591 * @returns {Array} Returns the new shuffled array.
3593 function arrayShuffle(array) {
3594 return shuffleSelf(copyArray(array));
3598 * This function is like `assignValue` except that it doesn't assign
3599 * `undefined` values.
3602 * @param {Object} object The object to modify.
3603 * @param {string} key The key of the property to assign.
3604 * @param {*} value The value to assign.
3606 function assignMergeValue(object, key, value) {
3607 if ((value !== undefined && !eq(object[key], value)) ||
3608 (value === undefined && !(key in object))) {
3609 baseAssignValue(object, key, value);
3614 * Assigns `value` to `key` of `object` if the existing value is not equivalent
3615 * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
3616 * for equality comparisons.
3619 * @param {Object} object The object to modify.
3620 * @param {string} key The key of the property to assign.
3621 * @param {*} value The value to assign.
3623 function assignValue(object, key, value) {
3624 var objValue = object[key];
3625 if (!(hasOwnProperty.call(object, key) && eq(objValue, value)) ||
3626 (value === undefined && !(key in object))) {
3627 baseAssignValue(object, key, value);
3632 * Gets the index at which the `key` is found in `array` of key-value pairs.
3635 * @param {Array} array The array to inspect.
3636 * @param {*} key The key to search for.
3637 * @returns {number} Returns the index of the matched value, else `-1`.
3639 function assocIndexOf(array, key) {
3640 var length = array.length;
3642 if (eq(array[length][0], key)) {
3650 * Aggregates elements of `collection` on `accumulator` with keys transformed
3651 * by `iteratee` and values set by `setter`.
3654 * @param {Array|Object} collection The collection to iterate over.
3655 * @param {Function} setter The function to set `accumulator` values.
3656 * @param {Function} iteratee The iteratee to transform keys.
3657 * @param {Object} accumulator The initial aggregated object.
3658 * @returns {Function} Returns `accumulator`.
3660 function baseAggregator(collection, setter, iteratee, accumulator) {
3661 baseEach(collection, function(value, key, collection) {
3662 setter(accumulator, value, iteratee(value), collection);
3668 * The base implementation of `_.assign` without support for multiple sources
3669 * or `customizer` functions.
3672 * @param {Object} object The destination object.
3673 * @param {Object} source The source object.
3674 * @returns {Object} Returns `object`.
3676 function baseAssign(object, source) {
3677 return object && copyObject(source, keys(source), object);
3681 * The base implementation of `_.assignIn` without support for multiple sources
3682 * or `customizer` functions.
3685 * @param {Object} object The destination object.
3686 * @param {Object} source The source object.
3687 * @returns {Object} Returns `object`.
3689 function baseAssignIn(object, source) {
3690 return object && copyObject(source, keysIn(source), object);
3694 * The base implementation of `assignValue` and `assignMergeValue` without
3698 * @param {Object} object The object to modify.
3699 * @param {string} key The key of the property to assign.
3700 * @param {*} value The value to assign.
3702 function baseAssignValue(object, key, value) {
3703 if (key == '__proto__' && defineProperty) {
3704 defineProperty(object, key, {
3705 'configurable': true,
3711 object[key] = value;
3716 * The base implementation of `_.at` without support for individual paths.
3719 * @param {Object} object The object to iterate over.
3720 * @param {string[]} paths The property paths to pick.
3721 * @returns {Array} Returns the picked elements.
3723 function baseAt(object, paths) {
3725 length = paths.length,
3726 result = Array(length),
3727 skip = object == null;
3729 while (++index < length) {
3730 result[index] = skip ? undefined : get(object, paths[index]);
3736 * The base implementation of `_.clamp` which doesn't coerce arguments.
3739 * @param {number} number The number to clamp.
3740 * @param {number} [lower] The lower bound.
3741 * @param {number} upper The upper bound.
3742 * @returns {number} Returns the clamped number.
3744 function baseClamp(number, lower, upper) {
3745 if (number === number) {
3746 if (upper !== undefined) {
3747 number = number <= upper ? number : upper;
3749 if (lower !== undefined) {
3750 number = number >= lower ? number : lower;
3757 * The base implementation of `_.clone` and `_.cloneDeep` which tracks
3758 * traversed objects.
3761 * @param {*} value The value to clone.
3762 * @param {boolean} bitmask The bitmask flags.
3764 * 2 - Flatten inherited properties
3766 * @param {Function} [customizer] The function to customize cloning.
3767 * @param {string} [key] The key of `value`.
3768 * @param {Object} [object] The parent object of `value`.
3769 * @param {Object} [stack] Tracks traversed objects and their clone counterparts.
3770 * @returns {*} Returns the cloned value.
3772 function baseClone(value, bitmask, customizer, key, object, stack) {
3774 isDeep = bitmask & CLONE_DEEP_FLAG,
3775 isFlat = bitmask & CLONE_FLAT_FLAG,
3776 isFull = bitmask & CLONE_SYMBOLS_FLAG;
3779 result = object ? customizer(value, key, object, stack) : customizer(value);
3781 if (result !== undefined) {
3784 if (!isObject(value)) {
3787 var isArr = isArray(value);
3789 result = initCloneArray(value);
3791 return copyArray(value, result);
3794 var tag = getTag(value),
3795 isFunc = tag == funcTag || tag == genTag;
3797 if (isBuffer(value)) {
3798 return cloneBuffer(value, isDeep);
3800 if (tag == objectTag || tag == argsTag || (isFunc && !object)) {
3801 result = (isFlat || isFunc) ? {} : initCloneObject(value);
3804 ? copySymbolsIn(value, baseAssignIn(result, value))
3805 : copySymbols(value, baseAssign(result, value));
3808 if (!cloneableTags[tag]) {
3809 return object ? value : {};
3811 result = initCloneByTag(value, tag, isDeep);
3814 // Check for circular references and return its corresponding clone.
3815 stack || (stack = new Stack);
3816 var stacked = stack.get(value);
3820 stack.set(value, result);
3823 value.forEach(function(subValue) {
3824 result.add(baseClone(subValue, bitmask, customizer, subValue, value, stack));
3826 } else if (isMap(value)) {
3827 value.forEach(function(subValue, key) {
3828 result.set(key, baseClone(subValue, bitmask, customizer, key, value, stack));
3832 var keysFunc = isFull
3833 ? (isFlat ? getAllKeysIn : getAllKeys)
3834 : (isFlat ? keysIn : keys);
3836 var props = isArr ? undefined : keysFunc(value);
3837 arrayEach(props || value, function(subValue, key) {
3840 subValue = value[key];
3842 // Recursively populate clone (susceptible to call stack limits).
3843 assignValue(result, key, baseClone(subValue, bitmask, customizer, key, value, stack));
3849 * The base implementation of `_.conforms` which doesn't clone `source`.
3852 * @param {Object} source The object of property predicates to conform to.
3853 * @returns {Function} Returns the new spec function.
3855 function baseConforms(source) {
3856 var props = keys(source);
3857 return function(object) {
3858 return baseConformsTo(object, source, props);
3863 * The base implementation of `_.conformsTo` which accepts `props` to check.
3866 * @param {Object} object The object to inspect.
3867 * @param {Object} source The object of property predicates to conform to.
3868 * @returns {boolean} Returns `true` if `object` conforms, else `false`.
3870 function baseConformsTo(object, source, props) {
3871 var length = props.length;
3872 if (object == null) {
3875 object = Object(object);
3877 var key = props[length],
3878 predicate = source[key],
3879 value = object[key];
3881 if ((value === undefined && !(key in object)) || !predicate(value)) {
3889 * The base implementation of `_.delay` and `_.defer` which accepts `args`
3890 * to provide to `func`.
3893 * @param {Function} func The function to delay.
3894 * @param {number} wait The number of milliseconds to delay invocation.
3895 * @param {Array} args The arguments to provide to `func`.
3896 * @returns {number|Object} Returns the timer id or timeout object.
3898 function baseDelay(func, wait, args) {
3899 if (typeof func != 'function') {
3900 throw new TypeError(FUNC_ERROR_TEXT);
3902 return setTimeout(function() { func.apply(undefined, args); }, wait);
3906 * The base implementation of methods like `_.difference` without support
3907 * for excluding multiple arrays or iteratee shorthands.
3910 * @param {Array} array The array to inspect.
3911 * @param {Array} values The values to exclude.
3912 * @param {Function} [iteratee] The iteratee invoked per element.
3913 * @param {Function} [comparator] The comparator invoked per element.
3914 * @returns {Array} Returns the new array of filtered values.
3916 function baseDifference(array, values, iteratee, comparator) {
3918 includes = arrayIncludes,
3920 length = array.length,
3922 valuesLength = values.length;
3928 values = arrayMap(values, baseUnary(iteratee));
3931 includes = arrayIncludesWith;
3934 else if (values.length >= LARGE_ARRAY_SIZE) {
3935 includes = cacheHas;
3937 values = new SetCache(values);
3940 while (++index < length) {
3941 var value = array[index],
3942 computed = iteratee == null ? value : iteratee(value);
3944 value = (comparator || value !== 0) ? value : 0;
3945 if (isCommon && computed === computed) {
3946 var valuesIndex = valuesLength;
3947 while (valuesIndex--) {
3948 if (values[valuesIndex] === computed) {
3954 else if (!includes(values, computed, comparator)) {
3962 * The base implementation of `_.forEach` without support for iteratee shorthands.
3965 * @param {Array|Object} collection The collection to iterate over.
3966 * @param {Function} iteratee The function invoked per iteration.
3967 * @returns {Array|Object} Returns `collection`.
3969 var baseEach = createBaseEach(baseForOwn);
3972 * The base implementation of `_.forEachRight` without support for iteratee shorthands.
3975 * @param {Array|Object} collection The collection to iterate over.
3976 * @param {Function} iteratee The function invoked per iteration.
3977 * @returns {Array|Object} Returns `collection`.
3979 var baseEachRight = createBaseEach(baseForOwnRight, true);
3982 * The base implementation of `_.every` without support for iteratee shorthands.
3985 * @param {Array|Object} collection The collection to iterate over.
3986 * @param {Function} predicate The function invoked per iteration.
3987 * @returns {boolean} Returns `true` if all elements pass the predicate check,
3990 function baseEvery(collection, predicate) {
3992 baseEach(collection, function(value, index, collection) {
3993 result = !!predicate(value, index, collection);
4000 * The base implementation of methods like `_.max` and `_.min` which accepts a
4001 * `comparator` to determine the extremum value.
4004 * @param {Array} array The array to iterate over.
4005 * @param {Function} iteratee The iteratee invoked per iteration.
4006 * @param {Function} comparator The comparator used to compare values.
4007 * @returns {*} Returns the extremum value.
4009 function baseExtremum(array, iteratee, comparator) {
4011 length = array.length;
4013 while (++index < length) {
4014 var value = array[index],
4015 current = iteratee(value);
4017 if (current != null && (computed === undefined
4018 ? (current === current && !isSymbol(current))
4019 : comparator(current, computed)
4021 var computed = current,
4029 * The base implementation of `_.fill` without an iteratee call guard.
4032 * @param {Array} array The array to fill.
4033 * @param {*} value The value to fill `array` with.
4034 * @param {number} [start=0] The start position.
4035 * @param {number} [end=array.length] The end position.
4036 * @returns {Array} Returns `array`.
4038 function baseFill(array, value, start, end) {
4039 var length = array.length;
4041 start = toInteger(start);
4043 start = -start > length ? 0 : (length + start);
4045 end = (end === undefined || end > length) ? length : toInteger(end);
4049 end = start > end ? 0 : toLength(end);
4050 while (start < end) {
4051 array[start++] = value;
4057 * The base implementation of `_.filter` without support for iteratee shorthands.
4060 * @param {Array|Object} collection The collection to iterate over.
4061 * @param {Function} predicate The function invoked per iteration.
4062 * @returns {Array} Returns the new filtered array.
4064 function baseFilter(collection, predicate) {
4066 baseEach(collection, function(value, index, collection) {
4067 if (predicate(value, index, collection)) {
4075 * The base implementation of `_.flatten` with support for restricting flattening.
4078 * @param {Array} array The array to flatten.
4079 * @param {number} depth The maximum recursion depth.
4080 * @param {boolean} [predicate=isFlattenable] The function invoked per iteration.
4081 * @param {boolean} [isStrict] Restrict to values that pass `predicate` checks.
4082 * @param {Array} [result=[]] The initial result value.
4083 * @returns {Array} Returns the new flattened array.
4085 function baseFlatten(array, depth, predicate, isStrict, result) {
4087 length = array.length;
4089 predicate || (predicate = isFlattenable);
4090 result || (result = []);
4092 while (++index < length) {
4093 var value = array[index];
4094 if (depth > 0 && predicate(value)) {
4096 // Recursively flatten arrays (susceptible to call stack limits).
4097 baseFlatten(value, depth - 1, predicate, isStrict, result);
4099 arrayPush(result, value);
4101 } else if (!isStrict) {
4102 result[result.length] = value;
4109 * The base implementation of `baseForOwn` which iterates over `object`
4110 * properties returned by `keysFunc` and invokes `iteratee` for each property.
4111 * Iteratee functions may exit iteration early by explicitly returning `false`.
4114 * @param {Object} object The object to iterate over.
4115 * @param {Function} iteratee The function invoked per iteration.
4116 * @param {Function} keysFunc The function to get the keys of `object`.
4117 * @returns {Object} Returns `object`.
4119 var baseFor = createBaseFor();
4122 * This function is like `baseFor` except that it iterates over properties
4123 * in the opposite order.
4126 * @param {Object} object The object to iterate over.
4127 * @param {Function} iteratee The function invoked per iteration.
4128 * @param {Function} keysFunc The function to get the keys of `object`.
4129 * @returns {Object} Returns `object`.
4131 var baseForRight = createBaseFor(true);
4134 * The base implementation of `_.forOwn` without support for iteratee shorthands.
4137 * @param {Object} object The object to iterate over.
4138 * @param {Function} iteratee The function invoked per iteration.
4139 * @returns {Object} Returns `object`.
4141 function baseForOwn(object, iteratee) {
4142 return object && baseFor(object, iteratee, keys);
4146 * The base implementation of `_.forOwnRight` without support for iteratee shorthands.
4149 * @param {Object} object The object to iterate over.
4150 * @param {Function} iteratee The function invoked per iteration.
4151 * @returns {Object} Returns `object`.
4153 function baseForOwnRight(object, iteratee) {
4154 return object && baseForRight(object, iteratee, keys);
4158 * The base implementation of `_.functions` which creates an array of
4159 * `object` function property names filtered from `props`.
4162 * @param {Object} object The object to inspect.
4163 * @param {Array} props The property names to filter.
4164 * @returns {Array} Returns the function names.
4166 function baseFunctions(object, props) {
4167 return arrayFilter(props, function(key) {
4168 return isFunction(object[key]);
4173 * The base implementation of `_.get` without support for default values.
4176 * @param {Object} object The object to query.
4177 * @param {Array|string} path The path of the property to get.
4178 * @returns {*} Returns the resolved value.
4180 function baseGet(object, path) {
4181 path = castPath(path, object);
4184 length = path.length;
4186 while (object != null && index < length) {
4187 object = object[toKey(path[index++])];
4189 return (index && index == length) ? object : undefined;
4193 * The base implementation of `getAllKeys` and `getAllKeysIn` which uses
4194 * `keysFunc` and `symbolsFunc` to get the enumerable property names and
4195 * symbols of `object`.
4198 * @param {Object} object The object to query.
4199 * @param {Function} keysFunc The function to get the keys of `object`.
4200 * @param {Function} symbolsFunc The function to get the symbols of `object`.
4201 * @returns {Array} Returns the array of property names and symbols.
4203 function baseGetAllKeys(object, keysFunc, symbolsFunc) {
4204 var result = keysFunc(object);
4205 return isArray(object) ? result : arrayPush(result, symbolsFunc(object));
4209 * The base implementation of `getTag` without fallbacks for buggy environments.
4212 * @param {*} value The value to query.
4213 * @returns {string} Returns the `toStringTag`.
4215 function baseGetTag(value) {
4216 if (value == null) {
4217 return value === undefined ? undefinedTag : nullTag;
4219 return (symToStringTag && symToStringTag in Object(value))
4221 : objectToString(value);
4225 * The base implementation of `_.gt` which doesn't coerce arguments.
4228 * @param {*} value The value to compare.
4229 * @param {*} other The other value to compare.
4230 * @returns {boolean} Returns `true` if `value` is greater than `other`,
4233 function baseGt(value, other) {
4234 return value > other;
4238 * The base implementation of `_.has` without support for deep paths.
4241 * @param {Object} [object] The object to query.
4242 * @param {Array|string} key The key to check.
4243 * @returns {boolean} Returns `true` if `key` exists, else `false`.
4245 function baseHas(object, key) {
4246 return object != null && hasOwnProperty.call(object, key);
4250 * The base implementation of `_.hasIn` without support for deep paths.
4253 * @param {Object} [object] The object to query.
4254 * @param {Array|string} key The key to check.
4255 * @returns {boolean} Returns `true` if `key` exists, else `false`.
4257 function baseHasIn(object, key) {
4258 return object != null && key in Object(object);
4262 * The base implementation of `_.inRange` which doesn't coerce arguments.
4265 * @param {number} number The number to check.
4266 * @param {number} start The start of the range.
4267 * @param {number} end The end of the range.
4268 * @returns {boolean} Returns `true` if `number` is in the range, else `false`.
4270 function baseInRange(number, start, end) {
4271 return number >= nativeMin(start, end) && number < nativeMax(start, end);
4275 * The base implementation of methods like `_.intersection`, without support
4276 * for iteratee shorthands, that accepts an array of arrays to inspect.
4279 * @param {Array} arrays The arrays to inspect.
4280 * @param {Function} [iteratee] The iteratee invoked per element.
4281 * @param {Function} [comparator] The comparator invoked per element.
4282 * @returns {Array} Returns the new array of shared values.
4284 function baseIntersection(arrays, iteratee, comparator) {
4285 var includes = comparator ? arrayIncludesWith : arrayIncludes,
4286 length = arrays[0].length,
4287 othLength = arrays.length,
4288 othIndex = othLength,
4289 caches = Array(othLength),
4290 maxLength = Infinity,
4293 while (othIndex--) {
4294 var array = arrays[othIndex];
4295 if (othIndex && iteratee) {
4296 array = arrayMap(array, baseUnary(iteratee));
4298 maxLength = nativeMin(array.length, maxLength);
4299 caches[othIndex] = !comparator && (iteratee || (length >= 120 && array.length >= 120))
4300 ? new SetCache(othIndex && array)
4309 while (++index < length && result.length < maxLength) {
4310 var value = array[index],
4311 computed = iteratee ? iteratee(value) : value;
4313 value = (comparator || value !== 0) ? value : 0;
4315 ? cacheHas(seen, computed)
4316 : includes(result, computed, comparator)
4318 othIndex = othLength;
4319 while (--othIndex) {
4320 var cache = caches[othIndex];
4322 ? cacheHas(cache, computed)
4323 : includes(arrays[othIndex], computed, comparator))
4329 seen.push(computed);
4338 * The base implementation of `_.invert` and `_.invertBy` which inverts
4339 * `object` with values transformed by `iteratee` and set by `setter`.
4342 * @param {Object} object The object to iterate over.
4343 * @param {Function} setter The function to set `accumulator` values.
4344 * @param {Function} iteratee The iteratee to transform values.
4345 * @param {Object} accumulator The initial inverted object.
4346 * @returns {Function} Returns `accumulator`.
4348 function baseInverter(object, setter, iteratee, accumulator) {
4349 baseForOwn(object, function(value, key, object) {
4350 setter(accumulator, iteratee(value), key, object);
4356 * The base implementation of `_.invoke` without support for individual
4360 * @param {Object} object The object to query.
4361 * @param {Array|string} path The path of the method to invoke.
4362 * @param {Array} args The arguments to invoke the method with.
4363 * @returns {*} Returns the result of the invoked method.
4365 function baseInvoke(object, path, args) {
4366 path = castPath(path, object);
4367 object = parent(object, path);
4368 var func = object == null ? object : object[toKey(last(path))];
4369 return func == null ? undefined : apply(func, object, args);
4373 * The base implementation of `_.isArguments`.
4376 * @param {*} value The value to check.
4377 * @returns {boolean} Returns `true` if `value` is an `arguments` object,
4379 function baseIsArguments(value) {
4380 return isObjectLike(value) && baseGetTag(value) == argsTag;
4384 * The base implementation of `_.isArrayBuffer` without Node.js optimizations.
4387 * @param {*} value The value to check.
4388 * @returns {boolean} Returns `true` if `value` is an array buffer, else `false`.
4390 function baseIsArrayBuffer(value) {
4391 return isObjectLike(value) && baseGetTag(value) == arrayBufferTag;
4395 * The base implementation of `_.isDate` without Node.js optimizations.
4398 * @param {*} value The value to check.
4399 * @returns {boolean} Returns `true` if `value` is a date object, else `false`.
4401 function baseIsDate(value) {
4402 return isObjectLike(value) && baseGetTag(value) == dateTag;
4406 * The base implementation of `_.isEqual` which supports partial comparisons
4407 * and tracks traversed objects.
4410 * @param {*} value The value to compare.
4411 * @param {*} other The other value to compare.
4412 * @param {boolean} bitmask The bitmask flags.
4413 * 1 - Unordered comparison
4414 * 2 - Partial comparison
4415 * @param {Function} [customizer] The function to customize comparisons.
4416 * @param {Object} [stack] Tracks traversed `value` and `other` objects.
4417 * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
4419 function baseIsEqual(value, other, bitmask, customizer, stack) {
4420 if (value === other) {
4423 if (value == null || other == null || (!isObjectLike(value) && !isObjectLike(other))) {
4424 return value !== value && other !== other;
4426 return baseIsEqualDeep(value, other, bitmask, customizer, baseIsEqual, stack);
4430 * A specialized version of `baseIsEqual` for arrays and objects which performs
4431 * deep comparisons and tracks traversed objects enabling objects with circular
4432 * references to be compared.
4435 * @param {Object} object The object to compare.
4436 * @param {Object} other The other object to compare.
4437 * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.
4438 * @param {Function} customizer The function to customize comparisons.
4439 * @param {Function} equalFunc The function to determine equivalents of values.
4440 * @param {Object} [stack] Tracks traversed `object` and `other` objects.
4441 * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
4443 function baseIsEqualDeep(object, other, bitmask, customizer, equalFunc, stack) {
4444 var objIsArr = isArray(object),
4445 othIsArr = isArray(other),
4446 objTag = objIsArr ? arrayTag : getTag(object),
4447 othTag = othIsArr ? arrayTag : getTag(other);
4449 objTag = objTag == argsTag ? objectTag : objTag;
4450 othTag = othTag == argsTag ? objectTag : othTag;
4452 var objIsObj = objTag == objectTag,
4453 othIsObj = othTag == objectTag,
4454 isSameTag = objTag == othTag;
4456 if (isSameTag && isBuffer(object)) {
4457 if (!isBuffer(other)) {
4463 if (isSameTag && !objIsObj) {
4464 stack || (stack = new Stack);
4465 return (objIsArr || isTypedArray(object))
4466 ? equalArrays(object, other, bitmask, customizer, equalFunc, stack)
4467 : equalByTag(object, other, objTag, bitmask, customizer, equalFunc, stack);
4469 if (!(bitmask & COMPARE_PARTIAL_FLAG)) {
4470 var objIsWrapped = objIsObj && hasOwnProperty.call(object, '__wrapped__'),
4471 othIsWrapped = othIsObj && hasOwnProperty.call(other, '__wrapped__');
4473 if (objIsWrapped || othIsWrapped) {
4474 var objUnwrapped = objIsWrapped ? object.value() : object,
4475 othUnwrapped = othIsWrapped ? other.value() : other;
4477 stack || (stack = new Stack);
4478 return equalFunc(objUnwrapped, othUnwrapped, bitmask, customizer, stack);
4484 stack || (stack = new Stack);
4485 return equalObjects(object, other, bitmask, customizer, equalFunc, stack);
4489 * The base implementation of `_.isMap` without Node.js optimizations.
4492 * @param {*} value The value to check.
4493 * @returns {boolean} Returns `true` if `value` is a map, else `false`.
4495 function baseIsMap(value) {
4496 return isObjectLike(value) && getTag(value) == mapTag;
4500 * The base implementation of `_.isMatch` without support for iteratee shorthands.
4503 * @param {Object} object The object to inspect.
4504 * @param {Object} source The object of property values to match.
4505 * @param {Array} matchData The property names, values, and compare flags to match.
4506 * @param {Function} [customizer] The function to customize comparisons.
4507 * @returns {boolean} Returns `true` if `object` is a match, else `false`.
4509 function baseIsMatch(object, source, matchData, customizer) {
4510 var index = matchData.length,
4512 noCustomizer = !customizer;
4514 if (object == null) {
4517 object = Object(object);
4519 var data = matchData[index];
4520 if ((noCustomizer && data[2])
4521 ? data[1] !== object[data[0]]
4522 : !(data[0] in object)
4527 while (++index < length) {
4528 data = matchData[index];
4530 objValue = object[key],
4533 if (noCustomizer && data[2]) {
4534 if (objValue === undefined && !(key in object)) {
4538 var stack = new Stack;
4540 var result = customizer(objValue, srcValue, key, object, source, stack);
4542 if (!(result === undefined
4543 ? baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG | COMPARE_UNORDERED_FLAG, customizer, stack)
4554 * The base implementation of `_.isNative` without bad shim checks.
4557 * @param {*} value The value to check.
4558 * @returns {boolean} Returns `true` if `value` is a native function,
4561 function baseIsNative(value) {
4562 if (!isObject(value) || isMasked(value)) {
4565 var pattern = isFunction(value) ? reIsNative : reIsHostCtor;
4566 return pattern.test(toSource(value));
4570 * The base implementation of `_.isRegExp` without Node.js optimizations.
4573 * @param {*} value The value to check.
4574 * @returns {boolean} Returns `true` if `value` is a regexp, else `false`.
4576 function baseIsRegExp(value) {
4577 return isObjectLike(value) && baseGetTag(value) == regexpTag;
4581 * The base implementation of `_.isSet` without Node.js optimizations.
4584 * @param {*} value The value to check.
4585 * @returns {boolean} Returns `true` if `value` is a set, else `false`.
4587 function baseIsSet(value) {
4588 return isObjectLike(value) && getTag(value) == setTag;
4592 * The base implementation of `_.isTypedArray` without Node.js optimizations.
4595 * @param {*} value The value to check.
4596 * @returns {boolean} Returns `true` if `value` is a typed array, else `false`.
4598 function baseIsTypedArray(value) {
4599 return isObjectLike(value) &&
4600 isLength(value.length) && !!typedArrayTags[baseGetTag(value)];
4604 * The base implementation of `_.iteratee`.
4607 * @param {*} [value=_.identity] The value to convert to an iteratee.
4608 * @returns {Function} Returns the iteratee.
4610 function baseIteratee(value) {
4611 // Don't store the `typeof` result in a variable to avoid a JIT bug in Safari 9.
4612 // See https://bugs.webkit.org/show_bug.cgi?id=156034 for more details.
4613 if (typeof value == 'function') {
4616 if (value == null) {
4619 if (typeof value == 'object') {
4620 return isArray(value)
4621 ? baseMatchesProperty(value[0], value[1])
4622 : baseMatches(value);
4624 return property(value);
4628 * The base implementation of `_.keys` which doesn't treat sparse arrays as dense.
4631 * @param {Object} object The object to query.
4632 * @returns {Array} Returns the array of property names.
4634 function baseKeys(object) {
4635 if (!isPrototype(object)) {
4636 return nativeKeys(object);
4639 for (var key in Object(object)) {
4640 if (hasOwnProperty.call(object, key) && key != 'constructor') {
4648 * The base implementation of `_.keysIn` which doesn't treat sparse arrays as dense.
4651 * @param {Object} object The object to query.
4652 * @returns {Array} Returns the array of property names.
4654 function baseKeysIn(object) {
4655 if (!isObject(object)) {
4656 return nativeKeysIn(object);
4658 var isProto = isPrototype(object),
4661 for (var key in object) {
4662 if (!(key == 'constructor' && (isProto || !hasOwnProperty.call(object, key)))) {
4670 * The base implementation of `_.lt` which doesn't coerce arguments.
4673 * @param {*} value The value to compare.
4674 * @param {*} other The other value to compare.
4675 * @returns {boolean} Returns `true` if `value` is less than `other`,
4678 function baseLt(value, other) {
4679 return value < other;
4683 * The base implementation of `_.map` without support for iteratee shorthands.
4686 * @param {Array|Object} collection The collection to iterate over.
4687 * @param {Function} iteratee The function invoked per iteration.
4688 * @returns {Array} Returns the new mapped array.
4690 function baseMap(collection, iteratee) {
4692 result = isArrayLike(collection) ? Array(collection.length) : [];
4694 baseEach(collection, function(value, key, collection) {
4695 result[++index] = iteratee(value, key, collection);
4701 * The base implementation of `_.matches` which doesn't clone `source`.
4704 * @param {Object} source The object of property values to match.
4705 * @returns {Function} Returns the new spec function.
4707 function baseMatches(source) {
4708 var matchData = getMatchData(source);
4709 if (matchData.length == 1 && matchData[0][2]) {
4710 return matchesStrictComparable(matchData[0][0], matchData[0][1]);
4712 return function(object) {
4713 return object === source || baseIsMatch(object, source, matchData);
4718 * The base implementation of `_.matchesProperty` which doesn't clone `srcValue`.
4721 * @param {string} path The path of the property to get.
4722 * @param {*} srcValue The value to match.
4723 * @returns {Function} Returns the new spec function.
4725 function baseMatchesProperty(path, srcValue) {
4726 if (isKey(path) && isStrictComparable(srcValue)) {
4727 return matchesStrictComparable(toKey(path), srcValue);
4729 return function(object) {
4730 var objValue = get(object, path);
4731 return (objValue === undefined && objValue === srcValue)
4732 ? hasIn(object, path)
4733 : baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG | COMPARE_UNORDERED_FLAG);
4738 * The base implementation of `_.merge` without support for multiple sources.
4741 * @param {Object} object The destination object.
4742 * @param {Object} source The source object.
4743 * @param {number} srcIndex The index of `source`.
4744 * @param {Function} [customizer] The function to customize merged values.
4745 * @param {Object} [stack] Tracks traversed source values and their merged
4748 function baseMerge(object, source, srcIndex, customizer, stack) {
4749 if (object === source) {
4752 baseFor(source, function(srcValue, key) {
4753 stack || (stack = new Stack);
4754 if (isObject(srcValue)) {
4755 baseMergeDeep(object, source, key, srcIndex, baseMerge, customizer, stack);
4758 var newValue = customizer
4759 ? customizer(safeGet(object, key), srcValue, (key + ''), object, source, stack)
4762 if (newValue === undefined) {
4763 newValue = srcValue;
4765 assignMergeValue(object, key, newValue);
4771 * A specialized version of `baseMerge` for arrays and objects which performs
4772 * deep merges and tracks traversed objects enabling objects with circular
4773 * references to be merged.
4776 * @param {Object} object The destination object.
4777 * @param {Object} source The source object.
4778 * @param {string} key The key of the value to merge.
4779 * @param {number} srcIndex The index of `source`.
4780 * @param {Function} mergeFunc The function to merge values.
4781 * @param {Function} [customizer] The function to customize assigned values.
4782 * @param {Object} [stack] Tracks traversed source values and their merged
4785 function baseMergeDeep(object, source, key, srcIndex, mergeFunc, customizer, stack) {
4786 var objValue = safeGet(object, key),
4787 srcValue = safeGet(source, key),
4788 stacked = stack.get(srcValue);
4791 assignMergeValue(object, key, stacked);
4794 var newValue = customizer
4795 ? customizer(objValue, srcValue, (key + ''), object, source, stack)
4798 var isCommon = newValue === undefined;
4801 var isArr = isArray(srcValue),
4802 isBuff = !isArr && isBuffer(srcValue),
4803 isTyped = !isArr && !isBuff && isTypedArray(srcValue);
4805 newValue = srcValue;
4806 if (isArr || isBuff || isTyped) {
4807 if (isArray(objValue)) {
4808 newValue = objValue;
4810 else if (isArrayLikeObject(objValue)) {
4811 newValue = copyArray(objValue);
4815 newValue = cloneBuffer(srcValue, true);
4819 newValue = cloneTypedArray(srcValue, true);
4825 else if (isPlainObject(srcValue) || isArguments(srcValue)) {
4826 newValue = objValue;
4827 if (isArguments(objValue)) {
4828 newValue = toPlainObject(objValue);
4830 else if (!isObject(objValue) || isFunction(objValue)) {
4831 newValue = initCloneObject(srcValue);
4839 // Recursively merge objects and arrays (susceptible to call stack limits).
4840 stack.set(srcValue, newValue);
4841 mergeFunc(newValue, srcValue, srcIndex, customizer, stack);
4842 stack['delete'](srcValue);
4844 assignMergeValue(object, key, newValue);
4848 * The base implementation of `_.nth` which doesn't coerce arguments.
4851 * @param {Array} array The array to query.
4852 * @param {number} n The index of the element to return.
4853 * @returns {*} Returns the nth element of `array`.
4855 function baseNth(array, n) {
4856 var length = array.length;
4860 n += n < 0 ? length : 0;
4861 return isIndex(n, length) ? array[n] : undefined;
4865 * The base implementation of `_.orderBy` without param guards.
4868 * @param {Array|Object} collection The collection to iterate over.
4869 * @param {Function[]|Object[]|string[]} iteratees The iteratees to sort by.
4870 * @param {string[]} orders The sort orders of `iteratees`.
4871 * @returns {Array} Returns the new sorted array.
4873 function baseOrderBy(collection, iteratees, orders) {
4874 if (iteratees.length) {
4875 iteratees = arrayMap(iteratees, function(iteratee) {
4876 if (isArray(iteratee)) {
4877 return function(value) {
4878 return baseGet(value, iteratee.length === 1 ? iteratee[0] : iteratee);
4884 iteratees = [identity];
4888 iteratees = arrayMap(iteratees, baseUnary(getIteratee()));
4890 var result = baseMap(collection, function(value, key, collection) {
4891 var criteria = arrayMap(iteratees, function(iteratee) {
4892 return iteratee(value);
4894 return { 'criteria': criteria, 'index': ++index, 'value': value };
4897 return baseSortBy(result, function(object, other) {
4898 return compareMultiple(object, other, orders);
4903 * The base implementation of `_.pick` without support for individual
4904 * property identifiers.
4907 * @param {Object} object The source object.
4908 * @param {string[]} paths The property paths to pick.
4909 * @returns {Object} Returns the new object.
4911 function basePick(object, paths) {
4912 return basePickBy(object, paths, function(value, path) {
4913 return hasIn(object, path);
4918 * The base implementation of `_.pickBy` without support for iteratee shorthands.
4921 * @param {Object} object The source object.
4922 * @param {string[]} paths The property paths to pick.
4923 * @param {Function} predicate The function invoked per property.
4924 * @returns {Object} Returns the new object.
4926 function basePickBy(object, paths, predicate) {
4928 length = paths.length,
4931 while (++index < length) {
4932 var path = paths[index],
4933 value = baseGet(object, path);
4935 if (predicate(value, path)) {
4936 baseSet(result, castPath(path, object), value);
4943 * A specialized version of `baseProperty` which supports deep paths.
4946 * @param {Array|string} path The path of the property to get.
4947 * @returns {Function} Returns the new accessor function.
4949 function basePropertyDeep(path) {
4950 return function(object) {
4951 return baseGet(object, path);
4956 * The base implementation of `_.pullAllBy` without support for iteratee
4960 * @param {Array} array The array to modify.
4961 * @param {Array} values The values to remove.
4962 * @param {Function} [iteratee] The iteratee invoked per element.
4963 * @param {Function} [comparator] The comparator invoked per element.
4964 * @returns {Array} Returns `array`.
4966 function basePullAll(array, values, iteratee, comparator) {
4967 var indexOf = comparator ? baseIndexOfWith : baseIndexOf,
4969 length = values.length,
4972 if (array === values) {
4973 values = copyArray(values);
4976 seen = arrayMap(array, baseUnary(iteratee));
4978 while (++index < length) {
4980 value = values[index],
4981 computed = iteratee ? iteratee(value) : value;
4983 while ((fromIndex = indexOf(seen, computed, fromIndex, comparator)) > -1) {
4984 if (seen !== array) {
4985 splice.call(seen, fromIndex, 1);
4987 splice.call(array, fromIndex, 1);
4994 * The base implementation of `_.pullAt` without support for individual
4995 * indexes or capturing the removed elements.
4998 * @param {Array} array The array to modify.
4999 * @param {number[]} indexes The indexes of elements to remove.
5000 * @returns {Array} Returns `array`.
5002 function basePullAt(array, indexes) {
5003 var length = array ? indexes.length : 0,
5004 lastIndex = length - 1;
5007 var index = indexes[length];
5008 if (length == lastIndex || index !== previous) {
5009 var previous = index;
5010 if (isIndex(index)) {
5011 splice.call(array, index, 1);
5013 baseUnset(array, index);
5021 * The base implementation of `_.random` without support for returning
5022 * floating-point numbers.
5025 * @param {number} lower The lower bound.
5026 * @param {number} upper The upper bound.
5027 * @returns {number} Returns the random number.
5029 function baseRandom(lower, upper) {
5030 return lower + nativeFloor(nativeRandom() * (upper - lower + 1));
5034 * The base implementation of `_.range` and `_.rangeRight` which doesn't
5038 * @param {number} start The start of the range.
5039 * @param {number} end The end of the range.
5040 * @param {number} step The value to increment or decrement by.
5041 * @param {boolean} [fromRight] Specify iterating from right to left.
5042 * @returns {Array} Returns the range of numbers.
5044 function baseRange(start, end, step, fromRight) {
5046 length = nativeMax(nativeCeil((end - start) / (step || 1)), 0),
5047 result = Array(length);
5050 result[fromRight ? length : ++index] = start;
5057 * The base implementation of `_.repeat` which doesn't coerce arguments.
5060 * @param {string} string The string to repeat.
5061 * @param {number} n The number of times to repeat the string.
5062 * @returns {string} Returns the repeated string.
5064 function baseRepeat(string, n) {
5066 if (!string || n < 1 || n > MAX_SAFE_INTEGER) {
5069 // Leverage the exponentiation by squaring algorithm for a faster repeat.
5070 // See https://en.wikipedia.org/wiki/Exponentiation_by_squaring for more details.
5075 n = nativeFloor(n / 2);
5085 * The base implementation of `_.rest` which doesn't validate or coerce arguments.
5088 * @param {Function} func The function to apply a rest parameter to.
5089 * @param {number} [start=func.length-1] The start position of the rest parameter.
5090 * @returns {Function} Returns the new function.
5092 function baseRest(func, start) {
5093 return setToString(overRest(func, start, identity), func + '');
5097 * The base implementation of `_.sample`.
5100 * @param {Array|Object} collection The collection to sample.
5101 * @returns {*} Returns the random element.
5103 function baseSample(collection) {
5104 return arraySample(values(collection));
5108 * The base implementation of `_.sampleSize` without param guards.
5111 * @param {Array|Object} collection The collection to sample.
5112 * @param {number} n The number of elements to sample.
5113 * @returns {Array} Returns the random elements.
5115 function baseSampleSize(collection, n) {
5116 var array = values(collection);
5117 return shuffleSelf(array, baseClamp(n, 0, array.length));
5121 * The base implementation of `_.set`.
5124 * @param {Object} object The object to modify.
5125 * @param {Array|string} path The path of the property to set.
5126 * @param {*} value The value to set.
5127 * @param {Function} [customizer] The function to customize path creation.
5128 * @returns {Object} Returns `object`.
5130 function baseSet(object, path, value, customizer) {
5131 if (!isObject(object)) {
5134 path = castPath(path, object);
5137 length = path.length,
5138 lastIndex = length - 1,
5141 while (nested != null && ++index < length) {
5142 var key = toKey(path[index]),
5145 if (key === '__proto__' || key === 'constructor' || key === 'prototype') {
5149 if (index != lastIndex) {
5150 var objValue = nested[key];
5151 newValue = customizer ? customizer(objValue, key, nested) : undefined;
5152 if (newValue === undefined) {
5153 newValue = isObject(objValue)
5155 : (isIndex(path[index + 1]) ? [] : {});
5158 assignValue(nested, key, newValue);
5159 nested = nested[key];
5165 * The base implementation of `setData` without support for hot loop shorting.
5168 * @param {Function} func The function to associate metadata with.
5169 * @param {*} data The metadata.
5170 * @returns {Function} Returns `func`.
5172 var baseSetData = !metaMap ? identity : function(func, data) {
5173 metaMap.set(func, data);
5178 * The base implementation of `setToString` without support for hot loop shorting.
5181 * @param {Function} func The function to modify.
5182 * @param {Function} string The `toString` result.
5183 * @returns {Function} Returns `func`.
5185 var baseSetToString = !defineProperty ? identity : function(func, string) {
5186 return defineProperty(func, 'toString', {
5187 'configurable': true,
5188 'enumerable': false,
5189 'value': constant(string),
5195 * The base implementation of `_.shuffle`.
5198 * @param {Array|Object} collection The collection to shuffle.
5199 * @returns {Array} Returns the new shuffled array.
5201 function baseShuffle(collection) {
5202 return shuffleSelf(values(collection));
5206 * The base implementation of `_.slice` without an iteratee call guard.
5209 * @param {Array} array The array to slice.
5210 * @param {number} [start=0] The start position.
5211 * @param {number} [end=array.length] The end position.
5212 * @returns {Array} Returns the slice of `array`.
5214 function baseSlice(array, start, end) {
5216 length = array.length;
5219 start = -start > length ? 0 : (length + start);
5221 end = end > length ? length : end;
5225 length = start > end ? 0 : ((end - start) >>> 0);
5228 var result = Array(length);
5229 while (++index < length) {
5230 result[index] = array[index + start];
5236 * The base implementation of `_.some` without support for iteratee shorthands.
5239 * @param {Array|Object} collection The collection to iterate over.
5240 * @param {Function} predicate The function invoked per iteration.
5241 * @returns {boolean} Returns `true` if any element passes the predicate check,
5244 function baseSome(collection, predicate) {
5247 baseEach(collection, function(value, index, collection) {
5248 result = predicate(value, index, collection);
5255 * The base implementation of `_.sortedIndex` and `_.sortedLastIndex` which
5256 * performs a binary search of `array` to determine the index at which `value`
5257 * should be inserted into `array` in order to maintain its sort order.
5260 * @param {Array} array The sorted array to inspect.
5261 * @param {*} value The value to evaluate.
5262 * @param {boolean} [retHighest] Specify returning the highest qualified index.
5263 * @returns {number} Returns the index at which `value` should be inserted
5266 function baseSortedIndex(array, value, retHighest) {
5268 high = array == null ? low : array.length;
5270 if (typeof value == 'number' && value === value && high <= HALF_MAX_ARRAY_LENGTH) {
5271 while (low < high) {
5272 var mid = (low + high) >>> 1,
5273 computed = array[mid];
5275 if (computed !== null && !isSymbol(computed) &&
5276 (retHighest ? (computed <= value) : (computed < value))) {
5284 return baseSortedIndexBy(array, value, identity, retHighest);
5288 * The base implementation of `_.sortedIndexBy` and `_.sortedLastIndexBy`
5289 * which invokes `iteratee` for `value` and each element of `array` to compute
5290 * their sort ranking. The iteratee is invoked with one argument; (value).
5293 * @param {Array} array The sorted array to inspect.
5294 * @param {*} value The value to evaluate.
5295 * @param {Function} iteratee The iteratee invoked per element.
5296 * @param {boolean} [retHighest] Specify returning the highest qualified index.
5297 * @returns {number} Returns the index at which `value` should be inserted
5300 function baseSortedIndexBy(array, value, iteratee, retHighest) {
5302 high = array == null ? 0 : array.length;
5307 value = iteratee(value);
5308 var valIsNaN = value !== value,
5309 valIsNull = value === null,
5310 valIsSymbol = isSymbol(value),
5311 valIsUndefined = value === undefined;
5313 while (low < high) {
5314 var mid = nativeFloor((low + high) / 2),
5315 computed = iteratee(array[mid]),
5316 othIsDefined = computed !== undefined,
5317 othIsNull = computed === null,
5318 othIsReflexive = computed === computed,
5319 othIsSymbol = isSymbol(computed);
5322 var setLow = retHighest || othIsReflexive;
5323 } else if (valIsUndefined) {
5324 setLow = othIsReflexive && (retHighest || othIsDefined);
5325 } else if (valIsNull) {
5326 setLow = othIsReflexive && othIsDefined && (retHighest || !othIsNull);
5327 } else if (valIsSymbol) {
5328 setLow = othIsReflexive && othIsDefined && !othIsNull && (retHighest || !othIsSymbol);
5329 } else if (othIsNull || othIsSymbol) {
5332 setLow = retHighest ? (computed <= value) : (computed < value);
5340 return nativeMin(high, MAX_ARRAY_INDEX);
5344 * The base implementation of `_.sortedUniq` and `_.sortedUniqBy` without
5345 * support for iteratee shorthands.
5348 * @param {Array} array The array to inspect.
5349 * @param {Function} [iteratee] The iteratee invoked per element.
5350 * @returns {Array} Returns the new duplicate free array.
5352 function baseSortedUniq(array, iteratee) {
5354 length = array.length,
5358 while (++index < length) {
5359 var value = array[index],
5360 computed = iteratee ? iteratee(value) : value;
5362 if (!index || !eq(computed, seen)) {
5363 var seen = computed;
5364 result[resIndex++] = value === 0 ? 0 : value;
5371 * The base implementation of `_.toNumber` which doesn't ensure correct
5372 * conversions of binary, hexadecimal, or octal string values.
5375 * @param {*} value The value to process.
5376 * @returns {number} Returns the number.
5378 function baseToNumber(value) {
5379 if (typeof value == 'number') {
5382 if (isSymbol(value)) {
5389 * The base implementation of `_.toString` which doesn't convert nullish
5390 * values to empty strings.
5393 * @param {*} value The value to process.
5394 * @returns {string} Returns the string.
5396 function baseToString(value) {
5397 // Exit early for strings to avoid a performance hit in some environments.
5398 if (typeof value == 'string') {
5401 if (isArray(value)) {
5402 // Recursively convert values (susceptible to call stack limits).
5403 return arrayMap(value, baseToString) + '';
5405 if (isSymbol(value)) {
5406 return symbolToString ? symbolToString.call(value) : '';
5408 var result = (value + '');
5409 return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;
5413 * The base implementation of `_.uniqBy` without support for iteratee shorthands.
5416 * @param {Array} array The array to inspect.
5417 * @param {Function} [iteratee] The iteratee invoked per element.
5418 * @param {Function} [comparator] The comparator invoked per element.
5419 * @returns {Array} Returns the new duplicate free array.
5421 function baseUniq(array, iteratee, comparator) {
5423 includes = arrayIncludes,
5424 length = array.length,
5431 includes = arrayIncludesWith;
5433 else if (length >= LARGE_ARRAY_SIZE) {
5434 var set = iteratee ? null : createSet(array);
5436 return setToArray(set);
5439 includes = cacheHas;
5440 seen = new SetCache;
5443 seen = iteratee ? [] : result;
5446 while (++index < length) {
5447 var value = array[index],
5448 computed = iteratee ? iteratee(value) : value;
5450 value = (comparator || value !== 0) ? value : 0;
5451 if (isCommon && computed === computed) {
5452 var seenIndex = seen.length;
5453 while (seenIndex--) {
5454 if (seen[seenIndex] === computed) {
5459 seen.push(computed);
5463 else if (!includes(seen, computed, comparator)) {
5464 if (seen !== result) {
5465 seen.push(computed);
5474 * The base implementation of `_.unset`.
5477 * @param {Object} object The object to modify.
5478 * @param {Array|string} path The property path to unset.
5479 * @returns {boolean} Returns `true` if the property is deleted, else `false`.
5481 function baseUnset(object, path) {
5482 path = castPath(path, object);
5483 object = parent(object, path);
5484 return object == null || delete object[toKey(last(path))];
5488 * The base implementation of `_.update`.
5491 * @param {Object} object The object to modify.
5492 * @param {Array|string} path The path of the property to update.
5493 * @param {Function} updater The function to produce the updated value.
5494 * @param {Function} [customizer] The function to customize path creation.
5495 * @returns {Object} Returns `object`.
5497 function baseUpdate(object, path, updater, customizer) {
5498 return baseSet(object, path, updater(baseGet(object, path)), customizer);
5502 * The base implementation of methods like `_.dropWhile` and `_.takeWhile`
5503 * without support for iteratee shorthands.
5506 * @param {Array} array The array to query.
5507 * @param {Function} predicate The function invoked per iteration.
5508 * @param {boolean} [isDrop] Specify dropping elements instead of taking them.
5509 * @param {boolean} [fromRight] Specify iterating from right to left.
5510 * @returns {Array} Returns the slice of `array`.
5512 function baseWhile(array, predicate, isDrop, fromRight) {
5513 var length = array.length,
5514 index = fromRight ? length : -1;
5516 while ((fromRight ? index-- : ++index < length) &&
5517 predicate(array[index], index, array)) {}
5520 ? baseSlice(array, (fromRight ? 0 : index), (fromRight ? index + 1 : length))
5521 : baseSlice(array, (fromRight ? index + 1 : 0), (fromRight ? length : index));
5525 * The base implementation of `wrapperValue` which returns the result of
5526 * performing a sequence of actions on the unwrapped `value`, where each
5527 * successive action is supplied the return value of the previous.
5530 * @param {*} value The unwrapped value.
5531 * @param {Array} actions Actions to perform to resolve the unwrapped value.
5532 * @returns {*} Returns the resolved value.
5534 function baseWrapperValue(value, actions) {
5536 if (result instanceof LazyWrapper) {
5537 result = result.value();
5539 return arrayReduce(actions, function(result, action) {
5540 return action.func.apply(action.thisArg, arrayPush([result], action.args));
5545 * The base implementation of methods like `_.xor`, without support for
5546 * iteratee shorthands, that accepts an array of arrays to inspect.
5549 * @param {Array} arrays The arrays to inspect.
5550 * @param {Function} [iteratee] The iteratee invoked per element.
5551 * @param {Function} [comparator] The comparator invoked per element.
5552 * @returns {Array} Returns the new array of values.
5554 function baseXor(arrays, iteratee, comparator) {
5555 var length = arrays.length;
5557 return length ? baseUniq(arrays[0]) : [];
5560 result = Array(length);
5562 while (++index < length) {
5563 var array = arrays[index],
5566 while (++othIndex < length) {
5567 if (othIndex != index) {
5568 result[index] = baseDifference(result[index] || array, arrays[othIndex], iteratee, comparator);
5572 return baseUniq(baseFlatten(result, 1), iteratee, comparator);
5576 * This base implementation of `_.zipObject` which assigns values using `assignFunc`.
5579 * @param {Array} props The property identifiers.
5580 * @param {Array} values The property values.
5581 * @param {Function} assignFunc The function to assign values.
5582 * @returns {Object} Returns the new object.
5584 function baseZipObject(props, values, assignFunc) {
5586 length = props.length,
5587 valsLength = values.length,
5590 while (++index < length) {
5591 var value = index < valsLength ? values[index] : undefined;
5592 assignFunc(result, props[index], value);
5598 * Casts `value` to an empty array if it's not an array like object.
5601 * @param {*} value The value to inspect.
5602 * @returns {Array|Object} Returns the cast array-like object.
5604 function castArrayLikeObject(value) {
5605 return isArrayLikeObject(value) ? value : [];
5609 * Casts `value` to `identity` if it's not a function.
5612 * @param {*} value The value to inspect.
5613 * @returns {Function} Returns cast function.
5615 function castFunction(value) {
5616 return typeof value == 'function' ? value : identity;
5620 * Casts `value` to a path array if it's not one.
5623 * @param {*} value The value to inspect.
5624 * @param {Object} [object] The object to query keys on.
5625 * @returns {Array} Returns the cast property path array.
5627 function castPath(value, object) {
5628 if (isArray(value)) {
5631 return isKey(value, object) ? [value] : stringToPath(toString(value));
5635 * A `baseRest` alias which can be replaced with `identity` by module
5636 * replacement plugins.
5640 * @param {Function} func The function to apply a rest parameter to.
5641 * @returns {Function} Returns the new function.
5643 var castRest = baseRest;
5646 * Casts `array` to a slice if it's needed.
5649 * @param {Array} array The array to inspect.
5650 * @param {number} start The start position.
5651 * @param {number} [end=array.length] The end position.
5652 * @returns {Array} Returns the cast slice.
5654 function castSlice(array, start, end) {
5655 var length = array.length;
5656 end = end === undefined ? length : end;
5657 return (!start && end >= length) ? array : baseSlice(array, start, end);
5661 * A simple wrapper around the global [`clearTimeout`](https://mdn.io/clearTimeout).
5664 * @param {number|Object} id The timer id or timeout object of the timer to clear.
5666 var clearTimeout = ctxClearTimeout || function(id) {
5667 return root.clearTimeout(id);
5671 * Creates a clone of `buffer`.
5674 * @param {Buffer} buffer The buffer to clone.
5675 * @param {boolean} [isDeep] Specify a deep clone.
5676 * @returns {Buffer} Returns the cloned buffer.
5678 function cloneBuffer(buffer, isDeep) {
5680 return buffer.slice();
5682 var length = buffer.length,
5683 result = allocUnsafe ? allocUnsafe(length) : new buffer.constructor(length);
5685 buffer.copy(result);
5690 * Creates a clone of `arrayBuffer`.
5693 * @param {ArrayBuffer} arrayBuffer The array buffer to clone.
5694 * @returns {ArrayBuffer} Returns the cloned array buffer.
5696 function cloneArrayBuffer(arrayBuffer) {
5697 var result = new arrayBuffer.constructor(arrayBuffer.byteLength);
5698 new Uint8Array(result).set(new Uint8Array(arrayBuffer));
5703 * Creates a clone of `dataView`.
5706 * @param {Object} dataView The data view to clone.
5707 * @param {boolean} [isDeep] Specify a deep clone.
5708 * @returns {Object} Returns the cloned data view.
5710 function cloneDataView(dataView, isDeep) {
5711 var buffer = isDeep ? cloneArrayBuffer(dataView.buffer) : dataView.buffer;
5712 return new dataView.constructor(buffer, dataView.byteOffset, dataView.byteLength);
5716 * Creates a clone of `regexp`.
5719 * @param {Object} regexp The regexp to clone.
5720 * @returns {Object} Returns the cloned regexp.
5722 function cloneRegExp(regexp) {
5723 var result = new regexp.constructor(regexp.source, reFlags.exec(regexp));
5724 result.lastIndex = regexp.lastIndex;
5729 * Creates a clone of the `symbol` object.
5732 * @param {Object} symbol The symbol object to clone.
5733 * @returns {Object} Returns the cloned symbol object.
5735 function cloneSymbol(symbol) {
5736 return symbolValueOf ? Object(symbolValueOf.call(symbol)) : {};
5740 * Creates a clone of `typedArray`.
5743 * @param {Object} typedArray The typed array to clone.
5744 * @param {boolean} [isDeep] Specify a deep clone.
5745 * @returns {Object} Returns the cloned typed array.
5747 function cloneTypedArray(typedArray, isDeep) {
5748 var buffer = isDeep ? cloneArrayBuffer(typedArray.buffer) : typedArray.buffer;
5749 return new typedArray.constructor(buffer, typedArray.byteOffset, typedArray.length);
5753 * Compares values to sort them in ascending order.
5756 * @param {*} value The value to compare.
5757 * @param {*} other The other value to compare.
5758 * @returns {number} Returns the sort order indicator for `value`.
5760 function compareAscending(value, other) {
5761 if (value !== other) {
5762 var valIsDefined = value !== undefined,
5763 valIsNull = value === null,
5764 valIsReflexive = value === value,
5765 valIsSymbol = isSymbol(value);
5767 var othIsDefined = other !== undefined,
5768 othIsNull = other === null,
5769 othIsReflexive = other === other,
5770 othIsSymbol = isSymbol(other);
5772 if ((!othIsNull && !othIsSymbol && !valIsSymbol && value > other) ||
5773 (valIsSymbol && othIsDefined && othIsReflexive && !othIsNull && !othIsSymbol) ||
5774 (valIsNull && othIsDefined && othIsReflexive) ||
5775 (!valIsDefined && othIsReflexive) ||
5779 if ((!valIsNull && !valIsSymbol && !othIsSymbol && value < other) ||
5780 (othIsSymbol && valIsDefined && valIsReflexive && !valIsNull && !valIsSymbol) ||
5781 (othIsNull && valIsDefined && valIsReflexive) ||
5782 (!othIsDefined && valIsReflexive) ||
5791 * Used by `_.orderBy` to compare multiple properties of a value to another
5792 * and stable sort them.
5794 * If `orders` is unspecified, all values are sorted in ascending order. Otherwise,
5795 * specify an order of "desc" for descending or "asc" for ascending sort order
5796 * of corresponding values.
5799 * @param {Object} object The object to compare.
5800 * @param {Object} other The other object to compare.
5801 * @param {boolean[]|string[]} orders The order to sort by for each property.
5802 * @returns {number} Returns the sort order indicator for `object`.
5804 function compareMultiple(object, other, orders) {
5806 objCriteria = object.criteria,
5807 othCriteria = other.criteria,
5808 length = objCriteria.length,
5809 ordersLength = orders.length;
5811 while (++index < length) {
5812 var result = compareAscending(objCriteria[index], othCriteria[index]);
5814 if (index >= ordersLength) {
5817 var order = orders[index];
5818 return result * (order == 'desc' ? -1 : 1);
5821 // Fixes an `Array#sort` bug in the JS engine embedded in Adobe applications
5822 // that causes it, under certain circumstances, to provide the same value for
5823 // `object` and `other`. See https://github.com/jashkenas/underscore/pull/1247
5824 // for more details.
5826 // This also ensures a stable sort in V8 and other engines.
5827 // See https://bugs.chromium.org/p/v8/issues/detail?id=90 for more details.
5828 return object.index - other.index;
5832 * Creates an array that is the composition of partially applied arguments,
5833 * placeholders, and provided arguments into a single array of arguments.
5836 * @param {Array} args The provided arguments.
5837 * @param {Array} partials The arguments to prepend to those provided.
5838 * @param {Array} holders The `partials` placeholder indexes.
5839 * @params {boolean} [isCurried] Specify composing for a curried function.
5840 * @returns {Array} Returns the new array of composed arguments.
5842 function composeArgs(args, partials, holders, isCurried) {
5844 argsLength = args.length,
5845 holdersLength = holders.length,
5847 leftLength = partials.length,
5848 rangeLength = nativeMax(argsLength - holdersLength, 0),
5849 result = Array(leftLength + rangeLength),
5850 isUncurried = !isCurried;
5852 while (++leftIndex < leftLength) {
5853 result[leftIndex] = partials[leftIndex];
5855 while (++argsIndex < holdersLength) {
5856 if (isUncurried || argsIndex < argsLength) {
5857 result[holders[argsIndex]] = args[argsIndex];
5860 while (rangeLength--) {
5861 result[leftIndex++] = args[argsIndex++];
5867 * This function is like `composeArgs` except that the arguments composition
5868 * is tailored for `_.partialRight`.
5871 * @param {Array} args The provided arguments.
5872 * @param {Array} partials The arguments to append to those provided.
5873 * @param {Array} holders The `partials` placeholder indexes.
5874 * @params {boolean} [isCurried] Specify composing for a curried function.
5875 * @returns {Array} Returns the new array of composed arguments.
5877 function composeArgsRight(args, partials, holders, isCurried) {
5879 argsLength = args.length,
5881 holdersLength = holders.length,
5883 rightLength = partials.length,
5884 rangeLength = nativeMax(argsLength - holdersLength, 0),
5885 result = Array(rangeLength + rightLength),
5886 isUncurried = !isCurried;
5888 while (++argsIndex < rangeLength) {
5889 result[argsIndex] = args[argsIndex];
5891 var offset = argsIndex;
5892 while (++rightIndex < rightLength) {
5893 result[offset + rightIndex] = partials[rightIndex];
5895 while (++holdersIndex < holdersLength) {
5896 if (isUncurried || argsIndex < argsLength) {
5897 result[offset + holders[holdersIndex]] = args[argsIndex++];
5904 * Copies the values of `source` to `array`.
5907 * @param {Array} source The array to copy values from.
5908 * @param {Array} [array=[]] The array to copy values to.
5909 * @returns {Array} Returns `array`.
5911 function copyArray(source, array) {
5913 length = source.length;
5915 array || (array = Array(length));
5916 while (++index < length) {
5917 array[index] = source[index];
5923 * Copies properties of `source` to `object`.
5926 * @param {Object} source The object to copy properties from.
5927 * @param {Array} props The property identifiers to copy.
5928 * @param {Object} [object={}] The object to copy properties to.
5929 * @param {Function} [customizer] The function to customize copied values.
5930 * @returns {Object} Returns `object`.
5932 function copyObject(source, props, object, customizer) {
5933 var isNew = !object;
5934 object || (object = {});
5937 length = props.length;
5939 while (++index < length) {
5940 var key = props[index];
5942 var newValue = customizer
5943 ? customizer(object[key], source[key], key, object, source)
5946 if (newValue === undefined) {
5947 newValue = source[key];
5950 baseAssignValue(object, key, newValue);
5952 assignValue(object, key, newValue);
5959 * Copies own symbols of `source` to `object`.
5962 * @param {Object} source The object to copy symbols from.
5963 * @param {Object} [object={}] The object to copy symbols to.
5964 * @returns {Object} Returns `object`.
5966 function copySymbols(source, object) {
5967 return copyObject(source, getSymbols(source), object);
5971 * Copies own and inherited symbols of `source` to `object`.
5974 * @param {Object} source The object to copy symbols from.
5975 * @param {Object} [object={}] The object to copy symbols to.
5976 * @returns {Object} Returns `object`.
5978 function copySymbolsIn(source, object) {
5979 return copyObject(source, getSymbolsIn(source), object);
5983 * Creates a function like `_.groupBy`.
5986 * @param {Function} setter The function to set accumulator values.
5987 * @param {Function} [initializer] The accumulator object initializer.
5988 * @returns {Function} Returns the new aggregator function.
5990 function createAggregator(setter, initializer) {
5991 return function(collection, iteratee) {
5992 var func = isArray(collection) ? arrayAggregator : baseAggregator,
5993 accumulator = initializer ? initializer() : {};
5995 return func(collection, setter, getIteratee(iteratee, 2), accumulator);
6000 * Creates a function like `_.assign`.
6003 * @param {Function} assigner The function to assign values.
6004 * @returns {Function} Returns the new assigner function.
6006 function createAssigner(assigner) {
6007 return baseRest(function(object, sources) {
6009 length = sources.length,
6010 customizer = length > 1 ? sources[length - 1] : undefined,
6011 guard = length > 2 ? sources[2] : undefined;
6013 customizer = (assigner.length > 3 && typeof customizer == 'function')
6014 ? (length--, customizer)
6017 if (guard && isIterateeCall(sources[0], sources[1], guard)) {
6018 customizer = length < 3 ? undefined : customizer;
6021 object = Object(object);
6022 while (++index < length) {
6023 var source = sources[index];
6025 assigner(object, source, index, customizer);
6033 * Creates a `baseEach` or `baseEachRight` function.
6036 * @param {Function} eachFunc The function to iterate over a collection.
6037 * @param {boolean} [fromRight] Specify iterating from right to left.
6038 * @returns {Function} Returns the new base function.
6040 function createBaseEach(eachFunc, fromRight) {
6041 return function(collection, iteratee) {
6042 if (collection == null) {
6045 if (!isArrayLike(collection)) {
6046 return eachFunc(collection, iteratee);
6048 var length = collection.length,
6049 index = fromRight ? length : -1,
6050 iterable = Object(collection);
6052 while ((fromRight ? index-- : ++index < length)) {
6053 if (iteratee(iterable[index], index, iterable) === false) {
6062 * Creates a base function for methods like `_.forIn` and `_.forOwn`.
6065 * @param {boolean} [fromRight] Specify iterating from right to left.
6066 * @returns {Function} Returns the new base function.
6068 function createBaseFor(fromRight) {
6069 return function(object, iteratee, keysFunc) {
6071 iterable = Object(object),
6072 props = keysFunc(object),
6073 length = props.length;
6076 var key = props[fromRight ? length : ++index];
6077 if (iteratee(iterable[key], key, iterable) === false) {
6086 * Creates a function that wraps `func` to invoke it with the optional `this`
6087 * binding of `thisArg`.
6090 * @param {Function} func The function to wrap.
6091 * @param {number} bitmask The bitmask flags. See `createWrap` for more details.
6092 * @param {*} [thisArg] The `this` binding of `func`.
6093 * @returns {Function} Returns the new wrapped function.
6095 function createBind(func, bitmask, thisArg) {
6096 var isBind = bitmask & WRAP_BIND_FLAG,
6097 Ctor = createCtor(func);
6099 function wrapper() {
6100 var fn = (this && this !== root && this instanceof wrapper) ? Ctor : func;
6101 return fn.apply(isBind ? thisArg : this, arguments);
6107 * Creates a function like `_.lowerFirst`.
6110 * @param {string} methodName The name of the `String` case method to use.
6111 * @returns {Function} Returns the new case function.
6113 function createCaseFirst(methodName) {
6114 return function(string) {
6115 string = toString(string);
6117 var strSymbols = hasUnicode(string)
6118 ? stringToArray(string)
6121 var chr = strSymbols
6125 var trailing = strSymbols
6126 ? castSlice(strSymbols, 1).join('')
6129 return chr[methodName]() + trailing;
6134 * Creates a function like `_.camelCase`.
6137 * @param {Function} callback The function to combine each word.
6138 * @returns {Function} Returns the new compounder function.
6140 function createCompounder(callback) {
6141 return function(string) {
6142 return arrayReduce(words(deburr(string).replace(reApos, '')), callback, '');
6147 * Creates a function that produces an instance of `Ctor` regardless of
6148 * whether it was invoked as part of a `new` expression or by `call` or `apply`.
6151 * @param {Function} Ctor The constructor to wrap.
6152 * @returns {Function} Returns the new wrapped function.
6154 function createCtor(Ctor) {
6156 // Use a `switch` statement to work with class constructors. See
6157 // http://ecma-international.org/ecma-262/7.0/#sec-ecmascript-function-objects-call-thisargument-argumentslist
6158 // for more details.
6159 var args = arguments;
6160 switch (args.length) {
6161 case 0: return new Ctor;
6162 case 1: return new Ctor(args[0]);
6163 case 2: return new Ctor(args[0], args[1]);
6164 case 3: return new Ctor(args[0], args[1], args[2]);
6165 case 4: return new Ctor(args[0], args[1], args[2], args[3]);
6166 case 5: return new Ctor(args[0], args[1], args[2], args[3], args[4]);
6167 case 6: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5]);
6168 case 7: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5], args[6]);
6170 var thisBinding = baseCreate(Ctor.prototype),
6171 result = Ctor.apply(thisBinding, args);
6173 // Mimic the constructor's `return` behavior.
6174 // See https://es5.github.io/#x13.2.2 for more details.
6175 return isObject(result) ? result : thisBinding;
6180 * Creates a function that wraps `func` to enable currying.
6183 * @param {Function} func The function to wrap.
6184 * @param {number} bitmask The bitmask flags. See `createWrap` for more details.
6185 * @param {number} arity The arity of `func`.
6186 * @returns {Function} Returns the new wrapped function.
6188 function createCurry(func, bitmask, arity) {
6189 var Ctor = createCtor(func);
6191 function wrapper() {
6192 var length = arguments.length,
6193 args = Array(length),
6195 placeholder = getHolder(wrapper);
6198 args[index] = arguments[index];
6200 var holders = (length < 3 && args[0] !== placeholder && args[length - 1] !== placeholder)
6202 : replaceHolders(args, placeholder);
6204 length -= holders.length;
6205 if (length < arity) {
6206 return createRecurry(
6207 func, bitmask, createHybrid, wrapper.placeholder, undefined,
6208 args, holders, undefined, undefined, arity - length);
6210 var fn = (this && this !== root && this instanceof wrapper) ? Ctor : func;
6211 return apply(fn, this, args);
6217 * Creates a `_.find` or `_.findLast` function.
6220 * @param {Function} findIndexFunc The function to find the collection index.
6221 * @returns {Function} Returns the new find function.
6223 function createFind(findIndexFunc) {
6224 return function(collection, predicate, fromIndex) {
6225 var iterable = Object(collection);
6226 if (!isArrayLike(collection)) {
6227 var iteratee = getIteratee(predicate, 3);
6228 collection = keys(collection);
6229 predicate = function(key) { return iteratee(iterable[key], key, iterable); };
6231 var index = findIndexFunc(collection, predicate, fromIndex);
6232 return index > -1 ? iterable[iteratee ? collection[index] : index] : undefined;
6237 * Creates a `_.flow` or `_.flowRight` function.
6240 * @param {boolean} [fromRight] Specify iterating from right to left.
6241 * @returns {Function} Returns the new flow function.
6243 function createFlow(fromRight) {
6244 return flatRest(function(funcs) {
6245 var length = funcs.length,
6247 prereq = LodashWrapper.prototype.thru;
6253 var func = funcs[index];
6254 if (typeof func != 'function') {
6255 throw new TypeError(FUNC_ERROR_TEXT);
6257 if (prereq && !wrapper && getFuncName(func) == 'wrapper') {
6258 var wrapper = new LodashWrapper([], true);
6261 index = wrapper ? index : length;
6262 while (++index < length) {
6263 func = funcs[index];
6265 var funcName = getFuncName(func),
6266 data = funcName == 'wrapper' ? getData(func) : undefined;
6268 if (data && isLaziable(data[0]) &&
6269 data[1] == (WRAP_ARY_FLAG | WRAP_CURRY_FLAG | WRAP_PARTIAL_FLAG | WRAP_REARG_FLAG) &&
6270 !data[4].length && data[9] == 1
6272 wrapper = wrapper[getFuncName(data[0])].apply(wrapper, data[3]);
6274 wrapper = (func.length == 1 && isLaziable(func))
6275 ? wrapper[funcName]()
6276 : wrapper.thru(func);
6280 var args = arguments,
6283 if (wrapper && args.length == 1 && isArray(value)) {
6284 return wrapper.plant(value).value();
6287 result = length ? funcs[index].apply(this, args) : value;
6289 while (++index < length) {
6290 result = funcs[index].call(this, result);
6298 * Creates a function that wraps `func` to invoke it with optional `this`
6299 * binding of `thisArg`, partial application, and currying.
6302 * @param {Function|string} func The function or method name to wrap.
6303 * @param {number} bitmask The bitmask flags. See `createWrap` for more details.
6304 * @param {*} [thisArg] The `this` binding of `func`.
6305 * @param {Array} [partials] The arguments to prepend to those provided to
6307 * @param {Array} [holders] The `partials` placeholder indexes.
6308 * @param {Array} [partialsRight] The arguments to append to those provided
6309 * to the new function.
6310 * @param {Array} [holdersRight] The `partialsRight` placeholder indexes.
6311 * @param {Array} [argPos] The argument positions of the new function.
6312 * @param {number} [ary] The arity cap of `func`.
6313 * @param {number} [arity] The arity of `func`.
6314 * @returns {Function} Returns the new wrapped function.
6316 function createHybrid(func, bitmask, thisArg, partials, holders, partialsRight, holdersRight, argPos, ary, arity) {
6317 var isAry = bitmask & WRAP_ARY_FLAG,
6318 isBind = bitmask & WRAP_BIND_FLAG,
6319 isBindKey = bitmask & WRAP_BIND_KEY_FLAG,
6320 isCurried = bitmask & (WRAP_CURRY_FLAG | WRAP_CURRY_RIGHT_FLAG),
6321 isFlip = bitmask & WRAP_FLIP_FLAG,
6322 Ctor = isBindKey ? undefined : createCtor(func);
6324 function wrapper() {
6325 var length = arguments.length,
6326 args = Array(length),
6330 args[index] = arguments[index];
6333 var placeholder = getHolder(wrapper),
6334 holdersCount = countHolders(args, placeholder);
6337 args = composeArgs(args, partials, holders, isCurried);
6339 if (partialsRight) {
6340 args = composeArgsRight(args, partialsRight, holdersRight, isCurried);
6342 length -= holdersCount;
6343 if (isCurried && length < arity) {
6344 var newHolders = replaceHolders(args, placeholder);
6345 return createRecurry(
6346 func, bitmask, createHybrid, wrapper.placeholder, thisArg,
6347 args, newHolders, argPos, ary, arity - length
6350 var thisBinding = isBind ? thisArg : this,
6351 fn = isBindKey ? thisBinding[func] : func;
6353 length = args.length;
6355 args = reorder(args, argPos);
6356 } else if (isFlip && length > 1) {
6359 if (isAry && ary < length) {
6362 if (this && this !== root && this instanceof wrapper) {
6363 fn = Ctor || createCtor(fn);
6365 return fn.apply(thisBinding, args);
6371 * Creates a function like `_.invertBy`.
6374 * @param {Function} setter The function to set accumulator values.
6375 * @param {Function} toIteratee The function to resolve iteratees.
6376 * @returns {Function} Returns the new inverter function.
6378 function createInverter(setter, toIteratee) {
6379 return function(object, iteratee) {
6380 return baseInverter(object, setter, toIteratee(iteratee), {});
6385 * Creates a function that performs a mathematical operation on two values.
6388 * @param {Function} operator The function to perform the operation.
6389 * @param {number} [defaultValue] The value used for `undefined` arguments.
6390 * @returns {Function} Returns the new mathematical operation function.
6392 function createMathOperation(operator, defaultValue) {
6393 return function(value, other) {
6395 if (value === undefined && other === undefined) {
6396 return defaultValue;
6398 if (value !== undefined) {
6401 if (other !== undefined) {
6402 if (result === undefined) {
6405 if (typeof value == 'string' || typeof other == 'string') {
6406 value = baseToString(value);
6407 other = baseToString(other);
6409 value = baseToNumber(value);
6410 other = baseToNumber(other);
6412 result = operator(value, other);
6419 * Creates a function like `_.over`.
6422 * @param {Function} arrayFunc The function to iterate over iteratees.
6423 * @returns {Function} Returns the new over function.
6425 function createOver(arrayFunc) {
6426 return flatRest(function(iteratees) {
6427 iteratees = arrayMap(iteratees, baseUnary(getIteratee()));
6428 return baseRest(function(args) {
6430 return arrayFunc(iteratees, function(iteratee) {
6431 return apply(iteratee, thisArg, args);
6438 * Creates the padding for `string` based on `length`. The `chars` string
6439 * is truncated if the number of characters exceeds `length`.
6442 * @param {number} length The padding length.
6443 * @param {string} [chars=' '] The string used as padding.
6444 * @returns {string} Returns the padding for `string`.
6446 function createPadding(length, chars) {
6447 chars = chars === undefined ? ' ' : baseToString(chars);
6449 var charsLength = chars.length;
6450 if (charsLength < 2) {
6451 return charsLength ? baseRepeat(chars, length) : chars;
6453 var result = baseRepeat(chars, nativeCeil(length / stringSize(chars)));
6454 return hasUnicode(chars)
6455 ? castSlice(stringToArray(result), 0, length).join('')
6456 : result.slice(0, length);
6460 * Creates a function that wraps `func` to invoke it with the `this` binding
6461 * of `thisArg` and `partials` prepended to the arguments it receives.
6464 * @param {Function} func The function to wrap.
6465 * @param {number} bitmask The bitmask flags. See `createWrap` for more details.
6466 * @param {*} thisArg The `this` binding of `func`.
6467 * @param {Array} partials The arguments to prepend to those provided to
6469 * @returns {Function} Returns the new wrapped function.
6471 function createPartial(func, bitmask, thisArg, partials) {
6472 var isBind = bitmask & WRAP_BIND_FLAG,
6473 Ctor = createCtor(func);
6475 function wrapper() {
6477 argsLength = arguments.length,
6479 leftLength = partials.length,
6480 args = Array(leftLength + argsLength),
6481 fn = (this && this !== root && this instanceof wrapper) ? Ctor : func;
6483 while (++leftIndex < leftLength) {
6484 args[leftIndex] = partials[leftIndex];
6486 while (argsLength--) {
6487 args[leftIndex++] = arguments[++argsIndex];
6489 return apply(fn, isBind ? thisArg : this, args);
6495 * Creates a `_.range` or `_.rangeRight` function.
6498 * @param {boolean} [fromRight] Specify iterating from right to left.
6499 * @returns {Function} Returns the new range function.
6501 function createRange(fromRight) {
6502 return function(start, end, step) {
6503 if (step && typeof step != 'number' && isIterateeCall(start, end, step)) {
6504 end = step = undefined;
6506 // Ensure the sign of `-0` is preserved.
6507 start = toFinite(start);
6508 if (end === undefined) {
6512 end = toFinite(end);
6514 step = step === undefined ? (start < end ? 1 : -1) : toFinite(step);
6515 return baseRange(start, end, step, fromRight);
6520 * Creates a function that performs a relational operation on two values.
6523 * @param {Function} operator The function to perform the operation.
6524 * @returns {Function} Returns the new relational operation function.
6526 function createRelationalOperation(operator) {
6527 return function(value, other) {
6528 if (!(typeof value == 'string' && typeof other == 'string')) {
6529 value = toNumber(value);
6530 other = toNumber(other);
6532 return operator(value, other);
6537 * Creates a function that wraps `func` to continue currying.
6540 * @param {Function} func The function to wrap.
6541 * @param {number} bitmask The bitmask flags. See `createWrap` for more details.
6542 * @param {Function} wrapFunc The function to create the `func` wrapper.
6543 * @param {*} placeholder The placeholder value.
6544 * @param {*} [thisArg] The `this` binding of `func`.
6545 * @param {Array} [partials] The arguments to prepend to those provided to
6547 * @param {Array} [holders] The `partials` placeholder indexes.
6548 * @param {Array} [argPos] The argument positions of the new function.
6549 * @param {number} [ary] The arity cap of `func`.
6550 * @param {number} [arity] The arity of `func`.
6551 * @returns {Function} Returns the new wrapped function.
6553 function createRecurry(func, bitmask, wrapFunc, placeholder, thisArg, partials, holders, argPos, ary, arity) {
6554 var isCurry = bitmask & WRAP_CURRY_FLAG,
6555 newHolders = isCurry ? holders : undefined,
6556 newHoldersRight = isCurry ? undefined : holders,
6557 newPartials = isCurry ? partials : undefined,
6558 newPartialsRight = isCurry ? undefined : partials;
6560 bitmask |= (isCurry ? WRAP_PARTIAL_FLAG : WRAP_PARTIAL_RIGHT_FLAG);
6561 bitmask &= ~(isCurry ? WRAP_PARTIAL_RIGHT_FLAG : WRAP_PARTIAL_FLAG);
6563 if (!(bitmask & WRAP_CURRY_BOUND_FLAG)) {
6564 bitmask &= ~(WRAP_BIND_FLAG | WRAP_BIND_KEY_FLAG);
6567 func, bitmask, thisArg, newPartials, newHolders, newPartialsRight,
6568 newHoldersRight, argPos, ary, arity
6571 var result = wrapFunc.apply(undefined, newData);
6572 if (isLaziable(func)) {
6573 setData(result, newData);
6575 result.placeholder = placeholder;
6576 return setWrapToString(result, func, bitmask);
6580 * Creates a function like `_.round`.
6583 * @param {string} methodName The name of the `Math` method to use when rounding.
6584 * @returns {Function} Returns the new round function.
6586 function createRound(methodName) {
6587 var func = Math[methodName];
6588 return function(number, precision) {
6589 number = toNumber(number);
6590 precision = precision == null ? 0 : nativeMin(toInteger(precision), 292);
6591 if (precision && nativeIsFinite(number)) {
6592 // Shift with exponential notation to avoid floating-point issues.
6593 // See [MDN](https://mdn.io/round#Examples) for more details.
6594 var pair = (toString(number) + 'e').split('e'),
6595 value = func(pair[0] + 'e' + (+pair[1] + precision));
6597 pair = (toString(value) + 'e').split('e');
6598 return +(pair[0] + 'e' + (+pair[1] - precision));
6600 return func(number);
6605 * Creates a set object of `values`.
6608 * @param {Array} values The values to add to the set.
6609 * @returns {Object} Returns the new set.
6611 var createSet = !(Set && (1 / setToArray(new Set([,-0]))[1]) == INFINITY) ? noop : function(values) {
6612 return new Set(values);
6616 * Creates a `_.toPairs` or `_.toPairsIn` function.
6619 * @param {Function} keysFunc The function to get the keys of a given object.
6620 * @returns {Function} Returns the new pairs function.
6622 function createToPairs(keysFunc) {
6623 return function(object) {
6624 var tag = getTag(object);
6625 if (tag == mapTag) {
6626 return mapToArray(object);
6628 if (tag == setTag) {
6629 return setToPairs(object);
6631 return baseToPairs(object, keysFunc(object));
6636 * Creates a function that either curries or invokes `func` with optional
6637 * `this` binding and partially applied arguments.
6640 * @param {Function|string} func The function or method name to wrap.
6641 * @param {number} bitmask The bitmask flags.
6644 * 4 - `_.curry` or `_.curryRight` of a bound function
6646 * 16 - `_.curryRight`
6648 * 64 - `_.partialRight`
6652 * @param {*} [thisArg] The `this` binding of `func`.
6653 * @param {Array} [partials] The arguments to be partially applied.
6654 * @param {Array} [holders] The `partials` placeholder indexes.
6655 * @param {Array} [argPos] The argument positions of the new function.
6656 * @param {number} [ary] The arity cap of `func`.
6657 * @param {number} [arity] The arity of `func`.
6658 * @returns {Function} Returns the new wrapped function.
6660 function createWrap(func, bitmask, thisArg, partials, holders, argPos, ary, arity) {
6661 var isBindKey = bitmask & WRAP_BIND_KEY_FLAG;
6662 if (!isBindKey && typeof func != 'function') {
6663 throw new TypeError(FUNC_ERROR_TEXT);
6665 var length = partials ? partials.length : 0;
6667 bitmask &= ~(WRAP_PARTIAL_FLAG | WRAP_PARTIAL_RIGHT_FLAG);
6668 partials = holders = undefined;
6670 ary = ary === undefined ? ary : nativeMax(toInteger(ary), 0);
6671 arity = arity === undefined ? arity : toInteger(arity);
6672 length -= holders ? holders.length : 0;
6674 if (bitmask & WRAP_PARTIAL_RIGHT_FLAG) {
6675 var partialsRight = partials,
6676 holdersRight = holders;
6678 partials = holders = undefined;
6680 var data = isBindKey ? undefined : getData(func);
6683 func, bitmask, thisArg, partials, holders, partialsRight, holdersRight,
6688 mergeData(newData, data);
6691 bitmask = newData[1];
6692 thisArg = newData[2];
6693 partials = newData[3];
6694 holders = newData[4];
6695 arity = newData[9] = newData[9] === undefined
6696 ? (isBindKey ? 0 : func.length)
6697 : nativeMax(newData[9] - length, 0);
6699 if (!arity && bitmask & (WRAP_CURRY_FLAG | WRAP_CURRY_RIGHT_FLAG)) {
6700 bitmask &= ~(WRAP_CURRY_FLAG | WRAP_CURRY_RIGHT_FLAG);
6702 if (!bitmask || bitmask == WRAP_BIND_FLAG) {
6703 var result = createBind(func, bitmask, thisArg);
6704 } else if (bitmask == WRAP_CURRY_FLAG || bitmask == WRAP_CURRY_RIGHT_FLAG) {
6705 result = createCurry(func, bitmask, arity);
6706 } else if ((bitmask == WRAP_PARTIAL_FLAG || bitmask == (WRAP_BIND_FLAG | WRAP_PARTIAL_FLAG)) && !holders.length) {
6707 result = createPartial(func, bitmask, thisArg, partials);
6709 result = createHybrid.apply(undefined, newData);
6711 var setter = data ? baseSetData : setData;
6712 return setWrapToString(setter(result, newData), func, bitmask);
6716 * Used by `_.defaults` to customize its `_.assignIn` use to assign properties
6717 * of source objects to the destination object for all destination properties
6718 * that resolve to `undefined`.
6721 * @param {*} objValue The destination value.
6722 * @param {*} srcValue The source value.
6723 * @param {string} key The key of the property to assign.
6724 * @param {Object} object The parent object of `objValue`.
6725 * @returns {*} Returns the value to assign.
6727 function customDefaultsAssignIn(objValue, srcValue, key, object) {
6728 if (objValue === undefined ||
6729 (eq(objValue, objectProto[key]) && !hasOwnProperty.call(object, key))) {
6736 * Used by `_.defaultsDeep` to customize its `_.merge` use to merge source
6737 * objects into destination objects that are passed thru.
6740 * @param {*} objValue The destination value.
6741 * @param {*} srcValue The source value.
6742 * @param {string} key The key of the property to merge.
6743 * @param {Object} object The parent object of `objValue`.
6744 * @param {Object} source The parent object of `srcValue`.
6745 * @param {Object} [stack] Tracks traversed source values and their merged
6747 * @returns {*} Returns the value to assign.
6749 function customDefaultsMerge(objValue, srcValue, key, object, source, stack) {
6750 if (isObject(objValue) && isObject(srcValue)) {
6751 // Recursively merge objects and arrays (susceptible to call stack limits).
6752 stack.set(srcValue, objValue);
6753 baseMerge(objValue, srcValue, undefined, customDefaultsMerge, stack);
6754 stack['delete'](srcValue);
6760 * Used by `_.omit` to customize its `_.cloneDeep` use to only clone plain
6764 * @param {*} value The value to inspect.
6765 * @param {string} key The key of the property to inspect.
6766 * @returns {*} Returns the uncloned value or `undefined` to defer cloning to `_.cloneDeep`.
6768 function customOmitClone(value) {
6769 return isPlainObject(value) ? undefined : value;
6773 * A specialized version of `baseIsEqualDeep` for arrays with support for
6774 * partial deep comparisons.
6777 * @param {Array} array The array to compare.
6778 * @param {Array} other The other array to compare.
6779 * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.
6780 * @param {Function} customizer The function to customize comparisons.
6781 * @param {Function} equalFunc The function to determine equivalents of values.
6782 * @param {Object} stack Tracks traversed `array` and `other` objects.
6783 * @returns {boolean} Returns `true` if the arrays are equivalent, else `false`.
6785 function equalArrays(array, other, bitmask, customizer, equalFunc, stack) {
6786 var isPartial = bitmask & COMPARE_PARTIAL_FLAG,
6787 arrLength = array.length,
6788 othLength = other.length;
6790 if (arrLength != othLength && !(isPartial && othLength > arrLength)) {
6793 // Check that cyclic values are equal.
6794 var arrStacked = stack.get(array);
6795 var othStacked = stack.get(other);
6796 if (arrStacked && othStacked) {
6797 return arrStacked == other && othStacked == array;
6801 seen = (bitmask & COMPARE_UNORDERED_FLAG) ? new SetCache : undefined;
6803 stack.set(array, other);
6804 stack.set(other, array);
6806 // Ignore non-index properties.
6807 while (++index < arrLength) {
6808 var arrValue = array[index],
6809 othValue = other[index];
6812 var compared = isPartial
6813 ? customizer(othValue, arrValue, index, other, array, stack)
6814 : customizer(arrValue, othValue, index, array, other, stack);
6816 if (compared !== undefined) {
6823 // Recursively compare arrays (susceptible to call stack limits).
6825 if (!arraySome(other, function(othValue, othIndex) {
6826 if (!cacheHas(seen, othIndex) &&
6827 (arrValue === othValue || equalFunc(arrValue, othValue, bitmask, customizer, stack))) {
6828 return seen.push(othIndex);
6835 arrValue === othValue ||
6836 equalFunc(arrValue, othValue, bitmask, customizer, stack)
6842 stack['delete'](array);
6843 stack['delete'](other);
6848 * A specialized version of `baseIsEqualDeep` for comparing objects of
6849 * the same `toStringTag`.
6851 * **Note:** This function only supports comparing values with tags of
6852 * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`.
6855 * @param {Object} object The object to compare.
6856 * @param {Object} other The other object to compare.
6857 * @param {string} tag The `toStringTag` of the objects to compare.
6858 * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.
6859 * @param {Function} customizer The function to customize comparisons.
6860 * @param {Function} equalFunc The function to determine equivalents of values.
6861 * @param {Object} stack Tracks traversed `object` and `other` objects.
6862 * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
6864 function equalByTag(object, other, tag, bitmask, customizer, equalFunc, stack) {
6867 if ((object.byteLength != other.byteLength) ||
6868 (object.byteOffset != other.byteOffset)) {
6871 object = object.buffer;
6872 other = other.buffer;
6874 case arrayBufferTag:
6875 if ((object.byteLength != other.byteLength) ||
6876 !equalFunc(new Uint8Array(object), new Uint8Array(other))) {
6884 // Coerce booleans to `1` or `0` and dates to milliseconds.
6885 // Invalid dates are coerced to `NaN`.
6886 return eq(+object, +other);
6889 return object.name == other.name && object.message == other.message;
6893 // Coerce regexes to strings and treat strings, primitives and objects,
6894 // as equal. See http://www.ecma-international.org/ecma-262/7.0/#sec-regexp.prototype.tostring
6895 // for more details.
6896 return object == (other + '');
6899 var convert = mapToArray;
6902 var isPartial = bitmask & COMPARE_PARTIAL_FLAG;
6903 convert || (convert = setToArray);
6905 if (object.size != other.size && !isPartial) {
6908 // Assume cyclic values are equal.
6909 var stacked = stack.get(object);
6911 return stacked == other;
6913 bitmask |= COMPARE_UNORDERED_FLAG;
6915 // Recursively compare objects (susceptible to call stack limits).
6916 stack.set(object, other);
6917 var result = equalArrays(convert(object), convert(other), bitmask, customizer, equalFunc, stack);
6918 stack['delete'](object);
6922 if (symbolValueOf) {
6923 return symbolValueOf.call(object) == symbolValueOf.call(other);
6930 * A specialized version of `baseIsEqualDeep` for objects with support for
6931 * partial deep comparisons.
6934 * @param {Object} object The object to compare.
6935 * @param {Object} other The other object to compare.
6936 * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.
6937 * @param {Function} customizer The function to customize comparisons.
6938 * @param {Function} equalFunc The function to determine equivalents of values.
6939 * @param {Object} stack Tracks traversed `object` and `other` objects.
6940 * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
6942 function equalObjects(object, other, bitmask, customizer, equalFunc, stack) {
6943 var isPartial = bitmask & COMPARE_PARTIAL_FLAG,
6944 objProps = getAllKeys(object),
6945 objLength = objProps.length,
6946 othProps = getAllKeys(other),
6947 othLength = othProps.length;
6949 if (objLength != othLength && !isPartial) {
6952 var index = objLength;
6954 var key = objProps[index];
6955 if (!(isPartial ? key in other : hasOwnProperty.call(other, key))) {
6959 // Check that cyclic values are equal.
6960 var objStacked = stack.get(object);
6961 var othStacked = stack.get(other);
6962 if (objStacked && othStacked) {
6963 return objStacked == other && othStacked == object;
6966 stack.set(object, other);
6967 stack.set(other, object);
6969 var skipCtor = isPartial;
6970 while (++index < objLength) {
6971 key = objProps[index];
6972 var objValue = object[key],
6973 othValue = other[key];
6976 var compared = isPartial
6977 ? customizer(othValue, objValue, key, other, object, stack)
6978 : customizer(objValue, othValue, key, object, other, stack);
6980 // Recursively compare objects (susceptible to call stack limits).
6981 if (!(compared === undefined
6982 ? (objValue === othValue || equalFunc(objValue, othValue, bitmask, customizer, stack))
6988 skipCtor || (skipCtor = key == 'constructor');
6990 if (result && !skipCtor) {
6991 var objCtor = object.constructor,
6992 othCtor = other.constructor;
6994 // Non `Object` object instances with different constructors are not equal.
6995 if (objCtor != othCtor &&
6996 ('constructor' in object && 'constructor' in other) &&
6997 !(typeof objCtor == 'function' && objCtor instanceof objCtor &&
6998 typeof othCtor == 'function' && othCtor instanceof othCtor)) {
7002 stack['delete'](object);
7003 stack['delete'](other);
7008 * A specialized version of `baseRest` which flattens the rest array.
7011 * @param {Function} func The function to apply a rest parameter to.
7012 * @returns {Function} Returns the new function.
7014 function flatRest(func) {
7015 return setToString(overRest(func, undefined, flatten), func + '');
7019 * Creates an array of own enumerable property names and symbols of `object`.
7022 * @param {Object} object The object to query.
7023 * @returns {Array} Returns the array of property names and symbols.
7025 function getAllKeys(object) {
7026 return baseGetAllKeys(object, keys, getSymbols);
7030 * Creates an array of own and inherited enumerable property names and
7031 * symbols of `object`.
7034 * @param {Object} object The object to query.
7035 * @returns {Array} Returns the array of property names and symbols.
7037 function getAllKeysIn(object) {
7038 return baseGetAllKeys(object, keysIn, getSymbolsIn);
7042 * Gets metadata for `func`.
7045 * @param {Function} func The function to query.
7046 * @returns {*} Returns the metadata for `func`.
7048 var getData = !metaMap ? noop : function(func) {
7049 return metaMap.get(func);
7053 * Gets the name of `func`.
7056 * @param {Function} func The function to query.
7057 * @returns {string} Returns the function name.
7059 function getFuncName(func) {
7060 var result = (func.name + ''),
7061 array = realNames[result],
7062 length = hasOwnProperty.call(realNames, result) ? array.length : 0;
7065 var data = array[length],
7066 otherFunc = data.func;
7067 if (otherFunc == null || otherFunc == func) {
7075 * Gets the argument placeholder value for `func`.
7078 * @param {Function} func The function to inspect.
7079 * @returns {*} Returns the placeholder value.
7081 function getHolder(func) {
7082 var object = hasOwnProperty.call(lodash, 'placeholder') ? lodash : func;
7083 return object.placeholder;
7087 * Gets the appropriate "iteratee" function. If `_.iteratee` is customized,
7088 * this function returns the custom method, otherwise it returns `baseIteratee`.
7089 * If arguments are provided, the chosen function is invoked with them and
7090 * its result is returned.
7093 * @param {*} [value] The value to convert to an iteratee.
7094 * @param {number} [arity] The arity of the created iteratee.
7095 * @returns {Function} Returns the chosen function or its result.
7097 function getIteratee() {
7098 var result = lodash.iteratee || iteratee;
7099 result = result === iteratee ? baseIteratee : result;
7100 return arguments.length ? result(arguments[0], arguments[1]) : result;
7104 * Gets the data for `map`.
7107 * @param {Object} map The map to query.
7108 * @param {string} key The reference key.
7109 * @returns {*} Returns the map data.
7111 function getMapData(map, key) {
7112 var data = map.__data__;
7113 return isKeyable(key)
7114 ? data[typeof key == 'string' ? 'string' : 'hash']
7119 * Gets the property names, values, and compare flags of `object`.
7122 * @param {Object} object The object to query.
7123 * @returns {Array} Returns the match data of `object`.
7125 function getMatchData(object) {
7126 var result = keys(object),
7127 length = result.length;
7130 var key = result[length],
7131 value = object[key];
7133 result[length] = [key, value, isStrictComparable(value)];
7139 * Gets the native function at `key` of `object`.
7142 * @param {Object} object The object to query.
7143 * @param {string} key The key of the method to get.
7144 * @returns {*} Returns the function if it's native, else `undefined`.
7146 function getNative(object, key) {
7147 var value = getValue(object, key);
7148 return baseIsNative(value) ? value : undefined;
7152 * A specialized version of `baseGetTag` which ignores `Symbol.toStringTag` values.
7155 * @param {*} value The value to query.
7156 * @returns {string} Returns the raw `toStringTag`.
7158 function getRawTag(value) {
7159 var isOwn = hasOwnProperty.call(value, symToStringTag),
7160 tag = value[symToStringTag];
7163 value[symToStringTag] = undefined;
7164 var unmasked = true;
7167 var result = nativeObjectToString.call(value);
7170 value[symToStringTag] = tag;
7172 delete value[symToStringTag];
7179 * Creates an array of the own enumerable symbols of `object`.
7182 * @param {Object} object The object to query.
7183 * @returns {Array} Returns the array of symbols.
7185 var getSymbols = !nativeGetSymbols ? stubArray : function(object) {
7186 if (object == null) {
7189 object = Object(object);
7190 return arrayFilter(nativeGetSymbols(object), function(symbol) {
7191 return propertyIsEnumerable.call(object, symbol);
7196 * Creates an array of the own and inherited enumerable symbols of `object`.
7199 * @param {Object} object The object to query.
7200 * @returns {Array} Returns the array of symbols.
7202 var getSymbolsIn = !nativeGetSymbols ? stubArray : function(object) {
7205 arrayPush(result, getSymbols(object));
7206 object = getPrototype(object);
7212 * Gets the `toStringTag` of `value`.
7215 * @param {*} value The value to query.
7216 * @returns {string} Returns the `toStringTag`.
7218 var getTag = baseGetTag;
7220 // Fallback for data views, maps, sets, and weak maps in IE 11 and promises in Node.js < 6.
7221 if ((DataView && getTag(new DataView(new ArrayBuffer(1))) != dataViewTag) ||
7222 (Map && getTag(new Map) != mapTag) ||
7223 (Promise && getTag(Promise.resolve()) != promiseTag) ||
7224 (Set && getTag(new Set) != setTag) ||
7225 (WeakMap && getTag(new WeakMap) != weakMapTag)) {
7226 getTag = function(value) {
7227 var result = baseGetTag(value),
7228 Ctor = result == objectTag ? value.constructor : undefined,
7229 ctorString = Ctor ? toSource(Ctor) : '';
7232 switch (ctorString) {
7233 case dataViewCtorString: return dataViewTag;
7234 case mapCtorString: return mapTag;
7235 case promiseCtorString: return promiseTag;
7236 case setCtorString: return setTag;
7237 case weakMapCtorString: return weakMapTag;
7245 * Gets the view, applying any `transforms` to the `start` and `end` positions.
7248 * @param {number} start The start of the view.
7249 * @param {number} end The end of the view.
7250 * @param {Array} transforms The transformations to apply to the view.
7251 * @returns {Object} Returns an object containing the `start` and `end`
7252 * positions of the view.
7254 function getView(start, end, transforms) {
7256 length = transforms.length;
7258 while (++index < length) {
7259 var data = transforms[index],
7262 switch (data.type) {
7263 case 'drop': start += size; break;
7264 case 'dropRight': end -= size; break;
7265 case 'take': end = nativeMin(end, start + size); break;
7266 case 'takeRight': start = nativeMax(start, end - size); break;
7269 return { 'start': start, 'end': end };
7273 * Extracts wrapper details from the `source` body comment.
7276 * @param {string} source The source to inspect.
7277 * @returns {Array} Returns the wrapper details.
7279 function getWrapDetails(source) {
7280 var match = source.match(reWrapDetails);
7281 return match ? match[1].split(reSplitDetails) : [];
7285 * Checks if `path` exists on `object`.
7288 * @param {Object} object The object to query.
7289 * @param {Array|string} path The path to check.
7290 * @param {Function} hasFunc The function to check properties.
7291 * @returns {boolean} Returns `true` if `path` exists, else `false`.
7293 function hasPath(object, path, hasFunc) {
7294 path = castPath(path, object);
7297 length = path.length,
7300 while (++index < length) {
7301 var key = toKey(path[index]);
7302 if (!(result = object != null && hasFunc(object, key))) {
7305 object = object[key];
7307 if (result || ++index != length) {
7310 length = object == null ? 0 : object.length;
7311 return !!length && isLength(length) && isIndex(key, length) &&
7312 (isArray(object) || isArguments(object));
7316 * Initializes an array clone.
7319 * @param {Array} array The array to clone.
7320 * @returns {Array} Returns the initialized clone.
7322 function initCloneArray(array) {
7323 var length = array.length,
7324 result = new array.constructor(length);
7326 // Add properties assigned by `RegExp#exec`.
7327 if (length && typeof array[0] == 'string' && hasOwnProperty.call(array, 'index')) {
7328 result.index = array.index;
7329 result.input = array.input;
7335 * Initializes an object clone.
7338 * @param {Object} object The object to clone.
7339 * @returns {Object} Returns the initialized clone.
7341 function initCloneObject(object) {
7342 return (typeof object.constructor == 'function' && !isPrototype(object))
7343 ? baseCreate(getPrototype(object))
7348 * Initializes an object clone based on its `toStringTag`.
7350 * **Note:** This function only supports cloning values with tags of
7351 * `Boolean`, `Date`, `Error`, `Map`, `Number`, `RegExp`, `Set`, or `String`.
7354 * @param {Object} object The object to clone.
7355 * @param {string} tag The `toStringTag` of the object to clone.
7356 * @param {boolean} [isDeep] Specify a deep clone.
7357 * @returns {Object} Returns the initialized clone.
7359 function initCloneByTag(object, tag, isDeep) {
7360 var Ctor = object.constructor;
7362 case arrayBufferTag:
7363 return cloneArrayBuffer(object);
7367 return new Ctor(+object);
7370 return cloneDataView(object, isDeep);
7372 case float32Tag: case float64Tag:
7373 case int8Tag: case int16Tag: case int32Tag:
7374 case uint8Tag: case uint8ClampedTag: case uint16Tag: case uint32Tag:
7375 return cloneTypedArray(object, isDeep);
7382 return new Ctor(object);
7385 return cloneRegExp(object);
7391 return cloneSymbol(object);
7396 * Inserts wrapper `details` in a comment at the top of the `source` body.
7399 * @param {string} source The source to modify.
7400 * @returns {Array} details The details to insert.
7401 * @returns {string} Returns the modified source.
7403 function insertWrapDetails(source, details) {
7404 var length = details.length;
7408 var lastIndex = length - 1;
7409 details[lastIndex] = (length > 1 ? '& ' : '') + details[lastIndex];
7410 details = details.join(length > 2 ? ', ' : ' ');
7411 return source.replace(reWrapComment, '{\n/* [wrapped with ' + details + '] */\n');
7415 * Checks if `value` is a flattenable `arguments` object or array.
7418 * @param {*} value The value to check.
7419 * @returns {boolean} Returns `true` if `value` is flattenable, else `false`.
7421 function isFlattenable(value) {
7422 return isArray(value) || isArguments(value) ||
7423 !!(spreadableSymbol && value && value[spreadableSymbol]);
7427 * Checks if `value` is a valid array-like index.
7430 * @param {*} value The value to check.
7431 * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.
7432 * @returns {boolean} Returns `true` if `value` is a valid index, else `false`.
7434 function isIndex(value, length) {
7435 var type = typeof value;
7436 length = length == null ? MAX_SAFE_INTEGER : length;
7439 (type == 'number' ||
7440 (type != 'symbol' && reIsUint.test(value))) &&
7441 (value > -1 && value % 1 == 0 && value < length);
7445 * Checks if the given arguments are from an iteratee call.
7448 * @param {*} value The potential iteratee value argument.
7449 * @param {*} index The potential iteratee index or key argument.
7450 * @param {*} object The potential iteratee object argument.
7451 * @returns {boolean} Returns `true` if the arguments are from an iteratee call,
7454 function isIterateeCall(value, index, object) {
7455 if (!isObject(object)) {
7458 var type = typeof index;
7459 if (type == 'number'
7460 ? (isArrayLike(object) && isIndex(index, object.length))
7461 : (type == 'string' && index in object)
7463 return eq(object[index], value);
7469 * Checks if `value` is a property name and not a property path.
7472 * @param {*} value The value to check.
7473 * @param {Object} [object] The object to query keys on.
7474 * @returns {boolean} Returns `true` if `value` is a property name, else `false`.
7476 function isKey(value, object) {
7477 if (isArray(value)) {
7480 var type = typeof value;
7481 if (type == 'number' || type == 'symbol' || type == 'boolean' ||
7482 value == null || isSymbol(value)) {
7485 return reIsPlainProp.test(value) || !reIsDeepProp.test(value) ||
7486 (object != null && value in Object(object));
7490 * Checks if `value` is suitable for use as unique object key.
7493 * @param {*} value The value to check.
7494 * @returns {boolean} Returns `true` if `value` is suitable, else `false`.
7496 function isKeyable(value) {
7497 var type = typeof value;
7498 return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean')
7499 ? (value !== '__proto__')
7504 * Checks if `func` has a lazy counterpart.
7507 * @param {Function} func The function to check.
7508 * @returns {boolean} Returns `true` if `func` has a lazy counterpart,
7511 function isLaziable(func) {
7512 var funcName = getFuncName(func),
7513 other = lodash[funcName];
7515 if (typeof other != 'function' || !(funcName in LazyWrapper.prototype)) {
7518 if (func === other) {
7521 var data = getData(other);
7522 return !!data && func === data[0];
7526 * Checks if `func` has its source masked.
7529 * @param {Function} func The function to check.
7530 * @returns {boolean} Returns `true` if `func` is masked, else `false`.
7532 function isMasked(func) {
7533 return !!maskSrcKey && (maskSrcKey in func);
7537 * Checks if `func` is capable of being masked.
7540 * @param {*} value The value to check.
7541 * @returns {boolean} Returns `true` if `func` is maskable, else `false`.
7543 var isMaskable = coreJsData ? isFunction : stubFalse;
7546 * Checks if `value` is likely a prototype object.
7549 * @param {*} value The value to check.
7550 * @returns {boolean} Returns `true` if `value` is a prototype, else `false`.
7552 function isPrototype(value) {
7553 var Ctor = value && value.constructor,
7554 proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto;
7556 return value === proto;
7560 * Checks if `value` is suitable for strict equality comparisons, i.e. `===`.
7563 * @param {*} value The value to check.
7564 * @returns {boolean} Returns `true` if `value` if suitable for strict
7565 * equality comparisons, else `false`.
7567 function isStrictComparable(value) {
7568 return value === value && !isObject(value);
7572 * A specialized version of `matchesProperty` for source values suitable
7573 * for strict equality comparisons, i.e. `===`.
7576 * @param {string} key The key of the property to get.
7577 * @param {*} srcValue The value to match.
7578 * @returns {Function} Returns the new spec function.
7580 function matchesStrictComparable(key, srcValue) {
7581 return function(object) {
7582 if (object == null) {
7585 return object[key] === srcValue &&
7586 (srcValue !== undefined || (key in Object(object)));
7591 * A specialized version of `_.memoize` which clears the memoized function's
7592 * cache when it exceeds `MAX_MEMOIZE_SIZE`.
7595 * @param {Function} func The function to have its output memoized.
7596 * @returns {Function} Returns the new memoized function.
7598 function memoizeCapped(func) {
7599 var result = memoize(func, function(key) {
7600 if (cache.size === MAX_MEMOIZE_SIZE) {
7606 var cache = result.cache;
7611 * Merges the function metadata of `source` into `data`.
7613 * Merging metadata reduces the number of wrappers used to invoke a function.
7614 * This is possible because methods like `_.bind`, `_.curry`, and `_.partial`
7615 * may be applied regardless of execution order. Methods like `_.ary` and
7616 * `_.rearg` modify function arguments, making the order in which they are
7617 * executed important, preventing the merging of metadata. However, we make
7618 * an exception for a safe combined case where curried functions have `_.ary`
7619 * and or `_.rearg` applied.
7622 * @param {Array} data The destination metadata.
7623 * @param {Array} source The source metadata.
7624 * @returns {Array} Returns `data`.
7626 function mergeData(data, source) {
7627 var bitmask = data[1],
7628 srcBitmask = source[1],
7629 newBitmask = bitmask | srcBitmask,
7630 isCommon = newBitmask < (WRAP_BIND_FLAG | WRAP_BIND_KEY_FLAG | WRAP_ARY_FLAG);
7633 ((srcBitmask == WRAP_ARY_FLAG) && (bitmask == WRAP_CURRY_FLAG)) ||
7634 ((srcBitmask == WRAP_ARY_FLAG) && (bitmask == WRAP_REARG_FLAG) && (data[7].length <= source[8])) ||
7635 ((srcBitmask == (WRAP_ARY_FLAG | WRAP_REARG_FLAG)) && (source[7].length <= source[8]) && (bitmask == WRAP_CURRY_FLAG));
7637 // Exit early if metadata can't be merged.
7638 if (!(isCommon || isCombo)) {
7641 // Use source `thisArg` if available.
7642 if (srcBitmask & WRAP_BIND_FLAG) {
7643 data[2] = source[2];
7644 // Set when currying a bound function.
7645 newBitmask |= bitmask & WRAP_BIND_FLAG ? 0 : WRAP_CURRY_BOUND_FLAG;
7647 // Compose partial arguments.
7648 var value = source[3];
7650 var partials = data[3];
7651 data[3] = partials ? composeArgs(partials, value, source[4]) : value;
7652 data[4] = partials ? replaceHolders(data[3], PLACEHOLDER) : source[4];
7654 // Compose partial right arguments.
7658 data[5] = partials ? composeArgsRight(partials, value, source[6]) : value;
7659 data[6] = partials ? replaceHolders(data[5], PLACEHOLDER) : source[6];
7661 // Use source `argPos` if available.
7666 // Use source `ary` if it's smaller.
7667 if (srcBitmask & WRAP_ARY_FLAG) {
7668 data[8] = data[8] == null ? source[8] : nativeMin(data[8], source[8]);
7670 // Use source `arity` if one is not provided.
7671 if (data[9] == null) {
7672 data[9] = source[9];
7674 // Use source `func` and merge bitmasks.
7675 data[0] = source[0];
7676 data[1] = newBitmask;
7682 * This function is like
7683 * [`Object.keys`](http://ecma-international.org/ecma-262/7.0/#sec-object.keys)
7684 * except that it includes inherited enumerable properties.
7687 * @param {Object} object The object to query.
7688 * @returns {Array} Returns the array of property names.
7690 function nativeKeysIn(object) {
7692 if (object != null) {
7693 for (var key in Object(object)) {
7701 * Converts `value` to a string using `Object.prototype.toString`.
7704 * @param {*} value The value to convert.
7705 * @returns {string} Returns the converted string.
7707 function objectToString(value) {
7708 return nativeObjectToString.call(value);
7712 * A specialized version of `baseRest` which transforms the rest array.
7715 * @param {Function} func The function to apply a rest parameter to.
7716 * @param {number} [start=func.length-1] The start position of the rest parameter.
7717 * @param {Function} transform The rest array transform.
7718 * @returns {Function} Returns the new function.
7720 function overRest(func, start, transform) {
7721 start = nativeMax(start === undefined ? (func.length - 1) : start, 0);
7723 var args = arguments,
7725 length = nativeMax(args.length - start, 0),
7726 array = Array(length);
7728 while (++index < length) {
7729 array[index] = args[start + index];
7732 var otherArgs = Array(start + 1);
7733 while (++index < start) {
7734 otherArgs[index] = args[index];
7736 otherArgs[start] = transform(array);
7737 return apply(func, this, otherArgs);
7742 * Gets the parent value at `path` of `object`.
7745 * @param {Object} object The object to query.
7746 * @param {Array} path The path to get the parent value of.
7747 * @returns {*} Returns the parent value.
7749 function parent(object, path) {
7750 return path.length < 2 ? object : baseGet(object, baseSlice(path, 0, -1));
7754 * Reorder `array` according to the specified indexes where the element at
7755 * the first index is assigned as the first element, the element at
7756 * the second index is assigned as the second element, and so on.
7759 * @param {Array} array The array to reorder.
7760 * @param {Array} indexes The arranged array indexes.
7761 * @returns {Array} Returns `array`.
7763 function reorder(array, indexes) {
7764 var arrLength = array.length,
7765 length = nativeMin(indexes.length, arrLength),
7766 oldArray = copyArray(array);
7769 var index = indexes[length];
7770 array[length] = isIndex(index, arrLength) ? oldArray[index] : undefined;
7776 * Gets the value at `key`, unless `key` is "__proto__" or "constructor".
7779 * @param {Object} object The object to query.
7780 * @param {string} key The key of the property to get.
7781 * @returns {*} Returns the property value.
7783 function safeGet(object, key) {
7784 if (key === 'constructor' && typeof object[key] === 'function') {
7788 if (key == '__proto__') {
7796 * Sets metadata for `func`.
7798 * **Note:** If this function becomes hot, i.e. is invoked a lot in a short
7799 * period of time, it will trip its breaker and transition to an identity
7800 * function to avoid garbage collection pauses in V8. See
7801 * [V8 issue 2070](https://bugs.chromium.org/p/v8/issues/detail?id=2070)
7805 * @param {Function} func The function to associate metadata with.
7806 * @param {*} data The metadata.
7807 * @returns {Function} Returns `func`.
7809 var setData = shortOut(baseSetData);
7812 * A simple wrapper around the global [`setTimeout`](https://mdn.io/setTimeout).
7815 * @param {Function} func The function to delay.
7816 * @param {number} wait The number of milliseconds to delay invocation.
7817 * @returns {number|Object} Returns the timer id or timeout object.
7819 var setTimeout = ctxSetTimeout || function(func, wait) {
7820 return root.setTimeout(func, wait);
7824 * Sets the `toString` method of `func` to return `string`.
7827 * @param {Function} func The function to modify.
7828 * @param {Function} string The `toString` result.
7829 * @returns {Function} Returns `func`.
7831 var setToString = shortOut(baseSetToString);
7834 * Sets the `toString` method of `wrapper` to mimic the source of `reference`
7835 * with wrapper details in a comment at the top of the source body.
7838 * @param {Function} wrapper The function to modify.
7839 * @param {Function} reference The reference function.
7840 * @param {number} bitmask The bitmask flags. See `createWrap` for more details.
7841 * @returns {Function} Returns `wrapper`.
7843 function setWrapToString(wrapper, reference, bitmask) {
7844 var source = (reference + '');
7845 return setToString(wrapper, insertWrapDetails(source, updateWrapDetails(getWrapDetails(source), bitmask)));
7849 * Creates a function that'll short out and invoke `identity` instead
7850 * of `func` when it's called `HOT_COUNT` or more times in `HOT_SPAN`
7854 * @param {Function} func The function to restrict.
7855 * @returns {Function} Returns the new shortable function.
7857 function shortOut(func) {
7862 var stamp = nativeNow(),
7863 remaining = HOT_SPAN - (stamp - lastCalled);
7866 if (remaining > 0) {
7867 if (++count >= HOT_COUNT) {
7868 return arguments[0];
7873 return func.apply(undefined, arguments);
7878 * A specialized version of `_.shuffle` which mutates and sets the size of `array`.
7881 * @param {Array} array The array to shuffle.
7882 * @param {number} [size=array.length] The size of `array`.
7883 * @returns {Array} Returns `array`.
7885 function shuffleSelf(array, size) {
7887 length = array.length,
7888 lastIndex = length - 1;
7890 size = size === undefined ? length : size;
7891 while (++index < size) {
7892 var rand = baseRandom(index, lastIndex),
7893 value = array[rand];
7895 array[rand] = array[index];
7896 array[index] = value;
7898 array.length = size;
7903 * Converts `string` to a property path array.
7906 * @param {string} string The string to convert.
7907 * @returns {Array} Returns the property path array.
7909 var stringToPath = memoizeCapped(function(string) {
7911 if (string.charCodeAt(0) === 46 /* . */) {
7914 string.replace(rePropName, function(match, number, quote, subString) {
7915 result.push(quote ? subString.replace(reEscapeChar, '$1') : (number || match));
7921 * Converts `value` to a string key if it's not a string or symbol.
7924 * @param {*} value The value to inspect.
7925 * @returns {string|symbol} Returns the key.
7927 function toKey(value) {
7928 if (typeof value == 'string' || isSymbol(value)) {
7931 var result = (value + '');
7932 return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;
7936 * Converts `func` to its source code.
7939 * @param {Function} func The function to convert.
7940 * @returns {string} Returns the source code.
7942 function toSource(func) {
7945 return funcToString.call(func);
7955 * Updates wrapper `details` based on `bitmask` flags.
7958 * @returns {Array} details The details to modify.
7959 * @param {number} bitmask The bitmask flags. See `createWrap` for more details.
7960 * @returns {Array} Returns `details`.
7962 function updateWrapDetails(details, bitmask) {
7963 arrayEach(wrapFlags, function(pair) {
7964 var value = '_.' + pair[0];
7965 if ((bitmask & pair[1]) && !arrayIncludes(details, value)) {
7966 details.push(value);
7969 return details.sort();
7973 * Creates a clone of `wrapper`.
7976 * @param {Object} wrapper The wrapper to clone.
7977 * @returns {Object} Returns the cloned wrapper.
7979 function wrapperClone(wrapper) {
7980 if (wrapper instanceof LazyWrapper) {
7981 return wrapper.clone();
7983 var result = new LodashWrapper(wrapper.__wrapped__, wrapper.__chain__);
7984 result.__actions__ = copyArray(wrapper.__actions__);
7985 result.__index__ = wrapper.__index__;
7986 result.__values__ = wrapper.__values__;
7990 /*------------------------------------------------------------------------*/
7993 * Creates an array of elements split into groups the length of `size`.
7994 * If `array` can't be split evenly, the final chunk will be the remaining
8001 * @param {Array} array The array to process.
8002 * @param {number} [size=1] The length of each chunk
8003 * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
8004 * @returns {Array} Returns the new array of chunks.
8007 * _.chunk(['a', 'b', 'c', 'd'], 2);
8008 * // => [['a', 'b'], ['c', 'd']]
8010 * _.chunk(['a', 'b', 'c', 'd'], 3);
8011 * // => [['a', 'b', 'c'], ['d']]
8013 function chunk(array, size, guard) {
8014 if ((guard ? isIterateeCall(array, size, guard) : size === undefined)) {
8017 size = nativeMax(toInteger(size), 0);
8019 var length = array == null ? 0 : array.length;
8020 if (!length || size < 1) {
8025 result = Array(nativeCeil(length / size));
8027 while (index < length) {
8028 result[resIndex++] = baseSlice(array, index, (index += size));
8034 * Creates an array with all falsey values removed. The values `false`, `null`,
8035 * `0`, `""`, `undefined`, and `NaN` are falsey.
8041 * @param {Array} array The array to compact.
8042 * @returns {Array} Returns the new array of filtered values.
8045 * _.compact([0, 1, false, 2, '', 3]);
8048 function compact(array) {
8050 length = array == null ? 0 : array.length,
8054 while (++index < length) {
8055 var value = array[index];
8057 result[resIndex++] = value;
8064 * Creates a new array concatenating `array` with any additional arrays
8071 * @param {Array} array The array to concatenate.
8072 * @param {...*} [values] The values to concatenate.
8073 * @returns {Array} Returns the new concatenated array.
8077 * var other = _.concat(array, 2, [3], [[4]]);
8079 * console.log(other);
8080 * // => [1, 2, 3, [4]]
8082 * console.log(array);
8086 var length = arguments.length;
8090 var args = Array(length - 1),
8091 array = arguments[0],
8095 args[index - 1] = arguments[index];
8097 return arrayPush(isArray(array) ? copyArray(array) : [array], baseFlatten(args, 1));
8101 * Creates an array of `array` values not included in the other given arrays
8102 * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
8103 * for equality comparisons. The order and references of result values are
8104 * determined by the first array.
8106 * **Note:** Unlike `_.pullAll`, this method returns a new array.
8112 * @param {Array} array The array to inspect.
8113 * @param {...Array} [values] The values to exclude.
8114 * @returns {Array} Returns the new array of filtered values.
8115 * @see _.without, _.xor
8118 * _.difference([2, 1], [2, 3]);
8121 var difference = baseRest(function(array, values) {
8122 return isArrayLikeObject(array)
8123 ? baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true))
8128 * This method is like `_.difference` except that it accepts `iteratee` which
8129 * is invoked for each element of `array` and `values` to generate the criterion
8130 * by which they're compared. The order and references of result values are
8131 * determined by the first array. The iteratee is invoked with one argument:
8134 * **Note:** Unlike `_.pullAllBy`, this method returns a new array.
8140 * @param {Array} array The array to inspect.
8141 * @param {...Array} [values] The values to exclude.
8142 * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
8143 * @returns {Array} Returns the new array of filtered values.
8146 * _.differenceBy([2.1, 1.2], [2.3, 3.4], Math.floor);
8149 * // The `_.property` iteratee shorthand.
8150 * _.differenceBy([{ 'x': 2 }, { 'x': 1 }], [{ 'x': 1 }], 'x');
8151 * // => [{ 'x': 2 }]
8153 var differenceBy = baseRest(function(array, values) {
8154 var iteratee = last(values);
8155 if (isArrayLikeObject(iteratee)) {
8156 iteratee = undefined;
8158 return isArrayLikeObject(array)
8159 ? baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true), getIteratee(iteratee, 2))
8164 * This method is like `_.difference` except that it accepts `comparator`
8165 * which is invoked to compare elements of `array` to `values`. The order and
8166 * references of result values are determined by the first array. The comparator
8167 * is invoked with two arguments: (arrVal, othVal).
8169 * **Note:** Unlike `_.pullAllWith`, this method returns a new array.
8175 * @param {Array} array The array to inspect.
8176 * @param {...Array} [values] The values to exclude.
8177 * @param {Function} [comparator] The comparator invoked per element.
8178 * @returns {Array} Returns the new array of filtered values.
8181 * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
8183 * _.differenceWith(objects, [{ 'x': 1, 'y': 2 }], _.isEqual);
8184 * // => [{ 'x': 2, 'y': 1 }]
8186 var differenceWith = baseRest(function(array, values) {
8187 var comparator = last(values);
8188 if (isArrayLikeObject(comparator)) {
8189 comparator = undefined;
8191 return isArrayLikeObject(array)
8192 ? baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true), undefined, comparator)
8197 * Creates a slice of `array` with `n` elements dropped from the beginning.
8203 * @param {Array} array The array to query.
8204 * @param {number} [n=1] The number of elements to drop.
8205 * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
8206 * @returns {Array} Returns the slice of `array`.
8209 * _.drop([1, 2, 3]);
8212 * _.drop([1, 2, 3], 2);
8215 * _.drop([1, 2, 3], 5);
8218 * _.drop([1, 2, 3], 0);
8221 function drop(array, n, guard) {
8222 var length = array == null ? 0 : array.length;
8226 n = (guard || n === undefined) ? 1 : toInteger(n);
8227 return baseSlice(array, n < 0 ? 0 : n, length);
8231 * Creates a slice of `array` with `n` elements dropped from the end.
8237 * @param {Array} array The array to query.
8238 * @param {number} [n=1] The number of elements to drop.
8239 * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
8240 * @returns {Array} Returns the slice of `array`.
8243 * _.dropRight([1, 2, 3]);
8246 * _.dropRight([1, 2, 3], 2);
8249 * _.dropRight([1, 2, 3], 5);
8252 * _.dropRight([1, 2, 3], 0);
8255 function dropRight(array, n, guard) {
8256 var length = array == null ? 0 : array.length;
8260 n = (guard || n === undefined) ? 1 : toInteger(n);
8262 return baseSlice(array, 0, n < 0 ? 0 : n);
8266 * Creates a slice of `array` excluding elements dropped from the end.
8267 * Elements are dropped until `predicate` returns falsey. The predicate is
8268 * invoked with three arguments: (value, index, array).
8274 * @param {Array} array The array to query.
8275 * @param {Function} [predicate=_.identity] The function invoked per iteration.
8276 * @returns {Array} Returns the slice of `array`.
8280 * { 'user': 'barney', 'active': true },
8281 * { 'user': 'fred', 'active': false },
8282 * { 'user': 'pebbles', 'active': false }
8285 * _.dropRightWhile(users, function(o) { return !o.active; });
8286 * // => objects for ['barney']
8288 * // The `_.matches` iteratee shorthand.
8289 * _.dropRightWhile(users, { 'user': 'pebbles', 'active': false });
8290 * // => objects for ['barney', 'fred']
8292 * // The `_.matchesProperty` iteratee shorthand.
8293 * _.dropRightWhile(users, ['active', false]);
8294 * // => objects for ['barney']
8296 * // The `_.property` iteratee shorthand.
8297 * _.dropRightWhile(users, 'active');
8298 * // => objects for ['barney', 'fred', 'pebbles']
8300 function dropRightWhile(array, predicate) {
8301 return (array && array.length)
8302 ? baseWhile(array, getIteratee(predicate, 3), true, true)
8307 * Creates a slice of `array` excluding elements dropped from the beginning.
8308 * Elements are dropped until `predicate` returns falsey. The predicate is
8309 * invoked with three arguments: (value, index, array).
8315 * @param {Array} array The array to query.
8316 * @param {Function} [predicate=_.identity] The function invoked per iteration.
8317 * @returns {Array} Returns the slice of `array`.
8321 * { 'user': 'barney', 'active': false },
8322 * { 'user': 'fred', 'active': false },
8323 * { 'user': 'pebbles', 'active': true }
8326 * _.dropWhile(users, function(o) { return !o.active; });
8327 * // => objects for ['pebbles']
8329 * // The `_.matches` iteratee shorthand.
8330 * _.dropWhile(users, { 'user': 'barney', 'active': false });
8331 * // => objects for ['fred', 'pebbles']
8333 * // The `_.matchesProperty` iteratee shorthand.
8334 * _.dropWhile(users, ['active', false]);
8335 * // => objects for ['pebbles']
8337 * // The `_.property` iteratee shorthand.
8338 * _.dropWhile(users, 'active');
8339 * // => objects for ['barney', 'fred', 'pebbles']
8341 function dropWhile(array, predicate) {
8342 return (array && array.length)
8343 ? baseWhile(array, getIteratee(predicate, 3), true)
8348 * Fills elements of `array` with `value` from `start` up to, but not
8351 * **Note:** This method mutates `array`.
8357 * @param {Array} array The array to fill.
8358 * @param {*} value The value to fill `array` with.
8359 * @param {number} [start=0] The start position.
8360 * @param {number} [end=array.length] The end position.
8361 * @returns {Array} Returns `array`.
8364 * var array = [1, 2, 3];
8366 * _.fill(array, 'a');
8367 * console.log(array);
8368 * // => ['a', 'a', 'a']
8370 * _.fill(Array(3), 2);
8373 * _.fill([4, 6, 8, 10], '*', 1, 3);
8374 * // => [4, '*', '*', 10]
8376 function fill(array, value, start, end) {
8377 var length = array == null ? 0 : array.length;
8381 if (start && typeof start != 'number' && isIterateeCall(array, value, start)) {
8385 return baseFill(array, value, start, end);
8389 * This method is like `_.find` except that it returns the index of the first
8390 * element `predicate` returns truthy for instead of the element itself.
8396 * @param {Array} array The array to inspect.
8397 * @param {Function} [predicate=_.identity] The function invoked per iteration.
8398 * @param {number} [fromIndex=0] The index to search from.
8399 * @returns {number} Returns the index of the found element, else `-1`.
8403 * { 'user': 'barney', 'active': false },
8404 * { 'user': 'fred', 'active': false },
8405 * { 'user': 'pebbles', 'active': true }
8408 * _.findIndex(users, function(o) { return o.user == 'barney'; });
8411 * // The `_.matches` iteratee shorthand.
8412 * _.findIndex(users, { 'user': 'fred', 'active': false });
8415 * // The `_.matchesProperty` iteratee shorthand.
8416 * _.findIndex(users, ['active', false]);
8419 * // The `_.property` iteratee shorthand.
8420 * _.findIndex(users, 'active');
8423 function findIndex(array, predicate, fromIndex) {
8424 var length = array == null ? 0 : array.length;
8428 var index = fromIndex == null ? 0 : toInteger(fromIndex);
8430 index = nativeMax(length + index, 0);
8432 return baseFindIndex(array, getIteratee(predicate, 3), index);
8436 * This method is like `_.findIndex` except that it iterates over elements
8437 * of `collection` from right to left.
8443 * @param {Array} array The array to inspect.
8444 * @param {Function} [predicate=_.identity] The function invoked per iteration.
8445 * @param {number} [fromIndex=array.length-1] The index to search from.
8446 * @returns {number} Returns the index of the found element, else `-1`.
8450 * { 'user': 'barney', 'active': true },
8451 * { 'user': 'fred', 'active': false },
8452 * { 'user': 'pebbles', 'active': false }
8455 * _.findLastIndex(users, function(o) { return o.user == 'pebbles'; });
8458 * // The `_.matches` iteratee shorthand.
8459 * _.findLastIndex(users, { 'user': 'barney', 'active': true });
8462 * // The `_.matchesProperty` iteratee shorthand.
8463 * _.findLastIndex(users, ['active', false]);
8466 * // The `_.property` iteratee shorthand.
8467 * _.findLastIndex(users, 'active');
8470 function findLastIndex(array, predicate, fromIndex) {
8471 var length = array == null ? 0 : array.length;
8475 var index = length - 1;
8476 if (fromIndex !== undefined) {
8477 index = toInteger(fromIndex);
8478 index = fromIndex < 0
8479 ? nativeMax(length + index, 0)
8480 : nativeMin(index, length - 1);
8482 return baseFindIndex(array, getIteratee(predicate, 3), index, true);
8486 * Flattens `array` a single level deep.
8492 * @param {Array} array The array to flatten.
8493 * @returns {Array} Returns the new flattened array.
8496 * _.flatten([1, [2, [3, [4]], 5]]);
8497 * // => [1, 2, [3, [4]], 5]
8499 function flatten(array) {
8500 var length = array == null ? 0 : array.length;
8501 return length ? baseFlatten(array, 1) : [];
8505 * Recursively flattens `array`.
8511 * @param {Array} array The array to flatten.
8512 * @returns {Array} Returns the new flattened array.
8515 * _.flattenDeep([1, [2, [3, [4]], 5]]);
8516 * // => [1, 2, 3, 4, 5]
8518 function flattenDeep(array) {
8519 var length = array == null ? 0 : array.length;
8520 return length ? baseFlatten(array, INFINITY) : [];
8524 * Recursively flatten `array` up to `depth` times.
8530 * @param {Array} array The array to flatten.
8531 * @param {number} [depth=1] The maximum recursion depth.
8532 * @returns {Array} Returns the new flattened array.
8535 * var array = [1, [2, [3, [4]], 5]];
8537 * _.flattenDepth(array, 1);
8538 * // => [1, 2, [3, [4]], 5]
8540 * _.flattenDepth(array, 2);
8541 * // => [1, 2, 3, [4], 5]
8543 function flattenDepth(array, depth) {
8544 var length = array == null ? 0 : array.length;
8548 depth = depth === undefined ? 1 : toInteger(depth);
8549 return baseFlatten(array, depth);
8553 * The inverse of `_.toPairs`; this method returns an object composed
8554 * from key-value `pairs`.
8560 * @param {Array} pairs The key-value pairs.
8561 * @returns {Object} Returns the new object.
8564 * _.fromPairs([['a', 1], ['b', 2]]);
8565 * // => { 'a': 1, 'b': 2 }
8567 function fromPairs(pairs) {
8569 length = pairs == null ? 0 : pairs.length,
8572 while (++index < length) {
8573 var pair = pairs[index];
8574 result[pair[0]] = pair[1];
8580 * Gets the first element of `array`.
8587 * @param {Array} array The array to query.
8588 * @returns {*} Returns the first element of `array`.
8591 * _.head([1, 2, 3]);
8597 function head(array) {
8598 return (array && array.length) ? array[0] : undefined;
8602 * Gets the index at which the first occurrence of `value` is found in `array`
8603 * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
8604 * for equality comparisons. If `fromIndex` is negative, it's used as the
8605 * offset from the end of `array`.
8611 * @param {Array} array The array to inspect.
8612 * @param {*} value The value to search for.
8613 * @param {number} [fromIndex=0] The index to search from.
8614 * @returns {number} Returns the index of the matched value, else `-1`.
8617 * _.indexOf([1, 2, 1, 2], 2);
8620 * // Search from the `fromIndex`.
8621 * _.indexOf([1, 2, 1, 2], 2, 2);
8624 function indexOf(array, value, fromIndex) {
8625 var length = array == null ? 0 : array.length;
8629 var index = fromIndex == null ? 0 : toInteger(fromIndex);
8631 index = nativeMax(length + index, 0);
8633 return baseIndexOf(array, value, index);
8637 * Gets all but the last element of `array`.
8643 * @param {Array} array The array to query.
8644 * @returns {Array} Returns the slice of `array`.
8647 * _.initial([1, 2, 3]);
8650 function initial(array) {
8651 var length = array == null ? 0 : array.length;
8652 return length ? baseSlice(array, 0, -1) : [];
8656 * Creates an array of unique values that are included in all given arrays
8657 * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
8658 * for equality comparisons. The order and references of result values are
8659 * determined by the first array.
8665 * @param {...Array} [arrays] The arrays to inspect.
8666 * @returns {Array} Returns the new array of intersecting values.
8669 * _.intersection([2, 1], [2, 3]);
8672 var intersection = baseRest(function(arrays) {
8673 var mapped = arrayMap(arrays, castArrayLikeObject);
8674 return (mapped.length && mapped[0] === arrays[0])
8675 ? baseIntersection(mapped)
8680 * This method is like `_.intersection` except that it accepts `iteratee`
8681 * which is invoked for each element of each `arrays` to generate the criterion
8682 * by which they're compared. The order and references of result values are
8683 * determined by the first array. The iteratee is invoked with one argument:
8690 * @param {...Array} [arrays] The arrays to inspect.
8691 * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
8692 * @returns {Array} Returns the new array of intersecting values.
8695 * _.intersectionBy([2.1, 1.2], [2.3, 3.4], Math.floor);
8698 * // The `_.property` iteratee shorthand.
8699 * _.intersectionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');
8700 * // => [{ 'x': 1 }]
8702 var intersectionBy = baseRest(function(arrays) {
8703 var iteratee = last(arrays),
8704 mapped = arrayMap(arrays, castArrayLikeObject);
8706 if (iteratee === last(mapped)) {
8707 iteratee = undefined;
8711 return (mapped.length && mapped[0] === arrays[0])
8712 ? baseIntersection(mapped, getIteratee(iteratee, 2))
8717 * This method is like `_.intersection` except that it accepts `comparator`
8718 * which is invoked to compare elements of `arrays`. The order and references
8719 * of result values are determined by the first array. The comparator is
8720 * invoked with two arguments: (arrVal, othVal).
8726 * @param {...Array} [arrays] The arrays to inspect.
8727 * @param {Function} [comparator] The comparator invoked per element.
8728 * @returns {Array} Returns the new array of intersecting values.
8731 * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
8732 * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }];
8734 * _.intersectionWith(objects, others, _.isEqual);
8735 * // => [{ 'x': 1, 'y': 2 }]
8737 var intersectionWith = baseRest(function(arrays) {
8738 var comparator = last(arrays),
8739 mapped = arrayMap(arrays, castArrayLikeObject);
8741 comparator = typeof comparator == 'function' ? comparator : undefined;
8745 return (mapped.length && mapped[0] === arrays[0])
8746 ? baseIntersection(mapped, undefined, comparator)
8751 * Converts all elements in `array` into a string separated by `separator`.
8757 * @param {Array} array The array to convert.
8758 * @param {string} [separator=','] The element separator.
8759 * @returns {string} Returns the joined string.
8762 * _.join(['a', 'b', 'c'], '~');
8765 function join(array, separator) {
8766 return array == null ? '' : nativeJoin.call(array, separator);
8770 * Gets the last element of `array`.
8776 * @param {Array} array The array to query.
8777 * @returns {*} Returns the last element of `array`.
8780 * _.last([1, 2, 3]);
8783 function last(array) {
8784 var length = array == null ? 0 : array.length;
8785 return length ? array[length - 1] : undefined;
8789 * This method is like `_.indexOf` except that it iterates over elements of
8790 * `array` from right to left.
8796 * @param {Array} array The array to inspect.
8797 * @param {*} value The value to search for.
8798 * @param {number} [fromIndex=array.length-1] The index to search from.
8799 * @returns {number} Returns the index of the matched value, else `-1`.
8802 * _.lastIndexOf([1, 2, 1, 2], 2);
8805 * // Search from the `fromIndex`.
8806 * _.lastIndexOf([1, 2, 1, 2], 2, 2);
8809 function lastIndexOf(array, value, fromIndex) {
8810 var length = array == null ? 0 : array.length;
8815 if (fromIndex !== undefined) {
8816 index = toInteger(fromIndex);
8817 index = index < 0 ? nativeMax(length + index, 0) : nativeMin(index, length - 1);
8819 return value === value
8820 ? strictLastIndexOf(array, value, index)
8821 : baseFindIndex(array, baseIsNaN, index, true);
8825 * Gets the element at index `n` of `array`. If `n` is negative, the nth
8826 * element from the end is returned.
8832 * @param {Array} array The array to query.
8833 * @param {number} [n=0] The index of the element to return.
8834 * @returns {*} Returns the nth element of `array`.
8837 * var array = ['a', 'b', 'c', 'd'];
8845 function nth(array, n) {
8846 return (array && array.length) ? baseNth(array, toInteger(n)) : undefined;
8850 * Removes all given values from `array` using
8851 * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
8852 * for equality comparisons.
8854 * **Note:** Unlike `_.without`, this method mutates `array`. Use `_.remove`
8855 * to remove elements from an array by predicate.
8861 * @param {Array} array The array to modify.
8862 * @param {...*} [values] The values to remove.
8863 * @returns {Array} Returns `array`.
8866 * var array = ['a', 'b', 'c', 'a', 'b', 'c'];
8868 * _.pull(array, 'a', 'c');
8869 * console.log(array);
8872 var pull = baseRest(pullAll);
8875 * This method is like `_.pull` except that it accepts an array of values to remove.
8877 * **Note:** Unlike `_.difference`, this method mutates `array`.
8883 * @param {Array} array The array to modify.
8884 * @param {Array} values The values to remove.
8885 * @returns {Array} Returns `array`.
8888 * var array = ['a', 'b', 'c', 'a', 'b', 'c'];
8890 * _.pullAll(array, ['a', 'c']);
8891 * console.log(array);
8894 function pullAll(array, values) {
8895 return (array && array.length && values && values.length)
8896 ? basePullAll(array, values)
8901 * This method is like `_.pullAll` except that it accepts `iteratee` which is
8902 * invoked for each element of `array` and `values` to generate the criterion
8903 * by which they're compared. The iteratee is invoked with one argument: (value).
8905 * **Note:** Unlike `_.differenceBy`, this method mutates `array`.
8911 * @param {Array} array The array to modify.
8912 * @param {Array} values The values to remove.
8913 * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
8914 * @returns {Array} Returns `array`.
8917 * var array = [{ 'x': 1 }, { 'x': 2 }, { 'x': 3 }, { 'x': 1 }];
8919 * _.pullAllBy(array, [{ 'x': 1 }, { 'x': 3 }], 'x');
8920 * console.log(array);
8921 * // => [{ 'x': 2 }]
8923 function pullAllBy(array, values, iteratee) {
8924 return (array && array.length && values && values.length)
8925 ? basePullAll(array, values, getIteratee(iteratee, 2))
8930 * This method is like `_.pullAll` except that it accepts `comparator` which
8931 * is invoked to compare elements of `array` to `values`. The comparator is
8932 * invoked with two arguments: (arrVal, othVal).
8934 * **Note:** Unlike `_.differenceWith`, this method mutates `array`.
8940 * @param {Array} array The array to modify.
8941 * @param {Array} values The values to remove.
8942 * @param {Function} [comparator] The comparator invoked per element.
8943 * @returns {Array} Returns `array`.
8946 * var array = [{ 'x': 1, 'y': 2 }, { 'x': 3, 'y': 4 }, { 'x': 5, 'y': 6 }];
8948 * _.pullAllWith(array, [{ 'x': 3, 'y': 4 }], _.isEqual);
8949 * console.log(array);
8950 * // => [{ 'x': 1, 'y': 2 }, { 'x': 5, 'y': 6 }]
8952 function pullAllWith(array, values, comparator) {
8953 return (array && array.length && values && values.length)
8954 ? basePullAll(array, values, undefined, comparator)
8959 * Removes elements from `array` corresponding to `indexes` and returns an
8960 * array of removed elements.
8962 * **Note:** Unlike `_.at`, this method mutates `array`.
8968 * @param {Array} array The array to modify.
8969 * @param {...(number|number[])} [indexes] The indexes of elements to remove.
8970 * @returns {Array} Returns the new array of removed elements.
8973 * var array = ['a', 'b', 'c', 'd'];
8974 * var pulled = _.pullAt(array, [1, 3]);
8976 * console.log(array);
8979 * console.log(pulled);
8982 var pullAt = flatRest(function(array, indexes) {
8983 var length = array == null ? 0 : array.length,
8984 result = baseAt(array, indexes);
8986 basePullAt(array, arrayMap(indexes, function(index) {
8987 return isIndex(index, length) ? +index : index;
8988 }).sort(compareAscending));
8994 * Removes all elements from `array` that `predicate` returns truthy for
8995 * and returns an array of the removed elements. The predicate is invoked
8996 * with three arguments: (value, index, array).
8998 * **Note:** Unlike `_.filter`, this method mutates `array`. Use `_.pull`
8999 * to pull elements from an array by value.
9005 * @param {Array} array The array to modify.
9006 * @param {Function} [predicate=_.identity] The function invoked per iteration.
9007 * @returns {Array} Returns the new array of removed elements.
9010 * var array = [1, 2, 3, 4];
9011 * var evens = _.remove(array, function(n) {
9012 * return n % 2 == 0;
9015 * console.log(array);
9018 * console.log(evens);
9021 function remove(array, predicate) {
9023 if (!(array && array.length)) {
9028 length = array.length;
9030 predicate = getIteratee(predicate, 3);
9031 while (++index < length) {
9032 var value = array[index];
9033 if (predicate(value, index, array)) {
9035 indexes.push(index);
9038 basePullAt(array, indexes);
9043 * Reverses `array` so that the first element becomes the last, the second
9044 * element becomes the second to last, and so on.
9046 * **Note:** This method mutates `array` and is based on
9047 * [`Array#reverse`](https://mdn.io/Array/reverse).
9053 * @param {Array} array The array to modify.
9054 * @returns {Array} Returns `array`.
9057 * var array = [1, 2, 3];
9062 * console.log(array);
9065 function reverse(array) {
9066 return array == null ? array : nativeReverse.call(array);
9070 * Creates a slice of `array` from `start` up to, but not including, `end`.
9072 * **Note:** This method is used instead of
9073 * [`Array#slice`](https://mdn.io/Array/slice) to ensure dense arrays are
9080 * @param {Array} array The array to slice.
9081 * @param {number} [start=0] The start position.
9082 * @param {number} [end=array.length] The end position.
9083 * @returns {Array} Returns the slice of `array`.
9085 function slice(array, start, end) {
9086 var length = array == null ? 0 : array.length;
9090 if (end && typeof end != 'number' && isIterateeCall(array, start, end)) {
9095 start = start == null ? 0 : toInteger(start);
9096 end = end === undefined ? length : toInteger(end);
9098 return baseSlice(array, start, end);
9102 * Uses a binary search to determine the lowest index at which `value`
9103 * should be inserted into `array` in order to maintain its sort order.
9109 * @param {Array} array The sorted array to inspect.
9110 * @param {*} value The value to evaluate.
9111 * @returns {number} Returns the index at which `value` should be inserted
9115 * _.sortedIndex([30, 50], 40);
9118 function sortedIndex(array, value) {
9119 return baseSortedIndex(array, value);
9123 * This method is like `_.sortedIndex` except that it accepts `iteratee`
9124 * which is invoked for `value` and each element of `array` to compute their
9125 * sort ranking. The iteratee is invoked with one argument: (value).
9131 * @param {Array} array The sorted array to inspect.
9132 * @param {*} value The value to evaluate.
9133 * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
9134 * @returns {number} Returns the index at which `value` should be inserted
9138 * var objects = [{ 'x': 4 }, { 'x': 5 }];
9140 * _.sortedIndexBy(objects, { 'x': 4 }, function(o) { return o.x; });
9143 * // The `_.property` iteratee shorthand.
9144 * _.sortedIndexBy(objects, { 'x': 4 }, 'x');
9147 function sortedIndexBy(array, value, iteratee) {
9148 return baseSortedIndexBy(array, value, getIteratee(iteratee, 2));
9152 * This method is like `_.indexOf` except that it performs a binary
9153 * search on a sorted `array`.
9159 * @param {Array} array The array to inspect.
9160 * @param {*} value The value to search for.
9161 * @returns {number} Returns the index of the matched value, else `-1`.
9164 * _.sortedIndexOf([4, 5, 5, 5, 6], 5);
9167 function sortedIndexOf(array, value) {
9168 var length = array == null ? 0 : array.length;
9170 var index = baseSortedIndex(array, value);
9171 if (index < length && eq(array[index], value)) {
9179 * This method is like `_.sortedIndex` except that it returns the highest
9180 * index at which `value` should be inserted into `array` in order to
9181 * maintain its sort order.
9187 * @param {Array} array The sorted array to inspect.
9188 * @param {*} value The value to evaluate.
9189 * @returns {number} Returns the index at which `value` should be inserted
9193 * _.sortedLastIndex([4, 5, 5, 5, 6], 5);
9196 function sortedLastIndex(array, value) {
9197 return baseSortedIndex(array, value, true);
9201 * This method is like `_.sortedLastIndex` except that it accepts `iteratee`
9202 * which is invoked for `value` and each element of `array` to compute their
9203 * sort ranking. The iteratee is invoked with one argument: (value).
9209 * @param {Array} array The sorted array to inspect.
9210 * @param {*} value The value to evaluate.
9211 * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
9212 * @returns {number} Returns the index at which `value` should be inserted
9216 * var objects = [{ 'x': 4 }, { 'x': 5 }];
9218 * _.sortedLastIndexBy(objects, { 'x': 4 }, function(o) { return o.x; });
9221 * // The `_.property` iteratee shorthand.
9222 * _.sortedLastIndexBy(objects, { 'x': 4 }, 'x');
9225 function sortedLastIndexBy(array, value, iteratee) {
9226 return baseSortedIndexBy(array, value, getIteratee(iteratee, 2), true);
9230 * This method is like `_.lastIndexOf` except that it performs a binary
9231 * search on a sorted `array`.
9237 * @param {Array} array The array to inspect.
9238 * @param {*} value The value to search for.
9239 * @returns {number} Returns the index of the matched value, else `-1`.
9242 * _.sortedLastIndexOf([4, 5, 5, 5, 6], 5);
9245 function sortedLastIndexOf(array, value) {
9246 var length = array == null ? 0 : array.length;
9248 var index = baseSortedIndex(array, value, true) - 1;
9249 if (eq(array[index], value)) {
9257 * This method is like `_.uniq` except that it's designed and optimized
9258 * for sorted arrays.
9264 * @param {Array} array The array to inspect.
9265 * @returns {Array} Returns the new duplicate free array.
9268 * _.sortedUniq([1, 1, 2]);
9271 function sortedUniq(array) {
9272 return (array && array.length)
9273 ? baseSortedUniq(array)
9278 * This method is like `_.uniqBy` except that it's designed and optimized
9279 * for sorted arrays.
9285 * @param {Array} array The array to inspect.
9286 * @param {Function} [iteratee] The iteratee invoked per element.
9287 * @returns {Array} Returns the new duplicate free array.
9290 * _.sortedUniqBy([1.1, 1.2, 2.3, 2.4], Math.floor);
9293 function sortedUniqBy(array, iteratee) {
9294 return (array && array.length)
9295 ? baseSortedUniq(array, getIteratee(iteratee, 2))
9300 * Gets all but the first element of `array`.
9306 * @param {Array} array The array to query.
9307 * @returns {Array} Returns the slice of `array`.
9310 * _.tail([1, 2, 3]);
9313 function tail(array) {
9314 var length = array == null ? 0 : array.length;
9315 return length ? baseSlice(array, 1, length) : [];
9319 * Creates a slice of `array` with `n` elements taken from the beginning.
9325 * @param {Array} array The array to query.
9326 * @param {number} [n=1] The number of elements to take.
9327 * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
9328 * @returns {Array} Returns the slice of `array`.
9331 * _.take([1, 2, 3]);
9334 * _.take([1, 2, 3], 2);
9337 * _.take([1, 2, 3], 5);
9340 * _.take([1, 2, 3], 0);
9343 function take(array, n, guard) {
9344 if (!(array && array.length)) {
9347 n = (guard || n === undefined) ? 1 : toInteger(n);
9348 return baseSlice(array, 0, n < 0 ? 0 : n);
9352 * Creates a slice of `array` with `n` elements taken from the end.
9358 * @param {Array} array The array to query.
9359 * @param {number} [n=1] The number of elements to take.
9360 * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
9361 * @returns {Array} Returns the slice of `array`.
9364 * _.takeRight([1, 2, 3]);
9367 * _.takeRight([1, 2, 3], 2);
9370 * _.takeRight([1, 2, 3], 5);
9373 * _.takeRight([1, 2, 3], 0);
9376 function takeRight(array, n, guard) {
9377 var length = array == null ? 0 : array.length;
9381 n = (guard || n === undefined) ? 1 : toInteger(n);
9383 return baseSlice(array, n < 0 ? 0 : n, length);
9387 * Creates a slice of `array` with elements taken from the end. Elements are
9388 * taken until `predicate` returns falsey. The predicate is invoked with
9389 * three arguments: (value, index, array).
9395 * @param {Array} array The array to query.
9396 * @param {Function} [predicate=_.identity] The function invoked per iteration.
9397 * @returns {Array} Returns the slice of `array`.
9401 * { 'user': 'barney', 'active': true },
9402 * { 'user': 'fred', 'active': false },
9403 * { 'user': 'pebbles', 'active': false }
9406 * _.takeRightWhile(users, function(o) { return !o.active; });
9407 * // => objects for ['fred', 'pebbles']
9409 * // The `_.matches` iteratee shorthand.
9410 * _.takeRightWhile(users, { 'user': 'pebbles', 'active': false });
9411 * // => objects for ['pebbles']
9413 * // The `_.matchesProperty` iteratee shorthand.
9414 * _.takeRightWhile(users, ['active', false]);
9415 * // => objects for ['fred', 'pebbles']
9417 * // The `_.property` iteratee shorthand.
9418 * _.takeRightWhile(users, 'active');
9421 function takeRightWhile(array, predicate) {
9422 return (array && array.length)
9423 ? baseWhile(array, getIteratee(predicate, 3), false, true)
9428 * Creates a slice of `array` with elements taken from the beginning. Elements
9429 * are taken until `predicate` returns falsey. The predicate is invoked with
9430 * three arguments: (value, index, array).
9436 * @param {Array} array The array to query.
9437 * @param {Function} [predicate=_.identity] The function invoked per iteration.
9438 * @returns {Array} Returns the slice of `array`.
9442 * { 'user': 'barney', 'active': false },
9443 * { 'user': 'fred', 'active': false },
9444 * { 'user': 'pebbles', 'active': true }
9447 * _.takeWhile(users, function(o) { return !o.active; });
9448 * // => objects for ['barney', 'fred']
9450 * // The `_.matches` iteratee shorthand.
9451 * _.takeWhile(users, { 'user': 'barney', 'active': false });
9452 * // => objects for ['barney']
9454 * // The `_.matchesProperty` iteratee shorthand.
9455 * _.takeWhile(users, ['active', false]);
9456 * // => objects for ['barney', 'fred']
9458 * // The `_.property` iteratee shorthand.
9459 * _.takeWhile(users, 'active');
9462 function takeWhile(array, predicate) {
9463 return (array && array.length)
9464 ? baseWhile(array, getIteratee(predicate, 3))
9469 * Creates an array of unique values, in order, from all given arrays using
9470 * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
9471 * for equality comparisons.
9477 * @param {...Array} [arrays] The arrays to inspect.
9478 * @returns {Array} Returns the new array of combined values.
9481 * _.union([2], [1, 2]);
9484 var union = baseRest(function(arrays) {
9485 return baseUniq(baseFlatten(arrays, 1, isArrayLikeObject, true));
9489 * This method is like `_.union` except that it accepts `iteratee` which is
9490 * invoked for each element of each `arrays` to generate the criterion by
9491 * which uniqueness is computed. Result values are chosen from the first
9492 * array in which the value occurs. The iteratee is invoked with one argument:
9499 * @param {...Array} [arrays] The arrays to inspect.
9500 * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
9501 * @returns {Array} Returns the new array of combined values.
9504 * _.unionBy([2.1], [1.2, 2.3], Math.floor);
9507 * // The `_.property` iteratee shorthand.
9508 * _.unionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');
9509 * // => [{ 'x': 1 }, { 'x': 2 }]
9511 var unionBy = baseRest(function(arrays) {
9512 var iteratee = last(arrays);
9513 if (isArrayLikeObject(iteratee)) {
9514 iteratee = undefined;
9516 return baseUniq(baseFlatten(arrays, 1, isArrayLikeObject, true), getIteratee(iteratee, 2));
9520 * This method is like `_.union` except that it accepts `comparator` which
9521 * is invoked to compare elements of `arrays`. Result values are chosen from
9522 * the first array in which the value occurs. The comparator is invoked
9523 * with two arguments: (arrVal, othVal).
9529 * @param {...Array} [arrays] The arrays to inspect.
9530 * @param {Function} [comparator] The comparator invoked per element.
9531 * @returns {Array} Returns the new array of combined values.
9534 * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
9535 * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }];
9537 * _.unionWith(objects, others, _.isEqual);
9538 * // => [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }, { 'x': 1, 'y': 1 }]
9540 var unionWith = baseRest(function(arrays) {
9541 var comparator = last(arrays);
9542 comparator = typeof comparator == 'function' ? comparator : undefined;
9543 return baseUniq(baseFlatten(arrays, 1, isArrayLikeObject, true), undefined, comparator);
9547 * Creates a duplicate-free version of an array, using
9548 * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
9549 * for equality comparisons, in which only the first occurrence of each element
9550 * is kept. The order of result values is determined by the order they occur
9557 * @param {Array} array The array to inspect.
9558 * @returns {Array} Returns the new duplicate free array.
9561 * _.uniq([2, 1, 2]);
9564 function uniq(array) {
9565 return (array && array.length) ? baseUniq(array) : [];
9569 * This method is like `_.uniq` except that it accepts `iteratee` which is
9570 * invoked for each element in `array` to generate the criterion by which
9571 * uniqueness is computed. The order of result values is determined by the
9572 * order they occur in the array. The iteratee is invoked with one argument:
9579 * @param {Array} array The array to inspect.
9580 * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
9581 * @returns {Array} Returns the new duplicate free array.
9584 * _.uniqBy([2.1, 1.2, 2.3], Math.floor);
9587 * // The `_.property` iteratee shorthand.
9588 * _.uniqBy([{ 'x': 1 }, { 'x': 2 }, { 'x': 1 }], 'x');
9589 * // => [{ 'x': 1 }, { 'x': 2 }]
9591 function uniqBy(array, iteratee) {
9592 return (array && array.length) ? baseUniq(array, getIteratee(iteratee, 2)) : [];
9596 * This method is like `_.uniq` except that it accepts `comparator` which
9597 * is invoked to compare elements of `array`. The order of result values is
9598 * determined by the order they occur in the array.The comparator is invoked
9599 * with two arguments: (arrVal, othVal).
9605 * @param {Array} array The array to inspect.
9606 * @param {Function} [comparator] The comparator invoked per element.
9607 * @returns {Array} Returns the new duplicate free array.
9610 * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }, { 'x': 1, 'y': 2 }];
9612 * _.uniqWith(objects, _.isEqual);
9613 * // => [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }]
9615 function uniqWith(array, comparator) {
9616 comparator = typeof comparator == 'function' ? comparator : undefined;
9617 return (array && array.length) ? baseUniq(array, undefined, comparator) : [];
9621 * This method is like `_.zip` except that it accepts an array of grouped
9622 * elements and creates an array regrouping the elements to their pre-zip
9629 * @param {Array} array The array of grouped elements to process.
9630 * @returns {Array} Returns the new array of regrouped elements.
9633 * var zipped = _.zip(['a', 'b'], [1, 2], [true, false]);
9634 * // => [['a', 1, true], ['b', 2, false]]
9637 * // => [['a', 'b'], [1, 2], [true, false]]
9639 function unzip(array) {
9640 if (!(array && array.length)) {
9644 array = arrayFilter(array, function(group) {
9645 if (isArrayLikeObject(group)) {
9646 length = nativeMax(group.length, length);
9650 return baseTimes(length, function(index) {
9651 return arrayMap(array, baseProperty(index));
9656 * This method is like `_.unzip` except that it accepts `iteratee` to specify
9657 * how regrouped values should be combined. The iteratee is invoked with the
9658 * elements of each group: (...group).
9664 * @param {Array} array The array of grouped elements to process.
9665 * @param {Function} [iteratee=_.identity] The function to combine
9667 * @returns {Array} Returns the new array of regrouped elements.
9670 * var zipped = _.zip([1, 2], [10, 20], [100, 200]);
9671 * // => [[1, 10, 100], [2, 20, 200]]
9673 * _.unzipWith(zipped, _.add);
9674 * // => [3, 30, 300]
9676 function unzipWith(array, iteratee) {
9677 if (!(array && array.length)) {
9680 var result = unzip(array);
9681 if (iteratee == null) {
9684 return arrayMap(result, function(group) {
9685 return apply(iteratee, undefined, group);
9690 * Creates an array excluding all given values using
9691 * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
9692 * for equality comparisons.
9694 * **Note:** Unlike `_.pull`, this method returns a new array.
9700 * @param {Array} array The array to inspect.
9701 * @param {...*} [values] The values to exclude.
9702 * @returns {Array} Returns the new array of filtered values.
9703 * @see _.difference, _.xor
9706 * _.without([2, 1, 2, 3], 1, 2);
9709 var without = baseRest(function(array, values) {
9710 return isArrayLikeObject(array)
9711 ? baseDifference(array, values)
9716 * Creates an array of unique values that is the
9717 * [symmetric difference](https://en.wikipedia.org/wiki/Symmetric_difference)
9718 * of the given arrays. The order of result values is determined by the order
9719 * they occur in the arrays.
9725 * @param {...Array} [arrays] The arrays to inspect.
9726 * @returns {Array} Returns the new array of filtered values.
9727 * @see _.difference, _.without
9730 * _.xor([2, 1], [2, 3]);
9733 var xor = baseRest(function(arrays) {
9734 return baseXor(arrayFilter(arrays, isArrayLikeObject));
9738 * This method is like `_.xor` except that it accepts `iteratee` which is
9739 * invoked for each element of each `arrays` to generate the criterion by
9740 * which by which they're compared. The order of result values is determined
9741 * by the order they occur in the arrays. The iteratee is invoked with one
9742 * argument: (value).
9748 * @param {...Array} [arrays] The arrays to inspect.
9749 * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
9750 * @returns {Array} Returns the new array of filtered values.
9753 * _.xorBy([2.1, 1.2], [2.3, 3.4], Math.floor);
9756 * // The `_.property` iteratee shorthand.
9757 * _.xorBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');
9758 * // => [{ 'x': 2 }]
9760 var xorBy = baseRest(function(arrays) {
9761 var iteratee = last(arrays);
9762 if (isArrayLikeObject(iteratee)) {
9763 iteratee = undefined;
9765 return baseXor(arrayFilter(arrays, isArrayLikeObject), getIteratee(iteratee, 2));
9769 * This method is like `_.xor` except that it accepts `comparator` which is
9770 * invoked to compare elements of `arrays`. The order of result values is
9771 * determined by the order they occur in the arrays. The comparator is invoked
9772 * with two arguments: (arrVal, othVal).
9778 * @param {...Array} [arrays] The arrays to inspect.
9779 * @param {Function} [comparator] The comparator invoked per element.
9780 * @returns {Array} Returns the new array of filtered values.
9783 * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
9784 * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }];
9786 * _.xorWith(objects, others, _.isEqual);
9787 * // => [{ 'x': 2, 'y': 1 }, { 'x': 1, 'y': 1 }]
9789 var xorWith = baseRest(function(arrays) {
9790 var comparator = last(arrays);
9791 comparator = typeof comparator == 'function' ? comparator : undefined;
9792 return baseXor(arrayFilter(arrays, isArrayLikeObject), undefined, comparator);
9796 * Creates an array of grouped elements, the first of which contains the
9797 * first elements of the given arrays, the second of which contains the
9798 * second elements of the given arrays, and so on.
9804 * @param {...Array} [arrays] The arrays to process.
9805 * @returns {Array} Returns the new array of grouped elements.
9808 * _.zip(['a', 'b'], [1, 2], [true, false]);
9809 * // => [['a', 1, true], ['b', 2, false]]
9811 var zip = baseRest(unzip);
9814 * This method is like `_.fromPairs` except that it accepts two arrays,
9815 * one of property identifiers and one of corresponding values.
9821 * @param {Array} [props=[]] The property identifiers.
9822 * @param {Array} [values=[]] The property values.
9823 * @returns {Object} Returns the new object.
9826 * _.zipObject(['a', 'b'], [1, 2]);
9827 * // => { 'a': 1, 'b': 2 }
9829 function zipObject(props, values) {
9830 return baseZipObject(props || [], values || [], assignValue);
9834 * This method is like `_.zipObject` except that it supports property paths.
9840 * @param {Array} [props=[]] The property identifiers.
9841 * @param {Array} [values=[]] The property values.
9842 * @returns {Object} Returns the new object.
9845 * _.zipObjectDeep(['a.b[0].c', 'a.b[1].d'], [1, 2]);
9846 * // => { 'a': { 'b': [{ 'c': 1 }, { 'd': 2 }] } }
9848 function zipObjectDeep(props, values) {
9849 return baseZipObject(props || [], values || [], baseSet);
9853 * This method is like `_.zip` except that it accepts `iteratee` to specify
9854 * how grouped values should be combined. The iteratee is invoked with the
9855 * elements of each group: (...group).
9861 * @param {...Array} [arrays] The arrays to process.
9862 * @param {Function} [iteratee=_.identity] The function to combine
9864 * @returns {Array} Returns the new array of grouped elements.
9867 * _.zipWith([1, 2], [10, 20], [100, 200], function(a, b, c) {
9872 var zipWith = baseRest(function(arrays) {
9873 var length = arrays.length,
9874 iteratee = length > 1 ? arrays[length - 1] : undefined;
9876 iteratee = typeof iteratee == 'function' ? (arrays.pop(), iteratee) : undefined;
9877 return unzipWith(arrays, iteratee);
9880 /*------------------------------------------------------------------------*/
9883 * Creates a `lodash` wrapper instance that wraps `value` with explicit method
9884 * chain sequences enabled. The result of such sequences must be unwrapped
9891 * @param {*} value The value to wrap.
9892 * @returns {Object} Returns the new `lodash` wrapper instance.
9896 * { 'user': 'barney', 'age': 36 },
9897 * { 'user': 'fred', 'age': 40 },
9898 * { 'user': 'pebbles', 'age': 1 }
9904 * .map(function(o) {
9905 * return o.user + ' is ' + o.age;
9909 * // => 'pebbles is 1'
9911 function chain(value) {
9912 var result = lodash(value);
9913 result.__chain__ = true;
9918 * This method invokes `interceptor` and returns `value`. The interceptor
9919 * is invoked with one argument; (value). The purpose of this method is to
9920 * "tap into" a method chain sequence in order to modify intermediate results.
9926 * @param {*} value The value to provide to `interceptor`.
9927 * @param {Function} interceptor The function to invoke.
9928 * @returns {*} Returns `value`.
9932 * .tap(function(array) {
9933 * // Mutate input array.
9940 function tap(value, interceptor) {
9946 * This method is like `_.tap` except that it returns the result of `interceptor`.
9947 * The purpose of this method is to "pass thru" values replacing intermediate
9948 * results in a method chain sequence.
9954 * @param {*} value The value to provide to `interceptor`.
9955 * @param {Function} interceptor The function to invoke.
9956 * @returns {*} Returns the result of `interceptor`.
9962 * .thru(function(value) {
9968 function thru(value, interceptor) {
9969 return interceptor(value);
9973 * This method is the wrapper version of `_.at`.
9979 * @param {...(string|string[])} [paths] The property paths to pick.
9980 * @returns {Object} Returns the new `lodash` wrapper instance.
9983 * var object = { 'a': [{ 'b': { 'c': 3 } }, 4] };
9985 * _(object).at(['a[0].b.c', 'a[1]']).value();
9988 var wrapperAt = flatRest(function(paths) {
9989 var length = paths.length,
9990 start = length ? paths[0] : 0,
9991 value = this.__wrapped__,
9992 interceptor = function(object) { return baseAt(object, paths); };
9994 if (length > 1 || this.__actions__.length ||
9995 !(value instanceof LazyWrapper) || !isIndex(start)) {
9996 return this.thru(interceptor);
9998 value = value.slice(start, +start + (length ? 1 : 0));
9999 value.__actions__.push({
10001 'args': [interceptor],
10002 'thisArg': undefined
10004 return new LodashWrapper(value, this.__chain__).thru(function(array) {
10005 if (length && !array.length) {
10006 array.push(undefined);
10013 * Creates a `lodash` wrapper instance with explicit method chain sequences enabled.
10019 * @returns {Object} Returns the new `lodash` wrapper instance.
10023 * { 'user': 'barney', 'age': 36 },
10024 * { 'user': 'fred', 'age': 40 }
10027 * // A sequence without explicit chaining.
10029 * // => { 'user': 'barney', 'age': 36 }
10031 * // A sequence with explicit chaining.
10037 * // => { 'user': 'barney' }
10039 function wrapperChain() {
10040 return chain(this);
10044 * Executes the chain sequence and returns the wrapped result.
10050 * @returns {Object} Returns the new `lodash` wrapper instance.
10053 * var array = [1, 2];
10054 * var wrapped = _(array).push(3);
10056 * console.log(array);
10059 * wrapped = wrapped.commit();
10060 * console.log(array);
10066 * console.log(array);
10069 function wrapperCommit() {
10070 return new LodashWrapper(this.value(), this.__chain__);
10074 * Gets the next value on a wrapped object following the
10075 * [iterator protocol](https://mdn.io/iteration_protocols#iterator).
10081 * @returns {Object} Returns the next iterator value.
10084 * var wrapped = _([1, 2]);
10087 * // => { 'done': false, 'value': 1 }
10090 * // => { 'done': false, 'value': 2 }
10093 * // => { 'done': true, 'value': undefined }
10095 function wrapperNext() {
10096 if (this.__values__ === undefined) {
10097 this.__values__ = toArray(this.value());
10099 var done = this.__index__ >= this.__values__.length,
10100 value = done ? undefined : this.__values__[this.__index__++];
10102 return { 'done': done, 'value': value };
10106 * Enables the wrapper to be iterable.
10108 * @name Symbol.iterator
10112 * @returns {Object} Returns the wrapper object.
10115 * var wrapped = _([1, 2]);
10117 * wrapped[Symbol.iterator]() === wrapped;
10120 * Array.from(wrapped);
10123 function wrapperToIterator() {
10128 * Creates a clone of the chain sequence planting `value` as the wrapped value.
10134 * @param {*} value The value to plant.
10135 * @returns {Object} Returns the new `lodash` wrapper instance.
10138 * function square(n) {
10142 * var wrapped = _([1, 2]).map(square);
10143 * var other = wrapped.plant([3, 4]);
10151 function wrapperPlant(value) {
10155 while (parent instanceof baseLodash) {
10156 var clone = wrapperClone(parent);
10157 clone.__index__ = 0;
10158 clone.__values__ = undefined;
10160 previous.__wrapped__ = clone;
10164 var previous = clone;
10165 parent = parent.__wrapped__;
10167 previous.__wrapped__ = value;
10172 * This method is the wrapper version of `_.reverse`.
10174 * **Note:** This method mutates the wrapped array.
10180 * @returns {Object} Returns the new `lodash` wrapper instance.
10183 * var array = [1, 2, 3];
10185 * _(array).reverse().value()
10188 * console.log(array);
10191 function wrapperReverse() {
10192 var value = this.__wrapped__;
10193 if (value instanceof LazyWrapper) {
10194 var wrapped = value;
10195 if (this.__actions__.length) {
10196 wrapped = new LazyWrapper(this);
10198 wrapped = wrapped.reverse();
10199 wrapped.__actions__.push({
10202 'thisArg': undefined
10204 return new LodashWrapper(wrapped, this.__chain__);
10206 return this.thru(reverse);
10210 * Executes the chain sequence to resolve the unwrapped value.
10215 * @alias toJSON, valueOf
10217 * @returns {*} Returns the resolved unwrapped value.
10220 * _([1, 2, 3]).value();
10223 function wrapperValue() {
10224 return baseWrapperValue(this.__wrapped__, this.__actions__);
10227 /*------------------------------------------------------------------------*/
10230 * Creates an object composed of keys generated from the results of running
10231 * each element of `collection` thru `iteratee`. The corresponding value of
10232 * each key is the number of times the key was returned by `iteratee`. The
10233 * iteratee is invoked with one argument: (value).
10238 * @category Collection
10239 * @param {Array|Object} collection The collection to iterate over.
10240 * @param {Function} [iteratee=_.identity] The iteratee to transform keys.
10241 * @returns {Object} Returns the composed aggregate object.
10244 * _.countBy([6.1, 4.2, 6.3], Math.floor);
10245 * // => { '4': 1, '6': 2 }
10247 * // The `_.property` iteratee shorthand.
10248 * _.countBy(['one', 'two', 'three'], 'length');
10249 * // => { '3': 2, '5': 1 }
10251 var countBy = createAggregator(function(result, value, key) {
10252 if (hasOwnProperty.call(result, key)) {
10255 baseAssignValue(result, key, 1);
10260 * Checks if `predicate` returns truthy for **all** elements of `collection`.
10261 * Iteration is stopped once `predicate` returns falsey. The predicate is
10262 * invoked with three arguments: (value, index|key, collection).
10264 * **Note:** This method returns `true` for
10265 * [empty collections](https://en.wikipedia.org/wiki/Empty_set) because
10266 * [everything is true](https://en.wikipedia.org/wiki/Vacuous_truth) of
10267 * elements of empty collections.
10272 * @category Collection
10273 * @param {Array|Object} collection The collection to iterate over.
10274 * @param {Function} [predicate=_.identity] The function invoked per iteration.
10275 * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
10276 * @returns {boolean} Returns `true` if all elements pass the predicate check,
10280 * _.every([true, 1, null, 'yes'], Boolean);
10284 * { 'user': 'barney', 'age': 36, 'active': false },
10285 * { 'user': 'fred', 'age': 40, 'active': false }
10288 * // The `_.matches` iteratee shorthand.
10289 * _.every(users, { 'user': 'barney', 'active': false });
10292 * // The `_.matchesProperty` iteratee shorthand.
10293 * _.every(users, ['active', false]);
10296 * // The `_.property` iteratee shorthand.
10297 * _.every(users, 'active');
10300 function every(collection, predicate, guard) {
10301 var func = isArray(collection) ? arrayEvery : baseEvery;
10302 if (guard && isIterateeCall(collection, predicate, guard)) {
10303 predicate = undefined;
10305 return func(collection, getIteratee(predicate, 3));
10309 * Iterates over elements of `collection`, returning an array of all elements
10310 * `predicate` returns truthy for. The predicate is invoked with three
10311 * arguments: (value, index|key, collection).
10313 * **Note:** Unlike `_.remove`, this method returns a new array.
10318 * @category Collection
10319 * @param {Array|Object} collection The collection to iterate over.
10320 * @param {Function} [predicate=_.identity] The function invoked per iteration.
10321 * @returns {Array} Returns the new filtered array.
10326 * { 'user': 'barney', 'age': 36, 'active': true },
10327 * { 'user': 'fred', 'age': 40, 'active': false }
10330 * _.filter(users, function(o) { return !o.active; });
10331 * // => objects for ['fred']
10333 * // The `_.matches` iteratee shorthand.
10334 * _.filter(users, { 'age': 36, 'active': true });
10335 * // => objects for ['barney']
10337 * // The `_.matchesProperty` iteratee shorthand.
10338 * _.filter(users, ['active', false]);
10339 * // => objects for ['fred']
10341 * // The `_.property` iteratee shorthand.
10342 * _.filter(users, 'active');
10343 * // => objects for ['barney']
10345 * // Combining several predicates using `_.overEvery` or `_.overSome`.
10346 * _.filter(users, _.overSome([{ 'age': 36 }, ['age', 40]]));
10347 * // => objects for ['fred', 'barney']
10349 function filter(collection, predicate) {
10350 var func = isArray(collection) ? arrayFilter : baseFilter;
10351 return func(collection, getIteratee(predicate, 3));
10355 * Iterates over elements of `collection`, returning the first element
10356 * `predicate` returns truthy for. The predicate is invoked with three
10357 * arguments: (value, index|key, collection).
10362 * @category Collection
10363 * @param {Array|Object} collection The collection to inspect.
10364 * @param {Function} [predicate=_.identity] The function invoked per iteration.
10365 * @param {number} [fromIndex=0] The index to search from.
10366 * @returns {*} Returns the matched element, else `undefined`.
10370 * { 'user': 'barney', 'age': 36, 'active': true },
10371 * { 'user': 'fred', 'age': 40, 'active': false },
10372 * { 'user': 'pebbles', 'age': 1, 'active': true }
10375 * _.find(users, function(o) { return o.age < 40; });
10376 * // => object for 'barney'
10378 * // The `_.matches` iteratee shorthand.
10379 * _.find(users, { 'age': 1, 'active': true });
10380 * // => object for 'pebbles'
10382 * // The `_.matchesProperty` iteratee shorthand.
10383 * _.find(users, ['active', false]);
10384 * // => object for 'fred'
10386 * // The `_.property` iteratee shorthand.
10387 * _.find(users, 'active');
10388 * // => object for 'barney'
10390 var find = createFind(findIndex);
10393 * This method is like `_.find` except that it iterates over elements of
10394 * `collection` from right to left.
10399 * @category Collection
10400 * @param {Array|Object} collection The collection to inspect.
10401 * @param {Function} [predicate=_.identity] The function invoked per iteration.
10402 * @param {number} [fromIndex=collection.length-1] The index to search from.
10403 * @returns {*} Returns the matched element, else `undefined`.
10406 * _.findLast([1, 2, 3, 4], function(n) {
10407 * return n % 2 == 1;
10411 var findLast = createFind(findLastIndex);
10414 * Creates a flattened array of values by running each element in `collection`
10415 * thru `iteratee` and flattening the mapped results. The iteratee is invoked
10416 * with three arguments: (value, index|key, collection).
10421 * @category Collection
10422 * @param {Array|Object} collection The collection to iterate over.
10423 * @param {Function} [iteratee=_.identity] The function invoked per iteration.
10424 * @returns {Array} Returns the new flattened array.
10427 * function duplicate(n) {
10431 * _.flatMap([1, 2], duplicate);
10432 * // => [1, 1, 2, 2]
10434 function flatMap(collection, iteratee) {
10435 return baseFlatten(map(collection, iteratee), 1);
10439 * This method is like `_.flatMap` except that it recursively flattens the
10445 * @category Collection
10446 * @param {Array|Object} collection The collection to iterate over.
10447 * @param {Function} [iteratee=_.identity] The function invoked per iteration.
10448 * @returns {Array} Returns the new flattened array.
10451 * function duplicate(n) {
10452 * return [[[n, n]]];
10455 * _.flatMapDeep([1, 2], duplicate);
10456 * // => [1, 1, 2, 2]
10458 function flatMapDeep(collection, iteratee) {
10459 return baseFlatten(map(collection, iteratee), INFINITY);
10463 * This method is like `_.flatMap` except that it recursively flattens the
10464 * mapped results up to `depth` times.
10469 * @category Collection
10470 * @param {Array|Object} collection The collection to iterate over.
10471 * @param {Function} [iteratee=_.identity] The function invoked per iteration.
10472 * @param {number} [depth=1] The maximum recursion depth.
10473 * @returns {Array} Returns the new flattened array.
10476 * function duplicate(n) {
10477 * return [[[n, n]]];
10480 * _.flatMapDepth([1, 2], duplicate, 2);
10481 * // => [[1, 1], [2, 2]]
10483 function flatMapDepth(collection, iteratee, depth) {
10484 depth = depth === undefined ? 1 : toInteger(depth);
10485 return baseFlatten(map(collection, iteratee), depth);
10489 * Iterates over elements of `collection` and invokes `iteratee` for each element.
10490 * The iteratee is invoked with three arguments: (value, index|key, collection).
10491 * Iteratee functions may exit iteration early by explicitly returning `false`.
10493 * **Note:** As with other "Collections" methods, objects with a "length"
10494 * property are iterated like arrays. To avoid this behavior use `_.forIn`
10495 * or `_.forOwn` for object iteration.
10501 * @category Collection
10502 * @param {Array|Object} collection The collection to iterate over.
10503 * @param {Function} [iteratee=_.identity] The function invoked per iteration.
10504 * @returns {Array|Object} Returns `collection`.
10505 * @see _.forEachRight
10508 * _.forEach([1, 2], function(value) {
10509 * console.log(value);
10511 * // => Logs `1` then `2`.
10513 * _.forEach({ 'a': 1, 'b': 2 }, function(value, key) {
10514 * console.log(key);
10516 * // => Logs 'a' then 'b' (iteration order is not guaranteed).
10518 function forEach(collection, iteratee) {
10519 var func = isArray(collection) ? arrayEach : baseEach;
10520 return func(collection, getIteratee(iteratee, 3));
10524 * This method is like `_.forEach` except that it iterates over elements of
10525 * `collection` from right to left.
10531 * @category Collection
10532 * @param {Array|Object} collection The collection to iterate over.
10533 * @param {Function} [iteratee=_.identity] The function invoked per iteration.
10534 * @returns {Array|Object} Returns `collection`.
10538 * _.forEachRight([1, 2], function(value) {
10539 * console.log(value);
10541 * // => Logs `2` then `1`.
10543 function forEachRight(collection, iteratee) {
10544 var func = isArray(collection) ? arrayEachRight : baseEachRight;
10545 return func(collection, getIteratee(iteratee, 3));
10549 * Creates an object composed of keys generated from the results of running
10550 * each element of `collection` thru `iteratee`. The order of grouped values
10551 * is determined by the order they occur in `collection`. The corresponding
10552 * value of each key is an array of elements responsible for generating the
10553 * key. The iteratee is invoked with one argument: (value).
10558 * @category Collection
10559 * @param {Array|Object} collection The collection to iterate over.
10560 * @param {Function} [iteratee=_.identity] The iteratee to transform keys.
10561 * @returns {Object} Returns the composed aggregate object.
10564 * _.groupBy([6.1, 4.2, 6.3], Math.floor);
10565 * // => { '4': [4.2], '6': [6.1, 6.3] }
10567 * // The `_.property` iteratee shorthand.
10568 * _.groupBy(['one', 'two', 'three'], 'length');
10569 * // => { '3': ['one', 'two'], '5': ['three'] }
10571 var groupBy = createAggregator(function(result, value, key) {
10572 if (hasOwnProperty.call(result, key)) {
10573 result[key].push(value);
10575 baseAssignValue(result, key, [value]);
10580 * Checks if `value` is in `collection`. If `collection` is a string, it's
10581 * checked for a substring of `value`, otherwise
10582 * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
10583 * is used for equality comparisons. If `fromIndex` is negative, it's used as
10584 * the offset from the end of `collection`.
10589 * @category Collection
10590 * @param {Array|Object|string} collection The collection to inspect.
10591 * @param {*} value The value to search for.
10592 * @param {number} [fromIndex=0] The index to search from.
10593 * @param- {Object} [guard] Enables use as an iteratee for methods like `_.reduce`.
10594 * @returns {boolean} Returns `true` if `value` is found, else `false`.
10597 * _.includes([1, 2, 3], 1);
10600 * _.includes([1, 2, 3], 1, 2);
10603 * _.includes({ 'a': 1, 'b': 2 }, 1);
10606 * _.includes('abcd', 'bc');
10609 function includes(collection, value, fromIndex, guard) {
10610 collection = isArrayLike(collection) ? collection : values(collection);
10611 fromIndex = (fromIndex && !guard) ? toInteger(fromIndex) : 0;
10613 var length = collection.length;
10614 if (fromIndex < 0) {
10615 fromIndex = nativeMax(length + fromIndex, 0);
10617 return isString(collection)
10618 ? (fromIndex <= length && collection.indexOf(value, fromIndex) > -1)
10619 : (!!length && baseIndexOf(collection, value, fromIndex) > -1);
10623 * Invokes the method at `path` of each element in `collection`, returning
10624 * an array of the results of each invoked method. Any additional arguments
10625 * are provided to each invoked method. If `path` is a function, it's invoked
10626 * for, and `this` bound to, each element in `collection`.
10631 * @category Collection
10632 * @param {Array|Object} collection The collection to iterate over.
10633 * @param {Array|Function|string} path The path of the method to invoke or
10634 * the function invoked per iteration.
10635 * @param {...*} [args] The arguments to invoke each method with.
10636 * @returns {Array} Returns the array of results.
10639 * _.invokeMap([[5, 1, 7], [3, 2, 1]], 'sort');
10640 * // => [[1, 5, 7], [1, 2, 3]]
10642 * _.invokeMap([123, 456], String.prototype.split, '');
10643 * // => [['1', '2', '3'], ['4', '5', '6']]
10645 var invokeMap = baseRest(function(collection, path, args) {
10647 isFunc = typeof path == 'function',
10648 result = isArrayLike(collection) ? Array(collection.length) : [];
10650 baseEach(collection, function(value) {
10651 result[++index] = isFunc ? apply(path, value, args) : baseInvoke(value, path, args);
10657 * Creates an object composed of keys generated from the results of running
10658 * each element of `collection` thru `iteratee`. The corresponding value of
10659 * each key is the last element responsible for generating the key. The
10660 * iteratee is invoked with one argument: (value).
10665 * @category Collection
10666 * @param {Array|Object} collection The collection to iterate over.
10667 * @param {Function} [iteratee=_.identity] The iteratee to transform keys.
10668 * @returns {Object} Returns the composed aggregate object.
10672 * { 'dir': 'left', 'code': 97 },
10673 * { 'dir': 'right', 'code': 100 }
10676 * _.keyBy(array, function(o) {
10677 * return String.fromCharCode(o.code);
10679 * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } }
10681 * _.keyBy(array, 'dir');
10682 * // => { 'left': { 'dir': 'left', 'code': 97 }, 'right': { 'dir': 'right', 'code': 100 } }
10684 var keyBy = createAggregator(function(result, value, key) {
10685 baseAssignValue(result, key, value);
10689 * Creates an array of values by running each element in `collection` thru
10690 * `iteratee`. The iteratee is invoked with three arguments:
10691 * (value, index|key, collection).
10693 * Many lodash methods are guarded to work as iteratees for methods like
10694 * `_.every`, `_.filter`, `_.map`, `_.mapValues`, `_.reject`, and `_.some`.
10696 * The guarded methods are:
10697 * `ary`, `chunk`, `curry`, `curryRight`, `drop`, `dropRight`, `every`,
10698 * `fill`, `invert`, `parseInt`, `random`, `range`, `rangeRight`, `repeat`,
10699 * `sampleSize`, `slice`, `some`, `sortBy`, `split`, `take`, `takeRight`,
10700 * `template`, `trim`, `trimEnd`, `trimStart`, and `words`
10705 * @category Collection
10706 * @param {Array|Object} collection The collection to iterate over.
10707 * @param {Function} [iteratee=_.identity] The function invoked per iteration.
10708 * @returns {Array} Returns the new mapped array.
10711 * function square(n) {
10715 * _.map([4, 8], square);
10718 * _.map({ 'a': 4, 'b': 8 }, square);
10719 * // => [16, 64] (iteration order is not guaranteed)
10722 * { 'user': 'barney' },
10723 * { 'user': 'fred' }
10726 * // The `_.property` iteratee shorthand.
10727 * _.map(users, 'user');
10728 * // => ['barney', 'fred']
10730 function map(collection, iteratee) {
10731 var func = isArray(collection) ? arrayMap : baseMap;
10732 return func(collection, getIteratee(iteratee, 3));
10736 * This method is like `_.sortBy` except that it allows specifying the sort
10737 * orders of the iteratees to sort by. If `orders` is unspecified, all values
10738 * are sorted in ascending order. Otherwise, specify an order of "desc" for
10739 * descending or "asc" for ascending sort order of corresponding values.
10744 * @category Collection
10745 * @param {Array|Object} collection The collection to iterate over.
10746 * @param {Array[]|Function[]|Object[]|string[]} [iteratees=[_.identity]]
10747 * The iteratees to sort by.
10748 * @param {string[]} [orders] The sort orders of `iteratees`.
10749 * @param- {Object} [guard] Enables use as an iteratee for methods like `_.reduce`.
10750 * @returns {Array} Returns the new sorted array.
10754 * { 'user': 'fred', 'age': 48 },
10755 * { 'user': 'barney', 'age': 34 },
10756 * { 'user': 'fred', 'age': 40 },
10757 * { 'user': 'barney', 'age': 36 }
10760 * // Sort by `user` in ascending order and by `age` in descending order.
10761 * _.orderBy(users, ['user', 'age'], ['asc', 'desc']);
10762 * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 40]]
10764 function orderBy(collection, iteratees, orders, guard) {
10765 if (collection == null) {
10768 if (!isArray(iteratees)) {
10769 iteratees = iteratees == null ? [] : [iteratees];
10771 orders = guard ? undefined : orders;
10772 if (!isArray(orders)) {
10773 orders = orders == null ? [] : [orders];
10775 return baseOrderBy(collection, iteratees, orders);
10779 * Creates an array of elements split into two groups, the first of which
10780 * contains elements `predicate` returns truthy for, the second of which
10781 * contains elements `predicate` returns falsey for. The predicate is
10782 * invoked with one argument: (value).
10787 * @category Collection
10788 * @param {Array|Object} collection The collection to iterate over.
10789 * @param {Function} [predicate=_.identity] The function invoked per iteration.
10790 * @returns {Array} Returns the array of grouped elements.
10794 * { 'user': 'barney', 'age': 36, 'active': false },
10795 * { 'user': 'fred', 'age': 40, 'active': true },
10796 * { 'user': 'pebbles', 'age': 1, 'active': false }
10799 * _.partition(users, function(o) { return o.active; });
10800 * // => objects for [['fred'], ['barney', 'pebbles']]
10802 * // The `_.matches` iteratee shorthand.
10803 * _.partition(users, { 'age': 1, 'active': false });
10804 * // => objects for [['pebbles'], ['barney', 'fred']]
10806 * // The `_.matchesProperty` iteratee shorthand.
10807 * _.partition(users, ['active', false]);
10808 * // => objects for [['barney', 'pebbles'], ['fred']]
10810 * // The `_.property` iteratee shorthand.
10811 * _.partition(users, 'active');
10812 * // => objects for [['fred'], ['barney', 'pebbles']]
10814 var partition = createAggregator(function(result, value, key) {
10815 result[key ? 0 : 1].push(value);
10816 }, function() { return [[], []]; });
10819 * Reduces `collection` to a value which is the accumulated result of running
10820 * each element in `collection` thru `iteratee`, where each successive
10821 * invocation is supplied the return value of the previous. If `accumulator`
10822 * is not given, the first element of `collection` is used as the initial
10823 * value. The iteratee is invoked with four arguments:
10824 * (accumulator, value, index|key, collection).
10826 * Many lodash methods are guarded to work as iteratees for methods like
10827 * `_.reduce`, `_.reduceRight`, and `_.transform`.
10829 * The guarded methods are:
10830 * `assign`, `defaults`, `defaultsDeep`, `includes`, `merge`, `orderBy`,
10836 * @category Collection
10837 * @param {Array|Object} collection The collection to iterate over.
10838 * @param {Function} [iteratee=_.identity] The function invoked per iteration.
10839 * @param {*} [accumulator] The initial value.
10840 * @returns {*} Returns the accumulated value.
10841 * @see _.reduceRight
10844 * _.reduce([1, 2], function(sum, n) {
10849 * _.reduce({ 'a': 1, 'b': 2, 'c': 1 }, function(result, value, key) {
10850 * (result[value] || (result[value] = [])).push(key);
10853 * // => { '1': ['a', 'c'], '2': ['b'] } (iteration order is not guaranteed)
10855 function reduce(collection, iteratee, accumulator) {
10856 var func = isArray(collection) ? arrayReduce : baseReduce,
10857 initAccum = arguments.length < 3;
10859 return func(collection, getIteratee(iteratee, 4), accumulator, initAccum, baseEach);
10863 * This method is like `_.reduce` except that it iterates over elements of
10864 * `collection` from right to left.
10869 * @category Collection
10870 * @param {Array|Object} collection The collection to iterate over.
10871 * @param {Function} [iteratee=_.identity] The function invoked per iteration.
10872 * @param {*} [accumulator] The initial value.
10873 * @returns {*} Returns the accumulated value.
10877 * var array = [[0, 1], [2, 3], [4, 5]];
10879 * _.reduceRight(array, function(flattened, other) {
10880 * return flattened.concat(other);
10882 * // => [4, 5, 2, 3, 0, 1]
10884 function reduceRight(collection, iteratee, accumulator) {
10885 var func = isArray(collection) ? arrayReduceRight : baseReduce,
10886 initAccum = arguments.length < 3;
10888 return func(collection, getIteratee(iteratee, 4), accumulator, initAccum, baseEachRight);
10892 * The opposite of `_.filter`; this method returns the elements of `collection`
10893 * that `predicate` does **not** return truthy for.
10898 * @category Collection
10899 * @param {Array|Object} collection The collection to iterate over.
10900 * @param {Function} [predicate=_.identity] The function invoked per iteration.
10901 * @returns {Array} Returns the new filtered array.
10906 * { 'user': 'barney', 'age': 36, 'active': false },
10907 * { 'user': 'fred', 'age': 40, 'active': true }
10910 * _.reject(users, function(o) { return !o.active; });
10911 * // => objects for ['fred']
10913 * // The `_.matches` iteratee shorthand.
10914 * _.reject(users, { 'age': 40, 'active': true });
10915 * // => objects for ['barney']
10917 * // The `_.matchesProperty` iteratee shorthand.
10918 * _.reject(users, ['active', false]);
10919 * // => objects for ['fred']
10921 * // The `_.property` iteratee shorthand.
10922 * _.reject(users, 'active');
10923 * // => objects for ['barney']
10925 function reject(collection, predicate) {
10926 var func = isArray(collection) ? arrayFilter : baseFilter;
10927 return func(collection, negate(getIteratee(predicate, 3)));
10931 * Gets a random element from `collection`.
10936 * @category Collection
10937 * @param {Array|Object} collection The collection to sample.
10938 * @returns {*} Returns the random element.
10941 * _.sample([1, 2, 3, 4]);
10944 function sample(collection) {
10945 var func = isArray(collection) ? arraySample : baseSample;
10946 return func(collection);
10950 * Gets `n` random elements at unique keys from `collection` up to the
10951 * size of `collection`.
10956 * @category Collection
10957 * @param {Array|Object} collection The collection to sample.
10958 * @param {number} [n=1] The number of elements to sample.
10959 * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
10960 * @returns {Array} Returns the random elements.
10963 * _.sampleSize([1, 2, 3], 2);
10966 * _.sampleSize([1, 2, 3], 4);
10969 function sampleSize(collection, n, guard) {
10970 if ((guard ? isIterateeCall(collection, n, guard) : n === undefined)) {
10975 var func = isArray(collection) ? arraySampleSize : baseSampleSize;
10976 return func(collection, n);
10980 * Creates an array of shuffled values, using a version of the
10981 * [Fisher-Yates shuffle](https://en.wikipedia.org/wiki/Fisher-Yates_shuffle).
10986 * @category Collection
10987 * @param {Array|Object} collection The collection to shuffle.
10988 * @returns {Array} Returns the new shuffled array.
10991 * _.shuffle([1, 2, 3, 4]);
10992 * // => [4, 1, 3, 2]
10994 function shuffle(collection) {
10995 var func = isArray(collection) ? arrayShuffle : baseShuffle;
10996 return func(collection);
11000 * Gets the size of `collection` by returning its length for array-like
11001 * values or the number of own enumerable string keyed properties for objects.
11006 * @category Collection
11007 * @param {Array|Object|string} collection The collection to inspect.
11008 * @returns {number} Returns the collection size.
11011 * _.size([1, 2, 3]);
11014 * _.size({ 'a': 1, 'b': 2 });
11017 * _.size('pebbles');
11020 function size(collection) {
11021 if (collection == null) {
11024 if (isArrayLike(collection)) {
11025 return isString(collection) ? stringSize(collection) : collection.length;
11027 var tag = getTag(collection);
11028 if (tag == mapTag || tag == setTag) {
11029 return collection.size;
11031 return baseKeys(collection).length;
11035 * Checks if `predicate` returns truthy for **any** element of `collection`.
11036 * Iteration is stopped once `predicate` returns truthy. The predicate is
11037 * invoked with three arguments: (value, index|key, collection).
11042 * @category Collection
11043 * @param {Array|Object} collection The collection to iterate over.
11044 * @param {Function} [predicate=_.identity] The function invoked per iteration.
11045 * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
11046 * @returns {boolean} Returns `true` if any element passes the predicate check,
11050 * _.some([null, 0, 'yes', false], Boolean);
11054 * { 'user': 'barney', 'active': true },
11055 * { 'user': 'fred', 'active': false }
11058 * // The `_.matches` iteratee shorthand.
11059 * _.some(users, { 'user': 'barney', 'active': false });
11062 * // The `_.matchesProperty` iteratee shorthand.
11063 * _.some(users, ['active', false]);
11066 * // The `_.property` iteratee shorthand.
11067 * _.some(users, 'active');
11070 function some(collection, predicate, guard) {
11071 var func = isArray(collection) ? arraySome : baseSome;
11072 if (guard && isIterateeCall(collection, predicate, guard)) {
11073 predicate = undefined;
11075 return func(collection, getIteratee(predicate, 3));
11079 * Creates an array of elements, sorted in ascending order by the results of
11080 * running each element in a collection thru each iteratee. This method
11081 * performs a stable sort, that is, it preserves the original sort order of
11082 * equal elements. The iteratees are invoked with one argument: (value).
11087 * @category Collection
11088 * @param {Array|Object} collection The collection to iterate over.
11089 * @param {...(Function|Function[])} [iteratees=[_.identity]]
11090 * The iteratees to sort by.
11091 * @returns {Array} Returns the new sorted array.
11095 * { 'user': 'fred', 'age': 48 },
11096 * { 'user': 'barney', 'age': 36 },
11097 * { 'user': 'fred', 'age': 30 },
11098 * { 'user': 'barney', 'age': 34 }
11101 * _.sortBy(users, [function(o) { return o.user; }]);
11102 * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 30]]
11104 * _.sortBy(users, ['user', 'age']);
11105 * // => objects for [['barney', 34], ['barney', 36], ['fred', 30], ['fred', 48]]
11107 var sortBy = baseRest(function(collection, iteratees) {
11108 if (collection == null) {
11111 var length = iteratees.length;
11112 if (length > 1 && isIterateeCall(collection, iteratees[0], iteratees[1])) {
11114 } else if (length > 2 && isIterateeCall(iteratees[0], iteratees[1], iteratees[2])) {
11115 iteratees = [iteratees[0]];
11117 return baseOrderBy(collection, baseFlatten(iteratees, 1), []);
11120 /*------------------------------------------------------------------------*/
11123 * Gets the timestamp of the number of milliseconds that have elapsed since
11124 * the Unix epoch (1 January 1970 00:00:00 UTC).
11130 * @returns {number} Returns the timestamp.
11133 * _.defer(function(stamp) {
11134 * console.log(_.now() - stamp);
11136 * // => Logs the number of milliseconds it took for the deferred invocation.
11138 var now = ctxNow || function() {
11139 return root.Date.now();
11142 /*------------------------------------------------------------------------*/
11145 * The opposite of `_.before`; this method creates a function that invokes
11146 * `func` once it's called `n` or more times.
11151 * @category Function
11152 * @param {number} n The number of calls before `func` is invoked.
11153 * @param {Function} func The function to restrict.
11154 * @returns {Function} Returns the new restricted function.
11157 * var saves = ['profile', 'settings'];
11159 * var done = _.after(saves.length, function() {
11160 * console.log('done saving!');
11163 * _.forEach(saves, function(type) {
11164 * asyncSave({ 'type': type, 'complete': done });
11166 * // => Logs 'done saving!' after the two async saves have completed.
11168 function after(n, func) {
11169 if (typeof func != 'function') {
11170 throw new TypeError(FUNC_ERROR_TEXT);
11173 return function() {
11175 return func.apply(this, arguments);
11181 * Creates a function that invokes `func`, with up to `n` arguments,
11182 * ignoring any additional arguments.
11187 * @category Function
11188 * @param {Function} func The function to cap arguments for.
11189 * @param {number} [n=func.length] The arity cap.
11190 * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
11191 * @returns {Function} Returns the new capped function.
11194 * _.map(['6', '8', '10'], _.ary(parseInt, 1));
11197 function ary(func, n, guard) {
11198 n = guard ? undefined : n;
11199 n = (func && n == null) ? func.length : n;
11200 return createWrap(func, WRAP_ARY_FLAG, undefined, undefined, undefined, undefined, n);
11204 * Creates a function that invokes `func`, with the `this` binding and arguments
11205 * of the created function, while it's called less than `n` times. Subsequent
11206 * calls to the created function return the result of the last `func` invocation.
11211 * @category Function
11212 * @param {number} n The number of calls at which `func` is no longer invoked.
11213 * @param {Function} func The function to restrict.
11214 * @returns {Function} Returns the new restricted function.
11217 * jQuery(element).on('click', _.before(5, addContactToList));
11218 * // => Allows adding up to 4 contacts to the list.
11220 function before(n, func) {
11222 if (typeof func != 'function') {
11223 throw new TypeError(FUNC_ERROR_TEXT);
11226 return function() {
11228 result = func.apply(this, arguments);
11238 * Creates a function that invokes `func` with the `this` binding of `thisArg`
11239 * and `partials` prepended to the arguments it receives.
11241 * The `_.bind.placeholder` value, which defaults to `_` in monolithic builds,
11242 * may be used as a placeholder for partially applied arguments.
11244 * **Note:** Unlike native `Function#bind`, this method doesn't set the "length"
11245 * property of bound functions.
11250 * @category Function
11251 * @param {Function} func The function to bind.
11252 * @param {*} thisArg The `this` binding of `func`.
11253 * @param {...*} [partials] The arguments to be partially applied.
11254 * @returns {Function} Returns the new bound function.
11257 * function greet(greeting, punctuation) {
11258 * return greeting + ' ' + this.user + punctuation;
11261 * var object = { 'user': 'fred' };
11263 * var bound = _.bind(greet, object, 'hi');
11267 * // Bound with placeholders.
11268 * var bound = _.bind(greet, object, _, '!');
11272 var bind = baseRest(function(func, thisArg, partials) {
11273 var bitmask = WRAP_BIND_FLAG;
11274 if (partials.length) {
11275 var holders = replaceHolders(partials, getHolder(bind));
11276 bitmask |= WRAP_PARTIAL_FLAG;
11278 return createWrap(func, bitmask, thisArg, partials, holders);
11282 * Creates a function that invokes the method at `object[key]` with `partials`
11283 * prepended to the arguments it receives.
11285 * This method differs from `_.bind` by allowing bound functions to reference
11286 * methods that may be redefined or don't yet exist. See
11287 * [Peter Michaux's article](http://peter.michaux.ca/articles/lazy-function-definition-pattern)
11288 * for more details.
11290 * The `_.bindKey.placeholder` value, which defaults to `_` in monolithic
11291 * builds, may be used as a placeholder for partially applied arguments.
11296 * @category Function
11297 * @param {Object} object The object to invoke the method on.
11298 * @param {string} key The key of the method.
11299 * @param {...*} [partials] The arguments to be partially applied.
11300 * @returns {Function} Returns the new bound function.
11305 * 'greet': function(greeting, punctuation) {
11306 * return greeting + ' ' + this.user + punctuation;
11310 * var bound = _.bindKey(object, 'greet', 'hi');
11314 * object.greet = function(greeting, punctuation) {
11315 * return greeting + 'ya ' + this.user + punctuation;
11319 * // => 'hiya fred!'
11321 * // Bound with placeholders.
11322 * var bound = _.bindKey(object, 'greet', _, '!');
11324 * // => 'hiya fred!'
11326 var bindKey = baseRest(function(object, key, partials) {
11327 var bitmask = WRAP_BIND_FLAG | WRAP_BIND_KEY_FLAG;
11328 if (partials.length) {
11329 var holders = replaceHolders(partials, getHolder(bindKey));
11330 bitmask |= WRAP_PARTIAL_FLAG;
11332 return createWrap(key, bitmask, object, partials, holders);
11336 * Creates a function that accepts arguments of `func` and either invokes
11337 * `func` returning its result, if at least `arity` number of arguments have
11338 * been provided, or returns a function that accepts the remaining `func`
11339 * arguments, and so on. The arity of `func` may be specified if `func.length`
11340 * is not sufficient.
11342 * The `_.curry.placeholder` value, which defaults to `_` in monolithic builds,
11343 * may be used as a placeholder for provided arguments.
11345 * **Note:** This method doesn't set the "length" property of curried functions.
11350 * @category Function
11351 * @param {Function} func The function to curry.
11352 * @param {number} [arity=func.length] The arity of `func`.
11353 * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
11354 * @returns {Function} Returns the new curried function.
11357 * var abc = function(a, b, c) {
11358 * return [a, b, c];
11361 * var curried = _.curry(abc);
11363 * curried(1)(2)(3);
11366 * curried(1, 2)(3);
11369 * curried(1, 2, 3);
11372 * // Curried with placeholders.
11373 * curried(1)(_, 3)(2);
11376 function curry(func, arity, guard) {
11377 arity = guard ? undefined : arity;
11378 var result = createWrap(func, WRAP_CURRY_FLAG, undefined, undefined, undefined, undefined, undefined, arity);
11379 result.placeholder = curry.placeholder;
11384 * This method is like `_.curry` except that arguments are applied to `func`
11385 * in the manner of `_.partialRight` instead of `_.partial`.
11387 * The `_.curryRight.placeholder` value, which defaults to `_` in monolithic
11388 * builds, may be used as a placeholder for provided arguments.
11390 * **Note:** This method doesn't set the "length" property of curried functions.
11395 * @category Function
11396 * @param {Function} func The function to curry.
11397 * @param {number} [arity=func.length] The arity of `func`.
11398 * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
11399 * @returns {Function} Returns the new curried function.
11402 * var abc = function(a, b, c) {
11403 * return [a, b, c];
11406 * var curried = _.curryRight(abc);
11408 * curried(3)(2)(1);
11411 * curried(2, 3)(1);
11414 * curried(1, 2, 3);
11417 * // Curried with placeholders.
11418 * curried(3)(1, _)(2);
11421 function curryRight(func, arity, guard) {
11422 arity = guard ? undefined : arity;
11423 var result = createWrap(func, WRAP_CURRY_RIGHT_FLAG, undefined, undefined, undefined, undefined, undefined, arity);
11424 result.placeholder = curryRight.placeholder;
11429 * Creates a debounced function that delays invoking `func` until after `wait`
11430 * milliseconds have elapsed since the last time the debounced function was
11431 * invoked. The debounced function comes with a `cancel` method to cancel
11432 * delayed `func` invocations and a `flush` method to immediately invoke them.
11433 * Provide `options` to indicate whether `func` should be invoked on the
11434 * leading and/or trailing edge of the `wait` timeout. The `func` is invoked
11435 * with the last arguments provided to the debounced function. Subsequent
11436 * calls to the debounced function return the result of the last `func`
11439 * **Note:** If `leading` and `trailing` options are `true`, `func` is
11440 * invoked on the trailing edge of the timeout only if the debounced function
11441 * is invoked more than once during the `wait` timeout.
11443 * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred
11444 * until to the next tick, similar to `setTimeout` with a timeout of `0`.
11446 * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/)
11447 * for details over the differences between `_.debounce` and `_.throttle`.
11452 * @category Function
11453 * @param {Function} func The function to debounce.
11454 * @param {number} [wait=0] The number of milliseconds to delay.
11455 * @param {Object} [options={}] The options object.
11456 * @param {boolean} [options.leading=false]
11457 * Specify invoking on the leading edge of the timeout.
11458 * @param {number} [options.maxWait]
11459 * The maximum time `func` is allowed to be delayed before it's invoked.
11460 * @param {boolean} [options.trailing=true]
11461 * Specify invoking on the trailing edge of the timeout.
11462 * @returns {Function} Returns the new debounced function.
11465 * // Avoid costly calculations while the window size is in flux.
11466 * jQuery(window).on('resize', _.debounce(calculateLayout, 150));
11468 * // Invoke `sendMail` when clicked, debouncing subsequent calls.
11469 * jQuery(element).on('click', _.debounce(sendMail, 300, {
11471 * 'trailing': false
11474 * // Ensure `batchLog` is invoked once after 1 second of debounced calls.
11475 * var debounced = _.debounce(batchLog, 250, { 'maxWait': 1000 });
11476 * var source = new EventSource('/stream');
11477 * jQuery(source).on('message', debounced);
11479 * // Cancel the trailing debounced invocation.
11480 * jQuery(window).on('popstate', debounced.cancel);
11482 function debounce(func, wait, options) {
11489 lastInvokeTime = 0,
11494 if (typeof func != 'function') {
11495 throw new TypeError(FUNC_ERROR_TEXT);
11497 wait = toNumber(wait) || 0;
11498 if (isObject(options)) {
11499 leading = !!options.leading;
11500 maxing = 'maxWait' in options;
11501 maxWait = maxing ? nativeMax(toNumber(options.maxWait) || 0, wait) : maxWait;
11502 trailing = 'trailing' in options ? !!options.trailing : trailing;
11505 function invokeFunc(time) {
11506 var args = lastArgs,
11507 thisArg = lastThis;
11509 lastArgs = lastThis = undefined;
11510 lastInvokeTime = time;
11511 result = func.apply(thisArg, args);
11515 function leadingEdge(time) {
11516 // Reset any `maxWait` timer.
11517 lastInvokeTime = time;
11518 // Start the timer for the trailing edge.
11519 timerId = setTimeout(timerExpired, wait);
11520 // Invoke the leading edge.
11521 return leading ? invokeFunc(time) : result;
11524 function remainingWait(time) {
11525 var timeSinceLastCall = time - lastCallTime,
11526 timeSinceLastInvoke = time - lastInvokeTime,
11527 timeWaiting = wait - timeSinceLastCall;
11530 ? nativeMin(timeWaiting, maxWait - timeSinceLastInvoke)
11534 function shouldInvoke(time) {
11535 var timeSinceLastCall = time - lastCallTime,
11536 timeSinceLastInvoke = time - lastInvokeTime;
11538 // Either this is the first call, activity has stopped and we're at the
11539 // trailing edge, the system time has gone backwards and we're treating
11540 // it as the trailing edge, or we've hit the `maxWait` limit.
11541 return (lastCallTime === undefined || (timeSinceLastCall >= wait) ||
11542 (timeSinceLastCall < 0) || (maxing && timeSinceLastInvoke >= maxWait));
11545 function timerExpired() {
11547 if (shouldInvoke(time)) {
11548 return trailingEdge(time);
11550 // Restart the timer.
11551 timerId = setTimeout(timerExpired, remainingWait(time));
11554 function trailingEdge(time) {
11555 timerId = undefined;
11557 // Only invoke if we have `lastArgs` which means `func` has been
11558 // debounced at least once.
11559 if (trailing && lastArgs) {
11560 return invokeFunc(time);
11562 lastArgs = lastThis = undefined;
11566 function cancel() {
11567 if (timerId !== undefined) {
11568 clearTimeout(timerId);
11570 lastInvokeTime = 0;
11571 lastArgs = lastCallTime = lastThis = timerId = undefined;
11575 return timerId === undefined ? result : trailingEdge(now());
11578 function debounced() {
11580 isInvoking = shouldInvoke(time);
11582 lastArgs = arguments;
11584 lastCallTime = time;
11587 if (timerId === undefined) {
11588 return leadingEdge(lastCallTime);
11591 // Handle invocations in a tight loop.
11592 clearTimeout(timerId);
11593 timerId = setTimeout(timerExpired, wait);
11594 return invokeFunc(lastCallTime);
11597 if (timerId === undefined) {
11598 timerId = setTimeout(timerExpired, wait);
11602 debounced.cancel = cancel;
11603 debounced.flush = flush;
11608 * Defers invoking the `func` until the current call stack has cleared. Any
11609 * additional arguments are provided to `func` when it's invoked.
11614 * @category Function
11615 * @param {Function} func The function to defer.
11616 * @param {...*} [args] The arguments to invoke `func` with.
11617 * @returns {number} Returns the timer id.
11620 * _.defer(function(text) {
11621 * console.log(text);
11623 * // => Logs 'deferred' after one millisecond.
11625 var defer = baseRest(function(func, args) {
11626 return baseDelay(func, 1, args);
11630 * Invokes `func` after `wait` milliseconds. Any additional arguments are
11631 * provided to `func` when it's invoked.
11636 * @category Function
11637 * @param {Function} func The function to delay.
11638 * @param {number} wait The number of milliseconds to delay invocation.
11639 * @param {...*} [args] The arguments to invoke `func` with.
11640 * @returns {number} Returns the timer id.
11643 * _.delay(function(text) {
11644 * console.log(text);
11645 * }, 1000, 'later');
11646 * // => Logs 'later' after one second.
11648 var delay = baseRest(function(func, wait, args) {
11649 return baseDelay(func, toNumber(wait) || 0, args);
11653 * Creates a function that invokes `func` with arguments reversed.
11658 * @category Function
11659 * @param {Function} func The function to flip arguments for.
11660 * @returns {Function} Returns the new flipped function.
11663 * var flipped = _.flip(function() {
11664 * return _.toArray(arguments);
11667 * flipped('a', 'b', 'c', 'd');
11668 * // => ['d', 'c', 'b', 'a']
11670 function flip(func) {
11671 return createWrap(func, WRAP_FLIP_FLAG);
11675 * Creates a function that memoizes the result of `func`. If `resolver` is
11676 * provided, it determines the cache key for storing the result based on the
11677 * arguments provided to the memoized function. By default, the first argument
11678 * provided to the memoized function is used as the map cache key. The `func`
11679 * is invoked with the `this` binding of the memoized function.
11681 * **Note:** The cache is exposed as the `cache` property on the memoized
11682 * function. Its creation may be customized by replacing the `_.memoize.Cache`
11683 * constructor with one whose instances implement the
11684 * [`Map`](http://ecma-international.org/ecma-262/7.0/#sec-properties-of-the-map-prototype-object)
11685 * method interface of `clear`, `delete`, `get`, `has`, and `set`.
11690 * @category Function
11691 * @param {Function} func The function to have its output memoized.
11692 * @param {Function} [resolver] The function to resolve the cache key.
11693 * @returns {Function} Returns the new memoized function.
11696 * var object = { 'a': 1, 'b': 2 };
11697 * var other = { 'c': 3, 'd': 4 };
11699 * var values = _.memoize(_.values);
11710 * // Modify the result cache.
11711 * values.cache.set(object, ['a', 'b']);
11715 * // Replace `_.memoize.Cache`.
11716 * _.memoize.Cache = WeakMap;
11718 function memoize(func, resolver) {
11719 if (typeof func != 'function' || (resolver != null && typeof resolver != 'function')) {
11720 throw new TypeError(FUNC_ERROR_TEXT);
11722 var memoized = function() {
11723 var args = arguments,
11724 key = resolver ? resolver.apply(this, args) : args[0],
11725 cache = memoized.cache;
11727 if (cache.has(key)) {
11728 return cache.get(key);
11730 var result = func.apply(this, args);
11731 memoized.cache = cache.set(key, result) || cache;
11734 memoized.cache = new (memoize.Cache || MapCache);
11738 // Expose `MapCache`.
11739 memoize.Cache = MapCache;
11742 * Creates a function that negates the result of the predicate `func`. The
11743 * `func` predicate is invoked with the `this` binding and arguments of the
11744 * created function.
11749 * @category Function
11750 * @param {Function} predicate The predicate to negate.
11751 * @returns {Function} Returns the new negated function.
11754 * function isEven(n) {
11755 * return n % 2 == 0;
11758 * _.filter([1, 2, 3, 4, 5, 6], _.negate(isEven));
11761 function negate(predicate) {
11762 if (typeof predicate != 'function') {
11763 throw new TypeError(FUNC_ERROR_TEXT);
11765 return function() {
11766 var args = arguments;
11767 switch (args.length) {
11768 case 0: return !predicate.call(this);
11769 case 1: return !predicate.call(this, args[0]);
11770 case 2: return !predicate.call(this, args[0], args[1]);
11771 case 3: return !predicate.call(this, args[0], args[1], args[2]);
11773 return !predicate.apply(this, args);
11778 * Creates a function that is restricted to invoking `func` once. Repeat calls
11779 * to the function return the value of the first invocation. The `func` is
11780 * invoked with the `this` binding and arguments of the created function.
11785 * @category Function
11786 * @param {Function} func The function to restrict.
11787 * @returns {Function} Returns the new restricted function.
11790 * var initialize = _.once(createApplication);
11793 * // => `createApplication` is invoked once
11795 function once(func) {
11796 return before(2, func);
11800 * Creates a function that invokes `func` with its arguments transformed.
11805 * @category Function
11806 * @param {Function} func The function to wrap.
11807 * @param {...(Function|Function[])} [transforms=[_.identity]]
11808 * The argument transforms.
11809 * @returns {Function} Returns the new function.
11812 * function doubled(n) {
11816 * function square(n) {
11820 * var func = _.overArgs(function(x, y) {
11822 * }, [square, doubled]);
11830 var overArgs = castRest(function(func, transforms) {
11831 transforms = (transforms.length == 1 && isArray(transforms[0]))
11832 ? arrayMap(transforms[0], baseUnary(getIteratee()))
11833 : arrayMap(baseFlatten(transforms, 1), baseUnary(getIteratee()));
11835 var funcsLength = transforms.length;
11836 return baseRest(function(args) {
11838 length = nativeMin(args.length, funcsLength);
11840 while (++index < length) {
11841 args[index] = transforms[index].call(this, args[index]);
11843 return apply(func, this, args);
11848 * Creates a function that invokes `func` with `partials` prepended to the
11849 * arguments it receives. This method is like `_.bind` except it does **not**
11850 * alter the `this` binding.
11852 * The `_.partial.placeholder` value, which defaults to `_` in monolithic
11853 * builds, may be used as a placeholder for partially applied arguments.
11855 * **Note:** This method doesn't set the "length" property of partially
11856 * applied functions.
11861 * @category Function
11862 * @param {Function} func The function to partially apply arguments to.
11863 * @param {...*} [partials] The arguments to be partially applied.
11864 * @returns {Function} Returns the new partially applied function.
11867 * function greet(greeting, name) {
11868 * return greeting + ' ' + name;
11871 * var sayHelloTo = _.partial(greet, 'hello');
11872 * sayHelloTo('fred');
11873 * // => 'hello fred'
11875 * // Partially applied with placeholders.
11876 * var greetFred = _.partial(greet, _, 'fred');
11880 var partial = baseRest(function(func, partials) {
11881 var holders = replaceHolders(partials, getHolder(partial));
11882 return createWrap(func, WRAP_PARTIAL_FLAG, undefined, partials, holders);
11886 * This method is like `_.partial` except that partially applied arguments
11887 * are appended to the arguments it receives.
11889 * The `_.partialRight.placeholder` value, which defaults to `_` in monolithic
11890 * builds, may be used as a placeholder for partially applied arguments.
11892 * **Note:** This method doesn't set the "length" property of partially
11893 * applied functions.
11898 * @category Function
11899 * @param {Function} func The function to partially apply arguments to.
11900 * @param {...*} [partials] The arguments to be partially applied.
11901 * @returns {Function} Returns the new partially applied function.
11904 * function greet(greeting, name) {
11905 * return greeting + ' ' + name;
11908 * var greetFred = _.partialRight(greet, 'fred');
11912 * // Partially applied with placeholders.
11913 * var sayHelloTo = _.partialRight(greet, 'hello', _);
11914 * sayHelloTo('fred');
11915 * // => 'hello fred'
11917 var partialRight = baseRest(function(func, partials) {
11918 var holders = replaceHolders(partials, getHolder(partialRight));
11919 return createWrap(func, WRAP_PARTIAL_RIGHT_FLAG, undefined, partials, holders);
11923 * Creates a function that invokes `func` with arguments arranged according
11924 * to the specified `indexes` where the argument value at the first index is
11925 * provided as the first argument, the argument value at the second index is
11926 * provided as the second argument, and so on.
11931 * @category Function
11932 * @param {Function} func The function to rearrange arguments for.
11933 * @param {...(number|number[])} indexes The arranged argument indexes.
11934 * @returns {Function} Returns the new function.
11937 * var rearged = _.rearg(function(a, b, c) {
11938 * return [a, b, c];
11941 * rearged('b', 'c', 'a')
11942 * // => ['a', 'b', 'c']
11944 var rearg = flatRest(function(func, indexes) {
11945 return createWrap(func, WRAP_REARG_FLAG, undefined, undefined, undefined, indexes);
11949 * Creates a function that invokes `func` with the `this` binding of the
11950 * created function and arguments from `start` and beyond provided as
11953 * **Note:** This method is based on the
11954 * [rest parameter](https://mdn.io/rest_parameters).
11959 * @category Function
11960 * @param {Function} func The function to apply a rest parameter to.
11961 * @param {number} [start=func.length-1] The start position of the rest parameter.
11962 * @returns {Function} Returns the new function.
11965 * var say = _.rest(function(what, names) {
11966 * return what + ' ' + _.initial(names).join(', ') +
11967 * (_.size(names) > 1 ? ', & ' : '') + _.last(names);
11970 * say('hello', 'fred', 'barney', 'pebbles');
11971 * // => 'hello fred, barney, & pebbles'
11973 function rest(func, start) {
11974 if (typeof func != 'function') {
11975 throw new TypeError(FUNC_ERROR_TEXT);
11977 start = start === undefined ? start : toInteger(start);
11978 return baseRest(func, start);
11982 * Creates a function that invokes `func` with the `this` binding of the
11983 * create function and an array of arguments much like
11984 * [`Function#apply`](http://www.ecma-international.org/ecma-262/7.0/#sec-function.prototype.apply).
11986 * **Note:** This method is based on the
11987 * [spread operator](https://mdn.io/spread_operator).
11992 * @category Function
11993 * @param {Function} func The function to spread arguments over.
11994 * @param {number} [start=0] The start position of the spread.
11995 * @returns {Function} Returns the new function.
11998 * var say = _.spread(function(who, what) {
11999 * return who + ' says ' + what;
12002 * say(['fred', 'hello']);
12003 * // => 'fred says hello'
12005 * var numbers = Promise.all([
12006 * Promise.resolve(40),
12007 * Promise.resolve(36)
12010 * numbers.then(_.spread(function(x, y) {
12013 * // => a Promise of 76
12015 function spread(func, start) {
12016 if (typeof func != 'function') {
12017 throw new TypeError(FUNC_ERROR_TEXT);
12019 start = start == null ? 0 : nativeMax(toInteger(start), 0);
12020 return baseRest(function(args) {
12021 var array = args[start],
12022 otherArgs = castSlice(args, 0, start);
12025 arrayPush(otherArgs, array);
12027 return apply(func, this, otherArgs);
12032 * Creates a throttled function that only invokes `func` at most once per
12033 * every `wait` milliseconds. The throttled function comes with a `cancel`
12034 * method to cancel delayed `func` invocations and a `flush` method to
12035 * immediately invoke them. Provide `options` to indicate whether `func`
12036 * should be invoked on the leading and/or trailing edge of the `wait`
12037 * timeout. The `func` is invoked with the last arguments provided to the
12038 * throttled function. Subsequent calls to the throttled function return the
12039 * result of the last `func` invocation.
12041 * **Note:** If `leading` and `trailing` options are `true`, `func` is
12042 * invoked on the trailing edge of the timeout only if the throttled function
12043 * is invoked more than once during the `wait` timeout.
12045 * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred
12046 * until to the next tick, similar to `setTimeout` with a timeout of `0`.
12048 * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/)
12049 * for details over the differences between `_.throttle` and `_.debounce`.
12054 * @category Function
12055 * @param {Function} func The function to throttle.
12056 * @param {number} [wait=0] The number of milliseconds to throttle invocations to.
12057 * @param {Object} [options={}] The options object.
12058 * @param {boolean} [options.leading=true]
12059 * Specify invoking on the leading edge of the timeout.
12060 * @param {boolean} [options.trailing=true]
12061 * Specify invoking on the trailing edge of the timeout.
12062 * @returns {Function} Returns the new throttled function.
12065 * // Avoid excessively updating the position while scrolling.
12066 * jQuery(window).on('scroll', _.throttle(updatePosition, 100));
12068 * // Invoke `renewToken` when the click event is fired, but not more than once every 5 minutes.
12069 * var throttled = _.throttle(renewToken, 300000, { 'trailing': false });
12070 * jQuery(element).on('click', throttled);
12072 * // Cancel the trailing throttled invocation.
12073 * jQuery(window).on('popstate', throttled.cancel);
12075 function throttle(func, wait, options) {
12076 var leading = true,
12079 if (typeof func != 'function') {
12080 throw new TypeError(FUNC_ERROR_TEXT);
12082 if (isObject(options)) {
12083 leading = 'leading' in options ? !!options.leading : leading;
12084 trailing = 'trailing' in options ? !!options.trailing : trailing;
12086 return debounce(func, wait, {
12087 'leading': leading,
12089 'trailing': trailing
12094 * Creates a function that accepts up to one argument, ignoring any
12095 * additional arguments.
12100 * @category Function
12101 * @param {Function} func The function to cap arguments for.
12102 * @returns {Function} Returns the new capped function.
12105 * _.map(['6', '8', '10'], _.unary(parseInt));
12108 function unary(func) {
12109 return ary(func, 1);
12113 * Creates a function that provides `value` to `wrapper` as its first
12114 * argument. Any additional arguments provided to the function are appended
12115 * to those provided to the `wrapper`. The wrapper is invoked with the `this`
12116 * binding of the created function.
12121 * @category Function
12122 * @param {*} value The value to wrap.
12123 * @param {Function} [wrapper=identity] The wrapper function.
12124 * @returns {Function} Returns the new function.
12127 * var p = _.wrap(_.escape, function(func, text) {
12128 * return '<p>' + func(text) + '</p>';
12131 * p('fred, barney, & pebbles');
12132 * // => '<p>fred, barney, & pebbles</p>'
12134 function wrap(value, wrapper) {
12135 return partial(castFunction(wrapper), value);
12138 /*------------------------------------------------------------------------*/
12141 * Casts `value` as an array if it's not one.
12147 * @param {*} value The value to inspect.
12148 * @returns {Array} Returns the cast array.
12154 * _.castArray({ 'a': 1 });
12155 * // => [{ 'a': 1 }]
12157 * _.castArray('abc');
12160 * _.castArray(null);
12163 * _.castArray(undefined);
12164 * // => [undefined]
12169 * var array = [1, 2, 3];
12170 * console.log(_.castArray(array) === array);
12173 function castArray() {
12174 if (!arguments.length) {
12177 var value = arguments[0];
12178 return isArray(value) ? value : [value];
12182 * Creates a shallow clone of `value`.
12184 * **Note:** This method is loosely based on the
12185 * [structured clone algorithm](https://mdn.io/Structured_clone_algorithm)
12186 * and supports cloning arrays, array buffers, booleans, date objects, maps,
12187 * numbers, `Object` objects, regexes, sets, strings, symbols, and typed
12188 * arrays. The own enumerable properties of `arguments` objects are cloned
12189 * as plain objects. An empty object is returned for uncloneable values such
12190 * as error objects, functions, DOM nodes, and WeakMaps.
12196 * @param {*} value The value to clone.
12197 * @returns {*} Returns the cloned value.
12201 * var objects = [{ 'a': 1 }, { 'b': 2 }];
12203 * var shallow = _.clone(objects);
12204 * console.log(shallow[0] === objects[0]);
12207 function clone(value) {
12208 return baseClone(value, CLONE_SYMBOLS_FLAG);
12212 * This method is like `_.clone` except that it accepts `customizer` which
12213 * is invoked to produce the cloned value. If `customizer` returns `undefined`,
12214 * cloning is handled by the method instead. The `customizer` is invoked with
12215 * up to four arguments; (value [, index|key, object, stack]).
12221 * @param {*} value The value to clone.
12222 * @param {Function} [customizer] The function to customize cloning.
12223 * @returns {*} Returns the cloned value.
12224 * @see _.cloneDeepWith
12227 * function customizer(value) {
12228 * if (_.isElement(value)) {
12229 * return value.cloneNode(false);
12233 * var el = _.cloneWith(document.body, customizer);
12235 * console.log(el === document.body);
12237 * console.log(el.nodeName);
12239 * console.log(el.childNodes.length);
12242 function cloneWith(value, customizer) {
12243 customizer = typeof customizer == 'function' ? customizer : undefined;
12244 return baseClone(value, CLONE_SYMBOLS_FLAG, customizer);
12248 * This method is like `_.clone` except that it recursively clones `value`.
12254 * @param {*} value The value to recursively clone.
12255 * @returns {*} Returns the deep cloned value.
12259 * var objects = [{ 'a': 1 }, { 'b': 2 }];
12261 * var deep = _.cloneDeep(objects);
12262 * console.log(deep[0] === objects[0]);
12265 function cloneDeep(value) {
12266 return baseClone(value, CLONE_DEEP_FLAG | CLONE_SYMBOLS_FLAG);
12270 * This method is like `_.cloneWith` except that it recursively clones `value`.
12276 * @param {*} value The value to recursively clone.
12277 * @param {Function} [customizer] The function to customize cloning.
12278 * @returns {*} Returns the deep cloned value.
12282 * function customizer(value) {
12283 * if (_.isElement(value)) {
12284 * return value.cloneNode(true);
12288 * var el = _.cloneDeepWith(document.body, customizer);
12290 * console.log(el === document.body);
12292 * console.log(el.nodeName);
12294 * console.log(el.childNodes.length);
12297 function cloneDeepWith(value, customizer) {
12298 customizer = typeof customizer == 'function' ? customizer : undefined;
12299 return baseClone(value, CLONE_DEEP_FLAG | CLONE_SYMBOLS_FLAG, customizer);
12303 * Checks if `object` conforms to `source` by invoking the predicate
12304 * properties of `source` with the corresponding property values of `object`.
12306 * **Note:** This method is equivalent to `_.conforms` when `source` is
12307 * partially applied.
12313 * @param {Object} object The object to inspect.
12314 * @param {Object} source The object of property predicates to conform to.
12315 * @returns {boolean} Returns `true` if `object` conforms, else `false`.
12318 * var object = { 'a': 1, 'b': 2 };
12320 * _.conformsTo(object, { 'b': function(n) { return n > 1; } });
12323 * _.conformsTo(object, { 'b': function(n) { return n > 2; } });
12326 function conformsTo(object, source) {
12327 return source == null || baseConformsTo(object, source, keys(source));
12332 * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
12333 * comparison between two values to determine if they are equivalent.
12339 * @param {*} value The value to compare.
12340 * @param {*} other The other value to compare.
12341 * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
12344 * var object = { 'a': 1 };
12345 * var other = { 'a': 1 };
12347 * _.eq(object, object);
12350 * _.eq(object, other);
12356 * _.eq('a', Object('a'));
12362 function eq(value, other) {
12363 return value === other || (value !== value && other !== other);
12367 * Checks if `value` is greater than `other`.
12373 * @param {*} value The value to compare.
12374 * @param {*} other The other value to compare.
12375 * @returns {boolean} Returns `true` if `value` is greater than `other`,
12389 var gt = createRelationalOperation(baseGt);
12392 * Checks if `value` is greater than or equal to `other`.
12398 * @param {*} value The value to compare.
12399 * @param {*} other The other value to compare.
12400 * @returns {boolean} Returns `true` if `value` is greater than or equal to
12401 * `other`, else `false`.
12414 var gte = createRelationalOperation(function(value, other) {
12415 return value >= other;
12419 * Checks if `value` is likely an `arguments` object.
12425 * @param {*} value The value to check.
12426 * @returns {boolean} Returns `true` if `value` is an `arguments` object,
12430 * _.isArguments(function() { return arguments; }());
12433 * _.isArguments([1, 2, 3]);
12436 var isArguments = baseIsArguments(function() { return arguments; }()) ? baseIsArguments : function(value) {
12437 return isObjectLike(value) && hasOwnProperty.call(value, 'callee') &&
12438 !propertyIsEnumerable.call(value, 'callee');
12442 * Checks if `value` is classified as an `Array` object.
12448 * @param {*} value The value to check.
12449 * @returns {boolean} Returns `true` if `value` is an array, else `false`.
12452 * _.isArray([1, 2, 3]);
12455 * _.isArray(document.body.children);
12458 * _.isArray('abc');
12461 * _.isArray(_.noop);
12464 var isArray = Array.isArray;
12467 * Checks if `value` is classified as an `ArrayBuffer` object.
12473 * @param {*} value The value to check.
12474 * @returns {boolean} Returns `true` if `value` is an array buffer, else `false`.
12477 * _.isArrayBuffer(new ArrayBuffer(2));
12480 * _.isArrayBuffer(new Array(2));
12483 var isArrayBuffer = nodeIsArrayBuffer ? baseUnary(nodeIsArrayBuffer) : baseIsArrayBuffer;
12486 * Checks if `value` is array-like. A value is considered array-like if it's
12487 * not a function and has a `value.length` that's an integer greater than or
12488 * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`.
12494 * @param {*} value The value to check.
12495 * @returns {boolean} Returns `true` if `value` is array-like, else `false`.
12498 * _.isArrayLike([1, 2, 3]);
12501 * _.isArrayLike(document.body.children);
12504 * _.isArrayLike('abc');
12507 * _.isArrayLike(_.noop);
12510 function isArrayLike(value) {
12511 return value != null && isLength(value.length) && !isFunction(value);
12515 * This method is like `_.isArrayLike` except that it also checks if `value`
12522 * @param {*} value The value to check.
12523 * @returns {boolean} Returns `true` if `value` is an array-like object,
12527 * _.isArrayLikeObject([1, 2, 3]);
12530 * _.isArrayLikeObject(document.body.children);
12533 * _.isArrayLikeObject('abc');
12536 * _.isArrayLikeObject(_.noop);
12539 function isArrayLikeObject(value) {
12540 return isObjectLike(value) && isArrayLike(value);
12544 * Checks if `value` is classified as a boolean primitive or object.
12550 * @param {*} value The value to check.
12551 * @returns {boolean} Returns `true` if `value` is a boolean, else `false`.
12554 * _.isBoolean(false);
12557 * _.isBoolean(null);
12560 function isBoolean(value) {
12561 return value === true || value === false ||
12562 (isObjectLike(value) && baseGetTag(value) == boolTag);
12566 * Checks if `value` is a buffer.
12572 * @param {*} value The value to check.
12573 * @returns {boolean} Returns `true` if `value` is a buffer, else `false`.
12576 * _.isBuffer(new Buffer(2));
12579 * _.isBuffer(new Uint8Array(2));
12582 var isBuffer = nativeIsBuffer || stubFalse;
12585 * Checks if `value` is classified as a `Date` object.
12591 * @param {*} value The value to check.
12592 * @returns {boolean} Returns `true` if `value` is a date object, else `false`.
12595 * _.isDate(new Date);
12598 * _.isDate('Mon April 23 2012');
12601 var isDate = nodeIsDate ? baseUnary(nodeIsDate) : baseIsDate;
12604 * Checks if `value` is likely a DOM element.
12610 * @param {*} value The value to check.
12611 * @returns {boolean} Returns `true` if `value` is a DOM element, else `false`.
12614 * _.isElement(document.body);
12617 * _.isElement('<body>');
12620 function isElement(value) {
12621 return isObjectLike(value) && value.nodeType === 1 && !isPlainObject(value);
12625 * Checks if `value` is an empty object, collection, map, or set.
12627 * Objects are considered empty if they have no own enumerable string keyed
12630 * Array-like values such as `arguments` objects, arrays, buffers, strings, or
12631 * jQuery-like collections are considered empty if they have a `length` of `0`.
12632 * Similarly, maps and sets are considered empty if they have a `size` of `0`.
12638 * @param {*} value The value to check.
12639 * @returns {boolean} Returns `true` if `value` is empty, else `false`.
12651 * _.isEmpty([1, 2, 3]);
12654 * _.isEmpty({ 'a': 1 });
12657 function isEmpty(value) {
12658 if (value == null) {
12661 if (isArrayLike(value) &&
12662 (isArray(value) || typeof value == 'string' || typeof value.splice == 'function' ||
12663 isBuffer(value) || isTypedArray(value) || isArguments(value))) {
12664 return !value.length;
12666 var tag = getTag(value);
12667 if (tag == mapTag || tag == setTag) {
12668 return !value.size;
12670 if (isPrototype(value)) {
12671 return !baseKeys(value).length;
12673 for (var key in value) {
12674 if (hasOwnProperty.call(value, key)) {
12682 * Performs a deep comparison between two values to determine if they are
12685 * **Note:** This method supports comparing arrays, array buffers, booleans,
12686 * date objects, error objects, maps, numbers, `Object` objects, regexes,
12687 * sets, strings, symbols, and typed arrays. `Object` objects are compared
12688 * by their own, not inherited, enumerable properties. Functions and DOM
12689 * nodes are compared by strict equality, i.e. `===`.
12695 * @param {*} value The value to compare.
12696 * @param {*} other The other value to compare.
12697 * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
12700 * var object = { 'a': 1 };
12701 * var other = { 'a': 1 };
12703 * _.isEqual(object, other);
12706 * object === other;
12709 function isEqual(value, other) {
12710 return baseIsEqual(value, other);
12714 * This method is like `_.isEqual` except that it accepts `customizer` which
12715 * is invoked to compare values. If `customizer` returns `undefined`, comparisons
12716 * are handled by the method instead. The `customizer` is invoked with up to
12717 * six arguments: (objValue, othValue [, index|key, object, other, stack]).
12723 * @param {*} value The value to compare.
12724 * @param {*} other The other value to compare.
12725 * @param {Function} [customizer] The function to customize comparisons.
12726 * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
12729 * function isGreeting(value) {
12730 * return /^h(?:i|ello)$/.test(value);
12733 * function customizer(objValue, othValue) {
12734 * if (isGreeting(objValue) && isGreeting(othValue)) {
12739 * var array = ['hello', 'goodbye'];
12740 * var other = ['hi', 'goodbye'];
12742 * _.isEqualWith(array, other, customizer);
12745 function isEqualWith(value, other, customizer) {
12746 customizer = typeof customizer == 'function' ? customizer : undefined;
12747 var result = customizer ? customizer(value, other) : undefined;
12748 return result === undefined ? baseIsEqual(value, other, undefined, customizer) : !!result;
12752 * Checks if `value` is an `Error`, `EvalError`, `RangeError`, `ReferenceError`,
12753 * `SyntaxError`, `TypeError`, or `URIError` object.
12759 * @param {*} value The value to check.
12760 * @returns {boolean} Returns `true` if `value` is an error object, else `false`.
12763 * _.isError(new Error);
12766 * _.isError(Error);
12769 function isError(value) {
12770 if (!isObjectLike(value)) {
12773 var tag = baseGetTag(value);
12774 return tag == errorTag || tag == domExcTag ||
12775 (typeof value.message == 'string' && typeof value.name == 'string' && !isPlainObject(value));
12779 * Checks if `value` is a finite primitive number.
12781 * **Note:** This method is based on
12782 * [`Number.isFinite`](https://mdn.io/Number/isFinite).
12788 * @param {*} value The value to check.
12789 * @returns {boolean} Returns `true` if `value` is a finite number, else `false`.
12795 * _.isFinite(Number.MIN_VALUE);
12798 * _.isFinite(Infinity);
12804 function isFinite(value) {
12805 return typeof value == 'number' && nativeIsFinite(value);
12809 * Checks if `value` is classified as a `Function` object.
12815 * @param {*} value The value to check.
12816 * @returns {boolean} Returns `true` if `value` is a function, else `false`.
12822 * _.isFunction(/abc/);
12825 function isFunction(value) {
12826 if (!isObject(value)) {
12829 // The use of `Object#toString` avoids issues with the `typeof` operator
12830 // in Safari 9 which returns 'object' for typed arrays and other constructors.
12831 var tag = baseGetTag(value);
12832 return tag == funcTag || tag == genTag || tag == asyncTag || tag == proxyTag;
12836 * Checks if `value` is an integer.
12838 * **Note:** This method is based on
12839 * [`Number.isInteger`](https://mdn.io/Number/isInteger).
12845 * @param {*} value The value to check.
12846 * @returns {boolean} Returns `true` if `value` is an integer, else `false`.
12852 * _.isInteger(Number.MIN_VALUE);
12855 * _.isInteger(Infinity);
12858 * _.isInteger('3');
12861 function isInteger(value) {
12862 return typeof value == 'number' && value == toInteger(value);
12866 * Checks if `value` is a valid array-like length.
12868 * **Note:** This method is loosely based on
12869 * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength).
12875 * @param {*} value The value to check.
12876 * @returns {boolean} Returns `true` if `value` is a valid length, else `false`.
12882 * _.isLength(Number.MIN_VALUE);
12885 * _.isLength(Infinity);
12891 function isLength(value) {
12892 return typeof value == 'number' &&
12893 value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;
12897 * Checks if `value` is the
12898 * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)
12899 * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
12905 * @param {*} value The value to check.
12906 * @returns {boolean} Returns `true` if `value` is an object, else `false`.
12912 * _.isObject([1, 2, 3]);
12915 * _.isObject(_.noop);
12918 * _.isObject(null);
12921 function isObject(value) {
12922 var type = typeof value;
12923 return value != null && (type == 'object' || type == 'function');
12927 * Checks if `value` is object-like. A value is object-like if it's not `null`
12928 * and has a `typeof` result of "object".
12934 * @param {*} value The value to check.
12935 * @returns {boolean} Returns `true` if `value` is object-like, else `false`.
12938 * _.isObjectLike({});
12941 * _.isObjectLike([1, 2, 3]);
12944 * _.isObjectLike(_.noop);
12947 * _.isObjectLike(null);
12950 function isObjectLike(value) {
12951 return value != null && typeof value == 'object';
12955 * Checks if `value` is classified as a `Map` object.
12961 * @param {*} value The value to check.
12962 * @returns {boolean} Returns `true` if `value` is a map, else `false`.
12965 * _.isMap(new Map);
12968 * _.isMap(new WeakMap);
12971 var isMap = nodeIsMap ? baseUnary(nodeIsMap) : baseIsMap;
12974 * Performs a partial deep comparison between `object` and `source` to
12975 * determine if `object` contains equivalent property values.
12977 * **Note:** This method is equivalent to `_.matches` when `source` is
12978 * partially applied.
12980 * Partial comparisons will match empty array and empty object `source`
12981 * values against any array or object value, respectively. See `_.isEqual`
12982 * for a list of supported value comparisons.
12988 * @param {Object} object The object to inspect.
12989 * @param {Object} source The object of property values to match.
12990 * @returns {boolean} Returns `true` if `object` is a match, else `false`.
12993 * var object = { 'a': 1, 'b': 2 };
12995 * _.isMatch(object, { 'b': 2 });
12998 * _.isMatch(object, { 'b': 1 });
13001 function isMatch(object, source) {
13002 return object === source || baseIsMatch(object, source, getMatchData(source));
13006 * This method is like `_.isMatch` except that it accepts `customizer` which
13007 * is invoked to compare values. If `customizer` returns `undefined`, comparisons
13008 * are handled by the method instead. The `customizer` is invoked with five
13009 * arguments: (objValue, srcValue, index|key, object, source).
13015 * @param {Object} object The object to inspect.
13016 * @param {Object} source The object of property values to match.
13017 * @param {Function} [customizer] The function to customize comparisons.
13018 * @returns {boolean} Returns `true` if `object` is a match, else `false`.
13021 * function isGreeting(value) {
13022 * return /^h(?:i|ello)$/.test(value);
13025 * function customizer(objValue, srcValue) {
13026 * if (isGreeting(objValue) && isGreeting(srcValue)) {
13031 * var object = { 'greeting': 'hello' };
13032 * var source = { 'greeting': 'hi' };
13034 * _.isMatchWith(object, source, customizer);
13037 function isMatchWith(object, source, customizer) {
13038 customizer = typeof customizer == 'function' ? customizer : undefined;
13039 return baseIsMatch(object, source, getMatchData(source), customizer);
13043 * Checks if `value` is `NaN`.
13045 * **Note:** This method is based on
13046 * [`Number.isNaN`](https://mdn.io/Number/isNaN) and is not the same as
13047 * global [`isNaN`](https://mdn.io/isNaN) which returns `true` for
13048 * `undefined` and other non-number values.
13054 * @param {*} value The value to check.
13055 * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`.
13061 * _.isNaN(new Number(NaN));
13064 * isNaN(undefined);
13067 * _.isNaN(undefined);
13070 function isNaN(value) {
13071 // An `NaN` primitive is the only value that is not equal to itself.
13072 // Perform the `toStringTag` check first to avoid errors with some
13073 // ActiveX objects in IE.
13074 return isNumber(value) && value != +value;
13078 * Checks if `value` is a pristine native function.
13080 * **Note:** This method can't reliably detect native functions in the presence
13081 * of the core-js package because core-js circumvents this kind of detection.
13082 * Despite multiple requests, the core-js maintainer has made it clear: any
13083 * attempt to fix the detection will be obstructed. As a result, we're left
13084 * with little choice but to throw an error. Unfortunately, this also affects
13085 * packages, like [babel-polyfill](https://www.npmjs.com/package/babel-polyfill),
13086 * which rely on core-js.
13092 * @param {*} value The value to check.
13093 * @returns {boolean} Returns `true` if `value` is a native function,
13097 * _.isNative(Array.prototype.push);
13103 function isNative(value) {
13104 if (isMaskable(value)) {
13105 throw new Error(CORE_ERROR_TEXT);
13107 return baseIsNative(value);
13111 * Checks if `value` is `null`.
13117 * @param {*} value The value to check.
13118 * @returns {boolean} Returns `true` if `value` is `null`, else `false`.
13124 * _.isNull(void 0);
13127 function isNull(value) {
13128 return value === null;
13132 * Checks if `value` is `null` or `undefined`.
13138 * @param {*} value The value to check.
13139 * @returns {boolean} Returns `true` if `value` is nullish, else `false`.
13151 function isNil(value) {
13152 return value == null;
13156 * Checks if `value` is classified as a `Number` primitive or object.
13158 * **Note:** To exclude `Infinity`, `-Infinity`, and `NaN`, which are
13159 * classified as numbers, use the `_.isFinite` method.
13165 * @param {*} value The value to check.
13166 * @returns {boolean} Returns `true` if `value` is a number, else `false`.
13172 * _.isNumber(Number.MIN_VALUE);
13175 * _.isNumber(Infinity);
13181 function isNumber(value) {
13182 return typeof value == 'number' ||
13183 (isObjectLike(value) && baseGetTag(value) == numberTag);
13187 * Checks if `value` is a plain object, that is, an object created by the
13188 * `Object` constructor or one with a `[[Prototype]]` of `null`.
13194 * @param {*} value The value to check.
13195 * @returns {boolean} Returns `true` if `value` is a plain object, else `false`.
13202 * _.isPlainObject(new Foo);
13205 * _.isPlainObject([1, 2, 3]);
13208 * _.isPlainObject({ 'x': 0, 'y': 0 });
13211 * _.isPlainObject(Object.create(null));
13214 function isPlainObject(value) {
13215 if (!isObjectLike(value) || baseGetTag(value) != objectTag) {
13218 var proto = getPrototype(value);
13219 if (proto === null) {
13222 var Ctor = hasOwnProperty.call(proto, 'constructor') && proto.constructor;
13223 return typeof Ctor == 'function' && Ctor instanceof Ctor &&
13224 funcToString.call(Ctor) == objectCtorString;
13228 * Checks if `value` is classified as a `RegExp` object.
13234 * @param {*} value The value to check.
13235 * @returns {boolean} Returns `true` if `value` is a regexp, else `false`.
13238 * _.isRegExp(/abc/);
13241 * _.isRegExp('/abc/');
13244 var isRegExp = nodeIsRegExp ? baseUnary(nodeIsRegExp) : baseIsRegExp;
13247 * Checks if `value` is a safe integer. An integer is safe if it's an IEEE-754
13248 * double precision number which isn't the result of a rounded unsafe integer.
13250 * **Note:** This method is based on
13251 * [`Number.isSafeInteger`](https://mdn.io/Number/isSafeInteger).
13257 * @param {*} value The value to check.
13258 * @returns {boolean} Returns `true` if `value` is a safe integer, else `false`.
13261 * _.isSafeInteger(3);
13264 * _.isSafeInteger(Number.MIN_VALUE);
13267 * _.isSafeInteger(Infinity);
13270 * _.isSafeInteger('3');
13273 function isSafeInteger(value) {
13274 return isInteger(value) && value >= -MAX_SAFE_INTEGER && value <= MAX_SAFE_INTEGER;
13278 * Checks if `value` is classified as a `Set` object.
13284 * @param {*} value The value to check.
13285 * @returns {boolean} Returns `true` if `value` is a set, else `false`.
13288 * _.isSet(new Set);
13291 * _.isSet(new WeakSet);
13294 var isSet = nodeIsSet ? baseUnary(nodeIsSet) : baseIsSet;
13297 * Checks if `value` is classified as a `String` primitive or object.
13303 * @param {*} value The value to check.
13304 * @returns {boolean} Returns `true` if `value` is a string, else `false`.
13307 * _.isString('abc');
13313 function isString(value) {
13314 return typeof value == 'string' ||
13315 (!isArray(value) && isObjectLike(value) && baseGetTag(value) == stringTag);
13319 * Checks if `value` is classified as a `Symbol` primitive or object.
13325 * @param {*} value The value to check.
13326 * @returns {boolean} Returns `true` if `value` is a symbol, else `false`.
13329 * _.isSymbol(Symbol.iterator);
13332 * _.isSymbol('abc');
13335 function isSymbol(value) {
13336 return typeof value == 'symbol' ||
13337 (isObjectLike(value) && baseGetTag(value) == symbolTag);
13341 * Checks if `value` is classified as a typed array.
13347 * @param {*} value The value to check.
13348 * @returns {boolean} Returns `true` if `value` is a typed array, else `false`.
13351 * _.isTypedArray(new Uint8Array);
13354 * _.isTypedArray([]);
13357 var isTypedArray = nodeIsTypedArray ? baseUnary(nodeIsTypedArray) : baseIsTypedArray;
13360 * Checks if `value` is `undefined`.
13366 * @param {*} value The value to check.
13367 * @returns {boolean} Returns `true` if `value` is `undefined`, else `false`.
13370 * _.isUndefined(void 0);
13373 * _.isUndefined(null);
13376 function isUndefined(value) {
13377 return value === undefined;
13381 * Checks if `value` is classified as a `WeakMap` object.
13387 * @param {*} value The value to check.
13388 * @returns {boolean} Returns `true` if `value` is a weak map, else `false`.
13391 * _.isWeakMap(new WeakMap);
13394 * _.isWeakMap(new Map);
13397 function isWeakMap(value) {
13398 return isObjectLike(value) && getTag(value) == weakMapTag;
13402 * Checks if `value` is classified as a `WeakSet` object.
13408 * @param {*} value The value to check.
13409 * @returns {boolean} Returns `true` if `value` is a weak set, else `false`.
13412 * _.isWeakSet(new WeakSet);
13415 * _.isWeakSet(new Set);
13418 function isWeakSet(value) {
13419 return isObjectLike(value) && baseGetTag(value) == weakSetTag;
13423 * Checks if `value` is less than `other`.
13429 * @param {*} value The value to compare.
13430 * @param {*} other The other value to compare.
13431 * @returns {boolean} Returns `true` if `value` is less than `other`,
13445 var lt = createRelationalOperation(baseLt);
13448 * Checks if `value` is less than or equal to `other`.
13454 * @param {*} value The value to compare.
13455 * @param {*} other The other value to compare.
13456 * @returns {boolean} Returns `true` if `value` is less than or equal to
13457 * `other`, else `false`.
13470 var lte = createRelationalOperation(function(value, other) {
13471 return value <= other;
13475 * Converts `value` to an array.
13481 * @param {*} value The value to convert.
13482 * @returns {Array} Returns the converted array.
13485 * _.toArray({ 'a': 1, 'b': 2 });
13488 * _.toArray('abc');
13489 * // => ['a', 'b', 'c']
13497 function toArray(value) {
13501 if (isArrayLike(value)) {
13502 return isString(value) ? stringToArray(value) : copyArray(value);
13504 if (symIterator && value[symIterator]) {
13505 return iteratorToArray(value[symIterator]());
13507 var tag = getTag(value),
13508 func = tag == mapTag ? mapToArray : (tag == setTag ? setToArray : values);
13510 return func(value);
13514 * Converts `value` to a finite number.
13520 * @param {*} value The value to convert.
13521 * @returns {number} Returns the converted number.
13527 * _.toFinite(Number.MIN_VALUE);
13530 * _.toFinite(Infinity);
13531 * // => 1.7976931348623157e+308
13533 * _.toFinite('3.2');
13536 function toFinite(value) {
13538 return value === 0 ? value : 0;
13540 value = toNumber(value);
13541 if (value === INFINITY || value === -INFINITY) {
13542 var sign = (value < 0 ? -1 : 1);
13543 return sign * MAX_INTEGER;
13545 return value === value ? value : 0;
13549 * Converts `value` to an integer.
13551 * **Note:** This method is loosely based on
13552 * [`ToInteger`](http://www.ecma-international.org/ecma-262/7.0/#sec-tointeger).
13558 * @param {*} value The value to convert.
13559 * @returns {number} Returns the converted integer.
13562 * _.toInteger(3.2);
13565 * _.toInteger(Number.MIN_VALUE);
13568 * _.toInteger(Infinity);
13569 * // => 1.7976931348623157e+308
13571 * _.toInteger('3.2');
13574 function toInteger(value) {
13575 var result = toFinite(value),
13576 remainder = result % 1;
13578 return result === result ? (remainder ? result - remainder : result) : 0;
13582 * Converts `value` to an integer suitable for use as the length of an
13583 * array-like object.
13585 * **Note:** This method is based on
13586 * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength).
13592 * @param {*} value The value to convert.
13593 * @returns {number} Returns the converted integer.
13599 * _.toLength(Number.MIN_VALUE);
13602 * _.toLength(Infinity);
13605 * _.toLength('3.2');
13608 function toLength(value) {
13609 return value ? baseClamp(toInteger(value), 0, MAX_ARRAY_LENGTH) : 0;
13613 * Converts `value` to a number.
13619 * @param {*} value The value to process.
13620 * @returns {number} Returns the number.
13626 * _.toNumber(Number.MIN_VALUE);
13629 * _.toNumber(Infinity);
13632 * _.toNumber('3.2');
13635 function toNumber(value) {
13636 if (typeof value == 'number') {
13639 if (isSymbol(value)) {
13642 if (isObject(value)) {
13643 var other = typeof value.valueOf == 'function' ? value.valueOf() : value;
13644 value = isObject(other) ? (other + '') : other;
13646 if (typeof value != 'string') {
13647 return value === 0 ? value : +value;
13649 value = baseTrim(value);
13650 var isBinary = reIsBinary.test(value);
13651 return (isBinary || reIsOctal.test(value))
13652 ? freeParseInt(value.slice(2), isBinary ? 2 : 8)
13653 : (reIsBadHex.test(value) ? NAN : +value);
13657 * Converts `value` to a plain object flattening inherited enumerable string
13658 * keyed properties of `value` to own properties of the plain object.
13664 * @param {*} value The value to convert.
13665 * @returns {Object} Returns the converted plain object.
13672 * Foo.prototype.c = 3;
13674 * _.assign({ 'a': 1 }, new Foo);
13675 * // => { 'a': 1, 'b': 2 }
13677 * _.assign({ 'a': 1 }, _.toPlainObject(new Foo));
13678 * // => { 'a': 1, 'b': 2, 'c': 3 }
13680 function toPlainObject(value) {
13681 return copyObject(value, keysIn(value));
13685 * Converts `value` to a safe integer. A safe integer can be compared and
13686 * represented correctly.
13692 * @param {*} value The value to convert.
13693 * @returns {number} Returns the converted integer.
13696 * _.toSafeInteger(3.2);
13699 * _.toSafeInteger(Number.MIN_VALUE);
13702 * _.toSafeInteger(Infinity);
13703 * // => 9007199254740991
13705 * _.toSafeInteger('3.2');
13708 function toSafeInteger(value) {
13710 ? baseClamp(toInteger(value), -MAX_SAFE_INTEGER, MAX_SAFE_INTEGER)
13711 : (value === 0 ? value : 0);
13715 * Converts `value` to a string. An empty string is returned for `null`
13716 * and `undefined` values. The sign of `-0` is preserved.
13722 * @param {*} value The value to convert.
13723 * @returns {string} Returns the converted string.
13726 * _.toString(null);
13732 * _.toString([1, 2, 3]);
13735 function toString(value) {
13736 return value == null ? '' : baseToString(value);
13739 /*------------------------------------------------------------------------*/
13742 * Assigns own enumerable string keyed properties of source objects to the
13743 * destination object. Source objects are applied from left to right.
13744 * Subsequent sources overwrite property assignments of previous sources.
13746 * **Note:** This method mutates `object` and is loosely based on
13747 * [`Object.assign`](https://mdn.io/Object/assign).
13753 * @param {Object} object The destination object.
13754 * @param {...Object} [sources] The source objects.
13755 * @returns {Object} Returns `object`.
13767 * Foo.prototype.b = 2;
13768 * Bar.prototype.d = 4;
13770 * _.assign({ 'a': 0 }, new Foo, new Bar);
13771 * // => { 'a': 1, 'c': 3 }
13773 var assign = createAssigner(function(object, source) {
13774 if (isPrototype(source) || isArrayLike(source)) {
13775 copyObject(source, keys(source), object);
13778 for (var key in source) {
13779 if (hasOwnProperty.call(source, key)) {
13780 assignValue(object, key, source[key]);
13786 * This method is like `_.assign` except that it iterates over own and
13787 * inherited source properties.
13789 * **Note:** This method mutates `object`.
13796 * @param {Object} object The destination object.
13797 * @param {...Object} [sources] The source objects.
13798 * @returns {Object} Returns `object`.
13810 * Foo.prototype.b = 2;
13811 * Bar.prototype.d = 4;
13813 * _.assignIn({ 'a': 0 }, new Foo, new Bar);
13814 * // => { 'a': 1, 'b': 2, 'c': 3, 'd': 4 }
13816 var assignIn = createAssigner(function(object, source) {
13817 copyObject(source, keysIn(source), object);
13821 * This method is like `_.assignIn` except that it accepts `customizer`
13822 * which is invoked to produce the assigned values. If `customizer` returns
13823 * `undefined`, assignment is handled by the method instead. The `customizer`
13824 * is invoked with five arguments: (objValue, srcValue, key, object, source).
13826 * **Note:** This method mutates `object`.
13831 * @alias extendWith
13833 * @param {Object} object The destination object.
13834 * @param {...Object} sources The source objects.
13835 * @param {Function} [customizer] The function to customize assigned values.
13836 * @returns {Object} Returns `object`.
13837 * @see _.assignWith
13840 * function customizer(objValue, srcValue) {
13841 * return _.isUndefined(objValue) ? srcValue : objValue;
13844 * var defaults = _.partialRight(_.assignInWith, customizer);
13846 * defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 });
13847 * // => { 'a': 1, 'b': 2 }
13849 var assignInWith = createAssigner(function(object, source, srcIndex, customizer) {
13850 copyObject(source, keysIn(source), object, customizer);
13854 * This method is like `_.assign` except that it accepts `customizer`
13855 * which is invoked to produce the assigned values. If `customizer` returns
13856 * `undefined`, assignment is handled by the method instead. The `customizer`
13857 * is invoked with five arguments: (objValue, srcValue, key, object, source).
13859 * **Note:** This method mutates `object`.
13865 * @param {Object} object The destination object.
13866 * @param {...Object} sources The source objects.
13867 * @param {Function} [customizer] The function to customize assigned values.
13868 * @returns {Object} Returns `object`.
13869 * @see _.assignInWith
13872 * function customizer(objValue, srcValue) {
13873 * return _.isUndefined(objValue) ? srcValue : objValue;
13876 * var defaults = _.partialRight(_.assignWith, customizer);
13878 * defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 });
13879 * // => { 'a': 1, 'b': 2 }
13881 var assignWith = createAssigner(function(object, source, srcIndex, customizer) {
13882 copyObject(source, keys(source), object, customizer);
13886 * Creates an array of values corresponding to `paths` of `object`.
13892 * @param {Object} object The object to iterate over.
13893 * @param {...(string|string[])} [paths] The property paths to pick.
13894 * @returns {Array} Returns the picked values.
13897 * var object = { 'a': [{ 'b': { 'c': 3 } }, 4] };
13899 * _.at(object, ['a[0].b.c', 'a[1]']);
13902 var at = flatRest(baseAt);
13905 * Creates an object that inherits from the `prototype` object. If a
13906 * `properties` object is given, its own enumerable string keyed properties
13907 * are assigned to the created object.
13913 * @param {Object} prototype The object to inherit from.
13914 * @param {Object} [properties] The properties to assign to the object.
13915 * @returns {Object} Returns the new object.
13918 * function Shape() {
13923 * function Circle() {
13924 * Shape.call(this);
13927 * Circle.prototype = _.create(Shape.prototype, {
13928 * 'constructor': Circle
13931 * var circle = new Circle;
13932 * circle instanceof Circle;
13935 * circle instanceof Shape;
13938 function create(prototype, properties) {
13939 var result = baseCreate(prototype);
13940 return properties == null ? result : baseAssign(result, properties);
13944 * Assigns own and inherited enumerable string keyed properties of source
13945 * objects to the destination object for all destination properties that
13946 * resolve to `undefined`. Source objects are applied from left to right.
13947 * Once a property is set, additional values of the same property are ignored.
13949 * **Note:** This method mutates `object`.
13955 * @param {Object} object The destination object.
13956 * @param {...Object} [sources] The source objects.
13957 * @returns {Object} Returns `object`.
13958 * @see _.defaultsDeep
13961 * _.defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 });
13962 * // => { 'a': 1, 'b': 2 }
13964 var defaults = baseRest(function(object, sources) {
13965 object = Object(object);
13968 var length = sources.length;
13969 var guard = length > 2 ? sources[2] : undefined;
13971 if (guard && isIterateeCall(sources[0], sources[1], guard)) {
13975 while (++index < length) {
13976 var source = sources[index];
13977 var props = keysIn(source);
13978 var propsIndex = -1;
13979 var propsLength = props.length;
13981 while (++propsIndex < propsLength) {
13982 var key = props[propsIndex];
13983 var value = object[key];
13985 if (value === undefined ||
13986 (eq(value, objectProto[key]) && !hasOwnProperty.call(object, key))) {
13987 object[key] = source[key];
13996 * This method is like `_.defaults` except that it recursively assigns
13997 * default properties.
13999 * **Note:** This method mutates `object`.
14005 * @param {Object} object The destination object.
14006 * @param {...Object} [sources] The source objects.
14007 * @returns {Object} Returns `object`.
14011 * _.defaultsDeep({ 'a': { 'b': 2 } }, { 'a': { 'b': 1, 'c': 3 } });
14012 * // => { 'a': { 'b': 2, 'c': 3 } }
14014 var defaultsDeep = baseRest(function(args) {
14015 args.push(undefined, customDefaultsMerge);
14016 return apply(mergeWith, undefined, args);
14020 * This method is like `_.find` except that it returns the key of the first
14021 * element `predicate` returns truthy for instead of the element itself.
14027 * @param {Object} object The object to inspect.
14028 * @param {Function} [predicate=_.identity] The function invoked per iteration.
14029 * @returns {string|undefined} Returns the key of the matched element,
14030 * else `undefined`.
14034 * 'barney': { 'age': 36, 'active': true },
14035 * 'fred': { 'age': 40, 'active': false },
14036 * 'pebbles': { 'age': 1, 'active': true }
14039 * _.findKey(users, function(o) { return o.age < 40; });
14040 * // => 'barney' (iteration order is not guaranteed)
14042 * // The `_.matches` iteratee shorthand.
14043 * _.findKey(users, { 'age': 1, 'active': true });
14046 * // The `_.matchesProperty` iteratee shorthand.
14047 * _.findKey(users, ['active', false]);
14050 * // The `_.property` iteratee shorthand.
14051 * _.findKey(users, 'active');
14054 function findKey(object, predicate) {
14055 return baseFindKey(object, getIteratee(predicate, 3), baseForOwn);
14059 * This method is like `_.findKey` except that it iterates over elements of
14060 * a collection in the opposite order.
14066 * @param {Object} object The object to inspect.
14067 * @param {Function} [predicate=_.identity] The function invoked per iteration.
14068 * @returns {string|undefined} Returns the key of the matched element,
14069 * else `undefined`.
14073 * 'barney': { 'age': 36, 'active': true },
14074 * 'fred': { 'age': 40, 'active': false },
14075 * 'pebbles': { 'age': 1, 'active': true }
14078 * _.findLastKey(users, function(o) { return o.age < 40; });
14079 * // => returns 'pebbles' assuming `_.findKey` returns 'barney'
14081 * // The `_.matches` iteratee shorthand.
14082 * _.findLastKey(users, { 'age': 36, 'active': true });
14085 * // The `_.matchesProperty` iteratee shorthand.
14086 * _.findLastKey(users, ['active', false]);
14089 * // The `_.property` iteratee shorthand.
14090 * _.findLastKey(users, 'active');
14093 function findLastKey(object, predicate) {
14094 return baseFindKey(object, getIteratee(predicate, 3), baseForOwnRight);
14098 * Iterates over own and inherited enumerable string keyed properties of an
14099 * object and invokes `iteratee` for each property. The iteratee is invoked
14100 * with three arguments: (value, key, object). Iteratee functions may exit
14101 * iteration early by explicitly returning `false`.
14107 * @param {Object} object The object to iterate over.
14108 * @param {Function} [iteratee=_.identity] The function invoked per iteration.
14109 * @returns {Object} Returns `object`.
14110 * @see _.forInRight
14118 * Foo.prototype.c = 3;
14120 * _.forIn(new Foo, function(value, key) {
14121 * console.log(key);
14123 * // => Logs 'a', 'b', then 'c' (iteration order is not guaranteed).
14125 function forIn(object, iteratee) {
14126 return object == null
14128 : baseFor(object, getIteratee(iteratee, 3), keysIn);
14132 * This method is like `_.forIn` except that it iterates over properties of
14133 * `object` in the opposite order.
14139 * @param {Object} object The object to iterate over.
14140 * @param {Function} [iteratee=_.identity] The function invoked per iteration.
14141 * @returns {Object} Returns `object`.
14150 * Foo.prototype.c = 3;
14152 * _.forInRight(new Foo, function(value, key) {
14153 * console.log(key);
14155 * // => Logs 'c', 'b', then 'a' assuming `_.forIn` logs 'a', 'b', then 'c'.
14157 function forInRight(object, iteratee) {
14158 return object == null
14160 : baseForRight(object, getIteratee(iteratee, 3), keysIn);
14164 * Iterates over own enumerable string keyed properties of an object and
14165 * invokes `iteratee` for each property. The iteratee is invoked with three
14166 * arguments: (value, key, object). Iteratee functions may exit iteration
14167 * early by explicitly returning `false`.
14173 * @param {Object} object The object to iterate over.
14174 * @param {Function} [iteratee=_.identity] The function invoked per iteration.
14175 * @returns {Object} Returns `object`.
14176 * @see _.forOwnRight
14184 * Foo.prototype.c = 3;
14186 * _.forOwn(new Foo, function(value, key) {
14187 * console.log(key);
14189 * // => Logs 'a' then 'b' (iteration order is not guaranteed).
14191 function forOwn(object, iteratee) {
14192 return object && baseForOwn(object, getIteratee(iteratee, 3));
14196 * This method is like `_.forOwn` except that it iterates over properties of
14197 * `object` in the opposite order.
14203 * @param {Object} object The object to iterate over.
14204 * @param {Function} [iteratee=_.identity] The function invoked per iteration.
14205 * @returns {Object} Returns `object`.
14214 * Foo.prototype.c = 3;
14216 * _.forOwnRight(new Foo, function(value, key) {
14217 * console.log(key);
14219 * // => Logs 'b' then 'a' assuming `_.forOwn` logs 'a' then 'b'.
14221 function forOwnRight(object, iteratee) {
14222 return object && baseForOwnRight(object, getIteratee(iteratee, 3));
14226 * Creates an array of function property names from own enumerable properties
14233 * @param {Object} object The object to inspect.
14234 * @returns {Array} Returns the function names.
14235 * @see _.functionsIn
14239 * this.a = _.constant('a');
14240 * this.b = _.constant('b');
14243 * Foo.prototype.c = _.constant('c');
14245 * _.functions(new Foo);
14248 function functions(object) {
14249 return object == null ? [] : baseFunctions(object, keys(object));
14253 * Creates an array of function property names from own and inherited
14254 * enumerable properties of `object`.
14260 * @param {Object} object The object to inspect.
14261 * @returns {Array} Returns the function names.
14266 * this.a = _.constant('a');
14267 * this.b = _.constant('b');
14270 * Foo.prototype.c = _.constant('c');
14272 * _.functionsIn(new Foo);
14273 * // => ['a', 'b', 'c']
14275 function functionsIn(object) {
14276 return object == null ? [] : baseFunctions(object, keysIn(object));
14280 * Gets the value at `path` of `object`. If the resolved value is
14281 * `undefined`, the `defaultValue` is returned in its place.
14287 * @param {Object} object The object to query.
14288 * @param {Array|string} path The path of the property to get.
14289 * @param {*} [defaultValue] The value returned for `undefined` resolved values.
14290 * @returns {*} Returns the resolved value.
14293 * var object = { 'a': [{ 'b': { 'c': 3 } }] };
14295 * _.get(object, 'a[0].b.c');
14298 * _.get(object, ['a', '0', 'b', 'c']);
14301 * _.get(object, 'a.b.c', 'default');
14304 function get(object, path, defaultValue) {
14305 var result = object == null ? undefined : baseGet(object, path);
14306 return result === undefined ? defaultValue : result;
14310 * Checks if `path` is a direct property of `object`.
14316 * @param {Object} object The object to query.
14317 * @param {Array|string} path The path to check.
14318 * @returns {boolean} Returns `true` if `path` exists, else `false`.
14321 * var object = { 'a': { 'b': 2 } };
14322 * var other = _.create({ 'a': _.create({ 'b': 2 }) });
14324 * _.has(object, 'a');
14327 * _.has(object, 'a.b');
14330 * _.has(object, ['a', 'b']);
14333 * _.has(other, 'a');
14336 function has(object, path) {
14337 return object != null && hasPath(object, path, baseHas);
14341 * Checks if `path` is a direct or inherited property of `object`.
14347 * @param {Object} object The object to query.
14348 * @param {Array|string} path The path to check.
14349 * @returns {boolean} Returns `true` if `path` exists, else `false`.
14352 * var object = _.create({ 'a': _.create({ 'b': 2 }) });
14354 * _.hasIn(object, 'a');
14357 * _.hasIn(object, 'a.b');
14360 * _.hasIn(object, ['a', 'b']);
14363 * _.hasIn(object, 'b');
14366 function hasIn(object, path) {
14367 return object != null && hasPath(object, path, baseHasIn);
14371 * Creates an object composed of the inverted keys and values of `object`.
14372 * If `object` contains duplicate values, subsequent values overwrite
14373 * property assignments of previous values.
14379 * @param {Object} object The object to invert.
14380 * @returns {Object} Returns the new inverted object.
14383 * var object = { 'a': 1, 'b': 2, 'c': 1 };
14385 * _.invert(object);
14386 * // => { '1': 'c', '2': 'b' }
14388 var invert = createInverter(function(result, value, key) {
14389 if (value != null &&
14390 typeof value.toString != 'function') {
14391 value = nativeObjectToString.call(value);
14394 result[value] = key;
14395 }, constant(identity));
14398 * This method is like `_.invert` except that the inverted object is generated
14399 * from the results of running each element of `object` thru `iteratee`. The
14400 * corresponding inverted value of each inverted key is an array of keys
14401 * responsible for generating the inverted value. The iteratee is invoked
14402 * with one argument: (value).
14408 * @param {Object} object The object to invert.
14409 * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
14410 * @returns {Object} Returns the new inverted object.
14413 * var object = { 'a': 1, 'b': 2, 'c': 1 };
14415 * _.invertBy(object);
14416 * // => { '1': ['a', 'c'], '2': ['b'] }
14418 * _.invertBy(object, function(value) {
14419 * return 'group' + value;
14421 * // => { 'group1': ['a', 'c'], 'group2': ['b'] }
14423 var invertBy = createInverter(function(result, value, key) {
14424 if (value != null &&
14425 typeof value.toString != 'function') {
14426 value = nativeObjectToString.call(value);
14429 if (hasOwnProperty.call(result, value)) {
14430 result[value].push(key);
14432 result[value] = [key];
14437 * Invokes the method at `path` of `object`.
14443 * @param {Object} object The object to query.
14444 * @param {Array|string} path The path of the method to invoke.
14445 * @param {...*} [args] The arguments to invoke the method with.
14446 * @returns {*} Returns the result of the invoked method.
14449 * var object = { 'a': [{ 'b': { 'c': [1, 2, 3, 4] } }] };
14451 * _.invoke(object, 'a[0].b.c.slice', 1, 3);
14454 var invoke = baseRest(baseInvoke);
14457 * Creates an array of the own enumerable property names of `object`.
14459 * **Note:** Non-object values are coerced to objects. See the
14460 * [ES spec](http://ecma-international.org/ecma-262/7.0/#sec-object.keys)
14461 * for more details.
14467 * @param {Object} object The object to query.
14468 * @returns {Array} Returns the array of property names.
14476 * Foo.prototype.c = 3;
14479 * // => ['a', 'b'] (iteration order is not guaranteed)
14484 function keys(object) {
14485 return isArrayLike(object) ? arrayLikeKeys(object) : baseKeys(object);
14489 * Creates an array of the own and inherited enumerable property names of `object`.
14491 * **Note:** Non-object values are coerced to objects.
14497 * @param {Object} object The object to query.
14498 * @returns {Array} Returns the array of property names.
14506 * Foo.prototype.c = 3;
14508 * _.keysIn(new Foo);
14509 * // => ['a', 'b', 'c'] (iteration order is not guaranteed)
14511 function keysIn(object) {
14512 return isArrayLike(object) ? arrayLikeKeys(object, true) : baseKeysIn(object);
14516 * The opposite of `_.mapValues`; this method creates an object with the
14517 * same values as `object` and keys generated by running each own enumerable
14518 * string keyed property of `object` thru `iteratee`. The iteratee is invoked
14519 * with three arguments: (value, key, object).
14525 * @param {Object} object The object to iterate over.
14526 * @param {Function} [iteratee=_.identity] The function invoked per iteration.
14527 * @returns {Object} Returns the new mapped object.
14531 * _.mapKeys({ 'a': 1, 'b': 2 }, function(value, key) {
14532 * return key + value;
14534 * // => { 'a1': 1, 'b2': 2 }
14536 function mapKeys(object, iteratee) {
14538 iteratee = getIteratee(iteratee, 3);
14540 baseForOwn(object, function(value, key, object) {
14541 baseAssignValue(result, iteratee(value, key, object), value);
14547 * Creates an object with the same keys as `object` and values generated
14548 * by running each own enumerable string keyed property of `object` thru
14549 * `iteratee`. The iteratee is invoked with three arguments:
14550 * (value, key, object).
14556 * @param {Object} object The object to iterate over.
14557 * @param {Function} [iteratee=_.identity] The function invoked per iteration.
14558 * @returns {Object} Returns the new mapped object.
14563 * 'fred': { 'user': 'fred', 'age': 40 },
14564 * 'pebbles': { 'user': 'pebbles', 'age': 1 }
14567 * _.mapValues(users, function(o) { return o.age; });
14568 * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed)
14570 * // The `_.property` iteratee shorthand.
14571 * _.mapValues(users, 'age');
14572 * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed)
14574 function mapValues(object, iteratee) {
14576 iteratee = getIteratee(iteratee, 3);
14578 baseForOwn(object, function(value, key, object) {
14579 baseAssignValue(result, key, iteratee(value, key, object));
14585 * This method is like `_.assign` except that it recursively merges own and
14586 * inherited enumerable string keyed properties of source objects into the
14587 * destination object. Source properties that resolve to `undefined` are
14588 * skipped if a destination value exists. Array and plain object properties
14589 * are merged recursively. Other objects and value types are overridden by
14590 * assignment. Source objects are applied from left to right. Subsequent
14591 * sources overwrite property assignments of previous sources.
14593 * **Note:** This method mutates `object`.
14599 * @param {Object} object The destination object.
14600 * @param {...Object} [sources] The source objects.
14601 * @returns {Object} Returns `object`.
14605 * 'a': [{ 'b': 2 }, { 'd': 4 }]
14609 * 'a': [{ 'c': 3 }, { 'e': 5 }]
14612 * _.merge(object, other);
14613 * // => { 'a': [{ 'b': 2, 'c': 3 }, { 'd': 4, 'e': 5 }] }
14615 var merge = createAssigner(function(object, source, srcIndex) {
14616 baseMerge(object, source, srcIndex);
14620 * This method is like `_.merge` except that it accepts `customizer` which
14621 * is invoked to produce the merged values of the destination and source
14622 * properties. If `customizer` returns `undefined`, merging is handled by the
14623 * method instead. The `customizer` is invoked with six arguments:
14624 * (objValue, srcValue, key, object, source, stack).
14626 * **Note:** This method mutates `object`.
14632 * @param {Object} object The destination object.
14633 * @param {...Object} sources The source objects.
14634 * @param {Function} customizer The function to customize assigned values.
14635 * @returns {Object} Returns `object`.
14638 * function customizer(objValue, srcValue) {
14639 * if (_.isArray(objValue)) {
14640 * return objValue.concat(srcValue);
14644 * var object = { 'a': [1], 'b': [2] };
14645 * var other = { 'a': [3], 'b': [4] };
14647 * _.mergeWith(object, other, customizer);
14648 * // => { 'a': [1, 3], 'b': [2, 4] }
14650 var mergeWith = createAssigner(function(object, source, srcIndex, customizer) {
14651 baseMerge(object, source, srcIndex, customizer);
14655 * The opposite of `_.pick`; this method creates an object composed of the
14656 * own and inherited enumerable property paths of `object` that are not omitted.
14658 * **Note:** This method is considerably slower than `_.pick`.
14664 * @param {Object} object The source object.
14665 * @param {...(string|string[])} [paths] The property paths to omit.
14666 * @returns {Object} Returns the new object.
14669 * var object = { 'a': 1, 'b': '2', 'c': 3 };
14671 * _.omit(object, ['a', 'c']);
14672 * // => { 'b': '2' }
14674 var omit = flatRest(function(object, paths) {
14676 if (object == null) {
14679 var isDeep = false;
14680 paths = arrayMap(paths, function(path) {
14681 path = castPath(path, object);
14682 isDeep || (isDeep = path.length > 1);
14685 copyObject(object, getAllKeysIn(object), result);
14687 result = baseClone(result, CLONE_DEEP_FLAG | CLONE_FLAT_FLAG | CLONE_SYMBOLS_FLAG, customOmitClone);
14689 var length = paths.length;
14691 baseUnset(result, paths[length]);
14697 * The opposite of `_.pickBy`; this method creates an object composed of
14698 * the own and inherited enumerable string keyed properties of `object` that
14699 * `predicate` doesn't return truthy for. The predicate is invoked with two
14700 * arguments: (value, key).
14706 * @param {Object} object The source object.
14707 * @param {Function} [predicate=_.identity] The function invoked per property.
14708 * @returns {Object} Returns the new object.
14711 * var object = { 'a': 1, 'b': '2', 'c': 3 };
14713 * _.omitBy(object, _.isNumber);
14714 * // => { 'b': '2' }
14716 function omitBy(object, predicate) {
14717 return pickBy(object, negate(getIteratee(predicate)));
14721 * Creates an object composed of the picked `object` properties.
14727 * @param {Object} object The source object.
14728 * @param {...(string|string[])} [paths] The property paths to pick.
14729 * @returns {Object} Returns the new object.
14732 * var object = { 'a': 1, 'b': '2', 'c': 3 };
14734 * _.pick(object, ['a', 'c']);
14735 * // => { 'a': 1, 'c': 3 }
14737 var pick = flatRest(function(object, paths) {
14738 return object == null ? {} : basePick(object, paths);
14742 * Creates an object composed of the `object` properties `predicate` returns
14743 * truthy for. The predicate is invoked with two arguments: (value, key).
14749 * @param {Object} object The source object.
14750 * @param {Function} [predicate=_.identity] The function invoked per property.
14751 * @returns {Object} Returns the new object.
14754 * var object = { 'a': 1, 'b': '2', 'c': 3 };
14756 * _.pickBy(object, _.isNumber);
14757 * // => { 'a': 1, 'c': 3 }
14759 function pickBy(object, predicate) {
14760 if (object == null) {
14763 var props = arrayMap(getAllKeysIn(object), function(prop) {
14766 predicate = getIteratee(predicate);
14767 return basePickBy(object, props, function(value, path) {
14768 return predicate(value, path[0]);
14773 * This method is like `_.get` except that if the resolved value is a
14774 * function it's invoked with the `this` binding of its parent object and
14775 * its result is returned.
14781 * @param {Object} object The object to query.
14782 * @param {Array|string} path The path of the property to resolve.
14783 * @param {*} [defaultValue] The value returned for `undefined` resolved values.
14784 * @returns {*} Returns the resolved value.
14787 * var object = { 'a': [{ 'b': { 'c1': 3, 'c2': _.constant(4) } }] };
14789 * _.result(object, 'a[0].b.c1');
14792 * _.result(object, 'a[0].b.c2');
14795 * _.result(object, 'a[0].b.c3', 'default');
14798 * _.result(object, 'a[0].b.c3', _.constant('default'));
14801 function result(object, path, defaultValue) {
14802 path = castPath(path, object);
14805 length = path.length;
14807 // Ensure the loop is entered when path is empty.
14810 object = undefined;
14812 while (++index < length) {
14813 var value = object == null ? undefined : object[toKey(path[index])];
14814 if (value === undefined) {
14816 value = defaultValue;
14818 object = isFunction(value) ? value.call(object) : value;
14824 * Sets the value at `path` of `object`. If a portion of `path` doesn't exist,
14825 * it's created. Arrays are created for missing index properties while objects
14826 * are created for all other missing properties. Use `_.setWith` to customize
14829 * **Note:** This method mutates `object`.
14835 * @param {Object} object The object to modify.
14836 * @param {Array|string} path The path of the property to set.
14837 * @param {*} value The value to set.
14838 * @returns {Object} Returns `object`.
14841 * var object = { 'a': [{ 'b': { 'c': 3 } }] };
14843 * _.set(object, 'a[0].b.c', 4);
14844 * console.log(object.a[0].b.c);
14847 * _.set(object, ['x', '0', 'y', 'z'], 5);
14848 * console.log(object.x[0].y.z);
14851 function set(object, path, value) {
14852 return object == null ? object : baseSet(object, path, value);
14856 * This method is like `_.set` except that it accepts `customizer` which is
14857 * invoked to produce the objects of `path`. If `customizer` returns `undefined`
14858 * path creation is handled by the method instead. The `customizer` is invoked
14859 * with three arguments: (nsValue, key, nsObject).
14861 * **Note:** This method mutates `object`.
14867 * @param {Object} object The object to modify.
14868 * @param {Array|string} path The path of the property to set.
14869 * @param {*} value The value to set.
14870 * @param {Function} [customizer] The function to customize assigned values.
14871 * @returns {Object} Returns `object`.
14876 * _.setWith(object, '[0][1]', 'a', Object);
14877 * // => { '0': { '1': 'a' } }
14879 function setWith(object, path, value, customizer) {
14880 customizer = typeof customizer == 'function' ? customizer : undefined;
14881 return object == null ? object : baseSet(object, path, value, customizer);
14885 * Creates an array of own enumerable string keyed-value pairs for `object`
14886 * which can be consumed by `_.fromPairs`. If `object` is a map or set, its
14887 * entries are returned.
14894 * @param {Object} object The object to query.
14895 * @returns {Array} Returns the key-value pairs.
14903 * Foo.prototype.c = 3;
14905 * _.toPairs(new Foo);
14906 * // => [['a', 1], ['b', 2]] (iteration order is not guaranteed)
14908 var toPairs = createToPairs(keys);
14911 * Creates an array of own and inherited enumerable string keyed-value pairs
14912 * for `object` which can be consumed by `_.fromPairs`. If `object` is a map
14913 * or set, its entries are returned.
14920 * @param {Object} object The object to query.
14921 * @returns {Array} Returns the key-value pairs.
14929 * Foo.prototype.c = 3;
14931 * _.toPairsIn(new Foo);
14932 * // => [['a', 1], ['b', 2], ['c', 3]] (iteration order is not guaranteed)
14934 var toPairsIn = createToPairs(keysIn);
14937 * An alternative to `_.reduce`; this method transforms `object` to a new
14938 * `accumulator` object which is the result of running each of its own
14939 * enumerable string keyed properties thru `iteratee`, with each invocation
14940 * potentially mutating the `accumulator` object. If `accumulator` is not
14941 * provided, a new object with the same `[[Prototype]]` will be used. The
14942 * iteratee is invoked with four arguments: (accumulator, value, key, object).
14943 * Iteratee functions may exit iteration early by explicitly returning `false`.
14949 * @param {Object} object The object to iterate over.
14950 * @param {Function} [iteratee=_.identity] The function invoked per iteration.
14951 * @param {*} [accumulator] The custom accumulator value.
14952 * @returns {*} Returns the accumulated value.
14955 * _.transform([2, 3, 4], function(result, n) {
14956 * result.push(n *= n);
14957 * return n % 2 == 0;
14961 * _.transform({ 'a': 1, 'b': 2, 'c': 1 }, function(result, value, key) {
14962 * (result[value] || (result[value] = [])).push(key);
14964 * // => { '1': ['a', 'c'], '2': ['b'] }
14966 function transform(object, iteratee, accumulator) {
14967 var isArr = isArray(object),
14968 isArrLike = isArr || isBuffer(object) || isTypedArray(object);
14970 iteratee = getIteratee(iteratee, 4);
14971 if (accumulator == null) {
14972 var Ctor = object && object.constructor;
14974 accumulator = isArr ? new Ctor : [];
14976 else if (isObject(object)) {
14977 accumulator = isFunction(Ctor) ? baseCreate(getPrototype(object)) : {};
14983 (isArrLike ? arrayEach : baseForOwn)(object, function(value, index, object) {
14984 return iteratee(accumulator, value, index, object);
14986 return accumulator;
14990 * Removes the property at `path` of `object`.
14992 * **Note:** This method mutates `object`.
14998 * @param {Object} object The object to modify.
14999 * @param {Array|string} path The path of the property to unset.
15000 * @returns {boolean} Returns `true` if the property is deleted, else `false`.
15003 * var object = { 'a': [{ 'b': { 'c': 7 } }] };
15004 * _.unset(object, 'a[0].b.c');
15007 * console.log(object);
15008 * // => { 'a': [{ 'b': {} }] };
15010 * _.unset(object, ['a', '0', 'b', 'c']);
15013 * console.log(object);
15014 * // => { 'a': [{ 'b': {} }] };
15016 function unset(object, path) {
15017 return object == null ? true : baseUnset(object, path);
15021 * This method is like `_.set` except that accepts `updater` to produce the
15022 * value to set. Use `_.updateWith` to customize `path` creation. The `updater`
15023 * is invoked with one argument: (value).
15025 * **Note:** This method mutates `object`.
15031 * @param {Object} object The object to modify.
15032 * @param {Array|string} path The path of the property to set.
15033 * @param {Function} updater The function to produce the updated value.
15034 * @returns {Object} Returns `object`.
15037 * var object = { 'a': [{ 'b': { 'c': 3 } }] };
15039 * _.update(object, 'a[0].b.c', function(n) { return n * n; });
15040 * console.log(object.a[0].b.c);
15043 * _.update(object, 'x[0].y.z', function(n) { return n ? n + 1 : 0; });
15044 * console.log(object.x[0].y.z);
15047 function update(object, path, updater) {
15048 return object == null ? object : baseUpdate(object, path, castFunction(updater));
15052 * This method is like `_.update` except that it accepts `customizer` which is
15053 * invoked to produce the objects of `path`. If `customizer` returns `undefined`
15054 * path creation is handled by the method instead. The `customizer` is invoked
15055 * with three arguments: (nsValue, key, nsObject).
15057 * **Note:** This method mutates `object`.
15063 * @param {Object} object The object to modify.
15064 * @param {Array|string} path The path of the property to set.
15065 * @param {Function} updater The function to produce the updated value.
15066 * @param {Function} [customizer] The function to customize assigned values.
15067 * @returns {Object} Returns `object`.
15072 * _.updateWith(object, '[0][1]', _.constant('a'), Object);
15073 * // => { '0': { '1': 'a' } }
15075 function updateWith(object, path, updater, customizer) {
15076 customizer = typeof customizer == 'function' ? customizer : undefined;
15077 return object == null ? object : baseUpdate(object, path, castFunction(updater), customizer);
15081 * Creates an array of the own enumerable string keyed property values of `object`.
15083 * **Note:** Non-object values are coerced to objects.
15089 * @param {Object} object The object to query.
15090 * @returns {Array} Returns the array of property values.
15098 * Foo.prototype.c = 3;
15100 * _.values(new Foo);
15101 * // => [1, 2] (iteration order is not guaranteed)
15106 function values(object) {
15107 return object == null ? [] : baseValues(object, keys(object));
15111 * Creates an array of the own and inherited enumerable string keyed property
15112 * values of `object`.
15114 * **Note:** Non-object values are coerced to objects.
15120 * @param {Object} object The object to query.
15121 * @returns {Array} Returns the array of property values.
15129 * Foo.prototype.c = 3;
15131 * _.valuesIn(new Foo);
15132 * // => [1, 2, 3] (iteration order is not guaranteed)
15134 function valuesIn(object) {
15135 return object == null ? [] : baseValues(object, keysIn(object));
15138 /*------------------------------------------------------------------------*/
15141 * Clamps `number` within the inclusive `lower` and `upper` bounds.
15147 * @param {number} number The number to clamp.
15148 * @param {number} [lower] The lower bound.
15149 * @param {number} upper The upper bound.
15150 * @returns {number} Returns the clamped number.
15153 * _.clamp(-10, -5, 5);
15156 * _.clamp(10, -5, 5);
15159 function clamp(number, lower, upper) {
15160 if (upper === undefined) {
15164 if (upper !== undefined) {
15165 upper = toNumber(upper);
15166 upper = upper === upper ? upper : 0;
15168 if (lower !== undefined) {
15169 lower = toNumber(lower);
15170 lower = lower === lower ? lower : 0;
15172 return baseClamp(toNumber(number), lower, upper);
15176 * Checks if `n` is between `start` and up to, but not including, `end`. If
15177 * `end` is not specified, it's set to `start` with `start` then set to `0`.
15178 * If `start` is greater than `end` the params are swapped to support
15185 * @param {number} number The number to check.
15186 * @param {number} [start=0] The start of the range.
15187 * @param {number} end The end of the range.
15188 * @returns {boolean} Returns `true` if `number` is in the range, else `false`.
15189 * @see _.range, _.rangeRight
15192 * _.inRange(3, 2, 4);
15204 * _.inRange(1.2, 2);
15207 * _.inRange(5.2, 4);
15210 * _.inRange(-3, -2, -6);
15213 function inRange(number, start, end) {
15214 start = toFinite(start);
15215 if (end === undefined) {
15219 end = toFinite(end);
15221 number = toNumber(number);
15222 return baseInRange(number, start, end);
15226 * Produces a random number between the inclusive `lower` and `upper` bounds.
15227 * If only one argument is provided a number between `0` and the given number
15228 * is returned. If `floating` is `true`, or either `lower` or `upper` are
15229 * floats, a floating-point number is returned instead of an integer.
15231 * **Note:** JavaScript follows the IEEE-754 standard for resolving
15232 * floating-point values which can produce unexpected results.
15238 * @param {number} [lower=0] The lower bound.
15239 * @param {number} [upper=1] The upper bound.
15240 * @param {boolean} [floating] Specify returning a floating-point number.
15241 * @returns {number} Returns the random number.
15245 * // => an integer between 0 and 5
15248 * // => also an integer between 0 and 5
15250 * _.random(5, true);
15251 * // => a floating-point number between 0 and 5
15253 * _.random(1.2, 5.2);
15254 * // => a floating-point number between 1.2 and 5.2
15256 function random(lower, upper, floating) {
15257 if (floating && typeof floating != 'boolean' && isIterateeCall(lower, upper, floating)) {
15258 upper = floating = undefined;
15260 if (floating === undefined) {
15261 if (typeof upper == 'boolean') {
15265 else if (typeof lower == 'boolean') {
15270 if (lower === undefined && upper === undefined) {
15275 lower = toFinite(lower);
15276 if (upper === undefined) {
15280 upper = toFinite(upper);
15283 if (lower > upper) {
15288 if (floating || lower % 1 || upper % 1) {
15289 var rand = nativeRandom();
15290 return nativeMin(lower + (rand * (upper - lower + freeParseFloat('1e-' + ((rand + '').length - 1)))), upper);
15292 return baseRandom(lower, upper);
15295 /*------------------------------------------------------------------------*/
15298 * Converts `string` to [camel case](https://en.wikipedia.org/wiki/CamelCase).
15304 * @param {string} [string=''] The string to convert.
15305 * @returns {string} Returns the camel cased string.
15308 * _.camelCase('Foo Bar');
15311 * _.camelCase('--foo-bar--');
15314 * _.camelCase('__FOO_BAR__');
15317 var camelCase = createCompounder(function(result, word, index) {
15318 word = word.toLowerCase();
15319 return result + (index ? capitalize(word) : word);
15323 * Converts the first character of `string` to upper case and the remaining
15330 * @param {string} [string=''] The string to capitalize.
15331 * @returns {string} Returns the capitalized string.
15334 * _.capitalize('FRED');
15337 function capitalize(string) {
15338 return upperFirst(toString(string).toLowerCase());
15342 * Deburrs `string` by converting
15343 * [Latin-1 Supplement](https://en.wikipedia.org/wiki/Latin-1_Supplement_(Unicode_block)#Character_table)
15344 * and [Latin Extended-A](https://en.wikipedia.org/wiki/Latin_Extended-A)
15345 * letters to basic Latin letters and removing
15346 * [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks).
15352 * @param {string} [string=''] The string to deburr.
15353 * @returns {string} Returns the deburred string.
15356 * _.deburr('déjà vu');
15359 function deburr(string) {
15360 string = toString(string);
15361 return string && string.replace(reLatin, deburrLetter).replace(reComboMark, '');
15365 * Checks if `string` ends with the given target string.
15371 * @param {string} [string=''] The string to inspect.
15372 * @param {string} [target] The string to search for.
15373 * @param {number} [position=string.length] The position to search up to.
15374 * @returns {boolean} Returns `true` if `string` ends with `target`,
15378 * _.endsWith('abc', 'c');
15381 * _.endsWith('abc', 'b');
15384 * _.endsWith('abc', 'b', 2);
15387 function endsWith(string, target, position) {
15388 string = toString(string);
15389 target = baseToString(target);
15391 var length = string.length;
15392 position = position === undefined
15394 : baseClamp(toInteger(position), 0, length);
15396 var end = position;
15397 position -= target.length;
15398 return position >= 0 && string.slice(position, end) == target;
15402 * Converts the characters "&", "<", ">", '"', and "'" in `string` to their
15403 * corresponding HTML entities.
15405 * **Note:** No other characters are escaped. To escape additional
15406 * characters use a third-party library like [_he_](https://mths.be/he).
15408 * Though the ">" character is escaped for symmetry, characters like
15409 * ">" and "/" don't need escaping in HTML and have no special meaning
15410 * unless they're part of a tag or unquoted attribute value. See
15411 * [Mathias Bynens's article](https://mathiasbynens.be/notes/ambiguous-ampersands)
15412 * (under "semi-related fun fact") for more details.
15414 * When working with HTML you should always
15415 * [quote attribute values](http://wonko.com/post/html-escaping) to reduce
15422 * @param {string} [string=''] The string to escape.
15423 * @returns {string} Returns the escaped string.
15426 * _.escape('fred, barney, & pebbles');
15427 * // => 'fred, barney, & pebbles'
15429 function escape(string) {
15430 string = toString(string);
15431 return (string && reHasUnescapedHtml.test(string))
15432 ? string.replace(reUnescapedHtml, escapeHtmlChar)
15437 * Escapes the `RegExp` special characters "^", "$", "\", ".", "*", "+",
15438 * "?", "(", ")", "[", "]", "{", "}", and "|" in `string`.
15444 * @param {string} [string=''] The string to escape.
15445 * @returns {string} Returns the escaped string.
15448 * _.escapeRegExp('[lodash](https://lodash.com/)');
15449 * // => '\[lodash\]\(https://lodash\.com/\)'
15451 function escapeRegExp(string) {
15452 string = toString(string);
15453 return (string && reHasRegExpChar.test(string))
15454 ? string.replace(reRegExpChar, '\\$&')
15459 * Converts `string` to
15460 * [kebab case](https://en.wikipedia.org/wiki/Letter_case#Special_case_styles).
15466 * @param {string} [string=''] The string to convert.
15467 * @returns {string} Returns the kebab cased string.
15470 * _.kebabCase('Foo Bar');
15473 * _.kebabCase('fooBar');
15476 * _.kebabCase('__FOO_BAR__');
15479 var kebabCase = createCompounder(function(result, word, index) {
15480 return result + (index ? '-' : '') + word.toLowerCase();
15484 * Converts `string`, as space separated words, to lower case.
15490 * @param {string} [string=''] The string to convert.
15491 * @returns {string} Returns the lower cased string.
15494 * _.lowerCase('--Foo-Bar--');
15497 * _.lowerCase('fooBar');
15500 * _.lowerCase('__FOO_BAR__');
15503 var lowerCase = createCompounder(function(result, word, index) {
15504 return result + (index ? ' ' : '') + word.toLowerCase();
15508 * Converts the first character of `string` to lower case.
15514 * @param {string} [string=''] The string to convert.
15515 * @returns {string} Returns the converted string.
15518 * _.lowerFirst('Fred');
15521 * _.lowerFirst('FRED');
15524 var lowerFirst = createCaseFirst('toLowerCase');
15527 * Pads `string` on the left and right sides if it's shorter than `length`.
15528 * Padding characters are truncated if they can't be evenly divided by `length`.
15534 * @param {string} [string=''] The string to pad.
15535 * @param {number} [length=0] The padding length.
15536 * @param {string} [chars=' '] The string used as padding.
15537 * @returns {string} Returns the padded string.
15543 * _.pad('abc', 8, '_-');
15549 function pad(string, length, chars) {
15550 string = toString(string);
15551 length = toInteger(length);
15553 var strLength = length ? stringSize(string) : 0;
15554 if (!length || strLength >= length) {
15557 var mid = (length - strLength) / 2;
15559 createPadding(nativeFloor(mid), chars) +
15561 createPadding(nativeCeil(mid), chars)
15566 * Pads `string` on the right side if it's shorter than `length`. Padding
15567 * characters are truncated if they exceed `length`.
15573 * @param {string} [string=''] The string to pad.
15574 * @param {number} [length=0] The padding length.
15575 * @param {string} [chars=' '] The string used as padding.
15576 * @returns {string} Returns the padded string.
15579 * _.padEnd('abc', 6);
15582 * _.padEnd('abc', 6, '_-');
15585 * _.padEnd('abc', 3);
15588 function padEnd(string, length, chars) {
15589 string = toString(string);
15590 length = toInteger(length);
15592 var strLength = length ? stringSize(string) : 0;
15593 return (length && strLength < length)
15594 ? (string + createPadding(length - strLength, chars))
15599 * Pads `string` on the left side if it's shorter than `length`. Padding
15600 * characters are truncated if they exceed `length`.
15606 * @param {string} [string=''] The string to pad.
15607 * @param {number} [length=0] The padding length.
15608 * @param {string} [chars=' '] The string used as padding.
15609 * @returns {string} Returns the padded string.
15612 * _.padStart('abc', 6);
15615 * _.padStart('abc', 6, '_-');
15618 * _.padStart('abc', 3);
15621 function padStart(string, length, chars) {
15622 string = toString(string);
15623 length = toInteger(length);
15625 var strLength = length ? stringSize(string) : 0;
15626 return (length && strLength < length)
15627 ? (createPadding(length - strLength, chars) + string)
15632 * Converts `string` to an integer of the specified radix. If `radix` is
15633 * `undefined` or `0`, a `radix` of `10` is used unless `value` is a
15634 * hexadecimal, in which case a `radix` of `16` is used.
15636 * **Note:** This method aligns with the
15637 * [ES5 implementation](https://es5.github.io/#x15.1.2.2) of `parseInt`.
15643 * @param {string} string The string to convert.
15644 * @param {number} [radix=10] The radix to interpret `value` by.
15645 * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
15646 * @returns {number} Returns the converted integer.
15649 * _.parseInt('08');
15652 * _.map(['6', '08', '10'], _.parseInt);
15655 function parseInt(string, radix, guard) {
15656 if (guard || radix == null) {
15658 } else if (radix) {
15661 return nativeParseInt(toString(string).replace(reTrimStart, ''), radix || 0);
15665 * Repeats the given string `n` times.
15671 * @param {string} [string=''] The string to repeat.
15672 * @param {number} [n=1] The number of times to repeat the string.
15673 * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
15674 * @returns {string} Returns the repeated string.
15677 * _.repeat('*', 3);
15680 * _.repeat('abc', 2);
15683 * _.repeat('abc', 0);
15686 function repeat(string, n, guard) {
15687 if ((guard ? isIterateeCall(string, n, guard) : n === undefined)) {
15692 return baseRepeat(toString(string), n);
15696 * Replaces matches for `pattern` in `string` with `replacement`.
15698 * **Note:** This method is based on
15699 * [`String#replace`](https://mdn.io/String/replace).
15705 * @param {string} [string=''] The string to modify.
15706 * @param {RegExp|string} pattern The pattern to replace.
15707 * @param {Function|string} replacement The match replacement.
15708 * @returns {string} Returns the modified string.
15711 * _.replace('Hi Fred', 'Fred', 'Barney');
15712 * // => 'Hi Barney'
15714 function replace() {
15715 var args = arguments,
15716 string = toString(args[0]);
15718 return args.length < 3 ? string : string.replace(args[1], args[2]);
15722 * Converts `string` to
15723 * [snake case](https://en.wikipedia.org/wiki/Snake_case).
15729 * @param {string} [string=''] The string to convert.
15730 * @returns {string} Returns the snake cased string.
15733 * _.snakeCase('Foo Bar');
15736 * _.snakeCase('fooBar');
15739 * _.snakeCase('--FOO-BAR--');
15742 var snakeCase = createCompounder(function(result, word, index) {
15743 return result + (index ? '_' : '') + word.toLowerCase();
15747 * Splits `string` by `separator`.
15749 * **Note:** This method is based on
15750 * [`String#split`](https://mdn.io/String/split).
15756 * @param {string} [string=''] The string to split.
15757 * @param {RegExp|string} separator The separator pattern to split by.
15758 * @param {number} [limit] The length to truncate results to.
15759 * @returns {Array} Returns the string segments.
15762 * _.split('a-b-c', '-', 2);
15765 function split(string, separator, limit) {
15766 if (limit && typeof limit != 'number' && isIterateeCall(string, separator, limit)) {
15767 separator = limit = undefined;
15769 limit = limit === undefined ? MAX_ARRAY_LENGTH : limit >>> 0;
15773 string = toString(string);
15775 typeof separator == 'string' ||
15776 (separator != null && !isRegExp(separator))
15778 separator = baseToString(separator);
15779 if (!separator && hasUnicode(string)) {
15780 return castSlice(stringToArray(string), 0, limit);
15783 return string.split(separator, limit);
15787 * Converts `string` to
15788 * [start case](https://en.wikipedia.org/wiki/Letter_case#Stylistic_or_specialised_usage).
15794 * @param {string} [string=''] The string to convert.
15795 * @returns {string} Returns the start cased string.
15798 * _.startCase('--foo-bar--');
15801 * _.startCase('fooBar');
15804 * _.startCase('__FOO_BAR__');
15807 var startCase = createCompounder(function(result, word, index) {
15808 return result + (index ? ' ' : '') + upperFirst(word);
15812 * Checks if `string` starts with the given target string.
15818 * @param {string} [string=''] The string to inspect.
15819 * @param {string} [target] The string to search for.
15820 * @param {number} [position=0] The position to search from.
15821 * @returns {boolean} Returns `true` if `string` starts with `target`,
15825 * _.startsWith('abc', 'a');
15828 * _.startsWith('abc', 'b');
15831 * _.startsWith('abc', 'b', 1);
15834 function startsWith(string, target, position) {
15835 string = toString(string);
15836 position = position == null
15838 : baseClamp(toInteger(position), 0, string.length);
15840 target = baseToString(target);
15841 return string.slice(position, position + target.length) == target;
15845 * Creates a compiled template function that can interpolate data properties
15846 * in "interpolate" delimiters, HTML-escape interpolated data properties in
15847 * "escape" delimiters, and execute JavaScript in "evaluate" delimiters. Data
15848 * properties may be accessed as free variables in the template. If a setting
15849 * object is given, it takes precedence over `_.templateSettings` values.
15851 * **Note:** In the development build `_.template` utilizes
15852 * [sourceURLs](http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl)
15853 * for easier debugging.
15855 * For more information on precompiling templates see
15856 * [lodash's custom builds documentation](https://lodash.com/custom-builds).
15858 * For more information on Chrome extension sandboxes see
15859 * [Chrome's extensions documentation](https://developer.chrome.com/extensions/sandboxingEval).
15865 * @param {string} [string=''] The template string.
15866 * @param {Object} [options={}] The options object.
15867 * @param {RegExp} [options.escape=_.templateSettings.escape]
15868 * The HTML "escape" delimiter.
15869 * @param {RegExp} [options.evaluate=_.templateSettings.evaluate]
15870 * The "evaluate" delimiter.
15871 * @param {Object} [options.imports=_.templateSettings.imports]
15872 * An object to import into the template as free variables.
15873 * @param {RegExp} [options.interpolate=_.templateSettings.interpolate]
15874 * The "interpolate" delimiter.
15875 * @param {string} [options.sourceURL='lodash.templateSources[n]']
15876 * The sourceURL of the compiled template.
15877 * @param {string} [options.variable='obj']
15878 * The data object variable name.
15879 * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
15880 * @returns {Function} Returns the compiled template function.
15883 * // Use the "interpolate" delimiter to create a compiled template.
15884 * var compiled = _.template('hello <%= user %>!');
15885 * compiled({ 'user': 'fred' });
15886 * // => 'hello fred!'
15888 * // Use the HTML "escape" delimiter to escape data property values.
15889 * var compiled = _.template('<b><%- value %></b>');
15890 * compiled({ 'value': '<script>' });
15891 * // => '<b><script></b>'
15893 * // Use the "evaluate" delimiter to execute JavaScript and generate HTML.
15894 * var compiled = _.template('<% _.forEach(users, function(user) { %><li><%- user %></li><% }); %>');
15895 * compiled({ 'users': ['fred', 'barney'] });
15896 * // => '<li>fred</li><li>barney</li>'
15898 * // Use the internal `print` function in "evaluate" delimiters.
15899 * var compiled = _.template('<% print("hello " + user); %>!');
15900 * compiled({ 'user': 'barney' });
15901 * // => 'hello barney!'
15903 * // Use the ES template literal delimiter as an "interpolate" delimiter.
15904 * // Disable support by replacing the "interpolate" delimiter.
15905 * var compiled = _.template('hello ${ user }!');
15906 * compiled({ 'user': 'pebbles' });
15907 * // => 'hello pebbles!'
15909 * // Use backslashes to treat delimiters as plain text.
15910 * var compiled = _.template('<%= "\\<%- value %\\>" %>');
15911 * compiled({ 'value': 'ignored' });
15912 * // => '<%- value %>'
15914 * // Use the `imports` option to import `jQuery` as `jq`.
15915 * var text = '<% jq.each(users, function(user) { %><li><%- user %></li><% }); %>';
15916 * var compiled = _.template(text, { 'imports': { 'jq': jQuery } });
15917 * compiled({ 'users': ['fred', 'barney'] });
15918 * // => '<li>fred</li><li>barney</li>'
15920 * // Use the `sourceURL` option to specify a custom sourceURL for the template.
15921 * var compiled = _.template('hello <%= user %>!', { 'sourceURL': '/basic/greeting.jst' });
15923 * // => Find the source of "greeting.jst" under the Sources tab or Resources panel of the web inspector.
15925 * // Use the `variable` option to ensure a with-statement isn't used in the compiled template.
15926 * var compiled = _.template('hi <%= data.user %>!', { 'variable': 'data' });
15928 * // => function(data) {
15929 * // var __t, __p = '';
15930 * // __p += 'hi ' + ((__t = ( data.user )) == null ? '' : __t) + '!';
15934 * // Use custom template delimiters.
15935 * _.templateSettings.interpolate = /{{([\s\S]+?)}}/g;
15936 * var compiled = _.template('hello {{ user }}!');
15937 * compiled({ 'user': 'mustache' });
15938 * // => 'hello mustache!'
15940 * // Use the `source` property to inline compiled templates for meaningful
15941 * // line numbers in error messages and stack traces.
15942 * fs.writeFileSync(path.join(process.cwd(), 'jst.js'), '\
15944 * "main": ' + _.template(mainText).source + '\
15948 function template(string, options, guard) {
15949 // Based on John Resig's `tmpl` implementation
15950 // (http://ejohn.org/blog/javascript-micro-templating/)
15951 // and Laura Doktorova's doT.js (https://github.com/olado/doT).
15952 var settings = lodash.templateSettings;
15954 if (guard && isIterateeCall(string, options, guard)) {
15955 options = undefined;
15957 string = toString(string);
15958 options = assignInWith({}, options, settings, customDefaultsAssignIn);
15960 var imports = assignInWith({}, options.imports, settings.imports, customDefaultsAssignIn),
15961 importsKeys = keys(imports),
15962 importsValues = baseValues(imports, importsKeys);
15967 interpolate = options.interpolate || reNoMatch,
15968 source = "__p += '";
15970 // Compile the regexp to match each delimiter.
15971 var reDelimiters = RegExp(
15972 (options.escape || reNoMatch).source + '|' +
15973 interpolate.source + '|' +
15974 (interpolate === reInterpolate ? reEsTemplate : reNoMatch).source + '|' +
15975 (options.evaluate || reNoMatch).source + '|$'
15978 // Use a sourceURL for easier debugging.
15979 // The sourceURL gets injected into the source that's eval-ed, so be careful
15980 // to normalize all kinds of whitespace, so e.g. newlines (and unicode versions of it) can't sneak in
15981 // and escape the comment, thus injecting code that gets evaled.
15982 var sourceURL = '//# sourceURL=' +
15983 (hasOwnProperty.call(options, 'sourceURL')
15984 ? (options.sourceURL + '').replace(/\s/g, ' ')
15985 : ('lodash.templateSources[' + (++templateCounter) + ']')
15988 string.replace(reDelimiters, function(match, escapeValue, interpolateValue, esTemplateValue, evaluateValue, offset) {
15989 interpolateValue || (interpolateValue = esTemplateValue);
15991 // Escape characters that can't be included in string literals.
15992 source += string.slice(index, offset).replace(reUnescapedString, escapeStringChar);
15994 // Replace delimiters with snippets.
15997 source += "' +\n__e(" + escapeValue + ") +\n'";
15999 if (evaluateValue) {
16000 isEvaluating = true;
16001 source += "';\n" + evaluateValue + ";\n__p += '";
16003 if (interpolateValue) {
16004 source += "' +\n((__t = (" + interpolateValue + ")) == null ? '' : __t) +\n'";
16006 index = offset + match.length;
16008 // The JS engine embedded in Adobe products needs `match` returned in
16009 // order to produce the correct `offset` value.
16015 // If `variable` is not specified wrap a with-statement around the generated
16016 // code to add the data object to the top of the scope chain.
16017 var variable = hasOwnProperty.call(options, 'variable') && options.variable;
16019 source = 'with (obj) {\n' + source + '\n}\n';
16021 // Throw an error if a forbidden character was found in `variable`, to prevent
16022 // potential command injection attacks.
16023 else if (reForbiddenIdentifierChars.test(variable)) {
16024 throw new Error(INVALID_TEMPL_VAR_ERROR_TEXT);
16027 // Cleanup code by stripping empty strings.
16028 source = (isEvaluating ? source.replace(reEmptyStringLeading, '') : source)
16029 .replace(reEmptyStringMiddle, '$1')
16030 .replace(reEmptyStringTrailing, '$1;');
16032 // Frame code as the function body.
16033 source = 'function(' + (variable || 'obj') + ') {\n' +
16036 : 'obj || (obj = {});\n'
16038 "var __t, __p = ''" +
16040 ? ', __e = _.escape'
16044 ? ', __j = Array.prototype.join;\n' +
16045 "function print() { __p += __j.call(arguments, '') }\n"
16051 var result = attempt(function() {
16052 return Function(importsKeys, sourceURL + 'return ' + source)
16053 .apply(undefined, importsValues);
16056 // Provide the compiled function's source by its `toString` method or
16057 // the `source` property as a convenience for inlining compiled templates.
16058 result.source = source;
16059 if (isError(result)) {
16066 * Converts `string`, as a whole, to lower case just like
16067 * [String#toLowerCase](https://mdn.io/toLowerCase).
16073 * @param {string} [string=''] The string to convert.
16074 * @returns {string} Returns the lower cased string.
16077 * _.toLower('--Foo-Bar--');
16078 * // => '--foo-bar--'
16080 * _.toLower('fooBar');
16083 * _.toLower('__FOO_BAR__');
16084 * // => '__foo_bar__'
16086 function toLower(value) {
16087 return toString(value).toLowerCase();
16091 * Converts `string`, as a whole, to upper case just like
16092 * [String#toUpperCase](https://mdn.io/toUpperCase).
16098 * @param {string} [string=''] The string to convert.
16099 * @returns {string} Returns the upper cased string.
16102 * _.toUpper('--foo-bar--');
16103 * // => '--FOO-BAR--'
16105 * _.toUpper('fooBar');
16108 * _.toUpper('__foo_bar__');
16109 * // => '__FOO_BAR__'
16111 function toUpper(value) {
16112 return toString(value).toUpperCase();
16116 * Removes leading and trailing whitespace or specified characters from `string`.
16122 * @param {string} [string=''] The string to trim.
16123 * @param {string} [chars=whitespace] The characters to trim.
16124 * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
16125 * @returns {string} Returns the trimmed string.
16131 * _.trim('-_-abc-_-', '_-');
16134 * _.map([' foo ', ' bar '], _.trim);
16135 * // => ['foo', 'bar']
16137 function trim(string, chars, guard) {
16138 string = toString(string);
16139 if (string && (guard || chars === undefined)) {
16140 return baseTrim(string);
16142 if (!string || !(chars = baseToString(chars))) {
16145 var strSymbols = stringToArray(string),
16146 chrSymbols = stringToArray(chars),
16147 start = charsStartIndex(strSymbols, chrSymbols),
16148 end = charsEndIndex(strSymbols, chrSymbols) + 1;
16150 return castSlice(strSymbols, start, end).join('');
16154 * Removes trailing whitespace or specified characters from `string`.
16160 * @param {string} [string=''] The string to trim.
16161 * @param {string} [chars=whitespace] The characters to trim.
16162 * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
16163 * @returns {string} Returns the trimmed string.
16166 * _.trimEnd(' abc ');
16169 * _.trimEnd('-_-abc-_-', '_-');
16172 function trimEnd(string, chars, guard) {
16173 string = toString(string);
16174 if (string && (guard || chars === undefined)) {
16175 return string.slice(0, trimmedEndIndex(string) + 1);
16177 if (!string || !(chars = baseToString(chars))) {
16180 var strSymbols = stringToArray(string),
16181 end = charsEndIndex(strSymbols, stringToArray(chars)) + 1;
16183 return castSlice(strSymbols, 0, end).join('');
16187 * Removes leading whitespace or specified characters from `string`.
16193 * @param {string} [string=''] The string to trim.
16194 * @param {string} [chars=whitespace] The characters to trim.
16195 * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
16196 * @returns {string} Returns the trimmed string.
16199 * _.trimStart(' abc ');
16202 * _.trimStart('-_-abc-_-', '_-');
16205 function trimStart(string, chars, guard) {
16206 string = toString(string);
16207 if (string && (guard || chars === undefined)) {
16208 return string.replace(reTrimStart, '');
16210 if (!string || !(chars = baseToString(chars))) {
16213 var strSymbols = stringToArray(string),
16214 start = charsStartIndex(strSymbols, stringToArray(chars));
16216 return castSlice(strSymbols, start).join('');
16220 * Truncates `string` if it's longer than the given maximum string length.
16221 * The last characters of the truncated string are replaced with the omission
16222 * string which defaults to "...".
16228 * @param {string} [string=''] The string to truncate.
16229 * @param {Object} [options={}] The options object.
16230 * @param {number} [options.length=30] The maximum string length.
16231 * @param {string} [options.omission='...'] The string to indicate text is omitted.
16232 * @param {RegExp|string} [options.separator] The separator pattern to truncate to.
16233 * @returns {string} Returns the truncated string.
16236 * _.truncate('hi-diddly-ho there, neighborino');
16237 * // => 'hi-diddly-ho there, neighbo...'
16239 * _.truncate('hi-diddly-ho there, neighborino', {
16243 * // => 'hi-diddly-ho there,...'
16245 * _.truncate('hi-diddly-ho there, neighborino', {
16247 * 'separator': /,? +/
16249 * // => 'hi-diddly-ho there...'
16251 * _.truncate('hi-diddly-ho there, neighborino', {
16252 * 'omission': ' [...]'
16254 * // => 'hi-diddly-ho there, neig [...]'
16256 function truncate(string, options) {
16257 var length = DEFAULT_TRUNC_LENGTH,
16258 omission = DEFAULT_TRUNC_OMISSION;
16260 if (isObject(options)) {
16261 var separator = 'separator' in options ? options.separator : separator;
16262 length = 'length' in options ? toInteger(options.length) : length;
16263 omission = 'omission' in options ? baseToString(options.omission) : omission;
16265 string = toString(string);
16267 var strLength = string.length;
16268 if (hasUnicode(string)) {
16269 var strSymbols = stringToArray(string);
16270 strLength = strSymbols.length;
16272 if (length >= strLength) {
16275 var end = length - stringSize(omission);
16279 var result = strSymbols
16280 ? castSlice(strSymbols, 0, end).join('')
16281 : string.slice(0, end);
16283 if (separator === undefined) {
16284 return result + omission;
16287 end += (result.length - end);
16289 if (isRegExp(separator)) {
16290 if (string.slice(end).search(separator)) {
16292 substring = result;
16294 if (!separator.global) {
16295 separator = RegExp(separator.source, toString(reFlags.exec(separator)) + 'g');
16297 separator.lastIndex = 0;
16298 while ((match = separator.exec(substring))) {
16299 var newEnd = match.index;
16301 result = result.slice(0, newEnd === undefined ? end : newEnd);
16303 } else if (string.indexOf(baseToString(separator), end) != end) {
16304 var index = result.lastIndexOf(separator);
16306 result = result.slice(0, index);
16309 return result + omission;
16313 * The inverse of `_.escape`; this method converts the HTML entities
16314 * `&`, `<`, `>`, `"`, and `'` in `string` to
16315 * their corresponding characters.
16317 * **Note:** No other HTML entities are unescaped. To unescape additional
16318 * HTML entities use a third-party library like [_he_](https://mths.be/he).
16324 * @param {string} [string=''] The string to unescape.
16325 * @returns {string} Returns the unescaped string.
16328 * _.unescape('fred, barney, & pebbles');
16329 * // => 'fred, barney, & pebbles'
16331 function unescape(string) {
16332 string = toString(string);
16333 return (string && reHasEscapedHtml.test(string))
16334 ? string.replace(reEscapedHtml, unescapeHtmlChar)
16339 * Converts `string`, as space separated words, to upper case.
16345 * @param {string} [string=''] The string to convert.
16346 * @returns {string} Returns the upper cased string.
16349 * _.upperCase('--foo-bar');
16352 * _.upperCase('fooBar');
16355 * _.upperCase('__foo_bar__');
16358 var upperCase = createCompounder(function(result, word, index) {
16359 return result + (index ? ' ' : '') + word.toUpperCase();
16363 * Converts the first character of `string` to upper case.
16369 * @param {string} [string=''] The string to convert.
16370 * @returns {string} Returns the converted string.
16373 * _.upperFirst('fred');
16376 * _.upperFirst('FRED');
16379 var upperFirst = createCaseFirst('toUpperCase');
16382 * Splits `string` into an array of its words.
16388 * @param {string} [string=''] The string to inspect.
16389 * @param {RegExp|string} [pattern] The pattern to match words.
16390 * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
16391 * @returns {Array} Returns the words of `string`.
16394 * _.words('fred, barney, & pebbles');
16395 * // => ['fred', 'barney', 'pebbles']
16397 * _.words('fred, barney, & pebbles', /[^, ]+/g);
16398 * // => ['fred', 'barney', '&', 'pebbles']
16400 function words(string, pattern, guard) {
16401 string = toString(string);
16402 pattern = guard ? undefined : pattern;
16404 if (pattern === undefined) {
16405 return hasUnicodeWord(string) ? unicodeWords(string) : asciiWords(string);
16407 return string.match(pattern) || [];
16410 /*------------------------------------------------------------------------*/
16413 * Attempts to invoke `func`, returning either the result or the caught error
16414 * object. Any additional arguments are provided to `func` when it's invoked.
16420 * @param {Function} func The function to attempt.
16421 * @param {...*} [args] The arguments to invoke `func` with.
16422 * @returns {*} Returns the `func` result or error object.
16425 * // Avoid throwing errors for invalid selectors.
16426 * var elements = _.attempt(function(selector) {
16427 * return document.querySelectorAll(selector);
16430 * if (_.isError(elements)) {
16434 var attempt = baseRest(function(func, args) {
16436 return apply(func, undefined, args);
16438 return isError(e) ? e : new Error(e);
16443 * Binds methods of an object to the object itself, overwriting the existing
16446 * **Note:** This method doesn't set the "length" property of bound functions.
16452 * @param {Object} object The object to bind and assign the bound methods to.
16453 * @param {...(string|string[])} methodNames The object method names to bind.
16454 * @returns {Object} Returns `object`.
16459 * 'click': function() {
16460 * console.log('clicked ' + this.label);
16464 * _.bindAll(view, ['click']);
16465 * jQuery(element).on('click', view.click);
16466 * // => Logs 'clicked docs' when clicked.
16468 var bindAll = flatRest(function(object, methodNames) {
16469 arrayEach(methodNames, function(key) {
16471 baseAssignValue(object, key, bind(object[key], object));
16477 * Creates a function that iterates over `pairs` and invokes the corresponding
16478 * function of the first predicate to return truthy. The predicate-function
16479 * pairs are invoked with the `this` binding and arguments of the created
16486 * @param {Array} pairs The predicate-function pairs.
16487 * @returns {Function} Returns the new composite function.
16490 * var func = _.cond([
16491 * [_.matches({ 'a': 1 }), _.constant('matches A')],
16492 * [_.conforms({ 'b': _.isNumber }), _.constant('matches B')],
16493 * [_.stubTrue, _.constant('no match')]
16496 * func({ 'a': 1, 'b': 2 });
16497 * // => 'matches A'
16499 * func({ 'a': 0, 'b': 1 });
16500 * // => 'matches B'
16502 * func({ 'a': '1', 'b': '2' });
16505 function cond(pairs) {
16506 var length = pairs == null ? 0 : pairs.length,
16507 toIteratee = getIteratee();
16509 pairs = !length ? [] : arrayMap(pairs, function(pair) {
16510 if (typeof pair[1] != 'function') {
16511 throw new TypeError(FUNC_ERROR_TEXT);
16513 return [toIteratee(pair[0]), pair[1]];
16516 return baseRest(function(args) {
16518 while (++index < length) {
16519 var pair = pairs[index];
16520 if (apply(pair[0], this, args)) {
16521 return apply(pair[1], this, args);
16528 * Creates a function that invokes the predicate properties of `source` with
16529 * the corresponding property values of a given object, returning `true` if
16530 * all predicates return truthy, else `false`.
16532 * **Note:** The created function is equivalent to `_.conformsTo` with
16533 * `source` partially applied.
16539 * @param {Object} source The object of property predicates to conform to.
16540 * @returns {Function} Returns the new spec function.
16544 * { 'a': 2, 'b': 1 },
16545 * { 'a': 1, 'b': 2 }
16548 * _.filter(objects, _.conforms({ 'b': function(n) { return n > 1; } }));
16549 * // => [{ 'a': 1, 'b': 2 }]
16551 function conforms(source) {
16552 return baseConforms(baseClone(source, CLONE_DEEP_FLAG));
16556 * Creates a function that returns `value`.
16562 * @param {*} value The value to return from the new function.
16563 * @returns {Function} Returns the new constant function.
16566 * var objects = _.times(2, _.constant({ 'a': 1 }));
16568 * console.log(objects);
16569 * // => [{ 'a': 1 }, { 'a': 1 }]
16571 * console.log(objects[0] === objects[1]);
16574 function constant(value) {
16575 return function() {
16581 * Checks `value` to determine whether a default value should be returned in
16582 * its place. The `defaultValue` is returned if `value` is `NaN`, `null`,
16589 * @param {*} value The value to check.
16590 * @param {*} defaultValue The default value.
16591 * @returns {*} Returns the resolved value.
16594 * _.defaultTo(1, 10);
16597 * _.defaultTo(undefined, 10);
16600 function defaultTo(value, defaultValue) {
16601 return (value == null || value !== value) ? defaultValue : value;
16605 * Creates a function that returns the result of invoking the given functions
16606 * with the `this` binding of the created function, where each successive
16607 * invocation is supplied the return value of the previous.
16613 * @param {...(Function|Function[])} [funcs] The functions to invoke.
16614 * @returns {Function} Returns the new composite function.
16618 * function square(n) {
16622 * var addSquare = _.flow([_.add, square]);
16626 var flow = createFlow();
16629 * This method is like `_.flow` except that it creates a function that
16630 * invokes the given functions from right to left.
16636 * @param {...(Function|Function[])} [funcs] The functions to invoke.
16637 * @returns {Function} Returns the new composite function.
16641 * function square(n) {
16645 * var addSquare = _.flowRight([square, _.add]);
16649 var flowRight = createFlow(true);
16652 * This method returns the first argument it receives.
16658 * @param {*} value Any value.
16659 * @returns {*} Returns `value`.
16662 * var object = { 'a': 1 };
16664 * console.log(_.identity(object) === object);
16667 function identity(value) {
16672 * Creates a function that invokes `func` with the arguments of the created
16673 * function. If `func` is a property name, the created function returns the
16674 * property value for a given element. If `func` is an array or object, the
16675 * created function returns `true` for elements that contain the equivalent
16676 * source properties, otherwise it returns `false`.
16682 * @param {*} [func=_.identity] The value to convert to a callback.
16683 * @returns {Function} Returns the callback.
16687 * { 'user': 'barney', 'age': 36, 'active': true },
16688 * { 'user': 'fred', 'age': 40, 'active': false }
16691 * // The `_.matches` iteratee shorthand.
16692 * _.filter(users, _.iteratee({ 'user': 'barney', 'active': true }));
16693 * // => [{ 'user': 'barney', 'age': 36, 'active': true }]
16695 * // The `_.matchesProperty` iteratee shorthand.
16696 * _.filter(users, _.iteratee(['user', 'fred']));
16697 * // => [{ 'user': 'fred', 'age': 40 }]
16699 * // The `_.property` iteratee shorthand.
16700 * _.map(users, _.iteratee('user'));
16701 * // => ['barney', 'fred']
16703 * // Create custom iteratee shorthands.
16704 * _.iteratee = _.wrap(_.iteratee, function(iteratee, func) {
16705 * return !_.isRegExp(func) ? iteratee(func) : function(string) {
16706 * return func.test(string);
16710 * _.filter(['abc', 'def'], /ef/);
16713 function iteratee(func) {
16714 return baseIteratee(typeof func == 'function' ? func : baseClone(func, CLONE_DEEP_FLAG));
16718 * Creates a function that performs a partial deep comparison between a given
16719 * object and `source`, returning `true` if the given object has equivalent
16720 * property values, else `false`.
16722 * **Note:** The created function is equivalent to `_.isMatch` with `source`
16723 * partially applied.
16725 * Partial comparisons will match empty array and empty object `source`
16726 * values against any array or object value, respectively. See `_.isEqual`
16727 * for a list of supported value comparisons.
16729 * **Note:** Multiple values can be checked by combining several matchers
16730 * using `_.overSome`
16736 * @param {Object} source The object of property values to match.
16737 * @returns {Function} Returns the new spec function.
16741 * { 'a': 1, 'b': 2, 'c': 3 },
16742 * { 'a': 4, 'b': 5, 'c': 6 }
16745 * _.filter(objects, _.matches({ 'a': 4, 'c': 6 }));
16746 * // => [{ 'a': 4, 'b': 5, 'c': 6 }]
16748 * // Checking for several possible values
16749 * _.filter(objects, _.overSome([_.matches({ 'a': 1 }), _.matches({ 'a': 4 })]));
16750 * // => [{ 'a': 1, 'b': 2, 'c': 3 }, { 'a': 4, 'b': 5, 'c': 6 }]
16752 function matches(source) {
16753 return baseMatches(baseClone(source, CLONE_DEEP_FLAG));
16757 * Creates a function that performs a partial deep comparison between the
16758 * value at `path` of a given object to `srcValue`, returning `true` if the
16759 * object value is equivalent, else `false`.
16761 * **Note:** Partial comparisons will match empty array and empty object
16762 * `srcValue` values against any array or object value, respectively. See
16763 * `_.isEqual` for a list of supported value comparisons.
16765 * **Note:** Multiple values can be checked by combining several matchers
16766 * using `_.overSome`
16772 * @param {Array|string} path The path of the property to get.
16773 * @param {*} srcValue The value to match.
16774 * @returns {Function} Returns the new spec function.
16778 * { 'a': 1, 'b': 2, 'c': 3 },
16779 * { 'a': 4, 'b': 5, 'c': 6 }
16782 * _.find(objects, _.matchesProperty('a', 4));
16783 * // => { 'a': 4, 'b': 5, 'c': 6 }
16785 * // Checking for several possible values
16786 * _.filter(objects, _.overSome([_.matchesProperty('a', 1), _.matchesProperty('a', 4)]));
16787 * // => [{ 'a': 1, 'b': 2, 'c': 3 }, { 'a': 4, 'b': 5, 'c': 6 }]
16789 function matchesProperty(path, srcValue) {
16790 return baseMatchesProperty(path, baseClone(srcValue, CLONE_DEEP_FLAG));
16794 * Creates a function that invokes the method at `path` of a given object.
16795 * Any additional arguments are provided to the invoked method.
16801 * @param {Array|string} path The path of the method to invoke.
16802 * @param {...*} [args] The arguments to invoke the method with.
16803 * @returns {Function} Returns the new invoker function.
16807 * { 'a': { 'b': _.constant(2) } },
16808 * { 'a': { 'b': _.constant(1) } }
16811 * _.map(objects, _.method('a.b'));
16814 * _.map(objects, _.method(['a', 'b']));
16817 var method = baseRest(function(path, args) {
16818 return function(object) {
16819 return baseInvoke(object, path, args);
16824 * The opposite of `_.method`; this method creates a function that invokes
16825 * the method at a given path of `object`. Any additional arguments are
16826 * provided to the invoked method.
16832 * @param {Object} object The object to query.
16833 * @param {...*} [args] The arguments to invoke the method with.
16834 * @returns {Function} Returns the new invoker function.
16837 * var array = _.times(3, _.constant),
16838 * object = { 'a': array, 'b': array, 'c': array };
16840 * _.map(['a[2]', 'c[0]'], _.methodOf(object));
16843 * _.map([['a', '2'], ['c', '0']], _.methodOf(object));
16846 var methodOf = baseRest(function(object, args) {
16847 return function(path) {
16848 return baseInvoke(object, path, args);
16853 * Adds all own enumerable string keyed function properties of a source
16854 * object to the destination object. If `object` is a function, then methods
16855 * are added to its prototype as well.
16857 * **Note:** Use `_.runInContext` to create a pristine `lodash` function to
16858 * avoid conflicts caused by modifying the original.
16864 * @param {Function|Object} [object=lodash] The destination object.
16865 * @param {Object} source The object of functions to add.
16866 * @param {Object} [options={}] The options object.
16867 * @param {boolean} [options.chain=true] Specify whether mixins are chainable.
16868 * @returns {Function|Object} Returns `object`.
16871 * function vowels(string) {
16872 * return _.filter(string, function(v) {
16873 * return /[aeiou]/i.test(v);
16877 * _.mixin({ 'vowels': vowels });
16878 * _.vowels('fred');
16881 * _('fred').vowels().value();
16884 * _.mixin({ 'vowels': vowels }, { 'chain': false });
16885 * _('fred').vowels();
16888 function mixin(object, source, options) {
16889 var props = keys(source),
16890 methodNames = baseFunctions(source, props);
16892 if (options == null &&
16893 !(isObject(source) && (methodNames.length || !props.length))) {
16897 methodNames = baseFunctions(source, keys(source));
16899 var chain = !(isObject(options) && 'chain' in options) || !!options.chain,
16900 isFunc = isFunction(object);
16902 arrayEach(methodNames, function(methodName) {
16903 var func = source[methodName];
16904 object[methodName] = func;
16906 object.prototype[methodName] = function() {
16907 var chainAll = this.__chain__;
16908 if (chain || chainAll) {
16909 var result = object(this.__wrapped__),
16910 actions = result.__actions__ = copyArray(this.__actions__);
16912 actions.push({ 'func': func, 'args': arguments, 'thisArg': object });
16913 result.__chain__ = chainAll;
16916 return func.apply(object, arrayPush([this.value()], arguments));
16925 * Reverts the `_` variable to its previous value and returns a reference to
16926 * the `lodash` function.
16932 * @returns {Function} Returns the `lodash` function.
16935 * var lodash = _.noConflict();
16937 function noConflict() {
16938 if (root._ === this) {
16945 * This method returns `undefined`.
16953 * _.times(2, _.noop);
16954 * // => [undefined, undefined]
16957 // No operation performed.
16961 * Creates a function that gets the argument at index `n`. If `n` is negative,
16962 * the nth argument from the end is returned.
16968 * @param {number} [n=0] The index of the argument to return.
16969 * @returns {Function} Returns the new pass-thru function.
16972 * var func = _.nthArg(1);
16973 * func('a', 'b', 'c', 'd');
16976 * var func = _.nthArg(-2);
16977 * func('a', 'b', 'c', 'd');
16980 function nthArg(n) {
16982 return baseRest(function(args) {
16983 return baseNth(args, n);
16988 * Creates a function that invokes `iteratees` with the arguments it receives
16989 * and returns their results.
16995 * @param {...(Function|Function[])} [iteratees=[_.identity]]
16996 * The iteratees to invoke.
16997 * @returns {Function} Returns the new function.
17000 * var func = _.over([Math.max, Math.min]);
17002 * func(1, 2, 3, 4);
17005 var over = createOver(arrayMap);
17008 * Creates a function that checks if **all** of the `predicates` return
17009 * truthy when invoked with the arguments it receives.
17011 * Following shorthands are possible for providing predicates.
17012 * Pass an `Object` and it will be used as an parameter for `_.matches` to create the predicate.
17013 * Pass an `Array` of parameters for `_.matchesProperty` and the predicate will be created using them.
17019 * @param {...(Function|Function[])} [predicates=[_.identity]]
17020 * The predicates to check.
17021 * @returns {Function} Returns the new function.
17024 * var func = _.overEvery([Boolean, isFinite]);
17035 var overEvery = createOver(arrayEvery);
17038 * Creates a function that checks if **any** of the `predicates` return
17039 * truthy when invoked with the arguments it receives.
17041 * Following shorthands are possible for providing predicates.
17042 * Pass an `Object` and it will be used as an parameter for `_.matches` to create the predicate.
17043 * Pass an `Array` of parameters for `_.matchesProperty` and the predicate will be created using them.
17049 * @param {...(Function|Function[])} [predicates=[_.identity]]
17050 * The predicates to check.
17051 * @returns {Function} Returns the new function.
17054 * var func = _.overSome([Boolean, isFinite]);
17065 * var matchesFunc = _.overSome([{ 'a': 1 }, { 'a': 2 }])
17066 * var matchesPropertyFunc = _.overSome([['a', 1], ['a', 2]])
17068 var overSome = createOver(arraySome);
17071 * Creates a function that returns the value at `path` of a given object.
17077 * @param {Array|string} path The path of the property to get.
17078 * @returns {Function} Returns the new accessor function.
17082 * { 'a': { 'b': 2 } },
17083 * { 'a': { 'b': 1 } }
17086 * _.map(objects, _.property('a.b'));
17089 * _.map(_.sortBy(objects, _.property(['a', 'b'])), 'a.b');
17092 function property(path) {
17093 return isKey(path) ? baseProperty(toKey(path)) : basePropertyDeep(path);
17097 * The opposite of `_.property`; this method creates a function that returns
17098 * the value at a given path of `object`.
17104 * @param {Object} object The object to query.
17105 * @returns {Function} Returns the new accessor function.
17108 * var array = [0, 1, 2],
17109 * object = { 'a': array, 'b': array, 'c': array };
17111 * _.map(['a[2]', 'c[0]'], _.propertyOf(object));
17114 * _.map([['a', '2'], ['c', '0']], _.propertyOf(object));
17117 function propertyOf(object) {
17118 return function(path) {
17119 return object == null ? undefined : baseGet(object, path);
17124 * Creates an array of numbers (positive and/or negative) progressing from
17125 * `start` up to, but not including, `end`. A step of `-1` is used if a negative
17126 * `start` is specified without an `end` or `step`. If `end` is not specified,
17127 * it's set to `start` with `start` then set to `0`.
17129 * **Note:** JavaScript follows the IEEE-754 standard for resolving
17130 * floating-point values which can produce unexpected results.
17136 * @param {number} [start=0] The start of the range.
17137 * @param {number} end The end of the range.
17138 * @param {number} [step=1] The value to increment or decrement by.
17139 * @returns {Array} Returns the range of numbers.
17140 * @see _.inRange, _.rangeRight
17144 * // => [0, 1, 2, 3]
17147 * // => [0, -1, -2, -3]
17150 * // => [1, 2, 3, 4]
17152 * _.range(0, 20, 5);
17153 * // => [0, 5, 10, 15]
17155 * _.range(0, -4, -1);
17156 * // => [0, -1, -2, -3]
17158 * _.range(1, 4, 0);
17164 var range = createRange();
17167 * This method is like `_.range` except that it populates values in
17168 * descending order.
17174 * @param {number} [start=0] The start of the range.
17175 * @param {number} end The end of the range.
17176 * @param {number} [step=1] The value to increment or decrement by.
17177 * @returns {Array} Returns the range of numbers.
17178 * @see _.inRange, _.range
17182 * // => [3, 2, 1, 0]
17184 * _.rangeRight(-4);
17185 * // => [-3, -2, -1, 0]
17187 * _.rangeRight(1, 5);
17188 * // => [4, 3, 2, 1]
17190 * _.rangeRight(0, 20, 5);
17191 * // => [15, 10, 5, 0]
17193 * _.rangeRight(0, -4, -1);
17194 * // => [-3, -2, -1, 0]
17196 * _.rangeRight(1, 4, 0);
17202 var rangeRight = createRange(true);
17205 * This method returns a new empty array.
17211 * @returns {Array} Returns the new empty array.
17214 * var arrays = _.times(2, _.stubArray);
17216 * console.log(arrays);
17219 * console.log(arrays[0] === arrays[1]);
17222 function stubArray() {
17227 * This method returns `false`.
17233 * @returns {boolean} Returns `false`.
17236 * _.times(2, _.stubFalse);
17237 * // => [false, false]
17239 function stubFalse() {
17244 * This method returns a new empty object.
17250 * @returns {Object} Returns the new empty object.
17253 * var objects = _.times(2, _.stubObject);
17255 * console.log(objects);
17258 * console.log(objects[0] === objects[1]);
17261 function stubObject() {
17266 * This method returns an empty string.
17272 * @returns {string} Returns the empty string.
17275 * _.times(2, _.stubString);
17278 function stubString() {
17283 * This method returns `true`.
17289 * @returns {boolean} Returns `true`.
17292 * _.times(2, _.stubTrue);
17293 * // => [true, true]
17295 function stubTrue() {
17300 * Invokes the iteratee `n` times, returning an array of the results of
17301 * each invocation. The iteratee is invoked with one argument; (index).
17307 * @param {number} n The number of times to invoke `iteratee`.
17308 * @param {Function} [iteratee=_.identity] The function invoked per iteration.
17309 * @returns {Array} Returns the array of results.
17312 * _.times(3, String);
17313 * // => ['0', '1', '2']
17315 * _.times(4, _.constant(0));
17316 * // => [0, 0, 0, 0]
17318 function times(n, iteratee) {
17320 if (n < 1 || n > MAX_SAFE_INTEGER) {
17323 var index = MAX_ARRAY_LENGTH,
17324 length = nativeMin(n, MAX_ARRAY_LENGTH);
17326 iteratee = getIteratee(iteratee);
17327 n -= MAX_ARRAY_LENGTH;
17329 var result = baseTimes(length, iteratee);
17330 while (++index < n) {
17337 * Converts `value` to a property path array.
17343 * @param {*} value The value to convert.
17344 * @returns {Array} Returns the new property path array.
17347 * _.toPath('a.b.c');
17348 * // => ['a', 'b', 'c']
17350 * _.toPath('a[0].b.c');
17351 * // => ['a', '0', 'b', 'c']
17353 function toPath(value) {
17354 if (isArray(value)) {
17355 return arrayMap(value, toKey);
17357 return isSymbol(value) ? [value] : copyArray(stringToPath(toString(value)));
17361 * Generates a unique ID. If `prefix` is given, the ID is appended to it.
17367 * @param {string} [prefix=''] The value to prefix the ID with.
17368 * @returns {string} Returns the unique ID.
17371 * _.uniqueId('contact_');
17372 * // => 'contact_104'
17377 function uniqueId(prefix) {
17378 var id = ++idCounter;
17379 return toString(prefix) + id;
17382 /*------------------------------------------------------------------------*/
17385 * Adds two numbers.
17391 * @param {number} augend The first number in an addition.
17392 * @param {number} addend The second number in an addition.
17393 * @returns {number} Returns the total.
17399 var add = createMathOperation(function(augend, addend) {
17400 return augend + addend;
17404 * Computes `number` rounded up to `precision`.
17410 * @param {number} number The number to round up.
17411 * @param {number} [precision=0] The precision to round up to.
17412 * @returns {number} Returns the rounded up number.
17418 * _.ceil(6.004, 2);
17421 * _.ceil(6040, -2);
17424 var ceil = createRound('ceil');
17427 * Divide two numbers.
17433 * @param {number} dividend The first number in a division.
17434 * @param {number} divisor The second number in a division.
17435 * @returns {number} Returns the quotient.
17441 var divide = createMathOperation(function(dividend, divisor) {
17442 return dividend / divisor;
17446 * Computes `number` rounded down to `precision`.
17452 * @param {number} number The number to round down.
17453 * @param {number} [precision=0] The precision to round down to.
17454 * @returns {number} Returns the rounded down number.
17460 * _.floor(0.046, 2);
17463 * _.floor(4060, -2);
17466 var floor = createRound('floor');
17469 * Computes the maximum value of `array`. If `array` is empty or falsey,
17470 * `undefined` is returned.
17476 * @param {Array} array The array to iterate over.
17477 * @returns {*} Returns the maximum value.
17480 * _.max([4, 2, 8, 6]);
17486 function max(array) {
17487 return (array && array.length)
17488 ? baseExtremum(array, identity, baseGt)
17493 * This method is like `_.max` except that it accepts `iteratee` which is
17494 * invoked for each element in `array` to generate the criterion by which
17495 * the value is ranked. The iteratee is invoked with one argument: (value).
17501 * @param {Array} array The array to iterate over.
17502 * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
17503 * @returns {*} Returns the maximum value.
17506 * var objects = [{ 'n': 1 }, { 'n': 2 }];
17508 * _.maxBy(objects, function(o) { return o.n; });
17511 * // The `_.property` iteratee shorthand.
17512 * _.maxBy(objects, 'n');
17515 function maxBy(array, iteratee) {
17516 return (array && array.length)
17517 ? baseExtremum(array, getIteratee(iteratee, 2), baseGt)
17522 * Computes the mean of the values in `array`.
17528 * @param {Array} array The array to iterate over.
17529 * @returns {number} Returns the mean.
17532 * _.mean([4, 2, 8, 6]);
17535 function mean(array) {
17536 return baseMean(array, identity);
17540 * This method is like `_.mean` except that it accepts `iteratee` which is
17541 * invoked for each element in `array` to generate the value to be averaged.
17542 * The iteratee is invoked with one argument: (value).
17548 * @param {Array} array The array to iterate over.
17549 * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
17550 * @returns {number} Returns the mean.
17553 * var objects = [{ 'n': 4 }, { 'n': 2 }, { 'n': 8 }, { 'n': 6 }];
17555 * _.meanBy(objects, function(o) { return o.n; });
17558 * // The `_.property` iteratee shorthand.
17559 * _.meanBy(objects, 'n');
17562 function meanBy(array, iteratee) {
17563 return baseMean(array, getIteratee(iteratee, 2));
17567 * Computes the minimum value of `array`. If `array` is empty or falsey,
17568 * `undefined` is returned.
17574 * @param {Array} array The array to iterate over.
17575 * @returns {*} Returns the minimum value.
17578 * _.min([4, 2, 8, 6]);
17584 function min(array) {
17585 return (array && array.length)
17586 ? baseExtremum(array, identity, baseLt)
17591 * This method is like `_.min` except that it accepts `iteratee` which is
17592 * invoked for each element in `array` to generate the criterion by which
17593 * the value is ranked. The iteratee is invoked with one argument: (value).
17599 * @param {Array} array The array to iterate over.
17600 * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
17601 * @returns {*} Returns the minimum value.
17604 * var objects = [{ 'n': 1 }, { 'n': 2 }];
17606 * _.minBy(objects, function(o) { return o.n; });
17609 * // The `_.property` iteratee shorthand.
17610 * _.minBy(objects, 'n');
17613 function minBy(array, iteratee) {
17614 return (array && array.length)
17615 ? baseExtremum(array, getIteratee(iteratee, 2), baseLt)
17620 * Multiply two numbers.
17626 * @param {number} multiplier The first number in a multiplication.
17627 * @param {number} multiplicand The second number in a multiplication.
17628 * @returns {number} Returns the product.
17631 * _.multiply(6, 4);
17634 var multiply = createMathOperation(function(multiplier, multiplicand) {
17635 return multiplier * multiplicand;
17639 * Computes `number` rounded to `precision`.
17645 * @param {number} number The number to round.
17646 * @param {number} [precision=0] The precision to round to.
17647 * @returns {number} Returns the rounded number.
17653 * _.round(4.006, 2);
17656 * _.round(4060, -2);
17659 var round = createRound('round');
17662 * Subtract two numbers.
17668 * @param {number} minuend The first number in a subtraction.
17669 * @param {number} subtrahend The second number in a subtraction.
17670 * @returns {number} Returns the difference.
17673 * _.subtract(6, 4);
17676 var subtract = createMathOperation(function(minuend, subtrahend) {
17677 return minuend - subtrahend;
17681 * Computes the sum of the values in `array`.
17687 * @param {Array} array The array to iterate over.
17688 * @returns {number} Returns the sum.
17691 * _.sum([4, 2, 8, 6]);
17694 function sum(array) {
17695 return (array && array.length)
17696 ? baseSum(array, identity)
17701 * This method is like `_.sum` except that it accepts `iteratee` which is
17702 * invoked for each element in `array` to generate the value to be summed.
17703 * The iteratee is invoked with one argument: (value).
17709 * @param {Array} array The array to iterate over.
17710 * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
17711 * @returns {number} Returns the sum.
17714 * var objects = [{ 'n': 4 }, { 'n': 2 }, { 'n': 8 }, { 'n': 6 }];
17716 * _.sumBy(objects, function(o) { return o.n; });
17719 * // The `_.property` iteratee shorthand.
17720 * _.sumBy(objects, 'n');
17723 function sumBy(array, iteratee) {
17724 return (array && array.length)
17725 ? baseSum(array, getIteratee(iteratee, 2))
17729 /*------------------------------------------------------------------------*/
17731 // Add methods that return wrapped values in chain sequences.
17732 lodash.after = after;
17734 lodash.assign = assign;
17735 lodash.assignIn = assignIn;
17736 lodash.assignInWith = assignInWith;
17737 lodash.assignWith = assignWith;
17739 lodash.before = before;
17740 lodash.bind = bind;
17741 lodash.bindAll = bindAll;
17742 lodash.bindKey = bindKey;
17743 lodash.castArray = castArray;
17744 lodash.chain = chain;
17745 lodash.chunk = chunk;
17746 lodash.compact = compact;
17747 lodash.concat = concat;
17748 lodash.cond = cond;
17749 lodash.conforms = conforms;
17750 lodash.constant = constant;
17751 lodash.countBy = countBy;
17752 lodash.create = create;
17753 lodash.curry = curry;
17754 lodash.curryRight = curryRight;
17755 lodash.debounce = debounce;
17756 lodash.defaults = defaults;
17757 lodash.defaultsDeep = defaultsDeep;
17758 lodash.defer = defer;
17759 lodash.delay = delay;
17760 lodash.difference = difference;
17761 lodash.differenceBy = differenceBy;
17762 lodash.differenceWith = differenceWith;
17763 lodash.drop = drop;
17764 lodash.dropRight = dropRight;
17765 lodash.dropRightWhile = dropRightWhile;
17766 lodash.dropWhile = dropWhile;
17767 lodash.fill = fill;
17768 lodash.filter = filter;
17769 lodash.flatMap = flatMap;
17770 lodash.flatMapDeep = flatMapDeep;
17771 lodash.flatMapDepth = flatMapDepth;
17772 lodash.flatten = flatten;
17773 lodash.flattenDeep = flattenDeep;
17774 lodash.flattenDepth = flattenDepth;
17775 lodash.flip = flip;
17776 lodash.flow = flow;
17777 lodash.flowRight = flowRight;
17778 lodash.fromPairs = fromPairs;
17779 lodash.functions = functions;
17780 lodash.functionsIn = functionsIn;
17781 lodash.groupBy = groupBy;
17782 lodash.initial = initial;
17783 lodash.intersection = intersection;
17784 lodash.intersectionBy = intersectionBy;
17785 lodash.intersectionWith = intersectionWith;
17786 lodash.invert = invert;
17787 lodash.invertBy = invertBy;
17788 lodash.invokeMap = invokeMap;
17789 lodash.iteratee = iteratee;
17790 lodash.keyBy = keyBy;
17791 lodash.keys = keys;
17792 lodash.keysIn = keysIn;
17794 lodash.mapKeys = mapKeys;
17795 lodash.mapValues = mapValues;
17796 lodash.matches = matches;
17797 lodash.matchesProperty = matchesProperty;
17798 lodash.memoize = memoize;
17799 lodash.merge = merge;
17800 lodash.mergeWith = mergeWith;
17801 lodash.method = method;
17802 lodash.methodOf = methodOf;
17803 lodash.mixin = mixin;
17804 lodash.negate = negate;
17805 lodash.nthArg = nthArg;
17806 lodash.omit = omit;
17807 lodash.omitBy = omitBy;
17808 lodash.once = once;
17809 lodash.orderBy = orderBy;
17810 lodash.over = over;
17811 lodash.overArgs = overArgs;
17812 lodash.overEvery = overEvery;
17813 lodash.overSome = overSome;
17814 lodash.partial = partial;
17815 lodash.partialRight = partialRight;
17816 lodash.partition = partition;
17817 lodash.pick = pick;
17818 lodash.pickBy = pickBy;
17819 lodash.property = property;
17820 lodash.propertyOf = propertyOf;
17821 lodash.pull = pull;
17822 lodash.pullAll = pullAll;
17823 lodash.pullAllBy = pullAllBy;
17824 lodash.pullAllWith = pullAllWith;
17825 lodash.pullAt = pullAt;
17826 lodash.range = range;
17827 lodash.rangeRight = rangeRight;
17828 lodash.rearg = rearg;
17829 lodash.reject = reject;
17830 lodash.remove = remove;
17831 lodash.rest = rest;
17832 lodash.reverse = reverse;
17833 lodash.sampleSize = sampleSize;
17835 lodash.setWith = setWith;
17836 lodash.shuffle = shuffle;
17837 lodash.slice = slice;
17838 lodash.sortBy = sortBy;
17839 lodash.sortedUniq = sortedUniq;
17840 lodash.sortedUniqBy = sortedUniqBy;
17841 lodash.split = split;
17842 lodash.spread = spread;
17843 lodash.tail = tail;
17844 lodash.take = take;
17845 lodash.takeRight = takeRight;
17846 lodash.takeRightWhile = takeRightWhile;
17847 lodash.takeWhile = takeWhile;
17849 lodash.throttle = throttle;
17850 lodash.thru = thru;
17851 lodash.toArray = toArray;
17852 lodash.toPairs = toPairs;
17853 lodash.toPairsIn = toPairsIn;
17854 lodash.toPath = toPath;
17855 lodash.toPlainObject = toPlainObject;
17856 lodash.transform = transform;
17857 lodash.unary = unary;
17858 lodash.union = union;
17859 lodash.unionBy = unionBy;
17860 lodash.unionWith = unionWith;
17861 lodash.uniq = uniq;
17862 lodash.uniqBy = uniqBy;
17863 lodash.uniqWith = uniqWith;
17864 lodash.unset = unset;
17865 lodash.unzip = unzip;
17866 lodash.unzipWith = unzipWith;
17867 lodash.update = update;
17868 lodash.updateWith = updateWith;
17869 lodash.values = values;
17870 lodash.valuesIn = valuesIn;
17871 lodash.without = without;
17872 lodash.words = words;
17873 lodash.wrap = wrap;
17875 lodash.xorBy = xorBy;
17876 lodash.xorWith = xorWith;
17878 lodash.zipObject = zipObject;
17879 lodash.zipObjectDeep = zipObjectDeep;
17880 lodash.zipWith = zipWith;
17883 lodash.entries = toPairs;
17884 lodash.entriesIn = toPairsIn;
17885 lodash.extend = assignIn;
17886 lodash.extendWith = assignInWith;
17888 // Add methods to `lodash.prototype`.
17889 mixin(lodash, lodash);
17891 /*------------------------------------------------------------------------*/
17893 // Add methods that return unwrapped values in chain sequences.
17895 lodash.attempt = attempt;
17896 lodash.camelCase = camelCase;
17897 lodash.capitalize = capitalize;
17898 lodash.ceil = ceil;
17899 lodash.clamp = clamp;
17900 lodash.clone = clone;
17901 lodash.cloneDeep = cloneDeep;
17902 lodash.cloneDeepWith = cloneDeepWith;
17903 lodash.cloneWith = cloneWith;
17904 lodash.conformsTo = conformsTo;
17905 lodash.deburr = deburr;
17906 lodash.defaultTo = defaultTo;
17907 lodash.divide = divide;
17908 lodash.endsWith = endsWith;
17910 lodash.escape = escape;
17911 lodash.escapeRegExp = escapeRegExp;
17912 lodash.every = every;
17913 lodash.find = find;
17914 lodash.findIndex = findIndex;
17915 lodash.findKey = findKey;
17916 lodash.findLast = findLast;
17917 lodash.findLastIndex = findLastIndex;
17918 lodash.findLastKey = findLastKey;
17919 lodash.floor = floor;
17920 lodash.forEach = forEach;
17921 lodash.forEachRight = forEachRight;
17922 lodash.forIn = forIn;
17923 lodash.forInRight = forInRight;
17924 lodash.forOwn = forOwn;
17925 lodash.forOwnRight = forOwnRight;
17930 lodash.hasIn = hasIn;
17931 lodash.head = head;
17932 lodash.identity = identity;
17933 lodash.includes = includes;
17934 lodash.indexOf = indexOf;
17935 lodash.inRange = inRange;
17936 lodash.invoke = invoke;
17937 lodash.isArguments = isArguments;
17938 lodash.isArray = isArray;
17939 lodash.isArrayBuffer = isArrayBuffer;
17940 lodash.isArrayLike = isArrayLike;
17941 lodash.isArrayLikeObject = isArrayLikeObject;
17942 lodash.isBoolean = isBoolean;
17943 lodash.isBuffer = isBuffer;
17944 lodash.isDate = isDate;
17945 lodash.isElement = isElement;
17946 lodash.isEmpty = isEmpty;
17947 lodash.isEqual = isEqual;
17948 lodash.isEqualWith = isEqualWith;
17949 lodash.isError = isError;
17950 lodash.isFinite = isFinite;
17951 lodash.isFunction = isFunction;
17952 lodash.isInteger = isInteger;
17953 lodash.isLength = isLength;
17954 lodash.isMap = isMap;
17955 lodash.isMatch = isMatch;
17956 lodash.isMatchWith = isMatchWith;
17957 lodash.isNaN = isNaN;
17958 lodash.isNative = isNative;
17959 lodash.isNil = isNil;
17960 lodash.isNull = isNull;
17961 lodash.isNumber = isNumber;
17962 lodash.isObject = isObject;
17963 lodash.isObjectLike = isObjectLike;
17964 lodash.isPlainObject = isPlainObject;
17965 lodash.isRegExp = isRegExp;
17966 lodash.isSafeInteger = isSafeInteger;
17967 lodash.isSet = isSet;
17968 lodash.isString = isString;
17969 lodash.isSymbol = isSymbol;
17970 lodash.isTypedArray = isTypedArray;
17971 lodash.isUndefined = isUndefined;
17972 lodash.isWeakMap = isWeakMap;
17973 lodash.isWeakSet = isWeakSet;
17974 lodash.join = join;
17975 lodash.kebabCase = kebabCase;
17976 lodash.last = last;
17977 lodash.lastIndexOf = lastIndexOf;
17978 lodash.lowerCase = lowerCase;
17979 lodash.lowerFirst = lowerFirst;
17983 lodash.maxBy = maxBy;
17984 lodash.mean = mean;
17985 lodash.meanBy = meanBy;
17987 lodash.minBy = minBy;
17988 lodash.stubArray = stubArray;
17989 lodash.stubFalse = stubFalse;
17990 lodash.stubObject = stubObject;
17991 lodash.stubString = stubString;
17992 lodash.stubTrue = stubTrue;
17993 lodash.multiply = multiply;
17995 lodash.noConflict = noConflict;
17996 lodash.noop = noop;
17999 lodash.padEnd = padEnd;
18000 lodash.padStart = padStart;
18001 lodash.parseInt = parseInt;
18002 lodash.random = random;
18003 lodash.reduce = reduce;
18004 lodash.reduceRight = reduceRight;
18005 lodash.repeat = repeat;
18006 lodash.replace = replace;
18007 lodash.result = result;
18008 lodash.round = round;
18009 lodash.runInContext = runInContext;
18010 lodash.sample = sample;
18011 lodash.size = size;
18012 lodash.snakeCase = snakeCase;
18013 lodash.some = some;
18014 lodash.sortedIndex = sortedIndex;
18015 lodash.sortedIndexBy = sortedIndexBy;
18016 lodash.sortedIndexOf = sortedIndexOf;
18017 lodash.sortedLastIndex = sortedLastIndex;
18018 lodash.sortedLastIndexBy = sortedLastIndexBy;
18019 lodash.sortedLastIndexOf = sortedLastIndexOf;
18020 lodash.startCase = startCase;
18021 lodash.startsWith = startsWith;
18022 lodash.subtract = subtract;
18024 lodash.sumBy = sumBy;
18025 lodash.template = template;
18026 lodash.times = times;
18027 lodash.toFinite = toFinite;
18028 lodash.toInteger = toInteger;
18029 lodash.toLength = toLength;
18030 lodash.toLower = toLower;
18031 lodash.toNumber = toNumber;
18032 lodash.toSafeInteger = toSafeInteger;
18033 lodash.toString = toString;
18034 lodash.toUpper = toUpper;
18035 lodash.trim = trim;
18036 lodash.trimEnd = trimEnd;
18037 lodash.trimStart = trimStart;
18038 lodash.truncate = truncate;
18039 lodash.unescape = unescape;
18040 lodash.uniqueId = uniqueId;
18041 lodash.upperCase = upperCase;
18042 lodash.upperFirst = upperFirst;
18045 lodash.each = forEach;
18046 lodash.eachRight = forEachRight;
18047 lodash.first = head;
18049 mixin(lodash, (function() {
18051 baseForOwn(lodash, function(func, methodName) {
18052 if (!hasOwnProperty.call(lodash.prototype, methodName)) {
18053 source[methodName] = func;
18057 }()), { 'chain': false });
18059 /*------------------------------------------------------------------------*/
18062 * The semantic version number.
18068 lodash.VERSION = VERSION;
18070 // Assign default placeholders.
18071 arrayEach(['bind', 'bindKey', 'curry', 'curryRight', 'partial', 'partialRight'], function(methodName) {
18072 lodash[methodName].placeholder = lodash;
18075 // Add `LazyWrapper` methods for `_.drop` and `_.take` variants.
18076 arrayEach(['drop', 'take'], function(methodName, index) {
18077 LazyWrapper.prototype[methodName] = function(n) {
18078 n = n === undefined ? 1 : nativeMax(toInteger(n), 0);
18080 var result = (this.__filtered__ && !index)
18081 ? new LazyWrapper(this)
18084 if (result.__filtered__) {
18085 result.__takeCount__ = nativeMin(n, result.__takeCount__);
18087 result.__views__.push({
18088 'size': nativeMin(n, MAX_ARRAY_LENGTH),
18089 'type': methodName + (result.__dir__ < 0 ? 'Right' : '')
18095 LazyWrapper.prototype[methodName + 'Right'] = function(n) {
18096 return this.reverse()[methodName](n).reverse();
18100 // Add `LazyWrapper` methods that accept an `iteratee` value.
18101 arrayEach(['filter', 'map', 'takeWhile'], function(methodName, index) {
18102 var type = index + 1,
18103 isFilter = type == LAZY_FILTER_FLAG || type == LAZY_WHILE_FLAG;
18105 LazyWrapper.prototype[methodName] = function(iteratee) {
18106 var result = this.clone();
18107 result.__iteratees__.push({
18108 'iteratee': getIteratee(iteratee, 3),
18111 result.__filtered__ = result.__filtered__ || isFilter;
18116 // Add `LazyWrapper` methods for `_.head` and `_.last`.
18117 arrayEach(['head', 'last'], function(methodName, index) {
18118 var takeName = 'take' + (index ? 'Right' : '');
18120 LazyWrapper.prototype[methodName] = function() {
18121 return this[takeName](1).value()[0];
18125 // Add `LazyWrapper` methods for `_.initial` and `_.tail`.
18126 arrayEach(['initial', 'tail'], function(methodName, index) {
18127 var dropName = 'drop' + (index ? '' : 'Right');
18129 LazyWrapper.prototype[methodName] = function() {
18130 return this.__filtered__ ? new LazyWrapper(this) : this[dropName](1);
18134 LazyWrapper.prototype.compact = function() {
18135 return this.filter(identity);
18138 LazyWrapper.prototype.find = function(predicate) {
18139 return this.filter(predicate).head();
18142 LazyWrapper.prototype.findLast = function(predicate) {
18143 return this.reverse().find(predicate);
18146 LazyWrapper.prototype.invokeMap = baseRest(function(path, args) {
18147 if (typeof path == 'function') {
18148 return new LazyWrapper(this);
18150 return this.map(function(value) {
18151 return baseInvoke(value, path, args);
18155 LazyWrapper.prototype.reject = function(predicate) {
18156 return this.filter(negate(getIteratee(predicate)));
18159 LazyWrapper.prototype.slice = function(start, end) {
18160 start = toInteger(start);
18163 if (result.__filtered__ && (start > 0 || end < 0)) {
18164 return new LazyWrapper(result);
18167 result = result.takeRight(-start);
18168 } else if (start) {
18169 result = result.drop(start);
18171 if (end !== undefined) {
18172 end = toInteger(end);
18173 result = end < 0 ? result.dropRight(-end) : result.take(end - start);
18178 LazyWrapper.prototype.takeRightWhile = function(predicate) {
18179 return this.reverse().takeWhile(predicate).reverse();
18182 LazyWrapper.prototype.toArray = function() {
18183 return this.take(MAX_ARRAY_LENGTH);
18186 // Add `LazyWrapper` methods to `lodash.prototype`.
18187 baseForOwn(LazyWrapper.prototype, function(func, methodName) {
18188 var checkIteratee = /^(?:filter|find|map|reject)|While$/.test(methodName),
18189 isTaker = /^(?:head|last)$/.test(methodName),
18190 lodashFunc = lodash[isTaker ? ('take' + (methodName == 'last' ? 'Right' : '')) : methodName],
18191 retUnwrapped = isTaker || /^find/.test(methodName);
18196 lodash.prototype[methodName] = function() {
18197 var value = this.__wrapped__,
18198 args = isTaker ? [1] : arguments,
18199 isLazy = value instanceof LazyWrapper,
18200 iteratee = args[0],
18201 useLazy = isLazy || isArray(value);
18203 var interceptor = function(value) {
18204 var result = lodashFunc.apply(lodash, arrayPush([value], args));
18205 return (isTaker && chainAll) ? result[0] : result;
18208 if (useLazy && checkIteratee && typeof iteratee == 'function' && iteratee.length != 1) {
18209 // Avoid lazy use if the iteratee has a "length" value other than `1`.
18210 isLazy = useLazy = false;
18212 var chainAll = this.__chain__,
18213 isHybrid = !!this.__actions__.length,
18214 isUnwrapped = retUnwrapped && !chainAll,
18215 onlyLazy = isLazy && !isHybrid;
18217 if (!retUnwrapped && useLazy) {
18218 value = onlyLazy ? value : new LazyWrapper(this);
18219 var result = func.apply(value, args);
18220 result.__actions__.push({ 'func': thru, 'args': [interceptor], 'thisArg': undefined });
18221 return new LodashWrapper(result, chainAll);
18223 if (isUnwrapped && onlyLazy) {
18224 return func.apply(this, args);
18226 result = this.thru(interceptor);
18227 return isUnwrapped ? (isTaker ? result.value()[0] : result.value()) : result;
18231 // Add `Array` methods to `lodash.prototype`.
18232 arrayEach(['pop', 'push', 'shift', 'sort', 'splice', 'unshift'], function(methodName) {
18233 var func = arrayProto[methodName],
18234 chainName = /^(?:push|sort|unshift)$/.test(methodName) ? 'tap' : 'thru',
18235 retUnwrapped = /^(?:pop|shift)$/.test(methodName);
18237 lodash.prototype[methodName] = function() {
18238 var args = arguments;
18239 if (retUnwrapped && !this.__chain__) {
18240 var value = this.value();
18241 return func.apply(isArray(value) ? value : [], args);
18243 return this[chainName](function(value) {
18244 return func.apply(isArray(value) ? value : [], args);
18249 // Map minified method names to their real names.
18250 baseForOwn(LazyWrapper.prototype, function(func, methodName) {
18251 var lodashFunc = lodash[methodName];
18253 var key = lodashFunc.name + '';
18254 if (!hasOwnProperty.call(realNames, key)) {
18255 realNames[key] = [];
18257 realNames[key].push({ 'name': methodName, 'func': lodashFunc });
18261 realNames[createHybrid(undefined, WRAP_BIND_KEY_FLAG).name] = [{
18266 // Add methods to `LazyWrapper`.
18267 LazyWrapper.prototype.clone = lazyClone;
18268 LazyWrapper.prototype.reverse = lazyReverse;
18269 LazyWrapper.prototype.value = lazyValue;
18271 // Add chain sequence methods to the `lodash` wrapper.
18272 lodash.prototype.at = wrapperAt;
18273 lodash.prototype.chain = wrapperChain;
18274 lodash.prototype.commit = wrapperCommit;
18275 lodash.prototype.next = wrapperNext;
18276 lodash.prototype.plant = wrapperPlant;
18277 lodash.prototype.reverse = wrapperReverse;
18278 lodash.prototype.toJSON = lodash.prototype.valueOf = lodash.prototype.value = wrapperValue;
18280 // Add lazy aliases.
18281 lodash.prototype.first = lodash.prototype.head;
18284 lodash.prototype[symIterator] = wrapperToIterator;
18289 /*--------------------------------------------------------------------------*/
18292 var _ = runInContext();
18294 // Some AMD build optimizers, like r.js, check for condition patterns like:
18296 // Expose Lodash on the global object to prevent errors when Lodash is
18297 // loaded by a script tag in the presence of an AMD loader.
18298 // See http://requirejs.org/docs/errors.html#mismatch for more details.
18299 // Use `_.noConflict` to remove Lodash from the global object.
18302 // Define as an anonymous module so, through path mapping, it can be
18303 // referenced as the "underscore" module.
18304 !(__WEBPACK_AMD_DEFINE_RESULT__ = (function() {
18306 }).call(exports, __webpack_require__, exports, module),
18307 __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
18309 // Check for `exports` after `define` in case a build optimizer adds it.
18316 /***/ "./src/client.ts":
18317 /*!***********************!*\
18318 !*** ./src/client.ts ***!
18319 \***********************/
18320 /***/ (function(__unused_webpack_module, exports, __webpack_require__) {
18324 var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
18325 if (k2 === undefined) k2 = k;
18326 var desc = Object.getOwnPropertyDescriptor(m, k);
18327 if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
18328 desc = { enumerable: true, get: function() { return m[k]; } };
18330 Object.defineProperty(o, k2, desc);
18331 }) : (function(o, m, k, k2) {
18332 if (k2 === undefined) k2 = k;
18335 var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
18336 Object.defineProperty(o, "default", { enumerable: true, value: v });
18337 }) : function(o, v) {
18340 var __importStar = (this && this.__importStar) || function (mod) {
18341 if (mod && mod.__esModule) return mod;
18343 if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
18344 __setModuleDefault(result, mod);
18347 var __importDefault = (this && this.__importDefault) || function (mod) {
18348 return (mod && mod.__esModule) ? mod : { "default": mod };
18350 Object.defineProperty(exports, "__esModule", ({ value: true }));
18351 const outline_1 = __webpack_require__(/*! ./outline */ "./src/outline.ts");
18352 const cursor_1 = __webpack_require__(/*! ./cursor */ "./src/cursor.ts");
18353 const keyboardjs_1 = __importDefault(__webpack_require__(/*! keyboardjs */ "./node_modules/keyboardjs/dist/keyboard.js"));
18354 const rawOutline = __importStar(__webpack_require__(/*! ./test-data.json */ "./src/test-data.json"));
18355 let outlineData = rawOutline;
18356 if (localStorage.getItem('activeOutline')) {
18357 const outlineId = localStorage.getItem('activeOutline');
18358 outlineData = JSON.parse(localStorage.getItem(outlineId));
18360 const state = new Map();
18361 const outline = new outline_1.Outline(outlineData);
18362 outliner().innerHTML = outline.render();
18363 const cursor = new cursor_1.Cursor();
18364 cursor.set('.node');
18365 function outliner() {
18366 return document.querySelector('#outliner');
18368 keyboardjs_1.default.withContext('navigation', () => {
18369 keyboardjs_1.default.bind('j', e => {
18370 const sibling = cursor.get().nextElementSibling;
18373 const res = outline.swapNodeWithNextSibling(cursor.getIdOfNode());
18374 const html = outline.renderNode(res.parentNode);
18375 if (res.parentNode.id === '000000') {
18376 cursor.get().parentElement.innerHTML = html;
18379 cursor.get().parentElement.outerHTML = html;
18381 cursor.set(`#id-${res.targetNode.id}`);
18385 cursor.set(`#id-${sibling.getAttribute('data-id')}`);
18389 keyboardjs_1.default.bind('k', e => {
18390 const sibling = cursor.get().previousElementSibling;
18391 if (sibling && !sibling.classList.contains('nodeContent')) {
18393 const res = outline.swapNodeWithPreviousSibling(cursor.getIdOfNode());
18394 const html = outline.renderNode(res.parentNode);
18395 if (res.parentNode.id === '000000') {
18396 cursor.get().parentElement.innerHTML = html;
18399 cursor.get().parentElement.outerHTML = html;
18401 cursor.set(`#id-${res.targetNode.id}`);
18405 cursor.set(`#id-${sibling.getAttribute('data-id')}`);
18409 keyboardjs_1.default.bind('l', e => {
18410 if (cursor.isNodeCollapsed()) {
18414 const res = outline.lowerNodeToChild(cursor.getIdOfNode());
18415 const html = outline.renderNode(res.oldParentNode);
18416 if (res.oldParentNode.id === '000000') {
18417 cursor.get().parentElement.innerHTML = html;
18420 cursor.get().parentElement.outerHTML = html;
18422 cursor.set(`#id-${res.targetNode.id}`);
18425 const children = cursor.get().querySelector('.node');
18427 cursor.set(`#id-${children.getAttribute('data-id')}`);
18431 keyboardjs_1.default.bind('h', e => {
18432 const parent = cursor.get().parentElement;
18433 if (parent && parent.classList.contains('node')) {
18435 if (outline.data.tree.children.map(n => n.id).includes(cursor.getIdOfNode())) {
18438 const res = outline.liftNodeToParent(cursor.getIdOfNode());
18439 const html = outline.renderNode(res.parentNode);
18440 if (res.parentNode.id === '000000') {
18441 cursor.get().parentElement.parentElement.innerHTML = html;
18444 cursor.get().parentElement.parentElement.outerHTML = html;
18446 cursor.set(`#id-${res.targetNode.id}`);
18450 cursor.set(`#id-${parent.getAttribute('data-id')}`);
18454 keyboardjs_1.default.bind('z', e => {
18455 if (cursor.isNodeExpanded()) {
18457 outline.fold(cursor.getIdOfNode());
18459 else if (cursor.isNodeCollapsed()) {
18461 outline.unfold(cursor.getIdOfNode());
18465 keyboardjs_1.default.bind('i', e => {
18466 e.preventDefault();
18467 cursor.get().classList.add('hidden-cursor');
18468 const contentNode = cursor.get().querySelector('.nodeContent');
18469 contentNode.innerHTML = outline.data.contentNodes[cursor.getIdOfNode()].content;
18470 contentNode.contentEditable = "true";
18471 contentNode.focus();
18472 keyboardjs_1.default.setContext('editing');
18474 keyboardjs_1.default.bind('tab', e => {
18475 e.preventDefault();
18476 const res = outline.createChildNode(cursor.getIdOfNode());
18477 const html = outline.renderNode(res.parentNode);
18478 cursor.get().outerHTML = html;
18479 cursor.set(`#id-${res.node.id}`);
18482 keyboardjs_1.default.bind('enter', e => {
18486 e.preventDefault();
18488 const res = outline.createSiblingNode(cursor.getIdOfNode());
18489 const html = outline.renderNode(res.parentNode);
18490 if (res.parentNode.id === '000000') {
18491 cursor.get().parentElement.innerHTML = html;
18494 cursor.get().parentElement.outerHTML = html;
18496 cursor.set(`#id-${res.node.id}`);
18499 keyboardjs_1.default.bind('d', e => {
18503 const res = outline.removeNode(cursor.getIdOfNode());
18504 const html = outline.renderNode(res.parentNode);
18505 const prevSibling = cursor.get().previousElementSibling;
18506 const nextSibling = cursor.get().nextElementSibling;
18507 if (res.parentNode.id === '000000') {
18508 cursor.get().parentElement.innerHTML = html;
18511 cursor.get().parentElement.outerHTML = html;
18513 if (prevSibling.getAttribute('data-id')) {
18514 cursor.set(`#id-${prevSibling.getAttribute('data-id')}`);
18516 else if (nextSibling.getAttribute('data-id')) {
18517 cursor.set(`#id-${nextSibling.getAttribute('data-id')}`);
18520 console.log(res.parentNode.id);
18521 cursor.set(`#id-${res.parentNode.id}`);
18526 keyboardjs_1.default.withContext('editing', () => {
18527 keyboardjs_1.default.bind(['esc', 'enter'], e => {
18528 cursor.get().classList.remove('hidden-cursor');
18529 const contentNode = cursor.get().querySelector('.nodeContent');
18530 contentNode.contentEditable = "false";
18531 contentNode.blur();
18532 keyboardjs_1.default.setContext('navigation');
18533 outline.updateContent(cursor.getIdOfNode(), contentNode.innerHTML.trim());
18534 contentNode.innerHTML = outline.renderContent(cursor.getIdOfNode());
18538 keyboardjs_1.default.setContext('navigation');
18539 function saveImmediate() {
18540 localStorage.setItem(outline.data.id, JSON.stringify(outline.data));
18541 localStorage.setItem('activeOutline', outline.data.id);
18542 console.log('saved...', outline.data);
18543 state.delete('saveTimeout');
18546 if (!state.has('saveTimeout')) {
18547 state.set('saveTimeout', setTimeout(saveImmediate, 2000));
18555 /***/ "./src/cursor.ts":
18556 /*!***********************!*\
18557 !*** ./src/cursor.ts ***!
18558 \***********************/
18559 /***/ ((__unused_webpack_module, exports) => {
18563 Object.defineProperty(exports, "__esModule", ({ value: true }));
18564 exports.Cursor = void 0;
18569 return document.querySelector('.cursor');
18572 return this.get().getAttribute('data-id');
18575 const el = this.get();
18577 el.classList.remove('cursor');
18582 const el = document.querySelector(elementId);
18584 el.classList.add('cursor');
18585 if (!this.isVisible(elementId)) {
18586 el.scrollIntoView(true);
18591 this.get().classList.remove('expanded');
18592 this.get().classList.add('collapsed');
18595 this.get().classList.remove('collapsed');
18596 this.get().classList.add('expanded');
18598 isNodeCollapsed() {
18599 return this.get().classList.contains('collapsed');
18602 return this.get().classList.contains('expanded');
18604 isVisible(elementId) {
18605 const el = document.querySelector(elementId);
18606 var rect = el.getBoundingClientRect();
18607 return (rect.top >= 0 &&
18609 rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) &&
18610 rect.right <= (window.innerWidth || document.documentElement.clientWidth));
18613 exports.Cursor = Cursor;
18618 /***/ "./src/outline.ts":
18619 /*!************************!*\
18620 !*** ./src/outline.ts ***!
18621 \************************/
18622 /***/ (function(__unused_webpack_module, exports, __webpack_require__) {
18626 var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
18627 if (k2 === undefined) k2 = k;
18628 var desc = Object.getOwnPropertyDescriptor(m, k);
18629 if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
18630 desc = { enumerable: true, get: function() { return m[k]; } };
18632 Object.defineProperty(o, k2, desc);
18633 }) : (function(o, m, k, k2) {
18634 if (k2 === undefined) k2 = k;
18637 var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
18638 Object.defineProperty(o, "default", { enumerable: true, value: v });
18639 }) : function(o, v) {
18642 var __importStar = (this && this.__importStar) || function (mod) {
18643 if (mod && mod.__esModule) return mod;
18645 if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
18646 __setModuleDefault(result, mod);
18649 Object.defineProperty(exports, "__esModule", ({ value: true }));
18650 exports.Outline = void 0;
18651 const _ = __importStar(__webpack_require__(/*! lodash */ "./node_modules/lodash/lodash.js"));
18652 const uuid_1 = __webpack_require__(/*! uuid */ "./node_modules/uuid/dist/commonjs-browser/index.js");
18653 const marked_1 = __webpack_require__(/*! marked */ "./node_modules/marked/lib/marked.cjs");
18656 constructor(outlineData) {
18657 this.data = outlineData;
18659 findNodeInTree(root, id, action, runState = false) {
18660 let run = runState;
18664 _.each(root.children, (childNode, idx) => {
18665 if (childNode.id === id) {
18666 action(childNode, root);
18670 else if (childNode.children) {
18671 this.findNodeInTree(childNode, id, action, run);
18676 this.findNodeInTree(this.data.tree, nodeId, item => {
18677 item.collapsed = true;
18681 this.findNodeInTree(this.data.tree, nodeId, item => {
18682 item.collapsed = true;
18685 flattenOutlineTreeChildren(tree) {
18686 return tree.children.map(node => node.id);
18688 liftNodeToParent(nodeId) {
18690 let targetNode, parentNode;
18691 this.findNodeInTree(this.data.tree, nodeId, (tNode, pNode) => {
18692 targetNode = tNode;
18693 this.findNodeInTree(this.data.tree, pNode.id, (originalParentNode, newParentNode) => {
18698 parentNode = newParentNode;
18700 const flatId = newParentNode.children.map(n => n.id);
18701 const originalNodePosition = originalParentNode.children.map(n => n.id).indexOf(targetNode.id);
18702 const newNodePosition = flatId.indexOf(originalParentNode.id);
18703 originalParentNode.children.splice(originalNodePosition, 1);
18704 newParentNode.children.splice(newNodePosition + 1, 0, targetNode);
18712 lowerNodeToChild(nodeId) {
18714 let targetNode, newParentNode, oldParentNode;
18715 this.findNodeInTree(this.data.tree, nodeId, (tNode, pNode) => {
18720 targetNode = tNode;
18721 let idList = pNode.children.map(n => n.id);
18722 if (idList.length === 1) {
18725 const position = idList.indexOf(targetNode.id);
18726 const prevSiblingPosition = position - 1;
18727 pNode.children[prevSiblingPosition].children.splice(0, 0, targetNode);
18728 pNode.children.splice(position, 1);
18729 newParentNode = pNode.children[prevSiblingPosition];
18730 oldParentNode = pNode;
18738 swapNodeWithNextSibling(nodeId) {
18739 let targetNode, parentNode;
18740 this.findNodeInTree(this.data.tree, nodeId, (tNode, pNode) => {
18741 targetNode = tNode;
18742 parentNode = pNode;
18743 const flatId = parentNode.children.map(n => n.id);
18744 const nodePosition = flatId.indexOf(targetNode.id);
18745 if (nodePosition === (flatId.length - 1)) {
18748 parentNode.children.splice(nodePosition, 1);
18749 parentNode.children.splice(nodePosition + 1, 0, targetNode);
18756 swapNodeWithPreviousSibling(nodeId) {
18757 let targetNode, parentNode;
18758 this.findNodeInTree(this.data.tree, nodeId, (tNode, pNode) => {
18759 targetNode = tNode;
18760 parentNode = pNode;
18761 const flatId = parentNode.children.map(n => n.id);
18762 const nodePosition = flatId.indexOf(targetNode.id);
18763 if (nodePosition === 0) {
18766 parentNode.children.splice(nodePosition, 1);
18767 parentNode.children.splice(nodePosition - 1, 0, targetNode);
18774 createSiblingNode(targetNode, nodeData) {
18775 const outlineNode = nodeData || {
18776 id: (0, uuid_1.v4)(),
18777 created: Date.now(),
18781 this.data.contentNodes[outlineNode.id] = outlineNode;
18783 this.findNodeInTree(this.data.tree, targetNode, (node, parent) => {
18784 const position = parent.children.map(n => n.id).indexOf(targetNode);
18785 parent.children.splice(position + 1, 0, {
18786 id: outlineNode.id,
18790 parentNode = parent;
18797 createChildNode(currentNode, nodeId) {
18798 const node = nodeId ? this.data.contentNodes[nodeId] :
18800 id: (0, uuid_1.v4)(),
18801 created: Date.now(),
18806 this.data.contentNodes[node.id] = node;
18809 this.findNodeInTree(this.data.tree, currentNode, (foundNode, parent) => {
18810 foundNode.children.unshift({
18815 parentNode = foundNode;
18822 removeNode(nodeId) {
18824 let removedNode, parentNode;
18825 this.findNodeInTree(this.data.tree, nodeId, (tNode, pNode) => {
18830 removedNode = tNode;
18831 parentNode = pNode;
18832 let position = parentNode.children.map(n => n.id).indexOf(tNode.id);
18833 parentNode.children.splice(position, 1);
18840 updateContent(id, content) {
18841 if (!this.data.contentNodes[id]) {
18842 throw new Error('Invalid node');
18844 this.data.contentNodes[id].content = content;
18846 renderContent(nodeId) {
18847 let node = this.data.contentNodes[nodeId];
18849 switch (node.type) {
18851 content = marked_1.marked.parse(node.content);
18854 content = node.content;
18860 if (node.id === '000000') {
18861 return this.render();
18863 const collapse = node.collapsed ? 'collapsed' : 'expanded';
18864 const content = this.data.contentNodes[node.id] || {
18866 created: Date.now(),
18870 let html = `<div class="node ${collapse}" data-id="${node.id}" id="id-${node.id}">
18871 <div class="nodeContent" data-type="${content.type}">
18872 ${this.renderContent(node.id)}
18874 ${node.children.length ? _.map(node.children, this.renderNode.bind(this)).join("\n") : ''}
18879 return _.map(this.data.tree.children, this.renderNode.bind(this)).join("\n");
18882 exports.Outline = Outline;
18887 /***/ "./node_modules/uuid/dist/commonjs-browser/index.js":
18888 /*!**********************************************************!*\
18889 !*** ./node_modules/uuid/dist/commonjs-browser/index.js ***!
18890 \**********************************************************/
18891 /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
18896 Object.defineProperty(exports, "__esModule", ({
18899 Object.defineProperty(exports, "NIL", ({
18901 get: function get() {
18902 return _nil.default;
18905 Object.defineProperty(exports, "parse", ({
18907 get: function get() {
18908 return _parse.default;
18911 Object.defineProperty(exports, "stringify", ({
18913 get: function get() {
18914 return _stringify.default;
18917 Object.defineProperty(exports, "v1", ({
18919 get: function get() {
18923 Object.defineProperty(exports, "v3", ({
18925 get: function get() {
18926 return _v2.default;
18929 Object.defineProperty(exports, "v4", ({
18931 get: function get() {
18932 return _v3.default;
18935 Object.defineProperty(exports, "v5", ({
18937 get: function get() {
18938 return _v4.default;
18941 Object.defineProperty(exports, "validate", ({
18943 get: function get() {
18944 return _validate.default;
18947 Object.defineProperty(exports, "version", ({
18949 get: function get() {
18950 return _version.default;
18954 var _v = _interopRequireDefault(__webpack_require__(/*! ./v1.js */ "./node_modules/uuid/dist/commonjs-browser/v1.js"));
18956 var _v2 = _interopRequireDefault(__webpack_require__(/*! ./v3.js */ "./node_modules/uuid/dist/commonjs-browser/v3.js"));
18958 var _v3 = _interopRequireDefault(__webpack_require__(/*! ./v4.js */ "./node_modules/uuid/dist/commonjs-browser/v4.js"));
18960 var _v4 = _interopRequireDefault(__webpack_require__(/*! ./v5.js */ "./node_modules/uuid/dist/commonjs-browser/v5.js"));
18962 var _nil = _interopRequireDefault(__webpack_require__(/*! ./nil.js */ "./node_modules/uuid/dist/commonjs-browser/nil.js"));
18964 var _version = _interopRequireDefault(__webpack_require__(/*! ./version.js */ "./node_modules/uuid/dist/commonjs-browser/version.js"));
18966 var _validate = _interopRequireDefault(__webpack_require__(/*! ./validate.js */ "./node_modules/uuid/dist/commonjs-browser/validate.js"));
18968 var _stringify = _interopRequireDefault(__webpack_require__(/*! ./stringify.js */ "./node_modules/uuid/dist/commonjs-browser/stringify.js"));
18970 var _parse = _interopRequireDefault(__webpack_require__(/*! ./parse.js */ "./node_modules/uuid/dist/commonjs-browser/parse.js"));
18972 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
18976 /***/ "./node_modules/uuid/dist/commonjs-browser/md5.js":
18977 /*!********************************************************!*\
18978 !*** ./node_modules/uuid/dist/commonjs-browser/md5.js ***!
18979 \********************************************************/
18980 /***/ ((__unused_webpack_module, exports) => {
18985 Object.defineProperty(exports, "__esModule", ({
18988 exports["default"] = void 0;
18991 * Browser-compatible JavaScript MD5
18993 * Modification of JavaScript MD5
18994 * https://github.com/blueimp/JavaScript-MD5
18996 * Copyright 2011, Sebastian Tschan
18997 * https://blueimp.net
18999 * Licensed under the MIT license:
19000 * https://opensource.org/licenses/MIT
19003 * A JavaScript implementation of the RSA Data Security, Inc. MD5 Message
19004 * Digest Algorithm, as defined in RFC 1321.
19005 * Version 2.2 Copyright (C) Paul Johnston 1999 - 2009
19006 * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
19007 * Distributed under the BSD License
19008 * See http://pajhome.org.uk/crypt/md5 for more info.
19010 function md5(bytes) {
19011 if (typeof bytes === 'string') {
19012 const msg = unescape(encodeURIComponent(bytes)); // UTF8 escape
19014 bytes = new Uint8Array(msg.length);
19016 for (let i = 0; i < msg.length; ++i) {
19017 bytes[i] = msg.charCodeAt(i);
19021 return md5ToHexEncodedArray(wordsToMd5(bytesToWords(bytes), bytes.length * 8));
19024 * Convert an array of little-endian words to an array of bytes
19028 function md5ToHexEncodedArray(input) {
19030 const length32 = input.length * 32;
19031 const hexTab = '0123456789abcdef';
19033 for (let i = 0; i < length32; i += 8) {
19034 const x = input[i >> 5] >>> i % 32 & 0xff;
19035 const hex = parseInt(hexTab.charAt(x >>> 4 & 0x0f) + hexTab.charAt(x & 0x0f), 16);
19042 * Calculate output length with padding and bit length
19046 function getOutputLength(inputLength8) {
19047 return (inputLength8 + 64 >>> 9 << 4) + 14 + 1;
19050 * Calculate the MD5 of an array of little-endian words, and a bit length.
19054 function wordsToMd5(x, len) {
19055 /* append padding */
19056 x[len >> 5] |= 0x80 << len % 32;
19057 x[getOutputLength(len) - 1] = len;
19058 let a = 1732584193;
19059 let b = -271733879;
19060 let c = -1732584194;
19063 for (let i = 0; i < x.length; i += 16) {
19068 a = md5ff(a, b, c, d, x[i], 7, -680876936);
19069 d = md5ff(d, a, b, c, x[i + 1], 12, -389564586);
19070 c = md5ff(c, d, a, b, x[i + 2], 17, 606105819);
19071 b = md5ff(b, c, d, a, x[i + 3], 22, -1044525330);
19072 a = md5ff(a, b, c, d, x[i + 4], 7, -176418897);
19073 d = md5ff(d, a, b, c, x[i + 5], 12, 1200080426);
19074 c = md5ff(c, d, a, b, x[i + 6], 17, -1473231341);
19075 b = md5ff(b, c, d, a, x[i + 7], 22, -45705983);
19076 a = md5ff(a, b, c, d, x[i + 8], 7, 1770035416);
19077 d = md5ff(d, a, b, c, x[i + 9], 12, -1958414417);
19078 c = md5ff(c, d, a, b, x[i + 10], 17, -42063);
19079 b = md5ff(b, c, d, a, x[i + 11], 22, -1990404162);
19080 a = md5ff(a, b, c, d, x[i + 12], 7, 1804603682);
19081 d = md5ff(d, a, b, c, x[i + 13], 12, -40341101);
19082 c = md5ff(c, d, a, b, x[i + 14], 17, -1502002290);
19083 b = md5ff(b, c, d, a, x[i + 15], 22, 1236535329);
19084 a = md5gg(a, b, c, d, x[i + 1], 5, -165796510);
19085 d = md5gg(d, a, b, c, x[i + 6], 9, -1069501632);
19086 c = md5gg(c, d, a, b, x[i + 11], 14, 643717713);
19087 b = md5gg(b, c, d, a, x[i], 20, -373897302);
19088 a = md5gg(a, b, c, d, x[i + 5], 5, -701558691);
19089 d = md5gg(d, a, b, c, x[i + 10], 9, 38016083);
19090 c = md5gg(c, d, a, b, x[i + 15], 14, -660478335);
19091 b = md5gg(b, c, d, a, x[i + 4], 20, -405537848);
19092 a = md5gg(a, b, c, d, x[i + 9], 5, 568446438);
19093 d = md5gg(d, a, b, c, x[i + 14], 9, -1019803690);
19094 c = md5gg(c, d, a, b, x[i + 3], 14, -187363961);
19095 b = md5gg(b, c, d, a, x[i + 8], 20, 1163531501);
19096 a = md5gg(a, b, c, d, x[i + 13], 5, -1444681467);
19097 d = md5gg(d, a, b, c, x[i + 2], 9, -51403784);
19098 c = md5gg(c, d, a, b, x[i + 7], 14, 1735328473);
19099 b = md5gg(b, c, d, a, x[i + 12], 20, -1926607734);
19100 a = md5hh(a, b, c, d, x[i + 5], 4, -378558);
19101 d = md5hh(d, a, b, c, x[i + 8], 11, -2022574463);
19102 c = md5hh(c, d, a, b, x[i + 11], 16, 1839030562);
19103 b = md5hh(b, c, d, a, x[i + 14], 23, -35309556);
19104 a = md5hh(a, b, c, d, x[i + 1], 4, -1530992060);
19105 d = md5hh(d, a, b, c, x[i + 4], 11, 1272893353);
19106 c = md5hh(c, d, a, b, x[i + 7], 16, -155497632);
19107 b = md5hh(b, c, d, a, x[i + 10], 23, -1094730640);
19108 a = md5hh(a, b, c, d, x[i + 13], 4, 681279174);
19109 d = md5hh(d, a, b, c, x[i], 11, -358537222);
19110 c = md5hh(c, d, a, b, x[i + 3], 16, -722521979);
19111 b = md5hh(b, c, d, a, x[i + 6], 23, 76029189);
19112 a = md5hh(a, b, c, d, x[i + 9], 4, -640364487);
19113 d = md5hh(d, a, b, c, x[i + 12], 11, -421815835);
19114 c = md5hh(c, d, a, b, x[i + 15], 16, 530742520);
19115 b = md5hh(b, c, d, a, x[i + 2], 23, -995338651);
19116 a = md5ii(a, b, c, d, x[i], 6, -198630844);
19117 d = md5ii(d, a, b, c, x[i + 7], 10, 1126891415);
19118 c = md5ii(c, d, a, b, x[i + 14], 15, -1416354905);
19119 b = md5ii(b, c, d, a, x[i + 5], 21, -57434055);
19120 a = md5ii(a, b, c, d, x[i + 12], 6, 1700485571);
19121 d = md5ii(d, a, b, c, x[i + 3], 10, -1894986606);
19122 c = md5ii(c, d, a, b, x[i + 10], 15, -1051523);
19123 b = md5ii(b, c, d, a, x[i + 1], 21, -2054922799);
19124 a = md5ii(a, b, c, d, x[i + 8], 6, 1873313359);
19125 d = md5ii(d, a, b, c, x[i + 15], 10, -30611744);
19126 c = md5ii(c, d, a, b, x[i + 6], 15, -1560198380);
19127 b = md5ii(b, c, d, a, x[i + 13], 21, 1309151649);
19128 a = md5ii(a, b, c, d, x[i + 4], 6, -145523070);
19129 d = md5ii(d, a, b, c, x[i + 11], 10, -1120210379);
19130 c = md5ii(c, d, a, b, x[i + 2], 15, 718787259);
19131 b = md5ii(b, c, d, a, x[i + 9], 21, -343485551);
19132 a = safeAdd(a, olda);
19133 b = safeAdd(b, oldb);
19134 c = safeAdd(c, oldc);
19135 d = safeAdd(d, oldd);
19138 return [a, b, c, d];
19141 * Convert an array bytes to an array of little-endian words
19142 * Characters >255 have their high-byte silently ignored.
19146 function bytesToWords(input) {
19147 if (input.length === 0) {
19151 const length8 = input.length * 8;
19152 const output = new Uint32Array(getOutputLength(length8));
19154 for (let i = 0; i < length8; i += 8) {
19155 output[i >> 5] |= (input[i / 8] & 0xff) << i % 32;
19161 * Add integers, wrapping at 2^32. This uses 16-bit operations internally
19162 * to work around bugs in some JS interpreters.
19166 function safeAdd(x, y) {
19167 const lsw = (x & 0xffff) + (y & 0xffff);
19168 const msw = (x >> 16) + (y >> 16) + (lsw >> 16);
19169 return msw << 16 | lsw & 0xffff;
19172 * Bitwise rotate a 32-bit number to the left.
19176 function bitRotateLeft(num, cnt) {
19177 return num << cnt | num >>> 32 - cnt;
19180 * These functions implement the four basic operations the algorithm uses.
19184 function md5cmn(q, a, b, x, s, t) {
19185 return safeAdd(bitRotateLeft(safeAdd(safeAdd(a, q), safeAdd(x, t)), s), b);
19188 function md5ff(a, b, c, d, x, s, t) {
19189 return md5cmn(b & c | ~b & d, a, b, x, s, t);
19192 function md5gg(a, b, c, d, x, s, t) {
19193 return md5cmn(b & d | c & ~d, a, b, x, s, t);
19196 function md5hh(a, b, c, d, x, s, t) {
19197 return md5cmn(b ^ c ^ d, a, b, x, s, t);
19200 function md5ii(a, b, c, d, x, s, t) {
19201 return md5cmn(c ^ (b | ~d), a, b, x, s, t);
19204 var _default = md5;
19205 exports["default"] = _default;
19209 /***/ "./node_modules/uuid/dist/commonjs-browser/native.js":
19210 /*!***********************************************************!*\
19211 !*** ./node_modules/uuid/dist/commonjs-browser/native.js ***!
19212 \***********************************************************/
19213 /***/ ((__unused_webpack_module, exports) => {
19218 Object.defineProperty(exports, "__esModule", ({
19221 exports["default"] = void 0;
19222 const randomUUID = typeof crypto !== 'undefined' && crypto.randomUUID && crypto.randomUUID.bind(crypto);
19226 exports["default"] = _default;
19230 /***/ "./node_modules/uuid/dist/commonjs-browser/nil.js":
19231 /*!********************************************************!*\
19232 !*** ./node_modules/uuid/dist/commonjs-browser/nil.js ***!
19233 \********************************************************/
19234 /***/ ((__unused_webpack_module, exports) => {
19239 Object.defineProperty(exports, "__esModule", ({
19242 exports["default"] = void 0;
19243 var _default = '00000000-0000-0000-0000-000000000000';
19244 exports["default"] = _default;
19248 /***/ "./node_modules/uuid/dist/commonjs-browser/parse.js":
19249 /*!**********************************************************!*\
19250 !*** ./node_modules/uuid/dist/commonjs-browser/parse.js ***!
19251 \**********************************************************/
19252 /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
19257 Object.defineProperty(exports, "__esModule", ({
19260 exports["default"] = void 0;
19262 var _validate = _interopRequireDefault(__webpack_require__(/*! ./validate.js */ "./node_modules/uuid/dist/commonjs-browser/validate.js"));
19264 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
19266 function parse(uuid) {
19267 if (!(0, _validate.default)(uuid)) {
19268 throw TypeError('Invalid UUID');
19272 const arr = new Uint8Array(16); // Parse ########-....-....-....-............
19274 arr[0] = (v = parseInt(uuid.slice(0, 8), 16)) >>> 24;
19275 arr[1] = v >>> 16 & 0xff;
19276 arr[2] = v >>> 8 & 0xff;
19277 arr[3] = v & 0xff; // Parse ........-####-....-....-............
19279 arr[4] = (v = parseInt(uuid.slice(9, 13), 16)) >>> 8;
19280 arr[5] = v & 0xff; // Parse ........-....-####-....-............
19282 arr[6] = (v = parseInt(uuid.slice(14, 18), 16)) >>> 8;
19283 arr[7] = v & 0xff; // Parse ........-....-....-####-............
19285 arr[8] = (v = parseInt(uuid.slice(19, 23), 16)) >>> 8;
19286 arr[9] = v & 0xff; // Parse ........-....-....-....-############
19287 // (Use "/" to avoid 32-bit truncation when bit-shifting high-order bytes)
19289 arr[10] = (v = parseInt(uuid.slice(24, 36), 16)) / 0x10000000000 & 0xff;
19290 arr[11] = v / 0x100000000 & 0xff;
19291 arr[12] = v >>> 24 & 0xff;
19292 arr[13] = v >>> 16 & 0xff;
19293 arr[14] = v >>> 8 & 0xff;
19294 arr[15] = v & 0xff;
19298 var _default = parse;
19299 exports["default"] = _default;
19303 /***/ "./node_modules/uuid/dist/commonjs-browser/regex.js":
19304 /*!**********************************************************!*\
19305 !*** ./node_modules/uuid/dist/commonjs-browser/regex.js ***!
19306 \**********************************************************/
19307 /***/ ((__unused_webpack_module, exports) => {
19312 Object.defineProperty(exports, "__esModule", ({
19315 exports["default"] = void 0;
19316 var _default = /^(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000)$/i;
19317 exports["default"] = _default;
19321 /***/ "./node_modules/uuid/dist/commonjs-browser/rng.js":
19322 /*!********************************************************!*\
19323 !*** ./node_modules/uuid/dist/commonjs-browser/rng.js ***!
19324 \********************************************************/
19325 /***/ ((__unused_webpack_module, exports) => {
19330 Object.defineProperty(exports, "__esModule", ({
19333 exports["default"] = rng;
19334 // Unique ID creation requires a high quality random # generator. In the browser we therefore
19335 // require the crypto API and do not support built-in fallback to lower quality random number
19336 // generators (like Math.random()).
19337 let getRandomValues;
19338 const rnds8 = new Uint8Array(16);
19341 // lazy load so that environments that need to polyfill have a chance to do so
19342 if (!getRandomValues) {
19343 // getRandomValues needs to be invoked in a context where "this" is a Crypto implementation.
19344 getRandomValues = typeof crypto !== 'undefined' && crypto.getRandomValues && crypto.getRandomValues.bind(crypto);
19346 if (!getRandomValues) {
19347 throw new Error('crypto.getRandomValues() not supported. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported');
19351 return getRandomValues(rnds8);
19356 /***/ "./node_modules/uuid/dist/commonjs-browser/sha1.js":
19357 /*!*********************************************************!*\
19358 !*** ./node_modules/uuid/dist/commonjs-browser/sha1.js ***!
19359 \*********************************************************/
19360 /***/ ((__unused_webpack_module, exports) => {
19365 Object.defineProperty(exports, "__esModule", ({
19368 exports["default"] = void 0;
19370 // Adapted from Chris Veness' SHA1 code at
19371 // http://www.movable-type.co.uk/scripts/sha1.html
19372 function f(s, x, y, z) {
19375 return x & y ^ ~x & z;
19381 return x & y ^ x & z ^ y & z;
19388 function ROTL(x, n) {
19389 return x << n | x >>> 32 - n;
19392 function sha1(bytes) {
19393 const K = [0x5a827999, 0x6ed9eba1, 0x8f1bbcdc, 0xca62c1d6];
19394 const H = [0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0];
19396 if (typeof bytes === 'string') {
19397 const msg = unescape(encodeURIComponent(bytes)); // UTF8 escape
19401 for (let i = 0; i < msg.length; ++i) {
19402 bytes.push(msg.charCodeAt(i));
19404 } else if (!Array.isArray(bytes)) {
19405 // Convert Array-like to Array
19406 bytes = Array.prototype.slice.call(bytes);
19410 const l = bytes.length / 4 + 2;
19411 const N = Math.ceil(l / 16);
19412 const M = new Array(N);
19414 for (let i = 0; i < N; ++i) {
19415 const arr = new Uint32Array(16);
19417 for (let j = 0; j < 16; ++j) {
19418 arr[j] = bytes[i * 64 + j * 4] << 24 | bytes[i * 64 + j * 4 + 1] << 16 | bytes[i * 64 + j * 4 + 2] << 8 | bytes[i * 64 + j * 4 + 3];
19424 M[N - 1][14] = (bytes.length - 1) * 8 / Math.pow(2, 32);
19425 M[N - 1][14] = Math.floor(M[N - 1][14]);
19426 M[N - 1][15] = (bytes.length - 1) * 8 & 0xffffffff;
19428 for (let i = 0; i < N; ++i) {
19429 const W = new Uint32Array(80);
19431 for (let t = 0; t < 16; ++t) {
19435 for (let t = 16; t < 80; ++t) {
19436 W[t] = ROTL(W[t - 3] ^ W[t - 8] ^ W[t - 14] ^ W[t - 16], 1);
19445 for (let t = 0; t < 80; ++t) {
19446 const s = Math.floor(t / 20);
19447 const T = ROTL(a, 5) + f(s, b, c, d) + e + K[s] + W[t] >>> 0;
19450 c = ROTL(b, 30) >>> 0;
19455 H[0] = H[0] + a >>> 0;
19456 H[1] = H[1] + b >>> 0;
19457 H[2] = H[2] + c >>> 0;
19458 H[3] = H[3] + d >>> 0;
19459 H[4] = H[4] + e >>> 0;
19462 return [H[0] >> 24 & 0xff, H[0] >> 16 & 0xff, H[0] >> 8 & 0xff, H[0] & 0xff, H[1] >> 24 & 0xff, H[1] >> 16 & 0xff, H[1] >> 8 & 0xff, H[1] & 0xff, H[2] >> 24 & 0xff, H[2] >> 16 & 0xff, H[2] >> 8 & 0xff, H[2] & 0xff, H[3] >> 24 & 0xff, H[3] >> 16 & 0xff, H[3] >> 8 & 0xff, H[3] & 0xff, H[4] >> 24 & 0xff, H[4] >> 16 & 0xff, H[4] >> 8 & 0xff, H[4] & 0xff];
19465 var _default = sha1;
19466 exports["default"] = _default;
19470 /***/ "./node_modules/uuid/dist/commonjs-browser/stringify.js":
19471 /*!**************************************************************!*\
19472 !*** ./node_modules/uuid/dist/commonjs-browser/stringify.js ***!
19473 \**************************************************************/
19474 /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
19479 Object.defineProperty(exports, "__esModule", ({
19482 exports["default"] = void 0;
19483 exports.unsafeStringify = unsafeStringify;
19485 var _validate = _interopRequireDefault(__webpack_require__(/*! ./validate.js */ "./node_modules/uuid/dist/commonjs-browser/validate.js"));
19487 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
19490 * Convert array of 16 byte values to UUID string format of the form:
19491 * XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
19493 const byteToHex = [];
19495 for (let i = 0; i < 256; ++i) {
19496 byteToHex.push((i + 0x100).toString(16).slice(1));
19499 function unsafeStringify(arr, offset = 0) {
19500 // Note: Be careful editing this code! It's been tuned for performance
19501 // and works in ways you may not expect. See https://github.com/uuidjs/uuid/pull/434
19502 return (byteToHex[arr[offset + 0]] + byteToHex[arr[offset + 1]] + byteToHex[arr[offset + 2]] + byteToHex[arr[offset + 3]] + '-' + byteToHex[arr[offset + 4]] + byteToHex[arr[offset + 5]] + '-' + byteToHex[arr[offset + 6]] + byteToHex[arr[offset + 7]] + '-' + byteToHex[arr[offset + 8]] + byteToHex[arr[offset + 9]] + '-' + byteToHex[arr[offset + 10]] + byteToHex[arr[offset + 11]] + byteToHex[arr[offset + 12]] + byteToHex[arr[offset + 13]] + byteToHex[arr[offset + 14]] + byteToHex[arr[offset + 15]]).toLowerCase();
19505 function stringify(arr, offset = 0) {
19506 const uuid = unsafeStringify(arr, offset); // Consistency check for valid UUID. If this throws, it's likely due to one
19507 // of the following:
19508 // - One or more input array values don't map to a hex octet (leading to
19509 // "undefined" in the uuid)
19510 // - Invalid input values for the RFC `version` or `variant` fields
19512 if (!(0, _validate.default)(uuid)) {
19513 throw TypeError('Stringified UUID is invalid');
19519 var _default = stringify;
19520 exports["default"] = _default;
19524 /***/ "./node_modules/uuid/dist/commonjs-browser/v1.js":
19525 /*!*******************************************************!*\
19526 !*** ./node_modules/uuid/dist/commonjs-browser/v1.js ***!
19527 \*******************************************************/
19528 /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
19533 Object.defineProperty(exports, "__esModule", ({
19536 exports["default"] = void 0;
19538 var _rng = _interopRequireDefault(__webpack_require__(/*! ./rng.js */ "./node_modules/uuid/dist/commonjs-browser/rng.js"));
19540 var _stringify = __webpack_require__(/*! ./stringify.js */ "./node_modules/uuid/dist/commonjs-browser/stringify.js");
19542 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
19544 // **`v1()` - Generate time-based UUID**
19546 // Inspired by https://github.com/LiosK/UUID.js
19547 // and http://docs.python.org/library/uuid.html
19550 let _clockseq; // Previous uuid creation time
19553 let _lastMSecs = 0;
19554 let _lastNSecs = 0; // See https://github.com/uuidjs/uuid for API details
19556 function v1(options, buf, offset) {
19557 let i = buf && offset || 0;
19558 const b = buf || new Array(16);
19559 options = options || {};
19560 let node = options.node || _nodeId;
19561 let clockseq = options.clockseq !== undefined ? options.clockseq : _clockseq; // node and clockseq need to be initialized to random values if they're not
19562 // specified. We do this lazily to minimize issues related to insufficient
19563 // system entropy. See #189
19565 if (node == null || clockseq == null) {
19566 const seedBytes = options.random || (options.rng || _rng.default)();
19568 if (node == null) {
19569 // Per 4.5, create and 48-bit node id, (47 random bits + multicast bit = 1)
19570 node = _nodeId = [seedBytes[0] | 0x01, seedBytes[1], seedBytes[2], seedBytes[3], seedBytes[4], seedBytes[5]];
19573 if (clockseq == null) {
19574 // Per 4.2.2, randomize (14 bit) clockseq
19575 clockseq = _clockseq = (seedBytes[6] << 8 | seedBytes[7]) & 0x3fff;
19577 } // UUID timestamps are 100 nano-second units since the Gregorian epoch,
19578 // (1582-10-15 00:00). JSNumbers aren't precise enough for this, so
19579 // time is handled internally as 'msecs' (integer milliseconds) and 'nsecs'
19580 // (100-nanoseconds offset from msecs) since unix epoch, 1970-01-01 00:00.
19583 let msecs = options.msecs !== undefined ? options.msecs : Date.now(); // Per 4.2.1.2, use count of uuid's generated during the current clock
19584 // cycle to simulate higher resolution clock
19586 let nsecs = options.nsecs !== undefined ? options.nsecs : _lastNSecs + 1; // Time since last uuid creation (in msecs)
19588 const dt = msecs - _lastMSecs + (nsecs - _lastNSecs) / 10000; // Per 4.2.1.2, Bump clockseq on clock regression
19590 if (dt < 0 && options.clockseq === undefined) {
19591 clockseq = clockseq + 1 & 0x3fff;
19592 } // Reset nsecs if clock regresses (new clockseq) or we've moved onto a new
19596 if ((dt < 0 || msecs > _lastMSecs) && options.nsecs === undefined) {
19598 } // Per 4.2.1.2 Throw error if too many uuids are requested
19601 if (nsecs >= 10000) {
19602 throw new Error("uuid.v1(): Can't create more than 10M uuids/sec");
19605 _lastMSecs = msecs;
19606 _lastNSecs = nsecs;
19607 _clockseq = clockseq; // Per 4.1.4 - Convert from unix epoch to Gregorian epoch
19609 msecs += 12219292800000; // `time_low`
19611 const tl = ((msecs & 0xfffffff) * 10000 + nsecs) % 0x100000000;
19612 b[i++] = tl >>> 24 & 0xff;
19613 b[i++] = tl >>> 16 & 0xff;
19614 b[i++] = tl >>> 8 & 0xff;
19615 b[i++] = tl & 0xff; // `time_mid`
19617 const tmh = msecs / 0x100000000 * 10000 & 0xfffffff;
19618 b[i++] = tmh >>> 8 & 0xff;
19619 b[i++] = tmh & 0xff; // `time_high_and_version`
19621 b[i++] = tmh >>> 24 & 0xf | 0x10; // include version
19623 b[i++] = tmh >>> 16 & 0xff; // `clock_seq_hi_and_reserved` (Per 4.2.2 - include variant)
19625 b[i++] = clockseq >>> 8 | 0x80; // `clock_seq_low`
19627 b[i++] = clockseq & 0xff; // `node`
19629 for (let n = 0; n < 6; ++n) {
19630 b[i + n] = node[n];
19633 return buf || (0, _stringify.unsafeStringify)(b);
19637 exports["default"] = _default;
19641 /***/ "./node_modules/uuid/dist/commonjs-browser/v3.js":
19642 /*!*******************************************************!*\
19643 !*** ./node_modules/uuid/dist/commonjs-browser/v3.js ***!
19644 \*******************************************************/
19645 /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
19650 Object.defineProperty(exports, "__esModule", ({
19653 exports["default"] = void 0;
19655 var _v = _interopRequireDefault(__webpack_require__(/*! ./v35.js */ "./node_modules/uuid/dist/commonjs-browser/v35.js"));
19657 var _md = _interopRequireDefault(__webpack_require__(/*! ./md5.js */ "./node_modules/uuid/dist/commonjs-browser/md5.js"));
19659 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
19661 const v3 = (0, _v.default)('v3', 0x30, _md.default);
19663 exports["default"] = _default;
19667 /***/ "./node_modules/uuid/dist/commonjs-browser/v35.js":
19668 /*!********************************************************!*\
19669 !*** ./node_modules/uuid/dist/commonjs-browser/v35.js ***!
19670 \********************************************************/
19671 /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
19676 Object.defineProperty(exports, "__esModule", ({
19679 exports.URL = exports.DNS = void 0;
19680 exports["default"] = v35;
19682 var _stringify = __webpack_require__(/*! ./stringify.js */ "./node_modules/uuid/dist/commonjs-browser/stringify.js");
19684 var _parse = _interopRequireDefault(__webpack_require__(/*! ./parse.js */ "./node_modules/uuid/dist/commonjs-browser/parse.js"));
19686 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
19688 function stringToBytes(str) {
19689 str = unescape(encodeURIComponent(str)); // UTF8 escape
19693 for (let i = 0; i < str.length; ++i) {
19694 bytes.push(str.charCodeAt(i));
19700 const DNS = '6ba7b810-9dad-11d1-80b4-00c04fd430c8';
19702 const URL = '6ba7b811-9dad-11d1-80b4-00c04fd430c8';
19705 function v35(name, version, hashfunc) {
19706 function generateUUID(value, namespace, buf, offset) {
19709 if (typeof value === 'string') {
19710 value = stringToBytes(value);
19713 if (typeof namespace === 'string') {
19714 namespace = (0, _parse.default)(namespace);
19717 if (((_namespace = namespace) === null || _namespace === void 0 ? void 0 : _namespace.length) !== 16) {
19718 throw TypeError('Namespace must be array-like (16 iterable integer values, 0-255)');
19719 } // Compute hash of namespace and value, Per 4.3
19720 // Future: Use spread syntax when supported on all platforms, e.g. `bytes =
19721 // hashfunc([...namespace, ... value])`
19724 let bytes = new Uint8Array(16 + value.length);
19725 bytes.set(namespace);
19726 bytes.set(value, namespace.length);
19727 bytes = hashfunc(bytes);
19728 bytes[6] = bytes[6] & 0x0f | version;
19729 bytes[8] = bytes[8] & 0x3f | 0x80;
19732 offset = offset || 0;
19734 for (let i = 0; i < 16; ++i) {
19735 buf[offset + i] = bytes[i];
19741 return (0, _stringify.unsafeStringify)(bytes);
19742 } // Function#name is not settable on some platforms (#270)
19746 generateUUID.name = name; // eslint-disable-next-line no-empty
19747 } catch (err) {} // For CommonJS default export support
19750 generateUUID.DNS = DNS;
19751 generateUUID.URL = URL;
19752 return generateUUID;
19757 /***/ "./node_modules/uuid/dist/commonjs-browser/v4.js":
19758 /*!*******************************************************!*\
19759 !*** ./node_modules/uuid/dist/commonjs-browser/v4.js ***!
19760 \*******************************************************/
19761 /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
19766 Object.defineProperty(exports, "__esModule", ({
19769 exports["default"] = void 0;
19771 var _native = _interopRequireDefault(__webpack_require__(/*! ./native.js */ "./node_modules/uuid/dist/commonjs-browser/native.js"));
19773 var _rng = _interopRequireDefault(__webpack_require__(/*! ./rng.js */ "./node_modules/uuid/dist/commonjs-browser/rng.js"));
19775 var _stringify = __webpack_require__(/*! ./stringify.js */ "./node_modules/uuid/dist/commonjs-browser/stringify.js");
19777 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
19779 function v4(options, buf, offset) {
19780 if (_native.default.randomUUID && !buf && !options) {
19781 return _native.default.randomUUID();
19784 options = options || {};
19786 const rnds = options.random || (options.rng || _rng.default)(); // Per 4.4, set bits for version and `clock_seq_hi_and_reserved`
19789 rnds[6] = rnds[6] & 0x0f | 0x40;
19790 rnds[8] = rnds[8] & 0x3f | 0x80; // Copy bytes to buffer, if provided
19793 offset = offset || 0;
19795 for (let i = 0; i < 16; ++i) {
19796 buf[offset + i] = rnds[i];
19802 return (0, _stringify.unsafeStringify)(rnds);
19806 exports["default"] = _default;
19810 /***/ "./node_modules/uuid/dist/commonjs-browser/v5.js":
19811 /*!*******************************************************!*\
19812 !*** ./node_modules/uuid/dist/commonjs-browser/v5.js ***!
19813 \*******************************************************/
19814 /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
19819 Object.defineProperty(exports, "__esModule", ({
19822 exports["default"] = void 0;
19824 var _v = _interopRequireDefault(__webpack_require__(/*! ./v35.js */ "./node_modules/uuid/dist/commonjs-browser/v35.js"));
19826 var _sha = _interopRequireDefault(__webpack_require__(/*! ./sha1.js */ "./node_modules/uuid/dist/commonjs-browser/sha1.js"));
19828 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
19830 const v5 = (0, _v.default)('v5', 0x50, _sha.default);
19832 exports["default"] = _default;
19836 /***/ "./node_modules/uuid/dist/commonjs-browser/validate.js":
19837 /*!*************************************************************!*\
19838 !*** ./node_modules/uuid/dist/commonjs-browser/validate.js ***!
19839 \*************************************************************/
19840 /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
19845 Object.defineProperty(exports, "__esModule", ({
19848 exports["default"] = void 0;
19850 var _regex = _interopRequireDefault(__webpack_require__(/*! ./regex.js */ "./node_modules/uuid/dist/commonjs-browser/regex.js"));
19852 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
19854 function validate(uuid) {
19855 return typeof uuid === 'string' && _regex.default.test(uuid);
19858 var _default = validate;
19859 exports["default"] = _default;
19863 /***/ "./node_modules/uuid/dist/commonjs-browser/version.js":
19864 /*!************************************************************!*\
19865 !*** ./node_modules/uuid/dist/commonjs-browser/version.js ***!
19866 \************************************************************/
19867 /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
19872 Object.defineProperty(exports, "__esModule", ({
19875 exports["default"] = void 0;
19877 var _validate = _interopRequireDefault(__webpack_require__(/*! ./validate.js */ "./node_modules/uuid/dist/commonjs-browser/validate.js"));
19879 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
19881 function version(uuid) {
19882 if (!(0, _validate.default)(uuid)) {
19883 throw TypeError('Invalid UUID');
19886 return parseInt(uuid.slice(14, 15), 16);
19889 var _default = version;
19890 exports["default"] = _default;
19894 /***/ "./node_modules/marked/lib/marked.cjs":
19895 /*!********************************************!*\
19896 !*** ./node_modules/marked/lib/marked.cjs ***!
19897 \********************************************/
19898 /***/ ((__unused_webpack_module, exports) => {
19902 * marked v4.2.12 - a markdown parser
19903 * Copyright (c) 2011-2023, Christopher Jeffrey. (MIT Licensed)
19904 * https://github.com/markedjs/marked
19908 * DO NOT EDIT THIS FILE
19909 * The code in this file is generated from files in ./src/
19914 function _defineProperties(target, props) {
19915 for (var i = 0; i < props.length; i++) {
19916 var descriptor = props[i];
19917 descriptor.enumerable = descriptor.enumerable || false;
19918 descriptor.configurable = true;
19919 if ("value" in descriptor) descriptor.writable = true;
19920 Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor);
19923 function _createClass(Constructor, protoProps, staticProps) {
19924 if (protoProps) _defineProperties(Constructor.prototype, protoProps);
19925 if (staticProps) _defineProperties(Constructor, staticProps);
19926 Object.defineProperty(Constructor, "prototype", {
19929 return Constructor;
19931 function _unsupportedIterableToArray(o, minLen) {
19933 if (typeof o === "string") return _arrayLikeToArray(o, minLen);
19934 var n = Object.prototype.toString.call(o).slice(8, -1);
19935 if (n === "Object" && o.constructor) n = o.constructor.name;
19936 if (n === "Map" || n === "Set") return Array.from(o);
19937 if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen);
19939 function _arrayLikeToArray(arr, len) {
19940 if (len == null || len > arr.length) len = arr.length;
19941 for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i];
19944 function _createForOfIteratorHelperLoose(o, allowArrayLike) {
19945 var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"];
19946 if (it) return (it = it.call(o)).next.bind(it);
19947 if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") {
19950 return function () {
19951 if (i >= o.length) return {
19960 throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
19962 function _toPrimitive(input, hint) {
19963 if (typeof input !== "object" || input === null) return input;
19964 var prim = input[Symbol.toPrimitive];
19965 if (prim !== undefined) {
19966 var res = prim.call(input, hint || "default");
19967 if (typeof res !== "object") return res;
19968 throw new TypeError("@@toPrimitive must return a primitive value.");
19970 return (hint === "string" ? String : Number)(input);
19972 function _toPropertyKey(arg) {
19973 var key = _toPrimitive(arg, "string");
19974 return typeof key === "symbol" ? key : String(key);
19977 function getDefaults() {
19987 langPrefix: 'language-',
19994 smartypants: false,
20000 exports.defaults = getDefaults();
20001 function changeDefaults(newDefaults) {
20002 exports.defaults = newDefaults;
20008 var escapeTest = /[&<>"']/;
20009 var escapeReplace = new RegExp(escapeTest.source, 'g');
20010 var escapeTestNoEncode = /[<>"']|&(?!(#\d{1,7}|#[Xx][a-fA-F0-9]{1,6}|\w+);)/;
20011 var escapeReplaceNoEncode = new RegExp(escapeTestNoEncode.source, 'g');
20012 var escapeReplacements = {
20019 var getEscapeReplacement = function getEscapeReplacement(ch) {
20020 return escapeReplacements[ch];
20022 function escape(html, encode) {
20024 if (escapeTest.test(html)) {
20025 return html.replace(escapeReplace, getEscapeReplacement);
20028 if (escapeTestNoEncode.test(html)) {
20029 return html.replace(escapeReplaceNoEncode, getEscapeReplacement);
20034 var unescapeTest = /&(#(?:\d+)|(?:#x[0-9A-Fa-f]+)|(?:\w+));?/ig;
20037 * @param {string} html
20039 function unescape(html) {
20040 // explicitly match decimal, hex, and named HTML entities
20041 return html.replace(unescapeTest, function (_, n) {
20042 n = n.toLowerCase();
20043 if (n === 'colon') return ':';
20044 if (n.charAt(0) === '#') {
20045 return n.charAt(1) === 'x' ? String.fromCharCode(parseInt(n.substring(2), 16)) : String.fromCharCode(+n.substring(1));
20050 var caret = /(^|[^\[])\^/g;
20053 * @param {string | RegExp} regex
20054 * @param {string} opt
20056 function edit(regex, opt) {
20057 regex = typeof regex === 'string' ? regex : regex.source;
20060 replace: function replace(name, val) {
20061 val = val.source || val;
20062 val = val.replace(caret, '$1');
20063 regex = regex.replace(name, val);
20066 getRegex: function getRegex() {
20067 return new RegExp(regex, opt);
20072 var nonWordAndColonTest = /[^\w:]/g;
20073 var originIndependentUrl = /^$|^[a-z][a-z0-9+.-]*:|^[?#]/i;
20076 * @param {boolean} sanitize
20077 * @param {string} base
20078 * @param {string} href
20080 function cleanUrl(sanitize, base, href) {
20084 prot = decodeURIComponent(unescape(href)).replace(nonWordAndColonTest, '').toLowerCase();
20088 if (prot.indexOf('javascript:') === 0 || prot.indexOf('vbscript:') === 0 || prot.indexOf('data:') === 0) {
20092 if (base && !originIndependentUrl.test(href)) {
20093 href = resolveUrl(base, href);
20096 href = encodeURI(href).replace(/%25/g, '%');
20103 var justDomain = /^[^:]+:\/*[^/]*$/;
20104 var protocol = /^([^:]+:)[\s\S]*$/;
20105 var domain = /^([^:]+:\/*[^/]*)[\s\S]*$/;
20108 * @param {string} base
20109 * @param {string} href
20111 function resolveUrl(base, href) {
20112 if (!baseUrls[' ' + base]) {
20113 // we can ignore everything in base after the last slash of its path component,
20114 // but we might need to add _that_
20115 // https://tools.ietf.org/html/rfc3986#section-3
20116 if (justDomain.test(base)) {
20117 baseUrls[' ' + base] = base + '/';
20119 baseUrls[' ' + base] = rtrim(base, '/', true);
20122 base = baseUrls[' ' + base];
20123 var relativeBase = base.indexOf(':') === -1;
20124 if (href.substring(0, 2) === '//') {
20125 if (relativeBase) {
20128 return base.replace(protocol, '$1') + href;
20129 } else if (href.charAt(0) === '/') {
20130 if (relativeBase) {
20133 return base.replace(domain, '$1') + href;
20135 return base + href;
20139 exec: function noopTest() {}
20141 function merge(obj) {
20145 for (; i < arguments.length; i++) {
20146 target = arguments[i];
20147 for (key in target) {
20148 if (Object.prototype.hasOwnProperty.call(target, key)) {
20149 obj[key] = target[key];
20155 function splitCells(tableRow, count) {
20156 // ensure that every cell-delimiting pipe has a space
20157 // before it to distinguish it from an escaped pipe
20158 var row = tableRow.replace(/\|/g, function (match, offset, str) {
20159 var escaped = false,
20161 while (--curr >= 0 && str[curr] === '\\') {
20162 escaped = !escaped;
20165 // odd number of slashes means | is escaped
20166 // so we leave it alone
20169 // add space before unescaped |
20173 cells = row.split(/ \|/);
20176 // First/last cell in a row cannot be empty if it has no leading/trailing pipe
20177 if (!cells[0].trim()) {
20180 if (cells.length > 0 && !cells[cells.length - 1].trim()) {
20183 if (cells.length > count) {
20184 cells.splice(count);
20186 while (cells.length < count) {
20190 for (; i < cells.length; i++) {
20191 // leading or trailing whitespace is ignored per the gfm spec
20192 cells[i] = cells[i].trim().replace(/\\\|/g, '|');
20198 * Remove trailing 'c's. Equivalent to str.replace(/c*$/, '').
20199 * /c*$/ is vulnerable to REDOS.
20201 * @param {string} str
20202 * @param {string} c
20203 * @param {boolean} invert Remove suffix of non-c chars instead. Default falsey.
20205 function rtrim(str, c, invert) {
20206 var l = str.length;
20211 // Length of suffix matching the invert condition.
20214 // Step left until we fail to match the invert condition.
20215 while (suffLen < l) {
20216 var currChar = str.charAt(l - suffLen - 1);
20217 if (currChar === c && !invert) {
20219 } else if (currChar !== c && invert) {
20225 return str.slice(0, l - suffLen);
20227 function findClosingBracket(str, b) {
20228 if (str.indexOf(b[1]) === -1) {
20231 var l = str.length;
20234 for (; i < l; i++) {
20235 if (str[i] === '\\') {
20237 } else if (str[i] === b[0]) {
20239 } else if (str[i] === b[1]) {
20248 function checkSanitizeDeprecation(opt) {
20249 if (opt && opt.sanitize && !opt.silent) {
20250 console.warn('marked(): sanitize and sanitizer parameters are deprecated since version 0.7.0, should not be used and will be removed in the future. Read more here: https://marked.js.org/#/USING_ADVANCED.md#options');
20254 // copied from https://stackoverflow.com/a/5450113/806777
20256 * @param {string} pattern
20257 * @param {number} count
20259 function repeatString(pattern, count) {
20264 while (count > 1) {
20269 pattern += pattern;
20271 return result + pattern;
20274 function outputLink(cap, link, raw, lexer) {
20275 var href = link.href;
20276 var title = link.title ? escape(link.title) : null;
20277 var text = cap[1].replace(/\\([\[\]])/g, '$1');
20278 if (cap[0].charAt(0) !== '!') {
20279 lexer.state.inLink = true;
20286 tokens: lexer.inlineTokens(text)
20288 lexer.state.inLink = false;
20299 function indentCodeCompensation(raw, text) {
20300 var matchIndentToCode = raw.match(/^(\s+)(?:```)/);
20301 if (matchIndentToCode === null) {
20304 var indentToCode = matchIndentToCode[1];
20305 return text.split('\n').map(function (node) {
20306 var matchIndentInNode = node.match(/^\s+/);
20307 if (matchIndentInNode === null) {
20310 var indentInNode = matchIndentInNode[0];
20311 if (indentInNode.length >= indentToCode.length) {
20312 return node.slice(indentToCode.length);
20321 var Tokenizer = /*#__PURE__*/function () {
20322 function Tokenizer(options) {
20323 this.options = options || exports.defaults;
20325 var _proto = Tokenizer.prototype;
20326 _proto.space = function space(src) {
20327 var cap = this.rules.block.newline.exec(src);
20328 if (cap && cap[0].length > 0) {
20335 _proto.code = function code(src) {
20336 var cap = this.rules.block.code.exec(src);
20338 var text = cap[0].replace(/^ {1,4}/gm, '');
20342 codeBlockStyle: 'indented',
20343 text: !this.options.pedantic ? rtrim(text, '\n') : text
20347 _proto.fences = function fences(src) {
20348 var cap = this.rules.block.fences.exec(src);
20351 var text = indentCodeCompensation(raw, cap[3] || '');
20355 lang: cap[2] ? cap[2].trim().replace(this.rules.inline._escapes, '$1') : cap[2],
20360 _proto.heading = function heading(src) {
20361 var cap = this.rules.block.heading.exec(src);
20363 var text = cap[2].trim();
20365 // remove trailing #s
20366 if (/#$/.test(text)) {
20367 var trimmed = rtrim(text, '#');
20368 if (this.options.pedantic) {
20369 text = trimmed.trim();
20370 } else if (!trimmed || / $/.test(trimmed)) {
20371 // CommonMark requires space before trailing #s
20372 text = trimmed.trim();
20378 depth: cap[1].length,
20380 tokens: this.lexer.inline(text)
20384 _proto.hr = function hr(src) {
20385 var cap = this.rules.block.hr.exec(src);
20393 _proto.blockquote = function blockquote(src) {
20394 var cap = this.rules.block.blockquote.exec(src);
20396 var text = cap[0].replace(/^ *>[ \t]?/gm, '');
20397 var top = this.lexer.state.top;
20398 this.lexer.state.top = true;
20399 var tokens = this.lexer.blockTokens(text);
20400 this.lexer.state.top = top;
20402 type: 'blockquote',
20409 _proto.list = function list(src) {
20410 var cap = this.rules.block.list.exec(src);
20412 var raw, istask, ischecked, indent, i, blankLine, endsWithBlankLine, line, nextLine, rawLine, itemContents, endEarly;
20413 var bull = cap[1].trim();
20414 var isordered = bull.length > 1;
20418 ordered: isordered,
20419 start: isordered ? +bull.slice(0, -1) : '',
20423 bull = isordered ? "\\d{1,9}\\" + bull.slice(-1) : "\\" + bull;
20424 if (this.options.pedantic) {
20425 bull = isordered ? bull : '[*+-]';
20428 // Get next list item
20429 var itemRegex = new RegExp("^( {0,3}" + bull + ")((?:[\t ][^\\n]*)?(?:\\n|$))");
20431 // Check if current bullet point can start a new List Item
20434 if (!(cap = itemRegex.exec(src))) {
20437 if (this.rules.block.hr.test(src)) {
20438 // End list if bullet was actually HR (possibly move into itemRegex?)
20442 src = src.substring(raw.length);
20443 line = cap[2].split('\n', 1)[0].replace(/^\t+/, function (t) {
20444 return ' '.repeat(3 * t.length);
20446 nextLine = src.split('\n', 1)[0];
20447 if (this.options.pedantic) {
20449 itemContents = line.trimLeft();
20451 indent = cap[2].search(/[^ ]/); // Find first non-space char
20452 indent = indent > 4 ? 1 : indent; // Treat indented code blocks (> 4 spaces) as having only 1 indent
20453 itemContents = line.slice(indent);
20454 indent += cap[1].length;
20457 if (!line && /^ *$/.test(nextLine)) {
20458 // Items begin with at most one blank line
20459 raw += nextLine + '\n';
20460 src = src.substring(nextLine.length + 1);
20464 var nextBulletRegex = new RegExp("^ {0," + Math.min(3, indent - 1) + "}(?:[*+-]|\\d{1,9}[.)])((?:[ \t][^\\n]*)?(?:\\n|$))");
20465 var hrRegex = new RegExp("^ {0," + Math.min(3, indent - 1) + "}((?:- *){3,}|(?:_ *){3,}|(?:\\* *){3,})(?:\\n+|$)");
20466 var fencesBeginRegex = new RegExp("^ {0," + Math.min(3, indent - 1) + "}(?:```|~~~)");
20467 var headingBeginRegex = new RegExp("^ {0," + Math.min(3, indent - 1) + "}#");
20469 // Check if following lines should be included in List Item
20471 rawLine = src.split('\n', 1)[0];
20472 nextLine = rawLine;
20474 // Re-align to follow commonmark nesting rules
20475 if (this.options.pedantic) {
20476 nextLine = nextLine.replace(/^ {1,4}(?=( {4})*[^ ])/g, ' ');
20479 // End list item if found code fences
20480 if (fencesBeginRegex.test(nextLine)) {
20484 // End list item if found start of new heading
20485 if (headingBeginRegex.test(nextLine)) {
20489 // End list item if found start of new bullet
20490 if (nextBulletRegex.test(nextLine)) {
20494 // Horizontal rule found
20495 if (hrRegex.test(src)) {
20498 if (nextLine.search(/[^ ]/) >= indent || !nextLine.trim()) {
20499 // Dedent if possible
20500 itemContents += '\n' + nextLine.slice(indent);
20502 // not enough indentation
20507 // paragraph continuation unless last line was a different block level element
20508 if (line.search(/[^ ]/) >= 4) {
20509 // indented code block
20512 if (fencesBeginRegex.test(line)) {
20515 if (headingBeginRegex.test(line)) {
20518 if (hrRegex.test(line)) {
20521 itemContents += '\n' + nextLine;
20523 if (!blankLine && !nextLine.trim()) {
20524 // Check if current line is blank
20527 raw += rawLine + '\n';
20528 src = src.substring(rawLine.length + 1);
20529 line = nextLine.slice(indent);
20533 // If the previous item ended with a blank line, the list is loose
20534 if (endsWithBlankLine) {
20536 } else if (/\n *\n *$/.test(raw)) {
20537 endsWithBlankLine = true;
20541 // Check for task list items
20542 if (this.options.gfm) {
20543 istask = /^\[[ xX]\] /.exec(itemContents);
20545 ischecked = istask[0] !== '[ ] ';
20546 itemContents = itemContents.replace(/^\[[ xX]\] +/, '');
20553 checked: ischecked,
20560 // Do not consume newlines at end of final item. Alternatively, make itemRegex *start* with any newlines to simplify/speed up endsWithBlankLine logic
20561 list.items[list.items.length - 1].raw = raw.trimRight();
20562 list.items[list.items.length - 1].text = itemContents.trimRight();
20563 list.raw = list.raw.trimRight();
20564 var l = list.items.length;
20566 // Item child tokens handled here at end because we needed to have the final item to trim it first
20567 for (i = 0; i < l; i++) {
20568 this.lexer.state.top = false;
20569 list.items[i].tokens = this.lexer.blockTokens(list.items[i].text, []);
20571 // Check if list should be loose
20572 var spacers = list.items[i].tokens.filter(function (t) {
20573 return t.type === 'space';
20575 var hasMultipleLineBreaks = spacers.length > 0 && spacers.some(function (t) {
20576 return /\n.*\n/.test(t.raw);
20578 list.loose = hasMultipleLineBreaks;
20582 // Set all items to loose if list is loose
20584 for (i = 0; i < l; i++) {
20585 list.items[i].loose = true;
20591 _proto.html = function html(src) {
20592 var cap = this.rules.block.html.exec(src);
20597 pre: !this.options.sanitizer && (cap[1] === 'pre' || cap[1] === 'script' || cap[1] === 'style'),
20600 if (this.options.sanitize) {
20601 var text = this.options.sanitizer ? this.options.sanitizer(cap[0]) : escape(cap[0]);
20602 token.type = 'paragraph';
20604 token.tokens = this.lexer.inline(text);
20609 _proto.def = function def(src) {
20610 var cap = this.rules.block.def.exec(src);
20612 var tag = cap[1].toLowerCase().replace(/\s+/g, ' ');
20613 var href = cap[2] ? cap[2].replace(/^<(.*)>$/, '$1').replace(this.rules.inline._escapes, '$1') : '';
20614 var title = cap[3] ? cap[3].substring(1, cap[3].length - 1).replace(this.rules.inline._escapes, '$1') : cap[3];
20624 _proto.table = function table(src) {
20625 var cap = this.rules.block.table.exec(src);
20629 header: splitCells(cap[1]).map(function (c) {
20634 align: cap[2].replace(/^ *|\| *$/g, '').split(/ *\| */),
20635 rows: cap[3] && cap[3].trim() ? cap[3].replace(/\n[ \t]*$/, '').split('\n') : []
20637 if (item.header.length === item.align.length) {
20639 var l = item.align.length;
20641 for (i = 0; i < l; i++) {
20642 if (/^ *-+: *$/.test(item.align[i])) {
20643 item.align[i] = 'right';
20644 } else if (/^ *:-+: *$/.test(item.align[i])) {
20645 item.align[i] = 'center';
20646 } else if (/^ *:-+ *$/.test(item.align[i])) {
20647 item.align[i] = 'left';
20649 item.align[i] = null;
20652 l = item.rows.length;
20653 for (i = 0; i < l; i++) {
20654 item.rows[i] = splitCells(item.rows[i], item.header.length).map(function (c) {
20661 // parse child tokens inside headers and cells
20663 // header child tokens
20664 l = item.header.length;
20665 for (j = 0; j < l; j++) {
20666 item.header[j].tokens = this.lexer.inline(item.header[j].text);
20669 // cell child tokens
20670 l = item.rows.length;
20671 for (j = 0; j < l; j++) {
20672 row = item.rows[j];
20673 for (k = 0; k < row.length; k++) {
20674 row[k].tokens = this.lexer.inline(row[k].text);
20681 _proto.lheading = function lheading(src) {
20682 var cap = this.rules.block.lheading.exec(src);
20687 depth: cap[2].charAt(0) === '=' ? 1 : 2,
20689 tokens: this.lexer.inline(cap[1])
20693 _proto.paragraph = function paragraph(src) {
20694 var cap = this.rules.block.paragraph.exec(src);
20696 var text = cap[1].charAt(cap[1].length - 1) === '\n' ? cap[1].slice(0, -1) : cap[1];
20701 tokens: this.lexer.inline(text)
20705 _proto.text = function text(src) {
20706 var cap = this.rules.block.text.exec(src);
20712 tokens: this.lexer.inline(cap[0])
20716 _proto.escape = function escape$1(src) {
20717 var cap = this.rules.inline.escape.exec(src);
20722 text: escape(cap[1])
20726 _proto.tag = function tag(src) {
20727 var cap = this.rules.inline.tag.exec(src);
20729 if (!this.lexer.state.inLink && /^<a /i.test(cap[0])) {
20730 this.lexer.state.inLink = true;
20731 } else if (this.lexer.state.inLink && /^<\/a>/i.test(cap[0])) {
20732 this.lexer.state.inLink = false;
20734 if (!this.lexer.state.inRawBlock && /^<(pre|code|kbd|script)(\s|>)/i.test(cap[0])) {
20735 this.lexer.state.inRawBlock = true;
20736 } else if (this.lexer.state.inRawBlock && /^<\/(pre|code|kbd|script)(\s|>)/i.test(cap[0])) {
20737 this.lexer.state.inRawBlock = false;
20740 type: this.options.sanitize ? 'text' : 'html',
20742 inLink: this.lexer.state.inLink,
20743 inRawBlock: this.lexer.state.inRawBlock,
20744 text: this.options.sanitize ? this.options.sanitizer ? this.options.sanitizer(cap[0]) : escape(cap[0]) : cap[0]
20748 _proto.link = function link(src) {
20749 var cap = this.rules.inline.link.exec(src);
20751 var trimmedUrl = cap[2].trim();
20752 if (!this.options.pedantic && /^</.test(trimmedUrl)) {
20753 // commonmark requires matching angle brackets
20754 if (!/>$/.test(trimmedUrl)) {
20758 // ending angle bracket cannot be escaped
20759 var rtrimSlash = rtrim(trimmedUrl.slice(0, -1), '\\');
20760 if ((trimmedUrl.length - rtrimSlash.length) % 2 === 0) {
20764 // find closing parenthesis
20765 var lastParenIndex = findClosingBracket(cap[2], '()');
20766 if (lastParenIndex > -1) {
20767 var start = cap[0].indexOf('!') === 0 ? 5 : 4;
20768 var linkLen = start + cap[1].length + lastParenIndex;
20769 cap[2] = cap[2].substring(0, lastParenIndex);
20770 cap[0] = cap[0].substring(0, linkLen).trim();
20776 if (this.options.pedantic) {
20777 // split pedantic href and title
20778 var link = /^([^'"]*[^\s])\s+(['"])(.*)\2/.exec(href);
20784 title = cap[3] ? cap[3].slice(1, -1) : '';
20786 href = href.trim();
20787 if (/^</.test(href)) {
20788 if (this.options.pedantic && !/>$/.test(trimmedUrl)) {
20789 // pedantic allows starting angle bracket without ending angle bracket
20790 href = href.slice(1);
20792 href = href.slice(1, -1);
20795 return outputLink(cap, {
20796 href: href ? href.replace(this.rules.inline._escapes, '$1') : href,
20797 title: title ? title.replace(this.rules.inline._escapes, '$1') : title
20798 }, cap[0], this.lexer);
20801 _proto.reflink = function reflink(src, links) {
20803 if ((cap = this.rules.inline.reflink.exec(src)) || (cap = this.rules.inline.nolink.exec(src))) {
20804 var link = (cap[2] || cap[1]).replace(/\s+/g, ' ');
20805 link = links[link.toLowerCase()];
20807 var text = cap[0].charAt(0);
20814 return outputLink(cap, link, cap[0], this.lexer);
20817 _proto.emStrong = function emStrong(src, maskedSrc, prevChar) {
20818 if (prevChar === void 0) {
20821 var match = this.rules.inline.emStrong.lDelim.exec(src);
20822 if (!match) return;
20824 // _ can't be between two alphanumerics. \p{L}\p{N} includes non-english alphabet/numbers as well
20825 if (match[3] && prevChar.match(/(?:[0-9A-Za-z\xAA\xB2\xB3\xB5\xB9\xBA\xBC-\xBE\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u048A-\u052F\u0531-\u0556\u0559\u0560-\u0588\u05D0-\u05EA\u05EF-\u05F2\u0620-\u064A\u0660-\u0669\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07C0-\u07EA\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u0860-\u086A\u0870-\u0887\u0889-\u088E\u08A0-\u08C9\u0904-\u0939\u093D\u0950\u0958-\u0961\u0966-\u096F\u0971-\u0980\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09E6-\u09F1\u09F4-\u09F9\u09FC\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A59-\u0A5C\u0A5E\u0A66-\u0A6F\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0AE6-\u0AEF\u0AF9\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C\u0B5D\u0B5F-\u0B61\u0B66-\u0B6F\u0B71-\u0B77\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0\u0BE6-\u0BF2\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D\u0C58-\u0C5A\u0C5D\u0C60\u0C61\u0C66-\u0C6F\u0C78-\u0C7E\u0C80\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD\u0CDD\u0CDE\u0CE0\u0CE1\u0CE6-\u0CEF\u0CF1\u0CF2\u0D04-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D\u0D4E\u0D54-\u0D56\u0D58-\u0D61\u0D66-\u0D78\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0DE6-\u0DEF\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E50-\u0E59\u0E81\u0E82\u0E84\u0E86-\u0E8A\u0E8C-\u0EA3\u0EA5\u0EA7-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6\u0ED0-\u0ED9\u0EDC-\u0EDF\u0F00\u0F20-\u0F33\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A\u103F-\u1049\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081\u108E\u1090-\u1099\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u1369-\u137C\u1380-\u138F\u13A0-\u13F5\u13F8-\u13FD\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u1711\u171F-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7\u17DC\u17E0-\u17E9\u17F0-\u17F9\u1810-\u1819\u1820-\u1878\u1880-\u1884\u1887-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191E\u1946-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u19D0-\u19DA\u1A00-\u1A16\u1A20-\u1A54\u1A80-\u1A89\u1A90-\u1A99\u1AA7\u1B05-\u1B33\u1B45-\u1B4C\u1B50-\u1B59\u1B83-\u1BA0\u1BAE-\u1BE5\u1C00-\u1C23\u1C40-\u1C49\u1C4D-\u1C7D\u1C80-\u1C88\u1C90-\u1CBA\u1CBD-\u1CBF\u1CE9-\u1CEC\u1CEE-\u1CF3\u1CF5\u1CF6\u1CFA\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2070\u2071\u2074-\u2079\u207F-\u2089\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2150-\u2189\u2460-\u249B\u24EA-\u24FF\u2776-\u2793\u2C00-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3\u2CFD\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303C\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312F\u3131-\u318E\u3192-\u3195\u31A0-\u31BF\u31F0-\u31FF\u3220-\u3229\u3248-\u324F\u3251-\u325F\u3280-\u3289\u32B1-\u32BF\u3400-\u4DBF\u4E00-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA62B\uA640-\uA66E\uA67F-\uA69D\uA6A0-\uA6EF\uA717-\uA71F\uA722-\uA788\uA78B-\uA7CA\uA7D0\uA7D1\uA7D3\uA7D5-\uA7D9\uA7F2-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA830-\uA835\uA840-\uA873\uA882-\uA8B3\uA8D0-\uA8D9\uA8F2-\uA8F7\uA8FB\uA8FD\uA8FE\uA900-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF-\uA9D9\uA9E0-\uA9E4\uA9E6-\uA9FE\uAA00-\uAA28\uAA40-\uAA42\uAA44-\uAA4B\uAA50-\uAA59\uAA60-\uAA76\uAA7A\uAA7E-\uAAAF\uAAB1\uAAB5\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB69\uAB70-\uABE2\uABF0-\uABF9\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC\uFF10-\uFF19\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]|\uD800[\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA\uDD07-\uDD33\uDD40-\uDD78\uDD8A\uDD8B\uDE80-\uDE9C\uDEA0-\uDED0\uDEE1-\uDEFB\uDF00-\uDF23\uDF2D-\uDF4A\uDF50-\uDF75\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF\uDFD1-\uDFD5]|\uD801[\uDC00-\uDC9D\uDCA0-\uDCA9\uDCB0-\uDCD3\uDCD8-\uDCFB\uDD00-\uDD27\uDD30-\uDD63\uDD70-\uDD7A\uDD7C-\uDD8A\uDD8C-\uDD92\uDD94\uDD95\uDD97-\uDDA1\uDDA3-\uDDB1\uDDB3-\uDDB9\uDDBB\uDDBC\uDE00-\uDF36\uDF40-\uDF55\uDF60-\uDF67\uDF80-\uDF85\uDF87-\uDFB0\uDFB2-\uDFBA]|\uD802[\uDC00-\uDC05\uDC08\uDC0A-\uDC35\uDC37\uDC38\uDC3C\uDC3F-\uDC55\uDC58-\uDC76\uDC79-\uDC9E\uDCA7-\uDCAF\uDCE0-\uDCF2\uDCF4\uDCF5\uDCFB-\uDD1B\uDD20-\uDD39\uDD80-\uDDB7\uDDBC-\uDDCF\uDDD2-\uDE00\uDE10-\uDE13\uDE15-\uDE17\uDE19-\uDE35\uDE40-\uDE48\uDE60-\uDE7E\uDE80-\uDE9F\uDEC0-\uDEC7\uDEC9-\uDEE4\uDEEB-\uDEEF\uDF00-\uDF35\uDF40-\uDF55\uDF58-\uDF72\uDF78-\uDF91\uDFA9-\uDFAF]|\uD803[\uDC00-\uDC48\uDC80-\uDCB2\uDCC0-\uDCF2\uDCFA-\uDD23\uDD30-\uDD39\uDE60-\uDE7E\uDE80-\uDEA9\uDEB0\uDEB1\uDF00-\uDF27\uDF30-\uDF45\uDF51-\uDF54\uDF70-\uDF81\uDFB0-\uDFCB\uDFE0-\uDFF6]|\uD804[\uDC03-\uDC37\uDC52-\uDC6F\uDC71\uDC72\uDC75\uDC83-\uDCAF\uDCD0-\uDCE8\uDCF0-\uDCF9\uDD03-\uDD26\uDD36-\uDD3F\uDD44\uDD47\uDD50-\uDD72\uDD76\uDD83-\uDDB2\uDDC1-\uDDC4\uDDD0-\uDDDA\uDDDC\uDDE1-\uDDF4\uDE00-\uDE11\uDE13-\uDE2B\uDE80-\uDE86\uDE88\uDE8A-\uDE8D\uDE8F-\uDE9D\uDE9F-\uDEA8\uDEB0-\uDEDE\uDEF0-\uDEF9\uDF05-\uDF0C\uDF0F\uDF10\uDF13-\uDF28\uDF2A-\uDF30\uDF32\uDF33\uDF35-\uDF39\uDF3D\uDF50\uDF5D-\uDF61]|\uD805[\uDC00-\uDC34\uDC47-\uDC4A\uDC50-\uDC59\uDC5F-\uDC61\uDC80-\uDCAF\uDCC4\uDCC5\uDCC7\uDCD0-\uDCD9\uDD80-\uDDAE\uDDD8-\uDDDB\uDE00-\uDE2F\uDE44\uDE50-\uDE59\uDE80-\uDEAA\uDEB8\uDEC0-\uDEC9\uDF00-\uDF1A\uDF30-\uDF3B\uDF40-\uDF46]|\uD806[\uDC00-\uDC2B\uDCA0-\uDCF2\uDCFF-\uDD06\uDD09\uDD0C-\uDD13\uDD15\uDD16\uDD18-\uDD2F\uDD3F\uDD41\uDD50-\uDD59\uDDA0-\uDDA7\uDDAA-\uDDD0\uDDE1\uDDE3\uDE00\uDE0B-\uDE32\uDE3A\uDE50\uDE5C-\uDE89\uDE9D\uDEB0-\uDEF8]|\uD807[\uDC00-\uDC08\uDC0A-\uDC2E\uDC40\uDC50-\uDC6C\uDC72-\uDC8F\uDD00-\uDD06\uDD08\uDD09\uDD0B-\uDD30\uDD46\uDD50-\uDD59\uDD60-\uDD65\uDD67\uDD68\uDD6A-\uDD89\uDD98\uDDA0-\uDDA9\uDEE0-\uDEF2\uDFB0\uDFC0-\uDFD4]|\uD808[\uDC00-\uDF99]|\uD809[\uDC00-\uDC6E\uDC80-\uDD43]|\uD80B[\uDF90-\uDFF0]|[\uD80C\uD81C-\uD820\uD822\uD840-\uD868\uD86A-\uD86C\uD86F-\uD872\uD874-\uD879\uD880-\uD883][\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2E]|\uD811[\uDC00-\uDE46]|\uD81A[\uDC00-\uDE38\uDE40-\uDE5E\uDE60-\uDE69\uDE70-\uDEBE\uDEC0-\uDEC9\uDED0-\uDEED\uDF00-\uDF2F\uDF40-\uDF43\uDF50-\uDF59\uDF5B-\uDF61\uDF63-\uDF77\uDF7D-\uDF8F]|\uD81B[\uDE40-\uDE96\uDF00-\uDF4A\uDF50\uDF93-\uDF9F\uDFE0\uDFE1\uDFE3]|\uD821[\uDC00-\uDFF7]|\uD823[\uDC00-\uDCD5\uDD00-\uDD08]|\uD82B[\uDFF0-\uDFF3\uDFF5-\uDFFB\uDFFD\uDFFE]|\uD82C[\uDC00-\uDD22\uDD50-\uDD52\uDD64-\uDD67\uDD70-\uDEFB]|\uD82F[\uDC00-\uDC6A\uDC70-\uDC7C\uDC80-\uDC88\uDC90-\uDC99]|\uD834[\uDEE0-\uDEF3\uDF60-\uDF78]|\uD835[\uDC00-\uDC54\uDC56-\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDEA5\uDEA8-\uDEC0\uDEC2-\uDEDA\uDEDC-\uDEFA\uDEFC-\uDF14\uDF16-\uDF34\uDF36-\uDF4E\uDF50-\uDF6E\uDF70-\uDF88\uDF8A-\uDFA8\uDFAA-\uDFC2\uDFC4-\uDFCB\uDFCE-\uDFFF]|\uD837[\uDF00-\uDF1E]|\uD838[\uDD00-\uDD2C\uDD37-\uDD3D\uDD40-\uDD49\uDD4E\uDE90-\uDEAD\uDEC0-\uDEEB\uDEF0-\uDEF9]|\uD839[\uDFE0-\uDFE6\uDFE8-\uDFEB\uDFED\uDFEE\uDFF0-\uDFFE]|\uD83A[\uDC00-\uDCC4\uDCC7-\uDCCF\uDD00-\uDD43\uDD4B\uDD50-\uDD59]|\uD83B[\uDC71-\uDCAB\uDCAD-\uDCAF\uDCB1-\uDCB4\uDD01-\uDD2D\uDD2F-\uDD3D\uDE00-\uDE03\uDE05-\uDE1F\uDE21\uDE22\uDE24\uDE27\uDE29-\uDE32\uDE34-\uDE37\uDE39\uDE3B\uDE42\uDE47\uDE49\uDE4B\uDE4D-\uDE4F\uDE51\uDE52\uDE54\uDE57\uDE59\uDE5B\uDE5D\uDE5F\uDE61\uDE62\uDE64\uDE67-\uDE6A\uDE6C-\uDE72\uDE74-\uDE77\uDE79-\uDE7C\uDE7E\uDE80-\uDE89\uDE8B-\uDE9B\uDEA1-\uDEA3\uDEA5-\uDEA9\uDEAB-\uDEBB]|\uD83C[\uDD00-\uDD0C]|\uD83E[\uDFF0-\uDFF9]|\uD869[\uDC00-\uDEDF\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF38\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D\uDC20-\uDFFF]|\uD873[\uDC00-\uDEA1\uDEB0-\uDFFF]|\uD87A[\uDC00-\uDFE0]|\uD87E[\uDC00-\uDE1D]|\uD884[\uDC00-\uDF4A])/)) return;
20826 var nextChar = match[1] || match[2] || '';
20827 if (!nextChar || nextChar && (prevChar === '' || this.rules.inline.punctuation.exec(prevChar))) {
20828 var lLength = match[0].length - 1;
20831 delimTotal = lLength,
20833 var endReg = match[0][0] === '*' ? this.rules.inline.emStrong.rDelimAst : this.rules.inline.emStrong.rDelimUnd;
20834 endReg.lastIndex = 0;
20836 // Clip maskedSrc to same section of string as src (move to lexer?)
20837 maskedSrc = maskedSrc.slice(-1 * src.length + lLength);
20838 while ((match = endReg.exec(maskedSrc)) != null) {
20839 rDelim = match[1] || match[2] || match[3] || match[4] || match[5] || match[6];
20840 if (!rDelim) continue; // skip single * in __abc*abc__
20842 rLength = rDelim.length;
20843 if (match[3] || match[4]) {
20844 // found another Left Delim
20845 delimTotal += rLength;
20847 } else if (match[5] || match[6]) {
20848 // either Left or Right Delim
20849 if (lLength % 3 && !((lLength + rLength) % 3)) {
20850 midDelimTotal += rLength;
20851 continue; // CommonMark Emphasis Rules 9-10
20855 delimTotal -= rLength;
20856 if (delimTotal > 0) continue; // Haven't found enough closing delimiters
20858 // Remove extra characters. *a*** -> *a*
20859 rLength = Math.min(rLength, rLength + delimTotal + midDelimTotal);
20860 var raw = src.slice(0, lLength + match.index + (match[0].length - rDelim.length) + rLength);
20862 // Create `em` if smallest delimiter has odd char count. *a***
20863 if (Math.min(lLength, rLength) % 2) {
20864 var _text = raw.slice(1, -1);
20869 tokens: this.lexer.inlineTokens(_text)
20873 // Create 'strong' if smallest delimiter has even char count. **a***
20874 var text = raw.slice(2, -2);
20879 tokens: this.lexer.inlineTokens(text)
20884 _proto.codespan = function codespan(src) {
20885 var cap = this.rules.inline.code.exec(src);
20887 var text = cap[2].replace(/\n/g, ' ');
20888 var hasNonSpaceChars = /[^ ]/.test(text);
20889 var hasSpaceCharsOnBothEnds = /^ /.test(text) && / $/.test(text);
20890 if (hasNonSpaceChars && hasSpaceCharsOnBothEnds) {
20891 text = text.substring(1, text.length - 1);
20893 text = escape(text, true);
20901 _proto.br = function br(src) {
20902 var cap = this.rules.inline.br.exec(src);
20910 _proto.del = function del(src) {
20911 var cap = this.rules.inline.del.exec(src);
20917 tokens: this.lexer.inlineTokens(cap[2])
20921 _proto.autolink = function autolink(src, mangle) {
20922 var cap = this.rules.inline.autolink.exec(src);
20925 if (cap[2] === '@') {
20926 text = escape(this.options.mangle ? mangle(cap[1]) : cap[1]);
20927 href = 'mailto:' + text;
20929 text = escape(cap[1]);
20945 _proto.url = function url(src, mangle) {
20947 if (cap = this.rules.inline.url.exec(src)) {
20949 if (cap[2] === '@') {
20950 text = escape(this.options.mangle ? mangle(cap[0]) : cap[0]);
20951 href = 'mailto:' + text;
20953 // do extended autolink path validation
20956 prevCapZero = cap[0];
20957 cap[0] = this.rules.inline._backpedal.exec(cap[0])[0];
20958 } while (prevCapZero !== cap[0]);
20959 text = escape(cap[0]);
20960 if (cap[1] === 'www.') {
20961 href = 'http://' + cap[0];
20979 _proto.inlineText = function inlineText(src, smartypants) {
20980 var cap = this.rules.inline.text.exec(src);
20983 if (this.lexer.state.inRawBlock) {
20984 text = this.options.sanitize ? this.options.sanitizer ? this.options.sanitizer(cap[0]) : escape(cap[0]) : cap[0];
20986 text = escape(this.options.smartypants ? smartypants(cap[0]) : cap[0]);
20999 * Block-Level Grammar
21002 newline: /^(?: *(?:\n|$))+/,
21003 code: /^( {4}[^\n]+(?:\n(?: *(?:\n|$))*)?)+/,
21004 fences: /^ {0,3}(`{3,}(?=[^`\n]*\n)|~{3,})([^\n]*)\n(?:|([\s\S]*?)\n)(?: {0,3}\1[~`]* *(?=\n|$)|$)/,
21005 hr: /^ {0,3}((?:-[\t ]*){3,}|(?:_[ \t]*){3,}|(?:\*[ \t]*){3,})(?:\n+|$)/,
21006 heading: /^ {0,3}(#{1,6})(?=\s|$)(.*)(?:\n+|$)/,
21007 blockquote: /^( {0,3}> ?(paragraph|[^\n]*)(?:\n|$))+/,
21008 list: /^( {0,3}bull)([ \t][^\n]+?)?(?:\n|$)/,
21009 html: '^ {0,3}(?:' // optional indentation
21010 + '<(script|pre|style|textarea)[\\s>][\\s\\S]*?(?:</\\1>[^\\n]*\\n+|$)' // (1)
21011 + '|comment[^\\n]*(\\n+|$)' // (2)
21012 + '|<\\?[\\s\\S]*?(?:\\?>\\n*|$)' // (3)
21013 + '|<![A-Z][\\s\\S]*?(?:>\\n*|$)' // (4)
21014 + '|<!\\[CDATA\\[[\\s\\S]*?(?:\\]\\]>\\n*|$)' // (5)
21015 + '|</?(tag)(?: +|\\n|/?>)[\\s\\S]*?(?:(?:\\n *)+\\n|$)' // (6)
21016 + '|<(?!script|pre|style|textarea)([a-z][\\w-]*)(?:attribute)*? */?>(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n *)+\\n|$)' // (7) open tag
21017 + '|</(?!script|pre|style|textarea)[a-z][\\w-]*\\s*>(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n *)+\\n|$)' // (7) closing tag
21019 def: /^ {0,3}\[(label)\]: *(?:\n *)?([^<\s][^\s]*|<.*?>)(?:(?: +(?:\n *)?| *\n *)(title))? *(?:\n+|$)/,
21021 lheading: /^((?:.|\n(?!\n))+?)\n {0,3}(=+|-+) *(?:\n+|$)/,
21022 // regex template, placeholders will be replaced according to different paragraph
21023 // interruption rules of commonmark and the original markdown spec:
21024 _paragraph: /^([^\n]+(?:\n(?!hr|heading|lheading|blockquote|fences|list|html|table| +\n)[^\n]+)*)/,
21027 block._label = /(?!\s*\])(?:\\.|[^\[\]\\])+/;
21028 block._title = /(?:"(?:\\"?|[^"\\])*"|'[^'\n]*(?:\n[^'\n]+)*\n?'|\([^()]*\))/;
21029 block.def = edit(block.def).replace('label', block._label).replace('title', block._title).getRegex();
21030 block.bullet = /(?:[*+-]|\d{1,9}[.)])/;
21031 block.listItemStart = edit(/^( *)(bull) */).replace('bull', block.bullet).getRegex();
21032 block.list = edit(block.list).replace(/bull/g, block.bullet).replace('hr', '\\n+(?=\\1?(?:(?:- *){3,}|(?:_ *){3,}|(?:\\* *){3,})(?:\\n+|$))').replace('def', '\\n+(?=' + block.def.source + ')').getRegex();
21033 block._tag = 'address|article|aside|base|basefont|blockquote|body|caption' + '|center|col|colgroup|dd|details|dialog|dir|div|dl|dt|fieldset|figcaption' + '|figure|footer|form|frame|frameset|h[1-6]|head|header|hr|html|iframe' + '|legend|li|link|main|menu|menuitem|meta|nav|noframes|ol|optgroup|option' + '|p|param|section|source|summary|table|tbody|td|tfoot|th|thead|title|tr' + '|track|ul';
21034 block._comment = /<!--(?!-?>)[\s\S]*?(?:-->|$)/;
21035 block.html = edit(block.html, 'i').replace('comment', block._comment).replace('tag', block._tag).replace('attribute', / +[a-zA-Z:_][\w.:-]*(?: *= *"[^"\n]*"| *= *'[^'\n]*'| *= *[^\s"'=<>`]+)?/).getRegex();
21036 block.paragraph = edit(block._paragraph).replace('hr', block.hr).replace('heading', ' {0,3}#{1,6} ').replace('|lheading', '') // setex headings don't interrupt commonmark paragraphs
21037 .replace('|table', '').replace('blockquote', ' {0,3}>').replace('fences', ' {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n').replace('list', ' {0,3}(?:[*+-]|1[.)]) ') // only lists starting from 1 can interrupt
21038 .replace('html', '</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)').replace('tag', block._tag) // pars can be interrupted by type (6) html blocks
21040 block.blockquote = edit(block.blockquote).replace('paragraph', block.paragraph).getRegex();
21043 * Normal Block Grammar
21046 block.normal = merge({}, block);
21049 * GFM Block Grammar
21052 block.gfm = merge({}, block.normal, {
21053 table: '^ *([^\\n ].*\\|.*)\\n' // Header
21054 + ' {0,3}(?:\\| *)?(:?-+:? *(?:\\| *:?-+:? *)*)(?:\\| *)?' // Align
21055 + '(?:\\n((?:(?! *\\n|hr|heading|blockquote|code|fences|list|html).*(?:\\n|$))*)\\n*|$)' // Cells
21058 block.gfm.table = edit(block.gfm.table).replace('hr', block.hr).replace('heading', ' {0,3}#{1,6} ').replace('blockquote', ' {0,3}>').replace('code', ' {4}[^\\n]').replace('fences', ' {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n').replace('list', ' {0,3}(?:[*+-]|1[.)]) ') // only lists starting from 1 can interrupt
21059 .replace('html', '</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)').replace('tag', block._tag) // tables can be interrupted by type (6) html blocks
21061 block.gfm.paragraph = edit(block._paragraph).replace('hr', block.hr).replace('heading', ' {0,3}#{1,6} ').replace('|lheading', '') // setex headings don't interrupt commonmark paragraphs
21062 .replace('table', block.gfm.table) // interrupt paragraphs with table
21063 .replace('blockquote', ' {0,3}>').replace('fences', ' {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n').replace('list', ' {0,3}(?:[*+-]|1[.)]) ') // only lists starting from 1 can interrupt
21064 .replace('html', '</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)').replace('tag', block._tag) // pars can be interrupted by type (6) html blocks
21067 * Pedantic grammar (original John Gruber's loose markdown specification)
21070 block.pedantic = merge({}, block.normal, {
21071 html: edit('^ *(?:comment *(?:\\n|\\s*$)' + '|<(tag)[\\s\\S]+?</\\1> *(?:\\n{2,}|\\s*$)' // closed tag
21072 + '|<tag(?:"[^"]*"|\'[^\']*\'|\\s[^\'"/>\\s]*)*?/?> *(?:\\n{2,}|\\s*$))').replace('comment', block._comment).replace(/tag/g, '(?!(?:' + 'a|em|strong|small|s|cite|q|dfn|abbr|data|time|code|var|samp|kbd|sub' + '|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo|span|br|wbr|ins|del|img)' + '\\b)\\w+(?!:|[^\\w\\s@]*@)\\b').getRegex(),
21073 def: /^ *\[([^\]]+)\]: *<?([^\s>]+)>?(?: +(["(][^\n]+[")]))? *(?:\n+|$)/,
21074 heading: /^(#{1,6})(.*)(?:\n+|$)/,
21076 // fences not supported
21077 lheading: /^(.+?)\n {0,3}(=+|-+) *(?:\n+|$)/,
21078 paragraph: edit(block.normal._paragraph).replace('hr', block.hr).replace('heading', ' *#{1,6} *[^\n]').replace('lheading', block.lheading).replace('blockquote', ' {0,3}>').replace('|fences', '').replace('|list', '').replace('|html', '').getRegex()
21082 * Inline-Level Grammar
21085 escape: /^\\([!"#$%&'()*+,\-./:;<=>?@\[\]\\^_`{|}~])/,
21086 autolink: /^<(scheme:[^\s\x00-\x1f<>]*|email)>/,
21088 tag: '^comment' + '|^</[a-zA-Z][\\w:-]*\\s*>' // self-closing tag
21089 + '|^<[a-zA-Z][\\w-]*(?:attribute)*?\\s*/?>' // open tag
21090 + '|^<\\?[\\s\\S]*?\\?>' // processing instruction, e.g. <?php ?>
21091 + '|^<![a-zA-Z]+\\s[\\s\\S]*?>' // declaration, e.g. <!DOCTYPE html>
21092 + '|^<!\\[CDATA\\[[\\s\\S]*?\\]\\]>',
21094 link: /^!?\[(label)\]\(\s*(href)(?:\s+(title))?\s*\)/,
21095 reflink: /^!?\[(label)\]\[(ref)\]/,
21096 nolink: /^!?\[(ref)\](?:\[\])?/,
21097 reflinkSearch: 'reflink|nolink(?!\\()',
21099 lDelim: /^(?:\*+(?:([punct_])|[^\s*]))|^_+(?:([punct*])|([^\s_]))/,
21100 // (1) and (2) can only be a Right Delimiter. (3) and (4) can only be Left. (5) and (6) can be either Left or Right.
21101 // () Skip orphan inside strong () Consume to delim (1) #*** (2) a***#, a*** (3) #***a, ***a (4) ***# (5) #***# (6) a***a
21102 rDelimAst: /^(?:[^_*\\]|\\.)*?\_\_(?:[^_*\\]|\\.)*?\*(?:[^_*\\]|\\.)*?(?=\_\_)|(?:[^*\\]|\\.)+(?=[^*])|[punct_](\*+)(?=[\s]|$)|(?:[^punct*_\s\\]|\\.)(\*+)(?=[punct_\s]|$)|[punct_\s](\*+)(?=[^punct*_\s])|[\s](\*+)(?=[punct_])|[punct_](\*+)(?=[punct_])|(?:[^punct*_\s\\]|\\.)(\*+)(?=[^punct*_\s])/,
21103 rDelimUnd: /^(?:[^_*\\]|\\.)*?\*\*(?:[^_*\\]|\\.)*?\_(?:[^_*\\]|\\.)*?(?=\*\*)|(?:[^_\\]|\\.)+(?=[^_])|[punct*](\_+)(?=[\s]|$)|(?:[^punct*_\s\\]|\\.)(\_+)(?=[punct*\s]|$)|[punct*\s](\_+)(?=[^punct*_\s])|[\s](\_+)(?=[punct*])|[punct*](\_+)(?=[punct*])/ // ^- Not allowed for _
21106 code: /^(`+)([^`]|[^`][\s\S]*?[^`])\1(?!`)/,
21107 br: /^( {2,}|\\)\n(?!\s*$)/,
21109 text: /^(`+|[^`])(?:(?= {2,}\n)|[\s\S]*?(?:(?=[\\<!\[`*_]|\b_|$)|[^ ](?= {2,}\n)))/,
21110 punctuation: /^([\spunctuation])/
21113 // list of punctuation marks from CommonMark spec
21114 // without * and _ to handle the different emphasis markers * and _
21115 inline._punctuation = '!"#$%&\'()+\\-.,/:;<=>?@\\[\\]`^{|}~';
21116 inline.punctuation = edit(inline.punctuation).replace(/punctuation/g, inline._punctuation).getRegex();
21118 // sequences em should skip over [title](link), `code`, <html>
21119 inline.blockSkip = /\[[^\]]*?\]\([^\)]*?\)|`[^`]*?`|<[^>]*?>/g;
21120 // lookbehind is not available on Safari as of version 16
21121 // inline.escapedEmSt = /(?<=(?:^|[^\\)(?:\\[^])*)\\[*_]/g;
21122 inline.escapedEmSt = /(?:^|[^\\])(?:\\\\)*\\[*_]/g;
21123 inline._comment = edit(block._comment).replace('(?:-->|$)', '-->').getRegex();
21124 inline.emStrong.lDelim = edit(inline.emStrong.lDelim).replace(/punct/g, inline._punctuation).getRegex();
21125 inline.emStrong.rDelimAst = edit(inline.emStrong.rDelimAst, 'g').replace(/punct/g, inline._punctuation).getRegex();
21126 inline.emStrong.rDelimUnd = edit(inline.emStrong.rDelimUnd, 'g').replace(/punct/g, inline._punctuation).getRegex();
21127 inline._escapes = /\\([!"#$%&'()*+,\-./:;<=>?@\[\]\\^_`{|}~])/g;
21128 inline._scheme = /[a-zA-Z][a-zA-Z0-9+.-]{1,31}/;
21129 inline._email = /[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+(@)[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)+(?![-_])/;
21130 inline.autolink = edit(inline.autolink).replace('scheme', inline._scheme).replace('email', inline._email).getRegex();
21131 inline._attribute = /\s+[a-zA-Z:_][\w.:-]*(?:\s*=\s*"[^"]*"|\s*=\s*'[^']*'|\s*=\s*[^\s"'=<>`]+)?/;
21132 inline.tag = edit(inline.tag).replace('comment', inline._comment).replace('attribute', inline._attribute).getRegex();
21133 inline._label = /(?:\[(?:\\.|[^\[\]\\])*\]|\\.|`[^`]*`|[^\[\]\\`])*?/;
21134 inline._href = /<(?:\\.|[^\n<>\\])+>|[^\s\x00-\x1f]*/;
21135 inline._title = /"(?:\\"?|[^"\\])*"|'(?:\\'?|[^'\\])*'|\((?:\\\)?|[^)\\])*\)/;
21136 inline.link = edit(inline.link).replace('label', inline._label).replace('href', inline._href).replace('title', inline._title).getRegex();
21137 inline.reflink = edit(inline.reflink).replace('label', inline._label).replace('ref', block._label).getRegex();
21138 inline.nolink = edit(inline.nolink).replace('ref', block._label).getRegex();
21139 inline.reflinkSearch = edit(inline.reflinkSearch, 'g').replace('reflink', inline.reflink).replace('nolink', inline.nolink).getRegex();
21142 * Normal Inline Grammar
21145 inline.normal = merge({}, inline);
21148 * Pedantic Inline Grammar
21151 inline.pedantic = merge({}, inline.normal, {
21154 middle: /^__(?=\S)([\s\S]*?\S)__(?!_)|^\*\*(?=\S)([\s\S]*?\S)\*\*(?!\*)/,
21155 endAst: /\*\*(?!\*)/g,
21160 middle: /^()\*(?=\S)([\s\S]*?\S)\*(?!\*)|^_(?=\S)([\s\S]*?\S)_(?!_)/,
21161 endAst: /\*(?!\*)/g,
21164 link: edit(/^!?\[(label)\]\((.*?)\)/).replace('label', inline._label).getRegex(),
21165 reflink: edit(/^!?\[(label)\]\s*\[([^\]]*)\]/).replace('label', inline._label).getRegex()
21169 * GFM Inline Grammar
21172 inline.gfm = merge({}, inline.normal, {
21173 escape: edit(inline.escape).replace('])', '~|])').getRegex(),
21174 _extended_email: /[A-Za-z0-9._+-]+(@)[a-zA-Z0-9-_]+(?:\.[a-zA-Z0-9-_]*[a-zA-Z0-9])+(?![-_])/,
21175 url: /^((?:ftp|https?):\/\/|www\.)(?:[a-zA-Z0-9\-]+\.?)+[^\s<]*|^email/,
21176 _backpedal: /(?:[^?!.,:;*_'"~()&]+|\([^)]*\)|&(?![a-zA-Z0-9]+;$)|[?!.,:;*_'"~)]+(?!$))+/,
21177 del: /^(~~?)(?=[^\s~])([\s\S]*?[^\s~])\1(?=[^~]|$)/,
21178 text: /^([`~]+|[^`~])(?:(?= {2,}\n)|(?=[a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-]+@)|[\s\S]*?(?:(?=[\\<!\[`*~_]|\b_|https?:\/\/|ftp:\/\/|www\.|$)|[^ ](?= {2,}\n)|[^a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-](?=[a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-]+@)))/
21180 inline.gfm.url = edit(inline.gfm.url, 'i').replace('email', inline.gfm._extended_email).getRegex();
21182 * GFM + Line Breaks Inline Grammar
21185 inline.breaks = merge({}, inline.gfm, {
21186 br: edit(inline.br).replace('{2,}', '*').getRegex(),
21187 text: edit(inline.gfm.text).replace('\\b_', '\\b_| {2,}\\n').replace(/\{2,\}/g, '*').getRegex()
21191 * smartypants text replacement
21192 * @param {string} text
21194 function smartypants(text) {
21197 .replace(/---/g, "\u2014")
21199 .replace(/--/g, "\u2013")
21201 .replace(/(^|[-\u2014/(\[{"\s])'/g, "$1\u2018")
21202 // closing singles & apostrophes
21203 .replace(/'/g, "\u2019")
21205 .replace(/(^|[-\u2014/(\[{\u2018\s])"/g, "$1\u201C")
21207 .replace(/"/g, "\u201D")
21209 .replace(/\.{3}/g, "\u2026");
21213 * mangle email addresses
21214 * @param {string} text
21216 function mangle(text) {
21220 var l = text.length;
21221 for (i = 0; i < l; i++) {
21222 ch = text.charCodeAt(i);
21223 if (Math.random() > 0.5) {
21224 ch = 'x' + ch.toString(16);
21226 out += '&#' + ch + ';';
21234 var Lexer = /*#__PURE__*/function () {
21235 function Lexer(options) {
21237 this.tokens.links = Object.create(null);
21238 this.options = options || exports.defaults;
21239 this.options.tokenizer = this.options.tokenizer || new Tokenizer();
21240 this.tokenizer = this.options.tokenizer;
21241 this.tokenizer.options = this.options;
21242 this.tokenizer.lexer = this;
21243 this.inlineQueue = [];
21250 block: block.normal,
21251 inline: inline.normal
21253 if (this.options.pedantic) {
21254 rules.block = block.pedantic;
21255 rules.inline = inline.pedantic;
21256 } else if (this.options.gfm) {
21257 rules.block = block.gfm;
21258 if (this.options.breaks) {
21259 rules.inline = inline.breaks;
21261 rules.inline = inline.gfm;
21264 this.tokenizer.rules = rules;
21271 * Static Lex Method
21273 Lexer.lex = function lex(src, options) {
21274 var lexer = new Lexer(options);
21275 return lexer.lex(src);
21279 * Static Lex Inline Method
21281 Lexer.lexInline = function lexInline(src, options) {
21282 var lexer = new Lexer(options);
21283 return lexer.inlineTokens(src);
21289 var _proto = Lexer.prototype;
21290 _proto.lex = function lex(src) {
21291 src = src.replace(/\r\n|\r/g, '\n');
21292 this.blockTokens(src, this.tokens);
21294 while (next = this.inlineQueue.shift()) {
21295 this.inlineTokens(next.src, next.tokens);
21297 return this.tokens;
21303 _proto.blockTokens = function blockTokens(src, tokens) {
21305 if (tokens === void 0) {
21308 if (this.options.pedantic) {
21309 src = src.replace(/\t/g, ' ').replace(/^ +$/gm, '');
21311 src = src.replace(/^( *)(\t+)/gm, function (_, leading, tabs) {
21312 return leading + ' '.repeat(tabs.length);
21315 var token, lastToken, cutSrc, lastParagraphClipped;
21317 if (this.options.extensions && this.options.extensions.block && this.options.extensions.block.some(function (extTokenizer) {
21318 if (token = extTokenizer.call({
21321 src = src.substring(token.raw.length);
21322 tokens.push(token);
21331 if (token = this.tokenizer.space(src)) {
21332 src = src.substring(token.raw.length);
21333 if (token.raw.length === 1 && tokens.length > 0) {
21334 // if there's a single \n as a spacer, it's terminating the last line,
21335 // so move it there so that we don't get unecessary paragraph tags
21336 tokens[tokens.length - 1].raw += '\n';
21338 tokens.push(token);
21344 if (token = this.tokenizer.code(src)) {
21345 src = src.substring(token.raw.length);
21346 lastToken = tokens[tokens.length - 1];
21347 // An indented code block cannot interrupt a paragraph.
21348 if (lastToken && (lastToken.type === 'paragraph' || lastToken.type === 'text')) {
21349 lastToken.raw += '\n' + token.raw;
21350 lastToken.text += '\n' + token.text;
21351 this.inlineQueue[this.inlineQueue.length - 1].src = lastToken.text;
21353 tokens.push(token);
21359 if (token = this.tokenizer.fences(src)) {
21360 src = src.substring(token.raw.length);
21361 tokens.push(token);
21366 if (token = this.tokenizer.heading(src)) {
21367 src = src.substring(token.raw.length);
21368 tokens.push(token);
21373 if (token = this.tokenizer.hr(src)) {
21374 src = src.substring(token.raw.length);
21375 tokens.push(token);
21380 if (token = this.tokenizer.blockquote(src)) {
21381 src = src.substring(token.raw.length);
21382 tokens.push(token);
21387 if (token = this.tokenizer.list(src)) {
21388 src = src.substring(token.raw.length);
21389 tokens.push(token);
21394 if (token = this.tokenizer.html(src)) {
21395 src = src.substring(token.raw.length);
21396 tokens.push(token);
21401 if (token = this.tokenizer.def(src)) {
21402 src = src.substring(token.raw.length);
21403 lastToken = tokens[tokens.length - 1];
21404 if (lastToken && (lastToken.type === 'paragraph' || lastToken.type === 'text')) {
21405 lastToken.raw += '\n' + token.raw;
21406 lastToken.text += '\n' + token.raw;
21407 this.inlineQueue[this.inlineQueue.length - 1].src = lastToken.text;
21408 } else if (!this.tokens.links[token.tag]) {
21409 this.tokens.links[token.tag] = {
21418 if (token = this.tokenizer.table(src)) {
21419 src = src.substring(token.raw.length);
21420 tokens.push(token);
21425 if (token = this.tokenizer.lheading(src)) {
21426 src = src.substring(token.raw.length);
21427 tokens.push(token);
21431 // top-level paragraph
21432 // prevent paragraph consuming extensions by clipping 'src' to extension start
21434 if (this.options.extensions && this.options.extensions.startBlock) {
21436 var startIndex = Infinity;
21437 var tempSrc = src.slice(1);
21438 var tempStart = void 0;
21439 _this.options.extensions.startBlock.forEach(function (getStartIndex) {
21440 tempStart = getStartIndex.call({
21443 if (typeof tempStart === 'number' && tempStart >= 0) {
21444 startIndex = Math.min(startIndex, tempStart);
21447 if (startIndex < Infinity && startIndex >= 0) {
21448 cutSrc = src.substring(0, startIndex + 1);
21452 if (this.state.top && (token = this.tokenizer.paragraph(cutSrc))) {
21453 lastToken = tokens[tokens.length - 1];
21454 if (lastParagraphClipped && lastToken.type === 'paragraph') {
21455 lastToken.raw += '\n' + token.raw;
21456 lastToken.text += '\n' + token.text;
21457 this.inlineQueue.pop();
21458 this.inlineQueue[this.inlineQueue.length - 1].src = lastToken.text;
21460 tokens.push(token);
21462 lastParagraphClipped = cutSrc.length !== src.length;
21463 src = src.substring(token.raw.length);
21468 if (token = this.tokenizer.text(src)) {
21469 src = src.substring(token.raw.length);
21470 lastToken = tokens[tokens.length - 1];
21471 if (lastToken && lastToken.type === 'text') {
21472 lastToken.raw += '\n' + token.raw;
21473 lastToken.text += '\n' + token.text;
21474 this.inlineQueue.pop();
21475 this.inlineQueue[this.inlineQueue.length - 1].src = lastToken.text;
21477 tokens.push(token);
21482 var errMsg = 'Infinite loop on byte: ' + src.charCodeAt(0);
21483 if (this.options.silent) {
21484 console.error(errMsg);
21487 throw new Error(errMsg);
21491 this.state.top = true;
21494 _proto.inline = function inline(src, tokens) {
21495 if (tokens === void 0) {
21498 this.inlineQueue.push({
21508 _proto.inlineTokens = function inlineTokens(src, tokens) {
21510 if (tokens === void 0) {
21513 var token, lastToken, cutSrc;
21515 // String with links masked to avoid interference with em and strong
21516 var maskedSrc = src;
21518 var keepPrevChar, prevChar;
21520 // Mask out reflinks
21521 if (this.tokens.links) {
21522 var links = Object.keys(this.tokens.links);
21523 if (links.length > 0) {
21524 while ((match = this.tokenizer.rules.inline.reflinkSearch.exec(maskedSrc)) != null) {
21525 if (links.includes(match[0].slice(match[0].lastIndexOf('[') + 1, -1))) {
21526 maskedSrc = maskedSrc.slice(0, match.index) + '[' + repeatString('a', match[0].length - 2) + ']' + maskedSrc.slice(this.tokenizer.rules.inline.reflinkSearch.lastIndex);
21531 // Mask out other blocks
21532 while ((match = this.tokenizer.rules.inline.blockSkip.exec(maskedSrc)) != null) {
21533 maskedSrc = maskedSrc.slice(0, match.index) + '[' + repeatString('a', match[0].length - 2) + ']' + maskedSrc.slice(this.tokenizer.rules.inline.blockSkip.lastIndex);
21536 // Mask out escaped em & strong delimiters
21537 while ((match = this.tokenizer.rules.inline.escapedEmSt.exec(maskedSrc)) != null) {
21538 maskedSrc = maskedSrc.slice(0, match.index + match[0].length - 2) + '++' + maskedSrc.slice(this.tokenizer.rules.inline.escapedEmSt.lastIndex);
21539 this.tokenizer.rules.inline.escapedEmSt.lastIndex--;
21542 if (!keepPrevChar) {
21545 keepPrevChar = false;
21548 if (this.options.extensions && this.options.extensions.inline && this.options.extensions.inline.some(function (extTokenizer) {
21549 if (token = extTokenizer.call({
21552 src = src.substring(token.raw.length);
21553 tokens.push(token);
21562 if (token = this.tokenizer.escape(src)) {
21563 src = src.substring(token.raw.length);
21564 tokens.push(token);
21569 if (token = this.tokenizer.tag(src)) {
21570 src = src.substring(token.raw.length);
21571 lastToken = tokens[tokens.length - 1];
21572 if (lastToken && token.type === 'text' && lastToken.type === 'text') {
21573 lastToken.raw += token.raw;
21574 lastToken.text += token.text;
21576 tokens.push(token);
21582 if (token = this.tokenizer.link(src)) {
21583 src = src.substring(token.raw.length);
21584 tokens.push(token);
21589 if (token = this.tokenizer.reflink(src, this.tokens.links)) {
21590 src = src.substring(token.raw.length);
21591 lastToken = tokens[tokens.length - 1];
21592 if (lastToken && token.type === 'text' && lastToken.type === 'text') {
21593 lastToken.raw += token.raw;
21594 lastToken.text += token.text;
21596 tokens.push(token);
21602 if (token = this.tokenizer.emStrong(src, maskedSrc, prevChar)) {
21603 src = src.substring(token.raw.length);
21604 tokens.push(token);
21609 if (token = this.tokenizer.codespan(src)) {
21610 src = src.substring(token.raw.length);
21611 tokens.push(token);
21616 if (token = this.tokenizer.br(src)) {
21617 src = src.substring(token.raw.length);
21618 tokens.push(token);
21623 if (token = this.tokenizer.del(src)) {
21624 src = src.substring(token.raw.length);
21625 tokens.push(token);
21630 if (token = this.tokenizer.autolink(src, mangle)) {
21631 src = src.substring(token.raw.length);
21632 tokens.push(token);
21637 if (!this.state.inLink && (token = this.tokenizer.url(src, mangle))) {
21638 src = src.substring(token.raw.length);
21639 tokens.push(token);
21644 // prevent inlineText consuming extensions by clipping 'src' to extension start
21646 if (this.options.extensions && this.options.extensions.startInline) {
21648 var startIndex = Infinity;
21649 var tempSrc = src.slice(1);
21650 var tempStart = void 0;
21651 _this2.options.extensions.startInline.forEach(function (getStartIndex) {
21652 tempStart = getStartIndex.call({
21655 if (typeof tempStart === 'number' && tempStart >= 0) {
21656 startIndex = Math.min(startIndex, tempStart);
21659 if (startIndex < Infinity && startIndex >= 0) {
21660 cutSrc = src.substring(0, startIndex + 1);
21664 if (token = this.tokenizer.inlineText(cutSrc, smartypants)) {
21665 src = src.substring(token.raw.length);
21666 if (token.raw.slice(-1) !== '_') {
21667 // Track prevChar before string of ____ started
21668 prevChar = token.raw.slice(-1);
21670 keepPrevChar = true;
21671 lastToken = tokens[tokens.length - 1];
21672 if (lastToken && lastToken.type === 'text') {
21673 lastToken.raw += token.raw;
21674 lastToken.text += token.text;
21676 tokens.push(token);
21681 var errMsg = 'Infinite loop on byte: ' + src.charCodeAt(0);
21682 if (this.options.silent) {
21683 console.error(errMsg);
21686 throw new Error(errMsg);
21692 _createClass(Lexer, null, [{
21694 get: function get() {
21707 var Renderer = /*#__PURE__*/function () {
21708 function Renderer(options) {
21709 this.options = options || exports.defaults;
21711 var _proto = Renderer.prototype;
21712 _proto.code = function code(_code, infostring, escaped) {
21713 var lang = (infostring || '').match(/\S*/)[0];
21714 if (this.options.highlight) {
21715 var out = this.options.highlight(_code, lang);
21716 if (out != null && out !== _code) {
21721 _code = _code.replace(/\n$/, '') + '\n';
21723 return '<pre><code>' + (escaped ? _code : escape(_code, true)) + '</code></pre>\n';
21725 return '<pre><code class="' + this.options.langPrefix + escape(lang) + '">' + (escaped ? _code : escape(_code, true)) + '</code></pre>\n';
21729 * @param {string} quote
21731 _proto.blockquote = function blockquote(quote) {
21732 return "<blockquote>\n" + quote + "</blockquote>\n";
21734 _proto.html = function html(_html) {
21739 * @param {string} text
21740 * @param {string} level
21741 * @param {string} raw
21742 * @param {any} slugger
21744 _proto.heading = function heading(text, level, raw, slugger) {
21745 if (this.options.headerIds) {
21746 var id = this.options.headerPrefix + slugger.slug(raw);
21747 return "<h" + level + " id=\"" + id + "\">" + text + "</h" + level + ">\n";
21751 return "<h" + level + ">" + text + "</h" + level + ">\n";
21753 _proto.hr = function hr() {
21754 return this.options.xhtml ? '<hr/>\n' : '<hr>\n';
21756 _proto.list = function list(body, ordered, start) {
21757 var type = ordered ? 'ol' : 'ul',
21758 startatt = ordered && start !== 1 ? ' start="' + start + '"' : '';
21759 return '<' + type + startatt + '>\n' + body + '</' + type + '>\n';
21763 * @param {string} text
21765 _proto.listitem = function listitem(text) {
21766 return "<li>" + text + "</li>\n";
21768 _proto.checkbox = function checkbox(checked) {
21769 return '<input ' + (checked ? 'checked="" ' : '') + 'disabled="" type="checkbox"' + (this.options.xhtml ? ' /' : '') + '> ';
21773 * @param {string} text
21775 _proto.paragraph = function paragraph(text) {
21776 return "<p>" + text + "</p>\n";
21780 * @param {string} header
21781 * @param {string} body
21783 _proto.table = function table(header, body) {
21784 if (body) body = "<tbody>" + body + "</tbody>";
21785 return '<table>\n' + '<thead>\n' + header + '</thead>\n' + body + '</table>\n';
21789 * @param {string} content
21791 _proto.tablerow = function tablerow(content) {
21792 return "<tr>\n" + content + "</tr>\n";
21794 _proto.tablecell = function tablecell(content, flags) {
21795 var type = flags.header ? 'th' : 'td';
21796 var tag = flags.align ? "<" + type + " align=\"" + flags.align + "\">" : "<" + type + ">";
21797 return tag + content + ("</" + type + ">\n");
21801 * span level renderer
21802 * @param {string} text
21804 _proto.strong = function strong(text) {
21805 return "<strong>" + text + "</strong>";
21809 * @param {string} text
21811 _proto.em = function em(text) {
21812 return "<em>" + text + "</em>";
21816 * @param {string} text
21818 _proto.codespan = function codespan(text) {
21819 return "<code>" + text + "</code>";
21821 _proto.br = function br() {
21822 return this.options.xhtml ? '<br/>' : '<br>';
21826 * @param {string} text
21828 _proto.del = function del(text) {
21829 return "<del>" + text + "</del>";
21833 * @param {string} href
21834 * @param {string} title
21835 * @param {string} text
21837 _proto.link = function link(href, title, text) {
21838 href = cleanUrl(this.options.sanitize, this.options.baseUrl, href);
21839 if (href === null) {
21842 var out = '<a href="' + href + '"';
21844 out += ' title="' + title + '"';
21846 out += '>' + text + '</a>';
21851 * @param {string} href
21852 * @param {string} title
21853 * @param {string} text
21855 _proto.image = function image(href, title, text) {
21856 href = cleanUrl(this.options.sanitize, this.options.baseUrl, href);
21857 if (href === null) {
21860 var out = "<img src=\"" + href + "\" alt=\"" + text + "\"";
21862 out += " title=\"" + title + "\"";
21864 out += this.options.xhtml ? '/>' : '>';
21867 _proto.text = function text(_text) {
21875 * returns only the textual part of the token
21877 var TextRenderer = /*#__PURE__*/function () {
21878 function TextRenderer() {}
21879 var _proto = TextRenderer.prototype;
21880 // no need for block level renderers
21881 _proto.strong = function strong(text) {
21884 _proto.em = function em(text) {
21887 _proto.codespan = function codespan(text) {
21890 _proto.del = function del(text) {
21893 _proto.html = function html(text) {
21896 _proto.text = function text(_text) {
21899 _proto.link = function link(href, title, text) {
21902 _proto.image = function image(href, title, text) {
21905 _proto.br = function br() {
21908 return TextRenderer;
21912 * Slugger generates header id
21914 var Slugger = /*#__PURE__*/function () {
21915 function Slugger() {
21920 * @param {string} value
21922 var _proto = Slugger.prototype;
21923 _proto.serialize = function serialize(value) {
21924 return value.toLowerCase().trim()
21925 // remove html tags
21926 .replace(/<[!\/a-z].*?>/ig, '')
21927 // remove unwanted chars
21928 .replace(/[\u2000-\u206F\u2E00-\u2E7F\\'!"#$%&()*+,./:;<=>?@[\]^`{|}~]/g, '').replace(/\s/g, '-');
21932 * Finds the next safe (unique) slug to use
21933 * @param {string} originalSlug
21934 * @param {boolean} isDryRun
21936 _proto.getNextSafeSlug = function getNextSafeSlug(originalSlug, isDryRun) {
21937 var slug = originalSlug;
21938 var occurenceAccumulator = 0;
21939 if (this.seen.hasOwnProperty(slug)) {
21940 occurenceAccumulator = this.seen[originalSlug];
21942 occurenceAccumulator++;
21943 slug = originalSlug + '-' + occurenceAccumulator;
21944 } while (this.seen.hasOwnProperty(slug));
21947 this.seen[originalSlug] = occurenceAccumulator;
21948 this.seen[slug] = 0;
21954 * Convert string to unique id
21955 * @param {object} [options]
21956 * @param {boolean} [options.dryrun] Generates the next unique slug without
21957 * updating the internal accumulator.
21959 _proto.slug = function slug(value, options) {
21960 if (options === void 0) {
21963 var slug = this.serialize(value);
21964 return this.getNextSafeSlug(slug, options.dryrun);
21970 * Parsing & Compiling
21972 var Parser = /*#__PURE__*/function () {
21973 function Parser(options) {
21974 this.options = options || exports.defaults;
21975 this.options.renderer = this.options.renderer || new Renderer();
21976 this.renderer = this.options.renderer;
21977 this.renderer.options = this.options;
21978 this.textRenderer = new TextRenderer();
21979 this.slugger = new Slugger();
21983 * Static Parse Method
21985 Parser.parse = function parse(tokens, options) {
21986 var parser = new Parser(options);
21987 return parser.parse(tokens);
21991 * Static Parse Inline Method
21993 Parser.parseInline = function parseInline(tokens, options) {
21994 var parser = new Parser(options);
21995 return parser.parseInline(tokens);
22001 var _proto = Parser.prototype;
22002 _proto.parse = function parse(tokens, top) {
22003 if (top === void 0) {
22026 var l = tokens.length;
22027 for (i = 0; i < l; i++) {
22030 // Run any renderer extensions
22031 if (this.options.extensions && this.options.extensions.renderers && this.options.extensions.renderers[token.type]) {
22032 ret = this.options.extensions.renderers[token.type].call({
22035 if (ret !== false || !['space', 'hr', 'heading', 'code', 'table', 'blockquote', 'list', 'html', 'paragraph', 'text'].includes(token.type)) {
22040 switch (token.type) {
22047 out += this.renderer.hr();
22052 out += this.renderer.heading(this.parseInline(token.tokens), token.depth, unescape(this.parseInline(token.tokens, this.textRenderer)), this.slugger);
22057 out += this.renderer.code(token.text, token.lang, token.escaped);
22066 l2 = token.header.length;
22067 for (j = 0; j < l2; j++) {
22068 cell += this.renderer.tablecell(this.parseInline(token.header[j].tokens), {
22070 align: token.align[j]
22073 header += this.renderer.tablerow(cell);
22075 l2 = token.rows.length;
22076 for (j = 0; j < l2; j++) {
22077 row = token.rows[j];
22080 for (k = 0; k < l3; k++) {
22081 cell += this.renderer.tablecell(this.parseInline(row[k].tokens), {
22083 align: token.align[k]
22086 body += this.renderer.tablerow(cell);
22088 out += this.renderer.table(header, body);
22093 body = this.parse(token.tokens);
22094 out += this.renderer.blockquote(body);
22099 ordered = token.ordered;
22100 start = token.start;
22101 loose = token.loose;
22102 l2 = token.items.length;
22104 for (j = 0; j < l2; j++) {
22105 item = token.items[j];
22106 checked = item.checked;
22110 checkbox = this.renderer.checkbox(checked);
22112 if (item.tokens.length > 0 && item.tokens[0].type === 'paragraph') {
22113 item.tokens[0].text = checkbox + ' ' + item.tokens[0].text;
22114 if (item.tokens[0].tokens && item.tokens[0].tokens.length > 0 && item.tokens[0].tokens[0].type === 'text') {
22115 item.tokens[0].tokens[0].text = checkbox + ' ' + item.tokens[0].tokens[0].text;
22118 item.tokens.unshift({
22124 itemBody += checkbox;
22127 itemBody += this.parse(item.tokens, loose);
22128 body += this.renderer.listitem(itemBody, task, checked);
22130 out += this.renderer.list(body, ordered, start);
22135 // TODO parse inline content if parameter markdown=1
22136 out += this.renderer.html(token.text);
22141 out += this.renderer.paragraph(this.parseInline(token.tokens));
22146 body = token.tokens ? this.parseInline(token.tokens) : token.text;
22147 while (i + 1 < l && tokens[i + 1].type === 'text') {
22148 token = tokens[++i];
22149 body += '\n' + (token.tokens ? this.parseInline(token.tokens) : token.text);
22151 out += top ? this.renderer.paragraph(body) : body;
22156 var errMsg = 'Token with "' + token.type + '" type was not found.';
22157 if (this.options.silent) {
22158 console.error(errMsg);
22161 throw new Error(errMsg);
22170 * Parse Inline Tokens
22172 _proto.parseInline = function parseInline(tokens, renderer) {
22173 renderer = renderer || this.renderer;
22178 var l = tokens.length;
22179 for (i = 0; i < l; i++) {
22182 // Run any renderer extensions
22183 if (this.options.extensions && this.options.extensions.renderers && this.options.extensions.renderers[token.type]) {
22184 ret = this.options.extensions.renderers[token.type].call({
22187 if (ret !== false || !['escape', 'html', 'link', 'image', 'strong', 'em', 'codespan', 'br', 'del', 'text'].includes(token.type)) {
22192 switch (token.type) {
22195 out += renderer.text(token.text);
22200 out += renderer.html(token.text);
22205 out += renderer.link(token.href, token.title, this.parseInline(token.tokens, renderer));
22210 out += renderer.image(token.href, token.title, token.text);
22215 out += renderer.strong(this.parseInline(token.tokens, renderer));
22220 out += renderer.em(this.parseInline(token.tokens, renderer));
22225 out += renderer.codespan(token.text);
22230 out += renderer.br();
22235 out += renderer.del(this.parseInline(token.tokens, renderer));
22240 out += renderer.text(token.text);
22245 var errMsg = 'Token with "' + token.type + '" type was not found.';
22246 if (this.options.silent) {
22247 console.error(errMsg);
22250 throw new Error(errMsg);
22263 function marked(src, opt, callback) {
22264 // throw error in case of non string input
22265 if (typeof src === 'undefined' || src === null) {
22266 throw new Error('marked(): input parameter is undefined or null');
22268 if (typeof src !== 'string') {
22269 throw new Error('marked(): input parameter is of type ' + Object.prototype.toString.call(src) + ', string expected');
22271 if (typeof opt === 'function') {
22275 opt = merge({}, marked.defaults, opt || {});
22276 checkSanitizeDeprecation(opt);
22278 var highlight = opt.highlight;
22281 tokens = Lexer.lex(src, opt);
22283 return callback(e);
22285 var done = function done(err) {
22289 if (opt.walkTokens) {
22290 marked.walkTokens(tokens, opt.walkTokens);
22292 out = Parser.parse(tokens, opt);
22297 opt.highlight = highlight;
22298 return err ? callback(err) : callback(null, out);
22300 if (!highlight || highlight.length < 3) {
22303 delete opt.highlight;
22304 if (!tokens.length) return done();
22306 marked.walkTokens(tokens, function (token) {
22307 if (token.type === 'code') {
22309 setTimeout(function () {
22310 highlight(token.text, token.lang, function (err, code) {
22314 if (code != null && code !== token.text) {
22316 token.escaped = true;
22319 if (pending === 0) {
22326 if (pending === 0) {
22331 function onError(e) {
22332 e.message += '\nPlease report this to https://github.com/markedjs/marked.';
22334 return '<p>An error occurred:</p><pre>' + escape(e.message + '', true) + '</pre>';
22339 var _tokens = Lexer.lex(src, opt);
22340 if (opt.walkTokens) {
22342 return Promise.all(marked.walkTokens(_tokens, opt.walkTokens)).then(function () {
22343 return Parser.parse(_tokens, opt);
22344 })["catch"](onError);
22346 marked.walkTokens(_tokens, opt.walkTokens);
22348 return Parser.parse(_tokens, opt);
22358 marked.options = marked.setOptions = function (opt) {
22359 merge(marked.defaults, opt);
22360 changeDefaults(marked.defaults);
22363 marked.getDefaults = getDefaults;
22364 marked.defaults = exports.defaults;
22370 marked.use = function () {
22371 var extensions = marked.defaults.extensions || {
22375 for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
22376 args[_key] = arguments[_key];
22378 args.forEach(function (pack) {
22379 // copy options to new object
22380 var opts = merge({}, pack);
22382 // set async to true if it was set to true before
22383 opts.async = marked.defaults.async || opts.async;
22385 // ==-- Parse "addon" extensions --== //
22386 if (pack.extensions) {
22387 pack.extensions.forEach(function (ext) {
22389 throw new Error('extension name required');
22391 if (ext.renderer) {
22392 // Renderer extensions
22393 var prevRenderer = extensions.renderers[ext.name];
22394 if (prevRenderer) {
22395 // Replace extension with func to run new extension but fall back if false
22396 extensions.renderers[ext.name] = function () {
22397 for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
22398 args[_key2] = arguments[_key2];
22400 var ret = ext.renderer.apply(this, args);
22401 if (ret === false) {
22402 ret = prevRenderer.apply(this, args);
22407 extensions.renderers[ext.name] = ext.renderer;
22410 if (ext.tokenizer) {
22411 // Tokenizer Extensions
22412 if (!ext.level || ext.level !== 'block' && ext.level !== 'inline') {
22413 throw new Error("extension level must be 'block' or 'inline'");
22415 if (extensions[ext.level]) {
22416 extensions[ext.level].unshift(ext.tokenizer);
22418 extensions[ext.level] = [ext.tokenizer];
22421 // Function to check for start of token
22422 if (ext.level === 'block') {
22423 if (extensions.startBlock) {
22424 extensions.startBlock.push(ext.start);
22426 extensions.startBlock = [ext.start];
22428 } else if (ext.level === 'inline') {
22429 if (extensions.startInline) {
22430 extensions.startInline.push(ext.start);
22432 extensions.startInline = [ext.start];
22437 if (ext.childTokens) {
22438 // Child tokens to be visited by walkTokens
22439 extensions.childTokens[ext.name] = ext.childTokens;
22442 opts.extensions = extensions;
22445 // ==-- Parse "overwrite" extensions --== //
22446 if (pack.renderer) {
22448 var renderer = marked.defaults.renderer || new Renderer();
22449 var _loop = function _loop(prop) {
22450 var prevRenderer = renderer[prop];
22451 // Replace renderer with func to run extension, but fall back if false
22452 renderer[prop] = function () {
22453 for (var _len3 = arguments.length, args = new Array(_len3), _key3 = 0; _key3 < _len3; _key3++) {
22454 args[_key3] = arguments[_key3];
22456 var ret = pack.renderer[prop].apply(renderer, args);
22457 if (ret === false) {
22458 ret = prevRenderer.apply(renderer, args);
22463 for (var prop in pack.renderer) {
22466 opts.renderer = renderer;
22469 if (pack.tokenizer) {
22471 var tokenizer = marked.defaults.tokenizer || new Tokenizer();
22472 var _loop2 = function _loop2(prop) {
22473 var prevTokenizer = tokenizer[prop];
22474 // Replace tokenizer with func to run extension, but fall back if false
22475 tokenizer[prop] = function () {
22476 for (var _len4 = arguments.length, args = new Array(_len4), _key4 = 0; _key4 < _len4; _key4++) {
22477 args[_key4] = arguments[_key4];
22479 var ret = pack.tokenizer[prop].apply(tokenizer, args);
22480 if (ret === false) {
22481 ret = prevTokenizer.apply(tokenizer, args);
22486 for (var prop in pack.tokenizer) {
22489 opts.tokenizer = tokenizer;
22493 // ==-- Parse WalkTokens extensions --== //
22494 if (pack.walkTokens) {
22495 var _walkTokens = marked.defaults.walkTokens;
22496 opts.walkTokens = function (token) {
22498 values.push(pack.walkTokens.call(this, token));
22500 values = values.concat(_walkTokens.call(this, token));
22505 marked.setOptions(opts);
22510 * Run callback for every token
22513 marked.walkTokens = function (tokens, callback) {
22515 var _loop3 = function _loop3() {
22516 var token = _step.value;
22517 values = values.concat(callback.call(marked, token));
22518 switch (token.type) {
22521 for (var _iterator2 = _createForOfIteratorHelperLoose(token.header), _step2; !(_step2 = _iterator2()).done;) {
22522 var cell = _step2.value;
22523 values = values.concat(marked.walkTokens(cell.tokens, callback));
22525 for (var _iterator3 = _createForOfIteratorHelperLoose(token.rows), _step3; !(_step3 = _iterator3()).done;) {
22526 var row = _step3.value;
22527 for (var _iterator4 = _createForOfIteratorHelperLoose(row), _step4; !(_step4 = _iterator4()).done;) {
22528 var _cell = _step4.value;
22529 values = values.concat(marked.walkTokens(_cell.tokens, callback));
22536 values = values.concat(marked.walkTokens(token.items, callback));
22541 if (marked.defaults.extensions && marked.defaults.extensions.childTokens && marked.defaults.extensions.childTokens[token.type]) {
22542 // Walk any extensions
22543 marked.defaults.extensions.childTokens[token.type].forEach(function (childTokens) {
22544 values = values.concat(marked.walkTokens(token[childTokens], callback));
22546 } else if (token.tokens) {
22547 values = values.concat(marked.walkTokens(token.tokens, callback));
22552 for (var _iterator = _createForOfIteratorHelperLoose(tokens), _step; !(_step = _iterator()).done;) {
22560 * @param {string} src
22562 marked.parseInline = function (src, opt) {
22563 // throw error in case of non string input
22564 if (typeof src === 'undefined' || src === null) {
22565 throw new Error('marked.parseInline(): input parameter is undefined or null');
22567 if (typeof src !== 'string') {
22568 throw new Error('marked.parseInline(): input parameter is of type ' + Object.prototype.toString.call(src) + ', string expected');
22570 opt = merge({}, marked.defaults, opt || {});
22571 checkSanitizeDeprecation(opt);
22573 var tokens = Lexer.lexInline(src, opt);
22574 if (opt.walkTokens) {
22575 marked.walkTokens(tokens, opt.walkTokens);
22577 return Parser.parseInline(tokens, opt);
22579 e.message += '\nPlease report this to https://github.com/markedjs/marked.';
22581 return '<p>An error occurred:</p><pre>' + escape(e.message + '', true) + '</pre>';
22590 marked.Parser = Parser;
22591 marked.parser = Parser.parse;
22592 marked.Renderer = Renderer;
22593 marked.TextRenderer = TextRenderer;
22594 marked.Lexer = Lexer;
22595 marked.lexer = Lexer.lex;
22596 marked.Tokenizer = Tokenizer;
22597 marked.Slugger = Slugger;
22598 marked.parse = marked;
22599 var options = marked.options;
22600 var setOptions = marked.setOptions;
22601 var use = marked.use;
22602 var walkTokens = marked.walkTokens;
22603 var parseInline = marked.parseInline;
22604 var parse = marked;
22605 var parser = Parser.parse;
22606 var lexer = Lexer.lex;
22608 exports.Lexer = Lexer;
22609 exports.Parser = Parser;
22610 exports.Renderer = Renderer;
22611 exports.Slugger = Slugger;
22612 exports.TextRenderer = TextRenderer;
22613 exports.Tokenizer = Tokenizer;
22614 exports.getDefaults = getDefaults;
22615 exports.lexer = lexer;
22616 exports.marked = marked;
22617 exports.options = options;
22618 exports.parse = parse;
22619 exports.parseInline = parseInline;
22620 exports.parser = parser;
22621 exports.setOptions = setOptions;
22623 exports.walkTokens = walkTokens;
22628 /***/ "./src/test-data.json":
22629 /*!****************************!*\
22630 !*** ./src/test-data.json ***!
22631 \****************************/
22632 /***/ ((module) => {
22635 module.exports = JSON.parse('{"id":"000000","name":"Sample","created":"1674409747467","tree":{"id":"000000","collapsed":false,"children":[{"id":"000001","collapsed":false,"children":[]},{"id":"1dc4c363-7440-4661-bbc5-7e995dc6ba71","collapsed":false,"children":[]},{"id":"e067419d-85c3-422d-b8c4-41690be4450d","collapsed":false,"children":[{"id":"6addd61d-d12f-4a27-a471-513becfff006","children":[],"collapsed":false}]},{"id":"2ab706de-fea9-42a0-a900-e88b2950ceb3","collapsed":false,"children":[{"id":"27c14755-ff26-4931-a676-b48cd958b781","children":[{"id":"116f8e0f-ab62-450f-914e-5ca0956a457f","children":[],"collapsed":false}],"collapsed":true},{"id":"d69efd32-fbf5-4b80-8a36-af1cb2af7b80","children":[{"id":"b5a55548-f65d-496a-8bea-6b6ba8296e21","children":[],"collapsed":false}],"collapsed":true},{"id":"2f67d730-c71b-4823-a986-fa510d9408e1","children":[{"id":"40194ea5-9c28-4adb-bffe-4f59e7eca666","children":[],"collapsed":false}],"collapsed":true}]},{"id":"21df5e96-d770-43f0-8bd1-1b01ab4626f9","collapsed":false,"children":[]},{"id":"89c3267b-0114-4138-98a8-443b28d2e679","collapsed":false,"children":[{"id":"6b457d6b-0228-41b7-bbba-6c0ba3b54f4d","collapsed":false,"children":[{"id":"bad021fc-24d1-4560-8321-042c28d438a8","collapsed":false,"children":[]}]},{"id":"9690699a-cb7d-4123-8fa5-f7a58a191a08","children":[{"id":"2831a7aa-7291-4ebc-997f-5572e767f5c0","children":[],"collapsed":false}],"collapsed":false},{"id":"88d336be-4910-4d74-b79a-441894af956d","collapsed":false,"children":[{"id":"eb7fd6d7-b3fe-46e5-814c-655a6eec2ba4","children":[],"collapsed":false}]},{"id":"51b2f235-b979-4d74-ad83-3e8b6152bb4a","collapsed":false,"children":[{"id":"9c576012-7e8f-4d2b-b58b-1886eba43341","children":[],"collapsed":false}]}]},{"id":"ef04ea02-aed6-4295-9117-2dcc45506f3a","collapsed":false,"children":[{"id":"255bfdfc-9260-4cb1-9dcd-15f2c9eca2b2","children":[{"id":"40b53a6f-0f43-40c2-b6d3-486982fc9d48","children":[{"id":"724d0e33-fe2c-459e-9e75-e3311809ba36","children":[],"collapsed":false},{"id":"588a65fd-69dd-4bb4-a819-f8c7f05a1d69","collapsed":false,"children":[]},{"id":"13ea01fb-339d-4e65-9fad-123d72830efb","collapsed":false,"children":[]},{"id":"a941538b-6834-4a65-b297-50036b89a41f","collapsed":false,"children":[]}],"collapsed":false},{"id":"80b86062-a197-4adf-baa4-56a5953e0a77","collapsed":false,"children":[{"id":"c09a5876-f825-4cb0-9a56-2916e28f9d02","children":[],"collapsed":false}]}],"collapsed":false}]}]},"contentNodes":{"000001":{"id":"000001","created":1674409747467,"type":"text","content":"**Welcome to my Outliner**<br>"},"e067419d-85c3-422d-b8c4-41690be4450d":{"id":"e067419d-85c3-422d-b8c4-41690be4450d","created":1674412571215,"type":"text","content":"This is my attempt to build a \\"home base\\" piece of software for myself. The goal is to be able to use this tool to serve as a way to write long-form content, manage my website, and keep notes + references. <br>"},"21df5e96-d770-43f0-8bd1-1b01ab4626f9":{"id":"21df5e96-d770-43f0-8bd1-1b01ab4626f9","created":1674412689419,"type":"text","content":"---"},"89c3267b-0114-4138-98a8-443b28d2e679":{"id":"89c3267b-0114-4138-98a8-443b28d2e679","created":1674412690374,"type":"text","content":"**FAQ**"},"9690699a-cb7d-4123-8fa5-f7a58a191a08":{"id":"9690699a-cb7d-4123-8fa5-f7a58a191a08","created":1674412696214,"type":"text","content":"**Why should I use this?**<br>"},"2831a7aa-7291-4ebc-997f-5572e767f5c0":{"id":"2831a7aa-7291-4ebc-997f-5572e767f5c0","created":1674412702948,"type":"text","content":"You shouldn\'t. This isn\'t a piece of software for you - it\'s for me. You may find some use for it, but you also may not. Along the way features will be introduced that likely break things for you.<br>"},"51b2f235-b979-4d74-ad83-3e8b6152bb4a":{"id":"51b2f235-b979-4d74-ad83-3e8b6152bb4a","created":1674412786944,"type":"text","content":"**Ok I used it, but my data is trapped?**<br>"},"9c576012-7e8f-4d2b-b58b-1886eba43341":{"id":"9c576012-7e8f-4d2b-b58b-1886eba43341","created":1674412794788,"type":"text","content":"I\'ll be adding the ability to export the entire thing as OPML, so that there\'s some interop between this and all of [Dave Winer\'s](https://scripting.com) tooling. Hopefully that\'s enough. At some point I\'m going to also introduce support for [RemoteStorage](https://remotestorage.io) which is a project that I\'ve previous contributed to in the past, but have mostly been neglecting lately. I\'m hoping between those two options that\'ll be enough for \\"backups\\" of data.<br>"},"88d336be-4910-4d74-b79a-441894af956d":{"id":"88d336be-4910-4d74-b79a-441894af956d","created":1674412890012,"type":"text","content":"**If I use this, does this mean you have access to all my data?**<br>"},"eb7fd6d7-b3fe-46e5-814c-655a6eec2ba4":{"id":"eb7fd6d7-b3fe-46e5-814c-655a6eec2ba4","created":1674412907752,"type":"text","content":"No. I\'m trying to keep this entirely \\"static\\" and \\"offline first\\". You should be able to use this without concern that I\'ll be watching what you type. Like I said - this is primarily a tool for me, and I already have access to all of my content.<br>"},"bad021fc-24d1-4560-8321-042c28d438a8":{"id":"bad021fc-24d1-4560-8321-042c28d438a8","created":1674491030563,"type":"text","content":"An outliner is simply a tool that allows for \\"infinite\\" hierarchy. You can create nested nodes, move them around, and generally treat it like a big old bulleted list. It seem silly, but being able to sort your list whenever you feel like is a huge deal. <br>"},"1dc4c363-7440-4661-bbc5-7e995dc6ba71":{"id":"1dc4c363-7440-4661-bbc5-7e995dc6ba71","created":1674491120429,"type":"text","content":"I\'ve long been a user of [Dave Winer\'s](https://scripting.com) outliner tools for the last decade since I first discovered Outliners. They\'ve been a massive benefit to me as I attempt to organize my thoughts across a variety of subjects. I\'ve also always struggled to adopt existing tooling as I found that they were ALMOST what I wanted.<br>"},"6addd61d-d12f-4a27-a471-513becfff006":{"id":"6addd61d-d12f-4a27-a471-513becfff006","created":1674491272253,"type":"text","content":"![Thumbs Up](http://www.tmsauto.com/wp-content/uploads/3-thumbs-up.jpg)<br>"},"ef04ea02-aed6-4295-9117-2dcc45506f3a":{"id":"ef04ea02-aed6-4295-9117-2dcc45506f3a","created":1674494561538,"type":"text","content":"**Changelog**"},"255bfdfc-9260-4cb1-9dcd-15f2c9eca2b2":{"id":"255bfdfc-9260-4cb1-9dcd-15f2c9eca2b2","created":1674494572205,"type":"text","content":"**2023-01-23 - Initial Release**<br>"},"40b53a6f-0f43-40c2-b6d3-486982fc9d48":{"id":"40b53a6f-0f43-40c2-b6d3-486982fc9d48","created":1674494588998,"type":"text","content":"The outliner supports all standard outliner functionality<br>"},"850bac59-c64f-4884-a24c-a10cad6b38c2":{"id":"850bac59-c64f-4884-a24c-a10cad6b38c2","created":1674494607269,"type":"text","content":"---"},"cccd8044-92b6-4e89-887c-2f979f4e0cab":{"id":"cccd8044-92b6-4e89-887c-2f979f4e0cab","created":1674494607378,"type":"text","content":"---"},"724d0e33-fe2c-459e-9e75-e3311809ba36":{"id":"724d0e33-fe2c-459e-9e75-e3311809ba36","created":1674496047585,"type":"text","content":"Ability to create/remove nodes at the same level or as children of the selected node<br>"},"588a65fd-69dd-4bb4-a819-f8c7f05a1d69":{"id":"588a65fd-69dd-4bb4-a819-f8c7f05a1d69","created":1674496066859,"type":"text","content":"Ability to move nodes up and down within the same level<br>"},"13ea01fb-339d-4e65-9fad-123d72830efb":{"id":"13ea01fb-339d-4e65-9fad-123d72830efb","created":1674496078557,"type":"text","content":"Ability to lift/lower nodes in the hierarchy<br>"},"80b86062-a197-4adf-baa4-56a5953e0a77":{"id":"80b86062-a197-4adf-baa4-56a5953e0a77","created":1674496103163,"type":"text","content":"**Known Issues**<br>"},"c09a5876-f825-4cb0-9a56-2916e28f9d02":{"id":"c09a5876-f825-4cb0-9a56-2916e28f9d02","created":1674496115316,"type":"text","content":"The `findNodeInTree` method seems to jump through the list multiple times and needs to be properly terminated. There\'s a hack in place right now that stops it from triggering the handler multiple times, but it would be good to get that fixed<br>"},"a941538b-6834-4a65-b297-50036b89a41f":{"id":"a941538b-6834-4a65-b297-50036b89a41f","created":1674496226731,"type":"text","content":"Ability to fold/unfold nodes to hide/display nested content<br>"},"6b457d6b-0228-41b7-bbba-6c0ba3b54f4d":{"id":"6b457d6b-0228-41b7-bbba-6c0ba3b54f4d","created":1674499489509,"type":"text","content":"**What is an outliner?**<br>"},"2ab706de-fea9-42a0-a900-e88b2950ceb3":{"id":"2ab706de-fea9-42a0-a900-e88b2950ceb3","created":1674504320041,"type":"text","content":"**Features**<br>"},"27c14755-ff26-4931-a676-b48cd958b781":{"id":"27c14755-ff26-4931-a676-b48cd958b781","created":1674504328945,"type":"text","content":"- [x] A simple keyboard-navigated outliner where each node supports Markdown<br>"},"116f8e0f-ab62-450f-914e-5ca0956a457f":{"id":"116f8e0f-ab62-450f-914e-5ca0956a457f","created":1674504343967,"type":"text","content":"This is probably the single biggest difference from other outliners - and it really is a simple change. The text nodes are all markdown - so by default it supports anything that would render via [marked.js](https://marked.js.org/). <br>"},"974ebeda-2d49-4a31-9bcc-666c6b910702":{"id":"974ebeda-2d49-4a31-9bcc-666c6b910702","created":1674504414730,"type":"text","content":"Roadmap<br>"},"b00509a3-694a-4159-b9f0-fdc11e1e04e3":{"id":"b00509a3-694a-4159-b9f0-fdc11e1e04e3","created":1674504415116,"type":"text","content":"---"},"3c51e000-8bf7-469d-94e5-4480b980993c":{"id":"3c51e000-8bf7-469d-94e5-4480b980993c","created":1674504438403,"type":"text","content":"---"},"0da3090a-9a6f-4b3f-9607-0e97bd4318f5":{"id":"0da3090a-9a6f-4b3f-9607-0e97bd4318f5","created":1674504442196,"type":"text","content":"Current"},"d69efd32-fbf5-4b80-8a36-af1cb2af7b80":{"id":"d69efd32-fbf5-4b80-8a36-af1cb2af7b80","created":1674504453605,"type":"text","content":"- [ ] Search!"},"b5a55548-f65d-496a-8bea-6b6ba8296e21":{"id":"b5a55548-f65d-496a-8bea-6b6ba8296e21","created":1674504458424,"type":"text","content":"This is the most important one. The ability to fuzzy search across the entirety of the document and jump to any node possible. When I was working with Fargo + Little Outliner, I tried building extensions that would allow me to do this - but they never quite worked as I envisioned. I\'m hoping to provide a full fuzzy-text search system<br>"},"315c3870-a6c2-49b6-89b1-8c9e0a950b4c":{"id":"315c3870-a6c2-49b6-89b1-8c9e0a950b4c","created":1674504522443,"type":"text","content":"---"},"4f84fa9b-bc13-43fa-9e31-cf4a0c976d27":{"id":"4f84fa9b-bc13-43fa-9e31-cf4a0c976d27","created":1674504522958,"type":"text","content":"---"},"2f67d730-c71b-4823-a986-fa510d9408e1":{"id":"2f67d730-c71b-4823-a986-fa510d9408e1","created":1674504531115,"type":"text","content":"- [ ] Export Data<br>"},"bb64c043-b69f-49f8-bde4-9018822d929b":{"id":"bb64c043-b69f-49f8-bde4-9018822d929b","created":1674504546666,"type":"text","content":"Being able to \\"publish\\" a node and <br>"},"40194ea5-9c28-4adb-bffe-4f59e7eca666":{"id":"40194ea5-9c28-4adb-bffe-4f59e7eca666","created":1674504558701,"type":"text","content":"Being able to export the data to OPML at any point will go a long way to ensuring that the tool never locks me in if I decide to leave<br>"},"82956c9c-33d1-44e1-aca7-298cdfc4c72c":{"id":"82956c9c-33d1-44e1-aca7-298cdfc4c72c","created":1674504834120,"type":"text","content":"---"},"a1f74891-c98b-4fc2-a7ce-c18b2ad2b8d0":{"id":"a1f74891-c98b-4fc2-a7ce-c18b2ad2b8d0","created":1674504838755,"type":"text","content":"---"},"e1e60a99-74da-436c-b140-ce8c10832889":{"id":"e1e60a99-74da-436c-b140-ce8c10832889","created":1674504891810,"type":"text","content":"---"},"de5fd362-402e-4769-8429-9fecab882da0":{"id":"de5fd362-402e-4769-8429-9fecab882da0","created":1674504894934,"type":"text","content":"---"},"de9ca950-e7c0-4f10-b65e-a5cf9000a618":{"id":"de9ca950-e7c0-4f10-b65e-a5cf9000a618","created":1674504899904,"type":"text","content":"---"},"8f1a787f-01b5-4b72-8308-8a3fe0a96383":{"id":"8f1a787f-01b5-4b72-8308-8a3fe0a96383","created":1674504923176,"type":"text","content":"eys"}}}');
22640 /************************************************************************/
22641 /******/ // The module cache
22642 /******/ var __webpack_module_cache__ = {};
22644 /******/ // The require function
22645 /******/ function __webpack_require__(moduleId) {
22646 /******/ // Check if module is in cache
22647 /******/ var cachedModule = __webpack_module_cache__[moduleId];
22648 /******/ if (cachedModule !== undefined) {
22649 /******/ return cachedModule.exports;
22651 /******/ // Create a new module (and put it into the cache)
22652 /******/ var module = __webpack_module_cache__[moduleId] = {
22653 /******/ id: moduleId,
22654 /******/ loaded: false,
22655 /******/ exports: {}
22658 /******/ // Execute the module function
22659 /******/ __webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__);
22661 /******/ // Flag the module as loaded
22662 /******/ module.loaded = true;
22664 /******/ // Return the exports of the module
22665 /******/ return module.exports;
22668 /************************************************************************/
22669 /******/ /* webpack/runtime/global */
22671 /******/ __webpack_require__.g = (function() {
22672 /******/ if (typeof globalThis === 'object') return globalThis;
22674 /******/ return this || new Function('return this')();
22675 /******/ } catch (e) {
22676 /******/ if (typeof window === 'object') return window;
22681 /******/ /* webpack/runtime/node module decorator */
22683 /******/ __webpack_require__.nmd = (module) => {
22684 /******/ module.paths = [];
22685 /******/ if (!module.children) module.children = [];
22686 /******/ return module;
22690 /************************************************************************/
22692 /******/ // startup
22693 /******/ // Load entry module and return exports
22694 /******/ // This entry module is referenced by other modules so it can't be inlined
22695 /******/ var __webpack_exports__ = __webpack_require__("./src/client.ts");
22699 //# sourceMappingURL=data:application/json;charset=utf-8;base64,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QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLDBCQUEwQix3QkFBd0I7QUFDbEQ7QUFDQTs7QUFFQTtBQUNBOztBQUVBLHlCQUF5Qiw2QkFBNkI7QUFDdEQ7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBOztBQUVBO0FBQ0EsMEVBQTBFLHFCQUFNLG1CQUFtQixxQkFBTTs7QUFFekc7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBLFVBQVU7OztBQUdWO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLFNBQVM7QUFDVDs7QUFFQSwwQkFBMEIsNkJBQTZCO0FBQ3ZEO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLDRCQUE0Qjs7QUFFNUI7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxXQUFXO0FBQ1gsNEJBQTRCLHNCQUFzQjtBQUNsRDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsK0JBQStCLCtCQUErQjtBQUM5RDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLHdCQUF3QiwyQkFBMkI7QUFDbkQ7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQSw0QkFBNEI7QUFDNUI7O0FBRUEsd0JBQXdCLG1DQUFtQztBQUMzRDtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7O0FBRUw7QUFDQSxHQUFHOztBQUVIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsbURBQW1EOztBQUVuRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSwyQ0FBMkM7O0FBRTNDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaURBQWlEOztBQUVqRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esc0NBQXNDOztBQUV0QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDJFQUEyRTtBQUMzRSw2RUFBNkU7QUFDN0U7QUFDQSwrQkFBK0I7QUFDL0I7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBLE1BQU07OztBQUdOLDJCQUEyQixlQUFlO0FBQzFDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNOzs7QUFHTjtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTs7QUFFQSx5REFBeUQ7QUFDekQ7QUFDQTtBQUNBO0FBQ0EsK0lBQStJOztBQUUvSTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUEsQ0FBQztBQUNELDJDQUEyQyxjQUFjOzs7Ozs7Ozs7Ozs7QUNsa0N6RDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQzs7QUFFRDtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLDJDQUEyQztBQUMzQztBQUNBLDJEQUEyRDs7QUFFM0Q7QUFDQSwrQ0FBK0M7QUFDL0M7QUFDQTtBQUNBOztBQUVBO0FBQ0E7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QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGtDQUFrQyw0QkFBNEI7QUFDOUQ7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLOztBQUVMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsZUFBZSxRQUFRO0FBQ3ZCO0FBQ0EsUUFBUTtBQUNSLEtBQUs7O0FBRUw7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG1FQUFtRTtBQUNuRTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLEdBQUc7QUFDbEIsaUJBQWlCLFFBQVE7QUFDekI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxRQUFRO0FBQ3ZCLGlCQUFpQixRQUFRO0FBQ3pCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7O0FBRUw7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsR0FBRztBQUNsQixlQUFlLFNBQVM7QUFDeEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWM7QUFDZDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0JBQWdCO0FBQ2hCO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQkFBZ0I7QUFDaEI7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdCQUFnQjtBQUNoQjtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0JBQWdCO0FBQ2hCO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQkFBZ0I7QUFDaEI7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGtCQUFrQjtBQUNsQjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxHQUFHO0FBQ2xCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQixRQUFRO0FBQ3pCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCLFFBQVE7QUFDekI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsUUFBUTtBQUNSO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCLEdBQUc7QUFDcEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsWUFBWTtBQUNaO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsT0FBTztBQUN0QjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLFFBQVE7QUFDdkIsZUFBZSxRQUFRO0FBQ3ZCLGlCQUFpQixTQUFTO0FBQzFCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLFFBQVE7QUFDdkIsaUJBQWlCLEdBQUc7QUFDcEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsUUFBUTtBQUN2QixpQkFBaUIsU0FBUztBQUMxQjtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsUUFBUTtBQUN2QixlQUFlLEdBQUc7QUFDbEIsaUJBQWlCLFFBQVE7QUFDekI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLE9BQU87QUFDdEI7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxRQUFRO0FBQ3ZCLGlCQUFpQixTQUFTO0FBQzFCO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQVE7QUFDUjtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsUUFBUTtBQUN2QixpQkFBaUIsR0FBRztBQUNwQjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsUUFBUTtBQUN2QixpQkFBaUIsU0FBUztBQUMxQjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLFFBQVE7QUFDdkIsZUFBZSxHQUFHO0FBQ2xCLGlCQUFpQixRQUFRO0FBQ3pCO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLFFBQVE7QUFDUjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsT0FBTztBQUN0QjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsUUFBUTtBQUN2QixpQkFBaUIsU0FBUztBQUMxQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxRQUFRO0FBQ3ZCLGlCQUFpQixHQUFHO0FBQ3BCO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsUUFBUTtBQUN2QixpQkFBaUIsU0FBUztBQUMxQjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLFFBQVE7QUFDdkIsZUFBZSxHQUFHO0FBQ2xCLGlCQUFpQixRQUFRO0FBQ3pCO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLE9BQU87QUFDdEI7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFD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QTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLEdBQUc7QUFDbEIsaUJBQWlCLFNBQVM7QUFDMUI7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLFFBQVE7QUFDdkIsZUFBZSxRQUFRO0FBQ3ZCLGVBQWUsT0FBTztBQUN0QixlQUFlLFVBQVU7QUFDekIsaUJBQWlCLFNBQVM7QUFDMUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsR0FBRztBQUNsQixpQkFBaUIsU0FBUztBQUMxQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLEdBQUc7QUFDbEIsaUJBQWlCLFNBQVM7QUFDMUI7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLEdBQUc7QUFDbEIsaUJBQWlCLFNBQVM7QUFDMUI7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLEdBQUc7QUFDbEIsaUJBQWlCLFNBQVM7QUFDMUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsR0FBRztBQUNsQixpQkFBaUIsVUFBVTtBQUMzQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FB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O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxVQUFVO0FBQ3pCLGVBQWUsU0FBUztBQUN4QixpQkFBaUIsVUFBVTtBQUMzQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsU0FBUztBQUN4QixpQkFBaUIsVUFBVTtBQUMzQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsVUFBVTtBQUN6QixlQUFlLFFBQVE7QUFDdkIsZUFBZSxHQUFHO0FBQ2xCLGlCQUFpQixVQUFVO0FBQzNCO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsUUFBUTtBQUN2QixpQkFBaUIsVUFBVTtBQUMzQjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLFVBQVU7QUFDekIsaUJBQWlCLFVBQVU7QUFDM0I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLFVBQVU7QUFDekIsaUJBQWlCLFVBQVU7QUFDM0I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsVUFBVTtBQUN6QixlQUFlLFFBQVE7QUFDdkIsZUFBZSxRQUFRO0FBQ3ZCLGlCQUFpQixVQUFVO0FBQzNCO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxVQUFVO0FBQ3pCLGlCQUFpQixVQUFVO0FBQzNCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esc0NBQXNDO0FBQ3RDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLFNBQVM7QUFDeEIsaUJBQWlCLFVBQVU7QUFDM0I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxZQUFZO0FBQ1o7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsaUJBQWlCO0FBQ2hDLGVBQWUsUUFBUTtBQUN2QixlQUFlLEdBQUc7QUFDbEIsZUFBZSxPQUFPO0FBQ3RCO0FBQ0EsZUFBZSxPQUFPO0FBQ3RCLGVBQWUsT0FBTztBQUN0QjtBQUNBLGVBQWUsT0FBTztBQUN0QixlQUFlLE9BQU87QUFDdEIsZUFBZSxRQUFRO0FBQ3ZCLGVBQWUsUUFBUTtBQUN2QixpQkFBaUIsVUFBVTtBQUMzQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsVUFBVTtBQUN6QixlQUFlLFVBQVU7QUFDekIsaUJBQWlCLFVBQVU7QUFDM0I7QUFDQTtBQUNBO0FBQ0Esb0VBQW9FO0FBQ3BFO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLFVBQVU7QUFDekIsZUFBZSxRQUFRO0FBQ3ZCLGlCQUFpQixVQUFVO0FBQzNCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxZQUFZO0FBQ1o7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsVUFBVTtBQUN6QixpQkFBaUIsVUFBVTtBQUMzQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsV0FBVztBQUNYLFNBQVM7QUFDVCxPQUFPO0FBQ1A7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsUUFBUTtBQUN2QixlQUFlLFFBQVE7QUFDdkIsaUJBQWlCLFFBQVE7QUFDekI7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxVQUFVO0FBQ3pCLGVBQWUsUUFBUTtBQUN2QixlQUFlLEdBQUc7QUFDbEIsZUFBZSxPQUFPO0FBQ3RCO0FBQ0EsaUJBQWlCLFVBQVU7QUFDM0I7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLFNBQVM7QUFDeEIsaUJBQWlCLFVBQVU7QUFDM0I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLFVBQVU7QUFDekIsaUJBQWlCLFVBQVU7QUFDM0I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLFVBQVU7QUFDekIsZUFBZSxRQUFRO0FBQ3ZCLGVBQWUsVUFBVTtBQUN6QixlQUFlLEdBQUc7QUFDbEIsZUFBZSxHQUFHO0FBQ2xCLGVBQWUsT0FBTztBQUN0QjtBQUNBLGVBQWUsT0FBTztBQUN0QixlQUFlLE9BQU87QUFDdEIsZUFBZSxRQUFRO0FBQ3ZCLGVBQWUsUUFBUTtBQUN2QixpQkFBaUIsVUFBVTtBQUMzQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxRQUFRO0FBQ3ZCLGlCQUFpQixVQUFVO0FBQzNCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxPQUFPO0FBQ3RCLGlCQUFpQixRQUFRO0FBQ3pCO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxVQUFVO0FBQ3pCLGlCQUFpQixVQUFVO0FBQzNCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLGlCQUFpQjtBQUNoQyxlQUFlLFFBQVE7QUFDdkI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLEdBQUc7QUFDbEIsZUFBZSxPQUFPO0FBQ3RCLGVBQWUsT0FBTztBQUN0QixlQUFlLE9BQU87QUFDdEIsZUFBZSxRQUFRO0FBQ3ZCLGVBQWUsUUFBUTtBQUN2QixpQkFBaUIsVUFBVTtBQUMzQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsUUFBUTtBQUNSO0FBQ0EsUUFBUTtBQUNSO0FBQ0EsUUFBUTtBQUNSO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxHQUFHO0FBQ2xCLGVBQWUsR0FBRztBQUNsQixlQUFlLFFBQVE7QUFDdkIsZUFBZSxRQUFRO0FBQ3ZCLGlCQUFpQixHQUFHO0FBQ3BCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsR0FBRztBQUNsQixlQUFlLEdBQUc7QUFDbEIsZUFBZSxRQUFRO0FBQ3ZCLGVBQWUsUUFBUTtBQUN2QixlQUFlLFFBQVE7QUFDdkIsZUFBZSxRQUFRO0FBQ3ZCO0FBQ0EsaUJBQWlCLEdBQUc7QUFDcEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsR0FBRztBQUNsQixlQUFlLFFBQVE7QUFDdkIsaUJBQWlCLEdBQUc7QUFDcEI7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsT0FBTztBQUN0QixlQUFlLE9BQU87QUFDdEIsZUFBZSxRQUFRO0FBQ3ZCLGVBQWUsVUFBVTtBQUN6QixlQUFlLFVBQVU7QUFDekIsZUFBZSxRQUFRO0FBQ3ZCLGlCQUFpQixTQUFTO0FBQzFCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlO0FBQ2Y7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsUUFBUTtBQUN2QixlQUFlLFFBQVE7QUFDdkIsZUFBZSxRQUFRO0FBQ3ZCLGVBQWUsUUFBUTtBQUN2QixlQUFlLFVBQVU7QUFDekIsZUFBZSxVQUFVO0FBQ3pCLGVBQWUsUUFBUTtBQUN2QixpQkFBaUIsU0FBUztBQUMxQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLFFBQVE7QUFDdkIsZUFBZSxRQUFRO0FBQ3ZCLGVBQWUsUUFBUTtBQUN2QixlQUFlLFVBQVU7QUFDekIsZUFBZSxVQUFVO0FBQ3pCLGVBQWUsUUFBUTtBQUN2QixpQkFBaUIsU0FBUztBQUMxQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLFVBQVU7QUFDekIsaUJBQWlCLFVBQVU7QUFDM0I7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLFFBQVE7QUFDdkIsaUJBQWlCLE9BQU87QUFDeEI7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsUUFBUTtBQUN2QixpQkFBaUIsT0FBTztBQUN4QjtBQUNBO0FBQ0E7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QTtBQUNBLGVBQWU7QUFDZjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWU7QUFDZjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQixRQUFRO0FBQ3pCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCLFFBQVE7QUFDekI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWU7QUFDZjtBQUNBO0FBQ0EsZUFBZTtBQUNmO0FBQ0E7QUFDQSxlQUFlO0FBQ2Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsZUFBZTtBQUNmOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCLFFBQVE7QUFDekI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLEdBQUc7QUFDbEIsaUJBQWlCLFFBQVE7QUFDekI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQixRQUFRO0FBQ3pCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7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QUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxVQUFVO0FBQ3pCLGVBQWUsUUFBUTtBQUN2QixlQUFlLFFBQVEsV0FBVztBQUNsQyxlQUFlLFNBQVM7QUFDeEI7QUFDQSxlQUFlLFFBQVE7QUFDdkI7QUFDQSxlQUFlLFNBQVM7QUFDeEI7QUFDQSxpQkFBaUIsVUFBVTtBQUMzQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxRQUFRO0FBQ1I7QUFDQTtBQUNBLG1EQUFtRCxpQkFBaUI7QUFDcEU7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxVQUFVO0FBQ3pCLGVBQWUsTUFBTTtBQUNyQixpQkFBaUIsUUFBUTtBQUN6QjtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQVE7QUFDUjtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7O0FBRUw7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsVUFBVTtBQUN6QixlQUFlLFFBQVE7QUFDdkIsZUFBZSxNQUFNO0FBQ3JCLGlCQUFpQixRQUFRO0FBQ3pCO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsUUFBUTtBQUNSO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSzs7QUFFTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsVUFBVTtBQUN6QixpQkFBaUIsVUFBVTtBQUMzQjtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQVE7QUFDUjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxVQUFVO0FBQ3pCLGVBQWUsVUFBVTtBQUN6QixpQkFBaUIsVUFBVTtBQUMzQjtBQUNBO0FBQ0Esc0JBQXNCO0FBQ3RCLHFCQUFxQjtBQUNyQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsVUFBVTtBQUN6QixpQkFBaUIsVUFBVTtBQUMzQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxVQUFVO0FBQ3pCLGlCQUFpQixVQUFVO0FBQzNCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxVQUFVO0FBQ3pCLGVBQWUsMEJBQTBCO0FBQ3pDO0FBQ0EsaUJBQWlCLFVBQVU7QUFDM0I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsUUFBUTtBQUNSO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1AsS0FBSzs7QUFFTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLFVBQVU7QUFDekIsZUFBZSxNQUFNO0FBQ3JCLGlCQUFpQixVQUFVO0FBQzNCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7O0FBRUw7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsVUFBVTtBQUN6QixlQUFlLE1BQU07QUFDckIsaUJBQWlCLFVBQVU7QUFDM0I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSzs7QUFFTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsVUFBVTtBQUN6QixlQUFlLHNCQUFzQjtBQUNyQyxpQkFBaUIsVUFBVTtBQUMzQjtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQVE7QUFDUjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLOztBQUVMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsVUFBVTtBQUN6QixlQUFlLFFBQVE7QUFDdkIsaUJBQWlCLFVBQVU7QUFDM0I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQVE7QUFDUjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsVUFBVTtBQUN6QixlQUFlLFFBQVE7QUFDdkIsaUJBQWlCLFVBQVU7QUFDM0I7QUFDQTtBQUNBO0FBQ0E7QUFDQSxRQUFRO0FBQ1I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQVE7QUFDUjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNB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QUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxHQUFHO0FBQ2xCLGlCQUFpQixTQUFTO0FBQzFCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLEdBQUc7QUFDbEIsaUJBQWlCLFNBQVM7QUFDMUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxHQUFHO0FBQ2xCLGlCQUFpQixTQUFTO0FBQzFCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsR0FBRztBQUNsQixpQkFBaUIsU0FBUztBQUMxQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLEdBQUc7QUFDbEIsaUJBQWlCLFNBQVM7QUFDMUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxHQUFHO0FBQ2xCLGlCQUFpQixTQUFTO0FBQzFCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsR0FBRztBQUNsQixpQkFBaUIsU0FBUztBQUMxQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLEdBQUc7QUFDbEIsaUJBQWlCLFNBQVM7QUFDMUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG1CQUFtQixRQUFRO0FBQzNCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLEdBQUc7QUFDbEIsZUFBZSxHQUFHO0FBQ2xCLGlCQUFpQixTQUFTO0FBQzFCO0FBQ0E7QUFDQSxzQkFBc0I7QUFDdEIscUJBQXFCO0FBQ3JCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxHQUFHO0FBQ2xCLGVBQWUsR0FBRztBQUNsQixlQUFlLFVBQVU7QUFDekIsaUJBQWlCLFNBQVM7QUFDMUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxHQUFHO0FBQ2xCLGlCQUFpQixTQUFTO0FBQzFCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxHQUFHO0FBQ2xCLGlCQUFpQixTQUFTO0FBQzFCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLEdBQUc7QUFDbEIsaUJBQWlCLFNBQVM7QUFDMUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsR0FBRztBQUNsQixpQkFBaUIsU0FBUztBQUMxQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxHQUFHO0FBQ2xCLGlCQUFpQixTQUFTO0FBQzFCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLEdBQUc7QUFDbEIsaUJBQWlCLFNBQVM7QUFDMUI7QUFDQTtBQUNBLG9CQUFvQjtBQUNwQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsR0FBRztBQUNsQixpQkFBaUIsU0FBUztBQUMxQjtBQUNBO0FBQ0Esd0JBQXdCO0FBQ3hCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLEdBQUc7QUFDbEIsaUJBQWlCLFNBQVM7QUFDMUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsUUFBUTtBQUN2QixlQUFlLFFBQVE7QUFDdkIsaUJBQWlCLFNBQVM7QUFDMUI7QUFDQTtBQUNBLHNCQUFzQjtBQUN0QjtBQUNBLDJCQUEyQixRQUFRO0FBQ25DO0FBQ0E7QUFDQSwyQkFBMkIsUUFBUTtBQUNuQztBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxRQUFRO0FBQ3ZCLGVBQWUsUUFBUTtBQUN2QixlQUFlLFVBQVU7QUFDekIsaUJBQWlCLFNBQVM7QUFDMUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esc0JBQXNCO0FBQ3RCLHNCQUFzQjtBQUN0QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsR0FBRztBQUNsQixpQkFBaUIsU0FBUztBQUMxQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsR0FBRztBQUNsQixpQkFBaUIsU0FBUztBQUMxQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLEdBQUc7QUFDbEIsaUJBQWlCLFNBQVM7QUFDMUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsR0FBRztBQUNsQixpQkFBaUIsU0FBUztBQUMxQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxHQUFHO0FBQ2xCLGlCQUFpQixTQUFTO0FBQzFCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxHQUFHO0FBQ2xCLGlCQUFpQixTQUFTO0FBQzFCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHlCQUF5QixnQkFBZ0I7QUFDekM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsR0FBRztBQUNsQixpQkFBaUIsU0FBUztBQUMxQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsR0FBRztBQUNsQixpQkFBaUIsU0FBUztBQUMxQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxHQUFHO0FBQ2xCLGlCQUFpQixTQUFTO0FBQzFCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsR0FBRztBQUNsQixpQkFBaUIsU0FBUztBQUMxQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLEdBQUc7QUFDbEIsaUJBQWlCLFNBQVM7QUFDMUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxHQUFHO0FBQ2xCLGlCQUFpQixTQUFTO0FBQzFCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsR0FBRztBQUNsQixpQkFBaUIsU0FBUztBQUMxQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7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Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxRQUFRO0FBQ3ZCLGVBQWUsUUFBUTtBQUN2QixlQUFlLFFBQVE7QUFDdkIsaUJBQWlCLFNBQVM7QUFDMUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQVE7QUFDUjtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxRQUFRO0FBQ3ZCLGVBQWUsUUFBUTtBQUN2QixlQUFlLFNBQVM7QUFDeEIsaUJBQWlCLFFBQVE7QUFDekI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsUUFBUTtBQUN2QixpQkFBaUIsUUFBUTtBQUN6QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSzs7QUFFTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxRQUFRO0FBQ3ZCLGlCQUFpQixRQUFRO0FBQ3pCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsUUFBUTtBQUN2QixpQkFBaUIsUUFBUTtBQUN6QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLFFBQVE7QUFDdkIsZUFBZSxRQUFRO0FBQ3ZCLGVBQWUsUUFBUTtBQUN2QixpQkFBaUIsU0FBUztBQUMxQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxRQUFRO0FBQ3ZCLGlCQUFpQixRQUFRO0FBQ3pCO0FBQ0E7QUFDQTtBQUNBLGtDQUFrQztBQUNsQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0Esa0NBQWtDLEtBQUs7QUFDdkM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsUUFBUTtBQUN2QixpQkFBaUIsUUFBUTtBQUN6QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLFFBQVE7QUFDdkIsaUJBQWlCLFFBQVE7QUFDekI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLOztBQUVMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxRQUFRO0FBQ3ZCLGlCQUFpQixRQUFRO0FBQ3pCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSzs7QUFFTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsUUFBUTtBQUN2QixpQkFBaUIsUUFBUTtBQUN6QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsUUFBUTtBQUN2QixlQUFlLFFBQVE7QUFDdkIsZUFBZSxRQUFRO0FBQ3ZCLGlCQUFpQixRQUFRO0FBQ3pCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxRQUFRO0FBQ3ZCLGVBQWUsUUFBUTtBQUN2QixlQUFlLFFBQVE7QUFDdkIsaUJBQWlCLFFBQVE7QUFDekI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLFFBQVE7QUFDdkIsZUFBZSxRQUFRO0FBQ3ZCLGVBQWUsUUFBUTtBQUN2QixpQkFBaUIsUUFBUTtBQUN6QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxRQUFRO0FBQ3ZCLGVBQWUsUUFBUTtBQUN2QixnQkFBZ0IsUUFBUTtBQUN4QixpQkFBaUIsUUFBUTtBQUN6QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsUUFBUTtBQUNSO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxRQUFRO0FBQ3ZCLGVBQWUsUUFBUTtBQUN2QixnQkFBZ0IsUUFBUTtBQUN4QixpQkFBaUIsUUFBUTtBQUN6QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsUUFBUTtBQUNSO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxRQUFRO0FBQ3ZCLGVBQWUsZUFBZTtBQUM5QixlQUFlLGlCQUFpQjtBQUNoQyxpQkFBaUIsUUFBUTtBQUN6QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsUUFBUTtBQUN2QixpQkFBaUIsUUFBUTtBQUN6QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7O0FBRUw7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLFFBQVE7QUFDdkIsZUFBZSxlQUFlO0FBQzlCLGVBQWUsUUFBUTtBQUN2QixpQkFBaUIsT0FBTztBQUN4QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxRQUFRO0FBQ3ZCLGlCQUFpQixRQUFRO0FBQ3pCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSzs7QUFFTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsUUFBUTtBQUN2QixlQUFlLFFBQVE7QUFDdkIsZUFBZSxRQUFRO0FBQ3ZCLGlCQUFpQixTQUFTO0FBQzFCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsUUFBUTtBQUN2QixlQUFlLFFBQVEsV0FBVztBQUNsQyxlQUFlLFFBQVE7QUFDdkI7QUFDQSxlQUFlLFFBQVE7QUFDdkI7QUFDQSxlQUFlLFFBQVE7QUFDdkI7QUFDQSxlQUFlLFFBQVE7QUFDdkI7QUFDQSxlQUFlLFFBQVE7QUFDdkI7QUFDQSxlQUFlLFFBQVE7QUFDdkI7QUFDQSxnQkFBZ0IsUUFBUTtBQUN4QixpQkFBaUIsVUFBVTtBQUMzQjtBQUNBO0FBQ0E7QUFDQTtBQUNBLGtCQUFrQixnQkFBZ0I7QUFDbEM7QUFDQTtBQUNBO0FBQ0E7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QTtBQUNBLGVBQWUsT0FBTztBQUN0QixlQUFlLFVBQVU7QUFDekIsaUJBQWlCLFFBQVE7QUFDekI7QUFDQTtBQUNBLHdCQUF3QixRQUFRLElBQUksUUFBUSxJQUFJLFFBQVEsSUFBSSxRQUFRO0FBQ3BFO0FBQ0Esc0NBQXNDLGFBQWE7QUFDbkQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQSxLQUFLLE9BQU8sZ0JBQWdCOztBQUU1Qjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYztBQUNkO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsS0FBSzs7QUFFTDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0E7QUFDQSxXQUFXO0FBQ1g7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7O0FBRUw7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQSxLQUFLOztBQUVMO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxLQUFLOztBQUVMO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxLQUFLOztBQUVMO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUCxLQUFLOztBQUVMO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQVE7QUFDUjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLG9DQUFvQywyREFBMkQ7QUFDL0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7O0FBRUw7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FB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QUNBLE9BQU87QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsZ0RBQWdELEVBQUUsR0FBRyxHQUFHO0FBQ3hEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsK0JBQStCOztBQUUvQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQTtBQUNBLHNCQUFzQjtBQUN0QjtBQUNBOztBQUVBO0FBQ0Esc0NBQXNDOztBQUV0QztBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxRQUFRO0FBQ1I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsUUFBUTtBQUNSO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQTtBQUNBO0FB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QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQSxXQUFXO0FBQ1g7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQSxXQUFXO0FBQ1g7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBLENBQUM7O0FBRUQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLGFBQWEsUUFBUTtBQUNyQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLGFBQWEsUUFBUTtBQUNyQixhQUFhLFFBQVE7QUFDckIsYUFBYSxRQUFRO0FBQ3JCLGFBQWEsS0FBSztBQUNsQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLGFBQWEsUUFBUTtBQUNyQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLGFBQWEsUUFBUTtBQUNyQjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLGFBQWEsUUFBUTtBQUNyQixhQUFhLFFBQVE7QUFDckI7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLGFBQWEsUUFBUTtBQUNyQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLGFBQWEsUUFBUTtBQUNyQjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLGFBQWEsUUFBUTtBQUNyQjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLGFBQWEsUUFBUTtBQUNyQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLGFBQWEsUUFBUTtBQUNyQjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLGFBQWEsUUFBUTtBQUNyQixhQUFhLFFBQVE7QUFDckIsYUFBYSxRQUFRO0FBQ3JCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsYUFBYSxRQUFRO0FBQ3JCLGFBQWEsUUFBUTtBQUNyQixhQUFhLFFBQVE7QUFDckI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7O0FBRUQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQzs7QUFFRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLGFBQWEsUUFBUTtBQUNyQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDJEQUEyRCxXQUFXLEVBQUU7QUFDeEU7O0FBRUE7QUFDQTtBQUNBLGFBQWEsUUFBUTtBQUNyQixhQUFhLFNBQVM7QUFDdEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsUUFBUTtBQUNSO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxhQUFhLFFBQVE7QUFDckIsYUFBYSxTQUFTO0FBQ3RCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQzs7QUFFRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdCQUFnQixPQUFPO0FBQ3ZCOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLHdCQUF3QixRQUFRO0FBQ2hDO0FBQ0E7QUFDQTtBQUNBLGVBQWU7QUFDZjtBQUNBO0FBQ0E7QUFDQTtBQUNBLHdCQUF3QixRQUFRO0FBQ2hDO0FBQ0E7QUFDQTtBQUNBLDBCQUEwQixRQUFRO0FBQ2xDO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQjtBQUNqQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHdCQUF3QixRQUFRO0FBQ2hDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG9CQUFvQjtBQUNwQjtBQUNBO0FBQ0E7QUFDQSxxQkFBcUI7QUFDckI7QUFDQSxrQkFBa0I7QUFDbEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYztBQUNkO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0JBQWdCLE9BQU87QUFDdkI7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWM7QUFDZDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQzs7QUFFRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQkFBZ0IsNEJBQTRCO0FBQzVDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFdBQVc7QUFDWCxTQUFTO0FBQ1Q7QUFDQSxLQUFLO0FBQ0w7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QUNBO1VBQ0E7VUFDQTtVQUNBO1VBQ0E7VUFDQTtVQUNBO1VBQ0E7VUFDQTtVQUNBO1VBQ0E7VUFDQTs7VUFFQTtVQUNBOztVQUVBO1VBQ0E7O1VBRUE7VUFDQTtVQUNBOzs7OztXQ3pCQTtXQUNBO1dBQ0E7V0FDQTtXQUNBLEdBQUc7V0FDSDtXQUNBO1dBQ0EsQ0FBQzs7Ozs7V0NQRDtXQUNBO1dBQ0E7V0FDQTtXQUNBOzs7OztVRUpBO1VBQ0E7VUFDQTtVQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vb3V0bGluZS1icm93c2VyLy4vbm9kZV9tb2R1bGVzL2tleWJvYXJkanMvZGlzdC9rZXlib2FyZC5qcyIsIndlYnBhY2s6Ly9vdXRsaW5lLWJyb3dzZXIvLi9ub2RlX21vZHVsZXMvbG9kYXNoL2xvZGFzaC5qcyIsIndlYnBhY2s6Ly9vdXRsaW5lLWJyb3dzZXIvLi9zcmMvY2xpZW50LnRzIiwid2VicGFjazovL291dGxpbmUtYnJvd3Nlci8uL3NyYy9jdXJzb3IudHMiLCJ3ZWJwYWNrOi8vb3V0bGluZS1icm93c2VyLy4vc3JjL291dGxpbmUudHMiLCJ3ZWJwYWNrOi8vb3V0bGluZS1icm93c2VyLy4vbm9kZV9tb2R1bGVzL3V1aWQvZGlzdC9jb21tb25qcy1icm93c2VyL2luZGV4LmpzIiwid2VicGFjazovL291dGxpbmUtYnJvd3Nlci8uL25vZGVfbW9kdWxlcy91dWlkL2Rpc3QvY29tbW9uanMtYnJvd3Nlci9tZDUuanMiLCJ3ZWJwYWNrOi8vb3V0bGluZS1icm93c2VyLy4vbm9kZV9tb2R1bGVzL3V1aWQvZGlzdC9jb21tb25qcy1icm93c2VyL25hdGl2ZS5qcyIsIndlYnBhY2s6Ly9vdXRsaW5lLWJyb3dzZXIvLi9ub2RlX21vZHVsZXMvdXVpZC9kaXN0L2NvbW1vbmpzLWJyb3dzZXIvbmlsLmpzIiwid2VicGFjazovL291dGxpbmUtYnJvd3Nlci8uL25vZGVfbW9kdWxlcy91dWlkL2Rpc3QvY29tbW9uanMtYnJvd3Nlci9wYXJzZS5qcyIsIndlYnBhY2s6Ly9vdXRsaW5lLWJyb3dzZXIvLi9ub2RlX21vZHVsZXMvdXVpZC9kaXN0L2NvbW1vbmpzLWJyb3dzZXIvcmVnZXguanMiLCJ3ZWJwYWNrOi8vb3V0bGluZS1icm93c2VyLy4vbm9kZV9tb2R1bGVzL3V1aWQvZGlzdC9jb21tb25qcy1icm93c2VyL3JuZy5qcyIsIndlYnBhY2s6Ly9vdXRsaW5lLWJyb3dzZXIvLi9ub2RlX21vZHVsZXMvdXVpZC9kaXN0L2NvbW1vbmpzLWJyb3dzZXIvc2hhMS5qcyIsIndlYnBhY2s6Ly9vdXRsaW5lLWJyb3dzZXIvLi9ub2RlX21vZHVsZXMvdXVpZC9kaXN0L2NvbW1vbmpzLWJyb3dzZXIvc3RyaW5naWZ5LmpzIiwid2VicGFjazovL291dGxpbmUtYnJvd3Nlci8uL25vZGVfbW9kdWxlcy91dWlkL2Rpc3QvY29tbW9uanMtYnJvd3Nlci92MS5qcyIsIndlYnBhY2s6Ly9vdXRsaW5lLWJyb3dzZXIvLi9ub2RlX21vZHVsZXMvdXVpZC9kaXN0L2NvbW1vbmpzLWJyb3dzZXIvdjMuanMiLCJ3ZWJwYWNrOi8vb3V0bGluZS1icm93c2VyLy4vbm9kZV9tb2R1bGVzL3V1aWQvZGlzdC9jb21tb25qcy1icm93c2VyL3YzNS5qcyIsIndlYnBhY2s6Ly9vdXRsaW5lLWJyb3dzZXIvLi9ub2RlX21vZHVsZXMvdXVpZC9kaXN0L2NvbW1vbmpzLWJyb3dzZXIvdjQuanMiLCJ3ZWJwYWNrOi8vb3V0bGluZS1icm93c2VyLy4vbm9kZV9tb2R1bGVzL3V1aWQvZGlzdC9jb21tb25qcy1icm93c2VyL3Y1LmpzIiwid2VicGFjazovL291dGxpbmUtYnJvd3Nlci8uL25vZGVfbW9kdWxlcy91dWlkL2Rpc3QvY29tbW9uanMtYnJvd3Nlci92YWxpZGF0ZS5qcyIsIndlYnBhY2s6Ly9vdXRsaW5lLWJyb3dzZXIvLi9ub2RlX21vZHVsZXMvdXVpZC9kaXN0L2NvbW1vbmpzLWJyb3dzZXIvdmVyc2lvbi5qcyIsIndlYnBhY2s6Ly9vdXRsaW5lLWJyb3dzZXIvLi9ub2RlX21vZHVsZXMvbWFya2VkL2xpYi9tYXJrZWQuY2pzIiwid2VicGFjazovL291dGxpbmUtYnJvd3Nlci93ZWJwYWNrL2Jvb3RzdHJhcCIsIndlYnBhY2s6Ly9vdXRsaW5lLWJyb3dzZXIvd2VicGFjay9ydW50aW1lL2dsb2JhbCIsIndlYnBhY2s6Ly9vdXRsaW5lLWJyb3dzZXIvd2VicGFjay9ydW50aW1lL25vZGUgbW9kdWxlIGRlY29yYXRvciIsIndlYnBhY2s6Ly9vdXRsaW5lLWJyb3dzZXIvd2VicGFjay9iZWZvcmUtc3RhcnR1cCIsIndlYnBhY2s6Ly9vdXRsaW5lLWJyb3dzZXIvd2VicGFjay9zdGFydHVwIiwid2VicGFjazovL291dGxpbmUtYnJvd3Nlci93ZWJwYWNrL2FmdGVyLXN0YXJ0dXAiXSwic291cmNlc0NvbnRlbnQiOlsiKGZ1bmN0aW9uIChnbG9iYWwsIGZhY3RvcnkpIHtcbiAgdHlwZW9mIGV4cG9ydHMgPT09ICdvYmplY3QnICYmIHR5cGVvZiBtb2R1bGUgIT09ICd1bmRlZmluZWQnID8gbW9kdWxlLmV4cG9ydHMgPSBmYWN0b3J5KCkgOlxuICB0eXBlb2YgZGVmaW5lID09PSAnZnVuY3Rpb24nICYmIGRlZmluZS5hbWQgPyBkZWZpbmUoZmFjdG9yeSkgOlxuICAoZ2xvYmFsID0gZ2xvYmFsIHx8IHNlbGYsIGdsb2JhbC5rZXlib2FyZEpTID0gZmFjdG9yeSgpKTtcbn0odGhpcywgKGZ1bmN0aW9uICgpIHsgJ3VzZSBzdHJpY3QnO1xuXG4gIGZ1bmN0aW9uIF90eXBlb2Yob2JqKSB7XG4gICAgXCJAYmFiZWwvaGVscGVycyAtIHR5cGVvZlwiO1xuXG4gICAgaWYgKHR5cGVvZiBTeW1ib2wgPT09IFwiZnVuY3Rpb25cIiAmJiB0eXBlb2YgU3ltYm9sLml0ZXJhdG9yID09PSBcInN5bWJvbFwiKSB7XG4gICAgICBfdHlwZW9mID0gZnVuY3Rpb24gKG9iaikge1xuICAgICAgICByZXR1cm4gdHlwZW9mIG9iajtcbiAgICAgIH07XG4gICAgfSBlbHNlIHtcbiAgICAgIF90eXBlb2YgPSBmdW5jdGlvbiAob2JqKSB7XG4gICAgICAgIHJldHVybiBvYmogJiYgdHlwZW9mIFN5bWJvbCA9PT0gXCJmdW5jdGlvblwiICYmIG9iai5jb25zdHJ1Y3RvciA9PT0gU3ltYm9sICYmIG9iaiAhPT0gU3ltYm9sLnByb3RvdHlwZSA/IFwic3ltYm9sXCIgOiB0eXBlb2Ygb2JqO1xuICAgICAgfTtcbiAgICB9XG5cbiAgICByZXR1cm4gX3R5cGVvZihvYmopO1xuICB9XG5cbiAgZnVuY3Rpb24gX2NsYXNzQ2FsbENoZWNrKGluc3RhbmNlLCBDb25zdHJ1Y3Rvcikge1xuICAgIGlmICghKGluc3RhbmNlIGluc3RhbmNlb2YgQ29uc3RydWN0b3IpKSB7XG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQ2Fubm90IGNhbGwgYSBjbGFzcyBhcyBhIGZ1bmN0aW9uXCIpO1xuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIF9kZWZpbmVQcm9wZXJ0aWVzKHRhcmdldCwgcHJvcHMpIHtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHByb3BzLmxlbmd0aDsgaSsrKSB7XG4gICAgICB2YXIgZGVzY3JpcHRvciA9IHByb3BzW2ldO1xuICAgICAgZGVzY3JpcHRvci5lbnVtZXJhYmxlID0gZGVzY3JpcHRvci5lbnVtZXJhYmxlIHx8IGZhbHNlO1xuICAgICAgZGVzY3JpcHRvci5jb25maWd1cmFibGUgPSB0cnVlO1xuICAgICAgaWYgKFwidmFsdWVcIiBpbiBkZXNjcmlwdG9yKSBkZXNjcmlwdG9yLndyaXRhYmxlID0gdHJ1ZTtcbiAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0YXJnZXQsIGRlc2NyaXB0b3Iua2V5LCBkZXNjcmlwdG9yKTtcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiBfY3JlYXRlQ2xhc3MoQ29uc3RydWN0b3IsIHByb3RvUHJvcHMsIHN0YXRpY1Byb3BzKSB7XG4gICAgaWYgKHByb3RvUHJvcHMpIF9kZWZpbmVQcm9wZXJ0aWVzKENvbnN0cnVjdG9yLnByb3RvdHlwZSwgcHJvdG9Qcm9wcyk7XG4gICAgaWYgKHN0YXRpY1Byb3BzKSBfZGVmaW5lUHJvcGVydGllcyhDb25zdHJ1Y3Rvciwgc3RhdGljUHJvcHMpO1xuICAgIHJldHVybiBDb25zdHJ1Y3RvcjtcbiAgfVxuXG4gIGZ1bmN0aW9uIF90b0NvbnN1bWFibGVBcnJheShhcnIpIHtcbiAgICByZXR1cm4gX2FycmF5V2l0aG91dEhvbGVzKGFycikgfHwgX2l0ZXJhYmxlVG9BcnJheShhcnIpIHx8IF91bnN1cHBvcnRlZEl0ZXJhYmxlVG9BcnJheShhcnIpIHx8IF9ub25JdGVyYWJsZVNwcmVhZCgpO1xuICB9XG5cbiAgZnVuY3Rpb24gX2FycmF5V2l0aG91dEhvbGVzKGFycikge1xuICAgIGlmIChBcnJheS5pc0FycmF5KGFycikpIHJldHVybiBfYXJyYXlMaWtlVG9BcnJheShhcnIpO1xuICB9XG5cbiAgZnVuY3Rpb24gX2l0ZXJhYmxlVG9BcnJheShpdGVyKSB7XG4gICAgaWYgKHR5cGVvZiBTeW1ib2wgIT09IFwidW5kZWZpbmVkXCIgJiYgU3ltYm9sLml0ZXJhdG9yIGluIE9iamVjdChpdGVyKSkgcmV0dXJuIEFycmF5LmZyb20oaXRlcik7XG4gIH1cblxuICBmdW5jdGlvbiBfdW5zdXBwb3J0ZWRJdGVyYWJsZVRvQXJyYXkobywgbWluTGVuKSB7XG4gICAgaWYgKCFvKSByZXR1cm47XG4gICAgaWYgKHR5cGVvZiBvID09PSBcInN0cmluZ1wiKSByZXR1cm4gX2FycmF5TGlrZVRvQXJyYXkobywgbWluTGVuKTtcbiAgICB2YXIgbiA9IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChvKS5zbGljZSg4LCAtMSk7XG4gICAgaWYgKG4gPT09IFwiT2JqZWN0XCIgJiYgby5jb25zdHJ1Y3RvcikgbiA9IG8uY29uc3RydWN0b3IubmFtZTtcbiAgICBpZiAobiA9PT0gXCJNYXBcIiB8fCBuID09PSBcIlNldFwiKSByZXR1cm4gQXJyYXkuZnJvbShvKTtcbiAgICBpZiAobiA9PT0gXCJBcmd1bWVudHNcIiB8fCAvXig/OlVpfEkpbnQoPzo4fDE2fDMyKSg/OkNsYW1wZWQpP0FycmF5JC8udGVzdChuKSkgcmV0dXJuIF9hcnJheUxpa2VUb0FycmF5KG8sIG1pbkxlbik7XG4gIH1cblxuICBmdW5jdGlvbiBfYXJyYXlMaWtlVG9BcnJheShhcnIsIGxlbikge1xuICAgIGlmIChsZW4gPT0gbnVsbCB8fCBsZW4gPiBhcnIubGVuZ3RoKSBsZW4gPSBhcnIubGVuZ3RoO1xuXG4gICAgZm9yICh2YXIgaSA9IDAsIGFycjIgPSBuZXcgQXJyYXkobGVuKTsgaSA8IGxlbjsgaSsrKSBhcnIyW2ldID0gYXJyW2ldO1xuXG4gICAgcmV0dXJuIGFycjI7XG4gIH1cblxuICBmdW5jdGlvbiBfbm9uSXRlcmFibGVTcHJlYWQoKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkludmFsaWQgYXR0ZW1wdCB0byBzcHJlYWQgbm9uLWl0ZXJhYmxlIGluc3RhbmNlLlxcbkluIG9yZGVyIHRvIGJlIGl0ZXJhYmxlLCBub24tYXJyYXkgb2JqZWN0cyBtdXN0IGhhdmUgYSBbU3ltYm9sLml0ZXJhdG9yXSgpIG1ldGhvZC5cIik7XG4gIH1cblxuICB2YXIgS2V5Q29tYm8gPSAvKiNfX1BVUkVfXyovZnVuY3Rpb24gKCkge1xuICAgIGZ1bmN0aW9uIEtleUNvbWJvKGtleUNvbWJvU3RyKSB7XG4gICAgICBfY2xhc3NDYWxsQ2hlY2sodGhpcywgS2V5Q29tYm8pO1xuXG4gICAgICB0aGlzLnNvdXJjZVN0ciA9IGtleUNvbWJvU3RyO1xuICAgICAgdGhpcy5zdWJDb21ib3MgPSBLZXlDb21iby5wYXJzZUNvbWJvU3RyKGtleUNvbWJvU3RyKTtcbiAgICAgIHRoaXMua2V5TmFtZXMgPSB0aGlzLnN1YkNvbWJvcy5yZWR1Y2UoZnVuY3Rpb24gKG1lbW8sIG5leHRTdWJDb21ibykge1xuICAgICAgICByZXR1cm4gbWVtby5jb25jYXQobmV4dFN1YkNvbWJvKTtcbiAgICAgIH0sIFtdKTtcbiAgICB9XG5cbiAgICBfY3JlYXRlQ2xhc3MoS2V5Q29tYm8sIFt7XG4gICAgICBrZXk6IFwiY2hlY2tcIixcbiAgICAgIHZhbHVlOiBmdW5jdGlvbiBjaGVjayhwcmVzc2VkS2V5TmFtZXMpIHtcbiAgICAgICAgdmFyIHN0YXJ0aW5nS2V5TmFtZUluZGV4ID0gMDtcblxuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMuc3ViQ29tYm9zLmxlbmd0aDsgaSArPSAxKSB7XG4gICAgICAgICAgc3RhcnRpbmdLZXlOYW1lSW5kZXggPSB0aGlzLl9jaGVja1N1YkNvbWJvKHRoaXMuc3ViQ29tYm9zW2ldLCBzdGFydGluZ0tleU5hbWVJbmRleCwgcHJlc3NlZEtleU5hbWVzKTtcblxuICAgICAgICAgIGlmIChzdGFydGluZ0tleU5hbWVJbmRleCA9PT0gLTEpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIH1cbiAgICB9LCB7XG4gICAgICBrZXk6IFwiaXNFcXVhbFwiLFxuICAgICAgdmFsdWU6IGZ1bmN0aW9uIGlzRXF1YWwob3RoZXJLZXlDb21ibykge1xuICAgICAgICBpZiAoIW90aGVyS2V5Q29tYm8gfHwgdHlwZW9mIG90aGVyS2V5Q29tYm8gIT09ICdzdHJpbmcnICYmIF90eXBlb2Yob3RoZXJLZXlDb21ibykgIT09ICdvYmplY3QnKSB7XG4gICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHR5cGVvZiBvdGhlcktleUNvbWJvID09PSAnc3RyaW5nJykge1xuICAgICAgICAgIG90aGVyS2V5Q29tYm8gPSBuZXcgS2V5Q29tYm8ob3RoZXJLZXlDb21ibyk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodGhpcy5zdWJDb21ib3MubGVuZ3RoICE9PSBvdGhlcktleUNvbWJvLnN1YkNvbWJvcy5sZW5ndGgpIHtcbiAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cblxuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMuc3ViQ29tYm9zLmxlbmd0aDsgaSArPSAxKSB7XG4gICAgICAgICAgaWYgKHRoaXMuc3ViQ29tYm9zW2ldLmxlbmd0aCAhPT0gb3RoZXJLZXlDb21iby5zdWJDb21ib3NbaV0ubGVuZ3RoKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgZm9yICh2YXIgX2kgPSAwOyBfaSA8IHRoaXMuc3ViQ29tYm9zLmxlbmd0aDsgX2kgKz0gMSkge1xuICAgICAgICAgIHZhciBzdWJDb21ibyA9IHRoaXMuc3ViQ29tYm9zW19pXTtcblxuICAgICAgICAgIHZhciBvdGhlclN1YkNvbWJvID0gb3RoZXJLZXlDb21iby5zdWJDb21ib3NbX2ldLnNsaWNlKDApO1xuXG4gICAgICAgICAgZm9yICh2YXIgaiA9IDA7IGogPCBzdWJDb21iby5sZW5ndGg7IGogKz0gMSkge1xuICAgICAgICAgICAgdmFyIGtleU5hbWUgPSBzdWJDb21ib1tqXTtcbiAgICAgICAgICAgIHZhciBpbmRleCA9IG90aGVyU3ViQ29tYm8uaW5kZXhPZihrZXlOYW1lKTtcblxuICAgICAgICAgICAgaWYgKGluZGV4ID4gLTEpIHtcbiAgICAgICAgICAgICAgb3RoZXJTdWJDb21iby5zcGxpY2UoaW5kZXgsIDEpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cblxuICAgICAgICAgIGlmIChvdGhlclN1YkNvbWJvLmxlbmd0aCAhPT0gMCkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgfVxuICAgIH0sIHtcbiAgICAgIGtleTogXCJfY2hlY2tTdWJDb21ib1wiLFxuICAgICAgdmFsdWU6IGZ1bmN0aW9uIF9jaGVja1N1YkNvbWJvKHN1YkNvbWJvLCBzdGFydGluZ0tleU5hbWVJbmRleCwgcHJlc3NlZEtleU5hbWVzKSB7XG4gICAgICAgIHN1YkNvbWJvID0gc3ViQ29tYm8uc2xpY2UoMCk7XG4gICAgICAgIHByZXNzZWRLZXlOYW1lcyA9IHByZXNzZWRLZXlOYW1lcy5zbGljZShzdGFydGluZ0tleU5hbWVJbmRleCk7XG4gICAgICAgIHZhciBlbmRJbmRleCA9IHN0YXJ0aW5nS2V5TmFtZUluZGV4O1xuXG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgc3ViQ29tYm8ubGVuZ3RoOyBpICs9IDEpIHtcbiAgICAgICAgICB2YXIga2V5TmFtZSA9IHN1YkNvbWJvW2ldO1xuXG4gICAgICAgICAgaWYgKGtleU5hbWVbMF0gPT09ICdcXFxcJykge1xuICAgICAgICAgICAgdmFyIGVzY2FwZWRLZXlOYW1lID0ga2V5TmFtZS5zbGljZSgxKTtcblxuICAgICAgICAgICAgaWYgKGVzY2FwZWRLZXlOYW1lID09PSBLZXlDb21iby5jb21ib0RlbGltaW5hdG9yIHx8IGVzY2FwZWRLZXlOYW1lID09PSBLZXlDb21iby5rZXlEZWxpbWluYXRvcikge1xuICAgICAgICAgICAgICBrZXlOYW1lID0gZXNjYXBlZEtleU5hbWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgdmFyIGluZGV4ID0gcHJlc3NlZEtleU5hbWVzLmluZGV4T2Yoa2V5TmFtZSk7XG5cbiAgICAgICAgICBpZiAoaW5kZXggPiAtMSkge1xuICAgICAgICAgICAgc3ViQ29tYm8uc3BsaWNlKGksIDEpO1xuICAgICAgICAgICAgaSAtPSAxO1xuXG4gICAgICAgICAgICBpZiAoaW5kZXggPiBlbmRJbmRleCkge1xuICAgICAgICAgICAgICBlbmRJbmRleCA9IGluZGV4O1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAoc3ViQ29tYm8ubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICAgIHJldHVybiBlbmRJbmRleDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gLTE7XG4gICAgICB9XG4gICAgfV0pO1xuXG4gICAgcmV0dXJuIEtleUNvbWJvO1xuICB9KCk7XG4gIEtleUNvbWJvLmNvbWJvRGVsaW1pbmF0b3IgPSAnPic7XG4gIEtleUNvbWJvLmtleURlbGltaW5hdG9yID0gJysnO1xuXG4gIEtleUNvbWJvLnBhcnNlQ29tYm9TdHIgPSBmdW5jdGlvbiAoa2V5Q29tYm9TdHIpIHtcbiAgICB2YXIgc3ViQ29tYm9TdHJzID0gS2V5Q29tYm8uX3NwbGl0U3RyKGtleUNvbWJvU3RyLCBLZXlDb21iby5jb21ib0RlbGltaW5hdG9yKTtcblxuICAgIHZhciBjb21ibyA9IFtdO1xuXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBzdWJDb21ib1N0cnMubGVuZ3RoOyBpICs9IDEpIHtcbiAgICAgIGNvbWJvLnB1c2goS2V5Q29tYm8uX3NwbGl0U3RyKHN1YkNvbWJvU3Ryc1tpXSwgS2V5Q29tYm8ua2V5RGVsaW1pbmF0b3IpKTtcbiAgICB9XG5cbiAgICByZXR1cm4gY29tYm87XG4gIH07XG5cbiAgS2V5Q29tYm8uX3NwbGl0U3RyID0gZnVuY3Rpb24gKHN0ciwgZGVsaW1pbmF0b3IpIHtcbiAgICB2YXIgcyA9IHN0cjtcbiAgICB2YXIgZCA9IGRlbGltaW5hdG9yO1xuICAgIHZhciBjID0gJyc7XG4gICAgdmFyIGNhID0gW107XG5cbiAgICBmb3IgKHZhciBjaSA9IDA7IGNpIDwgcy5sZW5ndGg7IGNpICs9IDEpIHtcbiAgICAgIGlmIChjaSA+IDAgJiYgc1tjaV0gPT09IGQgJiYgc1tjaSAtIDFdICE9PSAnXFxcXCcpIHtcbiAgICAgICAgY2EucHVzaChjLnRyaW0oKSk7XG4gICAgICAgIGMgPSAnJztcbiAgICAgICAgY2kgKz0gMTtcbiAgICAgIH1cblxuICAgICAgYyArPSBzW2NpXTtcbiAgICB9XG5cbiAgICBpZiAoYykge1xuICAgICAgY2EucHVzaChjLnRyaW0oKSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGNhO1xuICB9O1xuXG4gIHZhciBMb2NhbGUgPSAvKiNfX1BVUkVfXyovZnVuY3Rpb24gKCkge1xuICAgIGZ1bmN0aW9uIExvY2FsZShuYW1lKSB7XG4gICAgICBfY2xhc3NDYWxsQ2hlY2sodGhpcywgTG9jYWxlKTtcblxuICAgICAgdGhpcy5sb2NhbGVOYW1lID0gbmFtZTtcbiAgICAgIHRoaXMuYWN0aXZlVGFyZ2V0S2V5cyA9IFtdO1xuICAgICAgdGhpcy5wcmVzc2VkS2V5cyA9IFtdO1xuICAgICAgdGhpcy5fYXBwbGllZE1hY3JvcyA9IFtdO1xuICAgICAgdGhpcy5fa2V5TWFwID0ge307XG4gICAgICB0aGlzLl9raWxsS2V5Q29kZXMgPSBbXTtcbiAgICAgIHRoaXMuX21hY3JvcyA9IFtdO1xuICAgIH1cblxuICAgIF9jcmVhdGVDbGFzcyhMb2NhbGUsIFt7XG4gICAgICBrZXk6IFwiYmluZEtleUNvZGVcIixcbiAgICAgIHZhbHVlOiBmdW5jdGlvbiBiaW5kS2V5Q29kZShrZXlDb2RlLCBrZXlOYW1lcykge1xuICAgICAgICBpZiAodHlwZW9mIGtleU5hbWVzID09PSAnc3RyaW5nJykge1xuICAgICAgICAgIGtleU5hbWVzID0gW2tleU5hbWVzXTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuX2tleU1hcFtrZXlDb2RlXSA9IGtleU5hbWVzO1xuICAgICAgfVxuICAgIH0sIHtcbiAgICAgIGtleTogXCJiaW5kTWFjcm9cIixcbiAgICAgIHZhbHVlOiBmdW5jdGlvbiBiaW5kTWFjcm8oa2V5Q29tYm9TdHIsIGtleU5hbWVzKSB7XG4gICAgICAgIGlmICh0eXBlb2Yga2V5TmFtZXMgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAga2V5TmFtZXMgPSBba2V5TmFtZXNdO1xuICAgICAgICB9XG5cbiAgICAgICAgdmFyIGhhbmRsZXIgPSBudWxsO1xuXG4gICAgICAgIGlmICh0eXBlb2Yga2V5TmFtZXMgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICBoYW5kbGVyID0ga2V5TmFtZXM7XG4gICAgICAgICAga2V5TmFtZXMgPSBudWxsO1xuICAgICAgICB9XG5cbiAgICAgICAgdmFyIG1hY3JvID0ge1xuICAgICAgICAgIGtleUNvbWJvOiBuZXcgS2V5Q29tYm8oa2V5Q29tYm9TdHIpLFxuICAgICAgICAgIGtleU5hbWVzOiBrZXlOYW1lcyxcbiAgICAgICAgICBoYW5kbGVyOiBoYW5kbGVyXG4gICAgICAgIH07XG5cbiAgICAgICAgdGhpcy5fbWFjcm9zLnB1c2gobWFjcm8pO1xuICAgICAgfVxuICAgIH0sIHtcbiAgICAgIGtleTogXCJnZXRLZXlDb2Rlc1wiLFxuICAgICAgdmFsdWU6IGZ1bmN0aW9uIGdldEtleUNvZGVzKGtleU5hbWUpIHtcbiAgICAgICAgdmFyIGtleUNvZGVzID0gW107XG5cbiAgICAgICAgZm9yICh2YXIga2V5Q29kZSBpbiB0aGlzLl9rZXlNYXApIHtcbiAgICAgICAgICB2YXIgaW5kZXggPSB0aGlzLl9rZXlNYXBba2V5Q29kZV0uaW5kZXhPZihrZXlOYW1lKTtcblxuICAgICAgICAgIGlmIChpbmRleCA+IC0xKSB7XG4gICAgICAgICAgICBrZXlDb2Rlcy5wdXNoKGtleUNvZGUgfCAwKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4ga2V5Q29kZXM7XG4gICAgICB9XG4gICAgfSwge1xuICAgICAga2V5OiBcImdldEtleU5hbWVzXCIsXG4gICAgICB2YWx1ZTogZnVuY3Rpb24gZ2V0S2V5TmFtZXMoa2V5Q29kZSkge1xuICAgICAgICByZXR1cm4gdGhpcy5fa2V5TWFwW2tleUNvZGVdIHx8IFtdO1xuICAgICAgfVxuICAgIH0sIHtcbiAgICAgIGtleTogXCJzZXRLaWxsS2V5XCIsXG4gICAgICB2YWx1ZTogZnVuY3Rpb24gc2V0S2lsbEtleShrZXlDb2RlKSB7XG4gICAgICAgIGlmICh0eXBlb2Yga2V5Q29kZSA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgICB2YXIga2V5Q29kZXMgPSB0aGlzLmdldEtleUNvZGVzKGtleUNvZGUpO1xuXG4gICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBrZXlDb2Rlcy5sZW5ndGg7IGkgKz0gMSkge1xuICAgICAgICAgICAgdGhpcy5zZXRLaWxsS2V5KGtleUNvZGVzW2ldKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLl9raWxsS2V5Q29kZXMucHVzaChrZXlDb2RlKTtcbiAgICAgIH1cbiAgICB9LCB7XG4gICAgICBrZXk6IFwicHJlc3NLZXlcIixcbiAgICAgIHZhbHVlOiBmdW5jdGlvbiBwcmVzc0tleShrZXlDb2RlKSB7XG4gICAgICAgIGlmICh0eXBlb2Yga2V5Q29kZSA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgICB2YXIga2V5Q29kZXMgPSB0aGlzLmdldEtleUNvZGVzKGtleUNvZGUpO1xuXG4gICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBrZXlDb2Rlcy5sZW5ndGg7IGkgKz0gMSkge1xuICAgICAgICAgICAgdGhpcy5wcmVzc0tleShrZXlDb2Rlc1tpXSk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5hY3RpdmVUYXJnZXRLZXlzLmxlbmd0aCA9IDA7XG4gICAgICAgIHZhciBrZXlOYW1lcyA9IHRoaXMuZ2V0S2V5TmFtZXMoa2V5Q29kZSk7XG5cbiAgICAgICAgZm9yICh2YXIgX2kgPSAwOyBfaSA8IGtleU5hbWVzLmxlbmd0aDsgX2kgKz0gMSkge1xuICAgICAgICAgIHRoaXMuYWN0aXZlVGFyZ2V0S2V5cy5wdXNoKGtleU5hbWVzW19pXSk7XG5cbiAgICAgICAgICBpZiAodGhpcy5wcmVzc2VkS2V5cy5pbmRleE9mKGtleU5hbWVzW19pXSkgPT09IC0xKSB7XG4gICAgICAgICAgICB0aGlzLnByZXNzZWRLZXlzLnB1c2goa2V5TmFtZXNbX2ldKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLl9hcHBseU1hY3JvcygpO1xuICAgICAgfVxuICAgIH0sIHtcbiAgICAgIGtleTogXCJyZWxlYXNlS2V5XCIsXG4gICAgICB2YWx1ZTogZnVuY3Rpb24gcmVsZWFzZUtleShrZXlDb2RlKSB7XG4gICAgICAgIGlmICh0eXBlb2Yga2V5Q29kZSA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgICB2YXIga2V5Q29kZXMgPSB0aGlzLmdldEtleUNvZGVzKGtleUNvZGUpO1xuXG4gICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBrZXlDb2Rlcy5sZW5ndGg7IGkgKz0gMSkge1xuICAgICAgICAgICAgdGhpcy5yZWxlYXNlS2V5KGtleUNvZGVzW2ldKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdmFyIGtleU5hbWVzID0gdGhpcy5nZXRLZXlOYW1lcyhrZXlDb2RlKTtcblxuICAgICAgICAgIHZhciBraWxsS2V5Q29kZUluZGV4ID0gdGhpcy5fa2lsbEtleUNvZGVzLmluZGV4T2Yoa2V5Q29kZSk7XG5cbiAgICAgICAgICBpZiAoa2lsbEtleUNvZGVJbmRleCAhPT0gLTEpIHtcbiAgICAgICAgICAgIHRoaXMucHJlc3NlZEtleXMubGVuZ3RoID0gMDtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgZm9yICh2YXIgX2kyID0gMDsgX2kyIDwga2V5TmFtZXMubGVuZ3RoOyBfaTIgKz0gMSkge1xuICAgICAgICAgICAgICB2YXIgaW5kZXggPSB0aGlzLnByZXNzZWRLZXlzLmluZGV4T2Yoa2V5TmFtZXNbX2kyXSk7XG5cbiAgICAgICAgICAgICAgaWYgKGluZGV4ID4gLTEpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnByZXNzZWRLZXlzLnNwbGljZShpbmRleCwgMSk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG5cbiAgICAgICAgICB0aGlzLmFjdGl2ZVRhcmdldEtleXMubGVuZ3RoID0gMDtcblxuICAgICAgICAgIHRoaXMuX2NsZWFyTWFjcm9zKCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9LCB7XG4gICAgICBrZXk6IFwiX2FwcGx5TWFjcm9zXCIsXG4gICAgICB2YWx1ZTogZnVuY3Rpb24gX2FwcGx5TWFjcm9zKCkge1xuICAgICAgICB2YXIgbWFjcm9zID0gdGhpcy5fbWFjcm9zLnNsaWNlKDApO1xuXG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbWFjcm9zLmxlbmd0aDsgaSArPSAxKSB7XG4gICAgICAgICAgdmFyIG1hY3JvID0gbWFjcm9zW2ldO1xuXG4gICAgICAgICAgaWYgKG1hY3JvLmtleUNvbWJvLmNoZWNrKHRoaXMucHJlc3NlZEtleXMpKSB7XG4gICAgICAgICAgICBpZiAobWFjcm8uaGFuZGxlcikge1xuICAgICAgICAgICAgICBtYWNyby5rZXlOYW1lcyA9IG1hY3JvLmhhbmRsZXIodGhpcy5wcmVzc2VkS2V5cyk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGZvciAodmFyIGogPSAwOyBqIDwgbWFjcm8ua2V5TmFtZXMubGVuZ3RoOyBqICs9IDEpIHtcbiAgICAgICAgICAgICAgaWYgKHRoaXMucHJlc3NlZEtleXMuaW5kZXhPZihtYWNyby5rZXlOYW1lc1tqXSkgPT09IC0xKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5wcmVzc2VkS2V5cy5wdXNoKG1hY3JvLmtleU5hbWVzW2pdKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB0aGlzLl9hcHBsaWVkTWFjcm9zLnB1c2gobWFjcm8pO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0sIHtcbiAgICAgIGtleTogXCJfY2xlYXJNYWNyb3NcIixcbiAgICAgIHZhbHVlOiBmdW5jdGlvbiBfY2xlYXJNYWNyb3MoKSB7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5fYXBwbGllZE1hY3Jvcy5sZW5ndGg7IGkgKz0gMSkge1xuICAgICAgICAgIHZhciBtYWNybyA9IHRoaXMuX2FwcGxpZWRNYWNyb3NbaV07XG5cbiAgICAgICAgICBpZiAoIW1hY3JvLmtleUNvbWJvLmNoZWNrKHRoaXMucHJlc3NlZEtleXMpKSB7XG4gICAgICAgICAgICBmb3IgKHZhciBqID0gMDsgaiA8IG1hY3JvLmtleU5hbWVzLmxlbmd0aDsgaiArPSAxKSB7XG4gICAgICAgICAgICAgIHZhciBpbmRleCA9IHRoaXMucHJlc3NlZEtleXMuaW5kZXhPZihtYWNyby5rZXlOYW1lc1tqXSk7XG5cbiAgICAgICAgICAgICAgaWYgKGluZGV4ID4gLTEpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnByZXNzZWRLZXlzLnNwbGljZShpbmRleCwgMSk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKG1hY3JvLmhhbmRsZXIpIHtcbiAgICAgICAgICAgICAgbWFjcm8ua2V5TmFtZXMgPSBudWxsO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB0aGlzLl9hcHBsaWVkTWFjcm9zLnNwbGljZShpLCAxKTtcblxuICAgICAgICAgICAgaSAtPSAxO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1dKTtcblxuICAgIHJldHVybiBMb2NhbGU7XG4gIH0oKTtcblxuICB2YXIgS2V5Ym9hcmQgPSAvKiNfX1BVUkVfXyovZnVuY3Rpb24gKCkge1xuICAgIGZ1bmN0aW9uIEtleWJvYXJkKHRhcmdldFdpbmRvdywgdGFyZ2V0RWxlbWVudCwgdGFyZ2V0UGxhdGZvcm0sIHRhcmdldFVzZXJBZ2VudCkge1xuICAgICAgX2NsYXNzQ2FsbENoZWNrKHRoaXMsIEtleWJvYXJkKTtcblxuICAgICAgdGhpcy5fbG9jYWxlID0gbnVsbDtcbiAgICAgIHRoaXMuX2N1cnJlbnRDb250ZXh0ID0gJyc7XG4gICAgICB0aGlzLl9jb250ZXh0cyA9IHt9O1xuICAgICAgdGhpcy5fbGlzdGVuZXJzID0gW107XG4gICAgICB0aGlzLl9hcHBsaWVkTGlzdGVuZXJzID0gW107XG4gICAgICB0aGlzLl9sb2NhbGVzID0ge307XG4gICAgICB0aGlzLl90YXJnZXRFbGVtZW50ID0gbnVsbDtcbiAgICAgIHRoaXMuX3RhcmdldFdpbmRvdyA9IG51bGw7XG4gICAgICB0aGlzLl90YXJnZXRQbGF0Zm9ybSA9ICcnO1xuICAgICAgdGhpcy5fdGFyZ2V0VXNlckFnZW50ID0gJyc7XG4gICAgICB0aGlzLl9pc01vZGVybkJyb3dzZXIgPSBmYWxzZTtcbiAgICAgIHRoaXMuX3RhcmdldEtleURvd25CaW5kaW5nID0gbnVsbDtcbiAgICAgIHRoaXMuX3RhcmdldEtleVVwQmluZGluZyA9IG51bGw7XG4gICAgICB0aGlzLl90YXJnZXRSZXNldEJpbmRpbmcgPSBudWxsO1xuICAgICAgdGhpcy5fcGF1c2VkID0gZmFsc2U7XG4gICAgICB0aGlzLl9jb250ZXh0cy5nbG9iYWwgPSB7XG4gICAgICAgIGxpc3RlbmVyczogdGhpcy5fbGlzdGVuZXJzLFxuICAgICAgICB0YXJnZXRXaW5kb3c6IHRhcmdldFdpbmRvdyxcbiAgICAgICAgdGFyZ2V0RWxlbWVudDogdGFyZ2V0RWxlbWVudCxcbiAgICAgICAgdGFyZ2V0UGxhdGZvcm06IHRhcmdldFBsYXRmb3JtLFxuICAgICAgICB0YXJnZXRVc2VyQWdlbnQ6IHRhcmdldFVzZXJBZ2VudFxuICAgICAgfTtcbiAgICAgIHRoaXMuc2V0Q29udGV4dCgnZ2xvYmFsJyk7XG4gICAgfVxuXG4gICAgX2NyZWF0ZUNsYXNzKEtleWJvYXJkLCBbe1xuICAgICAga2V5OiBcInNldExvY2FsZVwiLFxuICAgICAgdmFsdWU6IGZ1bmN0aW9uIHNldExvY2FsZShsb2NhbGVOYW1lLCBsb2NhbGVCdWlsZGVyKSB7XG4gICAgICAgIHZhciBsb2NhbGUgPSBudWxsO1xuXG4gICAgICAgIGlmICh0eXBlb2YgbG9jYWxlTmFtZSA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgICBpZiAobG9jYWxlQnVpbGRlcikge1xuICAgICAgICAgICAgbG9jYWxlID0gbmV3IExvY2FsZShsb2NhbGVOYW1lKTtcbiAgICAgICAgICAgIGxvY2FsZUJ1aWxkZXIobG9jYWxlLCB0aGlzLl90YXJnZXRQbGF0Zm9ybSwgdGhpcy5fdGFyZ2V0VXNlckFnZW50KTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgbG9jYWxlID0gdGhpcy5fbG9jYWxlc1tsb2NhbGVOYW1lXSB8fCBudWxsO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBsb2NhbGUgPSBsb2NhbGVOYW1lO1xuICAgICAgICAgIGxvY2FsZU5hbWUgPSBsb2NhbGUuX2xvY2FsZU5hbWU7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLl9sb2NhbGUgPSBsb2NhbGU7XG4gICAgICAgIHRoaXMuX2xvY2FsZXNbbG9jYWxlTmFtZV0gPSBsb2NhbGU7XG5cbiAgICAgICAgaWYgKGxvY2FsZSkge1xuICAgICAgICAgIHRoaXMuX2xvY2FsZS5wcmVzc2VkS2V5cyA9IGxvY2FsZS5wcmVzc2VkS2V5cztcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgfVxuICAgIH0sIHtcbiAgICAgIGtleTogXCJnZXRMb2NhbGVcIixcbiAgICAgIHZhbHVlOiBmdW5jdGlvbiBnZXRMb2NhbGUobG9jYWxOYW1lKSB7XG4gICAgICAgIGxvY2FsTmFtZSB8fCAobG9jYWxOYW1lID0gdGhpcy5fbG9jYWxlLmxvY2FsZU5hbWUpO1xuICAgICAgICByZXR1cm4gdGhpcy5fbG9jYWxlc1tsb2NhbE5hbWVdIHx8IG51bGw7XG4gICAgICB9XG4gICAgfSwge1xuICAgICAga2V5OiBcImJpbmRcIixcbiAgICAgIHZhbHVlOiBmdW5jdGlvbiBiaW5kKGtleUNvbWJvU3RyLCBwcmVzc0hhbmRsZXIsIHJlbGVhc2VIYW5kbGVyLCBwcmV2ZW50UmVwZWF0QnlEZWZhdWx0KSB7XG4gICAgICAgIGlmIChrZXlDb21ib1N0ciA9PT0gbnVsbCB8fCB0eXBlb2Yga2V5Q29tYm9TdHIgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICBwcmV2ZW50UmVwZWF0QnlEZWZhdWx0ID0gcmVsZWFzZUhhbmRsZXI7XG4gICAgICAgICAgcmVsZWFzZUhhbmRsZXIgPSBwcmVzc0hhbmRsZXI7XG4gICAgICAgICAgcHJlc3NIYW5kbGVyID0ga2V5Q29tYm9TdHI7XG4gICAgICAgICAga2V5Q29tYm9TdHIgPSBudWxsO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGtleUNvbWJvU3RyICYmIF90eXBlb2Yoa2V5Q29tYm9TdHIpID09PSAnb2JqZWN0JyAmJiB0eXBlb2Yga2V5Q29tYm9TdHIubGVuZ3RoID09PSAnbnVtYmVyJykge1xuICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwga2V5Q29tYm9TdHIubGVuZ3RoOyBpICs9IDEpIHtcbiAgICAgICAgICAgIHRoaXMuYmluZChrZXlDb21ib1N0cltpXSwgcHJlc3NIYW5kbGVyLCByZWxlYXNlSGFuZGxlcik7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLl9saXN0ZW5lcnMucHVzaCh7XG4gICAgICAgICAga2V5Q29tYm86IGtleUNvbWJvU3RyID8gbmV3IEtleUNvbWJvKGtleUNvbWJvU3RyKSA6IG51bGwsXG4gICAgICAgICAgcHJlc3NIYW5kbGVyOiBwcmVzc0hhbmRsZXIgfHwgbnVsbCxcbiAgICAgICAgICByZWxlYXNlSGFuZGxlcjogcmVsZWFzZUhhbmRsZXIgfHwgbnVsbCxcbiAgICAgICAgICBwcmV2ZW50UmVwZWF0OiBmYWxzZSxcbiAgICAgICAgICBwcmV2ZW50UmVwZWF0QnlEZWZhdWx0OiBwcmV2ZW50UmVwZWF0QnlEZWZhdWx0IHx8IGZhbHNlLFxuICAgICAgICAgIGV4ZWN1dGluZ0hhbmRsZXI6IGZhbHNlXG4gICAgICAgIH0pO1xuXG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgfVxuICAgIH0sIHtcbiAgICAgIGtleTogXCJhZGRMaXN0ZW5lclwiLFxuICAgICAgdmFsdWU6IGZ1bmN0aW9uIGFkZExpc3RlbmVyKGtleUNvbWJvU3RyLCBwcmVzc0hhbmRsZXIsIHJlbGVhc2VIYW5kbGVyLCBwcmV2ZW50UmVwZWF0QnlEZWZhdWx0KSB7XG4gICAgICAgIHJldHVybiB0aGlzLmJpbmQoa2V5Q29tYm9TdHIsIHByZXNzSGFuZGxlciwgcmVsZWFzZUhhbmRsZXIsIHByZXZlbnRSZXBlYXRCeURlZmF1bHQpO1xuICAgICAgfVxuICAgIH0sIHtcbiAgICAgIGtleTogXCJvblwiLFxuICAgICAgdmFsdWU6IGZ1bmN0aW9uIG9uKGtleUNvbWJvU3RyLCBwcmVzc0hhbmRsZXIsIHJlbGVhc2VIYW5kbGVyLCBwcmV2ZW50UmVwZWF0QnlEZWZhdWx0KSB7XG4gICAgICAgIHJldHVybiB0aGlzLmJpbmQoa2V5Q29tYm9TdHIsIHByZXNzSGFuZGxlciwgcmVsZWFzZUhhbmRsZXIsIHByZXZlbnRSZXBlYXRCeURlZmF1bHQpO1xuICAgICAgfVxuICAgIH0sIHtcbiAgICAgIGtleTogXCJiaW5kUHJlc3NcIixcbiAgICAgIHZhbHVlOiBmdW5jdGlvbiBiaW5kUHJlc3Moa2V5Q29tYm9TdHIsIHByZXNzSGFuZGxlciwgcHJldmVudFJlcGVhdEJ5RGVmYXVsdCkge1xuICAgICAgICByZXR1cm4gdGhpcy5iaW5kKGtleUNvbWJvU3RyLCBwcmVzc0hhbmRsZXIsIG51bGwsIHByZXZlbnRSZXBlYXRCeURlZmF1bHQpO1xuICAgICAgfVxuICAgIH0sIHtcbiAgICAgIGtleTogXCJiaW5kUmVsZWFzZVwiLFxuICAgICAgdmFsdWU6IGZ1bmN0aW9uIGJpbmRSZWxlYXNlKGtleUNvbWJvU3RyLCByZWxlYXNlSGFuZGxlcikge1xuICAgICAgICByZXR1cm4gdGhpcy5iaW5kKGtleUNvbWJvU3RyLCBudWxsLCByZWxlYXNlSGFuZGxlciwgcHJldmVudFJlcGVhdEJ5RGVmYXVsdCk7XG4gICAgICB9XG4gICAgfSwge1xuICAgICAga2V5OiBcInVuYmluZFwiLFxuICAgICAgdmFsdWU6IGZ1bmN0aW9uIHVuYmluZChrZXlDb21ib1N0ciwgcHJlc3NIYW5kbGVyLCByZWxlYXNlSGFuZGxlcikge1xuICAgICAgICBpZiAoa2V5Q29tYm9TdHIgPT09IG51bGwgfHwgdHlwZW9mIGtleUNvbWJvU3RyID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgcmVsZWFzZUhhbmRsZXIgPSBwcmVzc0hhbmRsZXI7XG4gICAgICAgICAgcHJlc3NIYW5kbGVyID0ga2V5Q29tYm9TdHI7XG4gICAgICAgICAga2V5Q29tYm9TdHIgPSBudWxsO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGtleUNvbWJvU3RyICYmIF90eXBlb2Yoa2V5Q29tYm9TdHIpID09PSAnb2JqZWN0JyAmJiB0eXBlb2Yga2V5Q29tYm9TdHIubGVuZ3RoID09PSAnbnVtYmVyJykge1xuICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwga2V5Q29tYm9TdHIubGVuZ3RoOyBpICs9IDEpIHtcbiAgICAgICAgICAgIHRoaXMudW5iaW5kKGtleUNvbWJvU3RyW2ldLCBwcmVzc0hhbmRsZXIsIHJlbGVhc2VIYW5kbGVyKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgfVxuXG4gICAgICAgIGZvciAodmFyIF9pID0gMDsgX2kgPCB0aGlzLl9saXN0ZW5lcnMubGVuZ3RoOyBfaSArPSAxKSB7XG4gICAgICAgICAgdmFyIGxpc3RlbmVyID0gdGhpcy5fbGlzdGVuZXJzW19pXTtcbiAgICAgICAgICB2YXIgY29tYm9NYXRjaGVzID0gIWtleUNvbWJvU3RyICYmICFsaXN0ZW5lci5rZXlDb21ibyB8fCBsaXN0ZW5lci5rZXlDb21ibyAmJiBsaXN0ZW5lci5rZXlDb21iby5pc0VxdWFsKGtleUNvbWJvU3RyKTtcbiAgICAgICAgICB2YXIgcHJlc3NIYW5kbGVyTWF0Y2hlcyA9ICFwcmVzc0hhbmRsZXIgJiYgIXJlbGVhc2VIYW5kbGVyIHx8ICFwcmVzc0hhbmRsZXIgJiYgIWxpc3RlbmVyLnByZXNzSGFuZGxlciB8fCBwcmVzc0hhbmRsZXIgPT09IGxpc3RlbmVyLnByZXNzSGFuZGxlcjtcbiAgICAgICAgICB2YXIgcmVsZWFzZUhhbmRsZXJNYXRjaGVzID0gIXByZXNzSGFuZGxlciAmJiAhcmVsZWFzZUhhbmRsZXIgfHwgIXJlbGVhc2VIYW5kbGVyICYmICFsaXN0ZW5lci5yZWxlYXNlSGFuZGxlciB8fCByZWxlYXNlSGFuZGxlciA9PT0gbGlzdGVuZXIucmVsZWFzZUhhbmRsZXI7XG5cbiAgICAgICAgICBpZiAoY29tYm9NYXRjaGVzICYmIHByZXNzSGFuZGxlck1hdGNoZXMgJiYgcmVsZWFzZUhhbmRsZXJNYXRjaGVzKSB7XG4gICAgICAgICAgICB0aGlzLl9saXN0ZW5lcnMuc3BsaWNlKF9pLCAxKTtcblxuICAgICAgICAgICAgX2kgLT0gMTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgIH1cbiAgICB9LCB7XG4gICAgICBrZXk6IFwicmVtb3ZlTGlzdGVuZXJcIixcbiAgICAgIHZhbHVlOiBmdW5jdGlvbiByZW1vdmVMaXN0ZW5lcihrZXlDb21ib1N0ciwgcHJlc3NIYW5kbGVyLCByZWxlYXNlSGFuZGxlcikge1xuICAgICAgICByZXR1cm4gdGhpcy51bmJpbmQoa2V5Q29tYm9TdHIsIHByZXNzSGFuZGxlciwgcmVsZWFzZUhhbmRsZXIpO1xuICAgICAgfVxuICAgIH0sIHtcbiAgICAgIGtleTogXCJvZmZcIixcbiAgICAgIHZhbHVlOiBmdW5jdGlvbiBvZmYoa2V5Q29tYm9TdHIsIHByZXNzSGFuZGxlciwgcmVsZWFzZUhhbmRsZXIpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMudW5iaW5kKGtleUNvbWJvU3RyLCBwcmVzc0hhbmRsZXIsIHJlbGVhc2VIYW5kbGVyKTtcbiAgICAgIH1cbiAgICB9LCB7XG4gICAgICBrZXk6IFwic2V0Q29udGV4dFwiLFxuICAgICAgdmFsdWU6IGZ1bmN0aW9uIHNldENvbnRleHQoY29udGV4dE5hbWUpIHtcbiAgICAgICAgaWYgKHRoaXMuX2xvY2FsZSkge1xuICAgICAgICAgIHRoaXMucmVsZWFzZUFsbEtleXMoKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICghdGhpcy5fY29udGV4dHNbY29udGV4dE5hbWVdKSB7XG4gICAgICAgICAgdmFyIGdsb2JhbENvbnRleHQgPSB0aGlzLl9jb250ZXh0cy5nbG9iYWw7XG4gICAgICAgICAgdGhpcy5fY29udGV4dHNbY29udGV4dE5hbWVdID0ge1xuICAgICAgICAgICAgbGlzdGVuZXJzOiBbXSxcbiAgICAgICAgICAgIHRhcmdldFdpbmRvdzogZ2xvYmFsQ29udGV4dC50YXJnZXRXaW5kb3csXG4gICAgICAgICAgICB0YXJnZXRFbGVtZW50OiBnbG9iYWxDb250ZXh0LnRhcmdldEVsZW1lbnQsXG4gICAgICAgICAgICB0YXJnZXRQbGF0Zm9ybTogZ2xvYmFsQ29udGV4dC50YXJnZXRQbGF0Zm9ybSxcbiAgICAgICAgICAgIHRhcmdldFVzZXJBZ2VudDogZ2xvYmFsQ29udGV4dC50YXJnZXRVc2VyQWdlbnRcbiAgICAgICAgICB9O1xuICAgICAgICB9XG5cbiAgICAgICAgdmFyIGNvbnRleHQgPSB0aGlzLl9jb250ZXh0c1tjb250ZXh0TmFtZV07XG4gICAgICAgIHRoaXMuX2N1cnJlbnRDb250ZXh0ID0gY29udGV4dE5hbWU7XG4gICAgICAgIHRoaXMuX2xpc3RlbmVycyA9IGNvbnRleHQubGlzdGVuZXJzO1xuICAgICAgICB0aGlzLnN0b3AoKTtcbiAgICAgICAgdGhpcy53YXRjaChjb250ZXh0LnRhcmdldFdpbmRvdywgY29udGV4dC50YXJnZXRFbGVtZW50LCBjb250ZXh0LnRhcmdldFBsYXRmb3JtLCBjb250ZXh0LnRhcmdldFVzZXJBZ2VudCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgfVxuICAgIH0sIHtcbiAgICAgIGtleTogXCJnZXRDb250ZXh0XCIsXG4gICAgICB2YWx1ZTogZnVuY3Rpb24gZ2V0Q29udGV4dCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2N1cnJlbnRDb250ZXh0O1xuICAgICAgfVxuICAgIH0sIHtcbiAgICAgIGtleTogXCJ3aXRoQ29udGV4dFwiLFxuICAgICAgdmFsdWU6IGZ1bmN0aW9uIHdpdGhDb250ZXh0KGNvbnRleHROYW1lLCBjYWxsYmFjaykge1xuICAgICAgICB2YXIgcHJldmlvdXNDb250ZXh0TmFtZSA9IHRoaXMuZ2V0Q29udGV4dCgpO1xuICAgICAgICB0aGlzLnNldENvbnRleHQoY29udGV4dE5hbWUpO1xuICAgICAgICBjYWxsYmFjaygpO1xuICAgICAgICB0aGlzLnNldENvbnRleHQocHJldmlvdXNDb250ZXh0TmFtZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgfVxuICAgIH0sIHtcbiAgICAgIGtleTogXCJ3YXRjaFwiLFxuICAgICAgdmFsdWU6IGZ1bmN0aW9uIHdhdGNoKHRhcmdldFdpbmRvdywgdGFyZ2V0RWxlbWVudCwgdGFyZ2V0UGxhdGZvcm0sIHRhcmdldFVzZXJBZ2VudCkge1xuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xuXG4gICAgICAgIHRoaXMuc3RvcCgpO1xuICAgICAgICB2YXIgd2luID0gdHlwZW9mIGdsb2JhbFRoaXMgIT09ICd1bmRlZmluZWQnID8gZ2xvYmFsVGhpcyA6IHR5cGVvZiBnbG9iYWwgIT09ICd1bmRlZmluZWQnID8gZ2xvYmFsIDogdHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCcgPyB3aW5kb3cgOiB7fTtcblxuICAgICAgICBpZiAoIXRhcmdldFdpbmRvdykge1xuICAgICAgICAgIGlmICghd2luLmFkZEV2ZW50TGlzdGVuZXIgJiYgIXdpbi5hdHRhY2hFdmVudCkge1xuICAgICAgICAgICAgLy8gVGhpcyB3YXMgYWRkZWQgc28gd2hlbiB1c2luZyB0aGluZ3MgbGlrZSBKU0RPTSB3YXRjaCBjYW4gYmUgdXNlZCB0byBjb25maWd1cmUgd2F0Y2hcbiAgICAgICAgICAgIC8vIGZvciB0aGUgZ2xvYmFsIG5hbWVzcGFjZSBtYW51YWxseS5cbiAgICAgICAgICAgIGlmICh0aGlzLl9jdXJyZW50Q29udGV4dCA9PT0gJ2dsb2JhbCcpIHtcbiAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0Nhbm5vdCBmaW5kIHdpbmRvdyBmdW5jdGlvbnMgYWRkRXZlbnRMaXN0ZW5lciBvciBhdHRhY2hFdmVudC4nKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICB0YXJnZXRXaW5kb3cgPSB3aW47XG4gICAgICAgIH0gLy8gSGFuZGxlIGVsZW1lbnQgYmluZGluZ3Mgd2hlcmUgYSB0YXJnZXQgd2luZG93IGlzIG5vdCBwYXNzZWRcblxuXG4gICAgICAgIGlmICh0eXBlb2YgdGFyZ2V0V2luZG93Lm5vZGVUeXBlID09PSAnbnVtYmVyJykge1xuICAgICAgICAgIHRhcmdldFVzZXJBZ2VudCA9IHRhcmdldFBsYXRmb3JtO1xuICAgICAgICAgIHRhcmdldFBsYXRmb3JtID0gdGFyZ2V0RWxlbWVudDtcbiAgICAgICAgICB0YXJnZXRFbGVtZW50ID0gdGFyZ2V0V2luZG93O1xuICAgICAgICAgIHRhcmdldFdpbmRvdyA9IHdpbjtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICghdGFyZ2V0V2luZG93LmFkZEV2ZW50TGlzdGVuZXIgJiYgIXRhcmdldFdpbmRvdy5hdHRhY2hFdmVudCkge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcignQ2Fubm90IGZpbmQgYWRkRXZlbnRMaXN0ZW5lciBvciBhdHRhY2hFdmVudCBtZXRob2RzIG9uIHRhcmdldFdpbmRvdy4nKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuX2lzTW9kZXJuQnJvd3NlciA9ICEhdGFyZ2V0V2luZG93LmFkZEV2ZW50TGlzdGVuZXI7XG4gICAgICAgIHZhciB1c2VyQWdlbnQgPSB0YXJnZXRXaW5kb3cubmF2aWdhdG9yICYmIHRhcmdldFdpbmRvdy5uYXZpZ2F0b3IudXNlckFnZW50IHx8ICcnO1xuICAgICAgICB2YXIgcGxhdGZvcm0gPSB0YXJnZXRXaW5kb3cubmF2aWdhdG9yICYmIHRhcmdldFdpbmRvdy5uYXZpZ2F0b3IucGxhdGZvcm0gfHwgJyc7XG4gICAgICAgIHRhcmdldEVsZW1lbnQgJiYgdGFyZ2V0RWxlbWVudCAhPT0gbnVsbCB8fCAodGFyZ2V0RWxlbWVudCA9IHRhcmdldFdpbmRvdy5kb2N1bWVudCk7XG4gICAgICAgIHRhcmdldFBsYXRmb3JtICYmIHRhcmdldFBsYXRmb3JtICE9PSBudWxsIHx8ICh0YXJnZXRQbGF0Zm9ybSA9IHBsYXRmb3JtKTtcbiAgICAgICAgdGFyZ2V0VXNlckFnZW50ICYmIHRhcmdldFVzZXJBZ2VudCAhPT0gbnVsbCB8fCAodGFyZ2V0VXNlckFnZW50ID0gdXNlckFnZW50KTtcblxuICAgICAgICB0aGlzLl90YXJnZXRLZXlEb3duQmluZGluZyA9IGZ1bmN0aW9uIChldmVudCkge1xuICAgICAgICAgIF90aGlzLnByZXNzS2V5KGV2ZW50LmtleUNvZGUsIGV2ZW50KTtcblxuICAgICAgICAgIF90aGlzLl9oYW5kbGVDb21tYW5kQnVnKGV2ZW50LCBwbGF0Zm9ybSk7XG4gICAgICAgIH07XG5cbiAgICAgICAgdGhpcy5fdGFyZ2V0S2V5VXBCaW5kaW5nID0gZnVuY3Rpb24gKGV2ZW50KSB7XG4gICAgICAgICAgX3RoaXMucmVsZWFzZUtleShldmVudC5rZXlDb2RlLCBldmVudCk7XG4gICAgICAgIH07XG5cbiAgICAgICAgdGhpcy5fdGFyZ2V0UmVzZXRCaW5kaW5nID0gZnVuY3Rpb24gKGV2ZW50KSB7XG4gICAgICAgICAgX3RoaXMucmVsZWFzZUFsbEtleXMoZXZlbnQpO1xuICAgICAgICB9O1xuXG4gICAgICAgIHRoaXMuX2JpbmRFdmVudCh0YXJnZXRFbGVtZW50LCAna2V5ZG93bicsIHRoaXMuX3RhcmdldEtleURvd25CaW5kaW5nKTtcblxuICAgICAgICB0aGlzLl9iaW5kRXZlbnQodGFyZ2V0RWxlbWVudCwgJ2tleXVwJywgdGhpcy5fdGFyZ2V0S2V5VXBCaW5kaW5nKTtcblxuICAgICAgICB0aGlzLl9iaW5kRXZlbnQodGFyZ2V0V2luZG93LCAnZm9jdXMnLCB0aGlzLl90YXJnZXRSZXNldEJpbmRpbmcpO1xuXG4gICAgICAgIHRoaXMuX2JpbmRFdmVudCh0YXJnZXRXaW5kb3csICdibHVyJywgdGhpcy5fdGFyZ2V0UmVzZXRCaW5kaW5nKTtcblxuICAgICAgICB0aGlzLl90YXJnZXRFbGVtZW50ID0gdGFyZ2V0RWxlbWVudDtcbiAgICAgICAgdGhpcy5fdGFyZ2V0V2luZG93ID0gdGFyZ2V0V2luZG93O1xuICAgICAgICB0aGlzLl90YXJnZXRQbGF0Zm9ybSA9IHRhcmdldFBsYXRmb3JtO1xuICAgICAgICB0aGlzLl90YXJnZXRVc2VyQWdlbnQgPSB0YXJnZXRVc2VyQWdlbnQ7XG4gICAgICAgIHZhciBjdXJyZW50Q29udGV4dCA9IHRoaXMuX2NvbnRleHRzW3RoaXMuX2N1cnJlbnRDb250ZXh0XTtcbiAgICAgICAgY3VycmVudENvbnRleHQudGFyZ2V0V2luZG93ID0gdGhpcy5fdGFyZ2V0V2luZG93O1xuICAgICAgICBjdXJyZW50Q29udGV4dC50YXJnZXRFbGVtZW50ID0gdGhpcy5fdGFyZ2V0RWxlbWVudDtcbiAgICAgICAgY3VycmVudENvbnRleHQudGFyZ2V0UGxhdGZvcm0gPSB0aGlzLl90YXJnZXRQbGF0Zm9ybTtcbiAgICAgICAgY3VycmVudENvbnRleHQudGFyZ2V0VXNlckFnZW50ID0gdGhpcy5fdGFyZ2V0VXNlckFnZW50O1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgIH1cbiAgICB9LCB7XG4gICAgICBrZXk6IFwic3RvcFwiLFxuICAgICAgdmFsdWU6IGZ1bmN0aW9uIHN0b3AoKSB7XG4gICAgICAgIGlmICghdGhpcy5fdGFyZ2V0RWxlbWVudCB8fCAhdGhpcy5fdGFyZ2V0V2luZG93KSB7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5fdW5iaW5kRXZlbnQodGhpcy5fdGFyZ2V0RWxlbWVudCwgJ2tleWRvd24nLCB0aGlzLl90YXJnZXRLZXlEb3duQmluZGluZyk7XG5cbiAgICAgICAgdGhpcy5fdW5iaW5kRXZlbnQodGhpcy5fdGFyZ2V0RWxlbWVudCwgJ2tleXVwJywgdGhpcy5fdGFyZ2V0S2V5VXBCaW5kaW5nKTtcblxuICAgICAgICB0aGlzLl91bmJpbmRFdmVudCh0aGlzLl90YXJnZXRXaW5kb3csICdmb2N1cycsIHRoaXMuX3RhcmdldFJlc2V0QmluZGluZyk7XG5cbiAgICAgICAgdGhpcy5fdW5iaW5kRXZlbnQodGhpcy5fdGFyZ2V0V2luZG93LCAnYmx1cicsIHRoaXMuX3RhcmdldFJlc2V0QmluZGluZyk7XG5cbiAgICAgICAgdGhpcy5fdGFyZ2V0V2luZG93ID0gbnVsbDtcbiAgICAgICAgdGhpcy5fdGFyZ2V0RWxlbWVudCA9IG51bGw7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgfVxuICAgIH0sIHtcbiAgICAgIGtleTogXCJwcmVzc0tleVwiLFxuICAgICAgdmFsdWU6IGZ1bmN0aW9uIHByZXNzS2V5KGtleUNvZGUsIGV2ZW50KSB7XG4gICAgICAgIGlmICh0aGlzLl9wYXVzZWQpIHtcbiAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICghdGhpcy5fbG9jYWxlKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdMb2NhbGUgbm90IHNldCcpO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5fbG9jYWxlLnByZXNzS2V5KGtleUNvZGUpO1xuXG4gICAgICAgIHRoaXMuX2FwcGx5QmluZGluZ3MoZXZlbnQpO1xuXG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgfVxuICAgIH0sIHtcbiAgICAgIGtleTogXCJyZWxlYXNlS2V5XCIsXG4gICAgICB2YWx1ZTogZnVuY3Rpb24gcmVsZWFzZUtleShrZXlDb2RlLCBldmVudCkge1xuICAgICAgICBpZiAodGhpcy5fcGF1c2VkKSB7XG4gICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoIXRoaXMuX2xvY2FsZSkge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcignTG9jYWxlIG5vdCBzZXQnKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuX2xvY2FsZS5yZWxlYXNlS2V5KGtleUNvZGUpO1xuXG4gICAgICAgIHRoaXMuX2NsZWFyQmluZGluZ3MoZXZlbnQpO1xuXG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgfVxuICAgIH0sIHtcbiAgICAgIGtleTogXCJyZWxlYXNlQWxsS2V5c1wiLFxuICAgICAgdmFsdWU6IGZ1bmN0aW9uIHJlbGVhc2VBbGxLZXlzKGV2ZW50KSB7XG4gICAgICAgIGlmICh0aGlzLl9wYXVzZWQpIHtcbiAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICghdGhpcy5fbG9jYWxlKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdMb2NhbGUgbm90IHNldCcpO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5fbG9jYWxlLnByZXNzZWRLZXlzLmxlbmd0aCA9IDA7XG5cbiAgICAgICAgdGhpcy5fY2xlYXJCaW5kaW5ncyhldmVudCk7XG5cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICB9XG4gICAgfSwge1xuICAgICAga2V5OiBcInBhdXNlXCIsXG4gICAgICB2YWx1ZTogZnVuY3Rpb24gcGF1c2UoKSB7XG4gICAgICAgIGlmICh0aGlzLl9wYXVzZWQpIHtcbiAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0aGlzLl9sb2NhbGUpIHtcbiAgICAgICAgICB0aGlzLnJlbGVhc2VBbGxLZXlzKCk7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLl9wYXVzZWQgPSB0cnVlO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgIH1cbiAgICB9LCB7XG4gICAgICBrZXk6IFwicmVzdW1lXCIsXG4gICAgICB2YWx1ZTogZnVuY3Rpb24gcmVzdW1lKCkge1xuICAgICAgICB0aGlzLl9wYXVzZWQgPSBmYWxzZTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICB9XG4gICAgfSwge1xuICAgICAga2V5OiBcInJlc2V0XCIsXG4gICAgICB2YWx1ZTogZnVuY3Rpb24gcmVzZXQoKSB7XG4gICAgICAgIHRoaXMucmVsZWFzZUFsbEtleXMoKTtcbiAgICAgICAgdGhpcy5fbGlzdGVuZXJzLmxlbmd0aCA9IDA7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgfVxuICAgIH0sIHtcbiAgICAgIGtleTogXCJfYmluZEV2ZW50XCIsXG4gICAgICB2YWx1ZTogZnVuY3Rpb24gX2JpbmRFdmVudCh0YXJnZXRFbGVtZW50LCBldmVudE5hbWUsIGhhbmRsZXIpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2lzTW9kZXJuQnJvd3NlciA/IHRhcmdldEVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihldmVudE5hbWUsIGhhbmRsZXIsIGZhbHNlKSA6IHRhcmdldEVsZW1lbnQuYXR0YWNoRXZlbnQoJ29uJyArIGV2ZW50TmFtZSwgaGFuZGxlcik7XG4gICAgICB9XG4gICAgfSwge1xuICAgICAga2V5OiBcIl91bmJpbmRFdmVudFwiLFxuICAgICAgdmFsdWU6IGZ1bmN0aW9uIF91bmJpbmRFdmVudCh0YXJnZXRFbGVtZW50LCBldmVudE5hbWUsIGhhbmRsZXIpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2lzTW9kZXJuQnJvd3NlciA/IHRhcmdldEVsZW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcihldmVudE5hbWUsIGhhbmRsZXIsIGZhbHNlKSA6IHRhcmdldEVsZW1lbnQuZGV0YWNoRXZlbnQoJ29uJyArIGV2ZW50TmFtZSwgaGFuZGxlcik7XG4gICAgICB9XG4gICAgfSwge1xuICAgICAga2V5OiBcIl9nZXRHcm91cGVkTGlzdGVuZXJzXCIsXG4gICAgICB2YWx1ZTogZnVuY3Rpb24gX2dldEdyb3VwZWRMaXN0ZW5lcnMoKSB7XG4gICAgICAgIHZhciBsaXN0ZW5lckdyb3VwcyA9IFtdO1xuICAgICAgICB2YXIgbGlzdGVuZXJHcm91cE1hcCA9IFtdO1xuICAgICAgICB2YXIgbGlzdGVuZXJzID0gdGhpcy5fbGlzdGVuZXJzO1xuXG4gICAgICAgIGlmICh0aGlzLl9jdXJyZW50Q29udGV4dCAhPT0gJ2dsb2JhbCcpIHtcbiAgICAgICAgICBsaXN0ZW5lcnMgPSBbXS5jb25jYXQoX3RvQ29uc3VtYWJsZUFycmF5KGxpc3RlbmVycyksIF90b0NvbnN1bWFibGVBcnJheSh0aGlzLl9jb250ZXh0cy5nbG9iYWwubGlzdGVuZXJzKSk7XG4gICAgICAgIH1cblxuICAgICAgICBsaXN0ZW5lcnMuc29ydChmdW5jdGlvbiAoYSwgYikge1xuICAgICAgICAgIHJldHVybiAoYi5rZXlDb21ibyA/IGIua2V5Q29tYm8ua2V5TmFtZXMubGVuZ3RoIDogMCkgLSAoYS5rZXlDb21ibyA/IGEua2V5Q29tYm8ua2V5TmFtZXMubGVuZ3RoIDogMCk7XG4gICAgICAgIH0pLmZvckVhY2goZnVuY3Rpb24gKGwpIHtcbiAgICAgICAgICB2YXIgbWFwSW5kZXggPSAtMTtcblxuICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGlzdGVuZXJHcm91cE1hcC5sZW5ndGg7IGkgKz0gMSkge1xuICAgICAgICAgICAgaWYgKGxpc3RlbmVyR3JvdXBNYXBbaV0gPT09IG51bGwgJiYgbC5rZXlDb21ibyA9PT0gbnVsbCB8fCBsaXN0ZW5lckdyb3VwTWFwW2ldICE9PSBudWxsICYmIGxpc3RlbmVyR3JvdXBNYXBbaV0uaXNFcXVhbChsLmtleUNvbWJvKSkge1xuICAgICAgICAgICAgICBtYXBJbmRleCA9IGk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaWYgKG1hcEluZGV4ID09PSAtMSkge1xuICAgICAgICAgICAgbWFwSW5kZXggPSBsaXN0ZW5lckdyb3VwTWFwLmxlbmd0aDtcbiAgICAgICAgICAgIGxpc3RlbmVyR3JvdXBNYXAucHVzaChsLmtleUNvbWJvKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAoIWxpc3RlbmVyR3JvdXBzW21hcEluZGV4XSkge1xuICAgICAgICAgICAgbGlzdGVuZXJHcm91cHNbbWFwSW5kZXhdID0gW107XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgbGlzdGVuZXJHcm91cHNbbWFwSW5kZXhdLnB1c2gobCk7XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gbGlzdGVuZXJHcm91cHM7XG4gICAgICB9XG4gICAgfSwge1xuICAgICAga2V5OiBcIl9hcHBseUJpbmRpbmdzXCIsXG4gICAgICB2YWx1ZTogZnVuY3Rpb24gX2FwcGx5QmluZGluZ3MoZXZlbnQpIHtcbiAgICAgICAgdmFyIF90aGlzMiA9IHRoaXM7XG5cbiAgICAgICAgdmFyIHByZXZlbnRSZXBlYXQgPSBmYWxzZTtcbiAgICAgICAgZXZlbnQgfHwgKGV2ZW50ID0ge30pO1xuXG4gICAgICAgIGV2ZW50LnByZXZlbnRSZXBlYXQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgcHJldmVudFJlcGVhdCA9IHRydWU7XG4gICAgICAgIH07XG5cbiAgICAgICAgZXZlbnQucHJlc3NlZEtleXMgPSB0aGlzLl9sb2NhbGUucHJlc3NlZEtleXMuc2xpY2UoMCk7XG4gICAgICAgIHZhciBhY3RpdmVUYXJnZXRLZXlzID0gdGhpcy5fbG9jYWxlLmFjdGl2ZVRhcmdldEtleXM7XG5cbiAgICAgICAgdmFyIHByZXNzZWRLZXlzID0gdGhpcy5fbG9jYWxlLnByZXNzZWRLZXlzLnNsaWNlKDApO1xuXG4gICAgICAgIHZhciBsaXN0ZW5lckdyb3VwcyA9IHRoaXMuX2dldEdyb3VwZWRMaXN0ZW5lcnMoKTtcblxuICAgICAgICB2YXIgX2xvb3AgPSBmdW5jdGlvbiBfbG9vcChpKSB7XG4gICAgICAgICAgdmFyIGxpc3RlbmVycyA9IGxpc3RlbmVyR3JvdXBzW2ldO1xuICAgICAgICAgIHZhciBrZXlDb21ibyA9IGxpc3RlbmVyc1swXS5rZXlDb21ibztcblxuICAgICAgICAgIGlmIChrZXlDb21ibyA9PT0gbnVsbCB8fCBrZXlDb21iby5jaGVjayhwcmVzc2VkS2V5cykgJiYgYWN0aXZlVGFyZ2V0S2V5cy5zb21lKGZ1bmN0aW9uIChrKSB7XG4gICAgICAgICAgICByZXR1cm4ga2V5Q29tYm8ua2V5TmFtZXMuaW5jbHVkZXMoayk7XG4gICAgICAgICAgfSkpIHtcbiAgICAgICAgICAgIGZvciAodmFyIGogPSAwOyBqIDwgbGlzdGVuZXJzLmxlbmd0aDsgaiArPSAxKSB7XG4gICAgICAgICAgICAgIHZhciBsaXN0ZW5lciA9IGxpc3RlbmVyc1tqXTtcblxuICAgICAgICAgICAgICBpZiAoIWxpc3RlbmVyLmV4ZWN1dGluZ0hhbmRsZXIgJiYgbGlzdGVuZXIucHJlc3NIYW5kbGVyICYmICFsaXN0ZW5lci5wcmV2ZW50UmVwZWF0KSB7XG4gICAgICAgICAgICAgICAgbGlzdGVuZXIuZXhlY3V0aW5nSGFuZGxlciA9IHRydWU7XG4gICAgICAgICAgICAgICAgbGlzdGVuZXIucHJlc3NIYW5kbGVyLmNhbGwoX3RoaXMyLCBldmVudCk7XG4gICAgICAgICAgICAgICAgbGlzdGVuZXIuZXhlY3V0aW5nSGFuZGxlciA9IGZhbHNlO1xuXG4gICAgICAgICAgICAgICAgaWYgKHByZXZlbnRSZXBlYXQgfHwgbGlzdGVuZXIucHJldmVudFJlcGVhdEJ5RGVmYXVsdCkge1xuICAgICAgICAgICAgICAgICAgbGlzdGVuZXIucHJldmVudFJlcGVhdCA9IHRydWU7XG4gICAgICAgICAgICAgICAgICBwcmV2ZW50UmVwZWF0ID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgaWYgKF90aGlzMi5fYXBwbGllZExpc3RlbmVycy5pbmRleE9mKGxpc3RlbmVyKSA9PT0gLTEpIHtcbiAgICAgICAgICAgICAgICBfdGhpczIuX2FwcGxpZWRMaXN0ZW5lcnMucHVzaChsaXN0ZW5lcik7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKGtleUNvbWJvKSB7XG4gICAgICAgICAgICAgIGZvciAodmFyIF9qID0gMDsgX2ogPCBrZXlDb21iby5rZXlOYW1lcy5sZW5ndGg7IF9qICs9IDEpIHtcbiAgICAgICAgICAgICAgICB2YXIgaW5kZXggPSBwcmVzc2VkS2V5cy5pbmRleE9mKGtleUNvbWJvLmtleU5hbWVzW19qXSk7XG5cbiAgICAgICAgICAgICAgICBpZiAoaW5kZXggIT09IC0xKSB7XG4gICAgICAgICAgICAgICAgICBwcmVzc2VkS2V5cy5zcGxpY2UoaW5kZXgsIDEpO1xuICAgICAgICAgICAgICAgICAgX2ogLT0gMTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH07XG5cbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBsaXN0ZW5lckdyb3Vwcy5sZW5ndGg7IGkgKz0gMSkge1xuICAgICAgICAgIF9sb29wKGkpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSwge1xuICAgICAga2V5OiBcIl9jbGVhckJpbmRpbmdzXCIsXG4gICAgICB2YWx1ZTogZnVuY3Rpb24gX2NsZWFyQmluZGluZ3MoZXZlbnQpIHtcbiAgICAgICAgZXZlbnQgfHwgKGV2ZW50ID0ge30pO1xuICAgICAgICBldmVudC5wcmVzc2VkS2V5cyA9IHRoaXMuX2xvY2FsZS5wcmVzc2VkS2V5cy5zbGljZSgwKTtcblxuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMuX2FwcGxpZWRMaXN0ZW5lcnMubGVuZ3RoOyBpICs9IDEpIHtcbiAgICAgICAgICB2YXIgbGlzdGVuZXIgPSB0aGlzLl9hcHBsaWVkTGlzdGVuZXJzW2ldO1xuICAgICAgICAgIHZhciBrZXlDb21ibyA9IGxpc3RlbmVyLmtleUNvbWJvO1xuXG4gICAgICAgICAgaWYgKGtleUNvbWJvID09PSBudWxsIHx8ICFrZXlDb21iby5jaGVjayh0aGlzLl9sb2NhbGUucHJlc3NlZEtleXMpKSB7XG4gICAgICAgICAgICBsaXN0ZW5lci5wcmV2ZW50UmVwZWF0ID0gZmFsc2U7XG5cbiAgICAgICAgICAgIGlmIChrZXlDb21ibyAhPT0gbnVsbCB8fCBldmVudC5wcmVzc2VkS2V5cy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgICAgdGhpcy5fYXBwbGllZExpc3RlbmVycy5zcGxpY2UoaSwgMSk7XG5cbiAgICAgICAgICAgICAgaSAtPSAxO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAoIWxpc3RlbmVyLmV4ZWN1dGluZ0hhbmRsZXIgJiYgbGlzdGVuZXIucmVsZWFzZUhhbmRsZXIpIHtcbiAgICAgICAgICAgICAgbGlzdGVuZXIuZXhlY3V0aW5nSGFuZGxlciA9IHRydWU7XG4gICAgICAgICAgICAgIGxpc3RlbmVyLnJlbGVhc2VIYW5kbGVyLmNhbGwodGhpcywgZXZlbnQpO1xuICAgICAgICAgICAgICBsaXN0ZW5lci5leGVjdXRpbmdIYW5kbGVyID0gZmFsc2U7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfSwge1xuICAgICAga2V5OiBcIl9oYW5kbGVDb21tYW5kQnVnXCIsXG4gICAgICB2YWx1ZTogZnVuY3Rpb24gX2hhbmRsZUNvbW1hbmRCdWcoZXZlbnQsIHBsYXRmb3JtKSB7XG4gICAgICAgIC8vIE9uIE1hYyB3aGVuIHRoZSBjb21tYW5kIGtleSBpcyBrZXB0IHByZXNzZWQsIGtleXVwIGlzIG5vdCB0cmlnZ2VyZWQgZm9yIGFueSBvdGhlciBrZXkuXG4gICAgICAgIC8vIEluIHRoaXMgY2FzZSBmb3JjZSBhIGtleXVwIGZvciBub24tbW9kaWZpZXIga2V5cyBkaXJlY3RseSBhZnRlciB0aGUga2V5cHJlc3MuXG4gICAgICAgIHZhciBtb2RpZmllcktleXMgPSBbXCJzaGlmdFwiLCBcImN0cmxcIiwgXCJhbHRcIiwgXCJjYXBzbG9ja1wiLCBcInRhYlwiLCBcImNvbW1hbmRcIl07XG5cbiAgICAgICAgaWYgKHBsYXRmb3JtLm1hdGNoKFwiTWFjXCIpICYmIHRoaXMuX2xvY2FsZS5wcmVzc2VkS2V5cy5pbmNsdWRlcyhcImNvbW1hbmRcIikgJiYgIW1vZGlmaWVyS2V5cy5pbmNsdWRlcyh0aGlzLl9sb2NhbGUuZ2V0S2V5TmFtZXMoZXZlbnQua2V5Q29kZSlbMF0pKSB7XG4gICAgICAgICAgdGhpcy5fdGFyZ2V0S2V5VXBCaW5kaW5nKGV2ZW50KTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1dKTtcblxuICAgIHJldHVybiBLZXlib2FyZDtcbiAgfSgpO1xuXG4gIGZ1bmN0aW9uIHVzKGxvY2FsZSwgcGxhdGZvcm0sIHVzZXJBZ2VudCkge1xuICAgIC8vIGdlbmVyYWxcbiAgICBsb2NhbGUuYmluZEtleUNvZGUoMywgWydjYW5jZWwnXSk7XG4gICAgbG9jYWxlLmJpbmRLZXlDb2RlKDgsIFsnYmFja3NwYWNlJ10pO1xuICAgIGxvY2FsZS5iaW5kS2V5Q29kZSg5LCBbJ3RhYiddKTtcbiAgICBsb2NhbGUuYmluZEtleUNvZGUoMTIsIFsnY2xlYXInXSk7XG4gICAgbG9jYWxlLmJpbmRLZXlDb2RlKDEzLCBbJ2VudGVyJ10pO1xuICAgIGxvY2FsZS5iaW5kS2V5Q29kZSgxNiwgWydzaGlmdCddKTtcbiAgICBsb2NhbGUuYmluZEtleUNvZGUoMTcsIFsnY3RybCddKTtcbiAgICBsb2NhbGUuYmluZEtleUNvZGUoMTgsIFsnYWx0JywgJ21lbnUnXSk7XG4gICAgbG9jYWxlLmJpbmRLZXlDb2RlKDE5LCBbJ3BhdXNlJywgJ2JyZWFrJ10pO1xuICAgIGxvY2FsZS5iaW5kS2V5Q29kZSgyMCwgWydjYXBzbG9jayddKTtcbiAgICBsb2NhbGUuYmluZEtleUNvZGUoMjcsIFsnZXNjYXBlJywgJ2VzYyddKTtcbiAgICBsb2NhbGUuYmluZEtleUNvZGUoMzIsIFsnc3BhY2UnLCAnc3BhY2ViYXInXSk7XG4gICAgbG9jYWxlLmJpbmRLZXlDb2RlKDMzLCBbJ3BhZ2V1cCddKTtcbiAgICBsb2NhbGUuYmluZEtleUNvZGUoMzQsIFsncGFnZWRvd24nXSk7XG4gICAgbG9jYWxlLmJpbmRLZXlDb2RlKDM1LCBbJ2VuZCddKTtcbiAgICBsb2NhbGUuYmluZEtleUNvZGUoMzYsIFsnaG9tZSddKTtcbiAgICBsb2NhbGUuYmluZEtleUNvZGUoMzcsIFsnbGVmdCddKTtcbiAgICBsb2NhbGUuYmluZEtleUNvZGUoMzgsIFsndXAnXSk7XG4gICAgbG9jYWxlLmJpbmRLZXlDb2RlKDM5LCBbJ3JpZ2h0J10pO1xuICAgIGxvY2FsZS5iaW5kS2V5Q29kZSg0MCwgWydkb3duJ10pO1xuICAgIGxvY2FsZS5iaW5kS2V5Q29kZSg0MSwgWydzZWxlY3QnXSk7XG4gICAgbG9jYWxlLmJpbmRLZXlDb2RlKDQyLCBbJ3ByaW50c2NyZWVuJ10pO1xuICAgIGxvY2FsZS5iaW5kS2V5Q29kZSg0MywgWydleGVjdXRlJ10pO1xuICAgIGxvY2FsZS5iaW5kS2V5Q29kZSg0NCwgWydzbmFwc2hvdCddKTtcbiAgICBsb2NhbGUuYmluZEtleUNvZGUoNDUsIFsnaW5zZXJ0JywgJ2lucyddKTtcbiAgICBsb2NhbGUuYmluZEtleUNvZGUoNDYsIFsnZGVsZXRlJywgJ2RlbCddKTtcbiAgICBsb2NhbGUuYmluZEtleUNvZGUoNDcsIFsnaGVscCddKTtcbiAgICBsb2NhbGUuYmluZEtleUNvZGUoMTQ1LCBbJ3Njcm9sbGxvY2snLCAnc2Nyb2xsJ10pO1xuICAgIGxvY2FsZS5iaW5kS2V5Q29kZSgxODgsIFsnY29tbWEnLCAnLCddKTtcbiAgICBsb2NhbGUuYmluZEtleUNvZGUoMTkwLCBbJ3BlcmlvZCcsICcuJ10pO1xuICAgIGxvY2FsZS5iaW5kS2V5Q29kZSgxOTEsIFsnc2xhc2gnLCAnZm9yd2FyZHNsYXNoJywgJy8nXSk7XG4gICAgbG9jYWxlLmJpbmRLZXlDb2RlKDE5MiwgWydncmF2ZWFjY2VudCcsICdgJ10pO1xuICAgIGxvY2FsZS5iaW5kS2V5Q29kZSgyMTksIFsnb3BlbmJyYWNrZXQnLCAnWyddKTtcbiAgICBsb2NhbGUuYmluZEtleUNvZGUoMjIwLCBbJ2JhY2tzbGFzaCcsICdcXFxcJ10pO1xuICAgIGxvY2FsZS5iaW5kS2V5Q29kZSgyMjEsIFsnY2xvc2VicmFja2V0JywgJ10nXSk7XG4gICAgbG9jYWxlLmJpbmRLZXlDb2RlKDIyMiwgWydhcG9zdHJvcGhlJywgJ1xcJyddKTsgLy8gMC05XG5cbiAgICBsb2NhbGUuYmluZEtleUNvZGUoNDgsIFsnemVybycsICcwJ10pO1xuICAgIGxvY2FsZS5iaW5kS2V5Q29kZSg0OSwgWydvbmUnLCAnMSddKTtcbiAgICBsb2NhbGUuYmluZEtleUNvZGUoNTAsIFsndHdvJywgJzInXSk7XG4gICAgbG9jYWxlLmJpbmRLZXlDb2RlKDUxLCBbJ3RocmVlJywgJzMnXSk7XG4gICAgbG9jYWxlLmJpbmRLZXlDb2RlKDUyLCBbJ2ZvdXInLCAnNCddKTtcbiAgICBsb2NhbGUuYmluZEtleUNvZGUoNTMsIFsnZml2ZScsICc1J10pO1xuICAgIGxvY2FsZS5iaW5kS2V5Q29kZSg1NCwgWydzaXgnLCAnNiddKTtcbiAgICBsb2NhbGUuYmluZEtleUNvZGUoNTUsIFsnc2V2ZW4nLCAnNyddKTtcbiAgICBsb2NhbGUuYmluZEtleUNvZGUoNTYsIFsnZWlnaHQnLCAnOCddKTtcbiAgICBsb2NhbGUuYmluZEtleUNvZGUoNTcsIFsnbmluZScsICc5J10pOyAvLyBudW1wYWRcblxuICAgIGxvY2FsZS5iaW5kS2V5Q29kZSg5NiwgWydudW16ZXJvJywgJ251bTAnXSk7XG4gICAgbG9jYWxlLmJpbmRLZXlDb2RlKDk3LCBbJ251bW9uZScsICdudW0xJ10pO1xuICAgIGxvY2FsZS5iaW5kS2V5Q29kZSg5OCwgWydudW10d28nLCAnbnVtMiddKTtcbiAgICBsb2NhbGUuYmluZEtleUNvZGUoOTksIFsnbnVtdGhyZWUnLCAnbnVtMyddKTtcbiAgICBsb2NhbGUuYmluZEtleUNvZGUoMTAwLCBbJ251bWZvdXInLCAnbnVtNCddKTtcbiAgICBsb2NhbGUuYmluZEtleUNvZGUoMTAxLCBbJ251bWZpdmUnLCAnbnVtNSddKTtcbiAgICBsb2NhbGUuYmluZEtleUNvZGUoMTAyLCBbJ251bXNpeCcsICdudW02J10pO1xuICAgIGxvY2FsZS5iaW5kS2V5Q29kZSgxMDMsIFsnbnVtc2V2ZW4nLCAnbnVtNyddKTtcbiAgICBsb2NhbGUuYmluZEtleUNvZGUoMTA0LCBbJ251bWVpZ2h0JywgJ251bTgnXSk7XG4gICAgbG9jYWxlLmJpbmRLZXlDb2RlKDEwNSwgWydudW1uaW5lJywgJ251bTknXSk7XG4gICAgbG9jYWxlLmJpbmRLZXlDb2RlKDEwNiwgWydudW1tdWx0aXBseScsICdudW0qJ10pO1xuICAgIGxvY2FsZS5iaW5kS2V5Q29kZSgxMDcsIFsnbnVtYWRkJywgJ251bSsnXSk7XG4gICAgbG9jYWxlLmJpbmRLZXlDb2RlKDEwOCwgWydudW1lbnRlciddKTtcbiAgICBsb2NhbGUuYmluZEtleUNvZGUoMTA5LCBbJ251bXN1YnRyYWN0JywgJ251bS0nXSk7XG4gICAgbG9jYWxlLmJpbmRLZXlDb2RlKDExMCwgWydudW1kZWNpbWFsJywgJ251bS4nXSk7XG4gICAgbG9jYWxlLmJpbmRLZXlDb2RlKDExMSwgWydudW1kaXZpZGUnLCAnbnVtLyddKTtcbiAgICBsb2NhbGUuYmluZEtleUNvZGUoMTQ0LCBbJ251bWxvY2snLCAnbnVtJ10pOyAvLyBmdW5jdGlvbiBrZXlzXG5cbiAgICBsb2NhbGUuYmluZEtleUNvZGUoMTEyLCBbJ2YxJ10pO1xuICAgIGxvY2FsZS5iaW5kS2V5Q29kZSgxMTMsIFsnZjInXSk7XG4gICAgbG9jYWxlLmJpbmRLZXlDb2RlKDExNCwgWydmMyddKTtcbiAgICBsb2NhbGUuYmluZEtleUNvZGUoMTE1LCBbJ2Y0J10pO1xuICAgIGxvY2FsZS5iaW5kS2V5Q29kZSgxMTYsIFsnZjUnXSk7XG4gICAgbG9jYWxlLmJpbmRLZXlDb2RlKDExNywgWydmNiddKTtcbiAgICBsb2NhbGUuYmluZEtleUNvZGUoMTE4LCBbJ2Y3J10pO1xuICAgIGxvY2FsZS5iaW5kS2V5Q29kZSgxMTksIFsnZjgnXSk7XG4gICAgbG9jYWxlLmJpbmRLZXlDb2RlKDEyMCwgWydmOSddKTtcbiAgICBsb2NhbGUuYmluZEtleUNvZGUoMTIxLCBbJ2YxMCddKTtcbiAgICBsb2NhbGUuYmluZEtleUNvZGUoMTIyLCBbJ2YxMSddKTtcbiAgICBsb2NhbGUuYmluZEtleUNvZGUoMTIzLCBbJ2YxMiddKTtcbiAgICBsb2NhbGUuYmluZEtleUNvZGUoMTI0LCBbJ2YxMyddKTtcbiAgICBsb2NhbGUuYmluZEtleUNvZGUoMTI1LCBbJ2YxNCddKTtcbiAgICBsb2NhbGUuYmluZEtleUNvZGUoMTI2LCBbJ2YxNSddKTtcbiAgICBsb2NhbGUuYmluZEtleUNvZGUoMTI3LCBbJ2YxNiddKTtcbiAgICBsb2NhbGUuYmluZEtleUNvZGUoMTI4LCBbJ2YxNyddKTtcbiAgICBsb2NhbGUuYmluZEtleUNvZGUoMTI5LCBbJ2YxOCddKTtcbiAgICBsb2NhbGUuYmluZEtleUNvZGUoMTMwLCBbJ2YxOSddKTtcbiAgICBsb2NhbGUuYmluZEtleUNvZGUoMTMxLCBbJ2YyMCddKTtcbiAgICBsb2NhbGUuYmluZEtleUNvZGUoMTMyLCBbJ2YyMSddKTtcbiAgICBsb2NhbGUuYmluZEtleUNvZGUoMTMzLCBbJ2YyMiddKTtcbiAgICBsb2NhbGUuYmluZEtleUNvZGUoMTM0LCBbJ2YyMyddKTtcbiAgICBsb2NhbGUuYmluZEtleUNvZGUoMTM1LCBbJ2YyNCddKTsgLy8gc2Vjb25kYXJ5IGtleSBzeW1ib2xzXG5cbiAgICBsb2NhbGUuYmluZE1hY3JvKCdzaGlmdCArIGAnLCBbJ3RpbGRlJywgJ34nXSk7XG4gICAgbG9jYWxlLmJpbmRNYWNybygnc2hpZnQgKyAxJywgWydleGNsYW1hdGlvbicsICdleGNsYW1hdGlvbnBvaW50JywgJyEnXSk7XG4gICAgbG9jYWxlLmJpbmRNYWNybygnc2hpZnQgKyAyJywgWydhdCcsICdAJ10pO1xuICAgIGxvY2FsZS5iaW5kTWFjcm8oJ3NoaWZ0ICsgMycsIFsnbnVtYmVyJywgJyMnXSk7XG4gICAgbG9jYWxlLmJpbmRNYWNybygnc2hpZnQgKyA0JywgWydkb2xsYXInLCAnZG9sbGFycycsICdkb2xsYXJzaWduJywgJyQnXSk7XG4gICAgbG9jYWxlLmJpbmRNYWNybygnc2hpZnQgKyA1JywgWydwZXJjZW50JywgJyUnXSk7XG4gICAgbG9jYWxlLmJpbmRNYWNybygnc2hpZnQgKyA2JywgWydjYXJldCcsICdeJ10pO1xuICAgIGxvY2FsZS5iaW5kTWFjcm8oJ3NoaWZ0ICsgNycsIFsnYW1wZXJzYW5kJywgJ2FuZCcsICcmJ10pO1xuICAgIGxvY2FsZS5iaW5kTWFjcm8oJ3NoaWZ0ICsgOCcsIFsnYXN0ZXJpc2snLCAnKiddKTtcbiAgICBsb2NhbGUuYmluZE1hY3JvKCdzaGlmdCArIDknLCBbJ29wZW5wYXJlbicsICcoJ10pO1xuICAgIGxvY2FsZS5iaW5kTWFjcm8oJ3NoaWZ0ICsgMCcsIFsnY2xvc2VwYXJlbicsICcpJ10pO1xuICAgIGxvY2FsZS5iaW5kTWFjcm8oJ3NoaWZ0ICsgLScsIFsndW5kZXJzY29yZScsICdfJ10pO1xuICAgIGxvY2FsZS5iaW5kTWFjcm8oJ3NoaWZ0ICsgPScsIFsncGx1cycsICcrJ10pO1xuICAgIGxvY2FsZS5iaW5kTWFjcm8oJ3NoaWZ0ICsgWycsIFsnb3BlbmN1cmx5YnJhY2UnLCAnb3BlbmN1cmx5YnJhY2tldCcsICd7J10pO1xuICAgIGxvY2FsZS5iaW5kTWFjcm8oJ3NoaWZ0ICsgXScsIFsnY2xvc2VjdXJseWJyYWNlJywgJ2Nsb3NlY3VybHlicmFja2V0JywgJ30nXSk7XG4gICAgbG9jYWxlLmJpbmRNYWNybygnc2hpZnQgKyBcXFxcJywgWyd2ZXJ0aWNhbGJhcicsICd8J10pO1xuICAgIGxvY2FsZS5iaW5kTWFjcm8oJ3NoaWZ0ICsgOycsIFsnY29sb24nLCAnOiddKTtcbiAgICBsb2NhbGUuYmluZE1hY3JvKCdzaGlmdCArIFxcJycsIFsncXVvdGF0aW9ubWFyaycsICdcXCcnXSk7XG4gICAgbG9jYWxlLmJpbmRNYWNybygnc2hpZnQgKyAhLCcsIFsnb3BlbmFuZ2xlYnJhY2tldCcsICc8J10pO1xuICAgIGxvY2FsZS5iaW5kTWFjcm8oJ3NoaWZ0ICsgLicsIFsnY2xvc2VhbmdsZWJyYWNrZXQnLCAnPiddKTtcbiAgICBsb2NhbGUuYmluZE1hY3JvKCdzaGlmdCArIC8nLCBbJ3F1ZXN0aW9ubWFyaycsICc/J10pO1xuXG4gICAgaWYgKHBsYXRmb3JtLm1hdGNoKCdNYWMnKSkge1xuICAgICAgbG9jYWxlLmJpbmRNYWNybygnY29tbWFuZCcsIFsnbW9kJywgJ21vZGlmaWVyJ10pO1xuICAgIH0gZWxzZSB7XG4gICAgICBsb2NhbGUuYmluZE1hY3JvKCdjdHJsJywgWydtb2QnLCAnbW9kaWZpZXInXSk7XG4gICAgfSAvL2EteiBhbmQgQS1aXG5cblxuICAgIGZvciAodmFyIGtleUNvZGUgPSA2NTsga2V5Q29kZSA8PSA5MDsga2V5Q29kZSArPSAxKSB7XG4gICAgICB2YXIga2V5TmFtZSA9IFN0cmluZy5mcm9tQ2hhckNvZGUoa2V5Q29kZSArIDMyKTtcbiAgICAgIHZhciBjYXBpdGFsS2V5TmFtZSA9IFN0cmluZy5mcm9tQ2hhckNvZGUoa2V5Q29kZSk7XG4gICAgICBsb2NhbGUuYmluZEtleUNvZGUoa2V5Q29kZSwga2V5TmFtZSk7XG4gICAgICBsb2NhbGUuYmluZE1hY3JvKCdzaGlmdCArICcgKyBrZXlOYW1lLCBjYXBpdGFsS2V5TmFtZSk7XG4gICAgICBsb2NhbGUuYmluZE1hY3JvKCdjYXBzbG9jayArICcgKyBrZXlOYW1lLCBjYXBpdGFsS2V5TmFtZSk7XG4gICAgfSAvLyBicm93c2VyIGNhdmVhdHNcblxuXG4gICAgdmFyIHNlbWljb2xvbktleUNvZGUgPSB1c2VyQWdlbnQubWF0Y2goJ0ZpcmVmb3gnKSA/IDU5IDogMTg2O1xuICAgIHZhciBkYXNoS2V5Q29kZSA9IHVzZXJBZ2VudC5tYXRjaCgnRmlyZWZveCcpID8gMTczIDogMTg5O1xuICAgIHZhciBlcXVhbEtleUNvZGUgPSB1c2VyQWdlbnQubWF0Y2goJ0ZpcmVmb3gnKSA/IDYxIDogMTg3O1xuICAgIHZhciBsZWZ0Q29tbWFuZEtleUNvZGU7XG4gICAgdmFyIHJpZ2h0Q29tbWFuZEtleUNvZGU7XG5cbiAgICBpZiAocGxhdGZvcm0ubWF0Y2goJ01hYycpICYmICh1c2VyQWdlbnQubWF0Y2goJ1NhZmFyaScpIHx8IHVzZXJBZ2VudC5tYXRjaCgnQ2hyb21lJykpKSB7XG4gICAgICBsZWZ0Q29tbWFuZEtleUNvZGUgPSA5MTtcbiAgICAgIHJpZ2h0Q29tbWFuZEtleUNvZGUgPSA5MztcbiAgICB9IGVsc2UgaWYgKHBsYXRmb3JtLm1hdGNoKCdNYWMnKSAmJiB1c2VyQWdlbnQubWF0Y2goJ09wZXJhJykpIHtcbiAgICAgIGxlZnRDb21tYW5kS2V5Q29kZSA9IDE3O1xuICAgICAgcmlnaHRDb21tYW5kS2V5Q29kZSA9IDE3O1xuICAgIH0gZWxzZSBpZiAocGxhdGZvcm0ubWF0Y2goJ01hYycpICYmIHVzZXJBZ2VudC5tYXRjaCgnRmlyZWZveCcpKSB7XG4gICAgICBsZWZ0Q29tbWFuZEtleUNvZGUgPSAyMjQ7XG4gICAgICByaWdodENvbW1hbmRLZXlDb2RlID0gMjI0O1xuICAgIH1cblxuICAgIGxvY2FsZS5iaW5kS2V5Q29kZShzZW1pY29sb25LZXlDb2RlLCBbJ3NlbWljb2xvbicsICc7J10pO1xuICAgIGxvY2FsZS5iaW5kS2V5Q29kZShkYXNoS2V5Q29kZSwgWydkYXNoJywgJy0nXSk7XG4gICAgbG9jYWxlLmJpbmRLZXlDb2RlKGVxdWFsS2V5Q29kZSwgWydlcXVhbCcsICdlcXVhbHNpZ24nLCAnPSddKTtcbiAgICBsb2NhbGUuYmluZEtleUNvZGUobGVmdENvbW1hbmRLZXlDb2RlLCBbJ2NvbW1hbmQnLCAnd2luZG93cycsICd3aW4nLCAnc3VwZXInLCAnbGVmdGNvbW1hbmQnLCAnbGVmdHdpbmRvd3MnLCAnbGVmdHdpbicsICdsZWZ0c3VwZXInXSk7XG4gICAgbG9jYWxlLmJpbmRLZXlDb2RlKHJpZ2h0Q29tbWFuZEtleUNvZGUsIFsnY29tbWFuZCcsICd3aW5kb3dzJywgJ3dpbicsICdzdXBlcicsICdyaWdodGNvbW1hbmQnLCAncmlnaHR3aW5kb3dzJywgJ3JpZ2h0d2luJywgJ3JpZ2h0c3VwZXInXSk7IC8vIGtpbGwga2V5c1xuXG4gICAgbG9jYWxlLnNldEtpbGxLZXkoJ2NvbW1hbmQnKTtcbiAgfVxuXG4gIHZhciBrZXlib2FyZCA9IG5ldyBLZXlib2FyZCgpO1xuICBrZXlib2FyZC5zZXRMb2NhbGUoJ3VzJywgdXMpO1xuICBrZXlib2FyZC5LZXlib2FyZCA9IEtleWJvYXJkO1xuICBrZXlib2FyZC5Mb2NhbGUgPSBMb2NhbGU7XG4gIGtleWJvYXJkLktleUNvbWJvID0gS2V5Q29tYm87XG5cbiAgcmV0dXJuIGtleWJvYXJkO1xuXG59KSkpO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9ZGF0YTphcHBsaWNhdGlvbi9qc29uO2NoYXJzZXQ9dXRmLTg7YmFzZTY0LGV5SjJaWEp6YVc5dUlqb3pMQ0ptYVd4bElqb2lhMlY1WW05aGNtUXVhbk1pTENKemIzVnlZMlZ6SWpwYklpNHVMMnhwWWk5clpYa3RZMjl0WW04dWFuTWlMQ0l1TGk5c2FXSXZiRzlqWVd4bExtcHpJaXdpTGk0dmJHbGlMMnRsZVdKdllYSmtMbXB6SWl3aUxpNHZiRzlqWVd4bGN5OTFjeTVxY3lJc0lpNHVMMmx1WkdWNExtcHpJbDBzSW5OdmRYSmpaWE5EYjI1MFpXNTBJanBiSWx4dVpYaHdiM0owSUdOc1lYTnpJRXRsZVVOdmJXSnZJSHRjYmlBZ1kyOXVjM1J5ZFdOMGIzSW9hMlY1UTI5dFltOVRkSElwSUh0Y2JpQWdJQ0IwYUdsekxuTnZkWEpqWlZOMGNpQTlJR3RsZVVOdmJXSnZVM1J5TzF4dUlDQWdJSFJvYVhNdWMzVmlRMjl0WW05eklEMGdTMlY1UTI5dFltOHVjR0Z5YzJWRGIyMWliMU4wY2loclpYbERiMjFpYjFOMGNpazdYRzRnSUNBZ2RHaHBjeTVyWlhsT1lXMWxjeUFnUFNCMGFHbHpMbk4xWWtOdmJXSnZjeTV5WldSMVkyVW9LRzFsYlc4c0lHNWxlSFJUZFdKRGIyMWlieWtnUFQ1Y2JpQWdJQ0FnSUcxbGJXOHVZMjl1WTJGMEtHNWxlSFJUZFdKRGIyMWlieWtzSUZ0ZEtUdGNiaUFnZlZ4dVhHNGdJR05vWldOcktIQnlaWE56WldSTFpYbE9ZVzFsY3lrZ2UxeHVJQ0FnSUd4bGRDQnpkR0Z5ZEdsdVowdGxlVTVoYldWSmJtUmxlQ0E5SURBN1hHNGdJQ0FnWm05eUlDaHNaWFFnYVNBOUlEQTdJR2tnUENCMGFHbHpMbk4xWWtOdmJXSnZjeTVzWlc1bmRHZzdJR2tnS3owZ01Ta2dlMXh1SUNBZ0lDQWdjM1JoY25ScGJtZExaWGxPWVcxbFNXNWtaWGdnUFNCMGFHbHpMbDlqYUdWamExTjFZa052YldKdktGeHVJQ0FnSUNBZ0lDQjBhR2x6TG5OMVlrTnZiV0p2YzF0cFhTeGNiaUFnSUNBZ0lDQWdjM1JoY25ScGJtZExaWGxPWVcxbFNXNWtaWGdzWEc0Z0lDQWdJQ0FnSUhCeVpYTnpaV1JMWlhsT1lXMWxjMXh1SUNBZ0lDQWdLVHRjYmlBZ0lDQWdJR2xtSUNoemRHRnlkR2x1WjB0bGVVNWhiV1ZKYm1SbGVDQTlQVDBnTFRFcElIc2djbVYwZFhKdUlHWmhiSE5sT3lCOVhHNGdJQ0FnZlZ4dUlDQWdJSEpsZEhWeWJpQjBjblZsTzF4dUlDQjlPMXh1WEc0Z0lHbHpSWEYxWVd3b2IzUm9aWEpMWlhsRGIyMWlieWtnZTF4dUlDQWdJR2xtSUNoY2JpQWdJQ0FnSUNGdmRHaGxja3RsZVVOdmJXSnZJSHg4WEc0Z0lDQWdJQ0IwZVhCbGIyWWdiM1JvWlhKTFpYbERiMjFpYnlBaFBUMGdKM04wY21sdVp5Y2dKaVpjYmlBZ0lDQWdJSFI1Y0dWdlppQnZkR2hsY2t0bGVVTnZiV0p2SUNFOVBTQW5iMkpxWldOMEoxeHVJQ0FnSUNrZ2V5QnlaWFIxY200Z1ptRnNjMlU3SUgxY2JseHVJQ0FnSUdsbUlDaDBlWEJsYjJZZ2IzUm9aWEpMWlhsRGIyMWlieUE5UFQwZ0ozTjBjbWx1WnljcElIdGNiaUFnSUNBZ0lHOTBhR1Z5UzJWNVEyOXRZbThnUFNCdVpYY2dTMlY1UTI5dFltOG9iM1JvWlhKTFpYbERiMjFpYnlrN1hHNGdJQ0FnZlZ4dVhHNGdJQ0FnYVdZZ0tIUm9hWE11YzNWaVEyOXRZbTl6TG14bGJtZDBhQ0FoUFQwZ2IzUm9aWEpMWlhsRGIyMWlieTV6ZFdKRGIyMWliM011YkdWdVozUm9LU0I3WEc0Z0lDQWdJQ0J5WlhSMWNtNGdabUZzYzJVN1hHNGdJQ0FnZlZ4dUlDQWdJR1p2Y2lBb2JHVjBJR2tnUFNBd095QnBJRHdnZEdocGN5NXpkV0pEYjIxaWIzTXViR1Z1WjNSb095QnBJQ3M5SURFcElIdGNiaUFnSUNBZ0lHbG1JQ2gwYUdsekxuTjFZa052YldKdmMxdHBYUzVzWlc1bmRHZ2dJVDA5SUc5MGFHVnlTMlY1UTI5dFltOHVjM1ZpUTI5dFltOXpXMmxkTG14bGJtZDBhQ2tnZTF4dUlDQWdJQ0FnSUNCeVpYUjFjbTRnWm1Gc2MyVTdYRzRnSUNBZ0lDQjlYRzRnSUNBZ2ZWeHVYRzRnSUNBZ1ptOXlJQ2hzWlhRZ2FTQTlJREE3SUdrZ1BDQjBhR2x6TG5OMVlrTnZiV0p2Y3k1c1pXNW5kR2c3SUdrZ0t6MGdNU2tnZTF4dUlDQWdJQ0FnWTI5dWMzUWdjM1ZpUTI5dFltOGdJQ0FnSUNBOUlIUm9hWE11YzNWaVEyOXRZbTl6VzJsZE8xeHVJQ0FnSUNBZ1kyOXVjM1FnYjNSb1pYSlRkV0pEYjIxaWJ5QTlJRzkwYUdWeVMyVjVRMjl0WW04dWMzVmlRMjl0WW05elcybGRMbk5zYVdObEtEQXBPMXh1WEc0Z0lDQWdJQ0JtYjNJZ0tHeGxkQ0JxSUQwZ01Ec2dhaUE4SUhOMVlrTnZiV0p2TG14bGJtZDBhRHNnYWlBclBTQXhLU0I3WEc0Z0lDQWdJQ0FnSUdOdmJuTjBJR3RsZVU1aGJXVWdQU0J6ZFdKRGIyMWliMXRxWFR0Y2JpQWdJQ0FnSUNBZ1kyOXVjM1FnYVc1a1pYZ2dJQ0E5SUc5MGFHVnlVM1ZpUTI5dFltOHVhVzVrWlhoUFppaHJaWGxPWVcxbEtUdGNibHh1SUNBZ0lDQWdJQ0JwWmlBb2FXNWtaWGdnUGlBdE1Ta2dlMXh1SUNBZ0lDQWdJQ0FnSUc5MGFHVnlVM1ZpUTI5dFltOHVjM0JzYVdObEtHbHVaR1Y0TENBeEtUdGNiaUFnSUNBZ0lDQWdmVnh1SUNBZ0lDQWdmVnh1SUNBZ0lDQWdhV1lnS0c5MGFHVnlVM1ZpUTI5dFltOHViR1Z1WjNSb0lDRTlQU0F3S1NCN1hHNGdJQ0FnSUNBZ0lISmxkSFZ5YmlCbVlXeHpaVHRjYmlBZ0lDQWdJSDFjYmlBZ0lDQjlYRzVjYmlBZ0lDQnlaWFIxY200Z2RISjFaVHRjYmlBZ2ZUdGNibHh1SUNCZlkyaGxZMnRUZFdKRGIyMWlieWh6ZFdKRGIyMWlieXdnYzNSaGNuUnBibWRMWlhsT1lXMWxTVzVrWlhnc0lIQnlaWE56WldSTFpYbE9ZVzFsY3lrZ2UxeHVJQ0FnSUhOMVlrTnZiV0p2SUQwZ2MzVmlRMjl0WW04dWMyeHBZMlVvTUNrN1hHNGdJQ0FnY0hKbGMzTmxaRXRsZVU1aGJXVnpJRDBnY0hKbGMzTmxaRXRsZVU1aGJXVnpMbk5zYVdObEtITjBZWEowYVc1blMyVjVUbUZ0WlVsdVpHVjRLVHRjYmx4dUlDQWdJR3hsZENCbGJtUkpibVJsZUNBOUlITjBZWEowYVc1blMyVjVUbUZ0WlVsdVpHVjRPMXh1SUNBZ0lHWnZjaUFvYkdWMElHa2dQU0F3T3lCcElEd2djM1ZpUTI5dFltOHViR1Z1WjNSb095QnBJQ3M5SURFcElIdGNibHh1SUNBZ0lDQWdiR1YwSUd0bGVVNWhiV1VnUFNCemRXSkRiMjFpYjF0cFhUdGNiaUFnSUNBZ0lHbG1JQ2hyWlhsT1lXMWxXekJkSUQwOVBTQW5YRnhjWENjcElIdGNiaUFnSUNBZ0lDQWdZMjl1YzNRZ1pYTmpZWEJsWkV0bGVVNWhiV1VnUFNCclpYbE9ZVzFsTG5Oc2FXTmxLREVwTzF4dUlDQWdJQ0FnSUNCcFppQW9YRzRnSUNBZ0lDQWdJQ0FnWlhOallYQmxaRXRsZVU1aGJXVWdQVDA5SUV0bGVVTnZiV0p2TG1OdmJXSnZSR1ZzYVcxcGJtRjBiM0lnZkh4Y2JpQWdJQ0FnSUNBZ0lDQmxjMk5oY0dWa1MyVjVUbUZ0WlNBOVBUMGdTMlY1UTI5dFltOHVhMlY1UkdWc2FXMXBibUYwYjNKY2JpQWdJQ0FnSUNBZ0tTQjdYRzRnSUNBZ0lDQWdJQ0FnYTJWNVRtRnRaU0E5SUdWelkyRndaV1JMWlhsT1lXMWxPMXh1SUNBZ0lDQWdJQ0I5WEc0Z0lDQWdJQ0I5WEc1Y2JpQWdJQ0FnSUdOdmJuTjBJR2x1WkdWNElEMGdjSEpsYzNObFpFdGxlVTVoYldWekxtbHVaR1Y0VDJZb2EyVjVUbUZ0WlNrN1hHNGdJQ0FnSUNCcFppQW9hVzVrWlhnZ1BpQXRNU2tnZTF4dUlDQWdJQ0FnSUNCemRXSkRiMjFpYnk1emNHeHBZMlVvYVN3Z01TazdYRzRnSUNBZ0lDQWdJR2tnTFQwZ01UdGNiaUFnSUNBZ0lDQWdhV1lnS0dsdVpHVjRJRDRnWlc1a1NXNWtaWGdwSUh0Y2JpQWdJQ0FnSUNBZ0lDQmxibVJKYm1SbGVDQTlJR2x1WkdWNE8xeHVJQ0FnSUNBZ0lDQjlYRzRnSUNBZ0lDQWdJR2xtSUNoemRXSkRiMjFpYnk1c1pXNW5kR2dnUFQwOUlEQXBJSHRjYmlBZ0lDQWdJQ0FnSUNCeVpYUjFjbTRnWlc1a1NXNWtaWGc3WEc0Z0lDQWdJQ0FnSUgxY2JpQWdJQ0FnSUgxY2JpQWdJQ0I5WEc0Z0lDQWdjbVYwZFhKdUlDMHhPMXh1SUNCOU8xeHVmVnh1WEc1TFpYbERiMjFpYnk1amIyMWliMFJsYkdsdGFXNWhkRzl5SUQwZ0p6NG5PMXh1UzJWNVEyOXRZbTh1YTJWNVJHVnNhVzFwYm1GMGIzSWdJQ0E5SUNjckp6dGNibHh1UzJWNVEyOXRZbTh1Y0dGeWMyVkRiMjFpYjFOMGNpQTlJR1oxYm1OMGFXOXVLR3RsZVVOdmJXSnZVM1J5S1NCN1hHNGdJR052Ym5OMElITjFZa052YldKdlUzUnljeUE5SUV0bGVVTnZiV0p2TGw5emNHeHBkRk4wY2loclpYbERiMjFpYjFOMGNpd2dTMlY1UTI5dFltOHVZMjl0WW05RVpXeHBiV2x1WVhSdmNpazdYRzRnSUdOdmJuTjBJR052YldKdklDQWdJQ0FnSUNBOUlGdGRPMXh1WEc0Z0lHWnZjaUFvYkdWMElHa2dQU0F3SURzZ2FTQThJSE4xWWtOdmJXSnZVM1J5Y3k1c1pXNW5kR2c3SUdrZ0t6MGdNU2tnZTF4dUlDQWdJR052YldKdkxuQjFjMmdvUzJWNVEyOXRZbTh1WDNOd2JHbDBVM1J5S0hOMVlrTnZiV0p2VTNSeWMxdHBYU3dnUzJWNVEyOXRZbTh1YTJWNVJHVnNhVzFwYm1GMGIzSXBLVHRjYmlBZ2ZWeHVJQ0J5WlhSMWNtNGdZMjl0WW04N1hHNTlYRzVjYmt0bGVVTnZiV0p2TGw5emNHeHBkRk4wY2lBOUlHWjFibU4wYVc5dUtITjBjaXdnWkdWc2FXMXBibUYwYjNJcElIdGNiaUFnWTI5dWMzUWdjeUFnUFNCemRISTdYRzRnSUdOdmJuTjBJR1FnSUQwZ1pHVnNhVzFwYm1GMGIzSTdYRzRnSUd4bGRDQmpJQ0E5SUNjbk8xeHVJQ0JqYjI1emRDQmpZU0E5SUZ0ZE8xeHVYRzRnSUdadmNpQW9iR1YwSUdOcElEMGdNRHNnWTJrZ1BDQnpMbXhsYm1kMGFEc2dZMmtnS3owZ01Ta2dlMXh1SUNBZ0lHbG1JQ2hqYVNBK0lEQWdKaVlnYzF0amFWMGdQVDA5SUdRZ0ppWWdjMXRqYVNBdElERmRJQ0U5UFNBblhGeGNYQ2NwSUh0Y2JpQWdJQ0FnSUdOaExuQjFjMmdvWXk1MGNtbHRLQ2twTzF4dUlDQWdJQ0FnWXlBOUlDY25PMXh1SUNBZ0lDQWdZMmtnS3owZ01UdGNiaUFnSUNCOVhHNGdJQ0FnWXlBclBTQnpXMk5wWFR0Y2JpQWdmVnh1SUNCcFppQW9ZeWtnZXlCallTNXdkWE5vS0dNdWRISnBiU2dwS1RzZ2ZWeHVYRzRnSUhKbGRIVnliaUJqWVR0Y2JuMDdYRzRpTENKcGJYQnZjblFnZXlCTFpYbERiMjFpYnlCOUlHWnliMjBnSnk0dmEyVjVMV052YldKdkp6dGNibHh1WEc1bGVIQnZjblFnWTJ4aGMzTWdURzlqWVd4bElIdGNiaUFnWTI5dWMzUnlkV04wYjNJb2JtRnRaU2tnZTF4dUlDQWdJSFJvYVhNdWJHOWpZV3hsVG1GdFpTQWdJQ0FnSUNBZ0lDQTlJRzVoYldVN1hHNGdJQ0FnZEdocGN5NWhZM1JwZG1WVVlYSm5aWFJMWlhseklEMGdXMTA3WEc0Z0lDQWdkR2hwY3k1d2NtVnpjMlZrUzJWNWN5QWdJQ0FnSUNBZ0lEMGdXMTA3WEc0Z0lDQWdkR2hwY3k1ZllYQndiR2xsWkUxaFkzSnZjeUFnSUNBZ0lEMGdXMTA3WEc0Z0lDQWdkR2hwY3k1ZmEyVjVUV0Z3SUNBZ0lDQWdJQ0FnSUNBZ0lEMGdlMzA3WEc0Z0lDQWdkR2hwY3k1ZmEybHNiRXRsZVVOdlpHVnpJQ0FnSUNBZ0lEMGdXMTA3WEc0Z0lDQWdkR2hwY3k1ZmJXRmpjbTl6SUNBZ0lDQWdJQ0FnSUNBZ0lEMGdXMTA3WEc0Z0lIMWNibHh1SUNCaWFXNWtTMlY1UTI5a1pTaHJaWGxEYjJSbExDQnJaWGxPWVcxbGN5a2dlMXh1SUNBZ0lHbG1JQ2gwZVhCbGIyWWdhMlY1VG1GdFpYTWdQVDA5SUNkemRISnBibWNuS1NCN1hHNGdJQ0FnSUNCclpYbE9ZVzFsY3lBOUlGdHJaWGxPWVcxbGMxMDdYRzRnSUNBZ2ZWeHVYRzRnSUNBZ2RHaHBjeTVmYTJWNVRXRndXMnRsZVVOdlpHVmRJRDBnYTJWNVRtRnRaWE03WEc0Z0lIMDdYRzVjYmlBZ1ltbHVaRTFoWTNKdktHdGxlVU52YldKdlUzUnlMQ0JyWlhsT1lXMWxjeWtnZTF4dUlDQWdJR2xtSUNoMGVYQmxiMllnYTJWNVRtRnRaWE1nUFQwOUlDZHpkSEpwYm1jbktTQjdYRzRnSUNBZ0lDQnJaWGxPWVcxbGN5QTlJRnNnYTJWNVRtRnRaWE1nWFR0Y2JpQWdJQ0I5WEc1Y2JpQWdJQ0JzWlhRZ2FHRnVaR3hsY2lBOUlHNTFiR3c3WEc0Z0lDQWdhV1lnS0hSNWNHVnZaaUJyWlhsT1lXMWxjeUE5UFQwZ0oyWjFibU4wYVc5dUp5a2dlMXh1SUNBZ0lDQWdhR0Z1Wkd4bGNpQTlJR3RsZVU1aGJXVnpPMXh1SUNBZ0lDQWdhMlY1VG1GdFpYTWdQU0J1ZFd4c08xeHVJQ0FnSUgxY2JseHVJQ0FnSUdOdmJuTjBJRzFoWTNKdklEMGdlMXh1SUNBZ0lDQWdhMlY1UTI5dFltOGdPaUJ1WlhjZ1MyVjVRMjl0WW04b2EyVjVRMjl0WW05VGRISXBMRnh1SUNBZ0lDQWdhMlY1VG1GdFpYTWdPaUJyWlhsT1lXMWxjeXhjYmlBZ0lDQWdJR2hoYm1Sc1pYSWdJRG9nYUdGdVpHeGxjbHh1SUNBZ0lIMDdYRzVjYmlBZ0lDQjBhR2x6TGw5dFlXTnliM011Y0hWemFDaHRZV055YnlrN1hHNGdJSDA3WEc1Y2JpQWdaMlYwUzJWNVEyOWtaWE1vYTJWNVRtRnRaU2tnZTF4dUlDQWdJR052Ym5OMElHdGxlVU52WkdWeklEMGdXMTA3WEc0Z0lDQWdabTl5SUNoamIyNXpkQ0JyWlhsRGIyUmxJR2x1SUhSb2FYTXVYMnRsZVUxaGNDa2dlMXh1SUNBZ0lDQWdZMjl1YzNRZ2FXNWtaWGdnUFNCMGFHbHpMbDlyWlhsTllYQmJhMlY1UTI5a1pWMHVhVzVrWlhoUFppaHJaWGxPWVcxbEtUdGNiaUFnSUNBZ0lHbG1JQ2hwYm1SbGVDQStJQzB4S1NCN0lHdGxlVU52WkdWekxuQjFjMmdvYTJWNVEyOWtaWHd3S1RzZ2ZWeHVJQ0FnSUgxY2JpQWdJQ0J5WlhSMWNtNGdhMlY1UTI5a1pYTTdYRzRnSUgwN1hHNWNiaUFnWjJWMFMyVjVUbUZ0WlhNb2EyVjVRMjlrWlNrZ2UxeHVJQ0FnSUhKbGRIVnliaUIwYUdsekxsOXJaWGxOWVhCYmEyVjVRMjlrWlYwZ2ZId2dXMTA3WEc0Z0lIMDdYRzVjYmlBZ2MyVjBTMmxzYkV0bGVTaHJaWGxEYjJSbEtTQjdYRzRnSUNBZ2FXWWdLSFI1Y0dWdlppQnJaWGxEYjJSbElEMDlQU0FuYzNSeWFXNW5KeWtnZTF4dUlDQWdJQ0FnWTI5dWMzUWdhMlY1UTI5a1pYTWdQU0IwYUdsekxtZGxkRXRsZVVOdlpHVnpLR3RsZVVOdlpHVXBPMXh1SUNBZ0lDQWdabTl5SUNoc1pYUWdhU0E5SURBN0lHa2dQQ0JyWlhsRGIyUmxjeTVzWlc1bmRHZzdJR2tnS3owZ01Ta2dlMXh1SUNBZ0lDQWdJQ0IwYUdsekxuTmxkRXRwYkd4TFpYa29hMlY1UTI5a1pYTmJhVjBwTzF4dUlDQWdJQ0FnZlZ4dUlDQWdJQ0FnY21WMGRYSnVPMXh1SUNBZ0lIMWNibHh1SUNBZ0lIUm9hWE11WDJ0cGJHeExaWGxEYjJSbGN5NXdkWE5vS0d0bGVVTnZaR1VwTzF4dUlDQjlPMXh1WEc0Z0lIQnlaWE56UzJWNUtHdGxlVU52WkdVcElIdGNiaUFnSUNCcFppQW9kSGx3Wlc5bUlHdGxlVU52WkdVZ1BUMDlJQ2R6ZEhKcGJtY25LU0I3WEc0Z0lDQWdJQ0JqYjI1emRDQnJaWGxEYjJSbGN5QTlJSFJvYVhNdVoyVjBTMlY1UTI5a1pYTW9hMlY1UTI5a1pTazdYRzRnSUNBZ0lDQm1iM0lnS0d4bGRDQnBJRDBnTURzZ2FTQThJR3RsZVVOdlpHVnpMbXhsYm1kMGFEc2dhU0FyUFNBeEtTQjdYRzRnSUNBZ0lDQWdJSFJvYVhNdWNISmxjM05MWlhrb2EyVjVRMjlrWlhOYmFWMHBPMXh1SUNBZ0lDQWdmVnh1SUNBZ0lDQWdjbVYwZFhKdU8xeHVJQ0FnSUgxY2JseHVJQ0FnSUhSb2FYTXVZV04wYVhabFZHRnlaMlYwUzJWNWN5NXNaVzVuZEdnZ1BTQXdPMXh1SUNBZ0lHTnZibk4wSUd0bGVVNWhiV1Z6SUQwZ2RHaHBjeTVuWlhSTFpYbE9ZVzFsY3loclpYbERiMlJsS1R0Y2JpQWdJQ0JtYjNJZ0tHeGxkQ0JwSUQwZ01Ec2dhU0E4SUd0bGVVNWhiV1Z6TG14bGJtZDBhRHNnYVNBclBTQXhLU0I3WEc0Z0lDQWdJQ0IwYUdsekxtRmpkR2wyWlZSaGNtZGxkRXRsZVhNdWNIVnphQ2hyWlhsT1lXMWxjMXRwWFNrN1hHNGdJQ0FnSUNCcFppQW9kR2hwY3k1d2NtVnpjMlZrUzJWNWN5NXBibVJsZUU5bUtHdGxlVTVoYldWelcybGRLU0E5UFQwZ0xURXBJSHRjYmlBZ0lDQWdJQ0FnZEdocGN5NXdjbVZ6YzJWa1MyVjVjeTV3ZFhOb0tHdGxlVTVoYldWelcybGRLVHRjYmlBZ0lDQWdJSDFjYmlBZ0lDQjlYRzVjYmlBZ0lDQjBhR2x6TGw5aGNIQnNlVTFoWTNKdmN5Z3BPMXh1SUNCOU8xeHVYRzRnSUhKbGJHVmhjMlZMWlhrb2EyVjVRMjlrWlNrZ2UxeHVJQ0FnSUdsbUlDaDBlWEJsYjJZZ2EyVjVRMjlrWlNBOVBUMGdKM04wY21sdVp5Y3BJSHRjYmlBZ0lDQWdJR052Ym5OMElHdGxlVU52WkdWeklEMGdkR2hwY3k1blpYUkxaWGxEYjJSbGN5aHJaWGxEYjJSbEtUdGNiaUFnSUNBZ0lHWnZjaUFvYkdWMElHa2dQU0F3T3lCcElEd2dhMlY1UTI5a1pYTXViR1Z1WjNSb095QnBJQ3M5SURFcElIdGNiaUFnSUNBZ0lDQWdkR2hwY3k1eVpXeGxZWE5sUzJWNUtHdGxlVU52WkdWelcybGRLVHRjYmlBZ0lDQWdJSDFjYmx4dUlDQWdJSDBnWld4elpTQjdYRzRnSUNBZ0lDQmpiMjV6ZENCclpYbE9ZVzFsY3lBZ0lDQWdJQ0FnSUQwZ2RHaHBjeTVuWlhSTFpYbE9ZVzFsY3loclpYbERiMlJsS1R0Y2JpQWdJQ0FnSUdOdmJuTjBJR3RwYkd4TFpYbERiMlJsU1c1a1pYZ2dQU0IwYUdsekxsOXJhV3hzUzJWNVEyOWtaWE11YVc1a1pYaFBaaWhyWlhsRGIyUmxLVHRjYmx4dUlDQWdJQ0FnYVdZZ0tHdHBiR3hMWlhsRGIyUmxTVzVrWlhnZ0lUMDlJQzB4S1NCN1hHNGdJQ0FnSUNBZ0lIUm9hWE11Y0hKbGMzTmxaRXRsZVhNdWJHVnVaM1JvSUQwZ01EdGNiaUFnSUNBZ0lIMGdaV3h6WlNCN1hHNGdJQ0FnSUNBZ0lHWnZjaUFvYkdWMElHa2dQU0F3T3lCcElEd2dhMlY1VG1GdFpYTXViR1Z1WjNSb095QnBJQ3M5SURFcElIdGNiaUFnSUNBZ0lDQWdJQ0JqYjI1emRDQnBibVJsZUNBOUlIUm9hWE11Y0hKbGMzTmxaRXRsZVhNdWFXNWtaWGhQWmloclpYbE9ZVzFsYzF0cFhTazdYRzRnSUNBZ0lDQWdJQ0FnYVdZZ0tHbHVaR1Y0SUQ0Z0xURXBJSHRjYmlBZ0lDQWdJQ0FnSUNBZ0lIUm9hWE11Y0hKbGMzTmxaRXRsZVhNdWMzQnNhV05sS0dsdVpHVjRMQ0F4S1R0Y2JpQWdJQ0FnSUNBZ0lDQjlYRzRnSUNBZ0lDQWdJSDFjYmlBZ0lDQWdJSDFjYmx4dUlDQWdJQ0FnZEdocGN5NWhZM1JwZG1WVVlYSm5aWFJMWlhsekxteGxibWQwYUNBOUlEQTdYRzRnSUNBZ0lDQjBhR2x6TGw5amJHVmhjazFoWTNKdmN5Z3BPMXh1SUNBZ0lIMWNiaUFnZlR0Y2JseHVJQ0JmWVhCd2JIbE5ZV055YjNNb0tTQjdYRzRnSUNBZ1kyOXVjM1FnYldGamNtOXpJRDBnZEdocGN5NWZiV0ZqY205ekxuTnNhV05sS0RBcE8xeHVJQ0FnSUdadmNpQW9iR1YwSUdrZ1BTQXdPeUJwSUR3Z2JXRmpjbTl6TG14bGJtZDBhRHNnYVNBclBTQXhLU0I3WEc0Z0lDQWdJQ0JqYjI1emRDQnRZV055YnlBOUlHMWhZM0p2YzF0cFhUdGNiaUFnSUNBZ0lHbG1JQ2h0WVdOeWJ5NXJaWGxEYjIxaWJ5NWphR1ZqYXloMGFHbHpMbkJ5WlhOelpXUkxaWGx6S1NrZ2UxeHVJQ0FnSUNBZ0lDQnBaaUFvYldGamNtOHVhR0Z1Wkd4bGNpa2dlMXh1SUNBZ0lDQWdJQ0FnSUcxaFkzSnZMbXRsZVU1aGJXVnpJRDBnYldGamNtOHVhR0Z1Wkd4bGNpaDBhR2x6TG5CeVpYTnpaV1JMWlhsektUdGNiaUFnSUNBZ0lDQWdmVnh1SUNBZ0lDQWdJQ0JtYjNJZ0tHeGxkQ0JxSUQwZ01Ec2dhaUE4SUcxaFkzSnZMbXRsZVU1aGJXVnpMbXhsYm1kMGFEc2dhaUFyUFNBeEtTQjdYRzRnSUNBZ0lDQWdJQ0FnYVdZZ0tIUm9hWE11Y0hKbGMzTmxaRXRsZVhNdWFXNWtaWGhQWmlodFlXTnlieTVyWlhsT1lXMWxjMXRxWFNrZ1BUMDlJQzB4S1NCN1hHNGdJQ0FnSUNBZ0lDQWdJQ0IwYUdsekxuQnlaWE56WldSTFpYbHpMbkIxYzJnb2JXRmpjbTh1YTJWNVRtRnRaWE5iYWwwcE8xeHVJQ0FnSUNBZ0lDQWdJSDFjYmlBZ0lDQWdJQ0FnZlZ4dUlDQWdJQ0FnSUNCMGFHbHpMbDloY0hCc2FXVmtUV0ZqY205ekxuQjFjMmdvYldGamNtOHBPMXh1SUNBZ0lDQWdmVnh1SUNBZ0lIMWNiaUFnZlR0Y2JseHVJQ0JmWTJ4bFlYSk5ZV055YjNNb0tTQjdYRzRnSUNBZ1ptOXlJQ2hzWlhRZ2FTQTlJREE3SUdrZ1BDQjBhR2x6TGw5aGNIQnNhV1ZrVFdGamNtOXpMbXhsYm1kMGFEc2dhU0FyUFNBeEtTQjdYRzRnSUNBZ0lDQmpiMjV6ZENCdFlXTnlieUE5SUhSb2FYTXVYMkZ3Y0d4cFpXUk5ZV055YjNOYmFWMDdYRzRnSUNBZ0lDQnBaaUFvSVcxaFkzSnZMbXRsZVVOdmJXSnZMbU5vWldOcktIUm9hWE11Y0hKbGMzTmxaRXRsZVhNcEtTQjdYRzRnSUNBZ0lDQWdJR1p2Y2lBb2JHVjBJR29nUFNBd095QnFJRHdnYldGamNtOHVhMlY1VG1GdFpYTXViR1Z1WjNSb095QnFJQ3M5SURFcElIdGNiaUFnSUNBZ0lDQWdJQ0JqYjI1emRDQnBibVJsZUNBOUlIUm9hWE11Y0hKbGMzTmxaRXRsZVhNdWFXNWtaWGhQWmlodFlXTnlieTVyWlhsT1lXMWxjMXRxWFNrN1hHNGdJQ0FnSUNBZ0lDQWdhV1lnS0dsdVpHVjRJRDRnTFRFcElIdGNiaUFnSUNBZ0lDQWdJQ0FnSUhSb2FYTXVjSEpsYzNObFpFdGxlWE11YzNCc2FXTmxLR2x1WkdWNExDQXhLVHRjYmlBZ0lDQWdJQ0FnSUNCOVhHNGdJQ0FnSUNBZ0lIMWNiaUFnSUNBZ0lDQWdhV1lnS0cxaFkzSnZMbWhoYm1Sc1pYSXBJSHRjYmlBZ0lDQWdJQ0FnSUNCdFlXTnlieTVyWlhsT1lXMWxjeUE5SUc1MWJHdzdYRzRnSUNBZ0lDQWdJSDFjYmlBZ0lDQWdJQ0FnZEdocGN5NWZZWEJ3YkdsbFpFMWhZM0p2Y3k1emNHeHBZMlVvYVN3Z01TazdYRzRnSUNBZ0lDQWdJR2tnTFQwZ01UdGNiaUFnSUNBZ0lIMWNiaUFnSUNCOVhHNGdJSDFjYm4xY2JpSXNJbWx0Y0c5eWRDQjdJRXh2WTJGc1pTQjlJR1p5YjIwZ0p5NHZiRzlqWVd4bEp6dGNibWx0Y0c5eWRDQjdJRXRsZVVOdmJXSnZJSDBnWm5KdmJTQW5MaTlyWlhrdFkyOXRZbThuTzF4dVhHNWNibVY0Y0c5eWRDQmpiR0Z6Y3lCTFpYbGliMkZ5WkNCN1hHNGdJR052Ym5OMGNuVmpkRzl5S0hSaGNtZGxkRmRwYm1SdmR5d2dkR0Z5WjJWMFJXeGxiV1Z1ZEN3Z2RHRnlaMlYwVUd4aGRHWnZjbTBzSUhSaGNtZGxkRlZ6WlhKQloyVnVkQ2tnZTF4dUlDQWdJSFJvYVhNdVgyeHZZMkZzWlNBZ0lDQWdJQ0FnSUNBZ0lDQWdJRDBnYm5Wc2JEdGNiaUFnSUNCMGFHbHpMbDlqZFhKeVpXNTBRMjl1ZEdWNGRDQWdJQ0FnSUNBOUlDY25PMXh1SUNBZ0lIUm9hWE11WDJOdmJuUmxlSFJ6SUNBZ0lDQWdJQ0FnSUNBZ0lEMGdlMzA3WEc0Z0lDQWdkR2hwY3k1ZmJHbHpkR1Z1WlhKeklDQWdJQ0FnSUNBZ0lDQWdQU0JiWFR0Y2JpQWdJQ0IwYUdsekxsOWhjSEJzYVdWa1RHbHpkR1Z1WlhKeklDQWdJQ0E5SUZ0ZE8xeHVJQ0FnSUhSb2FYTXVYMnh2WTJGc1pYTWdJQ0FnSUNBZ0lDQWdJQ0FnSUQwZ2UzMDdYRzRnSUNBZ2RHaHBjeTVmZEdGeVoyVjBSV3hsYldWdWRDQWdJQ0FnSUNBZ1BTQnVkV3hzTzF4dUlDQWdJSFJvYVhNdVgzUmhjbWRsZEZkcGJtUnZkeUFnSUNBZ0lDQWdJRDBnYm5Wc2JEdGNiaUFnSUNCMGFHbHpMbDkwWVhKblpYUlFiR0YwWm05eWJTQWdJQ0FnSUNBOUlDY25PMXh1SUNBZ0lIUm9hWE11WDNSaGNtZGxkRlZ6WlhKQloyVnVkQ0FnSUNBZ0lEMGdKeWM3WEc0Z0lDQWdkR2hwY3k1ZmFYTk5iMlJsY201Q2NtOTNjMlZ5SUNBZ0lDQWdQU0JtWVd4elpUdGNiaUFnSUNCMGFHbHpMbDkwWVhKblpYUkxaWGxFYjNkdVFtbHVaR2x1WnlBOUlHNTFiR3c3WEc0Z0lDQWdkR2hwY3k1ZmRHRnlaMlYwUzJWNVZYQkNhVzVrYVc1bklDQWdQU0J1ZFd4c08xeHVJQ0FnSUhSb2FYTXVYM1JoY21kbGRGSmxjMlYwUW1sdVpHbHVaeUFnSUQwZ2JuVnNiRHRjYmlBZ0lDQjBhR2x6TGw5d1lYVnpaV1FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQTlJR1poYkhObE8xeHVYRzRnSUNBZ2RHaHBjeTVmWTI5dWRHVjRkSE11WjJ4dlltRnNJRDBnZTF4dUlDQWdJQ0FnYkdsemRHVnVaWEp6T2lCMGFHbHpMbDlzYVhOMFpXNWxjbk1zWEc0Z0lDQWdJQ0IwWVhKblpYUlhhVzVrYjNjc1hHNGdJQ0FnSUNCMFlYSm5aWFJGYkdWdFpXNTBMRnh1SUNBZ0lDQWdkR0Z5WjJWMFVHeGhkR1p2Y20wc1hHNGdJQ0FnSUNCMFlYSm5aWFJWYzJWeVFXZGxiblJjYmlBZ0lDQjlPMXh1WEc0Z0lDQWdkR2hwY3k1elpYUkRiMjUwWlhoMEtDZG5iRzlpWVd3bktUdGNiaUFnZlZ4dVhHNGdJSE5sZEV4dlkyRnNaU2hzYjJOaGJHVk9ZVzFsTENCc2IyTmhiR1ZDZFdsc1pHVnlLU0I3WEc0Z0lDQWdiR1YwSUd4dlkyRnNaU0E5SUc1MWJHdzdYRzRnSUNBZ2FXWWdLSFI1Y0dWdlppQnNiMk5oYkdWT1lXMWxJRDA5UFNBbmMzUnlhVzVuSnlrZ2UxeHVYRzRnSUNBZ0lDQnBaaUFvYkc5allXeGxRblZwYkdSbGNpa2dlMXh1SUNBZ0lDQWdJQ0JzYjJOaGJHVWdQU0J1WlhjZ1RHOWpZV3hsS0d4dlkyRnNaVTVoYldVcE8xeHVJQ0FnSUNBZ0lDQnNiMk5oYkdWQ2RXbHNaR1Z5S0d4dlkyRnNaU3dnZEdocGN5NWZkR0Z5WjJWMFVHeGhkR1p2Y20wc0lIUm9hWE11WDNSaGNtZGxkRlZ6WlhKQloyVnVkQ2s3WEc0Z0lDQWdJQ0I5SUdWc2MyVWdlMXh1SUNBZ0lDQWdJQ0JzYjJOaGJHVWdQU0IwYUdsekxsOXNiMk5oYkdWelcyeHZZMkZzWlU1aGJXVmRJSHg4SUc1MWJHdzdYRzRnSUNBZ0lDQjlYRzRnSUNBZ2ZTQmxiSE5sSUh0Y2JpQWdJQ0FnSUd4dlkyRnNaU0FnSUNBZ1BTQnNiMk5oYkdWT1lXMWxPMXh1SUNBZ0lDQWdiRzlqWVd4bFRtRnRaU0E5SUd4dlkyRnNaUzVmYkc5allXeGxUbUZ0WlR0Y2JpQWdJQ0I5WEc1Y2JpQWdJQ0IwYUdsekxsOXNiMk5oYkdVZ0lDQWdJQ0FnSUNBZ0lDQWdJRDBnYkc5allXeGxPMXh1SUNBZ0lIUm9hWE11WDJ4dlkyRnNaWE5iYkc5allXeGxUbUZ0WlYwZ1BTQnNiMk5oYkdVN1hHNGdJQ0FnYVdZZ0tHeHZZMkZzWlNrZ2UxeHVJQ0FnSUNBZ2RHaHBjeTVmYkc5allXeGxMbkJ5WlhOelpXUkxaWGx6SUQwZ2JHOWpZV3hsTG5CeVpYTnpaV1JMWlhsek8xeHVJQ0FnSUgxY2JseHVJQ0FnSUhKbGRIVnliaUIwYUdsek8xeHVJQ0I5WEc1Y2JpQWdaMlYwVEc5allXeGxLR3h2WTJGc1RtRnRaU2tnZTF4dUlDQWdJR3h2WTJGc1RtRnRaU0I4ZkNBb2JHOWpZV3hPWVcxbElEMGdkR2hwY3k1ZmJHOWpZV3hsTG14dlkyRnNaVTVoYldVcE8xeHVJQ0FnSUhKbGRIVnliaUIwYUdsekxsOXNiMk5oYkdWelcyeHZZMkZzVG1GdFpWMGdmSHdnYm5Wc2JEdGNiaUFnZlZ4dVhHNGdJR0pwYm1Rb2EyVjVRMjl0WW05VGRISXNJSEJ5WlhOelNHRnVaR3hsY2l3Z2NtVnNaV0Z6WlVoaGJtUnNaWElzSUhCeVpYWmxiblJTWlhCbFlYUkNlVVJsWm1GMWJIUXBJSHRjYmlBZ0lDQnBaaUFvYTJWNVEyOXRZbTlUZEhJZ1BUMDlJRzUxYkd3Z2ZId2dkSGx3Wlc5bUlHdGxlVU52YldKdlUzUnlJRDA5UFNBblpuVnVZM1JwYjI0bktTQjdYRzRnSUNBZ0lDQndjbVYyWlc1MFVtVndaV0YwUW5sRVpXWmhkV3gwSUQwZ2NtVnNaV0Z6WlVoaGJtUnNaWEk3WEc0Z0lDQWdJQ0J5Wld4bFlYTmxTR0Z1Wkd4bGNpQWdJQ0FnSUNBZ0lEMGdjSEpsYzNOSVlXNWtiR1Z5TzF4dUlDQWdJQ0FnY0hKbGMzTklZVzVrYkdWeUlDQWdJQ0FnSUNBZ0lDQTlJR3RsZVVOdmJXSnZVM1J5TzF4dUlDQWdJQ0FnYTJWNVEyOXRZbTlUZEhJZ0lDQWdJQ0FnSUNBZ0lDQTlJRzUxYkd3N1hHNGdJQ0FnZlZ4dVhHNGdJQ0FnYVdZZ0tGeHVJQ0FnSUNBZ2EyVjVRMjl0WW05VGRISWdKaVpjYmlBZ0lDQWdJSFI1Y0dWdlppQnJaWGxEYjIxaWIxTjBjaUE5UFQwZ0oyOWlhbVZqZENjZ0ppWmNiaUFnSUNBZ0lIUjVjR1Z2WmlCclpYbERiMjFpYjFOMGNpNXNaVzVuZEdnZ1BUMDlJQ2R1ZFcxaVpYSW5YRzRnSUNBZ0tTQjdYRzRnSUNBZ0lDQm1iM0lnS0d4bGRDQnBJRDBnTURzZ2FTQThJR3RsZVVOdmJXSnZVM1J5TG14bGJtZDBhRHNnYVNBclBTQXhLU0I3WEc0Z0lDQWdJQ0FnSUhSb2FYTXVZbWx1WkNoclpYbERiMjFpYjFOMGNsdHBYU3dnY0hKbGMzTklZVzVrYkdWeUxDQnlaV3hsWVhObFNHRnVaR3hsY2lrN1hHNGdJQ0FnSUNCOVhHNGdJQ0FnSUNCeVpYUjFjbTRnZEdocGN6dGNiaUFnSUNCOVhHNWNiaUFnSUNCMGFHbHpMbDlzYVhOMFpXNWxjbk11Y0hWemFDaDdYRzRnSUNBZ0lDQnJaWGxEYjIxaWJ5QWdJQ0FnSUNBZ0lDQWdJQ0FnT2lCclpYbERiMjFpYjFOMGNpQS9JRzVsZHlCTFpYbERiMjFpYnloclpYbERiMjFpYjFOMGNpa2dPaUJ1ZFd4c0xGeHVJQ0FnSUNBZ2NISmxjM05JWVc1a2JHVnlJQ0FnSUNBZ0lDQWdJRG9nY0hKbGMzTklZVzVrYkdWeUlDQWdJQ0FnSUNBZ0lDQjhmQ0J1ZFd4c0xGeHVJQ0FnSUNBZ2NtVnNaV0Z6WlVoaGJtUnNaWElnSUNBZ0lDQWdJRG9nY21Wc1pXRnpaVWhoYm1Sc1pYSWdJQ0FnSUNBZ0lDQjhmQ0J1ZFd4c0xGeHVJQ0FnSUNBZ2NISmxkbVZ1ZEZKbGNHVmhkQ0FnSUNBZ0lDQWdJRG9nWm1Gc2MyVXNYRzRnSUNBZ0lDQndjbVYyWlc1MFVtVndaV0YwUW5sRVpXWmhkV3gwT2lCd2NtVjJaVzUwVW1Wd1pXRjBRbmxFWldaaGRXeDBJSHg4SUdaaGJITmxMRnh1SUNBZ0lDQWdaWGhsWTNWMGFXNW5TR0Z1Wkd4bGNpQWdJQ0FnSURvZ1ptRnNjMlZjYmlBZ0lDQjlLVHRjYmx4dUlDQWdJSEpsZEhWeWJpQjBhR2x6TzF4dUlDQjlYRzVjYmlBZ1lXUmtUR2x6ZEdWdVpYSW9hMlY1UTI5dFltOVRkSElzSUhCeVpYTnpTR0Z1Wkd4bGNpd2djbVZzWldGelpVaGhibVJzWlhJc0lIQnlaWFpsYm5SU1pYQmxZWFJDZVVSbFptRjFiSFFwSUh0Y2JpQWdJQ0J5WlhSMWNtNGdkR2hwY3k1aWFXNWtLR3RsZVVOdmJXSnZVM1J5TENCd2NtVnpjMGhoYm1Sc1pYSXNJSEpsYkdWaGMyVklZVzVrYkdWeUxDQndjbVYyWlc1MFVtVndaV0YwUW5sRVpXWmhkV3gwS1R0Y2JpQWdmVnh1WEc0Z0lHOXVLR3RsZVVOdmJXSnZVM1J5TENCd2NtVnpjMGhoYm1Sc1pYSXNJSEpsYkdWaGMyVklZVzVrYkdWeUxDQndjbVYyWlc1MFVtVndaV0YwUW5sRVpXWmhkV3gwS1NCN1hHNGdJQ0FnY21WMGRYSnVJSFJvYVhNdVltbHVaQ2hyWlhsRGIyMWliMU4wY2l3Z2NISmxjM05JWVc1a2JHVnlMQ0J5Wld4bFlYTmxTR0Z1Wkd4bGNpd2djSEpsZG1WdWRGSmxjR1ZoZEVKNVJHVm1ZWFZzZENrN1hHNGdJSDFjYmx4dUlDQmlhVzVrVUhKbGMzTW9hMlY1UTI5dFltOVRkSElzSUhCeVpYTnpTR0Z1Wkd4bGNpd2djSEpsZG1WdWRGSmxjR1ZoZEVKNVJHVm1ZWFZzZENrZ2UxeHVJQ0FnSUhKbGRIVnliaUIwYUdsekxtSnBibVFvYTJWNVEyOXRZbTlUZEhJc0lIQnlaWE56U0dGdVpHeGxjaXdnYm5Wc2JDd2djSEpsZG1WdWRGSmxjR1ZoZEVKNVJHVm1ZWFZzZENrN1hHNGdJSDFjYmx4dUlDQmlhVzVrVW1Wc1pXRnpaU2hyWlhsRGIyMWliMU4wY2l3Z2NtVnNaV0Z6WlVoaGJtUnNaWElwSUh0Y2JpQWdJQ0J5WlhSMWNtNGdkR2hwY3k1aWFXNWtLR3RsZVVOdmJXSnZVM1J5TENCdWRXeHNMQ0J5Wld4bFlYTmxTR0Z1Wkd4bGNpd2djSEpsZG1WdWRGSmxjR1ZoZEVKNVJHVm1ZWFZzZENrN1hHNGdJSDFjYmx4dUlDQjFibUpwYm1Rb2EyVjVRMjl0WW05VGRISXNJSEJ5WlhOelNHRnVaR3hsY2l3Z2NtVnNaV0Z6WlVoaGJtUnNaWElwSUh0Y2JpQWdJQ0JwWmlBb2EyVjVRMjl0WW05VGRISWdQVDA5SUc1MWJHd2dmSHdnZEhsd1pXOW1JR3RsZVVOdmJXSnZVM1J5SUQwOVBTQW5ablZ1WTNScGIyNG5LU0I3WEc0Z0lDQWdJQ0J5Wld4bFlYTmxTR0Z1Wkd4bGNpQTlJSEJ5WlhOelNHRnVaR3hsY2p0Y2JpQWdJQ0FnSUhCeVpYTnpTR0Z1Wkd4bGNpQWdJRDBnYTJWNVEyOXRZbTlUZEhJN1hHNGdJQ0FnSUNCclpYbERiMjFpYjFOMGNpQTlJRzUxYkd3N1hHNGdJQ0FnZlZ4dVhHNGdJQ0FnYVdZZ0tGeHVJQ0FnSUNBZ2EyVjVRMjl0WW05VGRISWdKaVpjYmlBZ0lDQWdJSFI1Y0dWdlppQnJaWGxEYjIxaWIxTjBjaUE5UFQwZ0oyOWlhbVZqZENjZ0ppWmNiaUFnSUNBZ0lIUjVjR1Z2WmlCclpYbERiMjFpYjFOMGNpNXNaVzVuZEdnZ1BUMDlJQ2R1ZFcxaVpYSW5YRzRnSUNBZ0tTQjdYRzRnSUNBZ0lDQm1iM0lnS0d4bGRDQnBJRDBnTURzZ2FTQThJR3RsZVVOdmJXSnZVM1J5TG14bGJtZDBhRHNnYVNBclBTQXhLU0I3WEc0Z0lDQWdJQ0FnSUhSb2FYTXVkVzVpYVc1a0tHdGxlVU52YldKdlUzUnlXMmxkTENCd2NtVnpjMGhoYm1Sc1pYSXNJSEpsYkdWaGMyVklZVzVrYkdWeUtUdGNiaUFnSUNBZ0lIMWNiaUFnSUNBZ0lISmxkSFZ5YmlCMGFHbHpPMXh1SUNBZ0lIMWNibHh1SUNBZ0lHWnZjaUFvYkdWMElHa2dQU0F3T3lCcElEd2dkR2hwY3k1ZmJHbHpkR1Z1WlhKekxteGxibWQwYURzZ2FTQXJQU0F4S1NCN1hHNGdJQ0FnSUNCamIyNXpkQ0JzYVhOMFpXNWxjaUE5SUhSb2FYTXVYMnhwYzNSbGJtVnljMXRwWFR0Y2JseHVJQ0FnSUNBZ1kyOXVjM1FnWTI5dFltOU5ZWFJqYUdWeklDQWdJQ0FnSUNBZ0lEMGdJV3RsZVVOdmJXSnZVM1J5SUNZbUlDRnNhWE4wWlc1bGNpNXJaWGxEYjIxaWJ5QjhmRnh1SUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJR3hwYzNSbGJtVnlMbXRsZVVOdmJXSnZJQ1ltSUd4cGMzUmxibVZ5TG10bGVVTnZiV0p2TG1selJYRjFZV3dvYTJWNVEyOXRZbTlUZEhJcE8xeHVJQ0FnSUNBZ1kyOXVjM1FnY0hKbGMzTklZVzVrYkdWeVRXRjBZMmhsY3lBZ0lEMGdJWEJ5WlhOelNHRnVaR3hsY2lBbUppQWhjbVZzWldGelpVaGhibVJzWlhJZ2ZIeGNiaUFnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWhjSEpsYzNOSVlXNWtiR1Z5SUNZbUlDRnNhWE4wWlc1bGNpNXdjbVZ6YzBoaGJtUnNaWElnZkh4Y2JpQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNCd2NtVnpjMGhoYm1Sc1pYSWdQVDA5SUd4cGMzUmxibVZ5TG5CeVpYTnpTR0Z1Wkd4bGNqdGNiaUFnSUNBZ0lHTnZibk4wSUhKbGJHVmhjMlZJWVc1a2JHVnlUV0YwWTJobGN5QTlJQ0Z3Y21WemMwaGhibVJzWlhJZ0ppWWdJWEpsYkdWaGMyVklZVzVrYkdWeUlIeDhYRzRnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJWEpsYkdWaGMyVklZVzVrYkdWeUlDWW1JQ0ZzYVhOMFpXNWxjaTV5Wld4bFlYTmxTR0Z1Wkd4bGNpQjhmRnh1SUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJSEpsYkdWaGMyVklZVzVrYkdWeUlEMDlQU0JzYVhOMFpXNWxjaTV5Wld4bFlYTmxTR0Z1Wkd4bGNqdGNibHh1SUNBZ0lDQWdhV1lnS0dOdmJXSnZUV0YwWTJobGN5QW1KaUJ3Y21WemMwaGhibVJzWlhKTllYUmphR1Z6SUNZbUlISmxiR1ZoYzJWSVlXNWtiR1Z5VFdGMFkyaGxjeWtnZTF4dUlDQWdJQ0FnSUNCMGFHbHpMbDlzYVhOMFpXNWxjbk11YzNCc2FXTmxLR2tzSURFcE8xeHVJQ0FnSUNBZ0lDQnBJQzA5SURFN1hHNGdJQ0FnSUNCOVhHNGdJQ0FnZlZ4dVhHNGdJQ0FnY21WMGRYSnVJSFJvYVhNN1hHNGdJSDFjYmx4dUlDQnlaVzF2ZG1WTWFYTjBaVzVsY2loclpYbERiMjFpYjFOMGNpd2djSEpsYzNOSVlXNWtiR1Z5TENCeVpXeGxZWE5sU0dGdVpHeGxjaWtnZTF4dUlDQWdJSEpsZEhWeWJpQjBhR2x6TG5WdVltbHVaQ2hyWlhsRGIyMWliMU4wY2l3Z2NISmxjM05JWVc1a2JHVnlMQ0J5Wld4bFlYTmxTR0Z1Wkd4bGNpazdYRzRnSUgxY2JseHVJQ0J2Wm1Zb2EyVjVRMjl0WW05VGRISXNJSEJ5WlhOelNHRnVaR3hsY2l3Z2NtVnNaV0Z6WlVoaGJtUnNaWElwSUh0Y2JpQWdJQ0J5WlhSMWNtNGdkR2hwY3k1MWJtSnBibVFvYTJWNVEyOXRZbTlUZEhJc0lIQnlaWE56U0dGdVpHeGxjaXdnY21Wc1pXRnpaVWhoYm1Sc1pYSXBPMXh1SUNCOVhHNWNiaUFnYzJWMFEyOXVkR1Y0ZENoamIyNTBaWGgwVG1GdFpTa2dlMXh1SUNBZ0lHbG1LSFJvYVhNdVgyeHZZMkZzWlNrZ2V5QjBhR2x6TG5KbGJHVmhjMlZCYkd4TFpYbHpLQ2s3SUgxY2JseHVJQ0FnSUdsbUlDZ2hkR2hwY3k1ZlkyOXVkR1Y0ZEhOYlkyOXVkR1Y0ZEU1aGJXVmRLU0I3WEc0Z0lDQWdJQ0JqYjI1emRDQm5iRzlpWVd4RGIyNTBaWGgwSUQwZ2RHaHBjeTVmWTI5dWRHVjRkSE11WjJ4dlltRnNPMXh1SUNBZ0lDQWdkR2hwY3k1ZlkyOXVkR1Y0ZEhOYlkyOXVkR1Y0ZEU1aGJXVmRJRDBnZTF4dUlDQWdJQ0FnSUNCc2FYTjBaVzVsY25NZ0lDQWdJQ0E2SUZ0ZExGeHVJQ0FnSUNBZ0lDQjBZWEpuWlhSWGFXNWtiM2NnSUNBNklHZHNiMkpoYkVOdmJuUmxlSFF1ZEdGeVoyVjBWMmx1Wkc5M0xGeHVJQ0FnSUNBZ0lDQjBZWEpuWlhSRmJHVnRaVzUwSUNBNklHZHNiMkpoYkVOdmJuUmxlSFF1ZEdGeVoyVjBSV3hsYldWdWRDeGNiaUFnSUNBZ0lDQWdkR0Z5WjJWMFVHeGhkR1p2Y20wZ09pQm5iRzlpWVd4RGIyNTBaWGgwTG5SaGNtZGxkRkJzWVhSbWIzSnRMRnh1SUNBZ0lDQWdJQ0IwWVhKblpYUlZjMlZ5UVdkbGJuUTZJR2RzYjJKaGJFTnZiblJsZUhRdWRHRnlaMlYwVlhObGNrRm5aVzUwWEc0Z0lDQWdJQ0I5TzF4dUlDQWdJSDFjYmx4dUlDQWdJR052Ym5OMElHTnZiblJsZUhRZ0lDQWdJQ0FnSUQwZ2RHaHBjeTVmWTI5dWRHVjRkSE5iWTI5dWRHVjRkRTVoYldWZE8xeHVJQ0FnSUhSb2FYTXVYMk4xY25KbGJuUkRiMjUwWlhoMElEMGdZMjl1ZEdWNGRFNWhiV1U3WEc0Z0lDQWdkR2hwY3k1ZmJHbHpkR1Z1WlhKeklDQWdJQ0FnUFNCamIyNTBaWGgwTG14cGMzUmxibVZ5Y3p0Y2JseHVJQ0FnSUhSb2FYTXVjM1J2Y0NncE8xeHVJQ0FnSUhSb2FYTXVkMkYwWTJnb1hHNGdJQ0FnSUNCamIyNTBaWGgwTG5SaGNtZGxkRmRwYm1SdmR5eGNiaUFnSUNBZ0lHTnZiblJsZUhRdWRHRnlaMlYwUld4bGJXVnVkQ3hjYmlBZ0lDQWdJR052Ym5SbGVIUXVkR0Z5WjJWMFVHeGhkR1p2Y20wc1hHNGdJQ0FnSUNCamIyNTBaWGgwTG5SaGNtZGxkRlZ6WlhKQloyVnVkRnh1SUNBZ0lDazdYRzVjYmlBZ0lDQnlaWFIxY200Z2RHaHBjenRjYmlBZ2ZWeHVYRzRnSUdkbGRFTnZiblJsZUhRb0tTQjdYRzRnSUNBZ2NtVjBkWEp1SUhSb2FYTXVYMk4xY25KbGJuUkRiMjUwWlhoME8xeHVJQ0I5WEc1Y2JpQWdkMmwwYUVOdmJuUmxlSFFvWTI5dWRHVjRkRTVoYldVc0lHTmhiR3hpWVdOcktTQjdYRzRnSUNBZ1kyOXVjM1FnY0hKbGRtbHZkWE5EYjI1MFpYaDBUbUZ0WlNBOUlIUm9hWE11WjJWMFEyOXVkR1Y0ZENncE8xeHVJQ0FnSUhSb2FYTXVjMlYwUTI5dWRHVjRkQ2hqYjI1MFpYaDBUbUZ0WlNrN1hHNWNiaUFnSUNCallXeHNZbUZqYXlncE8xeHVYRzRnSUNBZ2RHaHBjeTV6WlhSRGIyNTBaWGgwS0hCeVpYWnBiM1Z6UTI5dWRHVjRkRTVoYldVcE8xeHVYRzRnSUNBZ2NtVjBkWEp1SUhSb2FYTTdYRzRnSUgxY2JseHVJQ0IzWVhSamFDaDBZWEpuWlhSWGFXNWtiM2NzSUhSaGNtZGxkRVZzWlcxbGJuUXNJSFJoY21kbGRGQnNZWFJtYjNKdExDQjBZWEpuWlhSVmMyVnlRV2RsYm5RcElIdGNiaUFnSUNCMGFHbHpMbk4wYjNBb0tUdGNibHh1SUNBZ0lHTnZibk4wSUhkcGJpQTlJSFI1Y0dWdlppQm5iRzlpWVd4VWFHbHpJQ0U5UFNBbmRXNWtaV1pwYm1Wa0p5QS9JR2RzYjJKaGJGUm9hWE1nT2x4dUlDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUhSNWNHVnZaaUJuYkc5aVlXd2dJVDA5SUNkMWJtUmxabWx1WldRbklEOGdaMnh2WW1Gc0lEcGNiaUFnSUNBZ0lDQWdJQ0FnSUNBZ0lDQjBlWEJsYjJZZ2QybHVaRzkzSUNFOVBTQW5kVzVrWldacGJtVmtKeUEvSUhkcGJtUnZkeUE2WEc0Z0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnZTMwN1hHNWNiaUFnSUNCcFppQW9JWFJoY21kbGRGZHBibVJ2ZHlrZ2UxeHVJQ0FnSUNBZ2FXWWdLQ0YzYVc0dVlXUmtSWFpsYm5STWFYTjBaVzVsY2lBbUppQWhkMmx1TG1GMGRHRmphRVYyWlc1MEtTQjdYRzRnSUNBZ0lDQWdJQzh2SUZSb2FYTWdkMkZ6SUdGa1pHVmtJSE52SUhkb1pXNGdkWE5wYm1jZ2RHaHBibWR6SUd4cGEyVWdTbE5FVDAwZ2QyRjBZMmdnWTJGdUlHSmxJSFZ6WldRZ2RHOGdZMjl1Wm1sbmRYSmxJSGRoZEdOb1hHNGdJQ0FnSUNBZ0lDOHZJR1p2Y2lCMGFHVWdaMnh2WW1Gc0lHNWhiV1Z6Y0dGalpTQnRZVzUxWVd4c2VTNWNiaUFnSUNBZ0lDQWdhV1lnS0hSb2FYTXVYMk4xY25KbGJuUkRiMjUwWlhoMElEMDlQU0FuWjJ4dlltRnNKeWtnZTF4dUlDQWdJQ0FnSUNBZ0lISmxkSFZ5Ymx4dUlDQWdJQ0FnSUNCOVhHNGdJQ0FnSUNBZ0lIUm9jbTkzSUc1bGR5QkZjbkp2Y2lnblEyRnVibTkwSUdacGJtUWdkMmx1Wkc5M0lHWjFibU4wYVc5dWN5QmhaR1JGZG1WdWRFeHBjM1JsYm1WeUlHOXlJR0YwZEdGamFFVjJaVzUwTGljcE8xeHVJQ0FnSUNBZ2ZWeHVJQ0FnSUNBZ2RHRnlaMlYwVjJsdVpHOTNJRDBnZDJsdU8xeHVJQ0FnSUgxY2JseHVJQ0FnSUM4dklFaGhibVJzWlNCbGJHVnRaVzUwSUdKcGJtUnBibWR6SUhkb1pYSmxJR0VnZEdGeVoyVjBJSGRwYm1SdmR5QnBjeUJ1YjNRZ2NHRnpjMlZrWEc0Z0lDQWdhV1lnS0hSNWNHVnZaaUIwWVhKblpYUlhhVzVrYjNjdWJtOWtaVlI1Y0dVZ1BUMDlJQ2R1ZFcxaVpYSW5LU0I3WEc0Z0lDQWdJQ0IwWVhKblpYUlZjMlZ5UVdkbGJuUWdQU0IwWVhKblpYUlFiR0YwWm05eWJUdGNiaUFnSUNBZ0lIUmhjbWRsZEZCc1lYUm1iM0p0SUNBOUlIUmhjbWRsZEVWc1pXMWxiblE3WEc0Z0lDQWdJQ0IwWVhKblpYUkZiR1Z0Wlc1MElDQWdQU0IwWVhKblpYUlhhVzVrYjNjN1hHNGdJQ0FnSUNCMFlYSm5aWFJYYVc1a2IzY2dJQ0FnUFNCM2FXNDdYRzRnSUNBZ2ZWeHVYRzRnSUNBZ2FXWWdLQ0YwWVhKblpYUlhhVzVrYjNjdVlXUmtSWFpsYm5STWFYTjBaVzVsY2lBbUppQWhkR0Z5WjJWMFYybHVaRzkzTG1GMGRHRmphRVYyWlc1MEtTQjdYRzRnSUNBZ0lDQjBhSEp2ZHlCdVpYY2dSWEp5YjNJb0owTmhibTV2ZENCbWFXNWtJR0ZrWkVWMlpXNTBUR2x6ZEdWdVpYSWdiM0lnWVhSMFlXTm9SWFpsYm5RZ2JXVjBhRzlrY3lCdmJpQjBZWEpuWlhSWGFXNWtiM2N1SnlrN1hHNGdJQ0FnZlZ4dVhHNGdJQ0FnZEdocGN5NWZhWE5OYjJSbGNtNUNjbTkzYzJWeUlEMGdJU0YwWVhKblpYUlhhVzVrYjNjdVlXUmtSWFpsYm5STWFYTjBaVzVsY2p0Y2JseHVJQ0FnSUdOdmJuTjBJSFZ6WlhKQloyVnVkQ0E5SUhSaGNtZGxkRmRwYm1SdmR5NXVZWFpwWjJGMGIzSWdKaVlnZEdGeVoyVjBWMmx1Wkc5M0xtNWhkbWxuWVhSdmNpNTFjMlZ5UVdkbGJuUWdmSHdnSnljN1hHNGdJQ0FnWTI5dWMzUWdjR3hoZEdadmNtMGdJRDBnZEdGeVoyVjBWMmx1Wkc5M0xtNWhkbWxuWVhSdmNpQW1KaUIwWVhKblpYUlhhVzVrYjNjdWJtRjJhV2RoZEc5eUxuQnNZWFJtYjNKdElDQjhmQ0FuSnp0Y2JseHVJQ0FnSUhSaGNtZGxkRVZzWlcxbGJuUWdJQ0FtSmlCMFlYSm5aWFJGYkdWdFpXNTBJQ0FnSVQwOUlHNTFiR3dnZkh3Z0tIUmhjbWRsZEVWc1pXMWxiblFnSUNBOUlIUmhjbWRsZEZkcGJtUnZkeTVrYjJOMWJXVnVkQ2s3WEc0Z0lDQWdkR0Z5WjJWMFVHeGhkR1p2Y20wZ0lDWW1JSFJoY21kbGRGQnNZWFJtYjNKdElDQWhQVDBnYm5Wc2JDQjhmQ0FvZEdGeVoyVjBVR3hoZEdadmNtMGdJRDBnY0d4aGRHWnZjbTBwTzF4dUlDQWdJSFJoY21kbGRGVnpaWEpCWjJWdWRDQW1KaUIwWVhKblpYUlZjMlZ5UVdkbGJuUWdJVDA5SUc1MWJHd2dmSHdnS0hSaGNtZGxkRlZ6WlhKQloyVnVkQ0E5SUhWelpYSkJaMlZ1ZENrN1hHNWNiaUFnSUNCMGFHbHpMbDkwWVhKblpYUkxaWGxFYjNkdVFtbHVaR2x1WnlBOUlDaGxkbVZ1ZENrZ1BUNGdlMXh1SUNBZ0lDQWdkR2hwY3k1d2NtVnpjMHRsZVNobGRtVnVkQzVyWlhsRGIyUmxMQ0JsZG1WdWRDazdYRzRnSUNBZ0lDQjBhR2x6TGw5b1lXNWtiR1ZEYjIxdFlXNWtRblZuS0dWMlpXNTBMQ0J3YkdGMFptOXliU2s3WEc0Z0lDQWdmVHRjYmlBZ0lDQjBhR2x6TGw5MFlYSm5aWFJMWlhsVmNFSnBibVJwYm1jZ1BTQW9aWFpsYm5RcElEMCtJSHRjYmlBZ0lDQWdJSFJvYVhNdWNtVnNaV0Z6WlV0bGVTaGxkbVZ1ZEM1clpYbERiMlJsTENCbGRtVnVkQ2s3WEc0Z0lDQWdmVHRjYmlBZ0lDQjBhR2x6TGw5MFlYSm5aWFJTWlhObGRFSnBibVJwYm1jZ1BTQW9aWFpsYm5RcElEMCtJSHRjYmlBZ0lDQWdJSFJvYVhNdWNtVnNaV0Z6WlVGc2JFdGxlWE1vWlhabGJuUXBPMXh1SUNBZ0lIMDdYRzVjYmlBZ0lDQjBhR2x6TGw5aWFXNWtSWFpsYm5Rb2RHRnlaMlYwUld4bGJXVnVkQ3dnSjJ0bGVXUnZkMjRuTENCMGFHbHpMbDkwWVhKblpYUkxaWGxFYjNkdVFtbHVaR2x1WnlrN1hHNGdJQ0FnZEdocGN5NWZZbWx1WkVWMlpXNTBLSFJoY21kbGRFVnNaVzFsYm5Rc0lDZHJaWGwxY0Njc0lDQWdkR2hwY3k1ZmRHRnlaMlYwUzJWNVZYQkNhVzVrYVc1bktUdGNiaUFnSUNCMGFHbHpMbDlpYVc1a1JYWmxiblFvZEdGeVoyVjBWMmx1Wkc5M0xDQWdKMlp2WTNWekp5d2dJQ0IwYUdsekxsOTBZWEpuWlhSU1pYTmxkRUpwYm1ScGJtY3BPMXh1SUNBZ0lIUm9hWE11WDJKcGJtUkZkbVZ1ZENoMFlYSm5aWFJYYVc1a2IzY3NJQ0FuWW14MWNpY3NJQ0FnSUhSb2FYTXVYM1JoY21kbGRGSmxjMlYwUW1sdVpHbHVaeWs3WEc1Y2JpQWdJQ0IwYUdsekxsOTBZWEpuWlhSRmJHVnRaVzUwSUNBZ1BTQjBZWEpuWlhSRmJHVnRaVzUwTzF4dUlDQWdJSFJvYVhNdVgzUmhjbWRsZEZkcGJtUnZkeUFnSUNBOUlIUmhjbWRsZEZkcGJtUnZkenRjYmlBZ0lDQjBhR2x6TGw5MFlYSm5aWFJRYkdGMFptOXliU0FnUFNCMFlYSm5aWFJRYkdGMFptOXliVHRjYmlBZ0lDQjBhR2x6TGw5MFlYSm5aWFJWYzJWeVFXZGxiblFnUFNCMFlYSm5aWFJWYzJWeVFXZGxiblE3WEc1Y2JpQWdJQ0JqYjI1emRDQmpkWEp5Wlc1MFEyOXVkR1Y0ZENBZ0lDQWdJQ0FnSUNBZ1BTQjBhR2x6TGw5amIyNTBaWGgwYzF0MGFHbHpMbDlqZFhKeVpXNTBRMjl1ZEdWNGRGMDdYRzRnSUNBZ1kzVnljbVZ1ZEVOdmJuUmxlSFF1ZEdGeVoyVjBWMmx1Wkc5M0lDQWdJRDBnZEdocGN5NWZkR0Z5WjJWMFYybHVaRzkzTzF4dUlDQWdJR04xY25KbGJuUkRiMjUwWlhoMExuUmhjbWRsZEVWc1pXMWxiblFnSUNBOUlIUm9hWE11WDNSaGNtZGxkRVZzWlcxbGJuUTdYRzRnSUNBZ1kzVnljbVZ1ZEVOdmJuUmxlSFF1ZEdGeVoyVjBVR3hoZEdadmNtMGdJRDBnZEdocGN5NWZkR0Z5WjJWMFVHeGhkR1p2Y20wN1hHNGdJQ0FnWTNWeWNtVnVkRU52Ym5SbGVIUXVkR0Z5WjJWMFZYTmxja0ZuWlc1MElEMGdkR2hwY3k1ZmRHRnlaMlYwVlhObGNrRm5aVzUwTzF4dVhHNGdJQ0FnY21WMGRYSnVJSFJvYVhNN1hHNGdJSDFjYmx4dUlDQnpkRzl3S0NrZ2UxeHVJQ0FnSUdsbUlDZ2hkR2hwY3k1ZmRHRnlaMlYwUld4bGJXVnVkQ0I4ZkNBaGRHaHBjeTVmZEdGeVoyVjBWMmx1Wkc5M0tTQjdJSEpsZEhWeWJqc2dmVnh1WEc0Z0lDQWdkR2hwY3k1ZmRXNWlhVzVrUlhabGJuUW9kR2hwY3k1ZmRHRnlaMlYwUld4bGJXVnVkQ3dnSjJ0bGVXUnZkMjRuTENCMGFHbHpMbDkwWVhKblpYUkxaWGxFYjNkdVFtbHVaR2x1WnlrN1hHNGdJQ0FnZEdocGN5NWZkVzVpYVc1a1JYWmxiblFvZEdocGN5NWZkR0Z5WjJWMFJXeGxiV1Z1ZEN3Z0oydGxlWFZ3Snl3Z0lDQjBhR2x6TGw5MFlYSm5aWFJMWlhsVmNFSnBibVJwYm1jcE8xeHVJQ0FnSUhSb2FYTXVYM1Z1WW1sdVpFVjJaVzUwS0hSb2FYTXVYM1JoY21kbGRGZHBibVJ2ZHl3Z0lDZG1iMk4xY3ljc0lDQWdkR2hwY3k1ZmRHRnlaMlYwVW1WelpYUkNhVzVrYVc1bktUdGNiaUFnSUNCMGFHbHpMbDkxYm1KcGJtUkZkbVZ1ZENoMGFHbHpMbDkwWVhKblpYUlhhVzVrYjNjc0lDQW5ZbXgxY2ljc0lDQWdJSFJvYVhNdVgzUmhjbWRsZEZKbGMyVjBRbWx1WkdsdVp5azdYRzVjYmlBZ0lDQjBhR2x6TGw5MFlYSm5aWFJYYVc1a2IzY2dJRDBnYm5Wc2JEdGNiaUFnSUNCMGFHbHpMbDkwWVhKblpYUkZiR1Z0Wlc1MElEMGdiblZzYkR0Y2JseHVJQ0FnSUhKbGRIVnliaUIwYUdsek8xeHVJQ0I5WEc1Y2JpQWdjSEpsYzNOTFpYa29hMlY1UTI5a1pTd2daWFpsYm5RcElIdGNiaUFnSUNCcFppQW9kR2hwY3k1ZmNHRjFjMlZrS1NCN0lISmxkSFZ5YmlCMGFHbHpPeUI5WEc0Z0lDQWdhV1lnS0NGMGFHbHpMbDlzYjJOaGJHVXBJSHNnZEdoeWIzY2dibVYzSUVWeWNtOXlLQ2RNYjJOaGJHVWdibTkwSUhObGRDY3BPeUI5WEc1Y2JpQWdJQ0IwYUdsekxsOXNiMk5oYkdVdWNISmxjM05MWlhrb2EyVjVRMjlrWlNrN1hHNGdJQ0FnZEdocGN5NWZZWEJ3YkhsQ2FXNWthVzVuY3lobGRtVnVkQ2s3WEc1Y2JpQWdJQ0J5WlhSMWNtNGdkR2hwY3p0Y2JpQWdmVnh1WEc0Z0lISmxiR1ZoYzJWTFpYa29hMlY1UTI5a1pTd2daWFpsYm5RcElIdGNiaUFnSUNCcFppQW9kR2hwY3k1ZmNHRjFjMlZrS1NCN0lISmxkSFZ5YmlCMGFHbHpPeUI5WEc0Z0lDQWdhV1lnS0NGMGFHbHpMbDlzYjJOaGJHVXBJSHNnZEdoeWIzY2dibVYzSUVWeWNtOXlLQ2RNYjJOaGJHVWdibTkwSUhObGRDY3BPeUI5WEc1Y2JpQWdJQ0IwYUdsekxsOXNiMk5oYkdVdWNtVnNaV0Z6WlV0bGVTaHJaWGxEYjJSbEtUdGNiaUFnSUNCMGFHbHpMbDlqYkdWaGNrSnBibVJwYm1kektHVjJaVzUwS1R0Y2JseHVJQ0FnSUhKbGRIVnliaUIwYUdsek8xeHVJQ0I5WEc1Y2JpQWdjbVZzWldGelpVRnNiRXRsZVhNb1pYWmxiblFwSUh0Y2JpQWdJQ0JwWmlBb2RHaHBjeTVmY0dGMWMyVmtLU0I3SUhKbGRIVnliaUIwYUdsek95QjlYRzRnSUNBZ2FXWWdLQ0YwYUdsekxsOXNiMk5oYkdVcElIc2dkR2h5YjNjZ2JtVjNJRVZ5Y205eUtDZE1iMk5oYkdVZ2JtOTBJSE5sZENjcE95QjlYRzVjYmlBZ0lDQjBhR2x6TGw5c2IyTmhiR1V1Y0hKbGMzTmxaRXRsZVhNdWJHVnVaM1JvSUQwZ01EdGNiaUFnSUNCMGFHbHpMbDlqYkdWaGNrSnBibVJwYm1kektHVjJaVzUwS1R0Y2JseHVJQ0FnSUhKbGRIVnliaUIwYUdsek8xeHVJQ0I5WEc1Y2JpQWdjR0YxYzJVb0tTQjdYRzRnSUNBZ2FXWWdLSFJvYVhNdVgzQmhkWE5sWkNrZ2V5QnlaWFIxY200Z2RHaHBjenNnZlZ4dUlDQWdJR2xtSUNoMGFHbHpMbDlzYjJOaGJHVXBJSHNnZEdocGN5NXlaV3hsWVhObFFXeHNTMlY1Y3lncE95QjlYRzRnSUNBZ2RHaHBjeTVmY0dGMWMyVmtJRDBnZEhKMVpUdGNibHh1SUNBZ0lISmxkSFZ5YmlCMGFHbHpPMXh1SUNCOVhHNWNiaUFnY21WemRXMWxLQ2tnZTF4dUlDQWdJSFJvYVhNdVgzQmhkWE5sWkNBOUlHWmhiSE5sTzF4dVhHNGdJQ0FnY21WMGRYSnVJSFJvYVhNN1hHNGdJSDFjYmx4dUlDQnlaWE5sZENncElIdGNiaUFnSUNCMGFHbHpMbkpsYkdWaGMyVkJiR3hMWlhsektDazdYRzRnSUNBZ2RHaHBjeTVmYkdsemRHVnVaWEp6TG14bGJtZDBhQ0E5SURBN1hHNWNiaUFnSUNCeVpYUjFjbTRnZEdocGN6dGNiaUFnZlZ4dVhHNGdJRjlpYVc1a1JYWmxiblFvZEdGeVoyVjBSV3hsYldWdWRDd2daWFpsYm5ST1lXMWxMQ0JvWVc1a2JHVnlLU0I3WEc0Z0lDQWdjbVYwZFhKdUlIUm9hWE11WDJselRXOWtaWEp1UW5KdmQzTmxjaUEvWEc0Z0lDQWdJQ0IwWVhKblpYUkZiR1Z0Wlc1MExtRmtaRVYyWlc1MFRHbHpkR1Z1WlhJb1pYWmxiblJPWVcxbExDQm9ZVzVrYkdWeUxDQm1ZV3h6WlNrZ09seHVJQ0FnSUNBZ2RHRnlaMlYwUld4bGJXVnVkQzVoZEhSaFkyaEZkbVZ1ZENnbmIyNG5JQ3NnWlhabGJuUk9ZVzFsTENCb1lXNWtiR1Z5S1R0Y2JpQWdmVnh1WEc0Z0lGOTFibUpwYm1SRmRtVnVkQ2gwWVhKblpYUkZiR1Z0Wlc1MExDQmxkbVZ1ZEU1aGJXVXNJR2hoYm1Sc1pYSXBJSHRjYmlBZ0lDQnlaWFIxY200Z2RHaHBjeTVmYVhOTmIyUmxjbTVDY205M2MyVnlJRDljYmlBZ0lDQWdJSFJoY21kbGRFVnNaVzFsYm5RdWNtVnRiM1psUlhabGJuUk1hWE4wWlc1bGNpaGxkbVZ1ZEU1aGJXVXNJR2hoYm1Sc1pYSXNJR1poYkhObEtTQTZYRzRnSUNBZ0lDQjBZWEpuWlhSRmJHVnRaVzUwTG1SbGRHRmphRVYyWlc1MEtDZHZiaWNnS3lCbGRtVnVkRTVoYldVc0lHaGhibVJzWlhJcE8xeHVJQ0I5WEc1Y2JpQWdYMmRsZEVkeWIzVndaV1JNYVhOMFpXNWxjbk1vS1NCN1hHNGdJQ0FnWTI5dWMzUWdiR2x6ZEdWdVpYSkhjbTkxY0hNZ0lDQTlJRnRkTzF4dUlDQWdJR052Ym5OMElHeHBjM1JsYm1WeVIzSnZkWEJOWVhBZ1BTQmJYVHRjYmx4dUlDQWdJR3hsZENCc2FYTjBaVzVsY25NZ1BTQjBhR2x6TGw5c2FYTjBaVzVsY25NN1hHNGdJQ0FnYVdZZ0tIUm9hWE11WDJOMWNuSmxiblJEYjI1MFpYaDBJQ0U5UFNBbloyeHZZbUZzSnlrZ2UxeHVJQ0FnSUNBZ2JHbHpkR1Z1WlhKeklEMGdXeTR1TG14cGMzUmxibVZ5Y3l3Z0xpNHVkR2hwY3k1ZlkyOXVkR1Y0ZEhNdVoyeHZZbUZzTG14cGMzUmxibVZ5YzEwN1hHNGdJQ0FnZlZ4dVhHNGdJQ0FnYkdsemRHVnVaWEp6TG5OdmNuUW9YRzRnSUNBZ0lDQW9ZU3dnWWlrZ1BUNWNiaUFnSUNBZ0lDQWdLR0l1YTJWNVEyOXRZbThnUHlCaUxtdGxlVU52YldKdkxtdGxlVTVoYldWekxteGxibWQwYUNBNklEQXBJQzFjYmlBZ0lDQWdJQ0FnS0dFdWEyVjVRMjl0WW04Z1B5QmhMbXRsZVVOdmJXSnZMbXRsZVU1aGJXVnpMbXhsYm1kMGFDQTZJREFwWEc0Z0lDQWdLUzVtYjNKRllXTm9LQ2hzS1NBOVBpQjdYRzRnSUNBZ0lDQnNaWFFnYldGd1NXNWtaWGdnUFNBdE1UdGNiaUFnSUNBZ0lHWnZjaUFvYkdWMElHa2dQU0F3T3lCcElEd2diR2x6ZEdWdVpYSkhjbTkxY0UxaGNDNXNaVzVuZEdnN0lHa2dLejBnTVNrZ2UxeHVJQ0FnSUNBZ0lDQnBaaUFvYkdsemRHVnVaWEpIY205MWNFMWhjRnRwWFNBOVBUMGdiblZzYkNBbUppQnNMbXRsZVVOdmJXSnZJRDA5UFNCdWRXeHNJSHg4WEc0Z0lDQWdJQ0FnSUNBZ0lDQnNhWE4wWlc1bGNrZHliM1Z3VFdGd1cybGRJQ0U5UFNCdWRXeHNJQ1ltSUd4cGMzUmxibVZ5UjNKdmRYQk5ZWEJiYVYwdWFYTkZjWFZoYkNoc0xtdGxlVU52YldKdktTa2dlMXh1SUNBZ0lDQWdJQ0FnSUcxaGNFbHVaR1Y0SUQwZ2FUdGNiaUFnSUNBZ0lDQWdmVnh1SUNBZ0lDQWdmVnh1SUNBZ0lDQWdhV1lnS0cxaGNFbHVaR1Y0SUQwOVBTQXRNU2tnZTF4dUlDQWdJQ0FnSUNCdFlYQkpibVJsZUNBOUlHeHBjM1JsYm1WeVIzSnZkWEJOWVhBdWJHVnVaM1JvTzF4dUlDQWdJQ0FnSUNCc2FYTjBaVzVsY2tkeWIzVndUV0Z3TG5CMWMyZ29iQzVyWlhsRGIyMWlieWs3WEc0Z0lDQWdJQ0I5WEc0Z0lDQWdJQ0JwWmlBb0lXeHBjM1JsYm1WeVIzSnZkWEJ6VzIxaGNFbHVaR1Y0WFNrZ2UxeHVJQ0FnSUNBZ0lDQnNhWE4wWlc1bGNrZHliM1Z3YzF0dFlYQkpibVJsZUYwZ1BTQmJYVHRjYmlBZ0lDQWdJSDFjYmlBZ0lDQWdJR3hwYzNSbGJtVnlSM0p2ZFhCelcyMWhjRWx1WkdWNFhTNXdkWE5vS0d3cE8xeHVJQ0FnSUgwcE8xeHVYRzRnSUNBZ2NtVjBkWEp1SUd4cGMzUmxibVZ5UjNKdmRYQnpPMXh1SUNCOVhHNWNiaUFnWDJGd2NHeDVRbWx1WkdsdVozTW9aWFpsYm5RcElIdGNiaUFnSUNCc1pYUWdjSEpsZG1WdWRGSmxjR1ZoZENBOUlHWmhiSE5sTzF4dVhHNGdJQ0FnWlhabGJuUWdmSHdnS0dWMlpXNTBJRDBnZTMwcE8xeHVJQ0FnSUdWMlpXNTBMbkJ5WlhabGJuUlNaWEJsWVhRZ1BTQW9LU0E5UGlCN0lIQnlaWFpsYm5SU1pYQmxZWFFnUFNCMGNuVmxPeUI5TzF4dUlDQWdJR1YyWlc1MExuQnlaWE56WldSTFpYbHpJQ0FnUFNCMGFHbHpMbDlzYjJOaGJHVXVjSEpsYzNObFpFdGxlWE11YzJ4cFkyVW9NQ2s3WEc1Y2JpQWdJQ0JqYjI1emRDQmhZM1JwZG1WVVlYSm5aWFJMWlhseklEMGdkR2hwY3k1ZmJHOWpZV3hsTG1GamRHbDJaVlJoY21kbGRFdGxlWE03WEc0Z0lDQWdZMjl1YzNRZ2NISmxjM05sWkV0bGVYTWdJQ0FnSUNBOUlIUm9hWE11WDJ4dlkyRnNaUzV3Y21WemMyVmtTMlY1Y3k1emJHbGpaU2d3S1R0Y2JpQWdJQ0JqYjI1emRDQnNhWE4wWlc1bGNrZHliM1Z3Y3lBZ0lEMGdkR2hwY3k1ZloyVjBSM0p2ZFhCbFpFeHBjM1JsYm1WeWN5Z3BPMXh1WEc0Z0lDQWdabTl5SUNoc1pYUWdhU0E5SURBN0lHa2dQQ0JzYVhOMFpXNWxja2R5YjNWd2N5NXNaVzVuZEdnN0lHa2dLejBnTVNrZ2UxeHVJQ0FnSUNBZ1kyOXVjM1FnYkdsemRHVnVaWEp6SUQwZ2JHbHpkR1Z1WlhKSGNtOTFjSE5iYVYwN1hHNGdJQ0FnSUNCamIyNXpkQ0JyWlhsRGIyMWlieUFnUFNCc2FYTjBaVzVsY25OYk1GMHVhMlY1UTI5dFltODdYRzVjYmlBZ0lDQWdJR2xtSUNoY2JpQWdJQ0FnSUNBZ2EyVjVRMjl0WW04Z1BUMDlJRzUxYkd3Z2ZIeGNiaUFnSUNBZ0lDQWdhMlY1UTI5dFltOHVZMmhsWTJzb2NISmxjM05sWkV0bGVYTXBJQ1ltWEc0Z0lDQWdJQ0FnSUdGamRHbDJaVlJoY21kbGRFdGxlWE11YzI5dFpTaHJJRDArSUd0bGVVTnZiV0p2TG10bGVVNWhiV1Z6TG1sdVkyeDFaR1Z6S0dzcEtWeHVJQ0FnSUNBZ0tTQjdYRzRnSUNBZ0lDQWdJR1p2Y2lBb2JHVjBJR29nUFNBd095QnFJRHdnYkdsemRHVnVaWEp6TG14bGJtZDBhRHNnYWlBclBTQXhLU0I3WEc0Z0lDQWdJQ0FnSUNBZ2JHVjBJR3hwYzNSbGJtVnlJRDBnYkdsemRHVnVaWEp6VzJwZE8xeHVYRzRnSUNBZ0lDQWdJQ0FnYVdZZ0tDRnNhWE4wWlc1bGNpNWxlR1ZqZFhScGJtZElZVzVrYkdWeUlDWW1JR3hwYzNSbGJtVnlMbkJ5WlhOelNHRnVaR3hsY2lBbUppQWhiR2x6ZEdWdVpYSXVjSEpsZG1WdWRGSmxjR1ZoZENrZ2UxeHVJQ0FnSUNBZ0lDQWdJQ0FnYkdsemRHVnVaWEl1WlhobFkzVjBhVzVuU0dGdVpHeGxjaUE5SUhSeWRXVTdYRzRnSUNBZ0lDQWdJQ0FnSUNCc2FYTjBaVzVsY2k1d2NtVnpjMGhoYm1Sc1pYSXVZMkZzYkNoMGFHbHpMQ0JsZG1WdWRDazdYRzRnSUNBZ0lDQWdJQ0FnSUNCc2FYTjBaVzVsY2k1bGVHVmpkWFJwYm1kSVlXNWtiR1Z5SUQwZ1ptRnNjMlU3WEc1Y2JpQWdJQ0FnSUNBZ0lDQWdJR2xtSUNod2NtVjJaVzUwVW1Wd1pXRjBJSHg4SUd4cGMzUmxibVZ5TG5CeVpYWmxiblJTWlhCbFlYUkNlVVJsWm1GMWJIUXBJSHRjYmlBZ0lDQWdJQ0FnSUNBZ0lDQWdiR2x6ZEdWdVpYSXVjSEpsZG1WdWRGSmxjR1ZoZENBOUlIUnlkV1U3WEc0Z0lDQWdJQ0FnSUNBZ0lDQWdJSEJ5WlhabGJuUlNaWEJsWVhRZ0lDQWdJQ0FnSUNBZ1BTQm1ZV3h6WlR0Y2JpQWdJQ0FnSUNBZ0lDQWdJSDFjYmlBZ0lDQWdJQ0FnSUNCOVhHNWNiaUFnSUNBZ0lDQWdJQ0JwWmlBb2RHaHBjeTVmWVhCd2JHbGxaRXhwYzNSbGJtVnljeTVwYm1SbGVFOW1LR3hwYzNSbGJtVnlLU0E5UFQwZ0xURXBJSHRjYmlBZ0lDQWdJQ0FnSUNBZ0lIUm9hWE11WDJGd2NHeHBaV1JNYVhOMFpXNWxjbk11Y0hWemFDaHNhWE4wWlc1bGNpazdYRzRnSUNBZ0lDQWdJQ0FnZlZ4dUlDQWdJQ0FnSUNCOVhHNWNiaUFnSUNBZ0lDQWdhV1lnS0d0bGVVTnZiV0p2S1NCN1hHNGdJQ0FnSUNBZ0lDQWdabTl5SUNoc1pYUWdhaUE5SURBN0lHb2dQQ0JyWlhsRGIyMWlieTVyWlhsT1lXMWxjeTVzWlc1bmRHZzdJR29nS3owZ01Ta2dlMXh1SUNBZ0lDQWdJQ0FnSUNBZ1kyOXVjM1FnYVc1a1pYZ2dQU0J3Y21WemMyVmtTMlY1Y3k1cGJtUmxlRTltS0d0bGVVTnZiV0p2TG10bGVVNWhiV1Z6VzJwZEtUdGNiaUFnSUNBZ0lDQWdJQ0FnSUdsbUlDaHBibVJsZUNBaFBUMGdMVEVwSUh0Y2JpQWdJQ0FnSUNBZ0lDQWdJQ0FnY0hKbGMzTmxaRXRsZVhNdWMzQnNhV05sS0dsdVpHVjRMQ0F4S1R0Y2JpQWdJQ0FnSUNBZ0lDQWdJQ0FnYWlBdFBTQXhPMXh1SUNBZ0lDQWdJQ0FnSUNBZ2ZWeHVJQ0FnSUNBZ0lDQWdJSDFjYmlBZ0lDQWdJQ0FnZlZ4dUlDQWdJQ0FnZlZ4dUlDQWdJSDFjYmlBZ2ZWeHVYRzRnSUY5amJHVmhja0pwYm1ScGJtZHpLR1YyWlc1MEtTQjdYRzRnSUNBZ1pYWmxiblFnZkh3Z0tHVjJaVzUwSUQwZ2UzMHBPMXh1SUNBZ0lHVjJaVzUwTG5CeVpYTnpaV1JMWlhseklEMGdkR2hwY3k1ZmJHOWpZV3hsTG5CeVpYTnpaV1JMWlhsekxuTnNhV05sS0RBcE8xeHVYRzRnSUNBZ1ptOXlJQ2hzWlhRZ2FTQTlJREE3SUdrZ1BDQjBhR2x6TGw5aGNIQnNhV1ZrVEdsemRHVnVaWEp6TG14bGJtZDBhRHNnYVNBclBTQXhLU0I3WEc0Z0lDQWdJQ0JqYjI1emRDQnNhWE4wWlc1bGNpQTlJSFJvYVhNdVgyRndjR3hwWldSTWFYTjBaVzVsY25OYmFWMDdYRzRnSUNBZ0lDQmpiMjV6ZENCclpYbERiMjFpYnlBOUlHeHBjM1JsYm1WeUxtdGxlVU52YldKdk8xeHVJQ0FnSUNBZ2FXWWdLR3RsZVVOdmJXSnZJRDA5UFNCdWRXeHNJSHg4SUNGclpYbERiMjFpYnk1amFHVmpheWgwYUdsekxsOXNiMk5oYkdVdWNISmxjM05sWkV0bGVYTXBLU0I3WEc0Z0lDQWdJQ0FnSUd4cGMzUmxibVZ5TG5CeVpYWmxiblJTWlhCbFlYUWdQU0JtWVd4elpUdGNiaUFnSUNBZ0lDQWdhV1lnS0d0bGVVTnZiV0p2SUNFOVBTQnVkV3hzSUh4OElHVjJaVzUwTG5CeVpYTnpaV1JMWlhsekxteGxibWQwYUNBOVBUMGdNQ2tnZTF4dUlDQWdJQ0FnSUNBZ0lIUm9hWE11WDJGd2NHeHBaV1JNYVhOMFpXNWxjbk11YzNCc2FXTmxLR2tzSURFcE8xeHVJQ0FnSUNBZ0lDQWdJR2tnTFQwZ01UdGNiaUFnSUNBZ0lDQWdmVnh1SUNBZ0lDQWdJQ0JwWmlBb0lXeHBjM1JsYm1WeUxtVjRaV04xZEdsdVowaGhibVJzWlhJZ0ppWWdiR2x6ZEdWdVpYSXVjbVZzWldGelpVaGhibVJzWlhJcElIdGNiaUFnSUNBZ0lDQWdJQ0JzYVhOMFpXNWxjaTVsZUdWamRYUnBibWRJWVc1a2JHVnlJRDBnZEhKMVpUdGNiaUFnSUNBZ0lDQWdJQ0JzYVhOMFpXNWxjaTV5Wld4bFlYTmxTR0Z1Wkd4bGNpNWpZV3hzS0hSb2FYTXNJR1YyWlc1MEtUdGNiaUFnSUNBZ0lDQWdJQ0JzYVhOMFpXNWxjaTVsZUdWamRYUnBibWRJWVc1a2JHVnlJRDBnWm1Gc2MyVTdYRzRnSUNBZ0lDQWdJSDFjYmlBZ0lDQWdJSDFjYmlBZ0lDQjlYRzRnSUgxY2JseHVJQ0JmYUdGdVpHeGxRMjl0YldGdVpFSjFaeWhsZG1WdWRDd2djR3hoZEdadmNtMHBJSHRjYmlBZ0lDQXZMeUJQYmlCTllXTWdkMmhsYmlCMGFHVWdZMjl0YldGdVpDQnJaWGtnYVhNZ2EyVndkQ0J3Y21WemMyVmtMQ0JyWlhsMWNDQnBjeUJ1YjNRZ2RISnBaMmRsY21Wa0lHWnZjaUJoYm5rZ2IzUm9aWElnYTJWNUxseHVJQ0FnSUM4dklFbHVJSFJvYVhNZ1kyRnpaU0JtYjNKalpTQmhJR3RsZVhWd0lHWnZjaUJ1YjI0dGJXOWthV1pwWlhJZ2EyVjVjeUJrYVhKbFkzUnNlU0JoWm5SbGNpQjBhR1VnYTJWNWNISmxjM011WEc0Z0lDQWdZMjl1YzNRZ2JXOWthV1pwWlhKTFpYbHpJRDBnVzF3aWMyaHBablJjSWl3Z1hDSmpkSEpzWENJc0lGd2lZV3gwWENJc0lGd2lZMkZ3YzJ4dlkydGNJaXdnWENKMFlXSmNJaXdnWENKamIyMXRZVzVrWENKZE8xeHVJQ0FnSUdsbUlDaHdiR0YwWm05eWJTNXRZWFJqYUNoY0lrMWhZMXdpS1NBbUppQjBhR2x6TGw5c2IyTmhiR1V1Y0hKbGMzTmxaRXRsZVhNdWFXNWpiSFZrWlhNb1hDSmpiMjF0WVc1a1hDSXBJQ1ltWEc0Z0lDQWdJQ0FnSUNGdGIyUnBabWxsY2t0bGVYTXVhVzVqYkhWa1pYTW9kR2hwY3k1ZmJHOWpZV3hsTG1kbGRFdGxlVTVoYldWektHVjJaVzUwTG10bGVVTnZaR1VwV3pCZEtTa2dlMXh1SUNBZ0lDQWdkR2hwY3k1ZmRHRnlaMlYwUzJWNVZYQkNhVzVrYVc1bktHVjJaVzUwS1R0Y2JpQWdJQ0I5WEc0Z0lIMWNibjFjYmlJc0lseHVaWGh3YjNKMElHWjFibU4wYVc5dUlIVnpLR3h2WTJGc1pTd2djR3hoZEdadmNtMHNJSFZ6WlhKQloyVnVkQ2tnZTF4dVhHNGdJQzh2SUdkbGJtVnlZV3hjYmlBZ2JHOWpZV3hsTG1KcGJtUkxaWGxEYjJSbEtETXNJQ0FnV3lkallXNWpaV3duWFNrN1hHNGdJR3h2WTJGc1pTNWlhVzVrUzJWNVEyOWtaU2c0TENBZ0lGc25ZbUZqYTNOd1lXTmxKMTBwTzF4dUlDQnNiMk5oYkdVdVltbHVaRXRsZVVOdlpHVW9PU3dnSUNCYkozUmhZaWRkS1R0Y2JpQWdiRzlqWVd4bExtSnBibVJMWlhsRGIyUmxLREV5TENBZ1d5ZGpiR1ZoY2lkZEtUdGNiaUFnYkc5allXeGxMbUpwYm1STFpYbERiMlJsS0RFekxDQWdXeWRsYm5SbGNpZGRLVHRjYmlBZ2JHOWpZV3hsTG1KcGJtUkxaWGxEYjJSbEtERTJMQ0FnV3lkemFHbG1kQ2RkS1R0Y2JpQWdiRzlqWVd4bExtSnBibVJMWlhsRGIyUmxLREUzTENBZ1d5ZGpkSEpzSjEwcE8xeHVJQ0JzYjJOaGJHVXVZbWx1WkV0bGVVTnZaR1VvTVRnc0lDQmJKMkZzZENjc0lDZHRaVzUxSjEwcE8xeHVJQ0JzYjJOaGJHVXVZbWx1WkV0bGVVTnZaR1VvTVRrc0lDQmJKM0JoZFhObEp5d2dKMkp5WldGckoxMHBPMXh1SUNCc2IyTmhiR1V1WW1sdVpFdGxlVU52WkdVb01qQXNJQ0JiSjJOaGNITnNiMk5ySjEwcE8xeHVJQ0JzYjJOaGJHVXVZbWx1WkV0bGVVTnZaR1VvTWpjc0lDQmJKMlZ6WTJGd1pTY3NJQ2RsYzJNblhTazdYRzRnSUd4dlkyRnNaUzVpYVc1a1MyVjVRMjlrWlNnek1pd2dJRnNuYzNCaFkyVW5MQ0FuYzNCaFkyVmlZWEluWFNrN1hHNGdJR3h2WTJGc1pTNWlhVzVrUzJWNVEyOWtaU2d6TXl3Z0lGc25jR0ZuWlhWd0oxMHBPMXh1SUNCc2IyTmhiR1V1WW1sdVpFdGxlVU52WkdVb016UXNJQ0JiSjNCaFoyVmtiM2R1SjEwcE8xeHVJQ0JzYjJOaGJHVXVZbWx1WkV0bGVVTnZaR1VvTXpVc0lDQmJKMlZ1WkNkZEtUdGNiaUFnYkc5allXeGxMbUpwYm1STFpYbERiMlJsS0RNMkxDQWdXeWRvYjIxbEoxMHBPMXh1SUNCc2IyTmhiR1V1WW1sdVpFdGxlVU52WkdVb016Y3NJQ0JiSjJ4bFpuUW5YU2s3WEc0Z0lHeHZZMkZzWlM1aWFXNWtTMlY1UTI5a1pTZ3pPQ3dnSUZzbmRYQW5YU2s3WEc0Z0lHeHZZMkZzWlM1aWFXNWtTMlY1UTI5a1pTZ3pPU3dnSUZzbmNtbG5hSFFuWFNrN1hHNGdJR3h2WTJGc1pTNWlhVzVrUzJWNVEyOWtaU2cwTUN3Z0lGc25aRzkzYmlkZEtUdGNiaUFnYkc5allXeGxMbUpwYm1STFpYbERiMlJsS0RReExDQWdXeWR6Wld4bFkzUW5YU2s3WEc0Z0lHeHZZMkZzWlM1aWFXNWtTMlY1UTI5a1pTZzBNaXdnSUZzbmNISnBiblJ6WTNKbFpXNG5YU2s3WEc0Z0lHeHZZMkZzWlM1aWFXNWtTMlY1UTI5a1pTZzBNeXdnSUZzblpYaGxZM1YwWlNkZEtUdGNiaUFnYkc5allXeGxMbUpwYm1STFpYbERiMlJsS0RRMExDQWdXeWR6Ym1Gd2MyaHZkQ2RkS1R0Y2JpQWdiRzlqWVd4bExtSnBibVJMWlhsRGIyUmxLRFExTENBZ1d5ZHBibk5sY25RbkxDQW5hVzV6SjEwcE8xeHVJQ0JzYjJOaGJHVXVZbWx1WkV0bGVVTnZaR1VvTkRZc0lDQmJKMlJsYkdWMFpTY3NJQ2RrWld3blhTazdYRzRnSUd4dlkyRnNaUzVpYVc1a1MyVjVRMjlrWlNnME55d2dJRnNuYUdWc2NDZGRLVHRjYmlBZ2JHOWpZV3hsTG1KcGJtUkxaWGxEYjJSbEtERTBOU3dnV3lkelkzSnZiR3hzYjJOckp5d2dKM05qY205c2JDZGRLVHRjYmlBZ2JHOWpZV3hsTG1KcGJtUkxaWGxEYjJSbEtERTRPQ3dnV3lkamIyMXRZU2NzSUNjc0oxMHBPMXh1SUNCc2IyTmhiR1V1WW1sdVpFdGxlVU52WkdVb01Ua3dMQ0JiSjNCbGNtbHZaQ2NzSUNjdUoxMHBPMXh1SUNCc2IyTmhiR1V1WW1sdVpFdGxlVU52WkdVb01Ua3hMQ0JiSjNOc1lYTm9KeXdnSjJadmNuZGhjbVJ6YkdGemFDY3NJQ2N2SjEwcE8xeHVJQ0JzYjJOaGJHVXVZbWx1WkV0bGVVTnZaR1VvTVRreUxDQmJKMmR5WVhabFlXTmpaVzUwSnl3Z0oyQW5YU2s3WEc0Z0lHeHZZMkZzWlM1aWFXNWtTMlY1UTI5a1pTZ3lNVGtzSUZzbmIzQmxibUp5WVdOclpYUW5MQ0FuV3lkZEtUdGNiaUFnYkc5allXeGxMbUpwYm1STFpYbERiMlJsS0RJeU1Dd2dXeWRpWVdOcmMyeGhjMmduTENBblhGeGNYQ2RkS1R0Y2JpQWdiRzlqWVd4bExtSnBibVJMWlhsRGIyUmxLREl5TVN3Z1d5ZGpiRzl6WldKeVlXTnJaWFFuTENBblhTZGRLVHRjYmlBZ2JHOWpZV3hsTG1KcGJtUkxaWGxEYjJSbEtESXlNaXdnV3lkaGNHOXpkSEp2Y0dobEp5d2dKMXhjSnlkZEtUdGNibHh1SUNBdkx5QXdMVGxjYmlBZ2JHOWpZV3hsTG1KcGJtUkxaWGxEYjJSbEtEUTRMQ0JiSjNwbGNtOG5MQ0FuTUNkZEtUdGNiaUFnYkc5allXeGxMbUpwYm1STFpYbERiMlJsS0RRNUxDQmJKMjl1WlNjc0lDY3hKMTBwTzF4dUlDQnNiMk5oYkdVdVltbHVaRXRsZVVOdlpHVW9OVEFzSUZzbmRIZHZKeXdnSnpJblhTazdYRzRnSUd4dlkyRnNaUzVpYVc1a1MyVjVRMjlrWlNnMU1Td2dXeWQwYUhKbFpTY3NJQ2N6SjEwcE8xeHVJQ0JzYjJOaGJHVXVZbWx1WkV0bGVVTnZaR1VvTlRJc0lGc25abTkxY2ljc0lDYzBKMTBwTzF4dUlDQnNiMk5oYkdVdVltbHVaRXRsZVVOdlpHVW9OVE1zSUZzblptbDJaU2NzSUNjMUoxMHBPMXh1SUNCc2IyTmhiR1V1WW1sdVpFdGxlVU52WkdVb05UUXNJRnNuYzJsNEp5d2dKelluWFNrN1hHNGdJR3h2WTJGc1pTNWlhVzVrUzJWNVEyOWtaU2cxTlN3Z1d5ZHpaWFpsYmljc0lDYzNKMTBwTzF4dUlDQnNiMk5oYkdVdVltbHVaRXRsZVVOdlpHVW9OVFlzSUZzblpXbG5hSFFuTENBbk9DZGRLVHRjYmlBZ2JHOWpZV3hsTG1KcGJtUkxaWGxEYjJSbEtEVTNMQ0JiSjI1cGJtVW5MQ0FuT1NkZEtUdGNibHh1SUNBdkx5QnVkVzF3WVdSY2JpQWdiRzlqWVd4bExtSnBibVJMWlhsRGIyUmxLRGsyTENCYkoyNTFiWHBsY204bkxDQW5iblZ0TUNkZEtUdGNiaUFnYkc5allXeGxMbUpwYm1STFpYbERiMlJsS0RrM0xDQmJKMjUxYlc5dVpTY3NJQ2R1ZFcweEoxMHBPMXh1SUNCc2IyTmhiR1V1WW1sdVpFdGxlVU52WkdVb09UZ3NJRnNuYm5WdGRIZHZKeXdnSjI1MWJUSW5YU2s3WEc0Z0lHeHZZMkZzWlM1aWFXNWtTMlY1UTI5a1pTZzVPU3dnV3lkdWRXMTBhSEpsWlNjc0lDZHVkVzB6SjEwcE8xeHVJQ0JzYjJOaGJHVXVZbWx1WkV0bGVVTnZaR1VvTVRBd0xDQmJKMjUxYldadmRYSW5MQ0FuYm5WdE5DZGRLVHRjYmlBZ2JHOWpZV3hsTG1KcGJtUkxaWGxEYjJSbEtERXdNU3dnV3lkdWRXMW1hWFpsSnl3Z0oyNTFiVFVuWFNrN1hHNGdJR3h2WTJGc1pTNWlhVzVrUzJWNVEyOWtaU2d4TURJc0lGc25iblZ0YzJsNEp5d2dKMjUxYlRZblhTazdYRzRnSUd4dlkyRnNaUzVpYVc1a1MyVjVRMjlrWlNneE1ETXNJRnNuYm5WdGMyVjJaVzRuTENBbmJuVnROeWRkS1R0Y2JpQWdiRzlqWVd4bExtSnBibVJMWlhsRGIyUmxLREV3TkN3Z1d5ZHVkVzFsYVdkb2RDY3NJQ2R1ZFcwNEoxMHBPMXh1SUNCc2IyTmhiR1V1WW1sdVpFdGxlVU52WkdVb01UQTFMQ0JiSjI1MWJXNXBibVVuTENBbmJuVnRPU2RkS1R0Y2JpQWdiRzlqWVd4bExtSnBibVJMWlhsRGIyUmxLREV3Tml3Z1d5ZHVkVzF0ZFd4MGFYQnNlU2NzSUNkdWRXMHFKMTBwTzF4dUlDQnNiMk5oYkdVdVltbHVaRXRsZVVOdlpHVW9NVEEzTENCYkoyNTFiV0ZrWkNjc0lDZHVkVzBySjEwcE8xeHVJQ0JzYjJOaGJHVXVZbWx1WkV0bGVVTnZaR1VvTVRBNExDQmJKMjUxYldWdWRHVnlKMTBwTzF4dUlDQnNiMk5oYkdVdVltbHVaRXRsZVVOdlpHVW9NVEE1TENCYkoyNTFiWE4xWW5SeVlXTjBKeXdnSjI1MWJTMG5YU2s3WEc0Z0lHeHZZMkZzWlM1aWFXNWtTMlY1UTI5a1pTZ3hNVEFzSUZzbmJuVnRaR1ZqYVcxaGJDY3NJQ2R1ZFcwdUoxMHBPMXh1SUNCc2IyTmhiR1V1WW1sdVpFdGxlVU52WkdVb01URXhMQ0JiSjI1MWJXUnBkbWxrWlNjc0lDZHVkVzB2SjEwcE8xeHVJQ0JzYjJOaGJHVXVZbWx1WkV0bGVVTnZaR1VvTVRRMExDQmJKMjUxYld4dlkyc25MQ0FuYm5WdEoxMHBPMXh1WEc0Z0lDOHZJR1oxYm1OMGFXOXVJR3RsZVhOY2JpQWdiRzlqWVd4bExtSnBibVJMWlhsRGIyUmxLREV4TWl3Z1d5ZG1NU2RkS1R0Y2JpQWdiRzlqWVd4bExtSnBibVJMWlhsRGIyUmxLREV4TXl3Z1d5ZG1NaWRkS1R0Y2JpQWdiRzlqWVd4bExtSnBibVJMWlhsRGIyUmxLREV4TkN3Z1d5ZG1NeWRkS1R0Y2JpQWdiRzlqWVd4bExtSnBibVJMWlhsRGIyUmxLREV4TlN3Z1d5ZG1OQ2RkS1R0Y2JpQWdiRzlqWVd4bExtSnBibVJMWlhsRGIyUmxLREV4Tml3Z1d5ZG1OU2RkS1R0Y2JpQWdiRzlqWVd4bExtSnBibVJMWlhsRGIyUmxLREV4Tnl3Z1d5ZG1OaWRkS1R0Y2JpQWdiRzlqWVd4bExtSnBibVJMWlhsRGIyUmxLREV4T0N3Z1d5ZG1OeWRkS1R0Y2JpQWdiRzlqWVd4bExtSnBibVJMWlhsRGIyUmxLREV4T1N3Z1d5ZG1PQ2RkS1R0Y2JpQWdiRzlqWVd4bExtSnBibVJMWlhsRGIyUmxLREV5TUN3Z1d5ZG1PU2RkS1R0Y2JpQWdiRzlqWVd4bExtSnBibVJMWlhsRGIyUmxLREV5TVN3Z1d5ZG1NVEFuWFNrN1hHNGdJR3h2WTJGc1pTNWlhVzVrUzJWNVEyOWtaU2d4TWpJc0lGc25aakV4SjEwcE8xeHVJQ0JzYjJOaGJHVXVZbWx1WkV0bGVVTnZaR1VvTVRJekxDQmJKMll4TWlkZEtUdGNiaUFnYkc5allXeGxMbUpwYm1STFpYbERiMlJsS0RFeU5Dd2dXeWRtTVRNblhTazdYRzRnSUd4dlkyRnNaUzVpYVc1a1MyVjVRMjlrWlNneE1qVXNJRnNuWmpFMEoxMHBPMXh1SUNCc2IyTmhiR1V1WW1sdVpFdGxlVU52WkdVb01USTJMQ0JiSjJZeE5TZGRLVHRjYmlBZ2JHOWpZV3hsTG1KcGJtUkxaWGxEYjJSbEtERXlOeXdnV3lkbU1UWW5YU2s3WEc0Z0lHeHZZMkZzWlM1aWFXNWtTMlY1UTI5a1pTZ3hNamdzSUZzblpqRTNKMTBwTzF4dUlDQnNiMk5oYkdVdVltbHVaRXRsZVVOdlpHVW9NVEk1TENCYkoyWXhPQ2RkS1R0Y2JpQWdiRzlqWVd4bExtSnBibVJMWlhsRGIyUmxLREV6TUN3Z1d5ZG1NVGtuWFNrN1hHNGdJR3h2WTJGc1pTNWlhVzVrUzJWNVEyOWtaU2d4TXpFc0lGc25aakl3SjEwcE8xeHVJQ0JzYjJOaGJHVXVZbWx1WkV0bGVVTnZaR1VvTVRNeUxDQmJKMll5TVNkZEtUdGNiaUFnYkc5allXeGxMbUpwYm1STFpYbERiMlJsS0RFek15d2dXeWRtTWpJblhTazdYRzRnSUd4dlkyRnNaUzVpYVc1a1MyVjVRMjlrWlNneE16UXNJRnNuWmpJekoxMHBPMXh1SUNCc2IyTmhiR1V1WW1sdVpFdGxlVU52WkdVb01UTTFMQ0JiSjJZeU5DZGRLVHRjYmx4dUlDQXZMeUJ6WldOdmJtUmhjbmtnYTJWNUlITjViV0p2YkhOY2JpQWdiRzlqWVd4bExtSnBibVJOWVdOeWJ5Z25jMmhwWm5RZ0t5QmdKeXdnV3lkMGFXeGtaU2NzSUNkK0oxMHBPMXh1SUNCc2IyTmhiR1V1WW1sdVpFMWhZM0p2S0NkemFHbG1kQ0FySURFbkxDQmJKMlY0WTJ4aGJXRjBhVzl1Snl3Z0oyVjRZMnhoYldGMGFXOXVjRzlwYm5RbkxDQW5JU2RkS1R0Y2JpQWdiRzlqWVd4bExtSnBibVJOWVdOeWJ5Z25jMmhwWm5RZ0t5QXlKeXdnV3lkaGRDY3NJQ2RBSjEwcE8xeHVJQ0JzYjJOaGJHVXVZbWx1WkUxaFkzSnZLQ2R6YUdsbWRDQXJJRE1uTENCYkoyNTFiV0psY2ljc0lDY2pKMTBwTzF4dUlDQnNiMk5oYkdVdVltbHVaRTFoWTNKdktDZHphR2xtZENBcklEUW5MQ0JiSjJSdmJHeGhjaWNzSUNka2IyeHNZWEp6Snl3Z0oyUnZiR3hoY25OcFoyNG5MQ0FuSkNkZEtUdGNiaUFnYkc5allXeGxMbUpwYm1STllXTnlieWduYzJocFpuUWdLeUExSnl3Z1d5ZHdaWEpqWlc1MEp5d2dKeVVuWFNrN1hHNGdJR3h2WTJGc1pTNWlhVzVrVFdGamNtOG9KM05vYVdaMElDc2dOaWNzSUZzblkyRnlaWFFuTENBblhpZGRLVHRjYmlBZ2JHOWpZV3hsTG1KcGJtUk5ZV055YnlnbmMyaHBablFnS3lBM0p5d2dXeWRoYlhCbGNuTmhibVFuTENBbllXNWtKeXdnSnlZblhTazdYRzRnSUd4dlkyRnNaUzVpYVc1a1RXRmpjbThvSjNOb2FXWjBJQ3NnT0Njc0lGc25ZWE4wWlhKcGMyc25MQ0FuS2lkZEtUdGNiaUFnYkc5allXeGxMbUpwYm1STllXTnlieWduYzJocFpuUWdLeUE1Snl3Z1d5ZHZjR1Z1Y0dGeVpXNG5MQ0FuS0NkZEtUdGNiaUFnYkc5allXeGxMbUpwYm1STllXTnlieWduYzJocFpuUWdLeUF3Snl3Z1d5ZGpiRzl6WlhCaGNtVnVKeXdnSnlrblhTazdYRzRnSUd4dlkyRnNaUzVpYVc1a1RXRmpjbThvSjNOb2FXWjBJQ3NnTFNjc0lGc25kVzVrWlhKelkyOXlaU2NzSUNkZkoxMHBPMXh1SUNCc2IyTmhiR1V1WW1sdVpFMWhZM0p2S0NkemFHbG1kQ0FySUQwbkxDQmJKM0JzZFhNbkxDQW5LeWRkS1R0Y2JpQWdiRzlqWVd4bExtSnBibVJOWVdOeWJ5Z25jMmhwWm5RZ0t5QmJKeXdnV3lkdmNHVnVZM1Z5YkhsaWNtRmpaU2NzSUNkdmNHVnVZM1Z5YkhsaWNtRmphMlYwSnl3Z0ozc25YU2s3WEc0Z0lHeHZZMkZzWlM1aWFXNWtUV0ZqY204b0ozTm9hV1owSUNzZ1hTY3NJRnNuWTJ4dmMyVmpkWEpzZVdKeVlXTmxKeXdnSjJOc2IzTmxZM1Z5YkhsaWNtRmphMlYwSnl3Z0ozMG5YU2s3WEc0Z0lHeHZZMkZzWlM1aWFXNWtUV0ZqY204b0ozTm9hV1owSUNzZ1hGeGNYQ2NzSUZzbmRtVnlkR2xqWVd4aVlYSW5MQ0FuZkNkZEtUdGNiaUFnYkc5allXeGxMbUpwYm1STllXTnlieWduYzJocFpuUWdLeUE3Snl3Z1d5ZGpiMnh2Ymljc0lDYzZKMTBwTzF4dUlDQnNiMk5oYkdVdVltbHVaRTFoWTNKdktDZHphR2xtZENBcklGeGNKeWNzSUZzbmNYVnZkR0YwYVc5dWJXRnlheWNzSUNkY1hDY25YU2s3WEc0Z0lHeHZZMkZzWlM1aWFXNWtUV0ZqY204b0ozTm9hV1owSUNzZ0lTd25MQ0JiSjI5d1pXNWhibWRzWldKeVlXTnJaWFFuTENBblBDZGRLVHRjYmlBZ2JHOWpZV3hsTG1KcGJtUk5ZV055YnlnbmMyaHBablFnS3lBdUp5d2dXeWRqYkc5elpXRnVaMnhsWW5KaFkydGxkQ2NzSUNjK0oxMHBPMXh1SUNCc2IyTmhiR1V1WW1sdVpFMWhZM0p2S0NkemFHbG1kQ0FySUM4bkxDQmJKM0YxWlhOMGFXOXViV0Z5YXljc0lDYy9KMTBwTzF4dVhHNGdJR2xtSUNod2JHRjBabTl5YlM1dFlYUmphQ2duVFdGakp5a3BJSHRjYmlBZ0lDQnNiMk5oYkdVdVltbHVaRTFoWTNKdktDZGpiMjF0WVc1a0p5d2dXeWR0YjJRbkxDQW5iVzlrYVdacFpYSW5YU2s3WEc0Z0lIMGdaV3h6WlNCN1hHNGdJQ0FnYkc5allXeGxMbUpwYm1STllXTnlieWduWTNSeWJDY3NJRnNuYlc5a0p5d2dKMjF2WkdsbWFXVnlKMTBwTzF4dUlDQjlYRzVjYmlBZ0x5OWhMWG9nWVc1a0lFRXRXbHh1SUNCbWIzSWdLR3hsZENCclpYbERiMlJsSUQwZ05qVTdJR3RsZVVOdlpHVWdQRDBnT1RBN0lHdGxlVU52WkdVZ0t6MGdNU2tnZTF4dUlDQWdJSFpoY2lCclpYbE9ZVzFsSUQwZ1UzUnlhVzVuTG1aeWIyMURhR0Z5UTI5a1pTaHJaWGxEYjJSbElDc2dNeklwTzF4dUlDQWdJSFpoY2lCallYQnBkR0ZzUzJWNVRtRnRaU0E5SUZOMGNtbHVaeTVtY205dFEyaGhja052WkdVb2EyVjVRMjlrWlNrN1hHNGdJRngwYkc5allXeGxMbUpwYm1STFpYbERiMlJsS0d0bGVVTnZaR1VzSUd0bGVVNWhiV1VwTzF4dUlDQmNkR3h2WTJGc1pTNWlhVzVrVFdGamNtOG9KM05vYVdaMElDc2dKeUFySUd0bGVVNWhiV1VzSUdOaGNHbDBZV3hMWlhsT1lXMWxLVHRjYmlBZ1hIUnNiMk5oYkdVdVltbHVaRTFoWTNKdktDZGpZWEJ6Ykc5amF5QXJJQ2NnS3lCclpYbE9ZVzFsTENCallYQnBkR0ZzUzJWNVRtRnRaU2s3WEc0Z0lIMWNibHh1SUNBdkx5QmljbTkzYzJWeUlHTmhkbVZoZEhOY2JpQWdZMjl1YzNRZ2MyVnRhV052Ykc5dVMyVjVRMjlrWlNBOUlIVnpaWEpCWjJWdWRDNXRZWFJqYUNnblJtbHlaV1p2ZUNjcElEOGdOVGtnSURvZ01UZzJPMXh1SUNCamIyNXpkQ0JrWVhOb1MyVjVRMjlrWlNBZ0lDQWdJRDBnZFhObGNrRm5aVzUwTG0xaGRHTm9LQ2RHYVhKbFptOTRKeWtnUHlBeE56TWdPaUF4T0RrN1hHNGdJR052Ym5OMElHVnhkV0ZzUzJWNVEyOWtaU0FnSUNBZ1BTQjFjMlZ5UVdkbGJuUXViV0YwWTJnb0owWnBjbVZtYjNnbktTQS9JRFl4SUNBNklERTROenRjYmlBZ2JHVjBJR3hsWm5SRGIyMXRZVzVrUzJWNVEyOWtaVHRjYmlBZ2JHVjBJSEpwWjJoMFEyOXRiV0Z1WkV0bGVVTnZaR1U3WEc0Z0lHbG1JQ2h3YkdGMFptOXliUzV0WVhSamFDZ25UV0ZqSnlrZ0ppWWdLSFZ6WlhKQloyVnVkQzV0WVhSamFDZ25VMkZtWVhKcEp5a2dmSHdnZFhObGNrRm5aVzUwTG0xaGRHTm9LQ2REYUhKdmJXVW5LU2twSUh0Y2JpQWdJQ0JzWldaMFEyOXRiV0Z1WkV0bGVVTnZaR1VnSUQwZ09URTdYRzRnSUNBZ2NtbG5hSFJEYjIxdFlXNWtTMlY1UTI5a1pTQTlJRGt6TzF4dUlDQjlJR1ZzYzJVZ2FXWW9jR3hoZEdadmNtMHViV0YwWTJnb0owMWhZeWNwSUNZbUlIVnpaWEpCWjJWdWRDNXRZWFJqYUNnblQzQmxjbUVuS1NrZ2UxeHVJQ0FnSUd4bFpuUkRiMjF0WVc1a1MyVjVRMjlrWlNBZ1BTQXhOenRjYmlBZ0lDQnlhV2RvZEVOdmJXMWhibVJMWlhsRGIyUmxJRDBnTVRjN1hHNGdJSDBnWld4elpTQnBaaWh3YkdGMFptOXliUzV0WVhSamFDZ25UV0ZqSnlrZ0ppWWdkWE5sY2tGblpXNTBMbTFoZEdOb0tDZEdhWEpsWm05NEp5a3BJSHRjYmlBZ0lDQnNaV1owUTI5dGJXRnVaRXRsZVVOdlpHVWdJRDBnTWpJME8xeHVJQ0FnSUhKcFoyaDBRMjl0YldGdVpFdGxlVU52WkdVZ1BTQXlNalE3WEc0Z0lIMWNiaUFnYkc5allXeGxMbUpwYm1STFpYbERiMlJsS0hObGJXbGpiMnh2Ymt0bGVVTnZaR1VzSUNBZ0lGc25jMlZ0YVdOdmJHOXVKeXdnSnpzblhTazdYRzRnSUd4dlkyRnNaUzVpYVc1a1MyVjVRMjlrWlNoa1lYTm9TMlY1UTI5a1pTd2dJQ0FnSUNBZ0lDQmJKMlJoYzJnbkxDQW5MU2RkS1R0Y2JpQWdiRzlqWVd4bExtSnBibVJMWlhsRGIyUmxLR1Z4ZFdGc1MyVjVRMjlrWlN3Z0lDQWdJQ0FnSUZzblpYRjFZV3duTENBblpYRjFZV3h6YVdkdUp5d2dKejBuWFNrN1hHNGdJR3h2WTJGc1pTNWlhVzVrUzJWNVEyOWtaU2hzWldaMFEyOXRiV0Z1WkV0bGVVTnZaR1VzSUNCYkoyTnZiVzFoYm1RbkxDQW5kMmx1Wkc5M2N5Y3NJQ2QzYVc0bkxDQW5jM1Z3WlhJbkxDQW5iR1ZtZEdOdmJXMWhibVFuTENBbmJHVm1kSGRwYm1SdmQzTW5MQ0FuYkdWbWRIZHBiaWNzSUNkc1pXWjBjM1Z3WlhJblhTazdYRzRnSUd4dlkyRnNaUzVpYVc1a1MyVjVRMjlrWlNoeWFXZG9kRU52YlcxaGJtUkxaWGxEYjJSbExDQmJKMk52YlcxaGJtUW5MQ0FuZDJsdVpHOTNjeWNzSUNkM2FXNG5MQ0FuYzNWd1pYSW5MQ0FuY21sbmFIUmpiMjF0WVc1a0p5d2dKM0pwWjJoMGQybHVaRzkzY3ljc0lDZHlhV2RvZEhkcGJpY3NJQ2R5YVdkb2RITjFjR1Z5SjEwcE8xeHVYRzRnSUM4dklHdHBiR3dnYTJWNWMxeHVJQ0JzYjJOaGJHVXVjMlYwUzJsc2JFdGxlU2duWTI5dGJXRnVaQ2NwTzF4dWZUdGNiaUlzSW1sdGNHOXlkQ0I3SUV0bGVXSnZZWEprSUgwZ1puSnZiU0FuTGk5c2FXSXZhMlY1WW05aGNtUW5PMXh1YVcxd2IzSjBJSHNnVEc5allXeGxJSDBnWm5KdmJTQW5MaTlzYVdJdmJHOWpZV3hsSnp0Y2JtbHRjRzl5ZENCN0lFdGxlVU52YldKdklIMGdabkp2YlNBbkxpOXNhV0l2YTJWNUxXTnZiV0p2Snp0Y2JtbHRjRzl5ZENCN0lIVnpJSDBnWm5KdmJTQW5MaTlzYjJOaGJHVnpMM1Z6Snp0Y2JseHVZMjl1YzNRZ2EyVjVZbTloY21RZ1BTQnVaWGNnUzJWNVltOWhjbVFvS1R0Y2JseHVhMlY1WW05aGNtUXVjMlYwVEc5allXeGxLQ2QxY3ljc0lIVnpLVHRjYmx4dWEyVjVZbTloY21RdVMyVjVZbTloY21RZ1BTQkxaWGxpYjJGeVpEdGNibXRsZVdKdllYSmtMa3h2WTJGc1pTQTlJRXh2WTJGc1pUdGNibXRsZVdKdllYSmtMa3RsZVVOdmJXSnZJRDBnUzJWNVEyOXRZbTg3WEc1Y2JtVjRjRzl5ZENCa1pXWmhkV3gwSUd0bGVXSnZZWEprTzF4dUlsMHNJbTVoYldWeklqcGJJa3RsZVVOdmJXSnZJaXdpYTJWNVEyOXRZbTlUZEhJaUxDSnpiM1Z5WTJWVGRISWlMQ0p6ZFdKRGIyMWliM01pTENKd1lYSnpaVU52YldKdlUzUnlJaXdpYTJWNVRtRnRaWE1pTENKeVpXUjFZMlVpTENKdFpXMXZJaXdpYm1WNGRGTjFZa052YldKdklpd2lZMjl1WTJGMElpd2ljSEpsYzNObFpFdGxlVTVoYldWeklpd2ljM1JoY25ScGJtZExaWGxPWVcxbFNXNWtaWGdpTENKcElpd2liR1Z1WjNSb0lpd2lYMk5vWldOclUzVmlRMjl0WW04aUxDSnZkR2hsY2t0bGVVTnZiV0p2SWl3aWMzVmlRMjl0WW04aUxDSnZkR2hsY2xOMVlrTnZiV0p2SWl3aWMyeHBZMlVpTENKcUlpd2lhMlY1VG1GdFpTSXNJbWx1WkdWNElpd2lhVzVrWlhoUFppSXNJbk53YkdsalpTSXNJbVZ1WkVsdVpHVjRJaXdpWlhOallYQmxaRXRsZVU1aGJXVWlMQ0pqYjIxaWIwUmxiR2x0YVc1aGRHOXlJaXdpYTJWNVJHVnNhVzFwYm1GMGIzSWlMQ0p6ZFdKRGIyMWliMU4wY25NaUxDSmZjM0JzYVhSVGRISWlMQ0pqYjIxaWJ5SXNJbkIxYzJnaUxDSnpkSElpTENKa1pXeHBiV2x1WVhSdmNpSXNJbk1pTENKa0lpd2lZeUlzSW1OaElpd2lZMmtpTENKMGNtbHRJaXdpVEc5allXeGxJaXdpYm1GdFpTSXNJbXh2WTJGc1pVNWhiV1VpTENKaFkzUnBkbVZVWVhKblpYUkxaWGx6SWl3aWNISmxjM05sWkV0bGVYTWlMQ0pmWVhCd2JHbGxaRTFoWTNKdmN5SXNJbDlyWlhsTllYQWlMQ0pmYTJsc2JFdGxlVU52WkdWeklpd2lYMjFoWTNKdmN5SXNJbXRsZVVOdlpHVWlMQ0pvWVc1a2JHVnlJaXdpYldGamNtOGlMQ0pyWlhsRGIyMWlieUlzSW10bGVVTnZaR1Z6SWl3aVoyVjBTMlY1UTI5a1pYTWlMQ0p6WlhSTGFXeHNTMlY1SWl3aWNISmxjM05MWlhraUxDSm5aWFJMWlhsT1lXMWxjeUlzSWw5aGNIQnNlVTFoWTNKdmN5SXNJbkpsYkdWaGMyVkxaWGtpTENKcmFXeHNTMlY1UTI5a1pVbHVaR1Y0SWl3aVgyTnNaV0Z5VFdGamNtOXpJaXdpYldGamNtOXpJaXdpWTJobFkyc2lMQ0pMWlhsaWIyRnlaQ0lzSW5SaGNtZGxkRmRwYm1SdmR5SXNJblJoY21kbGRFVnNaVzFsYm5RaUxDSjBZWEpuWlhSUWJHRjBabTl5YlNJc0luUmhjbWRsZEZWelpYSkJaMlZ1ZENJc0lsOXNiMk5oYkdVaUxDSmZZM1Z5Y21WdWRFTnZiblJsZUhRaUxDSmZZMjl1ZEdWNGRITWlMQ0pmYkdsemRHVnVaWEp6SWl3aVgyRndjR3hwWldSTWFYTjBaVzVsY25NaUxDSmZiRzlqWVd4bGN5SXNJbDkwWVhKblpYUkZiR1Z0Wlc1MElpd2lYM1JoY21kbGRGZHBibVJ2ZHlJc0lsOTBZWEpuWlhSUWJHRjBabTl5YlNJc0lsOTBZWEpuWlhSVmMyVnlRV2RsYm5RaUxDSmZhWE5OYjJSbGNtNUNjbTkzYzJWeUlpd2lYM1JoY21kbGRFdGxlVVJ2ZDI1Q2FXNWthVzVuSWl3aVgzUmhjbWRsZEV0bGVWVndRbWx1WkdsdVp5SXNJbDkwWVhKblpYUlNaWE5sZEVKcGJtUnBibWNpTENKZmNHRjFjMlZrSWl3aVoyeHZZbUZzSWl3aWJHbHpkR1Z1WlhKeklpd2ljMlYwUTI5dWRHVjRkQ0lzSW14dlkyRnNaVUoxYVd4a1pYSWlMQ0pzYjJOaGJHVWlMQ0pmYkc5allXeGxUbUZ0WlNJc0lteHZZMkZzVG1GdFpTSXNJbkJ5WlhOelNHRnVaR3hsY2lJc0luSmxiR1ZoYzJWSVlXNWtiR1Z5SWl3aWNISmxkbVZ1ZEZKbGNHVmhkRUo1UkdWbVlYVnNkQ0lzSW1KcGJtUWlMQ0p3Y21WMlpXNTBVbVZ3WldGMElpd2laWGhsWTNWMGFXNW5TR0Z1Wkd4bGNpSXNJblZ1WW1sdVpDSXNJbXhwYzNSbGJtVnlJaXdpWTI5dFltOU5ZWFJqYUdWeklpd2lhWE5GY1hWaGJDSXNJbkJ5WlhOelNHRnVaR3hsY2sxaGRHTm9aWE1pTENKeVpXeGxZWE5sU0dGdVpHeGxjazFoZEdOb1pYTWlMQ0pqYjI1MFpYaDBUbUZ0WlNJc0luSmxiR1ZoYzJWQmJHeExaWGx6SWl3aVoyeHZZbUZzUTI5dWRHVjRkQ0lzSW1OdmJuUmxlSFFpTENKemRHOXdJaXdpZDJGMFkyZ2lMQ0pqWVd4c1ltRmpheUlzSW5CeVpYWnBiM1Z6UTI5dWRHVjRkRTVoYldVaUxDSm5aWFJEYjI1MFpYaDBJaXdpZDJsdUlpd2laMnh2WW1Gc1ZHaHBjeUlzSW5kcGJtUnZkeUlzSW1Ga1pFVjJaVzUwVEdsemRHVnVaWElpTENKaGRIUmhZMmhGZG1WdWRDSXNJa1Z5Y205eUlpd2libTlrWlZSNWNHVWlMQ0oxYzJWeVFXZGxiblFpTENKdVlYWnBaMkYwYjNJaUxDSndiR0YwWm05eWJTSXNJbVJ2WTNWdFpXNTBJaXdpWlhabGJuUWlMQ0pmYUdGdVpHeGxRMjl0YldGdVpFSjFaeUlzSWw5aWFXNWtSWFpsYm5RaUxDSmpkWEp5Wlc1MFEyOXVkR1Y0ZENJc0lsOTFibUpwYm1SRmRtVnVkQ0lzSWw5aGNIQnNlVUpwYm1ScGJtZHpJaXdpWDJOc1pXRnlRbWx1WkdsdVozTWlMQ0psZG1WdWRFNWhiV1VpTENKeVpXMXZkbVZGZG1WdWRFeHBjM1JsYm1WeUlpd2laR1YwWVdOb1JYWmxiblFpTENKc2FYTjBaVzVsY2tkeWIzVndjeUlzSW14cGMzUmxibVZ5UjNKdmRYQk5ZWEFpTENKemIzSjBJaXdpWVNJc0ltSWlMQ0ptYjNKRllXTm9JaXdpYkNJc0ltMWhjRWx1WkdWNElpd2lYMmRsZEVkeWIzVndaV1JNYVhOMFpXNWxjbk1pTENKemIyMWxJaXdpYXlJc0ltbHVZMngxWkdWeklpd2lZMkZzYkNJc0ltMXZaR2xtYVdWeVMyVjVjeUlzSW0xaGRHTm9JaXdpZFhNaUxDSmlhVzVrUzJWNVEyOWtaU0lzSW1KcGJtUk5ZV055YnlJc0lsTjBjbWx1WnlJc0ltWnliMjFEYUdGeVEyOWtaU0lzSW1OaGNHbDBZV3hMWlhsT1lXMWxJaXdpYzJWdGFXTnZiRzl1UzJWNVEyOWtaU0lzSW1SaGMyaExaWGxEYjJSbElpd2laWEYxWVd4TFpYbERiMlJsSWl3aWJHVm1kRU52YlcxaGJtUkxaWGxEYjJSbElpd2ljbWxuYUhSRGIyMXRZVzVrUzJWNVEyOWtaU0lzSW10bGVXSnZZWEprSWl3aWMyVjBURzlqWVd4bElsMHNJbTFoY0hCcGJtZHpJam9pT3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096dE5RVU5oUVN4UlFVRmlPMFZCUTBVc2IwSkJRVmxETEZkQlFWb3NSVUZCZVVJN1JVRkJRVHM3UlVGRGRrSXNVMEZCUzBNc1UwRkJUQ3hIUVVGcFFrUXNWMEZCYWtJN1JVRkRRU3hUUVVGTFJTeFRRVUZNTEVkQlFXbENTQ3hSUVVGUkxFTkJRVU5KTEdGQlFWUXNRMEZCZFVKSUxGZEJRWFpDTEVOQlFXcENPMFZCUTBFc1UwRkJTMGtzVVVGQlRDeEhRVUZwUWl4TFFVRkxSaXhUUVVGTUxFTkJRV1ZITEUxQlFXWXNRMEZCYzBJc1ZVRkJRME1zU1VGQlJDeEZRVUZQUXl4WlFVRlFPMFZCUVVFc1lVRkRja05FTEVsQlFVa3NRMEZCUTBVc1RVRkJUQ3hEUVVGWlJDeFpRVUZhTEVOQlJIRkRPMFZCUVVFc1MwRkJkRUlzUlVGRFdTeEZRVVJhTEVOQlFXcENPMFZCUlVRN08wVkJUa2c3UlVGQlFUdEZRVUZCTERCQ1FWRlJSU3hsUVZKU0xFVkJVWGxDTzBWQlEzSkNMRlZCUVVsRExHOUNRVUZ2UWl4SFFVRkhMRU5CUVROQ096dEZRVU5CTEZkQlFVc3NTVUZCU1VNc1EwRkJReXhIUVVGSExFTkJRV0lzUlVGQlowSkJMRU5CUVVNc1IwRkJSeXhMUVVGTFZDeFRRVUZNTEVOQlFXVlZMRTFCUVc1RExFVkJRVEpEUkN4RFFVRkRMRWxCUVVrc1EwRkJhRVFzUlVGQmJVUTdSVUZEYWtSRUxGRkJRVUZCTEc5Q1FVRnZRaXhIUVVGSExFdEJRVXRITEdOQlFVd3NRMEZEY2tJc1MwRkJTMWdzVTBGQlRDeERRVUZsVXl4RFFVRm1MRU5CUkhGQ0xFVkJSWEpDUkN4dlFrRkdjVUlzUlVGSGNrSkVMR1ZCU0hGQ0xFTkJRWFpDT3p0RlFVdEJMRmxCUVVsRExHOUNRVUZ2UWl4TFFVRkxMRU5CUVVNc1EwRkJPVUlzUlVGQmFVTTdSVUZCUlN4cFFrRkJUeXhMUVVGUU8wVkJRV1U3UlVGRGJrUTdPMFZCUTBRc1lVRkJUeXhKUVVGUU8wVkJRMFE3UlVGdVFrZzdSVUZCUVR0RlFVRkJMRFJDUVhGQ1ZVa3NZVUZ5UWxZc1JVRnhRbmxDTzBWQlEzSkNMRlZCUTBVc1EwRkJRMEVzWVVGQlJDeEpRVU5CTEU5QlFVOUJMR0ZCUVZBc1MwRkJlVUlzVVVGQmVrSXNTVUZEUVN4UlFVRlBRU3hoUVVGUUxFMUJRWGxDTEZGQlNETkNMRVZCU1VVN1JVRkJSU3hsUVVGUExFdEJRVkE3UlVGQlpUczdSVUZGYmtJc1ZVRkJTU3hQUVVGUFFTeGhRVUZRTEV0QlFYbENMRkZCUVRkQ0xFVkJRWFZETzBWQlEzSkRRU3hSUVVGQlFTeGhRVUZoTEVkQlFVY3NTVUZCU1dZc1VVRkJTaXhEUVVGaFpTeGhRVUZpTEVOQlFXaENPMFZCUTBRN08wVkJSVVFzVlVGQlNTeExRVUZMV2l4VFFVRk1MRU5CUVdWVkxFMUJRV1lzUzBGQk1FSkZMR0ZCUVdFc1EwRkJRMW9zVTBGQlpDeERRVUYzUWxVc1RVRkJkRVFzUlVGQk9FUTdSVUZETlVRc1pVRkJUeXhMUVVGUU8wVkJRMFE3TzBWQlEwUXNWMEZCU3l4SlFVRkpSQ3hEUVVGRExFZEJRVWNzUTBGQllpeEZRVUZuUWtFc1EwRkJReXhIUVVGSExFdEJRVXRVTEZOQlFVd3NRMEZCWlZVc1RVRkJia01zUlVGQk1rTkVMRU5CUVVNc1NVRkJTU3hEUVVGb1JDeEZRVUZ0UkR0RlFVTnFSQ3haUVVGSkxFdEJRVXRVTEZOQlFVd3NRMEZCWlZNc1EwRkJaaXhGUVVGclFrTXNUVUZCYkVJc1MwRkJOa0pGTEdGQlFXRXNRMEZCUTFvc1UwRkJaQ3hEUVVGM1FsTXNRMEZCZUVJc1JVRkJNa0pETEUxQlFUVkVMRVZCUVc5Rk8wVkJRMnhGTEdsQ1FVRlBMRXRCUVZBN1JVRkRSRHRGUVVOR096dEZRVVZFTEZkQlFVc3NTVUZCU1VRc1JVRkJReXhIUVVGSExFTkJRV0lzUlVGQlowSkJMRVZCUVVNc1IwRkJSeXhMUVVGTFZDeFRRVUZNTEVOQlFXVlZMRTFCUVc1RExFVkJRVEpEUkN4RlFVRkRMRWxCUVVrc1EwRkJhRVFzUlVGQmJVUTdSVUZEYWtRc1dVRkJUVWtzVVVGQlVTeEhRVUZSTEV0QlFVdGlMRk5CUVV3c1EwRkJaVk1zUlVGQlppeERRVUYwUWpzN1JVRkRRU3haUVVGTlN5eGhRVUZoTEVkQlFVZEdMR0ZCUVdFc1EwRkJRMW9zVTBGQlpDeERRVUYzUWxNc1JVRkJlRUlzUlVGQk1rSk5MRXRCUVROQ0xFTkJRV2xETEVOQlFXcERMRU5CUVhSQ096dEZRVVZCTEdGQlFVc3NTVUZCU1VNc1EwRkJReXhIUVVGSExFTkJRV0lzUlVGQlowSkJMRU5CUVVNc1IwRkJSMGdzVVVGQlVTeERRVUZEU0N4TlFVRTNRaXhGUVVGeFEwMHNRMEZCUXl4SlFVRkpMRU5CUVRGRExFVkJRVFpETzBWQlF6TkRMR05CUVUxRExFOUJRVThzUjBGQlIwb3NVVUZCVVN4RFFVRkRSeXhEUVVGRUxFTkJRWGhDTzBWQlEwRXNZMEZCVFVVc1MwRkJTeXhIUVVGTFNpeGhRVUZoTEVOQlFVTkxMRTlCUVdRc1EwRkJjMEpHTEU5QlFYUkNMRU5CUVdoQ096dEZRVVZCTEdOQlFVbERMRXRCUVVzc1IwRkJSeXhEUVVGRExFTkJRV0lzUlVGQlowSTdSVUZEWkVvc1dVRkJRVUVzWVVGQllTeERRVUZEVFN4TlFVRmtMRU5CUVhGQ1JpeExRVUZ5UWl4RlFVRTBRaXhEUVVFMVFqdEZRVU5FTzBWQlEwWTdPMFZCUTBRc1dVRkJTVW9zWVVGQllTeERRVUZEU2l4TlFVRmtMRXRCUVhsQ0xFTkJRVGRDTEVWQlFXZERPMFZCUXpsQ0xHbENRVUZQTEV0QlFWQTdSVUZEUkR0RlFVTkdPenRGUVVWRUxHRkJRVThzU1VGQlVEdEZRVU5FTzBWQk0wUklPMFZCUVVFN1JVRkJRU3h0UTBFMlJHbENSeXhSUVRkRWFrSXNSVUUyUkRKQ1RDeHZRa0UzUkROQ0xFVkJOa1JwUkVRc1pVRTNSR3BFTEVWQk5rUnJSVHRGUVVNNVJFMHNUVUZCUVVFc1VVRkJVU3hIUVVGSFFTeFJRVUZSTEVOQlFVTkZMRXRCUVZRc1EwRkJaU3hEUVVGbUxFTkJRVmc3UlVGRFFWSXNUVUZCUVVFc1pVRkJaU3hIUVVGSFFTeGxRVUZsTEVOQlFVTlJMRXRCUVdoQ0xFTkJRWE5DVUN4dlFrRkJkRUlzUTBGQmJFSTdSVUZGUVN4VlFVRkpZU3hSUVVGUkxFZEJRVWRpTEc5Q1FVRm1PenRGUVVOQkxGZEJRVXNzU1VGQlNVTXNRMEZCUXl4SFFVRkhMRU5CUVdJc1JVRkJaMEpCTEVOQlFVTXNSMEZCUjBrc1VVRkJVU3hEUVVGRFNDeE5RVUUzUWl4RlFVRnhRMFFzUTBGQlF5eEpRVUZKTEVOQlFURkRMRVZCUVRaRE8wVkJSVE5ETEZsQlFVbFJMRTlCUVU4c1IwRkJSMG9zVVVGQlVTeERRVUZEU2l4RFFVRkVMRU5CUVhSQ096dEZRVU5CTEZsQlFVbFJMRTlCUVU4c1EwRkJReXhEUVVGRUxFTkJRVkFzUzBGQlpTeEpRVUZ1UWl4RlFVRjVRanRGUVVOMlFpeGpRVUZOU3l4alFVRmpMRWRCUVVkTUxFOUJRVThzUTBGQlEwWXNTMEZCVWl4RFFVRmpMRU5CUVdRc1EwRkJka0k3TzBWQlEwRXNZMEZEUlU4c1kwRkJZeXhMUVVGTGVrSXNVVUZCVVN4RFFVRkRNRUlzWjBKQlFUVkNMRWxCUTBGRUxHTkJRV01zUzBGQlMzcENMRkZCUVZFc1EwRkJRekpDTEdOQlJqbENMRVZCUjBVN1JVRkRRVkFzV1VGQlFVRXNUMEZCVHl4SFFVRkhTeXhqUVVGV08wVkJRMFE3UlVGRFJqczdSVUZGUkN4WlFVRk5TaXhMUVVGTExFZEJRVWRZTEdWQlFXVXNRMEZCUTFrc1QwRkJhRUlzUTBGQmQwSkdMRTlCUVhoQ0xFTkJRV1E3TzBWQlEwRXNXVUZCU1VNc1MwRkJTeXhIUVVGSExFTkJRVU1zUTBGQllpeEZRVUZuUWp0RlFVTmtUQ3hWUVVGQlFTeFJRVUZSTEVOQlFVTlBMRTFCUVZRc1EwRkJaMEpZTEVOQlFXaENMRVZCUVcxQ0xFTkJRVzVDTzBWQlEwRkJMRlZCUVVGQkxFTkJRVU1zU1VGQlNTeERRVUZNT3p0RlFVTkJMR05CUVVsVExFdEJRVXNzUjBGQlIwY3NVVUZCV2l4RlFVRnpRanRGUVVOd1FrRXNXVUZCUVVFc1VVRkJVU3hIUVVGSFNDeExRVUZZTzBWQlEwUTdPMFZCUTBRc1kwRkJTVXdzVVVGQlVTeERRVUZEU0N4TlFVRlVMRXRCUVc5Q0xFTkJRWGhDTEVWQlFUSkNPMFZCUTNwQ0xHMUNRVUZQVnl4UlFVRlFPMFZCUTBRN1JVRkRSanRGUVVOR096dEZRVU5FTEdGQlFVOHNRMEZCUXl4RFFVRlNPMFZCUTBRN1JVRTFSa2c3TzBWQlFVRTdSVUZCUVR0RlFTdEdRWGhDTEZGQlFWRXNRMEZCUXpCQ0xHZENRVUZVTEVkQlFUUkNMRWRCUVRWQ08wVkJRMEV4UWl4UlFVRlJMRU5CUVVNeVFpeGpRVUZVTEVkQlFUUkNMRWRCUVRWQ096dEZRVVZCTTBJc1VVRkJVU3hEUVVGRFNTeGhRVUZVTEVkQlFYbENMRlZCUVZOSUxGZEJRVlFzUlVGQmMwSTdSVUZETjBNc1RVRkJUVEpDTEZsQlFWa3NSMEZCUnpWQ0xGRkJRVkVzUTBGQlF6WkNMRk5CUVZRc1EwRkJiVUkxUWl4WFFVRnVRaXhGUVVGblEwUXNVVUZCVVN4RFFVRkRNRUlzWjBKQlFYcERMRU5CUVhKQ096dEZRVU5CTEUxQlFVMUpMRXRCUVVzc1IwRkJWU3hGUVVGeVFqczdSVUZGUVN4UFFVRkxMRWxCUVVsc1FpeERRVUZETEVkQlFVY3NRMEZCWWl4RlFVRnBRa0VzUTBGQlF5eEhRVUZIWjBJc1dVRkJXU3hEUVVGRFppeE5RVUZzUXl4RlFVRXdRMFFzUTBGQlF5eEpRVUZKTEVOQlFTOURMRVZCUVd0RU8wVkJRMmhFYTBJc1NVRkJRVUVzUzBGQlN5eERRVUZEUXl4SlFVRk9MRU5CUVZjdlFpeFJRVUZSTEVOQlFVTTJRaXhUUVVGVUxFTkJRVzFDUkN4WlFVRlpMRU5CUVVOb1FpeERRVUZFTEVOQlFTOUNMRVZCUVc5RFdpeFJRVUZSTEVOQlFVTXlRaXhqUVVFM1F5eERRVUZZTzBWQlEwUTdPMFZCUTBRc1UwRkJUMGNzUzBGQlVEdEZRVU5FTEVOQlVrUTdPMFZCVlVFNVFpeFJRVUZSTEVOQlFVTTJRaXhUUVVGVUxFZEJRWEZDTEZWQlFWTkhMRWRCUVZRc1JVRkJZME1zVjBGQlpDeEZRVUV5UWp0RlFVTTVReXhOUVVGTlF5eERRVUZETEVkQlFVbEdMRWRCUVZnN1JVRkRRU3hOUVVGTlJ5eERRVUZETEVkQlFVbEdMRmRCUVZnN1JVRkRRU3hOUVVGSlJ5eERRVUZETEVkQlFVa3NSVUZCVkR0RlFVTkJMRTFCUVUxRExFVkJRVVVzUjBGQlJ5eEZRVUZZT3p0RlFVVkJMRTlCUVVzc1NVRkJTVU1zUlVGQlJTeEhRVUZITEVOQlFXUXNSVUZCYVVKQkxFVkJRVVVzUjBGQlIwb3NRMEZCUXl4RFFVRkRja0lzVFVGQmVFSXNSVUZCWjBONVFpeEZRVUZGTEVsQlFVa3NRMEZCZEVNc1JVRkJlVU03UlVGRGRrTXNVVUZCU1VFc1JVRkJSU3hIUVVGSExFTkJRVXdzU1VGQlZVb3NRMEZCUXl4RFFVRkRTU3hGUVVGRUxFTkJRVVFzUzBGQlZVZ3NRMEZCY0VJc1NVRkJlVUpFTEVOQlFVTXNRMEZCUTBrc1JVRkJSU3hIUVVGSExFTkJRVTRzUTBGQlJDeExRVUZqTEVsQlFUTkRMRVZCUVdsRU8wVkJReTlEUkN4TlFVRkJRU3hGUVVGRkxFTkJRVU5PTEVsQlFVZ3NRMEZCVVVzc1EwRkJReXhEUVVGRFJ5eEpRVUZHTEVWQlFWSTdSVUZEUVVnc1RVRkJRVUVzUTBGQlF5eEhRVUZITEVWQlFVbzdSVUZEUVVVc1RVRkJRVUVzUlVGQlJTeEpRVUZKTEVOQlFVNDdSVUZEUkRzN1JVRkRSRVlzU1VGQlFVRXNRMEZCUXl4SlFVRkpSaXhEUVVGRExFTkJRVU5KTEVWQlFVUXNRMEZCVGp0RlFVTkVPenRGUVVORUxFMUJRVWxHTEVOQlFVb3NSVUZCVHp0RlFVRkZReXhKUVVGQlFTeEZRVUZGTEVOQlFVTk9MRWxCUVVnc1EwRkJVVXNzUTBGQlF5eERRVUZEUnl4SlFVRkdMRVZCUVZJN1JVRkJiMEk3TzBWQlJUZENMRk5CUVU5R0xFVkJRVkE3UlVGRFJDeERRV3BDUkRzN1RVTXhSMkZITEUxQlFXSTdSVUZEUlN4clFrRkJXVU1zU1VGQldpeEZRVUZyUWp0RlFVRkJPenRGUVVOb1FpeFRRVUZMUXl4VlFVRk1MRWRCUVRKQ1JDeEpRVUV6UWp0RlFVTkJMRk5CUVV0RkxHZENRVUZNTEVkQlFYZENMRVZCUVhoQ08wVkJRMEVzVTBGQlMwTXNWMEZCVEN4SFFVRXlRaXhGUVVFelFqdEZRVU5CTEZOQlFVdERMR05CUVV3c1IwRkJNa0lzUlVGQk0wSTdSVUZEUVN4VFFVRkxReXhQUVVGTUxFZEJRVEpDTEVWQlFUTkNPMFZCUTBFc1UwRkJTME1zWVVGQlRDeEhRVUV5UWl4RlFVRXpRanRGUVVOQkxGTkJRVXRETEU5QlFVd3NSMEZCTWtJc1JVRkJNMEk3UlVGRFJEczdSVUZVU0R0RlFVRkJPMFZCUVVFc1owTkJWMk5ETEU5QldHUXNSVUZYZFVJMVF5eFJRVmgyUWl4RlFWZHBRenRGUVVNM1FpeFZRVUZKTEU5QlFVOUJMRkZCUVZBc1MwRkJiMElzVVVGQmVFSXNSVUZCYTBNN1JVRkRhRU5CTEZGQlFVRkJMRkZCUVZFc1IwRkJSeXhEUVVGRFFTeFJRVUZFTEVOQlFWZzdSVUZEUkRzN1JVRkZSQ3hYUVVGTGVVTXNUMEZCVEN4RFFVRmhSeXhQUVVGaUxFbEJRWGRDTlVNc1VVRkJlRUk3UlVGRFJEdEZRV3BDU0R0RlFVRkJPMFZCUVVFc09FSkJiVUpaU2l4WFFXNUNXaXhGUVcxQ2VVSkpMRkZCYmtKNlFpeEZRVzFDYlVNN1JVRkRMMElzVlVGQlNTeFBRVUZQUVN4UlFVRlFMRXRCUVc5Q0xGRkJRWGhDTEVWQlFXdERPMFZCUTJoRFFTeFJRVUZCUVN4UlFVRlJMRWRCUVVjc1EwRkJSVUVzVVVGQlJpeERRVUZZTzBWQlEwUTdPMFZCUlVRc1ZVRkJTVFpETEU5QlFVOHNSMEZCUnl4SlFVRmtPenRGUVVOQkxGVkJRVWtzVDBGQlR6ZERMRkZCUVZBc1MwRkJiMElzVlVGQmVFSXNSVUZCYjBNN1JVRkRiRU0yUXl4UlFVRkJRU3hQUVVGUExFZEJRVWMzUXl4UlFVRldPMFZCUTBGQkxGRkJRVUZCTEZGQlFWRXNSMEZCUnl4SlFVRllPMFZCUTBRN08wVkJSVVFzVlVGQlRUaERMRXRCUVVzc1IwRkJSenRGUVVOYVF5eFJRVUZCUVN4UlFVRlJMRVZCUVVjc1NVRkJTWEJFTEZGQlFVb3NRMEZCWVVNc1YwRkJZaXhEUVVSRE8wVkJSVnBKTEZGQlFVRkJMRkZCUVZFc1JVRkJSMEVzVVVGR1F6dEZRVWRhTmtNc1VVRkJRVUVzVDBGQlR5eEZRVUZKUVR0RlFVaERMRTlCUVdRN08wVkJUVUVzVjBGQlMwWXNUMEZCVEN4RFFVRmhha0lzU1VGQllpeERRVUZyUW05Q0xFdEJRV3hDTzBWQlEwUTdSVUZ5UTBnN1JVRkJRVHRGUVVGQkxHZERRWFZEWXk5Q0xFOUJka05rTEVWQmRVTjFRanRGUVVOdVFpeFZRVUZOYVVNc1VVRkJVU3hIUVVGSExFVkJRV3BDT3p0RlFVTkJMRmRCUVVzc1NVRkJUVW9zVDBGQldDeEpRVUZ6UWl4TFFVRkxTQ3hQUVVFelFpeEZRVUZ2UXp0RlFVTnNReXhaUVVGTmVrSXNTMEZCU3l4SFFVRkhMRXRCUVV0NVFpeFBRVUZNTEVOQlFXRkhMRTlCUVdJc1JVRkJjMEl6UWl4UFFVRjBRaXhEUVVFNFFrWXNUMEZCT1VJc1EwRkJaRHM3UlVGRFFTeFpRVUZKUXl4TFFVRkxMRWRCUVVjc1EwRkJReXhEUVVGaUxFVkJRV2RDTzBWQlFVVm5ReXhWUVVGQlFTeFJRVUZSTEVOQlFVTjBRaXhKUVVGVUxFTkJRV05yUWl4UFFVRlBMRWRCUVVNc1EwRkJkRUk3UlVGQk1rSTdSVUZET1VNN08wVkJRMFFzWVVGQlQwa3NVVUZCVUR0RlFVTkVPMFZCT1VOSU8wVkJRVUU3UlVGQlFTeG5RMEZuUkdOS0xFOUJhRVJrTEVWQlowUjFRanRGUVVOdVFpeGhRVUZQTEV0QlFVdElMRTlCUVV3c1EwRkJZVWNzVDBGQllpeExRVUY1UWl4RlFVRm9RenRGUVVORU8wVkJiRVJJTzBWQlFVRTdSVUZCUVN3clFrRnZSR0ZCTEU5QmNFUmlMRVZCYjBSelFqdEZRVU5zUWl4VlFVRkpMRTlCUVU5QkxFOUJRVkFzUzBGQmJVSXNVVUZCZGtJc1JVRkJhVU03UlVGREwwSXNXVUZCVFVrc1VVRkJVU3hIUVVGSExFdEJRVXRETEZkQlFVd3NRMEZCYVVKTUxFOUJRV3BDTEVOQlFXcENPenRGUVVOQkxHRkJRVXNzU1VGQlNYSkRMRU5CUVVNc1IwRkJSeXhEUVVGaUxFVkJRV2RDUVN4RFFVRkRMRWRCUVVkNVF5eFJRVUZSTEVOQlFVTjRReXhOUVVFM1FpeEZRVUZ4UTBRc1EwRkJReXhKUVVGSkxFTkJRVEZETEVWQlFUWkRPMFZCUXpORExHVkJRVXN5UXl4VlFVRk1MRU5CUVdkQ1JpeFJRVUZSTEVOQlFVTjZReXhEUVVGRUxFTkJRWGhDTzBWQlEwUTdPMFZCUTBRN1JVRkRSRHM3UlVGRlJDeFhRVUZMYlVNc1lVRkJUQ3hEUVVGdFFtaENMRWxCUVc1Q0xFTkJRWGRDYTBJc1QwRkJlRUk3UlVGRFJEdEZRVGxFU0R0RlFVRkJPMFZCUVVFc05rSkJaMFZYUVN4UFFXaEZXQ3hGUVdkRmIwSTdSVUZEYUVJc1ZVRkJTU3hQUVVGUFFTeFBRVUZRTEV0QlFXMUNMRkZCUVhaQ0xFVkJRV2xETzBWQlF5OUNMRmxCUVUxSkxGRkJRVkVzUjBGQlJ5eExRVUZMUXl4WFFVRk1MRU5CUVdsQ1RDeFBRVUZxUWl4RFFVRnFRanM3UlVGRFFTeGhRVUZMTEVsQlFVbHlReXhEUVVGRExFZEJRVWNzUTBGQllpeEZRVUZuUWtFc1EwRkJReXhIUVVGSGVVTXNVVUZCVVN4RFFVRkRlRU1zVFVGQk4wSXNSVUZCY1VORUxFTkJRVU1zU1VGQlNTeERRVUV4UXl4RlFVRTJRenRGUVVNelF5eGxRVUZMTkVNc1VVRkJUQ3hEUVVGalNDeFJRVUZSTEVOQlFVTjZReXhEUVVGRUxFTkJRWFJDTzBWQlEwUTdPMFZCUTBRN1JVRkRSRHM3UlVGRlJDeFhRVUZMSzBJc1owSkJRVXdzUTBGQmMwSTVRaXhOUVVGMFFpeEhRVUVyUWl4RFFVRXZRanRGUVVOQkxGVkJRVTFTTEZGQlFWRXNSMEZCUnl4TFFVRkxiMFFzVjBGQlRDeERRVUZwUWxJc1QwRkJha0lzUTBGQmFrSTdPMFZCUTBFc1YwRkJTeXhKUVVGSmNrTXNSVUZCUXl4SFFVRkhMRU5CUVdJc1JVRkJaMEpCTEVWQlFVTXNSMEZCUjFBc1VVRkJVU3hEUVVGRFVTeE5RVUUzUWl4RlFVRnhRMFFzUlVGQlF5eEpRVUZKTEVOQlFURkRMRVZCUVRaRE8wVkJRek5ETEdGQlFVc3JRaXhuUWtGQlRDeERRVUZ6UWxvc1NVRkJkRUlzUTBGQk1rSXhRaXhSUVVGUkxFTkJRVU5QTEVWQlFVUXNRMEZCYmtNN08wVkJRMEVzV1VGQlNTeExRVUZMWjBNc1YwRkJUQ3hEUVVGcFFuUkNMRTlCUVdwQ0xFTkJRWGxDYWtJc1VVRkJVU3hEUVVGRFR5eEZRVUZFTEVOQlFXcERMRTFCUVRCRExFTkJRVU1zUTBGQkwwTXNSVUZCYTBRN1JVRkRhRVFzWlVGQlMyZERMRmRCUVV3c1EwRkJhVUppTEVsQlFXcENMRU5CUVhOQ01VSXNVVUZCVVN4RFFVRkRUeXhGUVVGRUxFTkJRVGxDTzBWQlEwUTdSVUZEUmpzN1JVRkZSQ3hYUVVGTE9FTXNXVUZCVER0RlFVTkVPMFZCYmtaSU8wVkJRVUU3UlVGQlFTd3JRa0Z4Um1GVUxFOUJja1ppTEVWQmNVWnpRanRGUVVOc1FpeFZRVUZKTEU5QlFVOUJMRTlCUVZBc1MwRkJiVUlzVVVGQmRrSXNSVUZCYVVNN1JVRkRMMElzV1VGQlRVa3NVVUZCVVN4SFFVRkhMRXRCUVV0RExGZEJRVXdzUTBGQmFVSk1MRTlCUVdwQ0xFTkJRV3BDT3p0RlFVTkJMR0ZCUVVzc1NVRkJTWEpETEVOQlFVTXNSMEZCUnl4RFFVRmlMRVZCUVdkQ1FTeERRVUZETEVkQlFVZDVReXhSUVVGUkxFTkJRVU40UXl4TlFVRTNRaXhGUVVGeFEwUXNRMEZCUXl4SlFVRkpMRU5CUVRGRExFVkJRVFpETzBWQlF6TkRMR1ZCUVVzclF5eFZRVUZNTEVOQlFXZENUaXhSUVVGUkxFTkJRVU42UXl4RFFVRkVMRU5CUVhoQ08wVkJRMFE3UlVGRlJpeFBRVTVFTEUxQlRVODdSVUZEVEN4WlFVRk5VQ3hSUVVGUkxFZEJRVmNzUzBGQlMyOUVMRmRCUVV3c1EwRkJhVUpTTEU5QlFXcENMRU5CUVhwQ096dEZRVU5CTEZsQlFVMVhMR2RDUVVGblFpeEhRVUZITEV0QlFVdGlMR0ZCUVV3c1EwRkJiVUo2UWl4UFFVRnVRaXhEUVVFeVFqSkNMRTlCUVROQ0xFTkJRWHBDT3p0RlFVVkJMRmxCUVVsWExHZENRVUZuUWl4TFFVRkxMRU5CUVVNc1EwRkJNVUlzUlVGQk5rSTdSVUZETTBJc1pVRkJTMmhDTEZkQlFVd3NRMEZCYVVJdlFpeE5RVUZxUWl4SFFVRXdRaXhEUVVFeFFqdEZRVU5FTEZOQlJrUXNUVUZGVHp0RlFVTk1MR1ZCUVVzc1NVRkJTVVFzUjBGQlF5eEhRVUZITEVOQlFXSXNSVUZCWjBKQkxFZEJRVU1zUjBGQlIxQXNVVUZCVVN4RFFVRkRVU3hOUVVFM1FpeEZRVUZ4UTBRc1IwRkJReXhKUVVGSkxFTkJRVEZETEVWQlFUWkRPMFZCUXpORExHZENRVUZOVXl4TFFVRkxMRWRCUVVjc1MwRkJTM1ZDTEZkQlFVd3NRMEZCYVVKMFFpeFBRVUZxUWl4RFFVRjVRbXBDTEZGQlFWRXNRMEZCUTA4c1IwRkJSQ3hEUVVGcVF5eERRVUZrT3p0RlFVTkJMR2RDUVVGSlV5eExRVUZMTEVkQlFVY3NRMEZCUXl4RFFVRmlMRVZCUVdkQ08wVkJRMlFzYlVKQlFVdDFRaXhYUVVGTUxFTkJRV2xDY2tJc1RVRkJha0lzUTBGQmQwSkdMRXRCUVhoQ0xFVkJRU3RDTEVOQlFTOUNPMFZCUTBRN1JVRkRSanRGUVVOR096dEZRVVZFTEdGQlFVdHpRaXhuUWtGQlRDeERRVUZ6UWpsQ0xFMUJRWFJDTEVkQlFTdENMRU5CUVM5Q096dEZRVU5CTEdGQlFVdG5SQ3haUVVGTU8wVkJRMFE3UlVGRFJqdEZRVGxIU0R0RlFVRkJPMFZCUVVFc2JVTkJaMGhwUWp0RlFVTmlMRlZCUVUxRExFMUJRVTBzUjBGQlJ5eExRVUZMWkN4UFFVRk1MRU5CUVdFNVFpeExRVUZpTEVOQlFXMUNMRU5CUVc1Q0xFTkJRV1k3TzBWQlEwRXNWMEZCU3l4SlFVRkpUaXhEUVVGRExFZEJRVWNzUTBGQllpeEZRVUZuUWtFc1EwRkJReXhIUVVGSGEwUXNUVUZCVFN4RFFVRkRha1FzVFVGQk0wSXNSVUZCYlVORUxFTkJRVU1zU1VGQlNTeERRVUY0UXl4RlFVRXlRenRGUVVONlF5eFpRVUZOZFVNc1MwRkJTeXhIUVVGSFZ5eE5RVUZOTEVOQlFVTnNSQ3hEUVVGRUxFTkJRWEJDT3p0RlFVTkJMRmxCUVVsMVF5eExRVUZMTEVOQlFVTkRMRkZCUVU0c1EwRkJaVmNzUzBGQlppeERRVUZ4UWl4TFFVRkxia0lzVjBGQk1VSXNRMEZCU2l4RlFVRTBRenRGUVVNeFF5eGpRVUZKVHl4TFFVRkxMRU5CUVVORUxFOUJRVllzUlVGQmJVSTdSVUZEYWtKRExGbEJRVUZCTEV0QlFVc3NRMEZCUXpsRExGRkJRVTRzUjBGQmFVSTRReXhMUVVGTExFTkJRVU5FTEU5QlFVNHNRMEZCWXl4TFFVRkxUaXhYUVVGdVFpeERRVUZxUWp0RlFVTkVPenRGUVVORUxHVkJRVXNzU1VGQlNYcENMRU5CUVVNc1IwRkJSeXhEUVVGaUxFVkJRV2RDUVN4RFFVRkRMRWRCUVVkblF5eExRVUZMTEVOQlFVTTVReXhSUVVGT0xFTkJRV1ZSTEUxQlFXNURMRVZCUVRKRFRTeERRVUZETEVsQlFVa3NRMEZCYUVRc1JVRkJiVVE3UlVGRGFrUXNaMEpCUVVrc1MwRkJTM2xDTEZkQlFVd3NRMEZCYVVKMFFpeFBRVUZxUWl4RFFVRjVRalpDTEV0QlFVc3NRMEZCUXpsRExGRkJRVTRzUTBGQlpXTXNRMEZCWml4RFFVRjZRaXhOUVVGblJDeERRVUZETEVOQlFYSkVMRVZCUVhkRU8wVkJRM1JFTEcxQ1FVRkxlVUlzVjBGQlRDeERRVUZwUW1Jc1NVRkJha0lzUTBGQmMwSnZRaXhMUVVGTExFTkJRVU01UXl4UlFVRk9MRU5CUVdWakxFTkJRV1lzUTBGQmRFSTdSVUZEUkR0RlFVTkdPenRGUVVORUxHVkJRVXN3UWl4alFVRk1MRU5CUVc5Q1pDeEpRVUZ3UWl4RFFVRjVRbTlDTEV0QlFYcENPMFZCUTBRN1JVRkRSanRGUVVOR08wVkJhRWxJTzBWQlFVRTdSVUZCUVN4dFEwRnJTV2xDTzBWQlEySXNWMEZCU3l4SlFVRkpka01zUTBGQlF5eEhRVUZITEVOQlFXSXNSVUZCWjBKQkxFTkJRVU1zUjBGQlJ5eExRVUZMYVVNc1kwRkJUQ3hEUVVGdlFtaERMRTFCUVhoRExFVkJRV2RFUkN4RFFVRkRMRWxCUVVrc1EwRkJja1FzUlVGQmQwUTdSVUZEZEVRc1dVRkJUWFZETEV0QlFVc3NSMEZCUnl4TFFVRkxUaXhqUVVGTUxFTkJRVzlDYWtNc1EwRkJjRUlzUTBGQlpEczdSVUZEUVN4WlFVRkpMRU5CUVVOMVF5eExRVUZMTEVOQlFVTkRMRkZCUVU0c1EwRkJaVmNzUzBGQlppeERRVUZ4UWl4TFFVRkxia0lzVjBGQk1VSXNRMEZCVEN4RlFVRTJRenRGUVVNelF5eGxRVUZMTEVsQlFVbDZRaXhEUVVGRExFZEJRVWNzUTBGQllpeEZRVUZuUWtFc1EwRkJReXhIUVVGSFowTXNTMEZCU3l4RFFVRkRPVU1zVVVGQlRpeERRVUZsVVN4TlFVRnVReXhGUVVFeVEwMHNRMEZCUXl4SlFVRkpMRU5CUVdoRUxFVkJRVzFFTzBWQlEycEVMR2RDUVVGTlJTeExRVUZMTEVkQlFVY3NTMEZCUzNWQ0xGZEJRVXdzUTBGQmFVSjBRaXhQUVVGcVFpeERRVUY1UWpaQ0xFdEJRVXNzUTBGQlF6bERMRkZCUVU0c1EwRkJaV01zUTBGQlppeERRVUY2UWl4RFFVRmtPenRGUVVOQkxHZENRVUZKUlN4TFFVRkxMRWRCUVVjc1EwRkJReXhEUVVGaUxFVkJRV2RDTzBWQlEyUXNiVUpCUVV0MVFpeFhRVUZNTEVOQlFXbENja0lzVFVGQmFrSXNRMEZCZDBKR0xFdEJRWGhDTEVWQlFTdENMRU5CUVM5Q08wVkJRMFE3UlVGRFJqczdSVUZEUkN4alFVRkpPRUlzUzBGQlN5eERRVUZEUkN4UFFVRldMRVZCUVcxQ08wVkJRMnBDUXl4WlFVRkJRU3hMUVVGTExFTkJRVU01UXl4UlFVRk9MRWRCUVdsQ0xFbEJRV3BDTzBWQlEwUTdPMFZCUTBRc1pVRkJTM2RETEdOQlFVd3NRMEZCYjBKMFFpeE5RVUZ3UWl4RFFVRXlRbGdzUTBGQk0wSXNSVUZCT0VJc1EwRkJPVUk3TzBWQlEwRkJMRlZCUVVGQkxFTkJRVU1zU1VGQlNTeERRVUZNTzBWQlEwUTdSVUZEUmp0RlFVTkdPMFZCYmtwSU96dEZRVUZCTzBWQlFVRTdPMDFEUTJGdlJDeFJRVUZpTzBWQlEwVXNiMEpCUVZsRExGbEJRVm9zUlVGQk1FSkRMR0ZCUVRGQ0xFVkJRWGxEUXl4alFVRjZReXhGUVVGNVJFTXNaVUZCZWtRc1JVRkJNRVU3UlVGQlFUczdSVUZEZUVVc1UwRkJTME1zVDBGQlRDeEhRVUUyUWl4SlFVRTNRanRGUVVOQkxGTkJRVXRETEdWQlFVd3NSMEZCTmtJc1JVRkJOMEk3UlVGRFFTeFRRVUZMUXl4VFFVRk1MRWRCUVRaQ0xFVkJRVGRDTzBWQlEwRXNVMEZCUzBNc1ZVRkJUQ3hIUVVFMlFpeEZRVUUzUWp0RlFVTkJMRk5CUVV0RExHbENRVUZNTEVkQlFUWkNMRVZCUVRkQ08wVkJRMEVzVTBGQlMwTXNVVUZCVEN4SFFVRTJRaXhGUVVFM1FqdEZRVU5CTEZOQlFVdERMR05CUVV3c1IwRkJOa0lzU1VGQk4wSTdSVUZEUVN4VFFVRkxReXhoUVVGTUxFZEJRVFpDTEVsQlFUZENPMFZCUTBFc1UwRkJTME1zWlVGQlRDeEhRVUUyUWl4RlFVRTNRanRGUVVOQkxGTkJRVXRETEdkQ1FVRk1MRWRCUVRaQ0xFVkJRVGRDTzBWQlEwRXNVMEZCUzBNc1owSkJRVXdzUjBGQk5rSXNTMEZCTjBJN1JVRkRRU3hUUVVGTFF5eHhRa0ZCVEN4SFFVRTJRaXhKUVVFM1FqdEZRVU5CTEZOQlFVdERMRzFDUVVGTUxFZEJRVFpDTEVsQlFUZENPMFZCUTBFc1UwRkJTME1zYlVKQlFVd3NSMEZCTmtJc1NVRkJOMEk3UlVGRFFTeFRRVUZMUXl4UFFVRk1MRWRCUVRaQ0xFdEJRVGRDTzBWQlJVRXNVMEZCUzFvc1UwRkJUQ3hEUVVGbFlTeE5RVUZtTEVkQlFYZENPMFZCUTNSQ1F5eE5RVUZCUVN4VFFVRlRMRVZCUVVVc1MwRkJTMklzVlVGRVRUdEZRVVYwUWxBc1RVRkJRVUVzV1VGQldTeEZRVUZhUVN4WlFVWnpRanRGUVVkMFFrTXNUVUZCUVVFc1lVRkJZU3hGUVVGaVFTeGhRVWh6UWp0RlFVbDBRa01zVFVGQlFVRXNZMEZCWXl4RlFVRmtRU3hqUVVwelFqdEZRVXQwUWtNc1RVRkJRVUVzWlVGQlpTeEZRVUZtUVR0RlFVeHpRaXhMUVVGNFFqdEZRVkZCTEZOQlFVdHJRaXhWUVVGTUxFTkJRV2RDTEZGQlFXaENPMFZCUTBRN08wVkJNMEpJTzBWQlFVRTdSVUZCUVN3NFFrRTJRbGsxUXl4VlFUZENXaXhGUVRaQ2QwSTJReXhoUVRkQ2VFSXNSVUUyUW5WRE8wVkJRMjVETEZWQlFVbERMRTFCUVUwc1IwRkJSeXhKUVVGaU96dEZRVU5CTEZWQlFVa3NUMEZCVHpsRExGVkJRVkFzUzBGQmMwSXNVVUZCTVVJc1JVRkJiME03UlVGRmJFTXNXVUZCU1RaRExHRkJRVW9zUlVGQmJVSTdSVUZEYWtKRExGVkJRVUZCTEUxQlFVMHNSMEZCUnl4SlFVRkphRVFzVFVGQlNpeERRVUZYUlN4VlFVRllMRU5CUVZRN1JVRkRRVFpETEZWQlFVRkJMR0ZCUVdFc1EwRkJRME1zVFVGQlJDeEZRVUZUTEV0QlFVdFlMR1ZCUVdRc1JVRkJLMElzUzBGQlMwTXNaMEpCUVhCRExFTkJRV0k3UlVGRFJDeFRRVWhFTEUxQlIwODdSVUZEVEZVc1ZVRkJRVUVzVFVGQlRTeEhRVUZITEV0QlFVdGtMRkZCUVV3c1EwRkJZMmhETEZWQlFXUXNTMEZCTmtJc1NVRkJkRU03UlVGRFJEdEZRVU5HTEU5QlVrUXNUVUZSVHp0RlFVTk1PRU1zVVVGQlFVRXNUVUZCVFN4SFFVRlBPVU1zVlVGQllqdEZRVU5CUVN4UlFVRkJRU3hWUVVGVkxFZEJRVWM0UXl4TlFVRk5MRU5CUVVORExGZEJRWEJDTzBWQlEwUTdPMFZCUlVRc1YwRkJTM0JDTEU5QlFVd3NSMEZCTkVKdFFpeE5RVUUxUWp0RlFVTkJMRmRCUVV0a0xGRkJRVXdzUTBGQlkyaERMRlZCUVdRc1NVRkJORUk0UXl4TlFVRTFRanM3UlVGRFFTeFZRVUZKUVN4TlFVRktMRVZCUVZrN1JVRkRWaXhoUVVGTGJrSXNUMEZCVEN4RFFVRmhla0lzVjBGQllpeEhRVUV5UWpSRExFMUJRVTBzUTBGQlF6VkRMRmRCUVd4RE8wVkJRMFE3TzBWQlJVUXNZVUZCVHl4SlFVRlFPMFZCUTBRN1JVRnVSRWc3UlVGQlFUdEZRVUZCTERoQ1FYRkVXVGhETEZOQmNrUmFMRVZCY1VSMVFqdEZRVU51UWtFc1RVRkJRVUVzVTBGQlV5eExRVUZMUVN4VFFVRlRMRWRCUVVjc1MwRkJTM0pDTEU5QlFVd3NRMEZCWVROQ0xGVkJRVGxDTEVOQlFWUTdSVUZEUVN4aFFVRlBMRXRCUVV0blF5eFJRVUZNTEVOQlFXTm5RaXhUUVVGa0xFdEJRVFJDTEVsQlFXNURPMFZCUTBRN1JVRjRSRWc3UlVGQlFUdEZRVUZCTEhsQ1FUQkVUM3BHTEZkQk1VUlFMRVZCTUVSdlFqQkdMRmxCTVVSd1FpeEZRVEJFYTBORExHTkJNVVJzUXl4RlFUQkVhMFJETEhOQ1FURkViRVFzUlVFd1JEQkZPMFZCUTNSRkxGVkJRVWsxUml4WFFVRlhMRXRCUVVzc1NVRkJhRUlzU1VGQmQwSXNUMEZCVDBFc1YwRkJVQ3hMUVVGMVFpeFZRVUZ1UkN4RlFVRXJSRHRGUVVNM1JEUkdMRkZCUVVGQkxITkNRVUZ6UWl4SFFVRkhSQ3hqUVVGNlFqdEZRVU5CUVN4UlFVRkJRU3hqUVVGakxFZEJRVmRFTEZsQlFYcENPMFZCUTBGQkxGRkJRVUZCTEZsQlFWa3NSMEZCWVRGR0xGZEJRWHBDTzBWQlEwRkJMRkZCUVVGQkxGZEJRVmNzUjBGQll5eEpRVUY2UWp0RlFVTkVPenRGUVVWRUxGVkJRMFZCTEZkQlFWY3NTVUZEV0N4UlFVRlBRU3hYUVVGUUxFMUJRWFZDTEZGQlJIWkNMRWxCUlVFc1QwRkJUMEVzVjBGQlZ5eERRVUZEV1N4TlFVRnVRaXhMUVVFNFFpeFJRVWhvUXl4RlFVbEZPMFZCUTBFc1lVRkJTeXhKUVVGSlJDeERRVUZETEVkQlFVY3NRMEZCWWl4RlFVRm5Ra0VzUTBGQlF5eEhRVUZIV0N4WFFVRlhMRU5CUVVOWkxFMUJRV2hETEVWQlFYZERSQ3hEUVVGRExFbEJRVWtzUTBGQk4wTXNSVUZCWjBRN1JVRkRPVU1zWlVGQlMydEdMRWxCUVV3c1EwRkJWVGRHTEZkQlFWY3NRMEZCUTFjc1EwRkJSQ3hEUVVGeVFpeEZRVUV3UWl0RkxGbEJRVEZDTEVWQlFYZERReXhqUVVGNFF6dEZRVU5FT3p0RlFVTkVMR1ZCUVU4c1NVRkJVRHRGUVVORU96dEZRVVZFTEZkQlFVdHdRaXhWUVVGTUxFTkJRV2RDZWtNc1NVRkJhRUlzUTBGQmNVSTdSVUZEYmtKeFFpeFJRVUZCUVN4UlFVRlJMRVZCUVdkQ2JrUXNWMEZCVnl4SFFVRkhMRWxCUVVsRUxGRkJRVW9zUTBGQllVTXNWMEZCWWl4RFFVRklMRWRCUVN0Q0xFbEJSQzlETzBWQlJXNUNNRVlzVVVGQlFVRXNXVUZCV1N4RlFVRlpRU3haUVVGWkxFbEJRV01zU1VGR0wwSTdSVUZIYmtKRExGRkJRVUZCTEdOQlFXTXNSVUZCVlVFc1kwRkJZeXhKUVVGWkxFbEJTQzlDTzBWQlNXNUNSeXhSUVVGQlFTeGhRVUZoTEVWQlFWY3NTMEZLVER0RlFVdHVRa1lzVVVGQlFVRXNjMEpCUVhOQ0xFVkJRVVZCTEhOQ1FVRnpRaXhKUVVGSkxFdEJUQzlDTzBWQlRXNUNSeXhSUVVGQlFTeG5Ra0ZCWjBJc1JVRkJVVHRGUVU1TUxFOUJRWEpDT3p0RlFWTkJMR0ZCUVU4c1NVRkJVRHRGUVVORU8wVkJka1pJTzBWQlFVRTdSVUZCUVN4blEwRjVSbU12Uml4WFFYcEdaQ3hGUVhsR01rSXdSaXhaUVhwR00wSXNSVUY1Um5sRFF5eGpRWHBHZWtNc1JVRjVSbmxFUXl4elFrRjZSbnBFTEVWQmVVWnBSanRGUVVNM1JTeGhRVUZQTEV0QlFVdERMRWxCUVV3c1EwRkJWVGRHTEZkQlFWWXNSVUZCZFVJd1JpeFpRVUYyUWl4RlFVRnhRME1zWTBGQmNrTXNSVUZCY1VSRExITkNRVUZ5UkN4RFFVRlFPMFZCUTBRN1JVRXpSa2c3UlVGQlFUdEZRVUZCTEhWQ1FUWkdTelZHTEZkQk4wWk1MRVZCTmtaclFqQkdMRmxCTjBac1FpeEZRVFpHWjBORExHTkJOMFpvUXl4RlFUWkdaMFJETEhOQ1FUZEdhRVFzUlVFMlJuZEZPMFZCUTNCRkxHRkJRVThzUzBGQlMwTXNTVUZCVEN4RFFVRlZOMFlzVjBGQlZpeEZRVUYxUWpCR0xGbEJRWFpDTEVWQlFYRkRReXhqUVVGeVF5eEZRVUZ4UkVNc2MwSkJRWEpFTEVOQlFWQTdSVUZEUkR0RlFTOUdTRHRGUVVGQk8wVkJRVUVzT0VKQmFVZFpOVVlzVjBGcVIxb3NSVUZwUjNsQ01FWXNXVUZxUjNwQ0xFVkJhVWQxUTBVc2MwSkJha2QyUXl4RlFXbEhLMFE3UlVGRE0wUXNZVUZCVHl4TFFVRkxReXhKUVVGTUxFTkJRVlUzUml4WFFVRldMRVZCUVhWQ01FWXNXVUZCZGtJc1JVRkJjVU1zU1VGQmNrTXNSVUZCTWtORkxITkNRVUV6UXl4RFFVRlFPMFZCUTBRN1JVRnVSMGc3UlVGQlFUdEZRVUZCTEdkRFFYRkhZelZHTEZkQmNrZGtMRVZCY1VjeVFqSkdMR05CY2tjelFpeEZRWEZITWtNN1JVRkRka01zWVVGQlR5eExRVUZMUlN4SlFVRk1MRU5CUVZVM1JpeFhRVUZXTEVWQlFYVkNMRWxCUVhaQ0xFVkJRVFpDTWtZc1kwRkJOMElzUlVGQk5rTkRMSE5DUVVFM1F5eERRVUZRTzBWQlEwUTdSVUYyUjBnN1JVRkJRVHRGUVVGQkxESkNRWGxIVXpWR0xGZEJla2RVTEVWQmVVZHpRakJHTEZsQmVrZDBRaXhGUVhsSGIwTkRMR05CZWtkd1F5eEZRWGxIYjBRN1JVRkRhRVFzVlVGQlNUTkdMRmRCUVZjc1MwRkJTeXhKUVVGb1FpeEpRVUYzUWl4UFFVRlBRU3hYUVVGUUxFdEJRWFZDTEZWQlFXNUVMRVZCUVN0RU8wVkJRemRFTWtZc1VVRkJRVUVzWTBGQll5eEhRVUZIUkN4WlFVRnFRanRGUVVOQlFTeFJRVUZCUVN4WlFVRlpMRWRCUVVzeFJpeFhRVUZxUWp0RlFVTkJRU3hSUVVGQlFTeFhRVUZYTEVkQlFVY3NTVUZCWkR0RlFVTkVPenRGUVVWRUxGVkJRMFZCTEZkQlFWY3NTVUZEV0N4UlFVRlBRU3hYUVVGUUxFMUJRWFZDTEZGQlJIWkNMRWxCUlVFc1QwRkJUMEVzVjBGQlZ5eERRVUZEV1N4TlFVRnVRaXhMUVVFNFFpeFJRVWhvUXl4RlFVbEZPMFZCUTBFc1lVRkJTeXhKUVVGSlJDeERRVUZETEVkQlFVY3NRMEZCWWl4RlFVRm5Ra0VzUTBGQlF5eEhRVUZIV0N4WFFVRlhMRU5CUVVOWkxFMUJRV2hETEVWQlFYZERSQ3hEUVVGRExFbEJRVWtzUTBGQk4wTXNSVUZCWjBRN1JVRkRPVU1zWlVGQlMzRkdMRTFCUVV3c1EwRkJXV2hITEZkQlFWY3NRMEZCUTFjc1EwRkJSQ3hEUVVGMlFpeEZRVUUwUWl0RkxGbEJRVFZDTEVWQlFUQkRReXhqUVVFeFF6dEZRVU5FT3p0RlFVTkVMR1ZCUVU4c1NVRkJVRHRGUVVORU96dEZRVVZFTEZkQlFVc3NTVUZCU1doR0xFVkJRVU1zUjBGQlJ5eERRVUZpTEVWQlFXZENRU3hGUVVGRExFZEJRVWNzUzBGQlN6UkVMRlZCUVV3c1EwRkJaMEl6UkN4TlFVRndReXhGUVVFMFEwUXNSVUZCUXl4SlFVRkpMRU5CUVdwRUxFVkJRVzlFTzBWQlEyeEVMRmxCUVUxelJpeFJRVUZSTEVkQlFVY3NTMEZCU3pGQ0xGVkJRVXdzUTBGQlowSTFSQ3hGUVVGb1FpeERRVUZxUWp0RlFVVkJMRmxCUVUxMVJpeFpRVUZaTEVkQlFWa3NRMEZCUTJ4SExGZEJRVVFzU1VGQlowSXNRMEZCUTJsSExGRkJRVkVzUTBGQlF6bERMRkZCUVRGQ0xFbEJRMFk0UXl4UlFVRlJMRU5CUVVNNVF5eFJRVUZVTEVsQlFYRkNPRU1zVVVGQlVTeERRVUZET1VNc1VVRkJWQ3hEUVVGclFtZEVMRTlCUVd4Q0xFTkJRVEJDYmtjc1YwRkJNVUlzUTBGRWFrUTdSVUZGUVN4WlFVRk5iMGNzYlVKQlFXMUNMRWRCUVVzc1EwRkJRMVlzV1VGQlJDeEpRVUZwUWl4RFFVRkRReXhqUVVGc1FpeEpRVU5HTEVOQlFVTkVMRmxCUVVRc1NVRkJhVUlzUTBGQlEwOHNVVUZCVVN4RFFVRkRVQ3haUVVSNlFpeEpRVVZHUVN4WlFVRlpMRXRCUVV0UExGRkJRVkVzUTBGQlExQXNXVUZHZEVRN1JVRkhRU3haUVVGTlZ5eHhRa0ZCY1VJc1IwRkJSeXhEUVVGRFdDeFpRVUZFTEVsQlFXbENMRU5CUVVORExHTkJRV3hDTEVsQlEwWXNRMEZCUTBFc1kwRkJSQ3hKUVVGdFFpeERRVUZEVFN4UlFVRlJMRU5CUVVOT0xHTkJSRE5DTEVsQlJVWkJMR05CUVdNc1MwRkJTMDBzVVVGQlVTeERRVUZEVGl4alFVWjRSRHM3UlVGSlFTeFpRVUZKVHl4WlFVRlpMRWxCUVVsRkxHMUNRVUZvUWl4SlFVRjFRME1zY1VKQlFUTkRMRVZCUVd0Rk8wVkJRMmhGTEdWQlFVczVRaXhWUVVGTUxFTkJRV2RDYWtRc1RVRkJhRUlzUTBGQmRVSllMRVZCUVhaQ0xFVkJRVEJDTEVOQlFURkNPenRGUVVOQlFTeFZRVUZCUVN4RlFVRkRMRWxCUVVrc1EwRkJURHRGUVVORU8wVkJRMFk3TzBWQlJVUXNZVUZCVHl4SlFVRlFPMFZCUTBRN1JVRTVTVWc3UlVGQlFUdEZRVUZCTEcxRFFXZEthVUpZTEZkQmFFcHFRaXhGUVdkS09FSXdSaXhaUVdoS09VSXNSVUZuU2pSRFF5eGpRV2hLTlVNc1JVRm5TalJFTzBWQlEzaEVMR0ZCUVU4c1MwRkJTMHNzVFVGQlRDeERRVUZaYUVjc1YwRkJXaXhGUVVGNVFqQkdMRmxCUVhwQ0xFVkJRWFZEUXl4alFVRjJReXhEUVVGUU8wVkJRMFE3UlVGc1NrZzdSVUZCUVR0RlFVRkJMSGRDUVc5S1RUTkdMRmRCY0VwT0xFVkJiMHB0UWpCR0xGbEJjRXB1UWl4RlFXOUthVU5ETEdOQmNFcHFReXhGUVc5S2FVUTdSVUZETjBNc1lVRkJUeXhMUVVGTFN5eE5RVUZNTEVOQlFWbG9SeXhYUVVGYUxFVkJRWGxDTUVZc1dVRkJla0lzUlVGQmRVTkRMR05CUVhaRExFTkJRVkE3UlVGRFJEdEZRWFJLU0R0RlFVRkJPMFZCUVVFc0swSkJkMHBoVnl4WFFYaEtZaXhGUVhkS01FSTdSVUZEZEVJc1ZVRkJSeXhMUVVGTGJFTXNUMEZCVWl4RlFVRnBRanRGUVVGRkxHRkJRVXR0UXl4alFVRk1PMFZCUVhkQ096dEZRVVV6UXl4VlFVRkpMRU5CUVVNc1MwRkJTMnBETEZOQlFVd3NRMEZCWldkRExGZEJRV1lzUTBGQlRDeEZRVUZyUXp0RlFVTm9ReXhaUVVGTlJTeGhRVUZoTEVkQlFVY3NTMEZCUzJ4RExGTkJRVXdzUTBGQlpXRXNUVUZCY2tNN1JVRkRRU3hoUVVGTFlpeFRRVUZNTEVOQlFXVm5ReXhYUVVGbUxFbEJRVGhDTzBWQlF6VkNiRUlzVlVGQlFVRXNVMEZCVXl4RlFVRlJMRVZCUkZjN1JVRkZOVUp3UWl4VlFVRkJRU3haUVVGWkxFVkJRVXQzUXl4aFFVRmhMRU5CUVVONFF5eFpRVVpJTzBWQlJ6VkNReXhWUVVGQlFTeGhRVUZoTEVWQlFVbDFReXhoUVVGaExFTkJRVU4yUXl4aFFVaElPMFZCU1RWQ1F5eFZRVUZCUVN4alFVRmpMRVZCUVVkelF5eGhRVUZoTEVOQlFVTjBReXhqUVVwSU8wVkJTelZDUXl4VlFVRkJRU3hsUVVGbExFVkJRVVZ4UXl4aFFVRmhMRU5CUVVOeVF6dEZRVXhJTEZOQlFUbENPMFZCVDBRN08wVkJSVVFzVlVGQlRYTkRMRTlCUVU4c1IwRkJWU3hMUVVGTGJrTXNVMEZCVEN4RFFVRmxaME1zVjBGQlppeERRVUYyUWp0RlFVTkJMRmRCUVV0cVF5eGxRVUZNTEVkQlFYVkNhVU1zVjBGQmRrSTdSVUZEUVN4WFFVRkxMMElzVlVGQlRDeEhRVUYxUW10RExFOUJRVThzUTBGQlEzSkNMRk5CUVM5Q08wVkJSVUVzVjBGQlMzTkNMRWxCUVV3N1JVRkRRU3hYUVVGTFF5eExRVUZNTEVOQlEwVkdMRTlCUVU4c1EwRkJRM3BETEZsQlJGWXNSVUZGUlhsRExFOUJRVThzUTBGQlEzaERMR0ZCUmxZc1JVRkhSWGRETEU5QlFVOHNRMEZCUTNaRExHTkJTRllzUlVGSlJYVkRMRTlCUVU4c1EwRkJRM1JETEdWQlNsWTdSVUZQUVN4aFFVRlBMRWxCUVZBN1JVRkRSRHRGUVc1TVNEdEZRVUZCTzBWQlFVRXNhVU5CY1V4bE8wVkJRMWdzWVVGQlR5eExRVUZMUlN4bFFVRmFPMFZCUTBRN1JVRjJURWc3UlVGQlFUdEZRVUZCTEdkRFFYbE1ZMmxETEZkQmVreGtMRVZCZVV3eVFrMHNVVUY2VEROQ0xFVkJlVXh4UXp0RlFVTnFReXhWUVVGTlF5eHRRa0ZCYlVJc1IwRkJSeXhMUVVGTFF5eFZRVUZNTEVWQlFUVkNPMFZCUTBFc1YwRkJTM3BDTEZWQlFVd3NRMEZCWjBKcFFpeFhRVUZvUWp0RlFVVkJUU3hOUVVGQlFTeFJRVUZSTzBWQlJWSXNWMEZCUzNaQ0xGVkJRVXdzUTBGQlowSjNRaXh0UWtGQmFFSTdSVUZGUVN4aFFVRlBMRWxCUVZBN1JVRkRSRHRGUVd4TlNEdEZRVUZCTzBWQlFVRXNNRUpCYjAxUk4wTXNXVUZ3VFZJc1JVRnZUWE5DUXl4aFFYQk5kRUlzUlVGdlRYRkRReXhqUVhCTmNrTXNSVUZ2VFhGRVF5eGxRWEJOY2tRc1JVRnZUWE5GTzBWQlFVRTdPMFZCUTJ4RkxGZEJRVXQxUXl4SlFVRk1PMFZCUlVFc1ZVRkJUVXNzUjBGQlJ5eEhRVUZITEU5QlFVOURMRlZCUVZBc1MwRkJjMElzVjBGQmRFSXNSMEZCYjBOQkxGVkJRWEJETEVkQlEwRXNUMEZCVHpkQ0xFMUJRVkFzUzBGQmEwSXNWMEZCYkVJc1IwRkJaME5CTEUxQlFXaERMRWRCUTBFc1QwRkJUemhDTEUxQlFWQXNTMEZCYTBJc1YwRkJiRUlzUjBGQlowTkJMRTFCUVdoRExFZEJRMEVzUlVGSVdqczdSVUZMUVN4VlFVRkpMRU5CUVVOcVJDeFpRVUZNTEVWQlFXMUNPMFZCUTJwQ0xGbEJRVWtzUTBGQlF5dERMRWRCUVVjc1EwRkJRMGNzWjBKQlFVd3NTVUZCZVVJc1EwRkJRMGdzUjBGQlJ5eERRVUZEU1N4WFFVRnNReXhGUVVFclF6dEZRVU0zUXp0RlFVTkJPMFZCUTBFc1kwRkJTU3hMUVVGTE9VTXNaVUZCVEN4TFFVRjVRaXhSUVVFM1FpeEZRVUYxUXp0RlFVTnlRenRGUVVORU96dEZRVU5FTEdkQ1FVRk5MRWxCUVVrclF5eExRVUZLTEVOQlFWVXNLMFJCUVZZc1EwRkJUanRGUVVORU96dEZRVU5FY0VRc1VVRkJRVUVzV1VGQldTeEhRVUZISzBNc1IwRkJaanRGUVVORUxFOUJiRUpwUlRzN08wVkJjVUpzUlN4VlFVRkpMRTlCUVU4dlF5eFpRVUZaTEVOQlFVTnhSQ3hSUVVGd1FpeExRVUZwUXl4UlFVRnlReXhGUVVFclF6dEZRVU0zUTJ4RUxGRkJRVUZCTEdWQlFXVXNSMEZCUjBRc1kwRkJiRUk3UlVGRFFVRXNVVUZCUVVFc1kwRkJZeXhIUVVGSlJDeGhRVUZzUWp0RlFVTkJRU3hSUVVGQlFTeGhRVUZoTEVkQlFVdEVMRmxCUVd4Q08wVkJRMEZCTEZGQlFVRkJMRmxCUVZrc1IwRkJUU3RETEVkQlFXeENPMFZCUTBRN08wVkJSVVFzVlVGQlNTeERRVUZETDBNc1dVRkJXU3hEUVVGRGEwUXNaMEpCUVdRc1NVRkJhME1zUTBGQlEyeEVMRmxCUVZrc1EwRkJRMjFFTEZkQlFYQkVMRVZCUVdsRk8wVkJReTlFTEdOQlFVMHNTVUZCU1VNc1MwRkJTaXhEUVVGVkxITkZRVUZXTEVOQlFVNDdSVUZEUkRzN1JVRkZSQ3hYUVVGTGRFTXNaMEpCUVV3c1IwRkJkMElzUTBGQlF5eERRVUZEWkN4WlFVRlpMRU5CUVVOclJDeG5Ra0ZCZGtNN1JVRkZRU3hWUVVGTlNTeFRRVUZUTEVkQlFVZDBSQ3haUVVGWkxFTkJRVU4xUkN4VFFVRmlMRWxCUVRCQ2RrUXNXVUZCV1N4RFFVRkRkVVFzVTBGQllpeERRVUYxUWtRc1UwRkJha1FzU1VGQk9FUXNSVUZCYUVZN1JVRkRRU3hWUVVGTlJTeFJRVUZSTEVkQlFVbDRSQ3haUVVGWkxFTkJRVU4xUkN4VFFVRmlMRWxCUVRCQ2RrUXNXVUZCV1N4RFFVRkRkVVFzVTBGQllpeERRVUYxUWtNc1VVRkJha1FzU1VGQk9FUXNSVUZCYUVZN1JVRkZRWFpFTEUxQlFVRkJMR0ZCUVdFc1NVRkJUVUVzWVVGQllTeExRVUZQTEVsQlFYWkRMRXRCUVdkRVFTeGhRVUZoTEVkQlFVdEVMRmxCUVZrc1EwRkJRM2xFTEZGQlFTOUZPMFZCUTBGMlJDeE5RVUZCUVN4alFVRmpMRWxCUVV0QkxHTkJRV01zUzBGQlRTeEpRVUYyUXl4TFFVRm5SRUVzWTBGQll5eEhRVUZKYzBRc1VVRkJiRVU3UlVGRFFYSkVMRTFCUVVGQkxHVkJRV1VzU1VGQlNVRXNaVUZCWlN4TFFVRkxMRWxCUVhaRExFdEJRV2RFUVN4bFFVRmxMRWRCUVVkdFJDeFRRVUZzUlRzN1JVRkZRU3hYUVVGTGRrTXNjVUpCUVV3c1IwRkJOa0lzVlVGQlF6SkRMRXRCUVVRc1JVRkJWenRGUVVOMFF5eFJRVUZCTEV0QlFVa3NRMEZCUTI1RkxGRkJRVXdzUTBGQlkyMUZMRXRCUVVzc1EwRkJRekZGTEU5QlFYQkNMRVZCUVRaQ01FVXNTMEZCTjBJN08wVkJRMEVzVVVGQlFTeExRVUZKTEVOQlFVTkRMR2xDUVVGTUxFTkJRWFZDUkN4TFFVRjJRaXhGUVVFNFFrWXNVVUZCT1VJN1JVRkRSQ3hQUVVoRU96dEZRVWxCTEZkQlFVdDRReXh0UWtGQlRDeEhRVUV5UWl4VlFVRkRNRU1zUzBGQlJDeEZRVUZYTzBWQlEzQkRMRkZCUVVFc1MwRkJTU3hEUVVGRGFFVXNWVUZCVEN4RFFVRm5RbWRGTEV0QlFVc3NRMEZCUXpGRkxFOUJRWFJDTEVWQlFTdENNRVVzUzBGQkwwSTdSVUZEUkN4UFFVWkVPenRGUVVkQkxGZEJRVXQ2UXl4dFFrRkJUQ3hIUVVFeVFpeFZRVUZEZVVNc1MwRkJSQ3hGUVVGWE8wVkJRM0JETEZGQlFVRXNTMEZCU1N4RFFVRkRia0lzWTBGQlRDeERRVUZ2UW0xQ0xFdEJRWEJDTzBWQlEwUXNUMEZHUkRzN1JVRkpRU3hYUVVGTFJTeFZRVUZNTEVOQlFXZENNMFFzWVVGQmFFSXNSVUZCSzBJc1UwRkJMMElzUlVGQk1FTXNTMEZCUzJNc2NVSkJRUzlET3p0RlFVTkJMRmRCUVVzMlF5eFZRVUZNTEVOQlFXZENNMFFzWVVGQmFFSXNSVUZCSzBJc1QwRkJMMElzUlVGQk1FTXNTMEZCUzJVc2JVSkJRUzlET3p0RlFVTkJMRmRCUVVzMFF5eFZRVUZNTEVOQlFXZENOVVFzV1VGQmFFSXNSVUZCSzBJc1QwRkJMMElzUlVGQk1FTXNTMEZCUzJsQ0xHMUNRVUV2UXpzN1JVRkRRU3hYUVVGTE1rTXNWVUZCVEN4RFFVRm5RalZFTEZsQlFXaENMRVZCUVN0Q0xFMUJRUzlDTEVWQlFUQkRMRXRCUVV0cFFpeHRRa0ZCTDBNN08wVkJSVUVzVjBGQlMxQXNZMEZCVEN4SFFVRjNRbFFzWVVGQmVFSTdSVUZEUVN4WFFVRkxWU3hoUVVGTUxFZEJRWGRDV0N4WlFVRjRRanRGUVVOQkxGZEJRVXRaTEdWQlFVd3NSMEZCZDBKV0xHTkJRWGhDTzBWQlEwRXNWMEZCUzFjc1owSkJRVXdzUjBGQmQwSldMR1ZCUVhoQ08wVkJSVUVzVlVGQlRUQkVMR05CUVdNc1IwRkJZU3hMUVVGTGRrUXNVMEZCVEN4RFFVRmxMRXRCUVV0RUxHVkJRWEJDTEVOQlFXcERPMFZCUTBGM1JDeE5RVUZCUVN4alFVRmpMRU5CUVVNM1JDeFpRVUZtTEVkQlFXbERMRXRCUVV0WExHRkJRWFJETzBWQlEwRnJSQ3hOUVVGQlFTeGpRVUZqTEVOQlFVTTFSQ3hoUVVGbUxFZEJRV2xETEV0QlFVdFRMR05CUVhSRE8wVkJRMEZ0UkN4TlFVRkJRU3hqUVVGakxFTkJRVU16UkN4alFVRm1MRWRCUVdsRExFdEJRVXRWTEdWQlFYUkRPMFZCUTBGcFJDeE5RVUZCUVN4alFVRmpMRU5CUVVNeFJDeGxRVUZtTEVkQlFXbERMRXRCUVV0VkxHZENRVUYwUXp0RlFVVkJMR0ZCUVU4c1NVRkJVRHRGUVVORU8wVkJlbEZJTzBWQlFVRTdSVUZCUVN3eVFrRXlVVk03UlVGRFRDeFZRVUZKTEVOQlFVTXNTMEZCUzBnc1kwRkJUaXhKUVVGM1FpeERRVUZETEV0QlFVdERMR0ZCUVd4RExFVkJRV2xFTzBWQlFVVTdSVUZCVXpzN1JVRkZOVVFzVjBGQlMyMUVMRmxCUVV3c1EwRkJhMElzUzBGQlMzQkVMR05CUVhaQ0xFVkJRWFZETEZOQlFYWkRMRVZCUVd0RUxFdEJRVXRMTEhGQ1FVRjJSRHM3UlVGRFFTeFhRVUZMSzBNc1dVRkJUQ3hEUVVGclFpeExRVUZMY0VRc1kwRkJka0lzUlVGQmRVTXNUMEZCZGtNc1JVRkJhMFFzUzBGQlMwMHNiVUpCUVhaRU96dEZRVU5CTEZkQlFVczRReXhaUVVGTUxFTkJRV3RDTEV0QlFVdHVSQ3hoUVVGMlFpeEZRVUYxUXl4UFFVRjJReXhGUVVGclJDeExRVUZMVFN4dFFrRkJka1E3TzBWQlEwRXNWMEZCU3paRExGbEJRVXdzUTBGQmEwSXNTMEZCUzI1RUxHRkJRWFpDTEVWQlFYVkRMRTFCUVhaRExFVkJRV3RFTEV0QlFVdE5MRzFDUVVGMlJEczdSVUZGUVN4WFFVRkxUaXhoUVVGTUxFZEJRWE5DTEVsQlFYUkNPMFZCUTBFc1YwRkJTMFFzWTBGQlRDeEhRVUZ6UWl4SlFVRjBRanRGUVVWQkxHRkJRVThzU1VGQlVEdEZRVU5FTzBWQmRsSklPMFZCUVVFN1JVRkJRU3cyUWtGNVVsY3hRaXhQUVhwU1dDeEZRWGxTYjBJd1JTeExRWHBTY0VJc1JVRjVVakpDTzBWQlEzWkNMRlZCUVVrc1MwRkJTM2hETEU5QlFWUXNSVUZCYTBJN1JVRkJSU3hsUVVGUExFbEJRVkE3UlVGQll6czdSVUZEYkVNc1ZVRkJTU3hEUVVGRExFdEJRVXRrTEU5QlFWWXNSVUZCYlVJN1JVRkJSU3hqUVVGTkxFbEJRVWxuUkN4TFFVRktMRU5CUVZVc1owSkJRVllzUTBGQlRqdEZRVUZ2UXpzN1JVRkZla1FzVjBGQlMyaEVMRTlCUVV3c1EwRkJZV0lzVVVGQllpeERRVUZ6UWxBc1QwRkJkRUk3TzBWQlEwRXNWMEZCU3l0RkxHTkJRVXdzUTBGQmIwSk1MRXRCUVhCQ096dEZRVVZCTEdGQlFVOHNTVUZCVUR0RlFVTkVPMFZCYWxOSU8wVkJRVUU3UlVGQlFTd3JRa0Z0VTJFeFJTeFBRVzVUWWl4RlFXMVRjMEl3UlN4TFFXNVRkRUlzUlVGdFV6WkNPMFZCUTNwQ0xGVkJRVWtzUzBGQlMzaERMRTlCUVZRc1JVRkJhMEk3UlVGQlJTeGxRVUZQTEVsQlFWQTdSVUZCWXpzN1JVRkRiRU1zVlVGQlNTeERRVUZETEV0QlFVdGtMRTlCUVZZc1JVRkJiVUk3UlVGQlJTeGpRVUZOTEVsQlFVbG5SQ3hMUVVGS0xFTkJRVlVzWjBKQlFWWXNRMEZCVGp0RlFVRnZRenM3UlVGRmVrUXNWMEZCUzJoRUxFOUJRVXdzUTBGQllWWXNWVUZCWWl4RFFVRjNRbFlzVDBGQmVFSTdPMFZCUTBFc1YwRkJTMmRHTEdOQlFVd3NRMEZCYjBKT0xFdEJRWEJDT3p0RlFVVkJMR0ZCUVU4c1NVRkJVRHRGUVVORU8wVkJNMU5JTzBWQlFVRTdSVUZCUVN4dFEwRTJVMmxDUVN4TFFUZFRha0lzUlVFMlUzZENPMFZCUTNCQ0xGVkJRVWtzUzBGQlMzaERMRTlCUVZRc1JVRkJhMEk3UlVGQlJTeGxRVUZQTEVsQlFWQTdSVUZCWXpzN1JVRkRiRU1zVlVGQlNTeERRVUZETEV0QlFVdGtMRTlCUVZZc1JVRkJiVUk3UlVGQlJTeGpRVUZOTEVsQlFVbG5SQ3hMUVVGS0xFTkJRVlVzWjBKQlFWWXNRMEZCVGp0RlFVRnZRenM3UlVGRmVrUXNWMEZCUzJoRUxFOUJRVXdzUTBGQllYcENMRmRCUVdJc1EwRkJlVUl2UWl4TlFVRjZRaXhIUVVGclF5eERRVUZzUXpzN1JVRkRRU3hYUVVGTGIwZ3NZMEZCVEN4RFFVRnZRazRzUzBGQmNFSTdPMFZCUlVFc1lVRkJUeXhKUVVGUU8wVkJRMFE3UlVGeVZFZzdSVUZCUVR0RlFVRkJMRFJDUVhWVVZUdEZRVU5PTEZWQlFVa3NTMEZCUzNoRExFOUJRVlFzUlVGQmEwSTdSVUZCUlN4bFFVRlBMRWxCUVZBN1JVRkJZenM3UlVGRGJFTXNWVUZCU1N4TFFVRkxaQ3hQUVVGVUxFVkJRV3RDTzBWQlFVVXNZVUZCUzIxRExHTkJRVXc3UlVGQmQwSTdPMFZCUXpWRExGZEJRVXR5UWl4UFFVRk1MRWRCUVdVc1NVRkJaanRGUVVWQkxHRkJRVThzU1VGQlVEdEZRVU5FTzBWQk4xUklPMFZCUVVFN1JVRkJRU3cyUWtFclZGYzdSVUZEVUN4WFFVRkxRU3hQUVVGTUxFZEJRV1VzUzBGQlpqdEZRVVZCTEdGQlFVOHNTVUZCVUR0RlFVTkVPMFZCYmxWSU8wVkJRVUU3UlVGQlFTdzBRa0Z4VlZVN1JVRkRUaXhYUVVGTGNVSXNZMEZCVER0RlFVTkJMRmRCUVV0b1F5eFZRVUZNTEVOQlFXZENNMFFzVFVGQmFFSXNSMEZCZVVJc1EwRkJla0k3UlVGRlFTeGhRVUZQTEVsQlFWQTdSVUZEUkR0RlFURlZTRHRGUVVGQk8wVkJRVUVzSzBKQk5GVmhjVVFzWVVFMVZXSXNSVUUwVlRSQ1owVXNVMEUxVlRWQ0xFVkJORlYxUTJoR0xFOUJOVlYyUXl4RlFUUlZaMFE3UlVGRE5VTXNZVUZCVHl4TFFVRkxOa0lzWjBKQlFVd3NSMEZEVEdJc1lVRkJZU3hEUVVGRGFVUXNaMEpCUVdRc1EwRkJLMEpsTEZOQlFTOUNMRVZCUVRCRGFFWXNUMEZCTVVNc1JVRkJiVVFzUzBGQmJrUXNRMEZFU3l4SFFVVk1aMElzWVVGQllTeERRVUZEYTBRc1YwRkJaQ3hEUVVFd1FpeFBRVUZQWXl4VFFVRnFReXhGUVVFMFEyaEdMRTlCUVRWRExFTkJSa1k3UlVGSFJEdEZRV2hXU0R0RlFVRkJPMFZCUVVFc2FVTkJhMVpsWjBJc1lVRnNWbVlzUlVGclZqaENaMFVzVTBGc1ZqbENMRVZCYTFaNVEyaEdMRTlCYkZaNlF5eEZRV3RXYTBRN1JVRkRPVU1zWVVGQlR5eExRVUZMTmtJc1owSkJRVXdzUjBGRFRHSXNZVUZCWVN4RFFVRkRhVVVzYlVKQlFXUXNRMEZCYTBORUxGTkJRV3hETEVWQlFUWkRhRVlzVDBGQk4wTXNSVUZCYzBRc1MwRkJkRVFzUTBGRVN5eEhRVVZNWjBJc1lVRkJZU3hEUVVGRGEwVXNWMEZCWkN4RFFVRXdRaXhQUVVGUFJpeFRRVUZxUXl4RlFVRTBRMmhHTEU5QlFUVkRMRU5CUmtZN1JVRkhSRHRGUVhSV1NEdEZRVUZCTzBWQlFVRXNNa05CZDFaNVFqdEZRVU55UWl4VlFVRk5iVVlzWTBGQll5eEhRVUZMTEVWQlFYcENPMFZCUTBFc1ZVRkJUVU1zWjBKQlFXZENMRWRCUVVjc1JVRkJla0k3UlVGRlFTeFZRVUZKYWtRc1UwRkJVeXhIUVVGSExFdEJRVXRpTEZWQlFYSkNPenRGUVVOQkxGVkJRVWtzUzBGQlMwWXNaVUZCVEN4TFFVRjVRaXhSUVVFM1FpeEZRVUYxUXp0RlFVTnlRMlVzVVVGQlFVRXNVMEZCVXl4blEwRkJUMEVzVTBGQlVDeHpRa0ZCY1VJc1MwRkJTMlFzVTBGQlRDeERRVUZsWVN4TlFVRm1MRU5CUVhOQ1F5eFRRVUV6UXl4RlFVRlVPMFZCUTBRN08wVkJSVVJCTEUxQlFVRkJMRk5CUVZNc1EwRkJRMnRFTEVsQlFWWXNRMEZEUlN4VlFVRkRReXhEUVVGRUxFVkJRVWxETEVOQlFVbzdSVUZCUVN4bFFVTkZMRU5CUVVOQkxFTkJRVU1zUTBGQlEzSkdMRkZCUVVZc1IwRkJZWEZHTEVOQlFVTXNRMEZCUTNKR0xGRkJRVVlzUTBGQlZ5OURMRkZCUVZnc1EwRkJiMEpSTEUxQlFXcERMRWRCUVRCRExFTkJRVE5ETEV0QlEwTXlTQ3hEUVVGRExFTkJRVU53Uml4UlFVRkdMRWRCUVdGdlJpeERRVUZETEVOQlFVTndSaXhSUVVGR0xFTkJRVmN2UXl4UlFVRllMRU5CUVc5Q1VTeE5RVUZxUXl4SFFVRXdReXhEUVVRelF5eERRVVJHTzBWQlFVRXNUMEZFUml4RlFVbEZOa2dzVDBGS1JpeERRVWxWTEZWQlFVTkRMRU5CUVVRc1JVRkJUenRGUVVObUxGbEJRVWxETEZGQlFWRXNSMEZCUnl4RFFVRkRMRU5CUVdoQ096dEZRVU5CTEdGQlFVc3NTVUZCU1doSkxFTkJRVU1zUjBGQlJ5eERRVUZpTEVWQlFXZENRU3hEUVVGRExFZEJRVWN3U0N4blFrRkJaMElzUTBGQlEzcElMRTFCUVhKRExFVkJRVFpEUkN4RFFVRkRMRWxCUVVrc1EwRkJiRVFzUlVGQmNVUTdSVUZEYmtRc1kwRkJTVEJJTEdkQ1FVRm5RaXhEUVVGRE1VZ3NRMEZCUkN4RFFVRm9RaXhMUVVGM1FpeEpRVUY0UWl4SlFVRm5ReXRJTEVOQlFVTXNRMEZCUTNaR0xGRkJRVVlzUzBGQlpTeEpRVUV2UXl4SlFVTkJhMFlzWjBKQlFXZENMRU5CUVVNeFNDeERRVUZFTEVOQlFXaENMRXRCUVhkQ0xFbEJRWGhDTEVsQlFXZERNRWdzWjBKQlFXZENMRU5CUVVNeFNDeERRVUZFTEVOQlFXaENMRU5CUVc5Q2QwWXNUMEZCY0VJc1EwRkJORUoxUXl4RFFVRkRMRU5CUVVOMlJpeFJRVUU1UWl4RFFVUndReXhGUVVNMlJUdEZRVU16UlhkR0xGbEJRVUZCTEZGQlFWRXNSMEZCUjJoSkxFTkJRVmc3UlVGRFJEdEZRVU5HT3p0RlFVTkVMRmxCUVVsblNTeFJRVUZSTEV0QlFVc3NRMEZCUXl4RFFVRnNRaXhGUVVGeFFqdEZRVU51UWtFc1ZVRkJRVUVzVVVGQlVTeEhRVUZIVGl4blFrRkJaMElzUTBGQlEzcElMRTFCUVRWQ08wVkJRMEY1U0N4VlFVRkJRU3huUWtGQlowSXNRMEZCUTNaSExFbEJRV3BDTEVOQlFYTkNORWNzUTBGQlF5eERRVUZEZGtZc1VVRkJlRUk3UlVGRFJEczdSVUZEUkN4WlFVRkpMRU5CUVVOcFJpeGpRVUZqTEVOQlFVTlBMRkZCUVVRc1EwRkJia0lzUlVGQkswSTdSVUZETjBKUUxGVkJRVUZCTEdOQlFXTXNRMEZCUTA4c1VVRkJSQ3hEUVVGa0xFZEJRVEpDTEVWQlFUTkNPMFZCUTBRN08wVkJRMFJRTEZGQlFVRkJMR05CUVdNc1EwRkJRMDhzVVVGQlJDeERRVUZrTEVOQlFYbENOMGNzU1VGQmVrSXNRMEZCT0VJMFJ5eERRVUU1UWp0RlFVTkVMRTlCY0VKRU8wVkJjMEpCTEdGQlFVOU9MR05CUVZBN1JVRkRSRHRGUVhoWVNEdEZRVUZCTzBWQlFVRXNiVU5CTUZocFFsWXNTMEV4V0dwQ0xFVkJNRmgzUWp0RlFVRkJPenRGUVVOd1FpeFZRVUZKTlVJc1lVRkJZU3hIUVVGSExFdEJRWEJDTzBWQlJVRTBRaXhOUVVGQlFTeExRVUZMTEV0QlFVdEJMRXRCUVVzc1IwRkJSeXhGUVVGaUxFTkJRVXc3TzBWQlEwRkJMRTFCUVVGQkxFdEJRVXNzUTBGQlF6VkNMR0ZCUVU0c1IwRkJjMElzV1VGQlRUdEZRVUZGUVN4UlFVRkJRU3hoUVVGaExFZEJRVWNzU1VGQmFFSTdSVUZCZFVJc1QwRkJja1E3TzBWQlEwRTBRaXhOUVVGQlFTeExRVUZMTEVOQlFVTXZSU3hYUVVGT0xFZEJRWE5DTEV0QlFVdDVRaXhQUVVGTUxFTkJRV0Y2UWl4WFFVRmlMRU5CUVhsQ01VSXNTMEZCZWtJc1EwRkJLMElzUTBGQkwwSXNRMEZCZEVJN1JVRkZRU3hWUVVGTmVVSXNaMEpCUVdkQ0xFZEJRVWNzUzBGQlN6QkNMRTlCUVV3c1EwRkJZVEZDTEdkQ1FVRjBRenM3UlVGRFFTeFZRVUZOUXl4WFFVRlhMRWRCUVZFc1MwRkJTM2xDTEU5QlFVd3NRMEZCWVhwQ0xGZEJRV0lzUTBGQmVVSXhRaXhMUVVGNlFpeERRVUVyUWl4RFFVRXZRaXhEUVVGNlFqczdSVUZEUVN4VlFVRk5iVWdzWTBGQll5eEhRVUZMTEV0QlFVdFJMRzlDUVVGTUxFVkJRWHBDT3p0RlFWUnZRaXhwUTBGWFdHcEpMRU5CV0ZjN1JVRlpiRUlzV1VGQlRYbEZMRk5CUVZNc1IwRkJSMmRFTEdOQlFXTXNRMEZCUTNwSUxFTkJRVVFzUTBGQmFFTTdSVUZEUVN4WlFVRk5kME1zVVVGQlVTeEhRVUZKYVVNc1UwRkJVeXhEUVVGRExFTkJRVVFzUTBGQlZDeERRVUZoYWtNc1VVRkJMMEk3TzBWQlJVRXNXVUZEUlVFc1VVRkJVU3hMUVVGTExFbEJRV0lzU1VGRFFVRXNVVUZCVVN4RFFVRkRWeXhMUVVGVUxFTkJRV1Z1UWl4WFFVRm1MRXRCUTBGRUxHZENRVUZuUWl4RFFVRkRiVWNzU1VGQmFrSXNRMEZCYzBJc1ZVRkJRVU1zUTBGQlF6dEZRVUZCTEdsQ1FVRkpNMFlzVVVGQlVTeERRVUZETDBNc1VVRkJWQ3hEUVVGclFqSkpMRkZCUVd4Q0xFTkJRVEpDUkN4RFFVRXpRaXhEUVVGS08wVkJRVUVzVTBGQmRrSXNRMEZJUml4RlFVbEZPMFZCUTBFc1pVRkJTeXhKUVVGSk5VZ3NRMEZCUXl4SFFVRkhMRU5CUVdJc1JVRkJaMEpCTEVOQlFVTXNSMEZCUjJ0RkxGTkJRVk1zUTBGQlEzaEZMRTFCUVRsQ0xFVkJRWE5EVFN4RFFVRkRMRWxCUVVrc1EwRkJNME1zUlVGQk9FTTdSVUZETlVNc1owSkJRVWtyUlN4UlFVRlJMRWRCUVVkaUxGTkJRVk1zUTBGQlEyeEZMRU5CUVVRc1EwRkJlRUk3TzBWQlJVRXNaMEpCUVVrc1EwRkJReXRGTEZGQlFWRXNRMEZCUTBZc1owSkJRVllzU1VGQk9FSkZMRkZCUVZFc1EwRkJRMUFzV1VGQmRrTXNTVUZCZFVRc1EwRkJRMDhzVVVGQlVTeERRVUZEU0N4aFFVRnlSU3hGUVVGdlJqdEZRVU5zUmtjc1kwRkJRVUVzVVVGQlVTeERRVUZEUml4blFrRkJWQ3hIUVVFMFFpeEpRVUUxUWp0RlFVTkJSU3hqUVVGQlFTeFJRVUZSTEVOQlFVTlFMRmxCUVZRc1EwRkJjMEp6UkN4SlFVRjBRaXhEUVVFeVFpeE5RVUV6UWl4RlFVRnBRM1JDTEV0QlFXcERPMFZCUTBGNlFpeGpRVUZCUVN4UlFVRlJMRU5CUVVOR0xHZENRVUZVTEVkQlFUUkNMRXRCUVRWQ096dEZRVVZCTEd0Q1FVRkpSQ3hoUVVGaExFbEJRVWxITEZGQlFWRXNRMEZCUTB3c2MwSkJRVGxDTEVWQlFYTkVPMFZCUTNCRVN5eG5Ra0ZCUVVFc1VVRkJVU3hEUVVGRFNDeGhRVUZVTEVkQlFYbENMRWxCUVhwQ08wVkJRMEZCTEdkQ1FVRkJRU3hoUVVGaExFZEJRVmtzUzBGQmVrSTdSVUZEUkR0RlFVTkdPenRGUVVWRUxHZENRVUZKTEUxQlFVa3NRMEZCUTNSQ0xHbENRVUZNTEVOQlFYVkNia1FzVDBGQmRrSXNRMEZCSzBJMFJTeFJRVUV2UWl4TlFVRTJReXhEUVVGRExFTkJRV3hFTEVWQlFYRkVPMFZCUTI1RUxHTkJRVUVzVFVGQlNTeERRVUZEZWtJc2FVSkJRVXdzUTBGQmRVSXhReXhKUVVGMlFpeERRVUUwUW0xRkxGRkJRVFZDTzBWQlEwUTdSVUZEUmpzN1JVRkZSQ3hqUVVGSk9VTXNVVUZCU2l4RlFVRmpPMFZCUTFvc2FVSkJRVXNzU1VGQlNXcERMRVZCUVVNc1IwRkJSeXhEUVVGaUxFVkJRV2RDUVN4RlFVRkRMRWRCUVVkcFF5eFJRVUZSTEVOQlFVTXZReXhSUVVGVUxFTkJRV3RDVVN4TlFVRjBReXhGUVVFNFEwMHNSVUZCUXl4SlFVRkpMRU5CUVc1RUxFVkJRWE5FTzBWQlEzQkVMR3RDUVVGTlJTeExRVUZMTEVkQlFVZDFRaXhYUVVGWExFTkJRVU4wUWl4UFFVRmFMRU5CUVc5Q09FSXNVVUZCVVN4RFFVRkRMME1zVVVGQlZDeERRVUZyUW1Nc1JVRkJiRUlzUTBGQmNFSXNRMEZCWkRzN1JVRkRRU3hyUWtGQlNVVXNTMEZCU3l4TFFVRkxMRU5CUVVNc1EwRkJaaXhGUVVGclFqdEZRVU5vUW5WQ0xHZENRVUZCUVN4WFFVRlhMRU5CUVVOeVFpeE5RVUZhTEVOQlFXMUNSaXhMUVVGdVFpeEZRVUV3UWl4RFFVRXhRanRGUVVOQlJpeG5Ra0ZCUVVFc1JVRkJReXhKUVVGSkxFTkJRVXc3UlVGRFJEdEZRVU5HTzBWQlEwWTdSVUZEUmp0RlFXaEVhVUk3TzBWQlYzQkNMRmRCUVVzc1NVRkJTVkFzUTBGQlF5eEhRVUZITEVOQlFXSXNSVUZCWjBKQkxFTkJRVU1zUjBGQlIzbElMR05CUVdNc1EwRkJRM2hJTEUxQlFXNURMRVZCUVRKRFJDeERRVUZETEVsQlFVa3NRMEZCYUVRc1JVRkJiVVE3UlVGQlFTeGpRVUV4UTBFc1EwRkJNRU03UlVGelEyeEVPMFZCUTBZN1JVRTFZVWc3UlVGQlFUdEZRVUZCTEcxRFFUaGhhVUlyUnl4TFFUbGhha0lzUlVFNFlYZENPMFZCUTNCQ1FTeE5RVUZCUVN4TFFVRkxMRXRCUVV0QkxFdEJRVXNzUjBGQlJ5eEZRVUZpTEVOQlFVdzdSVUZEUVVFc1RVRkJRVUVzUzBGQlN5eERRVUZETDBVc1YwRkJUaXhIUVVGdlFpeExRVUZMZVVJc1QwRkJUQ3hEUVVGaGVrSXNWMEZCWWl4RFFVRjVRakZDTEV0QlFYcENMRU5CUVN0Q0xFTkJRUzlDTEVOQlFYQkNPenRGUVVWQkxGZEJRVXNzU1VGQlNVNHNRMEZCUXl4SFFVRkhMRU5CUVdJc1JVRkJaMEpCTEVOQlFVTXNSMEZCUnl4TFFVRkxOa1FzYVVKQlFVd3NRMEZCZFVJMVJDeE5RVUV6UXl4RlFVRnRSRVFzUTBGQlF5eEpRVUZKTEVOQlFYaEVMRVZCUVRKRU8wVkJRM3BFTEZsQlFVMXpSaXhSUVVGUkxFZEJRVWNzUzBGQlMzcENMR2xDUVVGTUxFTkJRWFZDTjBRc1EwRkJka0lzUTBGQmFrSTdSVUZEUVN4WlFVRk5kME1zVVVGQlVTeEhRVUZIT0VNc1VVRkJVU3hEUVVGRE9VTXNVVUZCTVVJN08wVkJRMEVzV1VGQlNVRXNVVUZCVVN4TFFVRkxMRWxCUVdJc1NVRkJjVUlzUTBGQlEwRXNVVUZCVVN4RFFVRkRWeXhMUVVGVUxFTkJRV1VzUzBGQlMwMHNUMEZCVEN4RFFVRmhla0lzVjBGQk5VSXNRMEZCTVVJc1JVRkJiMFU3UlVGRGJFVnpSQ3hWUVVGQlFTeFJRVUZSTEVOQlFVTklMR0ZCUVZRc1IwRkJlVUlzUzBGQmVrSTdPMFZCUTBFc1kwRkJTVE5ETEZGQlFWRXNTMEZCU3l4SlFVRmlMRWxCUVhGQ2RVVXNTMEZCU3l4RFFVRkRMMFVzVjBGQlRpeERRVUZyUWk5Q0xFMUJRV3hDTEV0QlFUWkNMRU5CUVhSRUxFVkJRWGxFTzBWQlEzWkVMR2xDUVVGTE5FUXNhVUpCUVV3c1EwRkJkVUpzUkN4TlFVRjJRaXhEUVVFNFFsZ3NRMEZCT1VJc1JVRkJhVU1zUTBGQmFrTTdPMFZCUTBGQkxGbEJRVUZCTEVOQlFVTXNTVUZCU1N4RFFVRk1PMFZCUTBRN08wVkJRMFFzWTBGQlNTeERRVUZEYzBZc1VVRkJVU3hEUVVGRFJpeG5Ra0ZCVml4SlFVRTRRa1VzVVVGQlVTeERRVUZEVGl4alFVRXpReXhGUVVFeVJEdEZRVU42UkUwc1dVRkJRVUVzVVVGQlVTeERRVUZEUml4blFrRkJWQ3hIUVVFMFFpeEpRVUUxUWp0RlFVTkJSU3haUVVGQlFTeFJRVUZSTEVOQlFVTk9MR05CUVZRc1EwRkJkMEp4UkN4SlFVRjRRaXhEUVVFMlFpeEpRVUUzUWl4RlFVRnRRM1JDTEV0QlFXNURPMFZCUTBGNlFpeFpRVUZCUVN4UlFVRlJMRU5CUVVOR0xHZENRVUZVTEVkQlFUUkNMRXRCUVRWQ08wVkJRMFE3UlVGRFJqdEZRVU5HTzBWQlEwWTdSVUZzWTBnN1JVRkJRVHRGUVVGQkxITkRRVzlqYjBJeVFpeExRWEJqY0VJc1JVRnZZekpDUml4UlFYQmpNMElzUlVGdlkzRkRPMFZCUTJwRE8wVkJRMEU3UlVGRFFTeFZRVUZOZVVJc1dVRkJXU3hIUVVGSExFTkJRVU1zVDBGQlJDeEZRVUZWTEUxQlFWWXNSVUZCYTBJc1MwRkJiRUlzUlVGQmVVSXNWVUZCZWtJc1JVRkJjVU1zUzBGQmNrTXNSVUZCTkVNc1UwRkJOVU1zUTBGQmNrSTdPMFZCUTBFc1ZVRkJTWHBDTEZGQlFWRXNRMEZCUXpCQ0xFdEJRVlFzUTBGQlpTeExRVUZtTEV0QlFYbENMRXRCUVVzNVJTeFBRVUZNTEVOQlFXRjZRaXhYUVVGaUxFTkJRWGxDYjBjc1VVRkJla0lzUTBGQmEwTXNVMEZCYkVNc1EwRkJla0lzU1VGRFFTeERRVUZEUlN4WlFVRlpMRU5CUVVOR0xGRkJRV0lzUTBGQmMwSXNTMEZCU3pORkxFOUJRVXdzUTBGQllWb3NWMEZCWWl4RFFVRjVRbXRGTEV0QlFVc3NRMEZCUXpGRkxFOUJRUzlDTEVWQlFYZERMRU5CUVhoRExFTkJRWFJDTEVOQlJFd3NSVUZEZDBVN1JVRkRkRVVzWVVGQlMyZERMRzFDUVVGTUxFTkJRWGxDTUVNc1MwRkJla0k3UlVGRFJEdEZRVU5HTzBWQk5XTklPenRGUVVGQk8wVkJRVUU3TzBWRFNFOHNVMEZCVTNsQ0xFVkJRVlFzUTBGQldUVkVMRTFCUVZvc1JVRkJiMEpwUXl4UlFVRndRaXhGUVVFNFFrWXNVMEZCT1VJc1JVRkJlVU03UlVGRk9VTTdSVUZEUVM5Q0xFVkJRVUZCTEUxQlFVMHNRMEZCUXpaRUxGZEJRVkFzUTBGQmJVSXNRMEZCYmtJc1JVRkJkMElzUTBGQlF5eFJRVUZFTEVOQlFYaENPMFZCUTBFM1JDeEZRVUZCUVN4TlFVRk5MRU5CUVVNMlJDeFhRVUZRTEVOQlFXMUNMRU5CUVc1Q0xFVkJRWGRDTEVOQlFVTXNWMEZCUkN4RFFVRjRRanRGUVVOQk4wUXNSVUZCUVVFc1RVRkJUU3hEUVVGRE5rUXNWMEZCVUN4RFFVRnRRaXhEUVVGdVFpeEZRVUYzUWl4RFFVRkRMRXRCUVVRc1EwRkJlRUk3UlVGRFFUZEVMRVZCUVVGQkxFMUJRVTBzUTBGQlF6WkVMRmRCUVZBc1EwRkJiVUlzUlVGQmJrSXNSVUZCZDBJc1EwRkJReXhQUVVGRUxFTkJRWGhDTzBWQlEwRTNSQ3hGUVVGQlFTeE5RVUZOTEVOQlFVTTJSQ3hYUVVGUUxFTkJRVzFDTEVWQlFXNUNMRVZCUVhkQ0xFTkJRVU1zVDBGQlJDeERRVUY0UWp0RlFVTkJOMFFzUlVGQlFVRXNUVUZCVFN4RFFVRkROa1FzVjBGQlVDeERRVUZ0UWl4RlFVRnVRaXhGUVVGM1FpeERRVUZETEU5QlFVUXNRMEZCZUVJN1JVRkRRVGRFTEVWQlFVRkJMRTFCUVUwc1EwRkJRelpFTEZkQlFWQXNRMEZCYlVJc1JVRkJia0lzUlVGQmQwSXNRMEZCUXl4TlFVRkVMRU5CUVhoQ08wVkJRMEUzUkN4RlFVRkJRU3hOUVVGTkxFTkJRVU0yUkN4WFFVRlFMRU5CUVcxQ0xFVkJRVzVDTEVWQlFYZENMRU5CUVVNc1MwRkJSQ3hGUVVGUkxFMUJRVklzUTBGQmVFSTdSVUZEUVRkRUxFVkJRVUZCTEUxQlFVMHNRMEZCUXpaRUxGZEJRVkFzUTBGQmJVSXNSVUZCYmtJc1JVRkJkMElzUTBGQlF5eFBRVUZFTEVWQlFWVXNUMEZCVml4RFFVRjRRanRGUVVOQk4wUXNSVUZCUVVFc1RVRkJUU3hEUVVGRE5rUXNWMEZCVUN4RFFVRnRRaXhGUVVGdVFpeEZRVUYzUWl4RFFVRkRMRlZCUVVRc1EwRkJlRUk3UlVGRFFUZEVMRVZCUVVGQkxFMUJRVTBzUTBGQlF6WkVMRmRCUVZBc1EwRkJiVUlzUlVGQmJrSXNSVUZCZDBJc1EwRkJReXhSUVVGRUxFVkJRVmNzUzBGQldDeERRVUY0UWp0RlFVTkJOMFFzUlVGQlFVRXNUVUZCVFN4RFFVRkROa1FzVjBGQlVDeERRVUZ0UWl4RlFVRnVRaXhGUVVGM1FpeERRVUZETEU5QlFVUXNSVUZCVlN4VlFVRldMRU5CUVhoQ08wVkJRMEUzUkN4RlFVRkJRU3hOUVVGTkxFTkJRVU0yUkN4WFFVRlFMRU5CUVcxQ0xFVkJRVzVDTEVWQlFYZENMRU5CUVVNc1VVRkJSQ3hEUVVGNFFqdEZRVU5CTjBRc1JVRkJRVUVzVFVGQlRTeERRVUZETmtRc1YwRkJVQ3hEUVVGdFFpeEZRVUZ1UWl4RlFVRjNRaXhEUVVGRExGVkJRVVFzUTBGQmVFSTdSVUZEUVRkRUxFVkJRVUZCTEUxQlFVMHNRMEZCUXpaRUxGZEJRVkFzUTBGQmJVSXNSVUZCYmtJc1JVRkJkMElzUTBGQlF5eExRVUZFTEVOQlFYaENPMFZCUTBFM1JDeEZRVUZCUVN4TlFVRk5MRU5CUVVNMlJDeFhRVUZRTEVOQlFXMUNMRVZCUVc1Q0xFVkJRWGRDTEVOQlFVTXNUVUZCUkN4RFFVRjRRanRGUVVOQk4wUXNSVUZCUVVFc1RVRkJUU3hEUVVGRE5rUXNWMEZCVUN4RFFVRnRRaXhGUVVGdVFpeEZRVUYzUWl4RFFVRkRMRTFCUVVRc1EwRkJlRUk3UlVGRFFUZEVMRVZCUVVGQkxFMUJRVTBzUTBGQlF6WkVMRmRCUVZBc1EwRkJiVUlzUlVGQmJrSXNSVUZCZDBJc1EwRkJReXhKUVVGRUxFTkJRWGhDTzBWQlEwRTNSQ3hGUVVGQlFTeE5RVUZOTEVOQlFVTTJSQ3hYUVVGUUxFTkJRVzFDTEVWQlFXNUNMRVZCUVhkQ0xFTkJRVU1zVDBGQlJDeERRVUY0UWp0RlFVTkJOMFFzUlVGQlFVRXNUVUZCVFN4RFFVRkROa1FzVjBGQlVDeERRVUZ0UWl4RlFVRnVRaXhGUVVGM1FpeERRVUZETEUxQlFVUXNRMEZCZUVJN1JVRkRRVGRFTEVWQlFVRkJMRTFCUVUwc1EwRkJRelpFTEZkQlFWQXNRMEZCYlVJc1JVRkJia0lzUlVGQmQwSXNRMEZCUXl4UlFVRkVMRU5CUVhoQ08wVkJRMEUzUkN4RlFVRkJRU3hOUVVGTkxFTkJRVU0yUkN4WFFVRlFMRU5CUVcxQ0xFVkJRVzVDTEVWQlFYZENMRU5CUVVNc1lVRkJSQ3hEUVVGNFFqdEZRVU5CTjBRc1JVRkJRVUVzVFVGQlRTeERRVUZETmtRc1YwRkJVQ3hEUVVGdFFpeEZRVUZ1UWl4RlFVRjNRaXhEUVVGRExGTkJRVVFzUTBGQmVFSTdSVUZEUVRkRUxFVkJRVUZCTEUxQlFVMHNRMEZCUXpaRUxGZEJRVkFzUTBGQmJVSXNSVUZCYmtJc1JVRkJkMElzUTBGQlF5eFZRVUZFTEVOQlFYaENPMFZCUTBFM1JDeEZRVUZCUVN4TlFVRk5MRU5CUVVNMlJDeFhRVUZRTEVOQlFXMUNMRVZCUVc1Q0xFVkJRWGRDTEVOQlFVTXNVVUZCUkN4RlFVRlhMRXRCUVZnc1EwRkJlRUk3UlVGRFFUZEVMRVZCUVVGQkxFMUJRVTBzUTBGQlF6WkVMRmRCUVZBc1EwRkJiVUlzUlVGQmJrSXNSVUZCZDBJc1EwRkJReXhSUVVGRUxFVkJRVmNzUzBGQldDeERRVUY0UWp0RlFVTkJOMFFzUlVGQlFVRXNUVUZCVFN4RFFVRkROa1FzVjBGQlVDeERRVUZ0UWl4RlFVRnVRaXhGUVVGM1FpeERRVUZETEUxQlFVUXNRMEZCZUVJN1JVRkRRVGRFTEVWQlFVRkJMRTFCUVUwc1EwRkJRelpFTEZkQlFWQXNRMEZCYlVJc1IwRkJia0lzUlVGQmQwSXNRMEZCUXl4WlFVRkVMRVZCUVdVc1VVRkJaaXhEUVVGNFFqdEZRVU5CTjBRc1JVRkJRVUVzVFVGQlRTeERRVUZETmtRc1YwRkJVQ3hEUVVGdFFpeEhRVUZ1UWl4RlFVRjNRaXhEUVVGRExFOUJRVVFzUlVGQlZTeEhRVUZXTEVOQlFYaENPMFZCUTBFM1JDeEZRVUZCUVN4TlFVRk5MRU5CUVVNMlJDeFhRVUZRTEVOQlFXMUNMRWRCUVc1Q0xFVkJRWGRDTEVOQlFVTXNVVUZCUkN4RlFVRlhMRWRCUVZnc1EwRkJlRUk3UlVGRFFUZEVMRVZCUVVGQkxFMUJRVTBzUTBGQlF6WkVMRmRCUVZBc1EwRkJiVUlzUjBGQmJrSXNSVUZCZDBJc1EwRkJReXhQUVVGRUxFVkJRVlVzWTBGQlZpeEZRVUV3UWl4SFFVRXhRaXhEUVVGNFFqdEZRVU5CTjBRc1JVRkJRVUVzVFVGQlRTeERRVUZETmtRc1YwRkJVQ3hEUVVGdFFpeEhRVUZ1UWl4RlFVRjNRaXhEUVVGRExHRkJRVVFzUlVGQlowSXNSMEZCYUVJc1EwRkJlRUk3UlVGRFFUZEVMRVZCUVVGQkxFMUJRVTBzUTBGQlF6WkVMRmRCUVZBc1EwRkJiVUlzUjBGQmJrSXNSVUZCZDBJc1EwRkJReXhoUVVGRUxFVkJRV2RDTEVkQlFXaENMRU5CUVhoQ08wVkJRMEUzUkN4RlFVRkJRU3hOUVVGTkxFTkJRVU0yUkN4WFFVRlFMRU5CUVcxQ0xFZEJRVzVDTEVWQlFYZENMRU5CUVVNc1YwRkJSQ3hGUVVGakxFbEJRV1FzUTBGQmVFSTdSVUZEUVRkRUxFVkJRVUZCTEUxQlFVMHNRMEZCUXpaRUxGZEJRVkFzUTBGQmJVSXNSMEZCYmtJc1JVRkJkMElzUTBGQlF5eGpRVUZFTEVWQlFXbENMRWRCUVdwQ0xFTkJRWGhDTzBWQlEwRTNSQ3hGUVVGQlFTeE5RVUZOTEVOQlFVTTJSQ3hYUVVGUUxFTkJRVzFDTEVkQlFXNUNMRVZCUVhkQ0xFTkJRVU1zV1VGQlJDeEZRVUZsTEVsQlFXWXNRMEZCZUVJc1JVRjBRemhET3p0RlFYbERPVU0zUkN4RlFVRkJRU3hOUVVGTkxFTkJRVU0yUkN4WFFVRlFMRU5CUVcxQ0xFVkJRVzVDTEVWQlFYVkNMRU5CUVVNc1RVRkJSQ3hGUVVGVExFZEJRVlFzUTBGQmRrSTdSVUZEUVRkRUxFVkJRVUZCTEUxQlFVMHNRMEZCUXpaRUxGZEJRVkFzUTBGQmJVSXNSVUZCYmtJc1JVRkJkVUlzUTBGQlF5eExRVUZFTEVWQlFWRXNSMEZCVWl4RFFVRjJRanRGUVVOQk4wUXNSVUZCUVVFc1RVRkJUU3hEUVVGRE5rUXNWMEZCVUN4RFFVRnRRaXhGUVVGdVFpeEZRVUYxUWl4RFFVRkRMRXRCUVVRc1JVRkJVU3hIUVVGU0xFTkJRWFpDTzBWQlEwRTNSQ3hGUVVGQlFTeE5RVUZOTEVOQlFVTTJSQ3hYUVVGUUxFTkJRVzFDTEVWQlFXNUNMRVZCUVhWQ0xFTkJRVU1zVDBGQlJDeEZRVUZWTEVkQlFWWXNRMEZCZGtJN1JVRkRRVGRFTEVWQlFVRkJMRTFCUVUwc1EwRkJRelpFTEZkQlFWQXNRMEZCYlVJc1JVRkJia0lzUlVGQmRVSXNRMEZCUXl4TlFVRkVMRVZCUVZNc1IwRkJWQ3hEUVVGMlFqdEZRVU5CTjBRc1JVRkJRVUVzVFVGQlRTeERRVUZETmtRc1YwRkJVQ3hEUVVGdFFpeEZRVUZ1UWl4RlFVRjFRaXhEUVVGRExFMUJRVVFzUlVGQlV5eEhRVUZVTEVOQlFYWkNPMFZCUTBFM1JDeEZRVUZCUVN4TlFVRk5MRU5CUVVNMlJDeFhRVUZRTEVOQlFXMUNMRVZCUVc1Q0xFVkJRWFZDTEVOQlFVTXNTMEZCUkN4RlFVRlJMRWRCUVZJc1EwRkJka0k3UlVGRFFUZEVMRVZCUVVGQkxFMUJRVTBzUTBGQlF6WkVMRmRCUVZBc1EwRkJiVUlzUlVGQmJrSXNSVUZCZFVJc1EwRkJReXhQUVVGRUxFVkJRVlVzUjBGQlZpeERRVUYyUWp0RlFVTkJOMFFzUlVGQlFVRXNUVUZCVFN4RFFVRkROa1FzVjBGQlVDeERRVUZ0UWl4RlFVRnVRaXhGUVVGMVFpeERRVUZETEU5QlFVUXNSVUZCVlN4SFFVRldMRU5CUVhaQ08wVkJRMEUzUkN4RlFVRkJRU3hOUVVGTkxFTkJRVU0yUkN4WFFVRlFMRU5CUVcxQ0xFVkJRVzVDTEVWQlFYVkNMRU5CUVVNc1RVRkJSQ3hGUVVGVExFZEJRVlFzUTBGQmRrSXNSVUZzUkRoRE96dEZRWEZFT1VNM1JDeEZRVUZCUVN4TlFVRk5MRU5CUVVNMlJDeFhRVUZRTEVOQlFXMUNMRVZCUVc1Q0xFVkJRWFZDTEVOQlFVTXNVMEZCUkN4RlFVRlpMRTFCUVZvc1EwRkJka0k3UlVGRFFUZEVMRVZCUVVGQkxFMUJRVTBzUTBGQlF6WkVMRmRCUVZBc1EwRkJiVUlzUlVGQmJrSXNSVUZCZFVJc1EwRkJReXhSUVVGRUxFVkJRVmNzVFVGQldDeERRVUYyUWp0RlFVTkJOMFFzUlVGQlFVRXNUVUZCVFN4RFFVRkROa1FzVjBGQlVDeERRVUZ0UWl4RlFVRnVRaXhGUVVGMVFpeERRVUZETEZGQlFVUXNSVUZCVnl4TlFVRllMRU5CUVhaQ08wVkJRMEUzUkN4RlFVRkJRU3hOUVVGTkxFTkJRVU0yUkN4WFFVRlFMRU5CUVcxQ0xFVkJRVzVDTEVWQlFYVkNMRU5CUVVNc1ZVRkJSQ3hGUVVGaExFMUJRV0lzUTBGQmRrSTdSVUZEUVRkRUxFVkJRVUZCTEUxQlFVMHNRMEZCUXpaRUxGZEJRVkFzUTBGQmJVSXNSMEZCYmtJc1JVRkJkMElzUTBGQlF5eFRRVUZFTEVWQlFWa3NUVUZCV2l4RFFVRjRRanRGUVVOQk4wUXNSVUZCUVVFc1RVRkJUU3hEUVVGRE5rUXNWMEZCVUN4RFFVRnRRaXhIUVVGdVFpeEZRVUYzUWl4RFFVRkRMRk5CUVVRc1JVRkJXU3hOUVVGYUxFTkJRWGhDTzBWQlEwRTNSQ3hGUVVGQlFTeE5RVUZOTEVOQlFVTTJSQ3hYUVVGUUxFTkJRVzFDTEVkQlFXNUNMRVZCUVhkQ0xFTkJRVU1zVVVGQlJDeEZRVUZYTEUxQlFWZ3NRMEZCZUVJN1JVRkRRVGRFTEVWQlFVRkJMRTFCUVUwc1EwRkJRelpFTEZkQlFWQXNRMEZCYlVJc1IwRkJia0lzUlVGQmQwSXNRMEZCUXl4VlFVRkVMRVZCUVdFc1RVRkJZaXhEUVVGNFFqdEZRVU5CTjBRc1JVRkJRVUVzVFVGQlRTeERRVUZETmtRc1YwRkJVQ3hEUVVGdFFpeEhRVUZ1UWl4RlFVRjNRaXhEUVVGRExGVkJRVVFzUlVGQllTeE5RVUZpTEVOQlFYaENPMFZCUTBFM1JDeEZRVUZCUVN4TlFVRk5MRU5CUVVNMlJDeFhRVUZRTEVOQlFXMUNMRWRCUVc1Q0xFVkJRWGRDTEVOQlFVTXNVMEZCUkN4RlFVRlpMRTFCUVZvc1EwRkJlRUk3UlVGRFFUZEVMRVZCUVVGQkxFMUJRVTBzUTBGQlF6WkVMRmRCUVZBc1EwRkJiVUlzUjBGQmJrSXNSVUZCZDBJc1EwRkJReXhoUVVGRUxFVkJRV2RDTEUxQlFXaENMRU5CUVhoQ08wVkJRMEUzUkN4RlFVRkJRU3hOUVVGTkxFTkJRVU0yUkN4WFFVRlFMRU5CUVcxQ0xFZEJRVzVDTEVWQlFYZENMRU5CUVVNc1VVRkJSQ3hGUVVGWExFMUJRVmdzUTBGQmVFSTdSVUZEUVRkRUxFVkJRVUZCTEUxQlFVMHNRMEZCUXpaRUxGZEJRVkFzUTBGQmJVSXNSMEZCYmtJc1JVRkJkMElzUTBGQlF5eFZRVUZFTEVOQlFYaENPMFZCUTBFM1JDeEZRVUZCUVN4TlFVRk5MRU5CUVVNMlJDeFhRVUZRTEVOQlFXMUNMRWRCUVc1Q0xFVkJRWGRDTEVOQlFVTXNZVUZCUkN4RlFVRm5RaXhOUVVGb1FpeERRVUY0UWp0RlFVTkJOMFFzUlVGQlFVRXNUVUZCVFN4RFFVRkROa1FzVjBGQlVDeERRVUZ0UWl4SFFVRnVRaXhGUVVGM1FpeERRVUZETEZsQlFVUXNSVUZCWlN4TlFVRm1MRU5CUVhoQ08wVkJRMEUzUkN4RlFVRkJRU3hOUVVGTkxFTkJRVU0yUkN4WFFVRlFMRU5CUVcxQ0xFZEJRVzVDTEVWQlFYZENMRU5CUVVNc1YwRkJSQ3hGUVVGakxFMUJRV1FzUTBGQmVFSTdSVUZEUVRkRUxFVkJRVUZCTEUxQlFVMHNRMEZCUXpaRUxGZEJRVkFzUTBGQmJVSXNSMEZCYmtJc1JVRkJkMElzUTBGQlF5eFRRVUZFTEVWQlFWa3NTMEZCV2l4RFFVRjRRaXhGUVhKRk9FTTdPMFZCZDBVNVF6ZEVMRVZCUVVGQkxFMUJRVTBzUTBGQlF6WkVMRmRCUVZBc1EwRkJiVUlzUjBGQmJrSXNSVUZCZDBJc1EwRkJReXhKUVVGRUxFTkJRWGhDTzBWQlEwRTNSQ3hGUVVGQlFTeE5RVUZOTEVOQlFVTTJSQ3hYUVVGUUxFTkJRVzFDTEVkQlFXNUNMRVZCUVhkQ0xFTkJRVU1zU1VGQlJDeERRVUY0UWp0RlFVTkJOMFFzUlVGQlFVRXNUVUZCVFN4RFFVRkROa1FzVjBGQlVDeERRVUZ0UWl4SFFVRnVRaXhGUVVGM1FpeERRVUZETEVsQlFVUXNRMEZCZUVJN1JVRkRRVGRFTEVWQlFVRkJMRTFCUVUwc1EwRkJRelpFTEZkQlFWQXNRMEZCYlVJc1IwRkJia0lzUlVGQmQwSXNRMEZCUXl4SlFVRkVMRU5CUVhoQ08wVkJRMEUzUkN4RlFVRkJRU3hOUVVGTkxFTkJRVU0yUkN4WFFVRlFMRU5CUVcxQ0xFZEJRVzVDTEVWQlFYZENMRU5CUVVNc1NVRkJSQ3hEUVVGNFFqdEZRVU5CTjBRc1JVRkJRVUVzVFVGQlRTeERRVUZETmtRc1YwRkJVQ3hEUVVGdFFpeEhRVUZ1UWl4RlFVRjNRaXhEUVVGRExFbEJRVVFzUTBGQmVFSTdSVUZEUVRkRUxFVkJRVUZCTEUxQlFVMHNRMEZCUXpaRUxGZEJRVkFzUTBGQmJVSXNSMEZCYmtJc1JVRkJkMElzUTBGQlF5eEpRVUZFTEVOQlFYaENPMFZCUTBFM1JDeEZRVUZCUVN4TlFVRk5MRU5CUVVNMlJDeFhRVUZRTEVOQlFXMUNMRWRCUVc1Q0xFVkJRWGRDTEVOQlFVTXNTVUZCUkN4RFFVRjRRanRGUVVOQk4wUXNSVUZCUVVFc1RVRkJUU3hEUVVGRE5rUXNWMEZCVUN4RFFVRnRRaXhIUVVGdVFpeEZRVUYzUWl4RFFVRkRMRWxCUVVRc1EwRkJlRUk3UlVGRFFUZEVMRVZCUVVGQkxFMUJRVTBzUTBGQlF6WkVMRmRCUVZBc1EwRkJiVUlzUjBGQmJrSXNSVUZCZDBJc1EwRkJReXhMUVVGRUxFTkJRWGhDTzBWQlEwRTNSQ3hGUVVGQlFTeE5RVUZOTEVOQlFVTTJSQ3hYUVVGUUxFTkJRVzFDTEVkQlFXNUNMRVZCUVhkQ0xFTkJRVU1zUzBGQlJDeERRVUY0UWp0RlFVTkJOMFFzUlVGQlFVRXNUVUZCVFN4RFFVRkROa1FzVjBGQlVDeERRVUZ0UWl4SFFVRnVRaXhGUVVGM1FpeERRVUZETEV0QlFVUXNRMEZCZUVJN1JVRkRRVGRFTEVWQlFVRkJMRTFCUVUwc1EwRkJRelpFTEZkQlFWQXNRMEZCYlVJc1IwRkJia0lzUlVGQmQwSXNRMEZCUXl4TFFVRkVMRU5CUVhoQ08wVkJRMEUzUkN4RlFVRkJRU3hOUVVGTkxFTkJRVU0yUkN4WFFVRlFMRU5CUVcxQ0xFZEJRVzVDTEVWQlFYZENMRU5CUVVNc1MwRkJSQ3hEUVVGNFFqdEZRVU5CTjBRc1JVRkJRVUVzVFVGQlRTeERRVUZETmtRc1YwRkJVQ3hEUVVGdFFpeEhRVUZ1UWl4RlFVRjNRaXhEUVVGRExFdEJRVVFzUTBGQmVFSTdSVUZEUVRkRUxFVkJRVUZCTEUxQlFVMHNRMEZCUXpaRUxGZEJRVkFzUTBGQmJVSXNSMEZCYmtJc1JVRkJkMElzUTBGQlF5eExRVUZFTEVOQlFYaENPMFZCUTBFM1JDeEZRVUZCUVN4TlFVRk5MRU5CUVVNMlJDeFhRVUZRTEVOQlFXMUNMRWRCUVc1Q0xFVkJRWGRDTEVOQlFVTXNTMEZCUkN4RFFVRjRRanRGUVVOQk4wUXNSVUZCUVVFc1RVRkJUU3hEUVVGRE5rUXNWMEZCVUN4RFFVRnRRaXhIUVVGdVFpeEZRVUYzUWl4RFFVRkRMRXRCUVVRc1EwRkJlRUk3UlVGRFFUZEVMRVZCUVVGQkxFMUJRVTBzUTBGQlF6WkVMRmRCUVZBc1EwRkJiVUlzUjBGQmJrSXNSVUZCZDBJc1EwRkJReXhMUVVGRUxFTkJRWGhDTzBWQlEwRTNSQ3hGUVVGQlFTeE5RVUZOTEVOQlFVTTJSQ3hYUVVGUUxFTkJRVzFDTEVkQlFXNUNMRVZCUVhkQ0xFTkJRVU1zUzBGQlJDeERRVUY0UWp0RlFVTkJOMFFzUlVGQlFVRXNUVUZCVFN4RFFVRkROa1FzVjBGQlVDeERRVUZ0UWl4SFFVRnVRaXhGUVVGM1FpeERRVUZETEV0QlFVUXNRMEZCZUVJN1JVRkRRVGRFTEVWQlFVRkJMRTFCUVUwc1EwRkJRelpFTEZkQlFWQXNRMEZCYlVJc1IwRkJia0lzUlVGQmQwSXNRMEZCUXl4TFFVRkVMRU5CUVhoQ08wVkJRMEUzUkN4RlFVRkJRU3hOUVVGTkxFTkJRVU0yUkN4WFFVRlFMRU5CUVcxQ0xFZEJRVzVDTEVWQlFYZENMRU5CUVVNc1MwRkJSQ3hEUVVGNFFqdEZRVU5CTjBRc1JVRkJRVUVzVFVGQlRTeERRVUZETmtRc1YwRkJVQ3hEUVVGdFFpeEhRVUZ1UWl4RlFVRjNRaXhEUVVGRExFdEJRVVFzUTBGQmVFSXNSVUV2UmpoRE96dEZRV3RIT1VNM1JDeEZRVUZCUVN4TlFVRk5MRU5CUVVNNFJDeFRRVUZRTEVOQlFXbENMRmRCUVdwQ0xFVkJRVGhDTEVOQlFVTXNUMEZCUkN4RlFVRlZMRWRCUVZZc1EwRkJPVUk3UlVGRFFUbEVMRVZCUVVGQkxFMUJRVTBzUTBGQlF6aEVMRk5CUVZBc1EwRkJhVUlzVjBGQmFrSXNSVUZCT0VJc1EwRkJReXhoUVVGRUxFVkJRV2RDTEd0Q1FVRm9RaXhGUVVGdlF5eEhRVUZ3UXl4RFFVRTVRanRGUVVOQk9VUXNSVUZCUVVFc1RVRkJUU3hEUVVGRE9FUXNVMEZCVUN4RFFVRnBRaXhYUVVGcVFpeEZRVUU0UWl4RFFVRkRMRWxCUVVRc1JVRkJUeXhIUVVGUUxFTkJRVGxDTzBWQlEwRTVSQ3hGUVVGQlFTeE5RVUZOTEVOQlFVTTRSQ3hUUVVGUUxFTkJRV2xDTEZkQlFXcENMRVZCUVRoQ0xFTkJRVU1zVVVGQlJDeEZRVUZYTEVkQlFWZ3NRMEZCT1VJN1JVRkRRVGxFTEVWQlFVRkJMRTFCUVUwc1EwRkJRemhFTEZOQlFWQXNRMEZCYVVJc1YwRkJha0lzUlVGQk9FSXNRMEZCUXl4UlFVRkVMRVZCUVZjc1UwRkJXQ3hGUVVGelFpeFpRVUYwUWl4RlFVRnZReXhIUVVGd1F5eERRVUU1UWp0RlFVTkJPVVFzUlVGQlFVRXNUVUZCVFN4RFFVRkRPRVFzVTBGQlVDeERRVUZwUWl4WFFVRnFRaXhGUVVFNFFpeERRVUZETEZOQlFVUXNSVUZCV1N4SFFVRmFMRU5CUVRsQ08wVkJRMEU1UkN4RlFVRkJRU3hOUVVGTkxFTkJRVU00UkN4VFFVRlFMRU5CUVdsQ0xGZEJRV3BDTEVWQlFUaENMRU5CUVVNc1QwRkJSQ3hGUVVGVkxFZEJRVllzUTBGQk9VSTdSVUZEUVRsRUxFVkJRVUZCTEUxQlFVMHNRMEZCUXpoRUxGTkJRVkFzUTBGQmFVSXNWMEZCYWtJc1JVRkJPRUlzUTBGQlF5eFhRVUZFTEVWQlFXTXNTMEZCWkN4RlFVRnhRaXhIUVVGeVFpeERRVUU1UWp0RlFVTkJPVVFzUlVGQlFVRXNUVUZCVFN4RFFVRkRPRVFzVTBGQlVDeERRVUZwUWl4WFFVRnFRaXhGUVVFNFFpeERRVUZETEZWQlFVUXNSVUZCWVN4SFFVRmlMRU5CUVRsQ08wVkJRMEU1UkN4RlFVRkJRU3hOUVVGTkxFTkJRVU00UkN4VFFVRlFMRU5CUVdsQ0xGZEJRV3BDTEVWQlFUaENMRU5CUVVNc1YwRkJSQ3hGUVVGakxFZEJRV1FzUTBGQk9VSTdSVUZEUVRsRUxFVkJRVUZCTEUxQlFVMHNRMEZCUXpoRUxGTkJRVkFzUTBGQmFVSXNWMEZCYWtJc1JVRkJPRUlzUTBGQlF5eFpRVUZFTEVWQlFXVXNSMEZCWml4RFFVRTVRanRGUVVOQk9VUXNSVUZCUVVFc1RVRkJUU3hEUVVGRE9FUXNVMEZCVUN4RFFVRnBRaXhYUVVGcVFpeEZRVUU0UWl4RFFVRkRMRmxCUVVRc1JVRkJaU3hIUVVGbUxFTkJRVGxDTzBWQlEwRTVSQ3hGUVVGQlFTeE5RVUZOTEVOQlFVTTRSQ3hUUVVGUUxFTkJRV2xDTEZkQlFXcENMRVZCUVRoQ0xFTkJRVU1zVFVGQlJDeEZRVUZUTEVkQlFWUXNRMEZCT1VJN1JVRkRRVGxFTEVWQlFVRkJMRTFCUVUwc1EwRkJRemhFTEZOQlFWQXNRMEZCYVVJc1YwRkJha0lzUlVGQk9FSXNRMEZCUXl4blFrRkJSQ3hGUVVGdFFpeHJRa0ZCYmtJc1JVRkJkVU1zUjBGQmRrTXNRMEZCT1VJN1JVRkRRVGxFTEVWQlFVRkJMRTFCUVUwc1EwRkJRemhFTEZOQlFWQXNRMEZCYVVJc1YwRkJha0lzUlVGQk9FSXNRMEZCUXl4cFFrRkJSQ3hGUVVGdlFpeHRRa0ZCY0VJc1JVRkJlVU1zUjBGQmVrTXNRMEZCT1VJN1JVRkRRVGxFTEVWQlFVRkJMRTFCUVUwc1EwRkJRemhFTEZOQlFWQXNRMEZCYVVJc1dVRkJha0lzUlVGQkswSXNRMEZCUXl4aFFVRkVMRVZCUVdkQ0xFZEJRV2hDTEVOQlFTOUNPMFZCUTBFNVJDeEZRVUZCUVN4TlFVRk5MRU5CUVVNNFJDeFRRVUZRTEVOQlFXbENMRmRCUVdwQ0xFVkJRVGhDTEVOQlFVTXNUMEZCUkN4RlFVRlZMRWRCUVZZc1EwRkJPVUk3UlVGRFFUbEVMRVZCUVVGQkxFMUJRVTBzUTBGQlF6aEVMRk5CUVZBc1EwRkJhVUlzV1VGQmFrSXNSVUZCSzBJc1EwRkJReXhsUVVGRUxFVkJRV3RDTEVsQlFXeENMRU5CUVM5Q08wVkJRMEU1UkN4RlFVRkJRU3hOUVVGTkxFTkJRVU00UkN4VFFVRlFMRU5CUVdsQ0xGbEJRV3BDTEVWQlFTdENMRU5CUVVNc2EwSkJRVVFzUlVGQmNVSXNSMEZCY2tJc1EwRkJMMEk3UlVGRFFUbEVMRVZCUVVGQkxFMUJRVTBzUTBGQlF6aEVMRk5CUVZBc1EwRkJhVUlzVjBGQmFrSXNSVUZCT0VJc1EwRkJReXh0UWtGQlJDeEZRVUZ6UWl4SFFVRjBRaXhEUVVFNVFqdEZRVU5CT1VRc1JVRkJRVUVzVFVGQlRTeERRVUZET0VRc1UwRkJVQ3hEUVVGcFFpeFhRVUZxUWl4RlFVRTRRaXhEUVVGRExHTkJRVVFzUlVGQmFVSXNSMEZCYWtJc1EwRkJPVUk3TzBWQlJVRXNUVUZCU1RkQ0xGRkJRVkVzUTBGQlF6QkNMRXRCUVZRc1EwRkJaU3hMUVVGbUxFTkJRVW9zUlVGQk1rSTdSVUZEZWtJelJDeEpRVUZCUVN4TlFVRk5MRU5CUVVNNFJDeFRRVUZRTEVOQlFXbENMRk5CUVdwQ0xFVkJRVFJDTEVOQlFVTXNTMEZCUkN4RlFVRlJMRlZCUVZJc1EwRkJOVUk3UlVGRFJDeEhRVVpFTEUxQlJVODdSVUZEVERsRUxFbEJRVUZCTEUxQlFVMHNRMEZCUXpoRUxGTkJRVkFzUTBGQmFVSXNUVUZCYWtJc1JVRkJlVUlzUTBGQlF5eExRVUZFTEVWQlFWRXNWVUZCVWl4RFFVRjZRanRGUVVORUxFZEJOVWcyUXpzN08wVkJLMGc1UXl4UFFVRkxMRWxCUVVseVJ5eFBRVUZQTEVkQlFVY3NSVUZCYmtJc1JVRkJkVUpCTEU5QlFVOHNTVUZCU1N4RlFVRnNReXhGUVVGelEwRXNUMEZCVHl4SlFVRkpMRU5CUVdwRUxFVkJRVzlFTzBWQlEyeEVMRkZCUVVrM1FpeFBRVUZQTEVkQlFVZHRTU3hOUVVGTkxFTkJRVU5ETEZsQlFWQXNRMEZCYjBKMlJ5eFBRVUZQTEVkQlFVY3NSVUZCT1VJc1EwRkJaRHRGUVVOQkxGRkJRVWwzUnl4alFVRmpMRWRCUVVkR0xFMUJRVTBzUTBGQlEwTXNXVUZCVUN4RFFVRnZRblpITEU5QlFYQkNMRU5CUVhKQ08wVkJRMFIxUXl4SlFVRkJRU3hOUVVGTkxFTkJRVU0yUkN4WFFVRlFMRU5CUVcxQ2NFY3NUMEZCYmtJc1JVRkJORUkzUWl4UFFVRTFRanRGUVVOQmIwVXNTVUZCUVVFc1RVRkJUU3hEUVVGRE9FUXNVMEZCVUN4RFFVRnBRaXhoUVVGaGJFa3NUMEZCT1VJc1JVRkJkVU54U1N4alFVRjJRenRGUVVOQmFrVXNTVUZCUVVFc1RVRkJUU3hEUVVGRE9FUXNVMEZCVUN4RFFVRnBRaXhuUWtGQlowSnNTU3hQUVVGcVF5eEZRVUV3UTNGSkxHTkJRVEZETzBWQlEwRXNSMEZ5U1RaRE96czdSVUYzU1RsRExFMUJRVTFETEdkQ1FVRm5RaXhIUVVGSGJrTXNVMEZCVXl4RFFVRkRORUlzUzBGQlZpeERRVUZuUWl4VFFVRm9RaXhKUVVFMlFpeEZRVUUzUWl4SFFVRnRReXhIUVVFMVJEdEZRVU5CTEUxQlFVMVJMRmRCUVZjc1IwRkJVWEJETEZOQlFWTXNRMEZCUXpSQ0xFdEJRVllzUTBGQlowSXNVMEZCYUVJc1NVRkJOa0lzUjBGQk4wSXNSMEZCYlVNc1IwRkJOVVE3UlVGRFFTeE5RVUZOVXl4WlFVRlpMRWRCUVU5eVF5eFRRVUZUTEVOQlFVTTBRaXhMUVVGV0xFTkJRV2RDTEZOQlFXaENMRWxCUVRaQ0xFVkJRVGRDTEVkQlFXMURMRWRCUVRWRU8wVkJRMEVzVFVGQlNWVXNhMEpCUVVvN1JVRkRRU3hOUVVGSlF5eHRRa0ZCU2pzN1JVRkRRU3hOUVVGSmNrTXNVVUZCVVN4RFFVRkRNRUlzUzBGQlZDeERRVUZsTEV0QlFXWXNUVUZCTUVJMVFpeFRRVUZUTEVOQlFVTTBRaXhMUVVGV0xFTkJRV2RDTEZGQlFXaENMRXRCUVRaQ05VSXNVMEZCVXl4RFFVRkRORUlzUzBGQlZpeERRVUZuUWl4UlFVRm9RaXhEUVVGMlJDeERRVUZLTEVWQlFYVkdPMFZCUTNKR1ZTeEpRVUZCUVN4clFrRkJhMElzUjBGQlNTeEZRVUYwUWp0RlFVTkJReXhKUVVGQlFTeHRRa0ZCYlVJc1IwRkJSeXhGUVVGMFFqdEZRVU5FTEVkQlNFUXNUVUZIVHl4SlFVRkhja01zVVVGQlVTeERRVUZETUVJc1MwRkJWQ3hEUVVGbExFdEJRV1lzUzBGQmVVSTFRaXhUUVVGVExFTkJRVU0wUWl4TFFVRldMRU5CUVdkQ0xFOUJRV2hDTEVOQlFUVkNMRVZCUVhORU8wVkJRek5FVlN4SlFVRkJRU3hyUWtGQmEwSXNSMEZCU1N4RlFVRjBRanRGUVVOQlF5eEpRVUZCUVN4dFFrRkJiVUlzUjBGQlJ5eEZRVUYwUWp0RlFVTkVMRWRCU0Uwc1RVRkhRU3hKUVVGSGNrTXNVVUZCVVN4RFFVRkRNRUlzUzBGQlZDeERRVUZsTEV0QlFXWXNTMEZCZVVJMVFpeFRRVUZUTEVOQlFVTTBRaXhMUVVGV0xFTkJRV2RDTEZOQlFXaENMRU5CUVRWQ0xFVkJRWGRFTzBWQlF6ZEVWU3hKUVVGQlFTeHJRa0ZCYTBJc1IwRkJTU3hIUVVGMFFqdEZRVU5CUXl4SlFVRkJRU3h0UWtGQmJVSXNSMEZCUnl4SFFVRjBRanRGUVVORU96dEZRVU5FZEVVc1JVRkJRVUVzVFVGQlRTeERRVUZETmtRc1YwRkJVQ3hEUVVGdFFrc3NaMEpCUVc1Q0xFVkJRWGRETEVOQlFVTXNWMEZCUkN4RlFVRmpMRWRCUVdRc1EwRkJlRU03UlVGRFFXeEZMRVZCUVVGQkxFMUJRVTBzUTBGQlF6WkVMRmRCUVZBc1EwRkJiVUpOTEZkQlFXNUNMRVZCUVhkRExFTkJRVU1zVFVGQlJDeEZRVUZUTEVkQlFWUXNRMEZCZUVNN1JVRkRRVzVGTEVWQlFVRkJMRTFCUVUwc1EwRkJRelpFTEZkQlFWQXNRMEZCYlVKUExGbEJRVzVDTEVWQlFYZERMRU5CUVVNc1QwRkJSQ3hGUVVGVkxGZEJRVllzUlVGQmRVSXNSMEZCZGtJc1EwRkJlRU03UlVGRFFYQkZMRVZCUVVGQkxFMUJRVTBzUTBGQlF6WkVMRmRCUVZBc1EwRkJiVUpSTEd0Q1FVRnVRaXhGUVVGM1F5eERRVUZETEZOQlFVUXNSVUZCV1N4VFFVRmFMRVZCUVhWQ0xFdEJRWFpDTEVWQlFUaENMRTlCUVRsQ0xFVkJRWFZETEdGQlFYWkRMRVZCUVhORUxHRkJRWFJFTEVWQlFYRkZMRk5CUVhKRkxFVkJRV2RHTEZkQlFXaEdMRU5CUVhoRE8wVkJRMEZ5UlN4RlFVRkJRU3hOUVVGTkxFTkJRVU0yUkN4WFFVRlFMRU5CUVcxQ1V5eHRRa0ZCYmtJc1JVRkJkME1zUTBGQlF5eFRRVUZFTEVWQlFWa3NVMEZCV2l4RlFVRjFRaXhMUVVGMlFpeEZRVUU0UWl4UFFVRTVRaXhGUVVGMVF5eGpRVUYyUXl4RlFVRjFSQ3hqUVVGMlJDeEZRVUYxUlN4VlFVRjJSU3hGUVVGdFJpeFpRVUZ1Uml4RFFVRjRReXhGUVROS09FTTdPMFZCT0VvNVEzUkZMRVZCUVVGQkxFMUJRVTBzUTBGQlEycERMRlZCUVZBc1EwRkJhMElzVTBGQmJFSTdSVUZEUkRzN1RVTXpTa3QzUnl4UlFVRlJMRWRCUVVjc1NVRkJTUzlHTEZGQlFVbzdSVUZGYWtJclJpeFJRVUZSTEVOQlFVTkRMRk5CUVZRc1EwRkJiVUlzU1VGQmJrSXNSVUZCZVVKYUxFVkJRWHBDTzBWQlJVRlhMRkZCUVZFc1EwRkJReTlHTEZGQlFWUXNSMEZCYjBKQkxGRkJRWEJDTzBWQlEwRXJSaXhSUVVGUkxFTkJRVU4yU0N4TlFVRlVMRWRCUVd0Q1FTeE5RVUZzUWp0RlFVTkJkVWdzVVVGQlVTeERRVUZETDBvc1VVRkJWQ3hIUVVGdlFrRXNVVUZCY0VJN096czdPenM3T3lKOVxuIiwiLyoqXG4gKiBAbGljZW5zZVxuICogTG9kYXNoIDxodHRwczovL2xvZGFzaC5jb20vPlxuICogQ29weXJpZ2h0IE9wZW5KUyBGb3VuZGF0aW9uIGFuZCBvdGhlciBjb250cmlidXRvcnMgPGh0dHBzOi8vb3BlbmpzZi5vcmcvPlxuICogUmVsZWFzZWQgdW5kZXIgTUlUIGxpY2Vuc2UgPGh0dHBzOi8vbG9kYXNoLmNvbS9saWNlbnNlPlxuICogQmFzZWQgb24gVW5kZXJzY29yZS5qcyAxLjguMyA8aHR0cDovL3VuZGVyc2NvcmVqcy5vcmcvTElDRU5TRT5cbiAqIENvcHlyaWdodCBKZXJlbXkgQXNoa2VuYXMsIERvY3VtZW50Q2xvdWQgYW5kIEludmVzdGlnYXRpdmUgUmVwb3J0ZXJzICYgRWRpdG9yc1xuICovXG47KGZ1bmN0aW9uKCkge1xuXG4gIC8qKiBVc2VkIGFzIGEgc2FmZSByZWZlcmVuY2UgZm9yIGB1bmRlZmluZWRgIGluIHByZS1FUzUgZW52aXJvbm1lbnRzLiAqL1xuICB2YXIgdW5kZWZpbmVkO1xuXG4gIC8qKiBVc2VkIGFzIHRoZSBzZW1hbnRpYyB2ZXJzaW9uIG51bWJlci4gKi9cbiAgdmFyIFZFUlNJT04gPSAnNC4xNy4yMSc7XG5cbiAgLyoqIFVzZWQgYXMgdGhlIHNpemUgdG8gZW5hYmxlIGxhcmdlIGFycmF5IG9wdGltaXphdGlvbnMuICovXG4gIHZhciBMQVJHRV9BUlJBWV9TSVpFID0gMjAwO1xuXG4gIC8qKiBFcnJvciBtZXNzYWdlIGNvbnN0YW50cy4gKi9cbiAgdmFyIENPUkVfRVJST1JfVEVYVCA9ICdVbnN1cHBvcnRlZCBjb3JlLWpzIHVzZS4gVHJ5IGh0dHBzOi8vbnBtcy5pby9zZWFyY2g/cT1wb255ZmlsbC4nLFxuICAgICAgRlVOQ19FUlJPUl9URVhUID0gJ0V4cGVjdGVkIGEgZnVuY3Rpb24nLFxuICAgICAgSU5WQUxJRF9URU1QTF9WQVJfRVJST1JfVEVYVCA9ICdJbnZhbGlkIGB2YXJpYWJsZWAgb3B0aW9uIHBhc3NlZCBpbnRvIGBfLnRlbXBsYXRlYCc7XG5cbiAgLyoqIFVzZWQgdG8gc3RhbmQtaW4gZm9yIGB1bmRlZmluZWRgIGhhc2ggdmFsdWVzLiAqL1xuICB2YXIgSEFTSF9VTkRFRklORUQgPSAnX19sb2Rhc2hfaGFzaF91bmRlZmluZWRfXyc7XG5cbiAgLyoqIFVzZWQgYXMgdGhlIG1heGltdW0gbWVtb2l6ZSBjYWNoZSBzaXplLiAqL1xuICB2YXIgTUFYX01FTU9JWkVfU0laRSA9IDUwMDtcblxuICAvKiogVXNlZCBhcyB0aGUgaW50ZXJuYWwgYXJndW1lbnQgcGxhY2Vob2xkZXIuICovXG4gIHZhciBQTEFDRUhPTERFUiA9ICdfX2xvZGFzaF9wbGFjZWhvbGRlcl9fJztcblxuICAvKiogVXNlZCB0byBjb21wb3NlIGJpdG1hc2tzIGZvciBjbG9uaW5nLiAqL1xuICB2YXIgQ0xPTkVfREVFUF9GTEFHID0gMSxcbiAgICAgIENMT05FX0ZMQVRfRkxBRyA9IDIsXG4gICAgICBDTE9ORV9TWU1CT0xTX0ZMQUcgPSA0O1xuXG4gIC8qKiBVc2VkIHRvIGNvbXBvc2UgYml0bWFza3MgZm9yIHZhbHVlIGNvbXBhcmlzb25zLiAqL1xuICB2YXIgQ09NUEFSRV9QQVJUSUFMX0ZMQUcgPSAxLFxuICAgICAgQ09NUEFSRV9VTk9SREVSRURfRkxBRyA9IDI7XG5cbiAgLyoqIFVzZWQgdG8gY29tcG9zZSBiaXRtYXNrcyBmb3IgZnVuY3Rpb24gbWV0YWRhdGEuICovXG4gIHZhciBXUkFQX0JJTkRfRkxBRyA9IDEsXG4gICAgICBXUkFQX0JJTkRfS0VZX0ZMQUcgPSAyLFxuICAgICAgV1JBUF9DVVJSWV9CT1VORF9GTEFHID0gNCxcbiAgICAgIFdSQVBfQ1VSUllfRkxBRyA9IDgsXG4gICAgICBXUkFQX0NVUlJZX1JJR0hUX0ZMQUcgPSAxNixcbiAgICAgIFdSQVBfUEFSVElBTF9GTEFHID0gMzIsXG4gICAgICBXUkFQX1BBUlRJQUxfUklHSFRfRkxBRyA9IDY0LFxuICAgICAgV1JBUF9BUllfRkxBRyA9IDEyOCxcbiAgICAgIFdSQVBfUkVBUkdfRkxBRyA9IDI1NixcbiAgICAgIFdSQVBfRkxJUF9GTEFHID0gNTEyO1xuXG4gIC8qKiBVc2VkIGFzIGRlZmF1bHQgb3B0aW9ucyBmb3IgYF8udHJ1bmNhdGVgLiAqL1xuICB2YXIgREVGQVVMVF9UUlVOQ19MRU5HVEggPSAzMCxcbiAgICAgIERFRkFVTFRfVFJVTkNfT01JU1NJT04gPSAnLi4uJztcblxuICAvKiogVXNlZCB0byBkZXRlY3QgaG90IGZ1bmN0aW9ucyBieSBudW1iZXIgb2YgY2FsbHMgd2l0aGluIGEgc3BhbiBvZiBtaWxsaXNlY29uZHMuICovXG4gIHZhciBIT1RfQ09VTlQgPSA4MDAsXG4gICAgICBIT1RfU1BBTiA9IDE2O1xuXG4gIC8qKiBVc2VkIHRvIGluZGljYXRlIHRoZSB0eXBlIG9mIGxhenkgaXRlcmF0ZWVzLiAqL1xuICB2YXIgTEFaWV9GSUxURVJfRkxBRyA9IDEsXG4gICAgICBMQVpZX01BUF9GTEFHID0gMixcbiAgICAgIExBWllfV0hJTEVfRkxBRyA9IDM7XG5cbiAgLyoqIFVzZWQgYXMgcmVmZXJlbmNlcyBmb3IgdmFyaW91cyBgTnVtYmVyYCBjb25zdGFudHMuICovXG4gIHZhciBJTkZJTklUWSA9IDEgLyAwLFxuICAgICAgTUFYX1NBRkVfSU5URUdFUiA9IDkwMDcxOTkyNTQ3NDA5OTEsXG4gICAgICBNQVhfSU5URUdFUiA9IDEuNzk3NjkzMTM0ODYyMzE1N2UrMzA4LFxuICAgICAgTkFOID0gMCAvIDA7XG5cbiAgLyoqIFVzZWQgYXMgcmVmZXJlbmNlcyBmb3IgdGhlIG1heGltdW0gbGVuZ3RoIGFuZCBpbmRleCBvZiBhbiBhcnJheS4gKi9cbiAgdmFyIE1BWF9BUlJBWV9MRU5HVEggPSA0Mjk0OTY3Mjk1LFxuICAgICAgTUFYX0FSUkFZX0lOREVYID0gTUFYX0FSUkFZX0xFTkdUSCAtIDEsXG4gICAgICBIQUxGX01BWF9BUlJBWV9MRU5HVEggPSBNQVhfQVJSQVlfTEVOR1RIID4+PiAxO1xuXG4gIC8qKiBVc2VkIHRvIGFzc29jaWF0ZSB3cmFwIG1ldGhvZHMgd2l0aCB0aGVpciBiaXQgZmxhZ3MuICovXG4gIHZhciB3cmFwRmxhZ3MgPSBbXG4gICAgWydhcnknLCBXUkFQX0FSWV9GTEFHXSxcbiAgICBbJ2JpbmQnLCBXUkFQX0JJTkRfRkxBR10sXG4gICAgWydiaW5kS2V5JywgV1JBUF9CSU5EX0tFWV9GTEFHXSxcbiAgICBbJ2N1cnJ5JywgV1JBUF9DVVJSWV9GTEFHXSxcbiAgICBbJ2N1cnJ5UmlnaHQnLCBXUkFQX0NVUlJZX1JJR0hUX0ZMQUddLFxuICAgIFsnZmxpcCcsIFdSQVBfRkxJUF9GTEFHXSxcbiAgICBbJ3BhcnRpYWwnLCBXUkFQX1BBUlRJQUxfRkxBR10sXG4gICAgWydwYXJ0aWFsUmlnaHQnLCBXUkFQX1BBUlRJQUxfUklHSFRfRkxBR10sXG4gICAgWydyZWFyZycsIFdSQVBfUkVBUkdfRkxBR11cbiAgXTtcblxuICAvKiogYE9iamVjdCN0b1N0cmluZ2AgcmVzdWx0IHJlZmVyZW5jZXMuICovXG4gIHZhciBhcmdzVGFnID0gJ1tvYmplY3QgQXJndW1lbnRzXScsXG4gICAgICBhcnJheVRhZyA9ICdbb2JqZWN0IEFycmF5XScsXG4gICAgICBhc3luY1RhZyA9ICdbb2JqZWN0IEFzeW5jRnVuY3Rpb25dJyxcbiAgICAgIGJvb2xUYWcgPSAnW29iamVjdCBCb29sZWFuXScsXG4gICAgICBkYXRlVGFnID0gJ1tvYmplY3QgRGF0ZV0nLFxuICAgICAgZG9tRXhjVGFnID0gJ1tvYmplY3QgRE9NRXhjZXB0aW9uXScsXG4gICAgICBlcnJvclRhZyA9ICdbb2JqZWN0IEVycm9yXScsXG4gICAgICBmdW5jVGFnID0gJ1tvYmplY3QgRnVuY3Rpb25dJyxcbiAgICAgIGdlblRhZyA9ICdbb2JqZWN0IEdlbmVyYXRvckZ1bmN0aW9uXScsXG4gICAgICBtYXBUYWcgPSAnW29iamVjdCBNYXBdJyxcbiAgICAgIG51bWJlclRhZyA9ICdbb2JqZWN0IE51bWJlcl0nLFxuICAgICAgbnVsbFRhZyA9ICdbb2JqZWN0IE51bGxdJyxcbiAgICAgIG9iamVjdFRhZyA9ICdbb2JqZWN0IE9iamVjdF0nLFxuICAgICAgcHJvbWlzZVRhZyA9ICdbb2JqZWN0IFByb21pc2VdJyxcbiAgICAgIHByb3h5VGFnID0gJ1tvYmplY3QgUHJveHldJyxcbiAgICAgIHJlZ2V4cFRhZyA9ICdbb2JqZWN0IFJlZ0V4cF0nLFxuICAgICAgc2V0VGFnID0gJ1tvYmplY3QgU2V0XScsXG4gICAgICBzdHJpbmdUYWcgPSAnW29iamVjdCBTdHJpbmddJyxcbiAgICAgIHN5bWJvbFRhZyA9ICdbb2JqZWN0IFN5bWJvbF0nLFxuICAgICAgdW5kZWZpbmVkVGFnID0gJ1tvYmplY3QgVW5kZWZpbmVkXScsXG4gICAgICB3ZWFrTWFwVGFnID0gJ1tvYmplY3QgV2Vha01hcF0nLFxuICAgICAgd2Vha1NldFRhZyA9ICdbb2JqZWN0IFdlYWtTZXRdJztcblxuICB2YXIgYXJyYXlCdWZmZXJUYWcgPSAnW29iamVjdCBBcnJheUJ1ZmZlcl0nLFxuICAgICAgZGF0YVZpZXdUYWcgPSAnW29iamVjdCBEYXRhVmlld10nLFxuICAgICAgZmxvYXQzMlRhZyA9ICdbb2JqZWN0IEZsb2F0MzJBcnJheV0nLFxuICAgICAgZmxvYXQ2NFRhZyA9ICdbb2JqZWN0IEZsb2F0NjRBcnJheV0nLFxuICAgICAgaW50OFRhZyA9ICdbb2JqZWN0IEludDhBcnJheV0nLFxuICAgICAgaW50MTZUYWcgPSAnW29iamVjdCBJbnQxNkFycmF5XScsXG4gICAgICBpbnQzMlRhZyA9ICdbb2JqZWN0IEludDMyQXJyYXldJyxcbiAgICAgIHVpbnQ4VGFnID0gJ1tvYmplY3QgVWludDhBcnJheV0nLFxuICAgICAgdWludDhDbGFtcGVkVGFnID0gJ1tvYmplY3QgVWludDhDbGFtcGVkQXJyYXldJyxcbiAgICAgIHVpbnQxNlRhZyA9ICdbb2JqZWN0IFVpbnQxNkFycmF5XScsXG4gICAgICB1aW50MzJUYWcgPSAnW29iamVjdCBVaW50MzJBcnJheV0nO1xuXG4gIC8qKiBVc2VkIHRvIG1hdGNoIGVtcHR5IHN0cmluZyBsaXRlcmFscyBpbiBjb21waWxlZCB0ZW1wbGF0ZSBzb3VyY2UuICovXG4gIHZhciByZUVtcHR5U3RyaW5nTGVhZGluZyA9IC9cXGJfX3AgXFwrPSAnJzsvZyxcbiAgICAgIHJlRW1wdHlTdHJpbmdNaWRkbGUgPSAvXFxiKF9fcCBcXCs9KSAnJyBcXCsvZyxcbiAgICAgIHJlRW1wdHlTdHJpbmdUcmFpbGluZyA9IC8oX19lXFwoLio/XFwpfFxcYl9fdFxcKSkgXFwrXFxuJyc7L2c7XG5cbiAgLyoqIFVzZWQgdG8gbWF0Y2ggSFRNTCBlbnRpdGllcyBhbmQgSFRNTCBjaGFyYWN0ZXJzLiAqL1xuICB2YXIgcmVFc2NhcGVkSHRtbCA9IC8mKD86YW1wfGx0fGd0fHF1b3R8IzM5KTsvZyxcbiAgICAgIHJlVW5lc2NhcGVkSHRtbCA9IC9bJjw+XCInXS9nLFxuICAgICAgcmVIYXNFc2NhcGVkSHRtbCA9IFJlZ0V4cChyZUVzY2FwZWRIdG1sLnNvdXJjZSksXG4gICAgICByZUhhc1VuZXNjYXBlZEh0bWwgPSBSZWdFeHAocmVVbmVzY2FwZWRIdG1sLnNvdXJjZSk7XG5cbiAgLyoqIFVzZWQgdG8gbWF0Y2ggdGVtcGxhdGUgZGVsaW1pdGVycy4gKi9cbiAgdmFyIHJlRXNjYXBlID0gLzwlLShbXFxzXFxTXSs/KSU+L2csXG4gICAgICByZUV2YWx1YXRlID0gLzwlKFtcXHNcXFNdKz8pJT4vZyxcbiAgICAgIHJlSW50ZXJwb2xhdGUgPSAvPCU9KFtcXHNcXFNdKz8pJT4vZztcblxuICAvKiogVXNlZCB0byBtYXRjaCBwcm9wZXJ0eSBuYW1lcyB3aXRoaW4gcHJvcGVydHkgcGF0aHMuICovXG4gIHZhciByZUlzRGVlcFByb3AgPSAvXFwufFxcWyg/OlteW1xcXV0qfChbXCInXSkoPzooPyFcXDEpW15cXFxcXXxcXFxcLikqP1xcMSlcXF0vLFxuICAgICAgcmVJc1BsYWluUHJvcCA9IC9eXFx3KiQvLFxuICAgICAgcmVQcm9wTmFtZSA9IC9bXi5bXFxdXSt8XFxbKD86KC0/XFxkKyg/OlxcLlxcZCspPyl8KFtcIiddKSgoPzooPyFcXDIpW15cXFxcXXxcXFxcLikqPylcXDIpXFxdfCg/PSg/OlxcLnxcXFtcXF0pKD86XFwufFxcW1xcXXwkKSkvZztcblxuICAvKipcbiAgICogVXNlZCB0byBtYXRjaCBgUmVnRXhwYFxuICAgKiBbc3ludGF4IGNoYXJhY3RlcnNdKGh0dHA6Ly9lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzcuMC8jc2VjLXBhdHRlcm5zKS5cbiAgICovXG4gIHZhciByZVJlZ0V4cENoYXIgPSAvW1xcXFxeJC4qKz8oKVtcXF17fXxdL2csXG4gICAgICByZUhhc1JlZ0V4cENoYXIgPSBSZWdFeHAocmVSZWdFeHBDaGFyLnNvdXJjZSk7XG5cbiAgLyoqIFVzZWQgdG8gbWF0Y2ggbGVhZGluZyB3aGl0ZXNwYWNlLiAqL1xuICB2YXIgcmVUcmltU3RhcnQgPSAvXlxccysvO1xuXG4gIC8qKiBVc2VkIHRvIG1hdGNoIGEgc2luZ2xlIHdoaXRlc3BhY2UgY2hhcmFjdGVyLiAqL1xuICB2YXIgcmVXaGl0ZXNwYWNlID0gL1xccy87XG5cbiAgLyoqIFVzZWQgdG8gbWF0Y2ggd3JhcCBkZXRhaWwgY29tbWVudHMuICovXG4gIHZhciByZVdyYXBDb21tZW50ID0gL1xceyg/OlxcblxcL1xcKiBcXFt3cmFwcGVkIHdpdGggLitcXF0gXFwqXFwvKT9cXG4/LyxcbiAgICAgIHJlV3JhcERldGFpbHMgPSAvXFx7XFxuXFwvXFwqIFxcW3dyYXBwZWQgd2l0aCAoLispXFxdIFxcKi8sXG4gICAgICByZVNwbGl0RGV0YWlscyA9IC8sPyAmIC87XG5cbiAgLyoqIFVzZWQgdG8gbWF0Y2ggd29yZHMgY29tcG9zZWQgb2YgYWxwaGFudW1lcmljIGNoYXJhY3RlcnMuICovXG4gIHZhciByZUFzY2lpV29yZCA9IC9bXlxceDAwLVxceDJmXFx4M2EtXFx4NDBcXHg1Yi1cXHg2MFxceDdiLVxceDdmXSsvZztcblxuICAvKipcbiAgICogVXNlZCB0byB2YWxpZGF0ZSB0aGUgYHZhbGlkYXRlYCBvcHRpb24gaW4gYF8udGVtcGxhdGVgIHZhcmlhYmxlLlxuICAgKlxuICAgKiBGb3JiaWRzIGNoYXJhY3RlcnMgd2hpY2ggY291bGQgcG90ZW50aWFsbHkgY2hhbmdlIHRoZSBtZWFuaW5nIG9mIHRoZSBmdW5jdGlvbiBhcmd1bWVudCBkZWZpbml0aW9uOlxuICAgKiAtIFwiKCksXCIgKG1vZGlmaWNhdGlvbiBvZiBmdW5jdGlvbiBwYXJhbWV0ZXJzKVxuICAgKiAtIFwiPVwiIChkZWZhdWx0IHZhbHVlKVxuICAgKiAtIFwiW117fVwiIChkZXN0cnVjdHVyaW5nIG9mIGZ1bmN0aW9uIHBhcmFtZXRlcnMpXG4gICAqIC0gXCIvXCIgKGJlZ2lubmluZyBvZiBhIGNvbW1lbnQpXG4gICAqIC0gd2hpdGVzcGFjZVxuICAgKi9cbiAgdmFyIHJlRm9yYmlkZGVuSWRlbnRpZmllckNoYXJzID0gL1soKT0se31cXFtcXF1cXC9cXHNdLztcblxuICAvKiogVXNlZCB0byBtYXRjaCBiYWNrc2xhc2hlcyBpbiBwcm9wZXJ0eSBwYXRocy4gKi9cbiAgdmFyIHJlRXNjYXBlQ2hhciA9IC9cXFxcKFxcXFwpPy9nO1xuXG4gIC8qKlxuICAgKiBVc2VkIHRvIG1hdGNoXG4gICAqIFtFUyB0ZW1wbGF0ZSBkZWxpbWl0ZXJzXShodHRwOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi83LjAvI3NlYy10ZW1wbGF0ZS1saXRlcmFsLWxleGljYWwtY29tcG9uZW50cykuXG4gICAqL1xuICB2YXIgcmVFc1RlbXBsYXRlID0gL1xcJFxceyhbXlxcXFx9XSooPzpcXFxcLlteXFxcXH1dKikqKVxcfS9nO1xuXG4gIC8qKiBVc2VkIHRvIG1hdGNoIGBSZWdFeHBgIGZsYWdzIGZyb20gdGhlaXIgY29lcmNlZCBzdHJpbmcgdmFsdWVzLiAqL1xuICB2YXIgcmVGbGFncyA9IC9cXHcqJC87XG5cbiAgLyoqIFVzZWQgdG8gZGV0ZWN0IGJhZCBzaWduZWQgaGV4YWRlY2ltYWwgc3RyaW5nIHZhbHVlcy4gKi9cbiAgdmFyIHJlSXNCYWRIZXggPSAvXlstK10weFswLTlhLWZdKyQvaTtcblxuICAvKiogVXNlZCB0byBkZXRlY3QgYmluYXJ5IHN0cmluZyB2YWx1ZXMuICovXG4gIHZhciByZUlzQmluYXJ5ID0gL14wYlswMV0rJC9pO1xuXG4gIC8qKiBVc2VkIHRvIGRldGVjdCBob3N0IGNvbnN0cnVjdG9ycyAoU2FmYXJpKS4gKi9cbiAgdmFyIHJlSXNIb3N0Q3RvciA9IC9eXFxbb2JqZWN0IC4rP0NvbnN0cnVjdG9yXFxdJC87XG5cbiAgLyoqIFVzZWQgdG8gZGV0ZWN0IG9jdGFsIHN0cmluZyB2YWx1ZXMuICovXG4gIHZhciByZUlzT2N0YWwgPSAvXjBvWzAtN10rJC9pO1xuXG4gIC8qKiBVc2VkIHRvIGRldGVjdCB1bnNpZ25lZCBpbnRlZ2VyIHZhbHVlcy4gKi9cbiAgdmFyIHJlSXNVaW50ID0gL14oPzowfFsxLTldXFxkKikkLztcblxuICAvKiogVXNlZCB0byBtYXRjaCBMYXRpbiBVbmljb2RlIGxldHRlcnMgKGV4Y2x1ZGluZyBtYXRoZW1hdGljYWwgb3BlcmF0b3JzKS4gKi9cbiAgdmFyIHJlTGF0aW4gPSAvW1xceGMwLVxceGQ2XFx4ZDgtXFx4ZjZcXHhmOC1cXHhmZlxcdTAxMDAtXFx1MDE3Zl0vZztcblxuICAvKiogVXNlZCB0byBlbnN1cmUgY2FwdHVyaW5nIG9yZGVyIG9mIHRlbXBsYXRlIGRlbGltaXRlcnMuICovXG4gIHZhciByZU5vTWF0Y2ggPSAvKCReKS87XG5cbiAgLyoqIFVzZWQgdG8gbWF0Y2ggdW5lc2NhcGVkIGNoYXJhY3RlcnMgaW4gY29tcGlsZWQgc3RyaW5nIGxpdGVyYWxzLiAqL1xuICB2YXIgcmVVbmVzY2FwZWRTdHJpbmcgPSAvWydcXG5cXHJcXHUyMDI4XFx1MjAyOVxcXFxdL2c7XG5cbiAgLyoqIFVzZWQgdG8gY29tcG9zZSB1bmljb2RlIGNoYXJhY3RlciBjbGFzc2VzLiAqL1xuICB2YXIgcnNBc3RyYWxSYW5nZSA9ICdcXFxcdWQ4MDAtXFxcXHVkZmZmJyxcbiAgICAgIHJzQ29tYm9NYXJrc1JhbmdlID0gJ1xcXFx1MDMwMC1cXFxcdTAzNmYnLFxuICAgICAgcmVDb21ib0hhbGZNYXJrc1JhbmdlID0gJ1xcXFx1ZmUyMC1cXFxcdWZlMmYnLFxuICAgICAgcnNDb21ib1N5bWJvbHNSYW5nZSA9ICdcXFxcdTIwZDAtXFxcXHUyMGZmJyxcbiAgICAgIHJzQ29tYm9SYW5nZSA9IHJzQ29tYm9NYXJrc1JhbmdlICsgcmVDb21ib0hhbGZNYXJrc1JhbmdlICsgcnNDb21ib1N5bWJvbHNSYW5nZSxcbiAgICAgIHJzRGluZ2JhdFJhbmdlID0gJ1xcXFx1MjcwMC1cXFxcdTI3YmYnLFxuICAgICAgcnNMb3dlclJhbmdlID0gJ2EtelxcXFx4ZGYtXFxcXHhmNlxcXFx4ZjgtXFxcXHhmZicsXG4gICAgICByc01hdGhPcFJhbmdlID0gJ1xcXFx4YWNcXFxceGIxXFxcXHhkN1xcXFx4ZjcnLFxuICAgICAgcnNOb25DaGFyUmFuZ2UgPSAnXFxcXHgwMC1cXFxceDJmXFxcXHgzYS1cXFxceDQwXFxcXHg1Yi1cXFxceDYwXFxcXHg3Yi1cXFxceGJmJyxcbiAgICAgIHJzUHVuY3R1YXRpb25SYW5nZSA9ICdcXFxcdTIwMDAtXFxcXHUyMDZmJyxcbiAgICAgIHJzU3BhY2VSYW5nZSA9ICcgXFxcXHRcXFxceDBiXFxcXGZcXFxceGEwXFxcXHVmZWZmXFxcXG5cXFxcclxcXFx1MjAyOFxcXFx1MjAyOVxcXFx1MTY4MFxcXFx1MTgwZVxcXFx1MjAwMFxcXFx1MjAwMVxcXFx1MjAwMlxcXFx1MjAwM1xcXFx1MjAwNFxcXFx1MjAwNVxcXFx1MjAwNlxcXFx1MjAwN1xcXFx1MjAwOFxcXFx1MjAwOVxcXFx1MjAwYVxcXFx1MjAyZlxcXFx1MjA1ZlxcXFx1MzAwMCcsXG4gICAgICByc1VwcGVyUmFuZ2UgPSAnQS1aXFxcXHhjMC1cXFxceGQ2XFxcXHhkOC1cXFxceGRlJyxcbiAgICAgIHJzVmFyUmFuZ2UgPSAnXFxcXHVmZTBlXFxcXHVmZTBmJyxcbiAgICAgIHJzQnJlYWtSYW5nZSA9IHJzTWF0aE9wUmFuZ2UgKyByc05vbkNoYXJSYW5nZSArIHJzUHVuY3R1YXRpb25SYW5nZSArIHJzU3BhY2VSYW5nZTtcblxuICAvKiogVXNlZCB0byBjb21wb3NlIHVuaWNvZGUgY2FwdHVyZSBncm91cHMuICovXG4gIHZhciByc0Fwb3MgPSBcIlsnXFx1MjAxOV1cIixcbiAgICAgIHJzQXN0cmFsID0gJ1snICsgcnNBc3RyYWxSYW5nZSArICddJyxcbiAgICAgIHJzQnJlYWsgPSAnWycgKyByc0JyZWFrUmFuZ2UgKyAnXScsXG4gICAgICByc0NvbWJvID0gJ1snICsgcnNDb21ib1JhbmdlICsgJ10nLFxuICAgICAgcnNEaWdpdHMgPSAnXFxcXGQrJyxcbiAgICAgIHJzRGluZ2JhdCA9ICdbJyArIHJzRGluZ2JhdFJhbmdlICsgJ10nLFxuICAgICAgcnNMb3dlciA9ICdbJyArIHJzTG93ZXJSYW5nZSArICddJyxcbiAgICAgIHJzTWlzYyA9ICdbXicgKyByc0FzdHJhbFJhbmdlICsgcnNCcmVha1JhbmdlICsgcnNEaWdpdHMgKyByc0RpbmdiYXRSYW5nZSArIHJzTG93ZXJSYW5nZSArIHJzVXBwZXJSYW5nZSArICddJyxcbiAgICAgIHJzRml0eiA9ICdcXFxcdWQ4M2NbXFxcXHVkZmZiLVxcXFx1ZGZmZl0nLFxuICAgICAgcnNNb2RpZmllciA9ICcoPzonICsgcnNDb21ibyArICd8JyArIHJzRml0eiArICcpJyxcbiAgICAgIHJzTm9uQXN0cmFsID0gJ1teJyArIHJzQXN0cmFsUmFuZ2UgKyAnXScsXG4gICAgICByc1JlZ2lvbmFsID0gJyg/OlxcXFx1ZDgzY1tcXFxcdWRkZTYtXFxcXHVkZGZmXSl7Mn0nLFxuICAgICAgcnNTdXJyUGFpciA9ICdbXFxcXHVkODAwLVxcXFx1ZGJmZl1bXFxcXHVkYzAwLVxcXFx1ZGZmZl0nLFxuICAgICAgcnNVcHBlciA9ICdbJyArIHJzVXBwZXJSYW5nZSArICddJyxcbiAgICAgIHJzWldKID0gJ1xcXFx1MjAwZCc7XG5cbiAgLyoqIFVzZWQgdG8gY29tcG9zZSB1bmljb2RlIHJlZ2V4ZXMuICovXG4gIHZhciByc01pc2NMb3dlciA9ICcoPzonICsgcnNMb3dlciArICd8JyArIHJzTWlzYyArICcpJyxcbiAgICAgIHJzTWlzY1VwcGVyID0gJyg/OicgKyByc1VwcGVyICsgJ3wnICsgcnNNaXNjICsgJyknLFxuICAgICAgcnNPcHRDb250ckxvd2VyID0gJyg/OicgKyByc0Fwb3MgKyAnKD86ZHxsbHxtfHJlfHN8dHx2ZSkpPycsXG4gICAgICByc09wdENvbnRyVXBwZXIgPSAnKD86JyArIHJzQXBvcyArICcoPzpEfExMfE18UkV8U3xUfFZFKSk/JyxcbiAgICAgIHJlT3B0TW9kID0gcnNNb2RpZmllciArICc/JyxcbiAgICAgIHJzT3B0VmFyID0gJ1snICsgcnNWYXJSYW5nZSArICddPycsXG4gICAgICByc09wdEpvaW4gPSAnKD86JyArIHJzWldKICsgJyg/OicgKyBbcnNOb25Bc3RyYWwsIHJzUmVnaW9uYWwsIHJzU3VyclBhaXJdLmpvaW4oJ3wnKSArICcpJyArIHJzT3B0VmFyICsgcmVPcHRNb2QgKyAnKSonLFxuICAgICAgcnNPcmRMb3dlciA9ICdcXFxcZCooPzoxc3R8Mm5kfDNyZHwoPyFbMTIzXSlcXFxcZHRoKSg/PVxcXFxifFtBLVpfXSknLFxuICAgICAgcnNPcmRVcHBlciA9ICdcXFxcZCooPzoxU1R8Mk5EfDNSRHwoPyFbMTIzXSlcXFxcZFRIKSg/PVxcXFxifFthLXpfXSknLFxuICAgICAgcnNTZXEgPSByc09wdFZhciArIHJlT3B0TW9kICsgcnNPcHRKb2luLFxuICAgICAgcnNFbW9qaSA9ICcoPzonICsgW3JzRGluZ2JhdCwgcnNSZWdpb25hbCwgcnNTdXJyUGFpcl0uam9pbignfCcpICsgJyknICsgcnNTZXEsXG4gICAgICByc1N5bWJvbCA9ICcoPzonICsgW3JzTm9uQXN0cmFsICsgcnNDb21ibyArICc/JywgcnNDb21ibywgcnNSZWdpb25hbCwgcnNTdXJyUGFpciwgcnNBc3RyYWxdLmpvaW4oJ3wnKSArICcpJztcblxuICAvKiogVXNlZCB0byBtYXRjaCBhcG9zdHJvcGhlcy4gKi9cbiAgdmFyIHJlQXBvcyA9IFJlZ0V4cChyc0Fwb3MsICdnJyk7XG5cbiAgLyoqXG4gICAqIFVzZWQgdG8gbWF0Y2ggW2NvbWJpbmluZyBkaWFjcml0aWNhbCBtYXJrc10oaHR0cHM6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvQ29tYmluaW5nX0RpYWNyaXRpY2FsX01hcmtzKSBhbmRcbiAgICogW2NvbWJpbmluZyBkaWFjcml0aWNhbCBtYXJrcyBmb3Igc3ltYm9sc10oaHR0cHM6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvQ29tYmluaW5nX0RpYWNyaXRpY2FsX01hcmtzX2Zvcl9TeW1ib2xzKS5cbiAgICovXG4gIHZhciByZUNvbWJvTWFyayA9IFJlZ0V4cChyc0NvbWJvLCAnZycpO1xuXG4gIC8qKiBVc2VkIHRvIG1hdGNoIFtzdHJpbmcgc3ltYm9sc10oaHR0cHM6Ly9tYXRoaWFzYnluZW5zLmJlL25vdGVzL2phdmFzY3JpcHQtdW5pY29kZSkuICovXG4gIHZhciByZVVuaWNvZGUgPSBSZWdFeHAocnNGaXR6ICsgJyg/PScgKyByc0ZpdHogKyAnKXwnICsgcnNTeW1ib2wgKyByc1NlcSwgJ2cnKTtcblxuICAvKiogVXNlZCB0byBtYXRjaCBjb21wbGV4IG9yIGNvbXBvdW5kIHdvcmRzLiAqL1xuICB2YXIgcmVVbmljb2RlV29yZCA9IFJlZ0V4cChbXG4gICAgcnNVcHBlciArICc/JyArIHJzTG93ZXIgKyAnKycgKyByc09wdENvbnRyTG93ZXIgKyAnKD89JyArIFtyc0JyZWFrLCByc1VwcGVyLCAnJCddLmpvaW4oJ3wnKSArICcpJyxcbiAgICByc01pc2NVcHBlciArICcrJyArIHJzT3B0Q29udHJVcHBlciArICcoPz0nICsgW3JzQnJlYWssIHJzVXBwZXIgKyByc01pc2NMb3dlciwgJyQnXS5qb2luKCd8JykgKyAnKScsXG4gICAgcnNVcHBlciArICc/JyArIHJzTWlzY0xvd2VyICsgJysnICsgcnNPcHRDb250ckxvd2VyLFxuICAgIHJzVXBwZXIgKyAnKycgKyByc09wdENvbnRyVXBwZXIsXG4gICAgcnNPcmRVcHBlcixcbiAgICByc09yZExvd2VyLFxuICAgIHJzRGlnaXRzLFxuICAgIHJzRW1vamlcbiAgXS5qb2luKCd8JyksICdnJyk7XG5cbiAgLyoqIFVzZWQgdG8gZGV0ZWN0IHN0cmluZ3Mgd2l0aCBbemVyby13aWR0aCBqb2luZXJzIG9yIGNvZGUgcG9pbnRzIGZyb20gdGhlIGFzdHJhbCBwbGFuZXNdKGh0dHA6Ly9lZXYuZWUvYmxvZy8yMDE1LzA5LzEyL2RhcmstY29ybmVycy1vZi11bmljb2RlLykuICovXG4gIHZhciByZUhhc1VuaWNvZGUgPSBSZWdFeHAoJ1snICsgcnNaV0ogKyByc0FzdHJhbFJhbmdlICArIHJzQ29tYm9SYW5nZSArIHJzVmFyUmFuZ2UgKyAnXScpO1xuXG4gIC8qKiBVc2VkIHRvIGRldGVjdCBzdHJpbmdzIHRoYXQgbmVlZCBhIG1vcmUgcm9idXN0IHJlZ2V4cCB0byBtYXRjaCB3b3Jkcy4gKi9cbiAgdmFyIHJlSGFzVW5pY29kZVdvcmQgPSAvW2Etel1bQS1aXXxbQS1aXXsyfVthLXpdfFswLTldW2EtekEtWl18W2EtekEtWl1bMC05XXxbXmEtekEtWjAtOSBdLztcblxuICAvKiogVXNlZCB0byBhc3NpZ24gZGVmYXVsdCBgY29udGV4dGAgb2JqZWN0IHByb3BlcnRpZXMuICovXG4gIHZhciBjb250ZXh0UHJvcHMgPSBbXG4gICAgJ0FycmF5JywgJ0J1ZmZlcicsICdEYXRhVmlldycsICdEYXRlJywgJ0Vycm9yJywgJ0Zsb2F0MzJBcnJheScsICdGbG9hdDY0QXJyYXknLFxuICAgICdGdW5jdGlvbicsICdJbnQ4QXJyYXknLCAnSW50MTZBcnJheScsICdJbnQzMkFycmF5JywgJ01hcCcsICdNYXRoJywgJ09iamVjdCcsXG4gICAgJ1Byb21pc2UnLCAnUmVnRXhwJywgJ1NldCcsICdTdHJpbmcnLCAnU3ltYm9sJywgJ1R5cGVFcnJvcicsICdVaW50OEFycmF5JyxcbiAgICAnVWludDhDbGFtcGVkQXJyYXknLCAnVWludDE2QXJyYXknLCAnVWludDMyQXJyYXknLCAnV2Vha01hcCcsXG4gICAgJ18nLCAnY2xlYXJUaW1lb3V0JywgJ2lzRmluaXRlJywgJ3BhcnNlSW50JywgJ3NldFRpbWVvdXQnXG4gIF07XG5cbiAgLyoqIFVzZWQgdG8gbWFrZSB0ZW1wbGF0ZSBzb3VyY2VVUkxzIGVhc2llciB0byBpZGVudGlmeS4gKi9cbiAgdmFyIHRlbXBsYXRlQ291bnRlciA9IC0xO1xuXG4gIC8qKiBVc2VkIHRvIGlkZW50aWZ5IGB0b1N0cmluZ1RhZ2AgdmFsdWVzIG9mIHR5cGVkIGFycmF5cy4gKi9cbiAgdmFyIHR5cGVkQXJyYXlUYWdzID0ge307XG4gIHR5cGVkQXJyYXlUYWdzW2Zsb2F0MzJUYWddID0gdHlwZWRBcnJheVRhZ3NbZmxvYXQ2NFRhZ10gPVxuICB0eXBlZEFycmF5VGFnc1tpbnQ4VGFnXSA9IHR5cGVkQXJyYXlUYWdzW2ludDE2VGFnXSA9XG4gIHR5cGVkQXJyYXlUYWdzW2ludDMyVGFnXSA9IHR5cGVkQXJyYXlUYWdzW3VpbnQ4VGFnXSA9XG4gIHR5cGVkQXJyYXlUYWdzW3VpbnQ4Q2xhbXBlZFRhZ10gPSB0eXBlZEFycmF5VGFnc1t1aW50MTZUYWddID1cbiAgdHlwZWRBcnJheVRhZ3NbdWludDMyVGFnXSA9IHRydWU7XG4gIHR5cGVkQXJyYXlUYWdzW2FyZ3NUYWddID0gdHlwZWRBcnJheVRhZ3NbYXJyYXlUYWddID1cbiAgdHlwZWRBcnJheVRhZ3NbYXJyYXlCdWZmZXJUYWddID0gdHlwZWRBcnJheVRhZ3NbYm9vbFRhZ10gPVxuICB0eXBlZEFycmF5VGFnc1tkYXRhVmlld1RhZ10gPSB0eXBlZEFycmF5VGFnc1tkYXRlVGFnXSA9XG4gIHR5cGVkQXJyYXlUYWdzW2Vycm9yVGFnXSA9IHR5cGVkQXJyYXlUYWdzW2Z1bmNUYWddID1cbiAgdHlwZWRBcnJheVRhZ3NbbWFwVGFnXSA9IHR5cGVkQXJyYXlUYWdzW251bWJlclRhZ10gPVxuICB0eXBlZEFycmF5VGFnc1tvYmplY3RUYWddID0gdHlwZWRBcnJheVRhZ3NbcmVnZXhwVGFnXSA9XG4gIHR5cGVkQXJyYXlUYWdzW3NldFRhZ10gPSB0eXBlZEFycmF5VGFnc1tzdHJpbmdUYWddID1cbiAgdHlwZWRBcnJheVRhZ3Nbd2Vha01hcFRhZ10gPSBmYWxzZTtcblxuICAvKiogVXNlZCB0byBpZGVudGlmeSBgdG9TdHJpbmdUYWdgIHZhbHVlcyBzdXBwb3J0ZWQgYnkgYF8uY2xvbmVgLiAqL1xuICB2YXIgY2xvbmVhYmxlVGFncyA9IHt9O1xuICBjbG9uZWFibGVUYWdzW2FyZ3NUYWddID0gY2xvbmVhYmxlVGFnc1thcnJheVRhZ10gPVxuICBjbG9uZWFibGVUYWdzW2FycmF5QnVmZmVyVGFnXSA9IGNsb25lYWJsZVRhZ3NbZGF0YVZpZXdUYWddID1cbiAgY2xvbmVhYmxlVGFnc1tib29sVGFnXSA9IGNsb25lYWJsZVRhZ3NbZGF0ZVRhZ10gPVxuICBjbG9uZWFibGVUYWdzW2Zsb2F0MzJUYWddID0gY2xvbmVhYmxlVGFnc1tmbG9hdDY0VGFnXSA9XG4gIGNsb25lYWJsZVRhZ3NbaW50OFRhZ10gPSBjbG9uZWFibGVUYWdzW2ludDE2VGFnXSA9XG4gIGNsb25lYWJsZVRhZ3NbaW50MzJUYWddID0gY2xvbmVhYmxlVGFnc1ttYXBUYWddID1cbiAgY2xvbmVhYmxlVGFnc1tudW1iZXJUYWddID0gY2xvbmVhYmxlVGFnc1tvYmplY3RUYWddID1cbiAgY2xvbmVhYmxlVGFnc1tyZWdleHBUYWddID0gY2xvbmVhYmxlVGFnc1tzZXRUYWddID1cbiAgY2xvbmVhYmxlVGFnc1tzdHJpbmdUYWddID0gY2xvbmVhYmxlVGFnc1tzeW1ib2xUYWddID1cbiAgY2xvbmVhYmxlVGFnc1t1aW50OFRhZ10gPSBjbG9uZWFibGVUYWdzW3VpbnQ4Q2xhbXBlZFRhZ10gPVxuICBjbG9uZWFibGVUYWdzW3VpbnQxNlRhZ10gPSBjbG9uZWFibGVUYWdzW3VpbnQzMlRhZ10gPSB0cnVlO1xuICBjbG9uZWFibGVUYWdzW2Vycm9yVGFnXSA9IGNsb25lYWJsZVRhZ3NbZnVuY1RhZ10gPVxuICBjbG9uZWFibGVUYWdzW3dlYWtNYXBUYWddID0gZmFsc2U7XG5cbiAgLyoqIFVzZWQgdG8gbWFwIExhdGluIFVuaWNvZGUgbGV0dGVycyB0byBiYXNpYyBMYXRpbiBsZXR0ZXJzLiAqL1xuICB2YXIgZGVidXJyZWRMZXR0ZXJzID0ge1xuICAgIC8vIExhdGluLTEgU3VwcGxlbWVudCBibG9jay5cbiAgICAnXFx4YzAnOiAnQScsICAnXFx4YzEnOiAnQScsICdcXHhjMic6ICdBJywgJ1xceGMzJzogJ0EnLCAnXFx4YzQnOiAnQScsICdcXHhjNSc6ICdBJyxcbiAgICAnXFx4ZTAnOiAnYScsICAnXFx4ZTEnOiAnYScsICdcXHhlMic6ICdhJywgJ1xceGUzJzogJ2EnLCAnXFx4ZTQnOiAnYScsICdcXHhlNSc6ICdhJyxcbiAgICAnXFx4YzcnOiAnQycsICAnXFx4ZTcnOiAnYycsXG4gICAgJ1xceGQwJzogJ0QnLCAgJ1xceGYwJzogJ2QnLFxuICAgICdcXHhjOCc6ICdFJywgICdcXHhjOSc6ICdFJywgJ1xceGNhJzogJ0UnLCAnXFx4Y2InOiAnRScsXG4gICAgJ1xceGU4JzogJ2UnLCAgJ1xceGU5JzogJ2UnLCAnXFx4ZWEnOiAnZScsICdcXHhlYic6ICdlJyxcbiAgICAnXFx4Y2MnOiAnSScsICAnXFx4Y2QnOiAnSScsICdcXHhjZSc6ICdJJywgJ1xceGNmJzogJ0knLFxuICAgICdcXHhlYyc6ICdpJywgICdcXHhlZCc6ICdpJywgJ1xceGVlJzogJ2knLCAnXFx4ZWYnOiAnaScsXG4gICAgJ1xceGQxJzogJ04nLCAgJ1xceGYxJzogJ24nLFxuICAgICdcXHhkMic6ICdPJywgICdcXHhkMyc6ICdPJywgJ1xceGQ0JzogJ08nLCAnXFx4ZDUnOiAnTycsICdcXHhkNic6ICdPJywgJ1xceGQ4JzogJ08nLFxuICAgICdcXHhmMic6ICdvJywgICdcXHhmMyc6ICdvJywgJ1xceGY0JzogJ28nLCAnXFx4ZjUnOiAnbycsICdcXHhmNic6ICdvJywgJ1xceGY4JzogJ28nLFxuICAgICdcXHhkOSc6ICdVJywgICdcXHhkYSc6ICdVJywgJ1xceGRiJzogJ1UnLCAnXFx4ZGMnOiAnVScsXG4gICAgJ1xceGY5JzogJ3UnLCAgJ1xceGZhJzogJ3UnLCAnXFx4ZmInOiAndScsICdcXHhmYyc6ICd1JyxcbiAgICAnXFx4ZGQnOiAnWScsICAnXFx4ZmQnOiAneScsICdcXHhmZic6ICd5JyxcbiAgICAnXFx4YzYnOiAnQWUnLCAnXFx4ZTYnOiAnYWUnLFxuICAgICdcXHhkZSc6ICdUaCcsICdcXHhmZSc6ICd0aCcsXG4gICAgJ1xceGRmJzogJ3NzJyxcbiAgICAvLyBMYXRpbiBFeHRlbmRlZC1BIGJsb2NrLlxuICAgICdcXHUwMTAwJzogJ0EnLCAgJ1xcdTAxMDInOiAnQScsICdcXHUwMTA0JzogJ0EnLFxuICAgICdcXHUwMTAxJzogJ2EnLCAgJ1xcdTAxMDMnOiAnYScsICdcXHUwMTA1JzogJ2EnLFxuICAgICdcXHUwMTA2JzogJ0MnLCAgJ1xcdTAxMDgnOiAnQycsICdcXHUwMTBhJzogJ0MnLCAnXFx1MDEwYyc6ICdDJyxcbiAgICAnXFx1MDEwNyc6ICdjJywgICdcXHUwMTA5JzogJ2MnLCAnXFx1MDEwYic6ICdjJywgJ1xcdTAxMGQnOiAnYycsXG4gICAgJ1xcdTAxMGUnOiAnRCcsICAnXFx1MDExMCc6ICdEJywgJ1xcdTAxMGYnOiAnZCcsICdcXHUwMTExJzogJ2QnLFxuICAgICdcXHUwMTEyJzogJ0UnLCAgJ1xcdTAxMTQnOiAnRScsICdcXHUwMTE2JzogJ0UnLCAnXFx1MDExOCc6ICdFJywgJ1xcdTAxMWEnOiAnRScsXG4gICAgJ1xcdTAxMTMnOiAnZScsICAnXFx1MDExNSc6ICdlJywgJ1xcdTAxMTcnOiAnZScsICdcXHUwMTE5JzogJ2UnLCAnXFx1MDExYic6ICdlJyxcbiAgICAnXFx1MDExYyc6ICdHJywgICdcXHUwMTFlJzogJ0cnLCAnXFx1MDEyMCc6ICdHJywgJ1xcdTAxMjInOiAnRycsXG4gICAgJ1xcdTAxMWQnOiAnZycsICAnXFx1MDExZic6ICdnJywgJ1xcdTAxMjEnOiAnZycsICdcXHUwMTIzJzogJ2cnLFxuICAgICdcXHUwMTI0JzogJ0gnLCAgJ1xcdTAxMjYnOiAnSCcsICdcXHUwMTI1JzogJ2gnLCAnXFx1MDEyNyc6ICdoJyxcbiAgICAnXFx1MDEyOCc6ICdJJywgICdcXHUwMTJhJzogJ0knLCAnXFx1MDEyYyc6ICdJJywgJ1xcdTAxMmUnOiAnSScsICdcXHUwMTMwJzogJ0knLFxuICAgICdcXHUwMTI5JzogJ2knLCAgJ1xcdTAxMmInOiAnaScsICdcXHUwMTJkJzogJ2knLCAnXFx1MDEyZic6ICdpJywgJ1xcdTAxMzEnOiAnaScsXG4gICAgJ1xcdTAxMzQnOiAnSicsICAnXFx1MDEzNSc6ICdqJyxcbiAgICAnXFx1MDEzNic6ICdLJywgICdcXHUwMTM3JzogJ2snLCAnXFx1MDEzOCc6ICdrJyxcbiAgICAnXFx1MDEzOSc6ICdMJywgICdcXHUwMTNiJzogJ0wnLCAnXFx1MDEzZCc6ICdMJywgJ1xcdTAxM2YnOiAnTCcsICdcXHUwMTQxJzogJ0wnLFxuICAgICdcXHUwMTNhJzogJ2wnLCAgJ1xcdTAxM2MnOiAnbCcsICdcXHUwMTNlJzogJ2wnLCAnXFx1MDE0MCc6ICdsJywgJ1xcdTAxNDInOiAnbCcsXG4gICAgJ1xcdTAxNDMnOiAnTicsICAnXFx1MDE0NSc6ICdOJywgJ1xcdTAxNDcnOiAnTicsICdcXHUwMTRhJzogJ04nLFxuICAgICdcXHUwMTQ0JzogJ24nLCAgJ1xcdTAxNDYnOiAnbicsICdcXHUwMTQ4JzogJ24nLCAnXFx1MDE0Yic6ICduJyxcbiAgICAnXFx1MDE0Yyc6ICdPJywgICdcXHUwMTRlJzogJ08nLCAnXFx1MDE1MCc6ICdPJyxcbiAgICAnXFx1MDE0ZCc6ICdvJywgICdcXHUwMTRmJzogJ28nLCAnXFx1MDE1MSc6ICdvJyxcbiAgICAnXFx1MDE1NCc6ICdSJywgICdcXHUwMTU2JzogJ1InLCAnXFx1MDE1OCc6ICdSJyxcbiAgICAnXFx1MDE1NSc6ICdyJywgICdcXHUwMTU3JzogJ3InLCAnXFx1MDE1OSc6ICdyJyxcbiAgICAnXFx1MDE1YSc6ICdTJywgICdcXHUwMTVjJzogJ1MnLCAnXFx1MDE1ZSc6ICdTJywgJ1xcdTAxNjAnOiAnUycsXG4gICAgJ1xcdTAxNWInOiAncycsICAnXFx1MDE1ZCc6ICdzJywgJ1xcdTAxNWYnOiAncycsICdcXHUwMTYxJzogJ3MnLFxuICAgICdcXHUwMTYyJzogJ1QnLCAgJ1xcdTAxNjQnOiAnVCcsICdcXHUwMTY2JzogJ1QnLFxuICAgICdcXHUwMTYzJzogJ3QnLCAgJ1xcdTAxNjUnOiAndCcsICdcXHUwMTY3JzogJ3QnLFxuICAgICdcXHUwMTY4JzogJ1UnLCAgJ1xcdTAxNmEnOiAnVScsICdcXHUwMTZjJzogJ1UnLCAnXFx1MDE2ZSc6ICdVJywgJ1xcdTAxNzAnOiAnVScsICdcXHUwMTcyJzogJ1UnLFxuICAgICdcXHUwMTY5JzogJ3UnLCAgJ1xcdTAxNmInOiAndScsICdcXHUwMTZkJzogJ3UnLCAnXFx1MDE2Zic6ICd1JywgJ1xcdTAxNzEnOiAndScsICdcXHUwMTczJzogJ3UnLFxuICAgICdcXHUwMTc0JzogJ1cnLCAgJ1xcdTAxNzUnOiAndycsXG4gICAgJ1xcdTAxNzYnOiAnWScsICAnXFx1MDE3Nyc6ICd5JywgJ1xcdTAxNzgnOiAnWScsXG4gICAgJ1xcdTAxNzknOiAnWicsICAnXFx1MDE3Yic6ICdaJywgJ1xcdTAxN2QnOiAnWicsXG4gICAgJ1xcdTAxN2EnOiAneicsICAnXFx1MDE3Yyc6ICd6JywgJ1xcdTAxN2UnOiAneicsXG4gICAgJ1xcdTAxMzInOiAnSUonLCAnXFx1MDEzMyc6ICdpaicsXG4gICAgJ1xcdTAxNTInOiAnT2UnLCAnXFx1MDE1Myc6ICdvZScsXG4gICAgJ1xcdTAxNDknOiBcIiduXCIsICdcXHUwMTdmJzogJ3MnXG4gIH07XG5cbiAgLyoqIFVzZWQgdG8gbWFwIGNoYXJhY3RlcnMgdG8gSFRNTCBlbnRpdGllcy4gKi9cbiAgdmFyIGh0bWxFc2NhcGVzID0ge1xuICAgICcmJzogJyZhbXA7JyxcbiAgICAnPCc6ICcmbHQ7JyxcbiAgICAnPic6ICcmZ3Q7JyxcbiAgICAnXCInOiAnJnF1b3Q7JyxcbiAgICBcIidcIjogJyYjMzk7J1xuICB9O1xuXG4gIC8qKiBVc2VkIHRvIG1hcCBIVE1MIGVudGl0aWVzIHRvIGNoYXJhY3RlcnMuICovXG4gIHZhciBodG1sVW5lc2NhcGVzID0ge1xuICAgICcmYW1wOyc6ICcmJyxcbiAgICAnJmx0Oyc6ICc8JyxcbiAgICAnJmd0Oyc6ICc+JyxcbiAgICAnJnF1b3Q7JzogJ1wiJyxcbiAgICAnJiMzOTsnOiBcIidcIlxuICB9O1xuXG4gIC8qKiBVc2VkIHRvIGVzY2FwZSBjaGFyYWN0ZXJzIGZvciBpbmNsdXNpb24gaW4gY29tcGlsZWQgc3RyaW5nIGxpdGVyYWxzLiAqL1xuICB2YXIgc3RyaW5nRXNjYXBlcyA9IHtcbiAgICAnXFxcXCc6ICdcXFxcJyxcbiAgICBcIidcIjogXCInXCIsXG4gICAgJ1xcbic6ICduJyxcbiAgICAnXFxyJzogJ3InLFxuICAgICdcXHUyMDI4JzogJ3UyMDI4JyxcbiAgICAnXFx1MjAyOSc6ICd1MjAyOSdcbiAgfTtcblxuICAvKiogQnVpbHQtaW4gbWV0aG9kIHJlZmVyZW5jZXMgd2l0aG91dCBhIGRlcGVuZGVuY3kgb24gYHJvb3RgLiAqL1xuICB2YXIgZnJlZVBhcnNlRmxvYXQgPSBwYXJzZUZsb2F0LFxuICAgICAgZnJlZVBhcnNlSW50ID0gcGFyc2VJbnQ7XG5cbiAgLyoqIERldGVjdCBmcmVlIHZhcmlhYmxlIGBnbG9iYWxgIGZyb20gTm9kZS5qcy4gKi9cbiAgdmFyIGZyZWVHbG9iYWwgPSB0eXBlb2YgZ2xvYmFsID09ICdvYmplY3QnICYmIGdsb2JhbCAmJiBnbG9iYWwuT2JqZWN0ID09PSBPYmplY3QgJiYgZ2xvYmFsO1xuXG4gIC8qKiBEZXRlY3QgZnJlZSB2YXJpYWJsZSBgc2VsZmAuICovXG4gIHZhciBmcmVlU2VsZiA9IHR5cGVvZiBzZWxmID09ICdvYmplY3QnICYmIHNlbGYgJiYgc2VsZi5PYmplY3QgPT09IE9iamVjdCAmJiBzZWxmO1xuXG4gIC8qKiBVc2VkIGFzIGEgcmVmZXJlbmNlIHRvIHRoZSBnbG9iYWwgb2JqZWN0LiAqL1xuICB2YXIgcm9vdCA9IGZyZWVHbG9iYWwgfHwgZnJlZVNlbGYgfHwgRnVuY3Rpb24oJ3JldHVybiB0aGlzJykoKTtcblxuICAvKiogRGV0ZWN0IGZyZWUgdmFyaWFibGUgYGV4cG9ydHNgLiAqL1xuICB2YXIgZnJlZUV4cG9ydHMgPSB0eXBlb2YgZXhwb3J0cyA9PSAnb2JqZWN0JyAmJiBleHBvcnRzICYmICFleHBvcnRzLm5vZGVUeXBlICYmIGV4cG9ydHM7XG5cbiAgLyoqIERldGVjdCBmcmVlIHZhcmlhYmxlIGBtb2R1bGVgLiAqL1xuICB2YXIgZnJlZU1vZHVsZSA9IGZyZWVFeHBvcnRzICYmIHR5cGVvZiBtb2R1bGUgPT0gJ29iamVjdCcgJiYgbW9kdWxlICYmICFtb2R1bGUubm9kZVR5cGUgJiYgbW9kdWxlO1xuXG4gIC8qKiBEZXRlY3QgdGhlIHBvcHVsYXIgQ29tbW9uSlMgZXh0ZW5zaW9uIGBtb2R1bGUuZXhwb3J0c2AuICovXG4gIHZhciBtb2R1bGVFeHBvcnRzID0gZnJlZU1vZHVsZSAmJiBmcmVlTW9kdWxlLmV4cG9ydHMgPT09IGZyZWVFeHBvcnRzO1xuXG4gIC8qKiBEZXRlY3QgZnJlZSB2YXJpYWJsZSBgcHJvY2Vzc2AgZnJvbSBOb2RlLmpzLiAqL1xuICB2YXIgZnJlZVByb2Nlc3MgPSBtb2R1bGVFeHBvcnRzICYmIGZyZWVHbG9iYWwucHJvY2VzcztcblxuICAvKiogVXNlZCB0byBhY2Nlc3MgZmFzdGVyIE5vZGUuanMgaGVscGVycy4gKi9cbiAgdmFyIG5vZGVVdGlsID0gKGZ1bmN0aW9uKCkge1xuICAgIHRyeSB7XG4gICAgICAvLyBVc2UgYHV0aWwudHlwZXNgIGZvciBOb2RlLmpzIDEwKy5cbiAgICAgIHZhciB0eXBlcyA9IGZyZWVNb2R1bGUgJiYgZnJlZU1vZHVsZS5yZXF1aXJlICYmIGZyZWVNb2R1bGUucmVxdWlyZSgndXRpbCcpLnR5cGVzO1xuXG4gICAgICBpZiAodHlwZXMpIHtcbiAgICAgICAgcmV0dXJuIHR5cGVzO1xuICAgICAgfVxuXG4gICAgICAvLyBMZWdhY3kgYHByb2Nlc3MuYmluZGluZygndXRpbCcpYCBmb3IgTm9kZS5qcyA8IDEwLlxuICAgICAgcmV0dXJuIGZyZWVQcm9jZXNzICYmIGZyZWVQcm9jZXNzLmJpbmRpbmcgJiYgZnJlZVByb2Nlc3MuYmluZGluZygndXRpbCcpO1xuICAgIH0gY2F0Y2ggKGUpIHt9XG4gIH0oKSk7XG5cbiAgLyogTm9kZS5qcyBoZWxwZXIgcmVmZXJlbmNlcy4gKi9cbiAgdmFyIG5vZGVJc0FycmF5QnVmZmVyID0gbm9kZVV0aWwgJiYgbm9kZVV0aWwuaXNBcnJheUJ1ZmZlcixcbiAgICAgIG5vZGVJc0RhdGUgPSBub2RlVXRpbCAmJiBub2RlVXRpbC5pc0RhdGUsXG4gICAgICBub2RlSXNNYXAgPSBub2RlVXRpbCAmJiBub2RlVXRpbC5pc01hcCxcbiAgICAgIG5vZGVJc1JlZ0V4cCA9IG5vZGVVdGlsICYmIG5vZGVVdGlsLmlzUmVnRXhwLFxuICAgICAgbm9kZUlzU2V0ID0gbm9kZVV0aWwgJiYgbm9kZVV0aWwuaXNTZXQsXG4gICAgICBub2RlSXNUeXBlZEFycmF5ID0gbm9kZVV0aWwgJiYgbm9kZVV0aWwuaXNUeXBlZEFycmF5O1xuXG4gIC8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuXG4gIC8qKlxuICAgKiBBIGZhc3RlciBhbHRlcm5hdGl2ZSB0byBgRnVuY3Rpb24jYXBwbHlgLCB0aGlzIGZ1bmN0aW9uIGludm9rZXMgYGZ1bmNgXG4gICAqIHdpdGggdGhlIGB0aGlzYCBiaW5kaW5nIG9mIGB0aGlzQXJnYCBhbmQgdGhlIGFyZ3VtZW50cyBvZiBgYXJnc2AuXG4gICAqXG4gICAqIEBwcml2YXRlXG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIGludm9rZS5cbiAgICogQHBhcmFtIHsqfSB0aGlzQXJnIFRoZSBgdGhpc2AgYmluZGluZyBvZiBgZnVuY2AuXG4gICAqIEBwYXJhbSB7QXJyYXl9IGFyZ3MgVGhlIGFyZ3VtZW50cyB0byBpbnZva2UgYGZ1bmNgIHdpdGguXG4gICAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSByZXN1bHQgb2YgYGZ1bmNgLlxuICAgKi9cbiAgZnVuY3Rpb24gYXBwbHkoZnVuYywgdGhpc0FyZywgYXJncykge1xuICAgIHN3aXRjaCAoYXJncy5sZW5ndGgpIHtcbiAgICAgIGNhc2UgMDogcmV0dXJuIGZ1bmMuY2FsbCh0aGlzQXJnKTtcbiAgICAgIGNhc2UgMTogcmV0dXJuIGZ1bmMuY2FsbCh0aGlzQXJnLCBhcmdzWzBdKTtcbiAgICAgIGNhc2UgMjogcmV0dXJuIGZ1bmMuY2FsbCh0aGlzQXJnLCBhcmdzWzBdLCBhcmdzWzFdKTtcbiAgICAgIGNhc2UgMzogcmV0dXJuIGZ1bmMuY2FsbCh0aGlzQXJnLCBhcmdzWzBdLCBhcmdzWzFdLCBhcmdzWzJdKTtcbiAgICB9XG4gICAgcmV0dXJuIGZ1bmMuYXBwbHkodGhpc0FyZywgYXJncyk7XG4gIH1cblxuICAvKipcbiAgICogQSBzcGVjaWFsaXplZCB2ZXJzaW9uIG9mIGBiYXNlQWdncmVnYXRvcmAgZm9yIGFycmF5cy5cbiAgICpcbiAgICogQHByaXZhdGVcbiAgICogQHBhcmFtIHtBcnJheX0gW2FycmF5XSBUaGUgYXJyYXkgdG8gaXRlcmF0ZSBvdmVyLlxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBzZXR0ZXIgVGhlIGZ1bmN0aW9uIHRvIHNldCBgYWNjdW11bGF0b3JgIHZhbHVlcy5cbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gaXRlcmF0ZWUgVGhlIGl0ZXJhdGVlIHRvIHRyYW5zZm9ybSBrZXlzLlxuICAgKiBAcGFyYW0ge09iamVjdH0gYWNjdW11bGF0b3IgVGhlIGluaXRpYWwgYWdncmVnYXRlZCBvYmplY3QuXG4gICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyBgYWNjdW11bGF0b3JgLlxuICAgKi9cbiAgZnVuY3Rpb24gYXJyYXlBZ2dyZWdhdG9yKGFycmF5LCBzZXR0ZXIsIGl0ZXJhdGVlLCBhY2N1bXVsYXRvcikge1xuICAgIHZhciBpbmRleCA9IC0xLFxuICAgICAgICBsZW5ndGggPSBhcnJheSA9PSBudWxsID8gMCA6IGFycmF5Lmxlbmd0aDtcblxuICAgIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XG4gICAgICB2YXIgdmFsdWUgPSBhcnJheVtpbmRleF07XG4gICAgICBzZXR0ZXIoYWNjdW11bGF0b3IsIHZhbHVlLCBpdGVyYXRlZSh2YWx1ZSksIGFycmF5KTtcbiAgICB9XG4gICAgcmV0dXJuIGFjY3VtdWxhdG9yO1xuICB9XG5cbiAgLyoqXG4gICAqIEEgc3BlY2lhbGl6ZWQgdmVyc2lvbiBvZiBgXy5mb3JFYWNoYCBmb3IgYXJyYXlzIHdpdGhvdXQgc3VwcG9ydCBmb3JcbiAgICogaXRlcmF0ZWUgc2hvcnRoYW5kcy5cbiAgICpcbiAgICogQHByaXZhdGVcbiAgICogQHBhcmFtIHtBcnJheX0gW2FycmF5XSBUaGUgYXJyYXkgdG8gaXRlcmF0ZSBvdmVyLlxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBpdGVyYXRlZSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgYGFycmF5YC5cbiAgICovXG4gIGZ1bmN0aW9uIGFycmF5RWFjaChhcnJheSwgaXRlcmF0ZWUpIHtcbiAgICB2YXIgaW5kZXggPSAtMSxcbiAgICAgICAgbGVuZ3RoID0gYXJyYXkgPT0gbnVsbCA/IDAgOiBhcnJheS5sZW5ndGg7XG5cbiAgICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgICAgaWYgKGl0ZXJhdGVlKGFycmF5W2luZGV4XSwgaW5kZXgsIGFycmF5KSA9PT0gZmFsc2UpIHtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBhcnJheTtcbiAgfVxuXG4gIC8qKlxuICAgKiBBIHNwZWNpYWxpemVkIHZlcnNpb24gb2YgYF8uZm9yRWFjaFJpZ2h0YCBmb3IgYXJyYXlzIHdpdGhvdXQgc3VwcG9ydCBmb3JcbiAgICogaXRlcmF0ZWUgc2hvcnRoYW5kcy5cbiAgICpcbiAgICogQHByaXZhdGVcbiAgICogQHBhcmFtIHtBcnJheX0gW2FycmF5XSBUaGUgYXJyYXkgdG8gaXRlcmF0ZSBvdmVyLlxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBpdGVyYXRlZSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgYGFycmF5YC5cbiAgICovXG4gIGZ1bmN0aW9uIGFycmF5RWFjaFJpZ2h0KGFycmF5LCBpdGVyYXRlZSkge1xuICAgIHZhciBsZW5ndGggPSBhcnJheSA9PSBudWxsID8gMCA6IGFycmF5Lmxlbmd0aDtcblxuICAgIHdoaWxlIChsZW5ndGgtLSkge1xuICAgICAgaWYgKGl0ZXJhdGVlKGFycmF5W2xlbmd0aF0sIGxlbmd0aCwgYXJyYXkpID09PSBmYWxzZSkge1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGFycmF5O1xuICB9XG5cbiAgLyoqXG4gICAqIEEgc3BlY2lhbGl6ZWQgdmVyc2lvbiBvZiBgXy5ldmVyeWAgZm9yIGFycmF5cyB3aXRob3V0IHN1cHBvcnQgZm9yXG4gICAqIGl0ZXJhdGVlIHNob3J0aGFuZHMuXG4gICAqXG4gICAqIEBwcml2YXRlXG4gICAqIEBwYXJhbSB7QXJyYXl9IFthcnJheV0gVGhlIGFycmF5IHRvIGl0ZXJhdGUgb3Zlci5cbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gcHJlZGljYXRlIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uXG4gICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBhbGwgZWxlbWVudHMgcGFzcyB0aGUgcHJlZGljYXRlIGNoZWNrLFxuICAgKiAgZWxzZSBgZmFsc2VgLlxuICAgKi9cbiAgZnVuY3Rpb24gYXJyYXlFdmVyeShhcnJheSwgcHJlZGljYXRlKSB7XG4gICAgdmFyIGluZGV4ID0gLTEsXG4gICAgICAgIGxlbmd0aCA9IGFycmF5ID09IG51bGwgPyAwIDogYXJyYXkubGVuZ3RoO1xuXG4gICAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHtcbiAgICAgIGlmICghcHJlZGljYXRlKGFycmF5W2luZGV4XSwgaW5kZXgsIGFycmF5KSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgLyoqXG4gICAqIEEgc3BlY2lhbGl6ZWQgdmVyc2lvbiBvZiBgXy5maWx0ZXJgIGZvciBhcnJheXMgd2l0aG91dCBzdXBwb3J0IGZvclxuICAgKiBpdGVyYXRlZSBzaG9ydGhhbmRzLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge0FycmF5fSBbYXJyYXldIFRoZSBhcnJheSB0byBpdGVyYXRlIG92ZXIuXG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IHByZWRpY2F0ZSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIG5ldyBmaWx0ZXJlZCBhcnJheS5cbiAgICovXG4gIGZ1bmN0aW9uIGFycmF5RmlsdGVyKGFycmF5LCBwcmVkaWNhdGUpIHtcbiAgICB2YXIgaW5kZXggPSAtMSxcbiAgICAgICAgbGVuZ3RoID0gYXJyYXkgPT0gbnVsbCA/IDAgOiBhcnJheS5sZW5ndGgsXG4gICAgICAgIHJlc0luZGV4ID0gMCxcbiAgICAgICAgcmVzdWx0ID0gW107XG5cbiAgICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgICAgdmFyIHZhbHVlID0gYXJyYXlbaW5kZXhdO1xuICAgICAgaWYgKHByZWRpY2F0ZSh2YWx1ZSwgaW5kZXgsIGFycmF5KSkge1xuICAgICAgICByZXN1bHRbcmVzSW5kZXgrK10gPSB2YWx1ZTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuXG4gIC8qKlxuICAgKiBBIHNwZWNpYWxpemVkIHZlcnNpb24gb2YgYF8uaW5jbHVkZXNgIGZvciBhcnJheXMgd2l0aG91dCBzdXBwb3J0IGZvclxuICAgKiBzcGVjaWZ5aW5nIGFuIGluZGV4IHRvIHNlYXJjaCBmcm9tLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge0FycmF5fSBbYXJyYXldIFRoZSBhcnJheSB0byBpbnNwZWN0LlxuICAgKiBAcGFyYW0geyp9IHRhcmdldCBUaGUgdmFsdWUgdG8gc2VhcmNoIGZvci5cbiAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB0YXJnZXRgIGlzIGZvdW5kLCBlbHNlIGBmYWxzZWAuXG4gICAqL1xuICBmdW5jdGlvbiBhcnJheUluY2x1ZGVzKGFycmF5LCB2YWx1ZSkge1xuICAgIHZhciBsZW5ndGggPSBhcnJheSA9PSBudWxsID8gMCA6IGFycmF5Lmxlbmd0aDtcbiAgICByZXR1cm4gISFsZW5ndGggJiYgYmFzZUluZGV4T2YoYXJyYXksIHZhbHVlLCAwKSA+IC0xO1xuICB9XG5cbiAgLyoqXG4gICAqIFRoaXMgZnVuY3Rpb24gaXMgbGlrZSBgYXJyYXlJbmNsdWRlc2AgZXhjZXB0IHRoYXQgaXQgYWNjZXB0cyBhIGNvbXBhcmF0b3IuXG4gICAqXG4gICAqIEBwcml2YXRlXG4gICAqIEBwYXJhbSB7QXJyYXl9IFthcnJheV0gVGhlIGFycmF5IHRvIGluc3BlY3QuXG4gICAqIEBwYXJhbSB7Kn0gdGFyZ2V0IFRoZSB2YWx1ZSB0byBzZWFyY2ggZm9yLlxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBjb21wYXJhdG9yIFRoZSBjb21wYXJhdG9yIGludm9rZWQgcGVyIGVsZW1lbnQuXG4gICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdGFyZ2V0YCBpcyBmb3VuZCwgZWxzZSBgZmFsc2VgLlxuICAgKi9cbiAgZnVuY3Rpb24gYXJyYXlJbmNsdWRlc1dpdGgoYXJyYXksIHZhbHVlLCBjb21wYXJhdG9yKSB7XG4gICAgdmFyIGluZGV4ID0gLTEsXG4gICAgICAgIGxlbmd0aCA9IGFycmF5ID09IG51bGwgPyAwIDogYXJyYXkubGVuZ3RoO1xuXG4gICAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHtcbiAgICAgIGlmIChjb21wYXJhdG9yKHZhbHVlLCBhcnJheVtpbmRleF0pKSB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICAvKipcbiAgICogQSBzcGVjaWFsaXplZCB2ZXJzaW9uIG9mIGBfLm1hcGAgZm9yIGFycmF5cyB3aXRob3V0IHN1cHBvcnQgZm9yIGl0ZXJhdGVlXG4gICAqIHNob3J0aGFuZHMuXG4gICAqXG4gICAqIEBwcml2YXRlXG4gICAqIEBwYXJhbSB7QXJyYXl9IFthcnJheV0gVGhlIGFycmF5IHRvIGl0ZXJhdGUgb3Zlci5cbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gaXRlcmF0ZWUgVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIGl0ZXJhdGlvbi5cbiAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBuZXcgbWFwcGVkIGFycmF5LlxuICAgKi9cbiAgZnVuY3Rpb24gYXJyYXlNYXAoYXJyYXksIGl0ZXJhdGVlKSB7XG4gICAgdmFyIGluZGV4ID0gLTEsXG4gICAgICAgIGxlbmd0aCA9IGFycmF5ID09IG51bGwgPyAwIDogYXJyYXkubGVuZ3RoLFxuICAgICAgICByZXN1bHQgPSBBcnJheShsZW5ndGgpO1xuXG4gICAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHtcbiAgICAgIHJlc3VsdFtpbmRleF0gPSBpdGVyYXRlZShhcnJheVtpbmRleF0sIGluZGV4LCBhcnJheSk7XG4gICAgfVxuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICAvKipcbiAgICogQXBwZW5kcyB0aGUgZWxlbWVudHMgb2YgYHZhbHVlc2AgdG8gYGFycmF5YC5cbiAgICpcbiAgICogQHByaXZhdGVcbiAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIG1vZGlmeS5cbiAgICogQHBhcmFtIHtBcnJheX0gdmFsdWVzIFRoZSB2YWx1ZXMgdG8gYXBwZW5kLlxuICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgYGFycmF5YC5cbiAgICovXG4gIGZ1bmN0aW9uIGFycmF5UHVzaChhcnJheSwgdmFsdWVzKSB7XG4gICAgdmFyIGluZGV4ID0gLTEsXG4gICAgICAgIGxlbmd0aCA9IHZhbHVlcy5sZW5ndGgsXG4gICAgICAgIG9mZnNldCA9IGFycmF5Lmxlbmd0aDtcblxuICAgIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XG4gICAgICBhcnJheVtvZmZzZXQgKyBpbmRleF0gPSB2YWx1ZXNbaW5kZXhdO1xuICAgIH1cbiAgICByZXR1cm4gYXJyYXk7XG4gIH1cblxuICAvKipcbiAgICogQSBzcGVjaWFsaXplZCB2ZXJzaW9uIG9mIGBfLnJlZHVjZWAgZm9yIGFycmF5cyB3aXRob3V0IHN1cHBvcnQgZm9yXG4gICAqIGl0ZXJhdGVlIHNob3J0aGFuZHMuXG4gICAqXG4gICAqIEBwcml2YXRlXG4gICAqIEBwYXJhbSB7QXJyYXl9IFthcnJheV0gVGhlIGFycmF5IHRvIGl0ZXJhdGUgb3Zlci5cbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gaXRlcmF0ZWUgVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIGl0ZXJhdGlvbi5cbiAgICogQHBhcmFtIHsqfSBbYWNjdW11bGF0b3JdIFRoZSBpbml0aWFsIHZhbHVlLlxuICAgKiBAcGFyYW0ge2Jvb2xlYW59IFtpbml0QWNjdW1dIFNwZWNpZnkgdXNpbmcgdGhlIGZpcnN0IGVsZW1lbnQgb2YgYGFycmF5YCBhc1xuICAgKiAgdGhlIGluaXRpYWwgdmFsdWUuXG4gICAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSBhY2N1bXVsYXRlZCB2YWx1ZS5cbiAgICovXG4gIGZ1bmN0aW9uIGFycmF5UmVkdWNlKGFycmF5LCBpdGVyYXRlZSwgYWNjdW11bGF0b3IsIGluaXRBY2N1bSkge1xuICAgIHZhciBpbmRleCA9IC0xLFxuICAgICAgICBsZW5ndGggPSBhcnJheSA9PSBudWxsID8gMCA6IGFycmF5Lmxlbmd0aDtcblxuICAgIGlmIChpbml0QWNjdW0gJiYgbGVuZ3RoKSB7XG4gICAgICBhY2N1bXVsYXRvciA9IGFycmF5WysraW5kZXhdO1xuICAgIH1cbiAgICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgICAgYWNjdW11bGF0b3IgPSBpdGVyYXRlZShhY2N1bXVsYXRvciwgYXJyYXlbaW5kZXhdLCBpbmRleCwgYXJyYXkpO1xuICAgIH1cbiAgICByZXR1cm4gYWNjdW11bGF0b3I7XG4gIH1cblxuICAvKipcbiAgICogQSBzcGVjaWFsaXplZCB2ZXJzaW9uIG9mIGBfLnJlZHVjZVJpZ2h0YCBmb3IgYXJyYXlzIHdpdGhvdXQgc3VwcG9ydCBmb3JcbiAgICogaXRlcmF0ZWUgc2hvcnRoYW5kcy5cbiAgICpcbiAgICogQHByaXZhdGVcbiAgICogQHBhcmFtIHtBcnJheX0gW2FycmF5XSBUaGUgYXJyYXkgdG8gaXRlcmF0ZSBvdmVyLlxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBpdGVyYXRlZSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICAgKiBAcGFyYW0geyp9IFthY2N1bXVsYXRvcl0gVGhlIGluaXRpYWwgdmFsdWUuXG4gICAqIEBwYXJhbSB7Ym9vbGVhbn0gW2luaXRBY2N1bV0gU3BlY2lmeSB1c2luZyB0aGUgbGFzdCBlbGVtZW50IG9mIGBhcnJheWAgYXNcbiAgICogIHRoZSBpbml0aWFsIHZhbHVlLlxuICAgKiBAcmV0dXJucyB7Kn0gUmV0dXJucyB0aGUgYWNjdW11bGF0ZWQgdmFsdWUuXG4gICAqL1xuICBmdW5jdGlvbiBhcnJheVJlZHVjZVJpZ2h0KGFycmF5LCBpdGVyYXRlZSwgYWNjdW11bGF0b3IsIGluaXRBY2N1bSkge1xuICAgIHZhciBsZW5ndGggPSBhcnJheSA9PSBudWxsID8gMCA6IGFycmF5Lmxlbmd0aDtcbiAgICBpZiAoaW5pdEFjY3VtICYmIGxlbmd0aCkge1xuICAgICAgYWNjdW11bGF0b3IgPSBhcnJheVstLWxlbmd0aF07XG4gICAgfVxuICAgIHdoaWxlIChsZW5ndGgtLSkge1xuICAgICAgYWNjdW11bGF0b3IgPSBpdGVyYXRlZShhY2N1bXVsYXRvciwgYXJyYXlbbGVuZ3RoXSwgbGVuZ3RoLCBhcnJheSk7XG4gICAgfVxuICAgIHJldHVybiBhY2N1bXVsYXRvcjtcbiAgfVxuXG4gIC8qKlxuICAgKiBBIHNwZWNpYWxpemVkIHZlcnNpb24gb2YgYF8uc29tZWAgZm9yIGFycmF5cyB3aXRob3V0IHN1cHBvcnQgZm9yIGl0ZXJhdGVlXG4gICAqIHNob3J0aGFuZHMuXG4gICAqXG4gICAqIEBwcml2YXRlXG4gICAqIEBwYXJhbSB7QXJyYXl9IFthcnJheV0gVGhlIGFycmF5IHRvIGl0ZXJhdGUgb3Zlci5cbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gcHJlZGljYXRlIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uXG4gICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBhbnkgZWxlbWVudCBwYXNzZXMgdGhlIHByZWRpY2F0ZSBjaGVjayxcbiAgICogIGVsc2UgYGZhbHNlYC5cbiAgICovXG4gIGZ1bmN0aW9uIGFycmF5U29tZShhcnJheSwgcHJlZGljYXRlKSB7XG4gICAgdmFyIGluZGV4ID0gLTEsXG4gICAgICAgIGxlbmd0aCA9IGFycmF5ID09IG51bGwgPyAwIDogYXJyYXkubGVuZ3RoO1xuXG4gICAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHtcbiAgICAgIGlmIChwcmVkaWNhdGUoYXJyYXlbaW5kZXhdLCBpbmRleCwgYXJyYXkpKSB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICAvKipcbiAgICogR2V0cyB0aGUgc2l6ZSBvZiBhbiBBU0NJSSBgc3RyaW5nYC5cbiAgICpcbiAgICogQHByaXZhdGVcbiAgICogQHBhcmFtIHtzdHJpbmd9IHN0cmluZyBUaGUgc3RyaW5nIGluc3BlY3QuXG4gICAqIEByZXR1cm5zIHtudW1iZXJ9IFJldHVybnMgdGhlIHN0cmluZyBzaXplLlxuICAgKi9cbiAgdmFyIGFzY2lpU2l6ZSA9IGJhc2VQcm9wZXJ0eSgnbGVuZ3RoJyk7XG5cbiAgLyoqXG4gICAqIENvbnZlcnRzIGFuIEFTQ0lJIGBzdHJpbmdgIHRvIGFuIGFycmF5LlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge3N0cmluZ30gc3RyaW5nIFRoZSBzdHJpbmcgdG8gY29udmVydC5cbiAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBjb252ZXJ0ZWQgYXJyYXkuXG4gICAqL1xuICBmdW5jdGlvbiBhc2NpaVRvQXJyYXkoc3RyaW5nKSB7XG4gICAgcmV0dXJuIHN0cmluZy5zcGxpdCgnJyk7XG4gIH1cblxuICAvKipcbiAgICogU3BsaXRzIGFuIEFTQ0lJIGBzdHJpbmdgIGludG8gYW4gYXJyYXkgb2YgaXRzIHdvcmRzLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge3N0cmluZ30gVGhlIHN0cmluZyB0byBpbnNwZWN0LlxuICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIHdvcmRzIG9mIGBzdHJpbmdgLlxuICAgKi9cbiAgZnVuY3Rpb24gYXNjaWlXb3JkcyhzdHJpbmcpIHtcbiAgICByZXR1cm4gc3RyaW5nLm1hdGNoKHJlQXNjaWlXb3JkKSB8fCBbXTtcbiAgfVxuXG4gIC8qKlxuICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBtZXRob2RzIGxpa2UgYF8uZmluZEtleWAgYW5kIGBfLmZpbmRMYXN0S2V5YCxcbiAgICogd2l0aG91dCBzdXBwb3J0IGZvciBpdGVyYXRlZSBzaG9ydGhhbmRzLCB3aGljaCBpdGVyYXRlcyBvdmVyIGBjb2xsZWN0aW9uYFxuICAgKiB1c2luZyBgZWFjaEZ1bmNgLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge0FycmF5fE9iamVjdH0gY29sbGVjdGlvbiBUaGUgY29sbGVjdGlvbiB0byBpbnNwZWN0LlxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBwcmVkaWNhdGUgVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIGl0ZXJhdGlvbi5cbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gZWFjaEZ1bmMgVGhlIGZ1bmN0aW9uIHRvIGl0ZXJhdGUgb3ZlciBgY29sbGVjdGlvbmAuXG4gICAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSBmb3VuZCBlbGVtZW50IG9yIGl0cyBrZXksIGVsc2UgYHVuZGVmaW5lZGAuXG4gICAqL1xuICBmdW5jdGlvbiBiYXNlRmluZEtleShjb2xsZWN0aW9uLCBwcmVkaWNhdGUsIGVhY2hGdW5jKSB7XG4gICAgdmFyIHJlc3VsdDtcbiAgICBlYWNoRnVuYyhjb2xsZWN0aW9uLCBmdW5jdGlvbih2YWx1ZSwga2V5LCBjb2xsZWN0aW9uKSB7XG4gICAgICBpZiAocHJlZGljYXRlKHZhbHVlLCBrZXksIGNvbGxlY3Rpb24pKSB7XG4gICAgICAgIHJlc3VsdCA9IGtleTtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgIH0pO1xuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICAvKipcbiAgICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uZmluZEluZGV4YCBhbmQgYF8uZmluZExhc3RJbmRleGAgd2l0aG91dFxuICAgKiBzdXBwb3J0IGZvciBpdGVyYXRlZSBzaG9ydGhhbmRzLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gaW5zcGVjdC5cbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gcHJlZGljYXRlIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBmcm9tSW5kZXggVGhlIGluZGV4IHRvIHNlYXJjaCBmcm9tLlxuICAgKiBAcGFyYW0ge2Jvb2xlYW59IFtmcm9tUmlnaHRdIFNwZWNpZnkgaXRlcmF0aW5nIGZyb20gcmlnaHQgdG8gbGVmdC5cbiAgICogQHJldHVybnMge251bWJlcn0gUmV0dXJucyB0aGUgaW5kZXggb2YgdGhlIG1hdGNoZWQgdmFsdWUsIGVsc2UgYC0xYC5cbiAgICovXG4gIGZ1bmN0aW9uIGJhc2VGaW5kSW5kZXgoYXJyYXksIHByZWRpY2F0ZSwgZnJvbUluZGV4LCBmcm9tUmlnaHQpIHtcbiAgICB2YXIgbGVuZ3RoID0gYXJyYXkubGVuZ3RoLFxuICAgICAgICBpbmRleCA9IGZyb21JbmRleCArIChmcm9tUmlnaHQgPyAxIDogLTEpO1xuXG4gICAgd2hpbGUgKChmcm9tUmlnaHQgPyBpbmRleC0tIDogKytpbmRleCA8IGxlbmd0aCkpIHtcbiAgICAgIGlmIChwcmVkaWNhdGUoYXJyYXlbaW5kZXhdLCBpbmRleCwgYXJyYXkpKSB7XG4gICAgICAgIHJldHVybiBpbmRleDtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIC0xO1xuICB9XG5cbiAgLyoqXG4gICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLmluZGV4T2ZgIHdpdGhvdXQgYGZyb21JbmRleGAgYm91bmRzIGNoZWNrcy5cbiAgICpcbiAgICogQHByaXZhdGVcbiAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIGluc3BlY3QuXG4gICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIHNlYXJjaCBmb3IuXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBmcm9tSW5kZXggVGhlIGluZGV4IHRvIHNlYXJjaCBmcm9tLlxuICAgKiBAcmV0dXJucyB7bnVtYmVyfSBSZXR1cm5zIHRoZSBpbmRleCBvZiB0aGUgbWF0Y2hlZCB2YWx1ZSwgZWxzZSBgLTFgLlxuICAgKi9cbiAgZnVuY3Rpb24gYmFzZUluZGV4T2YoYXJyYXksIHZhbHVlLCBmcm9tSW5kZXgpIHtcbiAgICByZXR1cm4gdmFsdWUgPT09IHZhbHVlXG4gICAgICA/IHN0cmljdEluZGV4T2YoYXJyYXksIHZhbHVlLCBmcm9tSW5kZXgpXG4gICAgICA6IGJhc2VGaW5kSW5kZXgoYXJyYXksIGJhc2VJc05hTiwgZnJvbUluZGV4KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBUaGlzIGZ1bmN0aW9uIGlzIGxpa2UgYGJhc2VJbmRleE9mYCBleGNlcHQgdGhhdCBpdCBhY2NlcHRzIGEgY29tcGFyYXRvci5cbiAgICpcbiAgICogQHByaXZhdGVcbiAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIGluc3BlY3QuXG4gICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIHNlYXJjaCBmb3IuXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBmcm9tSW5kZXggVGhlIGluZGV4IHRvIHNlYXJjaCBmcm9tLlxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBjb21wYXJhdG9yIFRoZSBjb21wYXJhdG9yIGludm9rZWQgcGVyIGVsZW1lbnQuXG4gICAqIEByZXR1cm5zIHtudW1iZXJ9IFJldHVybnMgdGhlIGluZGV4IG9mIHRoZSBtYXRjaGVkIHZhbHVlLCBlbHNlIGAtMWAuXG4gICAqL1xuICBmdW5jdGlvbiBiYXNlSW5kZXhPZldpdGgoYXJyYXksIHZhbHVlLCBmcm9tSW5kZXgsIGNvbXBhcmF0b3IpIHtcbiAgICB2YXIgaW5kZXggPSBmcm9tSW5kZXggLSAxLFxuICAgICAgICBsZW5ndGggPSBhcnJheS5sZW5ndGg7XG5cbiAgICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgICAgaWYgKGNvbXBhcmF0b3IoYXJyYXlbaW5kZXhdLCB2YWx1ZSkpIHtcbiAgICAgICAgcmV0dXJuIGluZGV4O1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gLTE7XG4gIH1cblxuICAvKipcbiAgICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uaXNOYU5gIHdpdGhvdXQgc3VwcG9ydCBmb3IgbnVtYmVyIG9iamVjdHMuXG4gICAqXG4gICAqIEBwcml2YXRlXG4gICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBgTmFOYCwgZWxzZSBgZmFsc2VgLlxuICAgKi9cbiAgZnVuY3Rpb24gYmFzZUlzTmFOKHZhbHVlKSB7XG4gICAgcmV0dXJuIHZhbHVlICE9PSB2YWx1ZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5tZWFuYCBhbmQgYF8ubWVhbkJ5YCB3aXRob3V0IHN1cHBvcnQgZm9yXG4gICAqIGl0ZXJhdGVlIHNob3J0aGFuZHMuXG4gICAqXG4gICAqIEBwcml2YXRlXG4gICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBpdGVyYXRlIG92ZXIuXG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IGl0ZXJhdGVlIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uXG4gICAqIEByZXR1cm5zIHtudW1iZXJ9IFJldHVybnMgdGhlIG1lYW4uXG4gICAqL1xuICBmdW5jdGlvbiBiYXNlTWVhbihhcnJheSwgaXRlcmF0ZWUpIHtcbiAgICB2YXIgbGVuZ3RoID0gYXJyYXkgPT0gbnVsbCA/IDAgOiBhcnJheS5sZW5ndGg7XG4gICAgcmV0dXJuIGxlbmd0aCA/IChiYXNlU3VtKGFycmF5LCBpdGVyYXRlZSkgLyBsZW5ndGgpIDogTkFOO1xuICB9XG5cbiAgLyoqXG4gICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLnByb3BlcnR5YCB3aXRob3V0IHN1cHBvcnQgZm9yIGRlZXAgcGF0aHMuXG4gICAqXG4gICAqIEBwcml2YXRlXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgVGhlIGtleSBvZiB0aGUgcHJvcGVydHkgdG8gZ2V0LlxuICAgKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBhY2Nlc3NvciBmdW5jdGlvbi5cbiAgICovXG4gIGZ1bmN0aW9uIGJhc2VQcm9wZXJ0eShrZXkpIHtcbiAgICByZXR1cm4gZnVuY3Rpb24ob2JqZWN0KSB7XG4gICAgICByZXR1cm4gb2JqZWN0ID09IG51bGwgPyB1bmRlZmluZWQgOiBvYmplY3Rba2V5XTtcbiAgICB9O1xuICB9XG5cbiAgLyoqXG4gICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLnByb3BlcnR5T2ZgIHdpdGhvdXQgc3VwcG9ydCBmb3IgZGVlcCBwYXRocy5cbiAgICpcbiAgICogQHByaXZhdGVcbiAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIHF1ZXJ5LlxuICAgKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBhY2Nlc3NvciBmdW5jdGlvbi5cbiAgICovXG4gIGZ1bmN0aW9uIGJhc2VQcm9wZXJ0eU9mKG9iamVjdCkge1xuICAgIHJldHVybiBmdW5jdGlvbihrZXkpIHtcbiAgICAgIHJldHVybiBvYmplY3QgPT0gbnVsbCA/IHVuZGVmaW5lZCA6IG9iamVjdFtrZXldO1xuICAgIH07XG4gIH1cblxuICAvKipcbiAgICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8ucmVkdWNlYCBhbmQgYF8ucmVkdWNlUmlnaHRgLCB3aXRob3V0IHN1cHBvcnRcbiAgICogZm9yIGl0ZXJhdGVlIHNob3J0aGFuZHMsIHdoaWNoIGl0ZXJhdGVzIG92ZXIgYGNvbGxlY3Rpb25gIHVzaW5nIGBlYWNoRnVuY2AuXG4gICAqXG4gICAqIEBwcml2YXRlXG4gICAqIEBwYXJhbSB7QXJyYXl8T2JqZWN0fSBjb2xsZWN0aW9uIFRoZSBjb2xsZWN0aW9uIHRvIGl0ZXJhdGUgb3Zlci5cbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gaXRlcmF0ZWUgVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIGl0ZXJhdGlvbi5cbiAgICogQHBhcmFtIHsqfSBhY2N1bXVsYXRvciBUaGUgaW5pdGlhbCB2YWx1ZS5cbiAgICogQHBhcmFtIHtib29sZWFufSBpbml0QWNjdW0gU3BlY2lmeSB1c2luZyB0aGUgZmlyc3Qgb3IgbGFzdCBlbGVtZW50IG9mXG4gICAqICBgY29sbGVjdGlvbmAgYXMgdGhlIGluaXRpYWwgdmFsdWUuXG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IGVhY2hGdW5jIFRoZSBmdW5jdGlvbiB0byBpdGVyYXRlIG92ZXIgYGNvbGxlY3Rpb25gLlxuICAgKiBAcmV0dXJucyB7Kn0gUmV0dXJucyB0aGUgYWNjdW11bGF0ZWQgdmFsdWUuXG4gICAqL1xuICBmdW5jdGlvbiBiYXNlUmVkdWNlKGNvbGxlY3Rpb24sIGl0ZXJhdGVlLCBhY2N1bXVsYXRvciwgaW5pdEFjY3VtLCBlYWNoRnVuYykge1xuICAgIGVhY2hGdW5jKGNvbGxlY3Rpb24sIGZ1bmN0aW9uKHZhbHVlLCBpbmRleCwgY29sbGVjdGlvbikge1xuICAgICAgYWNjdW11bGF0b3IgPSBpbml0QWNjdW1cbiAgICAgICAgPyAoaW5pdEFjY3VtID0gZmFsc2UsIHZhbHVlKVxuICAgICAgICA6IGl0ZXJhdGVlKGFjY3VtdWxhdG9yLCB2YWx1ZSwgaW5kZXgsIGNvbGxlY3Rpb24pO1xuICAgIH0pO1xuICAgIHJldHVybiBhY2N1bXVsYXRvcjtcbiAgfVxuXG4gIC8qKlxuICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5zb3J0QnlgIHdoaWNoIHVzZXMgYGNvbXBhcmVyYCB0byBkZWZpbmUgdGhlXG4gICAqIHNvcnQgb3JkZXIgb2YgYGFycmF5YCBhbmQgcmVwbGFjZXMgY3JpdGVyaWEgb2JqZWN0cyB3aXRoIHRoZWlyIGNvcnJlc3BvbmRpbmdcbiAgICogdmFsdWVzLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gc29ydC5cbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gY29tcGFyZXIgVGhlIGZ1bmN0aW9uIHRvIGRlZmluZSBzb3J0IG9yZGVyLlxuICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgYGFycmF5YC5cbiAgICovXG4gIGZ1bmN0aW9uIGJhc2VTb3J0QnkoYXJyYXksIGNvbXBhcmVyKSB7XG4gICAgdmFyIGxlbmd0aCA9IGFycmF5Lmxlbmd0aDtcblxuICAgIGFycmF5LnNvcnQoY29tcGFyZXIpO1xuICAgIHdoaWxlIChsZW5ndGgtLSkge1xuICAgICAgYXJyYXlbbGVuZ3RoXSA9IGFycmF5W2xlbmd0aF0udmFsdWU7XG4gICAgfVxuICAgIHJldHVybiBhcnJheTtcbiAgfVxuXG4gIC8qKlxuICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5zdW1gIGFuZCBgXy5zdW1CeWAgd2l0aG91dCBzdXBwb3J0IGZvclxuICAgKiBpdGVyYXRlZSBzaG9ydGhhbmRzLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gaXRlcmF0ZSBvdmVyLlxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBpdGVyYXRlZSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICAgKiBAcmV0dXJucyB7bnVtYmVyfSBSZXR1cm5zIHRoZSBzdW0uXG4gICAqL1xuICBmdW5jdGlvbiBiYXNlU3VtKGFycmF5LCBpdGVyYXRlZSkge1xuICAgIHZhciByZXN1bHQsXG4gICAgICAgIGluZGV4ID0gLTEsXG4gICAgICAgIGxlbmd0aCA9IGFycmF5Lmxlbmd0aDtcblxuICAgIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XG4gICAgICB2YXIgY3VycmVudCA9IGl0ZXJhdGVlKGFycmF5W2luZGV4XSk7XG4gICAgICBpZiAoY3VycmVudCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHJlc3VsdCA9IHJlc3VsdCA9PT0gdW5kZWZpbmVkID8gY3VycmVudCA6IChyZXN1bHQgKyBjdXJyZW50KTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuXG4gIC8qKlxuICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy50aW1lc2Agd2l0aG91dCBzdXBwb3J0IGZvciBpdGVyYXRlZSBzaG9ydGhhbmRzXG4gICAqIG9yIG1heCBhcnJheSBsZW5ndGggY2hlY2tzLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge251bWJlcn0gbiBUaGUgbnVtYmVyIG9mIHRpbWVzIHRvIGludm9rZSBgaXRlcmF0ZWVgLlxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBpdGVyYXRlZSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIGFycmF5IG9mIHJlc3VsdHMuXG4gICAqL1xuICBmdW5jdGlvbiBiYXNlVGltZXMobiwgaXRlcmF0ZWUpIHtcbiAgICB2YXIgaW5kZXggPSAtMSxcbiAgICAgICAgcmVzdWx0ID0gQXJyYXkobik7XG5cbiAgICB3aGlsZSAoKytpbmRleCA8IG4pIHtcbiAgICAgIHJlc3VsdFtpbmRleF0gPSBpdGVyYXRlZShpbmRleCk7XG4gICAgfVxuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICAvKipcbiAgICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8udG9QYWlyc2AgYW5kIGBfLnRvUGFpcnNJbmAgd2hpY2ggY3JlYXRlcyBhbiBhcnJheVxuICAgKiBvZiBrZXktdmFsdWUgcGFpcnMgZm9yIGBvYmplY3RgIGNvcnJlc3BvbmRpbmcgdG8gdGhlIHByb3BlcnR5IG5hbWVzIG9mIGBwcm9wc2AuXG4gICAqXG4gICAqIEBwcml2YXRlXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBxdWVyeS5cbiAgICogQHBhcmFtIHtBcnJheX0gcHJvcHMgVGhlIHByb3BlcnR5IG5hbWVzIHRvIGdldCB2YWx1ZXMgZm9yLlxuICAgKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIHRoZSBrZXktdmFsdWUgcGFpcnMuXG4gICAqL1xuICBmdW5jdGlvbiBiYXNlVG9QYWlycyhvYmplY3QsIHByb3BzKSB7XG4gICAgcmV0dXJuIGFycmF5TWFwKHByb3BzLCBmdW5jdGlvbihrZXkpIHtcbiAgICAgIHJldHVybiBba2V5LCBvYmplY3Rba2V5XV07XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8udHJpbWAuXG4gICAqXG4gICAqIEBwcml2YXRlXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBzdHJpbmcgVGhlIHN0cmluZyB0byB0cmltLlxuICAgKiBAcmV0dXJucyB7c3RyaW5nfSBSZXR1cm5zIHRoZSB0cmltbWVkIHN0cmluZy5cbiAgICovXG4gIGZ1bmN0aW9uIGJhc2VUcmltKHN0cmluZykge1xuICAgIHJldHVybiBzdHJpbmdcbiAgICAgID8gc3RyaW5nLnNsaWNlKDAsIHRyaW1tZWRFbmRJbmRleChzdHJpbmcpICsgMSkucmVwbGFjZShyZVRyaW1TdGFydCwgJycpXG4gICAgICA6IHN0cmluZztcbiAgfVxuXG4gIC8qKlxuICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy51bmFyeWAgd2l0aG91dCBzdXBwb3J0IGZvciBzdG9yaW5nIG1ldGFkYXRhLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byBjYXAgYXJndW1lbnRzIGZvci5cbiAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgY2FwcGVkIGZ1bmN0aW9uLlxuICAgKi9cbiAgZnVuY3Rpb24gYmFzZVVuYXJ5KGZ1bmMpIHtcbiAgICByZXR1cm4gZnVuY3Rpb24odmFsdWUpIHtcbiAgICAgIHJldHVybiBmdW5jKHZhbHVlKTtcbiAgICB9O1xuICB9XG5cbiAgLyoqXG4gICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLnZhbHVlc2AgYW5kIGBfLnZhbHVlc0luYCB3aGljaCBjcmVhdGVzIGFuXG4gICAqIGFycmF5IG9mIGBvYmplY3RgIHByb3BlcnR5IHZhbHVlcyBjb3JyZXNwb25kaW5nIHRvIHRoZSBwcm9wZXJ0eSBuYW1lc1xuICAgKiBvZiBgcHJvcHNgLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gcXVlcnkuXG4gICAqIEBwYXJhbSB7QXJyYXl9IHByb3BzIFRoZSBwcm9wZXJ0eSBuYW1lcyB0byBnZXQgdmFsdWVzIGZvci5cbiAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyB0aGUgYXJyYXkgb2YgcHJvcGVydHkgdmFsdWVzLlxuICAgKi9cbiAgZnVuY3Rpb24gYmFzZVZhbHVlcyhvYmplY3QsIHByb3BzKSB7XG4gICAgcmV0dXJuIGFycmF5TWFwKHByb3BzLCBmdW5jdGlvbihrZXkpIHtcbiAgICAgIHJldHVybiBvYmplY3Rba2V5XTtcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDaGVja3MgaWYgYSBgY2FjaGVgIHZhbHVlIGZvciBga2V5YCBleGlzdHMuXG4gICAqXG4gICAqIEBwcml2YXRlXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBjYWNoZSBUaGUgY2FjaGUgdG8gcXVlcnkuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgVGhlIGtleSBvZiB0aGUgZW50cnkgdG8gY2hlY2suXG4gICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBhbiBlbnRyeSBmb3IgYGtleWAgZXhpc3RzLCBlbHNlIGBmYWxzZWAuXG4gICAqL1xuICBmdW5jdGlvbiBjYWNoZUhhcyhjYWNoZSwga2V5KSB7XG4gICAgcmV0dXJuIGNhY2hlLmhhcyhrZXkpO1xuICB9XG5cbiAgLyoqXG4gICAqIFVzZWQgYnkgYF8udHJpbWAgYW5kIGBfLnRyaW1TdGFydGAgdG8gZ2V0IHRoZSBpbmRleCBvZiB0aGUgZmlyc3Qgc3RyaW5nIHN5bWJvbFxuICAgKiB0aGF0IGlzIG5vdCBmb3VuZCBpbiB0aGUgY2hhcmFjdGVyIHN5bWJvbHMuXG4gICAqXG4gICAqIEBwcml2YXRlXG4gICAqIEBwYXJhbSB7QXJyYXl9IHN0clN5bWJvbHMgVGhlIHN0cmluZyBzeW1ib2xzIHRvIGluc3BlY3QuXG4gICAqIEBwYXJhbSB7QXJyYXl9IGNoclN5bWJvbHMgVGhlIGNoYXJhY3RlciBzeW1ib2xzIHRvIGZpbmQuXG4gICAqIEByZXR1cm5zIHtudW1iZXJ9IFJldHVybnMgdGhlIGluZGV4IG9mIHRoZSBmaXJzdCB1bm1hdGNoZWQgc3RyaW5nIHN5bWJvbC5cbiAgICovXG4gIGZ1bmN0aW9uIGNoYXJzU3RhcnRJbmRleChzdHJTeW1ib2xzLCBjaHJTeW1ib2xzKSB7XG4gICAgdmFyIGluZGV4ID0gLTEsXG4gICAgICAgIGxlbmd0aCA9IHN0clN5bWJvbHMubGVuZ3RoO1xuXG4gICAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGggJiYgYmFzZUluZGV4T2YoY2hyU3ltYm9scywgc3RyU3ltYm9sc1tpbmRleF0sIDApID4gLTEpIHt9XG4gICAgcmV0dXJuIGluZGV4O1xuICB9XG5cbiAgLyoqXG4gICAqIFVzZWQgYnkgYF8udHJpbWAgYW5kIGBfLnRyaW1FbmRgIHRvIGdldCB0aGUgaW5kZXggb2YgdGhlIGxhc3Qgc3RyaW5nIHN5bWJvbFxuICAgKiB0aGF0IGlzIG5vdCBmb3VuZCBpbiB0aGUgY2hhcmFjdGVyIHN5bWJvbHMuXG4gICAqXG4gICAqIEBwcml2YXRlXG4gICAqIEBwYXJhbSB7QXJyYXl9IHN0clN5bWJvbHMgVGhlIHN0cmluZyBzeW1ib2xzIHRvIGluc3BlY3QuXG4gICAqIEBwYXJhbSB7QXJyYXl9IGNoclN5bWJvbHMgVGhlIGNoYXJhY3RlciBzeW1ib2xzIHRvIGZpbmQuXG4gICAqIEByZXR1cm5zIHtudW1iZXJ9IFJldHVybnMgdGhlIGluZGV4IG9mIHRoZSBsYXN0IHVubWF0Y2hlZCBzdHJpbmcgc3ltYm9sLlxuICAgKi9cbiAgZnVuY3Rpb24gY2hhcnNFbmRJbmRleChzdHJTeW1ib2xzLCBjaHJTeW1ib2xzKSB7XG4gICAgdmFyIGluZGV4ID0gc3RyU3ltYm9scy5sZW5ndGg7XG5cbiAgICB3aGlsZSAoaW5kZXgtLSAmJiBiYXNlSW5kZXhPZihjaHJTeW1ib2xzLCBzdHJTeW1ib2xzW2luZGV4XSwgMCkgPiAtMSkge31cbiAgICByZXR1cm4gaW5kZXg7XG4gIH1cblxuICAvKipcbiAgICogR2V0cyB0aGUgbnVtYmVyIG9mIGBwbGFjZWhvbGRlcmAgb2NjdXJyZW5jZXMgaW4gYGFycmF5YC5cbiAgICpcbiAgICogQHByaXZhdGVcbiAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIGluc3BlY3QuXG4gICAqIEBwYXJhbSB7Kn0gcGxhY2Vob2xkZXIgVGhlIHBsYWNlaG9sZGVyIHRvIHNlYXJjaCBmb3IuXG4gICAqIEByZXR1cm5zIHtudW1iZXJ9IFJldHVybnMgdGhlIHBsYWNlaG9sZGVyIGNvdW50LlxuICAgKi9cbiAgZnVuY3Rpb24gY291bnRIb2xkZXJzKGFycmF5LCBwbGFjZWhvbGRlcikge1xuICAgIHZhciBsZW5ndGggPSBhcnJheS5sZW5ndGgsXG4gICAgICAgIHJlc3VsdCA9IDA7XG5cbiAgICB3aGlsZSAobGVuZ3RoLS0pIHtcbiAgICAgIGlmIChhcnJheVtsZW5ndGhdID09PSBwbGFjZWhvbGRlcikge1xuICAgICAgICArK3Jlc3VsdDtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuXG4gIC8qKlxuICAgKiBVc2VkIGJ5IGBfLmRlYnVycmAgdG8gY29udmVydCBMYXRpbi0xIFN1cHBsZW1lbnQgYW5kIExhdGluIEV4dGVuZGVkLUFcbiAgICogbGV0dGVycyB0byBiYXNpYyBMYXRpbiBsZXR0ZXJzLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge3N0cmluZ30gbGV0dGVyIFRoZSBtYXRjaGVkIGxldHRlciB0byBkZWJ1cnIuXG4gICAqIEByZXR1cm5zIHtzdHJpbmd9IFJldHVybnMgdGhlIGRlYnVycmVkIGxldHRlci5cbiAgICovXG4gIHZhciBkZWJ1cnJMZXR0ZXIgPSBiYXNlUHJvcGVydHlPZihkZWJ1cnJlZExldHRlcnMpO1xuXG4gIC8qKlxuICAgKiBVc2VkIGJ5IGBfLmVzY2FwZWAgdG8gY29udmVydCBjaGFyYWN0ZXJzIHRvIEhUTUwgZW50aXRpZXMuXG4gICAqXG4gICAqIEBwcml2YXRlXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBjaHIgVGhlIG1hdGNoZWQgY2hhcmFjdGVyIHRvIGVzY2FwZS5cbiAgICogQHJldHVybnMge3N0cmluZ30gUmV0dXJucyB0aGUgZXNjYXBlZCBjaGFyYWN0ZXIuXG4gICAqL1xuICB2YXIgZXNjYXBlSHRtbENoYXIgPSBiYXNlUHJvcGVydHlPZihodG1sRXNjYXBlcyk7XG5cbiAgLyoqXG4gICAqIFVzZWQgYnkgYF8udGVtcGxhdGVgIHRvIGVzY2FwZSBjaGFyYWN0ZXJzIGZvciBpbmNsdXNpb24gaW4gY29tcGlsZWQgc3RyaW5nIGxpdGVyYWxzLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge3N0cmluZ30gY2hyIFRoZSBtYXRjaGVkIGNoYXJhY3RlciB0byBlc2NhcGUuXG4gICAqIEByZXR1cm5zIHtzdHJpbmd9IFJldHVybnMgdGhlIGVzY2FwZWQgY2hhcmFjdGVyLlxuICAgKi9cbiAgZnVuY3Rpb24gZXNjYXBlU3RyaW5nQ2hhcihjaHIpIHtcbiAgICByZXR1cm4gJ1xcXFwnICsgc3RyaW5nRXNjYXBlc1tjaHJdO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldHMgdGhlIHZhbHVlIGF0IGBrZXlgIG9mIGBvYmplY3RgLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge09iamVjdH0gW29iamVjdF0gVGhlIG9iamVjdCB0byBxdWVyeS5cbiAgICogQHBhcmFtIHtzdHJpbmd9IGtleSBUaGUga2V5IG9mIHRoZSBwcm9wZXJ0eSB0byBnZXQuXG4gICAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSBwcm9wZXJ0eSB2YWx1ZS5cbiAgICovXG4gIGZ1bmN0aW9uIGdldFZhbHVlKG9iamVjdCwga2V5KSB7XG4gICAgcmV0dXJuIG9iamVjdCA9PSBudWxsID8gdW5kZWZpbmVkIDogb2JqZWN0W2tleV07XG4gIH1cblxuICAvKipcbiAgICogQ2hlY2tzIGlmIGBzdHJpbmdgIGNvbnRhaW5zIFVuaWNvZGUgc3ltYm9scy5cbiAgICpcbiAgICogQHByaXZhdGVcbiAgICogQHBhcmFtIHtzdHJpbmd9IHN0cmluZyBUaGUgc3RyaW5nIHRvIGluc3BlY3QuXG4gICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBhIHN5bWJvbCBpcyBmb3VuZCwgZWxzZSBgZmFsc2VgLlxuICAgKi9cbiAgZnVuY3Rpb24gaGFzVW5pY29kZShzdHJpbmcpIHtcbiAgICByZXR1cm4gcmVIYXNVbmljb2RlLnRlc3Qoc3RyaW5nKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDaGVja3MgaWYgYHN0cmluZ2AgY29udGFpbnMgYSB3b3JkIGNvbXBvc2VkIG9mIFVuaWNvZGUgc3ltYm9scy5cbiAgICpcbiAgICogQHByaXZhdGVcbiAgICogQHBhcmFtIHtzdHJpbmd9IHN0cmluZyBUaGUgc3RyaW5nIHRvIGluc3BlY3QuXG4gICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBhIHdvcmQgaXMgZm91bmQsIGVsc2UgYGZhbHNlYC5cbiAgICovXG4gIGZ1bmN0aW9uIGhhc1VuaWNvZGVXb3JkKHN0cmluZykge1xuICAgIHJldHVybiByZUhhc1VuaWNvZGVXb3JkLnRlc3Qoc3RyaW5nKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDb252ZXJ0cyBgaXRlcmF0b3JgIHRvIGFuIGFycmF5LlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge09iamVjdH0gaXRlcmF0b3IgVGhlIGl0ZXJhdG9yIHRvIGNvbnZlcnQuXG4gICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgY29udmVydGVkIGFycmF5LlxuICAgKi9cbiAgZnVuY3Rpb24gaXRlcmF0b3JUb0FycmF5KGl0ZXJhdG9yKSB7XG4gICAgdmFyIGRhdGEsXG4gICAgICAgIHJlc3VsdCA9IFtdO1xuXG4gICAgd2hpbGUgKCEoZGF0YSA9IGl0ZXJhdG9yLm5leHQoKSkuZG9uZSkge1xuICAgICAgcmVzdWx0LnB1c2goZGF0YS52YWx1ZSk7XG4gICAgfVxuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICAvKipcbiAgICogQ29udmVydHMgYG1hcGAgdG8gaXRzIGtleS12YWx1ZSBwYWlycy5cbiAgICpcbiAgICogQHByaXZhdGVcbiAgICogQHBhcmFtIHtPYmplY3R9IG1hcCBUaGUgbWFwIHRvIGNvbnZlcnQuXG4gICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUga2V5LXZhbHVlIHBhaXJzLlxuICAgKi9cbiAgZnVuY3Rpb24gbWFwVG9BcnJheShtYXApIHtcbiAgICB2YXIgaW5kZXggPSAtMSxcbiAgICAgICAgcmVzdWx0ID0gQXJyYXkobWFwLnNpemUpO1xuXG4gICAgbWFwLmZvckVhY2goZnVuY3Rpb24odmFsdWUsIGtleSkge1xuICAgICAgcmVzdWx0WysraW5kZXhdID0gW2tleSwgdmFsdWVdO1xuICAgIH0pO1xuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICAvKipcbiAgICogQ3JlYXRlcyBhIHVuYXJ5IGZ1bmN0aW9uIHRoYXQgaW52b2tlcyBgZnVuY2Agd2l0aCBpdHMgYXJndW1lbnQgdHJhbnNmb3JtZWQuXG4gICAqXG4gICAqIEBwcml2YXRlXG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIHdyYXAuXG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IHRyYW5zZm9ybSBUaGUgYXJndW1lbnQgdHJhbnNmb3JtLlxuICAgKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBmdW5jdGlvbi5cbiAgICovXG4gIGZ1bmN0aW9uIG92ZXJBcmcoZnVuYywgdHJhbnNmb3JtKSB7XG4gICAgcmV0dXJuIGZ1bmN0aW9uKGFyZykge1xuICAgICAgcmV0dXJuIGZ1bmModHJhbnNmb3JtKGFyZykpO1xuICAgIH07XG4gIH1cblxuICAvKipcbiAgICogUmVwbGFjZXMgYWxsIGBwbGFjZWhvbGRlcmAgZWxlbWVudHMgaW4gYGFycmF5YCB3aXRoIGFuIGludGVybmFsIHBsYWNlaG9sZGVyXG4gICAqIGFuZCByZXR1cm5zIGFuIGFycmF5IG9mIHRoZWlyIGluZGV4ZXMuXG4gICAqXG4gICAqIEBwcml2YXRlXG4gICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBtb2RpZnkuXG4gICAqIEBwYXJhbSB7Kn0gcGxhY2Vob2xkZXIgVGhlIHBsYWNlaG9sZGVyIHRvIHJlcGxhY2UuXG4gICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IGFycmF5IG9mIHBsYWNlaG9sZGVyIGluZGV4ZXMuXG4gICAqL1xuICBmdW5jdGlvbiByZXBsYWNlSG9sZGVycyhhcnJheSwgcGxhY2Vob2xkZXIpIHtcbiAgICB2YXIgaW5kZXggPSAtMSxcbiAgICAgICAgbGVuZ3RoID0gYXJyYXkubGVuZ3RoLFxuICAgICAgICByZXNJbmRleCA9IDAsXG4gICAgICAgIHJlc3VsdCA9IFtdO1xuXG4gICAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHtcbiAgICAgIHZhciB2YWx1ZSA9IGFycmF5W2luZGV4XTtcbiAgICAgIGlmICh2YWx1ZSA9PT0gcGxhY2Vob2xkZXIgfHwgdmFsdWUgPT09IFBMQUNFSE9MREVSKSB7XG4gICAgICAgIGFycmF5W2luZGV4XSA9IFBMQUNFSE9MREVSO1xuICAgICAgICByZXN1bHRbcmVzSW5kZXgrK10gPSBpbmRleDtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuXG4gIC8qKlxuICAgKiBDb252ZXJ0cyBgc2V0YCB0byBhbiBhcnJheSBvZiBpdHMgdmFsdWVzLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge09iamVjdH0gc2V0IFRoZSBzZXQgdG8gY29udmVydC5cbiAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSB2YWx1ZXMuXG4gICAqL1xuICBmdW5jdGlvbiBzZXRUb0FycmF5KHNldCkge1xuICAgIHZhciBpbmRleCA9IC0xLFxuICAgICAgICByZXN1bHQgPSBBcnJheShzZXQuc2l6ZSk7XG5cbiAgICBzZXQuZm9yRWFjaChmdW5jdGlvbih2YWx1ZSkge1xuICAgICAgcmVzdWx0WysraW5kZXhdID0gdmFsdWU7XG4gICAgfSk7XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuXG4gIC8qKlxuICAgKiBDb252ZXJ0cyBgc2V0YCB0byBpdHMgdmFsdWUtdmFsdWUgcGFpcnMuXG4gICAqXG4gICAqIEBwcml2YXRlXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBzZXQgVGhlIHNldCB0byBjb252ZXJ0LlxuICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIHZhbHVlLXZhbHVlIHBhaXJzLlxuICAgKi9cbiAgZnVuY3Rpb24gc2V0VG9QYWlycyhzZXQpIHtcbiAgICB2YXIgaW5kZXggPSAtMSxcbiAgICAgICAgcmVzdWx0ID0gQXJyYXkoc2V0LnNpemUpO1xuXG4gICAgc2V0LmZvckVhY2goZnVuY3Rpb24odmFsdWUpIHtcbiAgICAgIHJlc3VsdFsrK2luZGV4XSA9IFt2YWx1ZSwgdmFsdWVdO1xuICAgIH0pO1xuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICAvKipcbiAgICogQSBzcGVjaWFsaXplZCB2ZXJzaW9uIG9mIGBfLmluZGV4T2ZgIHdoaWNoIHBlcmZvcm1zIHN0cmljdCBlcXVhbGl0eVxuICAgKiBjb21wYXJpc29ucyBvZiB2YWx1ZXMsIGkuZS4gYD09PWAuXG4gICAqXG4gICAqIEBwcml2YXRlXG4gICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBpbnNwZWN0LlxuICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBzZWFyY2ggZm9yLlxuICAgKiBAcGFyYW0ge251bWJlcn0gZnJvbUluZGV4IFRoZSBpbmRleCB0byBzZWFyY2ggZnJvbS5cbiAgICogQHJldHVybnMge251bWJlcn0gUmV0dXJucyB0aGUgaW5kZXggb2YgdGhlIG1hdGNoZWQgdmFsdWUsIGVsc2UgYC0xYC5cbiAgICovXG4gIGZ1bmN0aW9uIHN0cmljdEluZGV4T2YoYXJyYXksIHZhbHVlLCBmcm9tSW5kZXgpIHtcbiAgICB2YXIgaW5kZXggPSBmcm9tSW5kZXggLSAxLFxuICAgICAgICBsZW5ndGggPSBhcnJheS5sZW5ndGg7XG5cbiAgICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgICAgaWYgKGFycmF5W2luZGV4XSA9PT0gdmFsdWUpIHtcbiAgICAgICAgcmV0dXJuIGluZGV4O1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gLTE7XG4gIH1cblxuICAvKipcbiAgICogQSBzcGVjaWFsaXplZCB2ZXJzaW9uIG9mIGBfLmxhc3RJbmRleE9mYCB3aGljaCBwZXJmb3JtcyBzdHJpY3QgZXF1YWxpdHlcbiAgICogY29tcGFyaXNvbnMgb2YgdmFsdWVzLCBpLmUuIGA9PT1gLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gaW5zcGVjdC5cbiAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gc2VhcmNoIGZvci5cbiAgICogQHBhcmFtIHtudW1iZXJ9IGZyb21JbmRleCBUaGUgaW5kZXggdG8gc2VhcmNoIGZyb20uXG4gICAqIEByZXR1cm5zIHtudW1iZXJ9IFJldHVybnMgdGhlIGluZGV4IG9mIHRoZSBtYXRjaGVkIHZhbHVlLCBlbHNlIGAtMWAuXG4gICAqL1xuICBmdW5jdGlvbiBzdHJpY3RMYXN0SW5kZXhPZihhcnJheSwgdmFsdWUsIGZyb21JbmRleCkge1xuICAgIHZhciBpbmRleCA9IGZyb21JbmRleCArIDE7XG4gICAgd2hpbGUgKGluZGV4LS0pIHtcbiAgICAgIGlmIChhcnJheVtpbmRleF0gPT09IHZhbHVlKSB7XG4gICAgICAgIHJldHVybiBpbmRleDtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGluZGV4O1xuICB9XG5cbiAgLyoqXG4gICAqIEdldHMgdGhlIG51bWJlciBvZiBzeW1ib2xzIGluIGBzdHJpbmdgLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge3N0cmluZ30gc3RyaW5nIFRoZSBzdHJpbmcgdG8gaW5zcGVjdC5cbiAgICogQHJldHVybnMge251bWJlcn0gUmV0dXJucyB0aGUgc3RyaW5nIHNpemUuXG4gICAqL1xuICBmdW5jdGlvbiBzdHJpbmdTaXplKHN0cmluZykge1xuICAgIHJldHVybiBoYXNVbmljb2RlKHN0cmluZylcbiAgICAgID8gdW5pY29kZVNpemUoc3RyaW5nKVxuICAgICAgOiBhc2NpaVNpemUoc3RyaW5nKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDb252ZXJ0cyBgc3RyaW5nYCB0byBhbiBhcnJheS5cbiAgICpcbiAgICogQHByaXZhdGVcbiAgICogQHBhcmFtIHtzdHJpbmd9IHN0cmluZyBUaGUgc3RyaW5nIHRvIGNvbnZlcnQuXG4gICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgY29udmVydGVkIGFycmF5LlxuICAgKi9cbiAgZnVuY3Rpb24gc3RyaW5nVG9BcnJheShzdHJpbmcpIHtcbiAgICByZXR1cm4gaGFzVW5pY29kZShzdHJpbmcpXG4gICAgICA/IHVuaWNvZGVUb0FycmF5KHN0cmluZylcbiAgICAgIDogYXNjaWlUb0FycmF5KHN0cmluZyk7XG4gIH1cblxuICAvKipcbiAgICogVXNlZCBieSBgXy50cmltYCBhbmQgYF8udHJpbUVuZGAgdG8gZ2V0IHRoZSBpbmRleCBvZiB0aGUgbGFzdCBub24td2hpdGVzcGFjZVxuICAgKiBjaGFyYWN0ZXIgb2YgYHN0cmluZ2AuXG4gICAqXG4gICAqIEBwcml2YXRlXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBzdHJpbmcgVGhlIHN0cmluZyB0byBpbnNwZWN0LlxuICAgKiBAcmV0dXJucyB7bnVtYmVyfSBSZXR1cm5zIHRoZSBpbmRleCBvZiB0aGUgbGFzdCBub24td2hpdGVzcGFjZSBjaGFyYWN0ZXIuXG4gICAqL1xuICBmdW5jdGlvbiB0cmltbWVkRW5kSW5kZXgoc3RyaW5nKSB7XG4gICAgdmFyIGluZGV4ID0gc3RyaW5nLmxlbmd0aDtcblxuICAgIHdoaWxlIChpbmRleC0tICYmIHJlV2hpdGVzcGFjZS50ZXN0KHN0cmluZy5jaGFyQXQoaW5kZXgpKSkge31cbiAgICByZXR1cm4gaW5kZXg7XG4gIH1cblxuICAvKipcbiAgICogVXNlZCBieSBgXy51bmVzY2FwZWAgdG8gY29udmVydCBIVE1MIGVudGl0aWVzIHRvIGNoYXJhY3RlcnMuXG4gICAqXG4gICAqIEBwcml2YXRlXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBjaHIgVGhlIG1hdGNoZWQgY2hhcmFjdGVyIHRvIHVuZXNjYXBlLlxuICAgKiBAcmV0dXJucyB7c3RyaW5nfSBSZXR1cm5zIHRoZSB1bmVzY2FwZWQgY2hhcmFjdGVyLlxuICAgKi9cbiAgdmFyIHVuZXNjYXBlSHRtbENoYXIgPSBiYXNlUHJvcGVydHlPZihodG1sVW5lc2NhcGVzKTtcblxuICAvKipcbiAgICogR2V0cyB0aGUgc2l6ZSBvZiBhIFVuaWNvZGUgYHN0cmluZ2AuXG4gICAqXG4gICAqIEBwcml2YXRlXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBzdHJpbmcgVGhlIHN0cmluZyBpbnNwZWN0LlxuICAgKiBAcmV0dXJucyB7bnVtYmVyfSBSZXR1cm5zIHRoZSBzdHJpbmcgc2l6ZS5cbiAgICovXG4gIGZ1bmN0aW9uIHVuaWNvZGVTaXplKHN0cmluZykge1xuICAgIHZhciByZXN1bHQgPSByZVVuaWNvZGUubGFzdEluZGV4ID0gMDtcbiAgICB3aGlsZSAocmVVbmljb2RlLnRlc3Qoc3RyaW5nKSkge1xuICAgICAgKytyZXN1bHQ7XG4gICAgfVxuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICAvKipcbiAgICogQ29udmVydHMgYSBVbmljb2RlIGBzdHJpbmdgIHRvIGFuIGFycmF5LlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge3N0cmluZ30gc3RyaW5nIFRoZSBzdHJpbmcgdG8gY29udmVydC5cbiAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBjb252ZXJ0ZWQgYXJyYXkuXG4gICAqL1xuICBmdW5jdGlvbiB1bmljb2RlVG9BcnJheShzdHJpbmcpIHtcbiAgICByZXR1cm4gc3RyaW5nLm1hdGNoKHJlVW5pY29kZSkgfHwgW107XG4gIH1cblxuICAvKipcbiAgICogU3BsaXRzIGEgVW5pY29kZSBgc3RyaW5nYCBpbnRvIGFuIGFycmF5IG9mIGl0cyB3b3Jkcy5cbiAgICpcbiAgICogQHByaXZhdGVcbiAgICogQHBhcmFtIHtzdHJpbmd9IFRoZSBzdHJpbmcgdG8gaW5zcGVjdC5cbiAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSB3b3JkcyBvZiBgc3RyaW5nYC5cbiAgICovXG4gIGZ1bmN0aW9uIHVuaWNvZGVXb3JkcyhzdHJpbmcpIHtcbiAgICByZXR1cm4gc3RyaW5nLm1hdGNoKHJlVW5pY29kZVdvcmQpIHx8IFtdO1xuICB9XG5cbiAgLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovXG5cbiAgLyoqXG4gICAqIENyZWF0ZSBhIG5ldyBwcmlzdGluZSBgbG9kYXNoYCBmdW5jdGlvbiB1c2luZyB0aGUgYGNvbnRleHRgIG9iamVjdC5cbiAgICpcbiAgICogQHN0YXRpY1xuICAgKiBAbWVtYmVyT2YgX1xuICAgKiBAc2luY2UgMS4xLjBcbiAgICogQGNhdGVnb3J5IFV0aWxcbiAgICogQHBhcmFtIHtPYmplY3R9IFtjb250ZXh0PXJvb3RdIFRoZSBjb250ZXh0IG9iamVjdC5cbiAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIGEgbmV3IGBsb2Rhc2hgIGZ1bmN0aW9uLlxuICAgKiBAZXhhbXBsZVxuICAgKlxuICAgKiBfLm1peGluKHsgJ2Zvbyc6IF8uY29uc3RhbnQoJ2ZvbycpIH0pO1xuICAgKlxuICAgKiB2YXIgbG9kYXNoID0gXy5ydW5JbkNvbnRleHQoKTtcbiAgICogbG9kYXNoLm1peGluKHsgJ2Jhcic6IGxvZGFzaC5jb25zdGFudCgnYmFyJykgfSk7XG4gICAqXG4gICAqIF8uaXNGdW5jdGlvbihfLmZvbyk7XG4gICAqIC8vID0+IHRydWVcbiAgICogXy5pc0Z1bmN0aW9uKF8uYmFyKTtcbiAgICogLy8gPT4gZmFsc2VcbiAgICpcbiAgICogbG9kYXNoLmlzRnVuY3Rpb24obG9kYXNoLmZvbyk7XG4gICAqIC8vID0+IGZhbHNlXG4gICAqIGxvZGFzaC5pc0Z1bmN0aW9uKGxvZGFzaC5iYXIpO1xuICAgKiAvLyA9PiB0cnVlXG4gICAqXG4gICAqIC8vIENyZWF0ZSBhIHN1cGVkLXVwIGBkZWZlcmAgaW4gTm9kZS5qcy5cbiAgICogdmFyIGRlZmVyID0gXy5ydW5JbkNvbnRleHQoeyAnc2V0VGltZW91dCc6IHNldEltbWVkaWF0ZSB9KS5kZWZlcjtcbiAgICovXG4gIHZhciBydW5JbkNvbnRleHQgPSAoZnVuY3Rpb24gcnVuSW5Db250ZXh0KGNvbnRleHQpIHtcbiAgICBjb250ZXh0ID0gY29udGV4dCA9PSBudWxsID8gcm9vdCA6IF8uZGVmYXVsdHMocm9vdC5PYmplY3QoKSwgY29udGV4dCwgXy5waWNrKHJvb3QsIGNvbnRleHRQcm9wcykpO1xuXG4gICAgLyoqIEJ1aWx0LWluIGNvbnN0cnVjdG9yIHJlZmVyZW5jZXMuICovXG4gICAgdmFyIEFycmF5ID0gY29udGV4dC5BcnJheSxcbiAgICAgICAgRGF0ZSA9IGNvbnRleHQuRGF0ZSxcbiAgICAgICAgRXJyb3IgPSBjb250ZXh0LkVycm9yLFxuICAgICAgICBGdW5jdGlvbiA9IGNvbnRleHQuRnVuY3Rpb24sXG4gICAgICAgIE1hdGggPSBjb250ZXh0Lk1hdGgsXG4gICAgICAgIE9iamVjdCA9IGNvbnRleHQuT2JqZWN0LFxuICAgICAgICBSZWdFeHAgPSBjb250ZXh0LlJlZ0V4cCxcbiAgICAgICAgU3RyaW5nID0gY29udGV4dC5TdHJpbmcsXG4gICAgICAgIFR5cGVFcnJvciA9IGNvbnRleHQuVHlwZUVycm9yO1xuXG4gICAgLyoqIFVzZWQgZm9yIGJ1aWx0LWluIG1ldGhvZCByZWZlcmVuY2VzLiAqL1xuICAgIHZhciBhcnJheVByb3RvID0gQXJyYXkucHJvdG90eXBlLFxuICAgICAgICBmdW5jUHJvdG8gPSBGdW5jdGlvbi5wcm90b3R5cGUsXG4gICAgICAgIG9iamVjdFByb3RvID0gT2JqZWN0LnByb3RvdHlwZTtcblxuICAgIC8qKiBVc2VkIHRvIGRldGVjdCBvdmVycmVhY2hpbmcgY29yZS1qcyBzaGltcy4gKi9cbiAgICB2YXIgY29yZUpzRGF0YSA9IGNvbnRleHRbJ19fY29yZS1qc19zaGFyZWRfXyddO1xuXG4gICAgLyoqIFVzZWQgdG8gcmVzb2x2ZSB0aGUgZGVjb21waWxlZCBzb3VyY2Ugb2YgZnVuY3Rpb25zLiAqL1xuICAgIHZhciBmdW5jVG9TdHJpbmcgPSBmdW5jUHJvdG8udG9TdHJpbmc7XG5cbiAgICAvKiogVXNlZCB0byBjaGVjayBvYmplY3RzIGZvciBvd24gcHJvcGVydGllcy4gKi9cbiAgICB2YXIgaGFzT3duUHJvcGVydHkgPSBvYmplY3RQcm90by5oYXNPd25Qcm9wZXJ0eTtcblxuICAgIC8qKiBVc2VkIHRvIGdlbmVyYXRlIHVuaXF1ZSBJRHMuICovXG4gICAgdmFyIGlkQ291bnRlciA9IDA7XG5cbiAgICAvKiogVXNlZCB0byBkZXRlY3QgbWV0aG9kcyBtYXNxdWVyYWRpbmcgYXMgbmF0aXZlLiAqL1xuICAgIHZhciBtYXNrU3JjS2V5ID0gKGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIHVpZCA9IC9bXi5dKyQvLmV4ZWMoY29yZUpzRGF0YSAmJiBjb3JlSnNEYXRhLmtleXMgJiYgY29yZUpzRGF0YS5rZXlzLklFX1BST1RPIHx8ICcnKTtcbiAgICAgIHJldHVybiB1aWQgPyAoJ1N5bWJvbChzcmMpXzEuJyArIHVpZCkgOiAnJztcbiAgICB9KCkpO1xuXG4gICAgLyoqXG4gICAgICogVXNlZCB0byByZXNvbHZlIHRoZVxuICAgICAqIFtgdG9TdHJpbmdUYWdgXShodHRwOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi83LjAvI3NlYy1vYmplY3QucHJvdG90eXBlLnRvc3RyaW5nKVxuICAgICAqIG9mIHZhbHVlcy5cbiAgICAgKi9cbiAgICB2YXIgbmF0aXZlT2JqZWN0VG9TdHJpbmcgPSBvYmplY3RQcm90by50b1N0cmluZztcblxuICAgIC8qKiBVc2VkIHRvIGluZmVyIHRoZSBgT2JqZWN0YCBjb25zdHJ1Y3Rvci4gKi9cbiAgICB2YXIgb2JqZWN0Q3RvclN0cmluZyA9IGZ1bmNUb1N0cmluZy5jYWxsKE9iamVjdCk7XG5cbiAgICAvKiogVXNlZCB0byByZXN0b3JlIHRoZSBvcmlnaW5hbCBgX2AgcmVmZXJlbmNlIGluIGBfLm5vQ29uZmxpY3RgLiAqL1xuICAgIHZhciBvbGREYXNoID0gcm9vdC5fO1xuXG4gICAgLyoqIFVzZWQgdG8gZGV0ZWN0IGlmIGEgbWV0aG9kIGlzIG5hdGl2ZS4gKi9cbiAgICB2YXIgcmVJc05hdGl2ZSA9IFJlZ0V4cCgnXicgK1xuICAgICAgZnVuY1RvU3RyaW5nLmNhbGwoaGFzT3duUHJvcGVydHkpLnJlcGxhY2UocmVSZWdFeHBDaGFyLCAnXFxcXCQmJylcbiAgICAgIC5yZXBsYWNlKC9oYXNPd25Qcm9wZXJ0eXwoZnVuY3Rpb24pLio/KD89XFxcXFxcKCl8IGZvciAuKz8oPz1cXFxcXFxdKS9nLCAnJDEuKj8nKSArICckJ1xuICAgICk7XG5cbiAgICAvKiogQnVpbHQtaW4gdmFsdWUgcmVmZXJlbmNlcy4gKi9cbiAgICB2YXIgQnVmZmVyID0gbW9kdWxlRXhwb3J0cyA/IGNvbnRleHQuQnVmZmVyIDogdW5kZWZpbmVkLFxuICAgICAgICBTeW1ib2wgPSBjb250ZXh0LlN5bWJvbCxcbiAgICAgICAgVWludDhBcnJheSA9IGNvbnRleHQuVWludDhBcnJheSxcbiAgICAgICAgYWxsb2NVbnNhZmUgPSBCdWZmZXIgPyBCdWZmZXIuYWxsb2NVbnNhZmUgOiB1bmRlZmluZWQsXG4gICAgICAgIGdldFByb3RvdHlwZSA9IG92ZXJBcmcoT2JqZWN0LmdldFByb3RvdHlwZU9mLCBPYmplY3QpLFxuICAgICAgICBvYmplY3RDcmVhdGUgPSBPYmplY3QuY3JlYXRlLFxuICAgICAgICBwcm9wZXJ0eUlzRW51bWVyYWJsZSA9IG9iamVjdFByb3RvLnByb3BlcnR5SXNFbnVtZXJhYmxlLFxuICAgICAgICBzcGxpY2UgPSBhcnJheVByb3RvLnNwbGljZSxcbiAgICAgICAgc3ByZWFkYWJsZVN5bWJvbCA9IFN5bWJvbCA/IFN5bWJvbC5pc0NvbmNhdFNwcmVhZGFibGUgOiB1bmRlZmluZWQsXG4gICAgICAgIHN5bUl0ZXJhdG9yID0gU3ltYm9sID8gU3ltYm9sLml0ZXJhdG9yIDogdW5kZWZpbmVkLFxuICAgICAgICBzeW1Ub1N0cmluZ1RhZyA9IFN5bWJvbCA/IFN5bWJvbC50b1N0cmluZ1RhZyA6IHVuZGVmaW5lZDtcblxuICAgIHZhciBkZWZpbmVQcm9wZXJ0eSA9IChmdW5jdGlvbigpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIHZhciBmdW5jID0gZ2V0TmF0aXZlKE9iamVjdCwgJ2RlZmluZVByb3BlcnR5Jyk7XG4gICAgICAgIGZ1bmMoe30sICcnLCB7fSk7XG4gICAgICAgIHJldHVybiBmdW5jO1xuICAgICAgfSBjYXRjaCAoZSkge31cbiAgICB9KCkpO1xuXG4gICAgLyoqIE1vY2tlZCBidWlsdC1pbnMuICovXG4gICAgdmFyIGN0eENsZWFyVGltZW91dCA9IGNvbnRleHQuY2xlYXJUaW1lb3V0ICE9PSByb290LmNsZWFyVGltZW91dCAmJiBjb250ZXh0LmNsZWFyVGltZW91dCxcbiAgICAgICAgY3R4Tm93ID0gRGF0ZSAmJiBEYXRlLm5vdyAhPT0gcm9vdC5EYXRlLm5vdyAmJiBEYXRlLm5vdyxcbiAgICAgICAgY3R4U2V0VGltZW91dCA9IGNvbnRleHQuc2V0VGltZW91dCAhPT0gcm9vdC5zZXRUaW1lb3V0ICYmIGNvbnRleHQuc2V0VGltZW91dDtcblxuICAgIC8qIEJ1aWx0LWluIG1ldGhvZCByZWZlcmVuY2VzIGZvciB0aG9zZSB3aXRoIHRoZSBzYW1lIG5hbWUgYXMgb3RoZXIgYGxvZGFzaGAgbWV0aG9kcy4gKi9cbiAgICB2YXIgbmF0aXZlQ2VpbCA9IE1hdGguY2VpbCxcbiAgICAgICAgbmF0aXZlRmxvb3IgPSBNYXRoLmZsb29yLFxuICAgICAgICBuYXRpdmVHZXRTeW1ib2xzID0gT2JqZWN0LmdldE93blByb3BlcnR5U3ltYm9scyxcbiAgICAgICAgbmF0aXZlSXNCdWZmZXIgPSBCdWZmZXIgPyBCdWZmZXIuaXNCdWZmZXIgOiB1bmRlZmluZWQsXG4gICAgICAgIG5hdGl2ZUlzRmluaXRlID0gY29udGV4dC5pc0Zpbml0ZSxcbiAgICAgICAgbmF0aXZlSm9pbiA9IGFycmF5UHJvdG8uam9pbixcbiAgICAgICAgbmF0aXZlS2V5cyA9IG92ZXJBcmcoT2JqZWN0LmtleXMsIE9iamVjdCksXG4gICAgICAgIG5hdGl2ZU1heCA9IE1hdGgubWF4LFxuICAgICAgICBuYXRpdmVNaW4gPSBNYXRoLm1pbixcbiAgICAgICAgbmF0aXZlTm93ID0gRGF0ZS5ub3csXG4gICAgICAgIG5hdGl2ZVBhcnNlSW50ID0gY29udGV4dC5wYXJzZUludCxcbiAgICAgICAgbmF0aXZlUmFuZG9tID0gTWF0aC5yYW5kb20sXG4gICAgICAgIG5hdGl2ZVJldmVyc2UgPSBhcnJheVByb3RvLnJldmVyc2U7XG5cbiAgICAvKiBCdWlsdC1pbiBtZXRob2QgcmVmZXJlbmNlcyB0aGF0IGFyZSB2ZXJpZmllZCB0byBiZSBuYXRpdmUuICovXG4gICAgdmFyIERhdGFWaWV3ID0gZ2V0TmF0aXZlKGNvbnRleHQsICdEYXRhVmlldycpLFxuICAgICAgICBNYXAgPSBnZXROYXRpdmUoY29udGV4dCwgJ01hcCcpLFxuICAgICAgICBQcm9taXNlID0gZ2V0TmF0aXZlKGNvbnRleHQsICdQcm9taXNlJyksXG4gICAgICAgIFNldCA9IGdldE5hdGl2ZShjb250ZXh0LCAnU2V0JyksXG4gICAgICAgIFdlYWtNYXAgPSBnZXROYXRpdmUoY29udGV4dCwgJ1dlYWtNYXAnKSxcbiAgICAgICAgbmF0aXZlQ3JlYXRlID0gZ2V0TmF0aXZlKE9iamVjdCwgJ2NyZWF0ZScpO1xuXG4gICAgLyoqIFVzZWQgdG8gc3RvcmUgZnVuY3Rpb24gbWV0YWRhdGEuICovXG4gICAgdmFyIG1ldGFNYXAgPSBXZWFrTWFwICYmIG5ldyBXZWFrTWFwO1xuXG4gICAgLyoqIFVzZWQgdG8gbG9va3VwIHVubWluaWZpZWQgZnVuY3Rpb24gbmFtZXMuICovXG4gICAgdmFyIHJlYWxOYW1lcyA9IHt9O1xuXG4gICAgLyoqIFVzZWQgdG8gZGV0ZWN0IG1hcHMsIHNldHMsIGFuZCB3ZWFrbWFwcy4gKi9cbiAgICB2YXIgZGF0YVZpZXdDdG9yU3RyaW5nID0gdG9Tb3VyY2UoRGF0YVZpZXcpLFxuICAgICAgICBtYXBDdG9yU3RyaW5nID0gdG9Tb3VyY2UoTWFwKSxcbiAgICAgICAgcHJvbWlzZUN0b3JTdHJpbmcgPSB0b1NvdXJjZShQcm9taXNlKSxcbiAgICAgICAgc2V0Q3RvclN0cmluZyA9IHRvU291cmNlKFNldCksXG4gICAgICAgIHdlYWtNYXBDdG9yU3RyaW5nID0gdG9Tb3VyY2UoV2Vha01hcCk7XG5cbiAgICAvKiogVXNlZCB0byBjb252ZXJ0IHN5bWJvbHMgdG8gcHJpbWl0aXZlcyBhbmQgc3RyaW5ncy4gKi9cbiAgICB2YXIgc3ltYm9sUHJvdG8gPSBTeW1ib2wgPyBTeW1ib2wucHJvdG90eXBlIDogdW5kZWZpbmVkLFxuICAgICAgICBzeW1ib2xWYWx1ZU9mID0gc3ltYm9sUHJvdG8gPyBzeW1ib2xQcm90by52YWx1ZU9mIDogdW5kZWZpbmVkLFxuICAgICAgICBzeW1ib2xUb1N0cmluZyA9IHN5bWJvbFByb3RvID8gc3ltYm9sUHJvdG8udG9TdHJpbmcgOiB1bmRlZmluZWQ7XG5cbiAgICAvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovXG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgYGxvZGFzaGAgb2JqZWN0IHdoaWNoIHdyYXBzIGB2YWx1ZWAgdG8gZW5hYmxlIGltcGxpY2l0IG1ldGhvZFxuICAgICAqIGNoYWluIHNlcXVlbmNlcy4gTWV0aG9kcyB0aGF0IG9wZXJhdGUgb24gYW5kIHJldHVybiBhcnJheXMsIGNvbGxlY3Rpb25zLFxuICAgICAqIGFuZCBmdW5jdGlvbnMgY2FuIGJlIGNoYWluZWQgdG9nZXRoZXIuIE1ldGhvZHMgdGhhdCByZXRyaWV2ZSBhIHNpbmdsZSB2YWx1ZVxuICAgICAqIG9yIG1heSByZXR1cm4gYSBwcmltaXRpdmUgdmFsdWUgd2lsbCBhdXRvbWF0aWNhbGx5IGVuZCB0aGUgY2hhaW4gc2VxdWVuY2VcbiAgICAgKiBhbmQgcmV0dXJuIHRoZSB1bndyYXBwZWQgdmFsdWUuIE90aGVyd2lzZSwgdGhlIHZhbHVlIG11c3QgYmUgdW53cmFwcGVkXG4gICAgICogd2l0aCBgXyN2YWx1ZWAuXG4gICAgICpcbiAgICAgKiBFeHBsaWNpdCBjaGFpbiBzZXF1ZW5jZXMsIHdoaWNoIG11c3QgYmUgdW53cmFwcGVkIHdpdGggYF8jdmFsdWVgLCBtYXkgYmVcbiAgICAgKiBlbmFibGVkIHVzaW5nIGBfLmNoYWluYC5cbiAgICAgKlxuICAgICAqIFRoZSBleGVjdXRpb24gb2YgY2hhaW5lZCBtZXRob2RzIGlzIGxhenksIHRoYXQgaXMsIGl0J3MgZGVmZXJyZWQgdW50aWxcbiAgICAgKiBgXyN2YWx1ZWAgaXMgaW1wbGljaXRseSBvciBleHBsaWNpdGx5IGNhbGxlZC5cbiAgICAgKlxuICAgICAqIExhenkgZXZhbHVhdGlvbiBhbGxvd3Mgc2V2ZXJhbCBtZXRob2RzIHRvIHN1cHBvcnQgc2hvcnRjdXQgZnVzaW9uLlxuICAgICAqIFNob3J0Y3V0IGZ1c2lvbiBpcyBhbiBvcHRpbWl6YXRpb24gdG8gbWVyZ2UgaXRlcmF0ZWUgY2FsbHM7IHRoaXMgYXZvaWRzXG4gICAgICogdGhlIGNyZWF0aW9uIG9mIGludGVybWVkaWF0ZSBhcnJheXMgYW5kIGNhbiBncmVhdGx5IHJlZHVjZSB0aGUgbnVtYmVyIG9mXG4gICAgICogaXRlcmF0ZWUgZXhlY3V0aW9ucy4gU2VjdGlvbnMgb2YgYSBjaGFpbiBzZXF1ZW5jZSBxdWFsaWZ5IGZvciBzaG9ydGN1dFxuICAgICAqIGZ1c2lvbiBpZiB0aGUgc2VjdGlvbiBpcyBhcHBsaWVkIHRvIGFuIGFycmF5IGFuZCBpdGVyYXRlZXMgYWNjZXB0IG9ubHlcbiAgICAgKiBvbmUgYXJndW1lbnQuIFRoZSBoZXVyaXN0aWMgZm9yIHdoZXRoZXIgYSBzZWN0aW9uIHF1YWxpZmllcyBmb3Igc2hvcnRjdXRcbiAgICAgKiBmdXNpb24gaXMgc3ViamVjdCB0byBjaGFuZ2UuXG4gICAgICpcbiAgICAgKiBDaGFpbmluZyBpcyBzdXBwb3J0ZWQgaW4gY3VzdG9tIGJ1aWxkcyBhcyBsb25nIGFzIHRoZSBgXyN2YWx1ZWAgbWV0aG9kIGlzXG4gICAgICogZGlyZWN0bHkgb3IgaW5kaXJlY3RseSBpbmNsdWRlZCBpbiB0aGUgYnVpbGQuXG4gICAgICpcbiAgICAgKiBJbiBhZGRpdGlvbiB0byBsb2Rhc2ggbWV0aG9kcywgd3JhcHBlcnMgaGF2ZSBgQXJyYXlgIGFuZCBgU3RyaW5nYCBtZXRob2RzLlxuICAgICAqXG4gICAgICogVGhlIHdyYXBwZXIgYEFycmF5YCBtZXRob2RzIGFyZTpcbiAgICAgKiBgY29uY2F0YCwgYGpvaW5gLCBgcG9wYCwgYHB1c2hgLCBgc2hpZnRgLCBgc29ydGAsIGBzcGxpY2VgLCBhbmQgYHVuc2hpZnRgXG4gICAgICpcbiAgICAgKiBUaGUgd3JhcHBlciBgU3RyaW5nYCBtZXRob2RzIGFyZTpcbiAgICAgKiBgcmVwbGFjZWAgYW5kIGBzcGxpdGBcbiAgICAgKlxuICAgICAqIFRoZSB3cmFwcGVyIG1ldGhvZHMgdGhhdCBzdXBwb3J0IHNob3J0Y3V0IGZ1c2lvbiBhcmU6XG4gICAgICogYGF0YCwgYGNvbXBhY3RgLCBgZHJvcGAsIGBkcm9wUmlnaHRgLCBgZHJvcFdoaWxlYCwgYGZpbHRlcmAsIGBmaW5kYCxcbiAgICAgKiBgZmluZExhc3RgLCBgaGVhZGAsIGBpbml0aWFsYCwgYGxhc3RgLCBgbWFwYCwgYHJlamVjdGAsIGByZXZlcnNlYCwgYHNsaWNlYCxcbiAgICAgKiBgdGFpbGAsIGB0YWtlYCwgYHRha2VSaWdodGAsIGB0YWtlUmlnaHRXaGlsZWAsIGB0YWtlV2hpbGVgLCBhbmQgYHRvQXJyYXlgXG4gICAgICpcbiAgICAgKiBUaGUgY2hhaW5hYmxlIHdyYXBwZXIgbWV0aG9kcyBhcmU6XG4gICAgICogYGFmdGVyYCwgYGFyeWAsIGBhc3NpZ25gLCBgYXNzaWduSW5gLCBgYXNzaWduSW5XaXRoYCwgYGFzc2lnbldpdGhgLCBgYXRgLFxuICAgICAqIGBiZWZvcmVgLCBgYmluZGAsIGBiaW5kQWxsYCwgYGJpbmRLZXlgLCBgY2FzdEFycmF5YCwgYGNoYWluYCwgYGNodW5rYCxcbiAgICAgKiBgY29tbWl0YCwgYGNvbXBhY3RgLCBgY29uY2F0YCwgYGNvbmZvcm1zYCwgYGNvbnN0YW50YCwgYGNvdW50QnlgLCBgY3JlYXRlYCxcbiAgICAgKiBgY3VycnlgLCBgZGVib3VuY2VgLCBgZGVmYXVsdHNgLCBgZGVmYXVsdHNEZWVwYCwgYGRlZmVyYCwgYGRlbGF5YCxcbiAgICAgKiBgZGlmZmVyZW5jZWAsIGBkaWZmZXJlbmNlQnlgLCBgZGlmZmVyZW5jZVdpdGhgLCBgZHJvcGAsIGBkcm9wUmlnaHRgLFxuICAgICAqIGBkcm9wUmlnaHRXaGlsZWAsIGBkcm9wV2hpbGVgLCBgZXh0ZW5kYCwgYGV4dGVuZFdpdGhgLCBgZmlsbGAsIGBmaWx0ZXJgLFxuICAgICAqIGBmbGF0TWFwYCwgYGZsYXRNYXBEZWVwYCwgYGZsYXRNYXBEZXB0aGAsIGBmbGF0dGVuYCwgYGZsYXR0ZW5EZWVwYCxcbiAgICAgKiBgZmxhdHRlbkRlcHRoYCwgYGZsaXBgLCBgZmxvd2AsIGBmbG93UmlnaHRgLCBgZnJvbVBhaXJzYCwgYGZ1bmN0aW9uc2AsXG4gICAgICogYGZ1bmN0aW9uc0luYCwgYGdyb3VwQnlgLCBgaW5pdGlhbGAsIGBpbnRlcnNlY3Rpb25gLCBgaW50ZXJzZWN0aW9uQnlgLFxuICAgICAqIGBpbnRlcnNlY3Rpb25XaXRoYCwgYGludmVydGAsIGBpbnZlcnRCeWAsIGBpbnZva2VNYXBgLCBgaXRlcmF0ZWVgLCBga2V5QnlgLFxuICAgICAqIGBrZXlzYCwgYGtleXNJbmAsIGBtYXBgLCBgbWFwS2V5c2AsIGBtYXBWYWx1ZXNgLCBgbWF0Y2hlc2AsIGBtYXRjaGVzUHJvcGVydHlgLFxuICAgICAqIGBtZW1vaXplYCwgYG1lcmdlYCwgYG1lcmdlV2l0aGAsIGBtZXRob2RgLCBgbWV0aG9kT2ZgLCBgbWl4aW5gLCBgbmVnYXRlYCxcbiAgICAgKiBgbnRoQXJnYCwgYG9taXRgLCBgb21pdEJ5YCwgYG9uY2VgLCBgb3JkZXJCeWAsIGBvdmVyYCwgYG92ZXJBcmdzYCxcbiAgICAgKiBgb3ZlckV2ZXJ5YCwgYG92ZXJTb21lYCwgYHBhcnRpYWxgLCBgcGFydGlhbFJpZ2h0YCwgYHBhcnRpdGlvbmAsIGBwaWNrYCxcbiAgICAgKiBgcGlja0J5YCwgYHBsYW50YCwgYHByb3BlcnR5YCwgYHByb3BlcnR5T2ZgLCBgcHVsbGAsIGBwdWxsQWxsYCwgYHB1bGxBbGxCeWAsXG4gICAgICogYHB1bGxBbGxXaXRoYCwgYHB1bGxBdGAsIGBwdXNoYCwgYHJhbmdlYCwgYHJhbmdlUmlnaHRgLCBgcmVhcmdgLCBgcmVqZWN0YCxcbiAgICAgKiBgcmVtb3ZlYCwgYHJlc3RgLCBgcmV2ZXJzZWAsIGBzYW1wbGVTaXplYCwgYHNldGAsIGBzZXRXaXRoYCwgYHNodWZmbGVgLFxuICAgICAqIGBzbGljZWAsIGBzb3J0YCwgYHNvcnRCeWAsIGBzcGxpY2VgLCBgc3ByZWFkYCwgYHRhaWxgLCBgdGFrZWAsIGB0YWtlUmlnaHRgLFxuICAgICAqIGB0YWtlUmlnaHRXaGlsZWAsIGB0YWtlV2hpbGVgLCBgdGFwYCwgYHRocm90dGxlYCwgYHRocnVgLCBgdG9BcnJheWAsXG4gICAgICogYHRvUGFpcnNgLCBgdG9QYWlyc0luYCwgYHRvUGF0aGAsIGB0b1BsYWluT2JqZWN0YCwgYHRyYW5zZm9ybWAsIGB1bmFyeWAsXG4gICAgICogYHVuaW9uYCwgYHVuaW9uQnlgLCBgdW5pb25XaXRoYCwgYHVuaXFgLCBgdW5pcUJ5YCwgYHVuaXFXaXRoYCwgYHVuc2V0YCxcbiAgICAgKiBgdW5zaGlmdGAsIGB1bnppcGAsIGB1bnppcFdpdGhgLCBgdXBkYXRlYCwgYHVwZGF0ZVdpdGhgLCBgdmFsdWVzYCxcbiAgICAgKiBgdmFsdWVzSW5gLCBgd2l0aG91dGAsIGB3cmFwYCwgYHhvcmAsIGB4b3JCeWAsIGB4b3JXaXRoYCwgYHppcGAsXG4gICAgICogYHppcE9iamVjdGAsIGB6aXBPYmplY3REZWVwYCwgYW5kIGB6aXBXaXRoYFxuICAgICAqXG4gICAgICogVGhlIHdyYXBwZXIgbWV0aG9kcyB0aGF0IGFyZSAqKm5vdCoqIGNoYWluYWJsZSBieSBkZWZhdWx0IGFyZTpcbiAgICAgKiBgYWRkYCwgYGF0dGVtcHRgLCBgY2FtZWxDYXNlYCwgYGNhcGl0YWxpemVgLCBgY2VpbGAsIGBjbGFtcGAsIGBjbG9uZWAsXG4gICAgICogYGNsb25lRGVlcGAsIGBjbG9uZURlZXBXaXRoYCwgYGNsb25lV2l0aGAsIGBjb25mb3Jtc1RvYCwgYGRlYnVycmAsXG4gICAgICogYGRlZmF1bHRUb2AsIGBkaXZpZGVgLCBgZWFjaGAsIGBlYWNoUmlnaHRgLCBgZW5kc1dpdGhgLCBgZXFgLCBgZXNjYXBlYCxcbiAgICAgKiBgZXNjYXBlUmVnRXhwYCwgYGV2ZXJ5YCwgYGZpbmRgLCBgZmluZEluZGV4YCwgYGZpbmRLZXlgLCBgZmluZExhc3RgLFxuICAgICAqIGBmaW5kTGFzdEluZGV4YCwgYGZpbmRMYXN0S2V5YCwgYGZpcnN0YCwgYGZsb29yYCwgYGZvckVhY2hgLCBgZm9yRWFjaFJpZ2h0YCxcbiAgICAgKiBgZm9ySW5gLCBgZm9ySW5SaWdodGAsIGBmb3JPd25gLCBgZm9yT3duUmlnaHRgLCBgZ2V0YCwgYGd0YCwgYGd0ZWAsIGBoYXNgLFxuICAgICAqIGBoYXNJbmAsIGBoZWFkYCwgYGlkZW50aXR5YCwgYGluY2x1ZGVzYCwgYGluZGV4T2ZgLCBgaW5SYW5nZWAsIGBpbnZva2VgLFxuICAgICAqIGBpc0FyZ3VtZW50c2AsIGBpc0FycmF5YCwgYGlzQXJyYXlCdWZmZXJgLCBgaXNBcnJheUxpa2VgLCBgaXNBcnJheUxpa2VPYmplY3RgLFxuICAgICAqIGBpc0Jvb2xlYW5gLCBgaXNCdWZmZXJgLCBgaXNEYXRlYCwgYGlzRWxlbWVudGAsIGBpc0VtcHR5YCwgYGlzRXF1YWxgLFxuICAgICAqIGBpc0VxdWFsV2l0aGAsIGBpc0Vycm9yYCwgYGlzRmluaXRlYCwgYGlzRnVuY3Rpb25gLCBgaXNJbnRlZ2VyYCwgYGlzTGVuZ3RoYCxcbiAgICAgKiBgaXNNYXBgLCBgaXNNYXRjaGAsIGBpc01hdGNoV2l0aGAsIGBpc05hTmAsIGBpc05hdGl2ZWAsIGBpc05pbGAsIGBpc051bGxgLFxuICAgICAqIGBpc051bWJlcmAsIGBpc09iamVjdGAsIGBpc09iamVjdExpa2VgLCBgaXNQbGFpbk9iamVjdGAsIGBpc1JlZ0V4cGAsXG4gICAgICogYGlzU2FmZUludGVnZXJgLCBgaXNTZXRgLCBgaXNTdHJpbmdgLCBgaXNVbmRlZmluZWRgLCBgaXNUeXBlZEFycmF5YCxcbiAgICAgKiBgaXNXZWFrTWFwYCwgYGlzV2Vha1NldGAsIGBqb2luYCwgYGtlYmFiQ2FzZWAsIGBsYXN0YCwgYGxhc3RJbmRleE9mYCxcbiAgICAgKiBgbG93ZXJDYXNlYCwgYGxvd2VyRmlyc3RgLCBgbHRgLCBgbHRlYCwgYG1heGAsIGBtYXhCeWAsIGBtZWFuYCwgYG1lYW5CeWAsXG4gICAgICogYG1pbmAsIGBtaW5CeWAsIGBtdWx0aXBseWAsIGBub0NvbmZsaWN0YCwgYG5vb3BgLCBgbm93YCwgYG50aGAsIGBwYWRgLFxuICAgICAqIGBwYWRFbmRgLCBgcGFkU3RhcnRgLCBgcGFyc2VJbnRgLCBgcG9wYCwgYHJhbmRvbWAsIGByZWR1Y2VgLCBgcmVkdWNlUmlnaHRgLFxuICAgICAqIGByZXBlYXRgLCBgcmVzdWx0YCwgYHJvdW5kYCwgYHJ1bkluQ29udGV4dGAsIGBzYW1wbGVgLCBgc2hpZnRgLCBgc2l6ZWAsXG4gICAgICogYHNuYWtlQ2FzZWAsIGBzb21lYCwgYHNvcnRlZEluZGV4YCwgYHNvcnRlZEluZGV4QnlgLCBgc29ydGVkTGFzdEluZGV4YCxcbiAgICAgKiBgc29ydGVkTGFzdEluZGV4QnlgLCBgc3RhcnRDYXNlYCwgYHN0YXJ0c1dpdGhgLCBgc3R1YkFycmF5YCwgYHN0dWJGYWxzZWAsXG4gICAgICogYHN0dWJPYmplY3RgLCBgc3R1YlN0cmluZ2AsIGBzdHViVHJ1ZWAsIGBzdWJ0cmFjdGAsIGBzdW1gLCBgc3VtQnlgLFxuICAgICAqIGB0ZW1wbGF0ZWAsIGB0aW1lc2AsIGB0b0Zpbml0ZWAsIGB0b0ludGVnZXJgLCBgdG9KU09OYCwgYHRvTGVuZ3RoYCxcbiAgICAgKiBgdG9Mb3dlcmAsIGB0b051bWJlcmAsIGB0b1NhZmVJbnRlZ2VyYCwgYHRvU3RyaW5nYCwgYHRvVXBwZXJgLCBgdHJpbWAsXG4gICAgICogYHRyaW1FbmRgLCBgdHJpbVN0YXJ0YCwgYHRydW5jYXRlYCwgYHVuZXNjYXBlYCwgYHVuaXF1ZUlkYCwgYHVwcGVyQ2FzZWAsXG4gICAgICogYHVwcGVyRmlyc3RgLCBgdmFsdWVgLCBhbmQgYHdvcmRzYFxuICAgICAqXG4gICAgICogQG5hbWUgX1xuICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAqIEBjYXRlZ29yeSBTZXFcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byB3cmFwIGluIGEgYGxvZGFzaGAgaW5zdGFuY2UuXG4gICAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyB0aGUgbmV3IGBsb2Rhc2hgIHdyYXBwZXIgaW5zdGFuY2UuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIGZ1bmN0aW9uIHNxdWFyZShuKSB7XG4gICAgICogICByZXR1cm4gbiAqIG47XG4gICAgICogfVxuICAgICAqXG4gICAgICogdmFyIHdyYXBwZWQgPSBfKFsxLCAyLCAzXSk7XG4gICAgICpcbiAgICAgKiAvLyBSZXR1cm5zIGFuIHVud3JhcHBlZCB2YWx1ZS5cbiAgICAgKiB3cmFwcGVkLnJlZHVjZShfLmFkZCk7XG4gICAgICogLy8gPT4gNlxuICAgICAqXG4gICAgICogLy8gUmV0dXJucyBhIHdyYXBwZWQgdmFsdWUuXG4gICAgICogdmFyIHNxdWFyZXMgPSB3cmFwcGVkLm1hcChzcXVhcmUpO1xuICAgICAqXG4gICAgICogXy5pc0FycmF5KHNxdWFyZXMpO1xuICAgICAqIC8vID0+IGZhbHNlXG4gICAgICpcbiAgICAgKiBfLmlzQXJyYXkoc3F1YXJlcy52YWx1ZSgpKTtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICovXG4gICAgZnVuY3Rpb24gbG9kYXNoKHZhbHVlKSB7XG4gICAgICBpZiAoaXNPYmplY3RMaWtlKHZhbHVlKSAmJiAhaXNBcnJheSh2YWx1ZSkgJiYgISh2YWx1ZSBpbnN0YW5jZW9mIExhenlXcmFwcGVyKSkge1xuICAgICAgICBpZiAodmFsdWUgaW5zdGFuY2VvZiBMb2Rhc2hXcmFwcGVyKSB7XG4gICAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgICAgICB9XG4gICAgICAgIGlmIChoYXNPd25Qcm9wZXJ0eS5jYWxsKHZhbHVlLCAnX193cmFwcGVkX18nKSkge1xuICAgICAgICAgIHJldHVybiB3cmFwcGVyQ2xvbmUodmFsdWUpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gbmV3IExvZGFzaFdyYXBwZXIodmFsdWUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLmNyZWF0ZWAgd2l0aG91dCBzdXBwb3J0IGZvciBhc3NpZ25pbmdcbiAgICAgKiBwcm9wZXJ0aWVzIHRvIHRoZSBjcmVhdGVkIG9iamVjdC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtPYmplY3R9IHByb3RvIFRoZSBvYmplY3QgdG8gaW5oZXJpdCBmcm9tLlxuICAgICAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgdGhlIG5ldyBvYmplY3QuXG4gICAgICovXG4gICAgdmFyIGJhc2VDcmVhdGUgPSAoZnVuY3Rpb24oKSB7XG4gICAgICBmdW5jdGlvbiBvYmplY3QoKSB7fVxuICAgICAgcmV0dXJuIGZ1bmN0aW9uKHByb3RvKSB7XG4gICAgICAgIGlmICghaXNPYmplY3QocHJvdG8pKSB7XG4gICAgICAgICAgcmV0dXJuIHt9O1xuICAgICAgICB9XG4gICAgICAgIGlmIChvYmplY3RDcmVhdGUpIHtcbiAgICAgICAgICByZXR1cm4gb2JqZWN0Q3JlYXRlKHByb3RvKTtcbiAgICAgICAgfVxuICAgICAgICBvYmplY3QucHJvdG90eXBlID0gcHJvdG87XG4gICAgICAgIHZhciByZXN1bHQgPSBuZXcgb2JqZWN0O1xuICAgICAgICBvYmplY3QucHJvdG90eXBlID0gdW5kZWZpbmVkO1xuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgfTtcbiAgICB9KCkpO1xuXG4gICAgLyoqXG4gICAgICogVGhlIGZ1bmN0aW9uIHdob3NlIHByb3RvdHlwZSBjaGFpbiBzZXF1ZW5jZSB3cmFwcGVycyBpbmhlcml0IGZyb20uXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGJhc2VMb2Rhc2goKSB7XG4gICAgICAvLyBObyBvcGVyYXRpb24gcGVyZm9ybWVkLlxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBiYXNlIGNvbnN0cnVjdG9yIGZvciBjcmVhdGluZyBgbG9kYXNoYCB3cmFwcGVyIG9iamVjdHMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIHdyYXAuXG4gICAgICogQHBhcmFtIHtib29sZWFufSBbY2hhaW5BbGxdIEVuYWJsZSBleHBsaWNpdCBtZXRob2QgY2hhaW4gc2VxdWVuY2VzLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIExvZGFzaFdyYXBwZXIodmFsdWUsIGNoYWluQWxsKSB7XG4gICAgICB0aGlzLl9fd3JhcHBlZF9fID0gdmFsdWU7XG4gICAgICB0aGlzLl9fYWN0aW9uc19fID0gW107XG4gICAgICB0aGlzLl9fY2hhaW5fXyA9ICEhY2hhaW5BbGw7XG4gICAgICB0aGlzLl9faW5kZXhfXyA9IDA7XG4gICAgICB0aGlzLl9fdmFsdWVzX18gPSB1bmRlZmluZWQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQnkgZGVmYXVsdCwgdGhlIHRlbXBsYXRlIGRlbGltaXRlcnMgdXNlZCBieSBsb2Rhc2ggYXJlIGxpa2UgdGhvc2UgaW5cbiAgICAgKiBlbWJlZGRlZCBSdWJ5IChFUkIpIGFzIHdlbGwgYXMgRVMyMDE1IHRlbXBsYXRlIHN0cmluZ3MuIENoYW5nZSB0aGVcbiAgICAgKiBmb2xsb3dpbmcgdGVtcGxhdGUgc2V0dGluZ3MgdG8gdXNlIGFsdGVybmF0aXZlIGRlbGltaXRlcnMuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAdHlwZSB7T2JqZWN0fVxuICAgICAqL1xuICAgIGxvZGFzaC50ZW1wbGF0ZVNldHRpbmdzID0ge1xuXG4gICAgICAvKipcbiAgICAgICAqIFVzZWQgdG8gZGV0ZWN0IGBkYXRhYCBwcm9wZXJ0eSB2YWx1ZXMgdG8gYmUgSFRNTC1lc2NhcGVkLlxuICAgICAgICpcbiAgICAgICAqIEBtZW1iZXJPZiBfLnRlbXBsYXRlU2V0dGluZ3NcbiAgICAgICAqIEB0eXBlIHtSZWdFeHB9XG4gICAgICAgKi9cbiAgICAgICdlc2NhcGUnOiByZUVzY2FwZSxcblxuICAgICAgLyoqXG4gICAgICAgKiBVc2VkIHRvIGRldGVjdCBjb2RlIHRvIGJlIGV2YWx1YXRlZC5cbiAgICAgICAqXG4gICAgICAgKiBAbWVtYmVyT2YgXy50ZW1wbGF0ZVNldHRpbmdzXG4gICAgICAgKiBAdHlwZSB7UmVnRXhwfVxuICAgICAgICovXG4gICAgICAnZXZhbHVhdGUnOiByZUV2YWx1YXRlLFxuXG4gICAgICAvKipcbiAgICAgICAqIFVzZWQgdG8gZGV0ZWN0IGBkYXRhYCBwcm9wZXJ0eSB2YWx1ZXMgdG8gaW5qZWN0LlxuICAgICAgICpcbiAgICAgICAqIEBtZW1iZXJPZiBfLnRlbXBsYXRlU2V0dGluZ3NcbiAgICAgICAqIEB0eXBlIHtSZWdFeHB9XG4gICAgICAgKi9cbiAgICAgICdpbnRlcnBvbGF0ZSc6IHJlSW50ZXJwb2xhdGUsXG5cbiAgICAgIC8qKlxuICAgICAgICogVXNlZCB0byByZWZlcmVuY2UgdGhlIGRhdGEgb2JqZWN0IGluIHRoZSB0ZW1wbGF0ZSB0ZXh0LlxuICAgICAgICpcbiAgICAgICAqIEBtZW1iZXJPZiBfLnRlbXBsYXRlU2V0dGluZ3NcbiAgICAgICAqIEB0eXBlIHtzdHJpbmd9XG4gICAgICAgKi9cbiAgICAgICd2YXJpYWJsZSc6ICcnLFxuXG4gICAgICAvKipcbiAgICAgICAqIFVzZWQgdG8gaW1wb3J0IHZhcmlhYmxlcyBpbnRvIHRoZSBjb21waWxlZCB0ZW1wbGF0ZS5cbiAgICAgICAqXG4gICAgICAgKiBAbWVtYmVyT2YgXy50ZW1wbGF0ZVNldHRpbmdzXG4gICAgICAgKiBAdHlwZSB7T2JqZWN0fVxuICAgICAgICovXG4gICAgICAnaW1wb3J0cyc6IHtcblxuICAgICAgICAvKipcbiAgICAgICAgICogQSByZWZlcmVuY2UgdG8gdGhlIGBsb2Rhc2hgIGZ1bmN0aW9uLlxuICAgICAgICAgKlxuICAgICAgICAgKiBAbWVtYmVyT2YgXy50ZW1wbGF0ZVNldHRpbmdzLmltcG9ydHNcbiAgICAgICAgICogQHR5cGUge0Z1bmN0aW9ufVxuICAgICAgICAgKi9cbiAgICAgICAgJ18nOiBsb2Rhc2hcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgLy8gRW5zdXJlIHdyYXBwZXJzIGFyZSBpbnN0YW5jZXMgb2YgYGJhc2VMb2Rhc2hgLlxuICAgIGxvZGFzaC5wcm90b3R5cGUgPSBiYXNlTG9kYXNoLnByb3RvdHlwZTtcbiAgICBsb2Rhc2gucHJvdG90eXBlLmNvbnN0cnVjdG9yID0gbG9kYXNoO1xuXG4gICAgTG9kYXNoV3JhcHBlci5wcm90b3R5cGUgPSBiYXNlQ3JlYXRlKGJhc2VMb2Rhc2gucHJvdG90eXBlKTtcbiAgICBMb2Rhc2hXcmFwcGVyLnByb3RvdHlwZS5jb25zdHJ1Y3RvciA9IExvZGFzaFdyYXBwZXI7XG5cbiAgICAvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovXG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgbGF6eSB3cmFwcGVyIG9iamVjdCB3aGljaCB3cmFwcyBgdmFsdWVgIHRvIGVuYWJsZSBsYXp5IGV2YWx1YXRpb24uXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIHdyYXAuXG4gICAgICovXG4gICAgZnVuY3Rpb24gTGF6eVdyYXBwZXIodmFsdWUpIHtcbiAgICAgIHRoaXMuX193cmFwcGVkX18gPSB2YWx1ZTtcbiAgICAgIHRoaXMuX19hY3Rpb25zX18gPSBbXTtcbiAgICAgIHRoaXMuX19kaXJfXyA9IDE7XG4gICAgICB0aGlzLl9fZmlsdGVyZWRfXyA9IGZhbHNlO1xuICAgICAgdGhpcy5fX2l0ZXJhdGVlc19fID0gW107XG4gICAgICB0aGlzLl9fdGFrZUNvdW50X18gPSBNQVhfQVJSQVlfTEVOR1RIO1xuICAgICAgdGhpcy5fX3ZpZXdzX18gPSBbXTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgY2xvbmUgb2YgdGhlIGxhenkgd3JhcHBlciBvYmplY3QuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBuYW1lIGNsb25lXG4gICAgICogQG1lbWJlck9mIExhenlXcmFwcGVyXG4gICAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyB0aGUgY2xvbmVkIGBMYXp5V3JhcHBlcmAgb2JqZWN0LlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGxhenlDbG9uZSgpIHtcbiAgICAgIHZhciByZXN1bHQgPSBuZXcgTGF6eVdyYXBwZXIodGhpcy5fX3dyYXBwZWRfXyk7XG4gICAgICByZXN1bHQuX19hY3Rpb25zX18gPSBjb3B5QXJyYXkodGhpcy5fX2FjdGlvbnNfXyk7XG4gICAgICByZXN1bHQuX19kaXJfXyA9IHRoaXMuX19kaXJfXztcbiAgICAgIHJlc3VsdC5fX2ZpbHRlcmVkX18gPSB0aGlzLl9fZmlsdGVyZWRfXztcbiAgICAgIHJlc3VsdC5fX2l0ZXJhdGVlc19fID0gY29weUFycmF5KHRoaXMuX19pdGVyYXRlZXNfXyk7XG4gICAgICByZXN1bHQuX190YWtlQ291bnRfXyA9IHRoaXMuX190YWtlQ291bnRfXztcbiAgICAgIHJlc3VsdC5fX3ZpZXdzX18gPSBjb3B5QXJyYXkodGhpcy5fX3ZpZXdzX18pO1xuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZXZlcnNlcyB0aGUgZGlyZWN0aW9uIG9mIGxhenkgaXRlcmF0aW9uLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAbmFtZSByZXZlcnNlXG4gICAgICogQG1lbWJlck9mIExhenlXcmFwcGVyXG4gICAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyB0aGUgbmV3IHJldmVyc2VkIGBMYXp5V3JhcHBlcmAgb2JqZWN0LlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGxhenlSZXZlcnNlKCkge1xuICAgICAgaWYgKHRoaXMuX19maWx0ZXJlZF9fKSB7XG4gICAgICAgIHZhciByZXN1bHQgPSBuZXcgTGF6eVdyYXBwZXIodGhpcyk7XG4gICAgICAgIHJlc3VsdC5fX2Rpcl9fID0gLTE7XG4gICAgICAgIHJlc3VsdC5fX2ZpbHRlcmVkX18gPSB0cnVlO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmVzdWx0ID0gdGhpcy5jbG9uZSgpO1xuICAgICAgICByZXN1bHQuX19kaXJfXyAqPSAtMTtcbiAgICAgIH1cbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRXh0cmFjdHMgdGhlIHVud3JhcHBlZCB2YWx1ZSBmcm9tIGl0cyBsYXp5IHdyYXBwZXIuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBuYW1lIHZhbHVlXG4gICAgICogQG1lbWJlck9mIExhenlXcmFwcGVyXG4gICAgICogQHJldHVybnMgeyp9IFJldHVybnMgdGhlIHVud3JhcHBlZCB2YWx1ZS5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBsYXp5VmFsdWUoKSB7XG4gICAgICB2YXIgYXJyYXkgPSB0aGlzLl9fd3JhcHBlZF9fLnZhbHVlKCksXG4gICAgICAgICAgZGlyID0gdGhpcy5fX2Rpcl9fLFxuICAgICAgICAgIGlzQXJyID0gaXNBcnJheShhcnJheSksXG4gICAgICAgICAgaXNSaWdodCA9IGRpciA8IDAsXG4gICAgICAgICAgYXJyTGVuZ3RoID0gaXNBcnIgPyBhcnJheS5sZW5ndGggOiAwLFxuICAgICAgICAgIHZpZXcgPSBnZXRWaWV3KDAsIGFyckxlbmd0aCwgdGhpcy5fX3ZpZXdzX18pLFxuICAgICAgICAgIHN0YXJ0ID0gdmlldy5zdGFydCxcbiAgICAgICAgICBlbmQgPSB2aWV3LmVuZCxcbiAgICAgICAgICBsZW5ndGggPSBlbmQgLSBzdGFydCxcbiAgICAgICAgICBpbmRleCA9IGlzUmlnaHQgPyBlbmQgOiAoc3RhcnQgLSAxKSxcbiAgICAgICAgICBpdGVyYXRlZXMgPSB0aGlzLl9faXRlcmF0ZWVzX18sXG4gICAgICAgICAgaXRlckxlbmd0aCA9IGl0ZXJhdGVlcy5sZW5ndGgsXG4gICAgICAgICAgcmVzSW5kZXggPSAwLFxuICAgICAgICAgIHRha2VDb3VudCA9IG5hdGl2ZU1pbihsZW5ndGgsIHRoaXMuX190YWtlQ291bnRfXyk7XG5cbiAgICAgIGlmICghaXNBcnIgfHwgKCFpc1JpZ2h0ICYmIGFyckxlbmd0aCA9PSBsZW5ndGggJiYgdGFrZUNvdW50ID09IGxlbmd0aCkpIHtcbiAgICAgICAgcmV0dXJuIGJhc2VXcmFwcGVyVmFsdWUoYXJyYXksIHRoaXMuX19hY3Rpb25zX18pO1xuICAgICAgfVxuICAgICAgdmFyIHJlc3VsdCA9IFtdO1xuXG4gICAgICBvdXRlcjpcbiAgICAgIHdoaWxlIChsZW5ndGgtLSAmJiByZXNJbmRleCA8IHRha2VDb3VudCkge1xuICAgICAgICBpbmRleCArPSBkaXI7XG5cbiAgICAgICAgdmFyIGl0ZXJJbmRleCA9IC0xLFxuICAgICAgICAgICAgdmFsdWUgPSBhcnJheVtpbmRleF07XG5cbiAgICAgICAgd2hpbGUgKCsraXRlckluZGV4IDwgaXRlckxlbmd0aCkge1xuICAgICAgICAgIHZhciBkYXRhID0gaXRlcmF0ZWVzW2l0ZXJJbmRleF0sXG4gICAgICAgICAgICAgIGl0ZXJhdGVlID0gZGF0YS5pdGVyYXRlZSxcbiAgICAgICAgICAgICAgdHlwZSA9IGRhdGEudHlwZSxcbiAgICAgICAgICAgICAgY29tcHV0ZWQgPSBpdGVyYXRlZSh2YWx1ZSk7XG5cbiAgICAgICAgICBpZiAodHlwZSA9PSBMQVpZX01BUF9GTEFHKSB7XG4gICAgICAgICAgICB2YWx1ZSA9IGNvbXB1dGVkO1xuICAgICAgICAgIH0gZWxzZSBpZiAoIWNvbXB1dGVkKSB7XG4gICAgICAgICAgICBpZiAodHlwZSA9PSBMQVpZX0ZJTFRFUl9GTEFHKSB7XG4gICAgICAgICAgICAgIGNvbnRpbnVlIG91dGVyO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgYnJlYWsgb3V0ZXI7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJlc3VsdFtyZXNJbmRleCsrXSA9IHZhbHVlO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG5cbiAgICAvLyBFbnN1cmUgYExhenlXcmFwcGVyYCBpcyBhbiBpbnN0YW5jZSBvZiBgYmFzZUxvZGFzaGAuXG4gICAgTGF6eVdyYXBwZXIucHJvdG90eXBlID0gYmFzZUNyZWF0ZShiYXNlTG9kYXNoLnByb3RvdHlwZSk7XG4gICAgTGF6eVdyYXBwZXIucHJvdG90eXBlLmNvbnN0cnVjdG9yID0gTGF6eVdyYXBwZXI7XG5cbiAgICAvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovXG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgaGFzaCBvYmplY3QuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAqIEBwYXJhbSB7QXJyYXl9IFtlbnRyaWVzXSBUaGUga2V5LXZhbHVlIHBhaXJzIHRvIGNhY2hlLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIEhhc2goZW50cmllcykge1xuICAgICAgdmFyIGluZGV4ID0gLTEsXG4gICAgICAgICAgbGVuZ3RoID0gZW50cmllcyA9PSBudWxsID8gMCA6IGVudHJpZXMubGVuZ3RoO1xuXG4gICAgICB0aGlzLmNsZWFyKCk7XG4gICAgICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgICAgICB2YXIgZW50cnkgPSBlbnRyaWVzW2luZGV4XTtcbiAgICAgICAgdGhpcy5zZXQoZW50cnlbMF0sIGVudHJ5WzFdKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZW1vdmVzIGFsbCBrZXktdmFsdWUgZW50cmllcyBmcm9tIHRoZSBoYXNoLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAbmFtZSBjbGVhclxuICAgICAqIEBtZW1iZXJPZiBIYXNoXG4gICAgICovXG4gICAgZnVuY3Rpb24gaGFzaENsZWFyKCkge1xuICAgICAgdGhpcy5fX2RhdGFfXyA9IG5hdGl2ZUNyZWF0ZSA/IG5hdGl2ZUNyZWF0ZShudWxsKSA6IHt9O1xuICAgICAgdGhpcy5zaXplID0gMDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZW1vdmVzIGBrZXlgIGFuZCBpdHMgdmFsdWUgZnJvbSB0aGUgaGFzaC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQG5hbWUgZGVsZXRlXG4gICAgICogQG1lbWJlck9mIEhhc2hcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gaGFzaCBUaGUgaGFzaCB0byBtb2RpZnkuXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGtleSBUaGUga2V5IG9mIHRoZSB2YWx1ZSB0byByZW1vdmUuXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIHRoZSBlbnRyeSB3YXMgcmVtb3ZlZCwgZWxzZSBgZmFsc2VgLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGhhc2hEZWxldGUoa2V5KSB7XG4gICAgICB2YXIgcmVzdWx0ID0gdGhpcy5oYXMoa2V5KSAmJiBkZWxldGUgdGhpcy5fX2RhdGFfX1trZXldO1xuICAgICAgdGhpcy5zaXplIC09IHJlc3VsdCA/IDEgOiAwO1xuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXRzIHRoZSBoYXNoIHZhbHVlIGZvciBga2V5YC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQG5hbWUgZ2V0XG4gICAgICogQG1lbWJlck9mIEhhc2hcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30ga2V5IFRoZSBrZXkgb2YgdGhlIHZhbHVlIHRvIGdldC5cbiAgICAgKiBAcmV0dXJucyB7Kn0gUmV0dXJucyB0aGUgZW50cnkgdmFsdWUuXG4gICAgICovXG4gICAgZnVuY3Rpb24gaGFzaEdldChrZXkpIHtcbiAgICAgIHZhciBkYXRhID0gdGhpcy5fX2RhdGFfXztcbiAgICAgIGlmIChuYXRpdmVDcmVhdGUpIHtcbiAgICAgICAgdmFyIHJlc3VsdCA9IGRhdGFba2V5XTtcbiAgICAgICAgcmV0dXJuIHJlc3VsdCA9PT0gSEFTSF9VTkRFRklORUQgPyB1bmRlZmluZWQgOiByZXN1bHQ7XG4gICAgICB9XG4gICAgICByZXR1cm4gaGFzT3duUHJvcGVydHkuY2FsbChkYXRhLCBrZXkpID8gZGF0YVtrZXldIDogdW5kZWZpbmVkO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENoZWNrcyBpZiBhIGhhc2ggdmFsdWUgZm9yIGBrZXlgIGV4aXN0cy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQG5hbWUgaGFzXG4gICAgICogQG1lbWJlck9mIEhhc2hcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30ga2V5IFRoZSBrZXkgb2YgdGhlIGVudHJ5IHRvIGNoZWNrLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBhbiBlbnRyeSBmb3IgYGtleWAgZXhpc3RzLCBlbHNlIGBmYWxzZWAuXG4gICAgICovXG4gICAgZnVuY3Rpb24gaGFzaEhhcyhrZXkpIHtcbiAgICAgIHZhciBkYXRhID0gdGhpcy5fX2RhdGFfXztcbiAgICAgIHJldHVybiBuYXRpdmVDcmVhdGUgPyAoZGF0YVtrZXldICE9PSB1bmRlZmluZWQpIDogaGFzT3duUHJvcGVydHkuY2FsbChkYXRhLCBrZXkpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFNldHMgdGhlIGhhc2ggYGtleWAgdG8gYHZhbHVlYC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQG5hbWUgc2V0XG4gICAgICogQG1lbWJlck9mIEhhc2hcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30ga2V5IFRoZSBrZXkgb2YgdGhlIHZhbHVlIHRvIHNldC5cbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBzZXQuXG4gICAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyB0aGUgaGFzaCBpbnN0YW5jZS5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBoYXNoU2V0KGtleSwgdmFsdWUpIHtcbiAgICAgIHZhciBkYXRhID0gdGhpcy5fX2RhdGFfXztcbiAgICAgIHRoaXMuc2l6ZSArPSB0aGlzLmhhcyhrZXkpID8gMCA6IDE7XG4gICAgICBkYXRhW2tleV0gPSAobmF0aXZlQ3JlYXRlICYmIHZhbHVlID09PSB1bmRlZmluZWQpID8gSEFTSF9VTkRFRklORUQgOiB2YWx1ZTtcbiAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8vIEFkZCBtZXRob2RzIHRvIGBIYXNoYC5cbiAgICBIYXNoLnByb3RvdHlwZS5jbGVhciA9IGhhc2hDbGVhcjtcbiAgICBIYXNoLnByb3RvdHlwZVsnZGVsZXRlJ10gPSBoYXNoRGVsZXRlO1xuICAgIEhhc2gucHJvdG90eXBlLmdldCA9IGhhc2hHZXQ7XG4gICAgSGFzaC5wcm90b3R5cGUuaGFzID0gaGFzaEhhcztcbiAgICBIYXNoLnByb3RvdHlwZS5zZXQgPSBoYXNoU2V0O1xuXG4gICAgLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhbiBsaXN0IGNhY2hlIG9iamVjdC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQGNvbnN0cnVjdG9yXG4gICAgICogQHBhcmFtIHtBcnJheX0gW2VudHJpZXNdIFRoZSBrZXktdmFsdWUgcGFpcnMgdG8gY2FjaGUuXG4gICAgICovXG4gICAgZnVuY3Rpb24gTGlzdENhY2hlKGVudHJpZXMpIHtcbiAgICAgIHZhciBpbmRleCA9IC0xLFxuICAgICAgICAgIGxlbmd0aCA9IGVudHJpZXMgPT0gbnVsbCA/IDAgOiBlbnRyaWVzLmxlbmd0aDtcblxuICAgICAgdGhpcy5jbGVhcigpO1xuICAgICAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHtcbiAgICAgICAgdmFyIGVudHJ5ID0gZW50cmllc1tpbmRleF07XG4gICAgICAgIHRoaXMuc2V0KGVudHJ5WzBdLCBlbnRyeVsxXSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmVtb3ZlcyBhbGwga2V5LXZhbHVlIGVudHJpZXMgZnJvbSB0aGUgbGlzdCBjYWNoZS5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQG5hbWUgY2xlYXJcbiAgICAgKiBAbWVtYmVyT2YgTGlzdENhY2hlXG4gICAgICovXG4gICAgZnVuY3Rpb24gbGlzdENhY2hlQ2xlYXIoKSB7XG4gICAgICB0aGlzLl9fZGF0YV9fID0gW107XG4gICAgICB0aGlzLnNpemUgPSAwO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJlbW92ZXMgYGtleWAgYW5kIGl0cyB2YWx1ZSBmcm9tIHRoZSBsaXN0IGNhY2hlLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAbmFtZSBkZWxldGVcbiAgICAgKiBAbWVtYmVyT2YgTGlzdENhY2hlXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGtleSBUaGUga2V5IG9mIHRoZSB2YWx1ZSB0byByZW1vdmUuXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIHRoZSBlbnRyeSB3YXMgcmVtb3ZlZCwgZWxzZSBgZmFsc2VgLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGxpc3RDYWNoZURlbGV0ZShrZXkpIHtcbiAgICAgIHZhciBkYXRhID0gdGhpcy5fX2RhdGFfXyxcbiAgICAgICAgICBpbmRleCA9IGFzc29jSW5kZXhPZihkYXRhLCBrZXkpO1xuXG4gICAgICBpZiAoaW5kZXggPCAwKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICAgIHZhciBsYXN0SW5kZXggPSBkYXRhLmxlbmd0aCAtIDE7XG4gICAgICBpZiAoaW5kZXggPT0gbGFzdEluZGV4KSB7XG4gICAgICAgIGRhdGEucG9wKCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBzcGxpY2UuY2FsbChkYXRhLCBpbmRleCwgMSk7XG4gICAgICB9XG4gICAgICAtLXRoaXMuc2l6ZTtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldHMgdGhlIGxpc3QgY2FjaGUgdmFsdWUgZm9yIGBrZXlgLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAbmFtZSBnZXRcbiAgICAgKiBAbWVtYmVyT2YgTGlzdENhY2hlXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGtleSBUaGUga2V5IG9mIHRoZSB2YWx1ZSB0byBnZXQuXG4gICAgICogQHJldHVybnMgeyp9IFJldHVybnMgdGhlIGVudHJ5IHZhbHVlLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGxpc3RDYWNoZUdldChrZXkpIHtcbiAgICAgIHZhciBkYXRhID0gdGhpcy5fX2RhdGFfXyxcbiAgICAgICAgICBpbmRleCA9IGFzc29jSW5kZXhPZihkYXRhLCBrZXkpO1xuXG4gICAgICByZXR1cm4gaW5kZXggPCAwID8gdW5kZWZpbmVkIDogZGF0YVtpbmRleF1bMV07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2hlY2tzIGlmIGEgbGlzdCBjYWNoZSB2YWx1ZSBmb3IgYGtleWAgZXhpc3RzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAbmFtZSBoYXNcbiAgICAgKiBAbWVtYmVyT2YgTGlzdENhY2hlXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGtleSBUaGUga2V5IG9mIHRoZSBlbnRyeSB0byBjaGVjay5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYW4gZW50cnkgZm9yIGBrZXlgIGV4aXN0cywgZWxzZSBgZmFsc2VgLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGxpc3RDYWNoZUhhcyhrZXkpIHtcbiAgICAgIHJldHVybiBhc3NvY0luZGV4T2YodGhpcy5fX2RhdGFfXywga2V5KSA+IC0xO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFNldHMgdGhlIGxpc3QgY2FjaGUgYGtleWAgdG8gYHZhbHVlYC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQG5hbWUgc2V0XG4gICAgICogQG1lbWJlck9mIExpc3RDYWNoZVxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgVGhlIGtleSBvZiB0aGUgdmFsdWUgdG8gc2V0LlxuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIHNldC5cbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIHRoZSBsaXN0IGNhY2hlIGluc3RhbmNlLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGxpc3RDYWNoZVNldChrZXksIHZhbHVlKSB7XG4gICAgICB2YXIgZGF0YSA9IHRoaXMuX19kYXRhX18sXG4gICAgICAgICAgaW5kZXggPSBhc3NvY0luZGV4T2YoZGF0YSwga2V5KTtcblxuICAgICAgaWYgKGluZGV4IDwgMCkge1xuICAgICAgICArK3RoaXMuc2l6ZTtcbiAgICAgICAgZGF0YS5wdXNoKFtrZXksIHZhbHVlXSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBkYXRhW2luZGV4XVsxXSA9IHZhbHVlO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLy8gQWRkIG1ldGhvZHMgdG8gYExpc3RDYWNoZWAuXG4gICAgTGlzdENhY2hlLnByb3RvdHlwZS5jbGVhciA9IGxpc3RDYWNoZUNsZWFyO1xuICAgIExpc3RDYWNoZS5wcm90b3R5cGVbJ2RlbGV0ZSddID0gbGlzdENhY2hlRGVsZXRlO1xuICAgIExpc3RDYWNoZS5wcm90b3R5cGUuZ2V0ID0gbGlzdENhY2hlR2V0O1xuICAgIExpc3RDYWNoZS5wcm90b3R5cGUuaGFzID0gbGlzdENhY2hlSGFzO1xuICAgIExpc3RDYWNoZS5wcm90b3R5cGUuc2V0ID0gbGlzdENhY2hlU2V0O1xuXG4gICAgLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIG1hcCBjYWNoZSBvYmplY3QgdG8gc3RvcmUga2V5LXZhbHVlIHBhaXJzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBbZW50cmllc10gVGhlIGtleS12YWx1ZSBwYWlycyB0byBjYWNoZS5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBNYXBDYWNoZShlbnRyaWVzKSB7XG4gICAgICB2YXIgaW5kZXggPSAtMSxcbiAgICAgICAgICBsZW5ndGggPSBlbnRyaWVzID09IG51bGwgPyAwIDogZW50cmllcy5sZW5ndGg7XG5cbiAgICAgIHRoaXMuY2xlYXIoKTtcbiAgICAgIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XG4gICAgICAgIHZhciBlbnRyeSA9IGVudHJpZXNbaW5kZXhdO1xuICAgICAgICB0aGlzLnNldChlbnRyeVswXSwgZW50cnlbMV0pO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJlbW92ZXMgYWxsIGtleS12YWx1ZSBlbnRyaWVzIGZyb20gdGhlIG1hcC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQG5hbWUgY2xlYXJcbiAgICAgKiBAbWVtYmVyT2YgTWFwQ2FjaGVcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBtYXBDYWNoZUNsZWFyKCkge1xuICAgICAgdGhpcy5zaXplID0gMDtcbiAgICAgIHRoaXMuX19kYXRhX18gPSB7XG4gICAgICAgICdoYXNoJzogbmV3IEhhc2gsXG4gICAgICAgICdtYXAnOiBuZXcgKE1hcCB8fCBMaXN0Q2FjaGUpLFxuICAgICAgICAnc3RyaW5nJzogbmV3IEhhc2hcbiAgICAgIH07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmVtb3ZlcyBga2V5YCBhbmQgaXRzIHZhbHVlIGZyb20gdGhlIG1hcC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQG5hbWUgZGVsZXRlXG4gICAgICogQG1lbWJlck9mIE1hcENhY2hlXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGtleSBUaGUga2V5IG9mIHRoZSB2YWx1ZSB0byByZW1vdmUuXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIHRoZSBlbnRyeSB3YXMgcmVtb3ZlZCwgZWxzZSBgZmFsc2VgLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIG1hcENhY2hlRGVsZXRlKGtleSkge1xuICAgICAgdmFyIHJlc3VsdCA9IGdldE1hcERhdGEodGhpcywga2V5KVsnZGVsZXRlJ10oa2V5KTtcbiAgICAgIHRoaXMuc2l6ZSAtPSByZXN1bHQgPyAxIDogMDtcbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0cyB0aGUgbWFwIHZhbHVlIGZvciBga2V5YC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQG5hbWUgZ2V0XG4gICAgICogQG1lbWJlck9mIE1hcENhY2hlXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGtleSBUaGUga2V5IG9mIHRoZSB2YWx1ZSB0byBnZXQuXG4gICAgICogQHJldHVybnMgeyp9IFJldHVybnMgdGhlIGVudHJ5IHZhbHVlLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIG1hcENhY2hlR2V0KGtleSkge1xuICAgICAgcmV0dXJuIGdldE1hcERhdGEodGhpcywga2V5KS5nZXQoa2V5KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDaGVja3MgaWYgYSBtYXAgdmFsdWUgZm9yIGBrZXlgIGV4aXN0cy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQG5hbWUgaGFzXG4gICAgICogQG1lbWJlck9mIE1hcENhY2hlXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGtleSBUaGUga2V5IG9mIHRoZSBlbnRyeSB0byBjaGVjay5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYW4gZW50cnkgZm9yIGBrZXlgIGV4aXN0cywgZWxzZSBgZmFsc2VgLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIG1hcENhY2hlSGFzKGtleSkge1xuICAgICAgcmV0dXJuIGdldE1hcERhdGEodGhpcywga2V5KS5oYXMoa2V5KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTZXRzIHRoZSBtYXAgYGtleWAgdG8gYHZhbHVlYC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQG5hbWUgc2V0XG4gICAgICogQG1lbWJlck9mIE1hcENhY2hlXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGtleSBUaGUga2V5IG9mIHRoZSB2YWx1ZSB0byBzZXQuXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gc2V0LlxuICAgICAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgdGhlIG1hcCBjYWNoZSBpbnN0YW5jZS5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBtYXBDYWNoZVNldChrZXksIHZhbHVlKSB7XG4gICAgICB2YXIgZGF0YSA9IGdldE1hcERhdGEodGhpcywga2V5KSxcbiAgICAgICAgICBzaXplID0gZGF0YS5zaXplO1xuXG4gICAgICBkYXRhLnNldChrZXksIHZhbHVlKTtcbiAgICAgIHRoaXMuc2l6ZSArPSBkYXRhLnNpemUgPT0gc2l6ZSA/IDAgOiAxO1xuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLy8gQWRkIG1ldGhvZHMgdG8gYE1hcENhY2hlYC5cbiAgICBNYXBDYWNoZS5wcm90b3R5cGUuY2xlYXIgPSBtYXBDYWNoZUNsZWFyO1xuICAgIE1hcENhY2hlLnByb3RvdHlwZVsnZGVsZXRlJ10gPSBtYXBDYWNoZURlbGV0ZTtcbiAgICBNYXBDYWNoZS5wcm90b3R5cGUuZ2V0ID0gbWFwQ2FjaGVHZXQ7XG4gICAgTWFwQ2FjaGUucHJvdG90eXBlLmhhcyA9IG1hcENhY2hlSGFzO1xuICAgIE1hcENhY2hlLnByb3RvdHlwZS5zZXQgPSBtYXBDYWNoZVNldDtcblxuICAgIC8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi9cblxuICAgIC8qKlxuICAgICAqXG4gICAgICogQ3JlYXRlcyBhbiBhcnJheSBjYWNoZSBvYmplY3QgdG8gc3RvcmUgdW5pcXVlIHZhbHVlcy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQGNvbnN0cnVjdG9yXG4gICAgICogQHBhcmFtIHtBcnJheX0gW3ZhbHVlc10gVGhlIHZhbHVlcyB0byBjYWNoZS5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBTZXRDYWNoZSh2YWx1ZXMpIHtcbiAgICAgIHZhciBpbmRleCA9IC0xLFxuICAgICAgICAgIGxlbmd0aCA9IHZhbHVlcyA9PSBudWxsID8gMCA6IHZhbHVlcy5sZW5ndGg7XG5cbiAgICAgIHRoaXMuX19kYXRhX18gPSBuZXcgTWFwQ2FjaGU7XG4gICAgICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgICAgICB0aGlzLmFkZCh2YWx1ZXNbaW5kZXhdKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBBZGRzIGB2YWx1ZWAgdG8gdGhlIGFycmF5IGNhY2hlLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAbmFtZSBhZGRcbiAgICAgKiBAbWVtYmVyT2YgU2V0Q2FjaGVcbiAgICAgKiBAYWxpYXMgcHVzaFxuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNhY2hlLlxuICAgICAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgdGhlIGNhY2hlIGluc3RhbmNlLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIHNldENhY2hlQWRkKHZhbHVlKSB7XG4gICAgICB0aGlzLl9fZGF0YV9fLnNldCh2YWx1ZSwgSEFTSF9VTkRFRklORUQpO1xuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgaW4gdGhlIGFycmF5IGNhY2hlLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAbmFtZSBoYXNcbiAgICAgKiBAbWVtYmVyT2YgU2V0Q2FjaGVcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBzZWFyY2ggZm9yLlxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgZm91bmQsIGVsc2UgYGZhbHNlYC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBzZXRDYWNoZUhhcyh2YWx1ZSkge1xuICAgICAgcmV0dXJuIHRoaXMuX19kYXRhX18uaGFzKHZhbHVlKTtcbiAgICB9XG5cbiAgICAvLyBBZGQgbWV0aG9kcyB0byBgU2V0Q2FjaGVgLlxuICAgIFNldENhY2hlLnByb3RvdHlwZS5hZGQgPSBTZXRDYWNoZS5wcm90b3R5cGUucHVzaCA9IHNldENhY2hlQWRkO1xuICAgIFNldENhY2hlLnByb3RvdHlwZS5oYXMgPSBzZXRDYWNoZUhhcztcblxuICAgIC8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi9cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBzdGFjayBjYWNoZSBvYmplY3QgdG8gc3RvcmUga2V5LXZhbHVlIHBhaXJzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBbZW50cmllc10gVGhlIGtleS12YWx1ZSBwYWlycyB0byBjYWNoZS5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBTdGFjayhlbnRyaWVzKSB7XG4gICAgICB2YXIgZGF0YSA9IHRoaXMuX19kYXRhX18gPSBuZXcgTGlzdENhY2hlKGVudHJpZXMpO1xuICAgICAgdGhpcy5zaXplID0gZGF0YS5zaXplO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJlbW92ZXMgYWxsIGtleS12YWx1ZSBlbnRyaWVzIGZyb20gdGhlIHN0YWNrLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAbmFtZSBjbGVhclxuICAgICAqIEBtZW1iZXJPZiBTdGFja1xuICAgICAqL1xuICAgIGZ1bmN0aW9uIHN0YWNrQ2xlYXIoKSB7XG4gICAgICB0aGlzLl9fZGF0YV9fID0gbmV3IExpc3RDYWNoZTtcbiAgICAgIHRoaXMuc2l6ZSA9IDA7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmVtb3ZlcyBga2V5YCBhbmQgaXRzIHZhbHVlIGZyb20gdGhlIHN0YWNrLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAbmFtZSBkZWxldGVcbiAgICAgKiBAbWVtYmVyT2YgU3RhY2tcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30ga2V5IFRoZSBrZXkgb2YgdGhlIHZhbHVlIHRvIHJlbW92ZS5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgdGhlIGVudHJ5IHdhcyByZW1vdmVkLCBlbHNlIGBmYWxzZWAuXG4gICAgICovXG4gICAgZnVuY3Rpb24gc3RhY2tEZWxldGUoa2V5KSB7XG4gICAgICB2YXIgZGF0YSA9IHRoaXMuX19kYXRhX18sXG4gICAgICAgICAgcmVzdWx0ID0gZGF0YVsnZGVsZXRlJ10oa2V5KTtcblxuICAgICAgdGhpcy5zaXplID0gZGF0YS5zaXplO1xuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXRzIHRoZSBzdGFjayB2YWx1ZSBmb3IgYGtleWAuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBuYW1lIGdldFxuICAgICAqIEBtZW1iZXJPZiBTdGFja1xuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgVGhlIGtleSBvZiB0aGUgdmFsdWUgdG8gZ2V0LlxuICAgICAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSBlbnRyeSB2YWx1ZS5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBzdGFja0dldChrZXkpIHtcbiAgICAgIHJldHVybiB0aGlzLl9fZGF0YV9fLmdldChrZXkpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENoZWNrcyBpZiBhIHN0YWNrIHZhbHVlIGZvciBga2V5YCBleGlzdHMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBuYW1lIGhhc1xuICAgICAqIEBtZW1iZXJPZiBTdGFja1xuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgVGhlIGtleSBvZiB0aGUgZW50cnkgdG8gY2hlY2suXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGFuIGVudHJ5IGZvciBga2V5YCBleGlzdHMsIGVsc2UgYGZhbHNlYC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBzdGFja0hhcyhrZXkpIHtcbiAgICAgIHJldHVybiB0aGlzLl9fZGF0YV9fLmhhcyhrZXkpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFNldHMgdGhlIHN0YWNrIGBrZXlgIHRvIGB2YWx1ZWAuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBuYW1lIHNldFxuICAgICAqIEBtZW1iZXJPZiBTdGFja1xuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgVGhlIGtleSBvZiB0aGUgdmFsdWUgdG8gc2V0LlxuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIHNldC5cbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIHRoZSBzdGFjayBjYWNoZSBpbnN0YW5jZS5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBzdGFja1NldChrZXksIHZhbHVlKSB7XG4gICAgICB2YXIgZGF0YSA9IHRoaXMuX19kYXRhX187XG4gICAgICBpZiAoZGF0YSBpbnN0YW5jZW9mIExpc3RDYWNoZSkge1xuICAgICAgICB2YXIgcGFpcnMgPSBkYXRhLl9fZGF0YV9fO1xuICAgICAgICBpZiAoIU1hcCB8fCAocGFpcnMubGVuZ3RoIDwgTEFSR0VfQVJSQVlfU0laRSAtIDEpKSB7XG4gICAgICAgICAgcGFpcnMucHVzaChba2V5LCB2YWx1ZV0pO1xuICAgICAgICAgIHRoaXMuc2l6ZSA9ICsrZGF0YS5zaXplO1xuICAgICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgICB9XG4gICAgICAgIGRhdGEgPSB0aGlzLl9fZGF0YV9fID0gbmV3IE1hcENhY2hlKHBhaXJzKTtcbiAgICAgIH1cbiAgICAgIGRhdGEuc2V0KGtleSwgdmFsdWUpO1xuICAgICAgdGhpcy5zaXplID0gZGF0YS5zaXplO1xuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLy8gQWRkIG1ldGhvZHMgdG8gYFN0YWNrYC5cbiAgICBTdGFjay5wcm90b3R5cGUuY2xlYXIgPSBzdGFja0NsZWFyO1xuICAgIFN0YWNrLnByb3RvdHlwZVsnZGVsZXRlJ10gPSBzdGFja0RlbGV0ZTtcbiAgICBTdGFjay5wcm90b3R5cGUuZ2V0ID0gc3RhY2tHZXQ7XG4gICAgU3RhY2sucHJvdG90eXBlLmhhcyA9IHN0YWNrSGFzO1xuICAgIFN0YWNrLnByb3RvdHlwZS5zZXQgPSBzdGFja1NldDtcblxuICAgIC8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi9cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYW4gYXJyYXkgb2YgdGhlIGVudW1lcmFibGUgcHJvcGVydHkgbmFtZXMgb2YgdGhlIGFycmF5LWxpa2UgYHZhbHVlYC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gcXVlcnkuXG4gICAgICogQHBhcmFtIHtib29sZWFufSBpbmhlcml0ZWQgU3BlY2lmeSByZXR1cm5pbmcgaW5oZXJpdGVkIHByb3BlcnR5IG5hbWVzLlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgYXJyYXkgb2YgcHJvcGVydHkgbmFtZXMuXG4gICAgICovXG4gICAgZnVuY3Rpb24gYXJyYXlMaWtlS2V5cyh2YWx1ZSwgaW5oZXJpdGVkKSB7XG4gICAgICB2YXIgaXNBcnIgPSBpc0FycmF5KHZhbHVlKSxcbiAgICAgICAgICBpc0FyZyA9ICFpc0FyciAmJiBpc0FyZ3VtZW50cyh2YWx1ZSksXG4gICAgICAgICAgaXNCdWZmID0gIWlzQXJyICYmICFpc0FyZyAmJiBpc0J1ZmZlcih2YWx1ZSksXG4gICAgICAgICAgaXNUeXBlID0gIWlzQXJyICYmICFpc0FyZyAmJiAhaXNCdWZmICYmIGlzVHlwZWRBcnJheSh2YWx1ZSksXG4gICAgICAgICAgc2tpcEluZGV4ZXMgPSBpc0FyciB8fCBpc0FyZyB8fCBpc0J1ZmYgfHwgaXNUeXBlLFxuICAgICAgICAgIHJlc3VsdCA9IHNraXBJbmRleGVzID8gYmFzZVRpbWVzKHZhbHVlLmxlbmd0aCwgU3RyaW5nKSA6IFtdLFxuICAgICAgICAgIGxlbmd0aCA9IHJlc3VsdC5sZW5ndGg7XG5cbiAgICAgIGZvciAodmFyIGtleSBpbiB2YWx1ZSkge1xuICAgICAgICBpZiAoKGluaGVyaXRlZCB8fCBoYXNPd25Qcm9wZXJ0eS5jYWxsKHZhbHVlLCBrZXkpKSAmJlxuICAgICAgICAgICAgIShza2lwSW5kZXhlcyAmJiAoXG4gICAgICAgICAgICAgICAvLyBTYWZhcmkgOSBoYXMgZW51bWVyYWJsZSBgYXJndW1lbnRzLmxlbmd0aGAgaW4gc3RyaWN0IG1vZGUuXG4gICAgICAgICAgICAgICBrZXkgPT0gJ2xlbmd0aCcgfHxcbiAgICAgICAgICAgICAgIC8vIE5vZGUuanMgMC4xMCBoYXMgZW51bWVyYWJsZSBub24taW5kZXggcHJvcGVydGllcyBvbiBidWZmZXJzLlxuICAgICAgICAgICAgICAgKGlzQnVmZiAmJiAoa2V5ID09ICdvZmZzZXQnIHx8IGtleSA9PSAncGFyZW50JykpIHx8XG4gICAgICAgICAgICAgICAvLyBQaGFudG9tSlMgMiBoYXMgZW51bWVyYWJsZSBub24taW5kZXggcHJvcGVydGllcyBvbiB0eXBlZCBhcnJheXMuXG4gICAgICAgICAgICAgICAoaXNUeXBlICYmIChrZXkgPT0gJ2J1ZmZlcicgfHwga2V5ID09ICdieXRlTGVuZ3RoJyB8fCBrZXkgPT0gJ2J5dGVPZmZzZXQnKSkgfHxcbiAgICAgICAgICAgICAgIC8vIFNraXAgaW5kZXggcHJvcGVydGllcy5cbiAgICAgICAgICAgICAgIGlzSW5kZXgoa2V5LCBsZW5ndGgpXG4gICAgICAgICAgICApKSkge1xuICAgICAgICAgIHJlc3VsdC5wdXNoKGtleSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQSBzcGVjaWFsaXplZCB2ZXJzaW9uIG9mIGBfLnNhbXBsZWAgZm9yIGFycmF5cy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIHNhbXBsZS5cbiAgICAgKiBAcmV0dXJucyB7Kn0gUmV0dXJucyB0aGUgcmFuZG9tIGVsZW1lbnQuXG4gICAgICovXG4gICAgZnVuY3Rpb24gYXJyYXlTYW1wbGUoYXJyYXkpIHtcbiAgICAgIHZhciBsZW5ndGggPSBhcnJheS5sZW5ndGg7XG4gICAgICByZXR1cm4gbGVuZ3RoID8gYXJyYXlbYmFzZVJhbmRvbSgwLCBsZW5ndGggLSAxKV0gOiB1bmRlZmluZWQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQSBzcGVjaWFsaXplZCB2ZXJzaW9uIG9mIGBfLnNhbXBsZVNpemVgIGZvciBhcnJheXMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBzYW1wbGUuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IG4gVGhlIG51bWJlciBvZiBlbGVtZW50cyB0byBzYW1wbGUuXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSByYW5kb20gZWxlbWVudHMuXG4gICAgICovXG4gICAgZnVuY3Rpb24gYXJyYXlTYW1wbGVTaXplKGFycmF5LCBuKSB7XG4gICAgICByZXR1cm4gc2h1ZmZsZVNlbGYoY29weUFycmF5KGFycmF5KSwgYmFzZUNsYW1wKG4sIDAsIGFycmF5Lmxlbmd0aCkpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEEgc3BlY2lhbGl6ZWQgdmVyc2lvbiBvZiBgXy5zaHVmZmxlYCBmb3IgYXJyYXlzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gc2h1ZmZsZS5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIG5ldyBzaHVmZmxlZCBhcnJheS5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBhcnJheVNodWZmbGUoYXJyYXkpIHtcbiAgICAgIHJldHVybiBzaHVmZmxlU2VsZihjb3B5QXJyYXkoYXJyYXkpKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIGZ1bmN0aW9uIGlzIGxpa2UgYGFzc2lnblZhbHVlYCBleGNlcHQgdGhhdCBpdCBkb2Vzbid0IGFzc2lnblxuICAgICAqIGB1bmRlZmluZWRgIHZhbHVlcy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIG1vZGlmeS5cbiAgICAgKiBAcGFyYW0ge3N0cmluZ30ga2V5IFRoZSBrZXkgb2YgdGhlIHByb3BlcnR5IHRvIGFzc2lnbi5cbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBhc3NpZ24uXG4gICAgICovXG4gICAgZnVuY3Rpb24gYXNzaWduTWVyZ2VWYWx1ZShvYmplY3QsIGtleSwgdmFsdWUpIHtcbiAgICAgIGlmICgodmFsdWUgIT09IHVuZGVmaW5lZCAmJiAhZXEob2JqZWN0W2tleV0sIHZhbHVlKSkgfHxcbiAgICAgICAgICAodmFsdWUgPT09IHVuZGVmaW5lZCAmJiAhKGtleSBpbiBvYmplY3QpKSkge1xuICAgICAgICBiYXNlQXNzaWduVmFsdWUob2JqZWN0LCBrZXksIHZhbHVlKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBBc3NpZ25zIGB2YWx1ZWAgdG8gYGtleWAgb2YgYG9iamVjdGAgaWYgdGhlIGV4aXN0aW5nIHZhbHVlIGlzIG5vdCBlcXVpdmFsZW50XG4gICAgICogdXNpbmcgW2BTYW1lVmFsdWVaZXJvYF0oaHR0cDovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNy4wLyNzZWMtc2FtZXZhbHVlemVybylcbiAgICAgKiBmb3IgZXF1YWxpdHkgY29tcGFyaXNvbnMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBtb2RpZnkuXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGtleSBUaGUga2V5IG9mIHRoZSBwcm9wZXJ0eSB0byBhc3NpZ24uXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gYXNzaWduLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGFzc2lnblZhbHVlKG9iamVjdCwga2V5LCB2YWx1ZSkge1xuICAgICAgdmFyIG9ialZhbHVlID0gb2JqZWN0W2tleV07XG4gICAgICBpZiAoIShoYXNPd25Qcm9wZXJ0eS5jYWxsKG9iamVjdCwga2V5KSAmJiBlcShvYmpWYWx1ZSwgdmFsdWUpKSB8fFxuICAgICAgICAgICh2YWx1ZSA9PT0gdW5kZWZpbmVkICYmICEoa2V5IGluIG9iamVjdCkpKSB7XG4gICAgICAgIGJhc2VBc3NpZ25WYWx1ZShvYmplY3QsIGtleSwgdmFsdWUpO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldHMgdGhlIGluZGV4IGF0IHdoaWNoIHRoZSBga2V5YCBpcyBmb3VuZCBpbiBgYXJyYXlgIG9mIGtleS12YWx1ZSBwYWlycy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIGluc3BlY3QuXG4gICAgICogQHBhcmFtIHsqfSBrZXkgVGhlIGtleSB0byBzZWFyY2ggZm9yLlxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9IFJldHVybnMgdGhlIGluZGV4IG9mIHRoZSBtYXRjaGVkIHZhbHVlLCBlbHNlIGAtMWAuXG4gICAgICovXG4gICAgZnVuY3Rpb24gYXNzb2NJbmRleE9mKGFycmF5LCBrZXkpIHtcbiAgICAgIHZhciBsZW5ndGggPSBhcnJheS5sZW5ndGg7XG4gICAgICB3aGlsZSAobGVuZ3RoLS0pIHtcbiAgICAgICAgaWYgKGVxKGFycmF5W2xlbmd0aF1bMF0sIGtleSkpIHtcbiAgICAgICAgICByZXR1cm4gbGVuZ3RoO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gLTE7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQWdncmVnYXRlcyBlbGVtZW50cyBvZiBgY29sbGVjdGlvbmAgb24gYGFjY3VtdWxhdG9yYCB3aXRoIGtleXMgdHJhbnNmb3JtZWRcbiAgICAgKiBieSBgaXRlcmF0ZWVgIGFuZCB2YWx1ZXMgc2V0IGJ5IGBzZXR0ZXJgLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0FycmF5fE9iamVjdH0gY29sbGVjdGlvbiBUaGUgY29sbGVjdGlvbiB0byBpdGVyYXRlIG92ZXIuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gc2V0dGVyIFRoZSBmdW5jdGlvbiB0byBzZXQgYGFjY3VtdWxhdG9yYCB2YWx1ZXMuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gaXRlcmF0ZWUgVGhlIGl0ZXJhdGVlIHRvIHRyYW5zZm9ybSBrZXlzLlxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBhY2N1bXVsYXRvciBUaGUgaW5pdGlhbCBhZ2dyZWdhdGVkIG9iamVjdC5cbiAgICAgKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgYGFjY3VtdWxhdG9yYC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBiYXNlQWdncmVnYXRvcihjb2xsZWN0aW9uLCBzZXR0ZXIsIGl0ZXJhdGVlLCBhY2N1bXVsYXRvcikge1xuICAgICAgYmFzZUVhY2goY29sbGVjdGlvbiwgZnVuY3Rpb24odmFsdWUsIGtleSwgY29sbGVjdGlvbikge1xuICAgICAgICBzZXR0ZXIoYWNjdW11bGF0b3IsIHZhbHVlLCBpdGVyYXRlZSh2YWx1ZSksIGNvbGxlY3Rpb24pO1xuICAgICAgfSk7XG4gICAgICByZXR1cm4gYWNjdW11bGF0b3I7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uYXNzaWduYCB3aXRob3V0IHN1cHBvcnQgZm9yIG11bHRpcGxlIHNvdXJjZXNcbiAgICAgKiBvciBgY3VzdG9taXplcmAgZnVuY3Rpb25zLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBkZXN0aW5hdGlvbiBvYmplY3QuXG4gICAgICogQHBhcmFtIHtPYmplY3R9IHNvdXJjZSBUaGUgc291cmNlIG9iamVjdC5cbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIGBvYmplY3RgLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGJhc2VBc3NpZ24ob2JqZWN0LCBzb3VyY2UpIHtcbiAgICAgIHJldHVybiBvYmplY3QgJiYgY29weU9iamVjdChzb3VyY2UsIGtleXMoc291cmNlKSwgb2JqZWN0KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5hc3NpZ25JbmAgd2l0aG91dCBzdXBwb3J0IGZvciBtdWx0aXBsZSBzb3VyY2VzXG4gICAgICogb3IgYGN1c3RvbWl6ZXJgIGZ1bmN0aW9ucy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgZGVzdGluYXRpb24gb2JqZWN0LlxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBzb3VyY2UgVGhlIHNvdXJjZSBvYmplY3QuXG4gICAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyBgb2JqZWN0YC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBiYXNlQXNzaWduSW4ob2JqZWN0LCBzb3VyY2UpIHtcbiAgICAgIHJldHVybiBvYmplY3QgJiYgY29weU9iamVjdChzb3VyY2UsIGtleXNJbihzb3VyY2UpLCBvYmplY3QpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBhc3NpZ25WYWx1ZWAgYW5kIGBhc3NpZ25NZXJnZVZhbHVlYCB3aXRob3V0XG4gICAgICogdmFsdWUgY2hlY2tzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gbW9kaWZ5LlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgVGhlIGtleSBvZiB0aGUgcHJvcGVydHkgdG8gYXNzaWduLlxuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGFzc2lnbi5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBiYXNlQXNzaWduVmFsdWUob2JqZWN0LCBrZXksIHZhbHVlKSB7XG4gICAgICBpZiAoa2V5ID09ICdfX3Byb3RvX18nICYmIGRlZmluZVByb3BlcnR5KSB7XG4gICAgICAgIGRlZmluZVByb3BlcnR5KG9iamVjdCwga2V5LCB7XG4gICAgICAgICAgJ2NvbmZpZ3VyYWJsZSc6IHRydWUsXG4gICAgICAgICAgJ2VudW1lcmFibGUnOiB0cnVlLFxuICAgICAgICAgICd2YWx1ZSc6IHZhbHVlLFxuICAgICAgICAgICd3cml0YWJsZSc6IHRydWVcbiAgICAgICAgfSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBvYmplY3Rba2V5XSA9IHZhbHVlO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLmF0YCB3aXRob3V0IHN1cHBvcnQgZm9yIGluZGl2aWR1YWwgcGF0aHMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBpdGVyYXRlIG92ZXIuXG4gICAgICogQHBhcmFtIHtzdHJpbmdbXX0gcGF0aHMgVGhlIHByb3BlcnR5IHBhdGhzIHRvIHBpY2suXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBwaWNrZWQgZWxlbWVudHMuXG4gICAgICovXG4gICAgZnVuY3Rpb24gYmFzZUF0KG9iamVjdCwgcGF0aHMpIHtcbiAgICAgIHZhciBpbmRleCA9IC0xLFxuICAgICAgICAgIGxlbmd0aCA9IHBhdGhzLmxlbmd0aCxcbiAgICAgICAgICByZXN1bHQgPSBBcnJheShsZW5ndGgpLFxuICAgICAgICAgIHNraXAgPSBvYmplY3QgPT0gbnVsbDtcblxuICAgICAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHtcbiAgICAgICAgcmVzdWx0W2luZGV4XSA9IHNraXAgPyB1bmRlZmluZWQgOiBnZXQob2JqZWN0LCBwYXRoc1tpbmRleF0pO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5jbGFtcGAgd2hpY2ggZG9lc24ndCBjb2VyY2UgYXJndW1lbnRzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gbnVtYmVyIFRoZSBudW1iZXIgdG8gY2xhbXAuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtsb3dlcl0gVGhlIGxvd2VyIGJvdW5kLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSB1cHBlciBUaGUgdXBwZXIgYm91bmQuXG4gICAgICogQHJldHVybnMge251bWJlcn0gUmV0dXJucyB0aGUgY2xhbXBlZCBudW1iZXIuXG4gICAgICovXG4gICAgZnVuY3Rpb24gYmFzZUNsYW1wKG51bWJlciwgbG93ZXIsIHVwcGVyKSB7XG4gICAgICBpZiAobnVtYmVyID09PSBudW1iZXIpIHtcbiAgICAgICAgaWYgKHVwcGVyICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICBudW1iZXIgPSBudW1iZXIgPD0gdXBwZXIgPyBudW1iZXIgOiB1cHBlcjtcbiAgICAgICAgfVxuICAgICAgICBpZiAobG93ZXIgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIG51bWJlciA9IG51bWJlciA+PSBsb3dlciA/IG51bWJlciA6IGxvd2VyO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gbnVtYmVyO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLmNsb25lYCBhbmQgYF8uY2xvbmVEZWVwYCB3aGljaCB0cmFja3NcbiAgICAgKiB0cmF2ZXJzZWQgb2JqZWN0cy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2xvbmUuXG4gICAgICogQHBhcmFtIHtib29sZWFufSBiaXRtYXNrIFRoZSBiaXRtYXNrIGZsYWdzLlxuICAgICAqICAxIC0gRGVlcCBjbG9uZVxuICAgICAqICAyIC0gRmxhdHRlbiBpbmhlcml0ZWQgcHJvcGVydGllc1xuICAgICAqICA0IC0gQ2xvbmUgc3ltYm9sc1xuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IFtjdXN0b21pemVyXSBUaGUgZnVuY3Rpb24gdG8gY3VzdG9taXplIGNsb25pbmcuXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IFtrZXldIFRoZSBrZXkgb2YgYHZhbHVlYC5cbiAgICAgKiBAcGFyYW0ge09iamVjdH0gW29iamVjdF0gVGhlIHBhcmVudCBvYmplY3Qgb2YgYHZhbHVlYC5cbiAgICAgKiBAcGFyYW0ge09iamVjdH0gW3N0YWNrXSBUcmFja3MgdHJhdmVyc2VkIG9iamVjdHMgYW5kIHRoZWlyIGNsb25lIGNvdW50ZXJwYXJ0cy5cbiAgICAgKiBAcmV0dXJucyB7Kn0gUmV0dXJucyB0aGUgY2xvbmVkIHZhbHVlLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGJhc2VDbG9uZSh2YWx1ZSwgYml0bWFzaywgY3VzdG9taXplciwga2V5LCBvYmplY3QsIHN0YWNrKSB7XG4gICAgICB2YXIgcmVzdWx0LFxuICAgICAgICAgIGlzRGVlcCA9IGJpdG1hc2sgJiBDTE9ORV9ERUVQX0ZMQUcsXG4gICAgICAgICAgaXNGbGF0ID0gYml0bWFzayAmIENMT05FX0ZMQVRfRkxBRyxcbiAgICAgICAgICBpc0Z1bGwgPSBiaXRtYXNrICYgQ0xPTkVfU1lNQk9MU19GTEFHO1xuXG4gICAgICBpZiAoY3VzdG9taXplcikge1xuICAgICAgICByZXN1bHQgPSBvYmplY3QgPyBjdXN0b21pemVyKHZhbHVlLCBrZXksIG9iamVjdCwgc3RhY2spIDogY3VzdG9taXplcih2YWx1ZSk7XG4gICAgICB9XG4gICAgICBpZiAocmVzdWx0ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgIH1cbiAgICAgIGlmICghaXNPYmplY3QodmFsdWUpKSB7XG4gICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICAgIH1cbiAgICAgIHZhciBpc0FyciA9IGlzQXJyYXkodmFsdWUpO1xuICAgICAgaWYgKGlzQXJyKSB7XG4gICAgICAgIHJlc3VsdCA9IGluaXRDbG9uZUFycmF5KHZhbHVlKTtcbiAgICAgICAgaWYgKCFpc0RlZXApIHtcbiAgICAgICAgICByZXR1cm4gY29weUFycmF5KHZhbHVlLCByZXN1bHQpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB2YXIgdGFnID0gZ2V0VGFnKHZhbHVlKSxcbiAgICAgICAgICAgIGlzRnVuYyA9IHRhZyA9PSBmdW5jVGFnIHx8IHRhZyA9PSBnZW5UYWc7XG5cbiAgICAgICAgaWYgKGlzQnVmZmVyKHZhbHVlKSkge1xuICAgICAgICAgIHJldHVybiBjbG9uZUJ1ZmZlcih2YWx1ZSwgaXNEZWVwKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodGFnID09IG9iamVjdFRhZyB8fCB0YWcgPT0gYXJnc1RhZyB8fCAoaXNGdW5jICYmICFvYmplY3QpKSB7XG4gICAgICAgICAgcmVzdWx0ID0gKGlzRmxhdCB8fCBpc0Z1bmMpID8ge30gOiBpbml0Q2xvbmVPYmplY3QodmFsdWUpO1xuICAgICAgICAgIGlmICghaXNEZWVwKSB7XG4gICAgICAgICAgICByZXR1cm4gaXNGbGF0XG4gICAgICAgICAgICAgID8gY29weVN5bWJvbHNJbih2YWx1ZSwgYmFzZUFzc2lnbkluKHJlc3VsdCwgdmFsdWUpKVxuICAgICAgICAgICAgICA6IGNvcHlTeW1ib2xzKHZhbHVlLCBiYXNlQXNzaWduKHJlc3VsdCwgdmFsdWUpKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgaWYgKCFjbG9uZWFibGVUYWdzW3RhZ10pIHtcbiAgICAgICAgICAgIHJldHVybiBvYmplY3QgPyB2YWx1ZSA6IHt9O1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXN1bHQgPSBpbml0Q2xvbmVCeVRhZyh2YWx1ZSwgdGFnLCBpc0RlZXApO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICAvLyBDaGVjayBmb3IgY2lyY3VsYXIgcmVmZXJlbmNlcyBhbmQgcmV0dXJuIGl0cyBjb3JyZXNwb25kaW5nIGNsb25lLlxuICAgICAgc3RhY2sgfHwgKHN0YWNrID0gbmV3IFN0YWNrKTtcbiAgICAgIHZhciBzdGFja2VkID0gc3RhY2suZ2V0KHZhbHVlKTtcbiAgICAgIGlmIChzdGFja2VkKSB7XG4gICAgICAgIHJldHVybiBzdGFja2VkO1xuICAgICAgfVxuICAgICAgc3RhY2suc2V0KHZhbHVlLCByZXN1bHQpO1xuXG4gICAgICBpZiAoaXNTZXQodmFsdWUpKSB7XG4gICAgICAgIHZhbHVlLmZvckVhY2goZnVuY3Rpb24oc3ViVmFsdWUpIHtcbiAgICAgICAgICByZXN1bHQuYWRkKGJhc2VDbG9uZShzdWJWYWx1ZSwgYml0bWFzaywgY3VzdG9taXplciwgc3ViVmFsdWUsIHZhbHVlLCBzdGFjaykpO1xuICAgICAgICB9KTtcbiAgICAgIH0gZWxzZSBpZiAoaXNNYXAodmFsdWUpKSB7XG4gICAgICAgIHZhbHVlLmZvckVhY2goZnVuY3Rpb24oc3ViVmFsdWUsIGtleSkge1xuICAgICAgICAgIHJlc3VsdC5zZXQoa2V5LCBiYXNlQ2xvbmUoc3ViVmFsdWUsIGJpdG1hc2ssIGN1c3RvbWl6ZXIsIGtleSwgdmFsdWUsIHN0YWNrKSk7XG4gICAgICAgIH0pO1xuICAgICAgfVxuXG4gICAgICB2YXIga2V5c0Z1bmMgPSBpc0Z1bGxcbiAgICAgICAgPyAoaXNGbGF0ID8gZ2V0QWxsS2V5c0luIDogZ2V0QWxsS2V5cylcbiAgICAgICAgOiAoaXNGbGF0ID8ga2V5c0luIDoga2V5cyk7XG5cbiAgICAgIHZhciBwcm9wcyA9IGlzQXJyID8gdW5kZWZpbmVkIDoga2V5c0Z1bmModmFsdWUpO1xuICAgICAgYXJyYXlFYWNoKHByb3BzIHx8IHZhbHVlLCBmdW5jdGlvbihzdWJWYWx1ZSwga2V5KSB7XG4gICAgICAgIGlmIChwcm9wcykge1xuICAgICAgICAgIGtleSA9IHN1YlZhbHVlO1xuICAgICAgICAgIHN1YlZhbHVlID0gdmFsdWVba2V5XTtcbiAgICAgICAgfVxuICAgICAgICAvLyBSZWN1cnNpdmVseSBwb3B1bGF0ZSBjbG9uZSAoc3VzY2VwdGlibGUgdG8gY2FsbCBzdGFjayBsaW1pdHMpLlxuICAgICAgICBhc3NpZ25WYWx1ZShyZXN1bHQsIGtleSwgYmFzZUNsb25lKHN1YlZhbHVlLCBiaXRtYXNrLCBjdXN0b21pemVyLCBrZXksIHZhbHVlLCBzdGFjaykpO1xuICAgICAgfSk7XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLmNvbmZvcm1zYCB3aGljaCBkb2Vzbid0IGNsb25lIGBzb3VyY2VgLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gc291cmNlIFRoZSBvYmplY3Qgb2YgcHJvcGVydHkgcHJlZGljYXRlcyB0byBjb25mb3JtIHRvLlxuICAgICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IHNwZWMgZnVuY3Rpb24uXG4gICAgICovXG4gICAgZnVuY3Rpb24gYmFzZUNvbmZvcm1zKHNvdXJjZSkge1xuICAgICAgdmFyIHByb3BzID0ga2V5cyhzb3VyY2UpO1xuICAgICAgcmV0dXJuIGZ1bmN0aW9uKG9iamVjdCkge1xuICAgICAgICByZXR1cm4gYmFzZUNvbmZvcm1zVG8ob2JqZWN0LCBzb3VyY2UsIHByb3BzKTtcbiAgICAgIH07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uY29uZm9ybXNUb2Agd2hpY2ggYWNjZXB0cyBgcHJvcHNgIHRvIGNoZWNrLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gaW5zcGVjdC5cbiAgICAgKiBAcGFyYW0ge09iamVjdH0gc291cmNlIFRoZSBvYmplY3Qgb2YgcHJvcGVydHkgcHJlZGljYXRlcyB0byBjb25mb3JtIHRvLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgb2JqZWN0YCBjb25mb3JtcywgZWxzZSBgZmFsc2VgLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGJhc2VDb25mb3Jtc1RvKG9iamVjdCwgc291cmNlLCBwcm9wcykge1xuICAgICAgdmFyIGxlbmd0aCA9IHByb3BzLmxlbmd0aDtcbiAgICAgIGlmIChvYmplY3QgPT0gbnVsbCkge1xuICAgICAgICByZXR1cm4gIWxlbmd0aDtcbiAgICAgIH1cbiAgICAgIG9iamVjdCA9IE9iamVjdChvYmplY3QpO1xuICAgICAgd2hpbGUgKGxlbmd0aC0tKSB7XG4gICAgICAgIHZhciBrZXkgPSBwcm9wc1tsZW5ndGhdLFxuICAgICAgICAgICAgcHJlZGljYXRlID0gc291cmNlW2tleV0sXG4gICAgICAgICAgICB2YWx1ZSA9IG9iamVjdFtrZXldO1xuXG4gICAgICAgIGlmICgodmFsdWUgPT09IHVuZGVmaW5lZCAmJiAhKGtleSBpbiBvYmplY3QpKSB8fCAhcHJlZGljYXRlKHZhbHVlKSkge1xuICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uZGVsYXlgIGFuZCBgXy5kZWZlcmAgd2hpY2ggYWNjZXB0cyBgYXJnc2BcbiAgICAgKiB0byBwcm92aWRlIHRvIGBmdW5jYC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gZnVuYyBUaGUgZnVuY3Rpb24gdG8gZGVsYXkuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHdhaXQgVGhlIG51bWJlciBvZiBtaWxsaXNlY29uZHMgdG8gZGVsYXkgaW52b2NhdGlvbi5cbiAgICAgKiBAcGFyYW0ge0FycmF5fSBhcmdzIFRoZSBhcmd1bWVudHMgdG8gcHJvdmlkZSB0byBgZnVuY2AuXG4gICAgICogQHJldHVybnMge251bWJlcnxPYmplY3R9IFJldHVybnMgdGhlIHRpbWVyIGlkIG9yIHRpbWVvdXQgb2JqZWN0LlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGJhc2VEZWxheShmdW5jLCB3YWl0LCBhcmdzKSB7XG4gICAgICBpZiAodHlwZW9mIGZ1bmMgIT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKEZVTkNfRVJST1JfVEVYVCk7XG4gICAgICB9XG4gICAgICByZXR1cm4gc2V0VGltZW91dChmdW5jdGlvbigpIHsgZnVuYy5hcHBseSh1bmRlZmluZWQsIGFyZ3MpOyB9LCB3YWl0KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBtZXRob2RzIGxpa2UgYF8uZGlmZmVyZW5jZWAgd2l0aG91dCBzdXBwb3J0XG4gICAgICogZm9yIGV4Y2x1ZGluZyBtdWx0aXBsZSBhcnJheXMgb3IgaXRlcmF0ZWUgc2hvcnRoYW5kcy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIGluc3BlY3QuXG4gICAgICogQHBhcmFtIHtBcnJheX0gdmFsdWVzIFRoZSB2YWx1ZXMgdG8gZXhjbHVkZS5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbaXRlcmF0ZWVdIFRoZSBpdGVyYXRlZSBpbnZva2VkIHBlciBlbGVtZW50LlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IFtjb21wYXJhdG9yXSBUaGUgY29tcGFyYXRvciBpbnZva2VkIHBlciBlbGVtZW50LlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IGFycmF5IG9mIGZpbHRlcmVkIHZhbHVlcy5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBiYXNlRGlmZmVyZW5jZShhcnJheSwgdmFsdWVzLCBpdGVyYXRlZSwgY29tcGFyYXRvcikge1xuICAgICAgdmFyIGluZGV4ID0gLTEsXG4gICAgICAgICAgaW5jbHVkZXMgPSBhcnJheUluY2x1ZGVzLFxuICAgICAgICAgIGlzQ29tbW9uID0gdHJ1ZSxcbiAgICAgICAgICBsZW5ndGggPSBhcnJheS5sZW5ndGgsXG4gICAgICAgICAgcmVzdWx0ID0gW10sXG4gICAgICAgICAgdmFsdWVzTGVuZ3RoID0gdmFsdWVzLmxlbmd0aDtcblxuICAgICAgaWYgKCFsZW5ndGgpIHtcbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgIH1cbiAgICAgIGlmIChpdGVyYXRlZSkge1xuICAgICAgICB2YWx1ZXMgPSBhcnJheU1hcCh2YWx1ZXMsIGJhc2VVbmFyeShpdGVyYXRlZSkpO1xuICAgICAgfVxuICAgICAgaWYgKGNvbXBhcmF0b3IpIHtcbiAgICAgICAgaW5jbHVkZXMgPSBhcnJheUluY2x1ZGVzV2l0aDtcbiAgICAgICAgaXNDb21tb24gPSBmYWxzZTtcbiAgICAgIH1cbiAgICAgIGVsc2UgaWYgKHZhbHVlcy5sZW5ndGggPj0gTEFSR0VfQVJSQVlfU0laRSkge1xuICAgICAgICBpbmNsdWRlcyA9IGNhY2hlSGFzO1xuICAgICAgICBpc0NvbW1vbiA9IGZhbHNlO1xuICAgICAgICB2YWx1ZXMgPSBuZXcgU2V0Q2FjaGUodmFsdWVzKTtcbiAgICAgIH1cbiAgICAgIG91dGVyOlxuICAgICAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHtcbiAgICAgICAgdmFyIHZhbHVlID0gYXJyYXlbaW5kZXhdLFxuICAgICAgICAgICAgY29tcHV0ZWQgPSBpdGVyYXRlZSA9PSBudWxsID8gdmFsdWUgOiBpdGVyYXRlZSh2YWx1ZSk7XG5cbiAgICAgICAgdmFsdWUgPSAoY29tcGFyYXRvciB8fCB2YWx1ZSAhPT0gMCkgPyB2YWx1ZSA6IDA7XG4gICAgICAgIGlmIChpc0NvbW1vbiAmJiBjb21wdXRlZCA9PT0gY29tcHV0ZWQpIHtcbiAgICAgICAgICB2YXIgdmFsdWVzSW5kZXggPSB2YWx1ZXNMZW5ndGg7XG4gICAgICAgICAgd2hpbGUgKHZhbHVlc0luZGV4LS0pIHtcbiAgICAgICAgICAgIGlmICh2YWx1ZXNbdmFsdWVzSW5kZXhdID09PSBjb21wdXRlZCkge1xuICAgICAgICAgICAgICBjb250aW51ZSBvdXRlcjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICAgcmVzdWx0LnB1c2godmFsdWUpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKCFpbmNsdWRlcyh2YWx1ZXMsIGNvbXB1dGVkLCBjb21wYXJhdG9yKSkge1xuICAgICAgICAgIHJlc3VsdC5wdXNoKHZhbHVlKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5mb3JFYWNoYCB3aXRob3V0IHN1cHBvcnQgZm9yIGl0ZXJhdGVlIHNob3J0aGFuZHMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7QXJyYXl8T2JqZWN0fSBjb2xsZWN0aW9uIFRoZSBjb2xsZWN0aW9uIHRvIGl0ZXJhdGUgb3Zlci5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBpdGVyYXRlZSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICAgICAqIEByZXR1cm5zIHtBcnJheXxPYmplY3R9IFJldHVybnMgYGNvbGxlY3Rpb25gLlxuICAgICAqL1xuICAgIHZhciBiYXNlRWFjaCA9IGNyZWF0ZUJhc2VFYWNoKGJhc2VGb3JPd24pO1xuXG4gICAgLyoqXG4gICAgICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uZm9yRWFjaFJpZ2h0YCB3aXRob3V0IHN1cHBvcnQgZm9yIGl0ZXJhdGVlIHNob3J0aGFuZHMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7QXJyYXl8T2JqZWN0fSBjb2xsZWN0aW9uIFRoZSBjb2xsZWN0aW9uIHRvIGl0ZXJhdGUgb3Zlci5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBpdGVyYXRlZSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICAgICAqIEByZXR1cm5zIHtBcnJheXxPYmplY3R9IFJldHVybnMgYGNvbGxlY3Rpb25gLlxuICAgICAqL1xuICAgIHZhciBiYXNlRWFjaFJpZ2h0ID0gY3JlYXRlQmFzZUVhY2goYmFzZUZvck93blJpZ2h0LCB0cnVlKTtcblxuICAgIC8qKlxuICAgICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLmV2ZXJ5YCB3aXRob3V0IHN1cHBvcnQgZm9yIGl0ZXJhdGVlIHNob3J0aGFuZHMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7QXJyYXl8T2JqZWN0fSBjb2xsZWN0aW9uIFRoZSBjb2xsZWN0aW9uIHRvIGl0ZXJhdGUgb3Zlci5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBwcmVkaWNhdGUgVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIGl0ZXJhdGlvbi5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYWxsIGVsZW1lbnRzIHBhc3MgdGhlIHByZWRpY2F0ZSBjaGVjayxcbiAgICAgKiAgZWxzZSBgZmFsc2VgXG4gICAgICovXG4gICAgZnVuY3Rpb24gYmFzZUV2ZXJ5KGNvbGxlY3Rpb24sIHByZWRpY2F0ZSkge1xuICAgICAgdmFyIHJlc3VsdCA9IHRydWU7XG4gICAgICBiYXNlRWFjaChjb2xsZWN0aW9uLCBmdW5jdGlvbih2YWx1ZSwgaW5kZXgsIGNvbGxlY3Rpb24pIHtcbiAgICAgICAgcmVzdWx0ID0gISFwcmVkaWNhdGUodmFsdWUsIGluZGV4LCBjb2xsZWN0aW9uKTtcbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgIH0pO1xuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBtZXRob2RzIGxpa2UgYF8ubWF4YCBhbmQgYF8ubWluYCB3aGljaCBhY2NlcHRzIGFcbiAgICAgKiBgY29tcGFyYXRvcmAgdG8gZGV0ZXJtaW5lIHRoZSBleHRyZW11bSB2YWx1ZS5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIGl0ZXJhdGUgb3Zlci5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBpdGVyYXRlZSBUaGUgaXRlcmF0ZWUgaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGNvbXBhcmF0b3IgVGhlIGNvbXBhcmF0b3IgdXNlZCB0byBjb21wYXJlIHZhbHVlcy5cbiAgICAgKiBAcmV0dXJucyB7Kn0gUmV0dXJucyB0aGUgZXh0cmVtdW0gdmFsdWUuXG4gICAgICovXG4gICAgZnVuY3Rpb24gYmFzZUV4dHJlbXVtKGFycmF5LCBpdGVyYXRlZSwgY29tcGFyYXRvcikge1xuICAgICAgdmFyIGluZGV4ID0gLTEsXG4gICAgICAgICAgbGVuZ3RoID0gYXJyYXkubGVuZ3RoO1xuXG4gICAgICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgICAgICB2YXIgdmFsdWUgPSBhcnJheVtpbmRleF0sXG4gICAgICAgICAgICBjdXJyZW50ID0gaXRlcmF0ZWUodmFsdWUpO1xuXG4gICAgICAgIGlmIChjdXJyZW50ICE9IG51bGwgJiYgKGNvbXB1dGVkID09PSB1bmRlZmluZWRcbiAgICAgICAgICAgICAgPyAoY3VycmVudCA9PT0gY3VycmVudCAmJiAhaXNTeW1ib2woY3VycmVudCkpXG4gICAgICAgICAgICAgIDogY29tcGFyYXRvcihjdXJyZW50LCBjb21wdXRlZClcbiAgICAgICAgICAgICkpIHtcbiAgICAgICAgICB2YXIgY29tcHV0ZWQgPSBjdXJyZW50LFxuICAgICAgICAgICAgICByZXN1bHQgPSB2YWx1ZTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5maWxsYCB3aXRob3V0IGFuIGl0ZXJhdGVlIGNhbGwgZ3VhcmQuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBmaWxsLlxuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGZpbGwgYGFycmF5YCB3aXRoLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbc3RhcnQ9MF0gVGhlIHN0YXJ0IHBvc2l0aW9uLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbZW5kPWFycmF5Lmxlbmd0aF0gVGhlIGVuZCBwb3NpdGlvbi5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgYGFycmF5YC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBiYXNlRmlsbChhcnJheSwgdmFsdWUsIHN0YXJ0LCBlbmQpIHtcbiAgICAgIHZhciBsZW5ndGggPSBhcnJheS5sZW5ndGg7XG5cbiAgICAgIHN0YXJ0ID0gdG9JbnRlZ2VyKHN0YXJ0KTtcbiAgICAgIGlmIChzdGFydCA8IDApIHtcbiAgICAgICAgc3RhcnQgPSAtc3RhcnQgPiBsZW5ndGggPyAwIDogKGxlbmd0aCArIHN0YXJ0KTtcbiAgICAgIH1cbiAgICAgIGVuZCA9IChlbmQgPT09IHVuZGVmaW5lZCB8fCBlbmQgPiBsZW5ndGgpID8gbGVuZ3RoIDogdG9JbnRlZ2VyKGVuZCk7XG4gICAgICBpZiAoZW5kIDwgMCkge1xuICAgICAgICBlbmQgKz0gbGVuZ3RoO1xuICAgICAgfVxuICAgICAgZW5kID0gc3RhcnQgPiBlbmQgPyAwIDogdG9MZW5ndGgoZW5kKTtcbiAgICAgIHdoaWxlIChzdGFydCA8IGVuZCkge1xuICAgICAgICBhcnJheVtzdGFydCsrXSA9IHZhbHVlO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGFycmF5O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLmZpbHRlcmAgd2l0aG91dCBzdXBwb3J0IGZvciBpdGVyYXRlZSBzaG9ydGhhbmRzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0FycmF5fE9iamVjdH0gY29sbGVjdGlvbiBUaGUgY29sbGVjdGlvbiB0byBpdGVyYXRlIG92ZXIuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gcHJlZGljYXRlIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBuZXcgZmlsdGVyZWQgYXJyYXkuXG4gICAgICovXG4gICAgZnVuY3Rpb24gYmFzZUZpbHRlcihjb2xsZWN0aW9uLCBwcmVkaWNhdGUpIHtcbiAgICAgIHZhciByZXN1bHQgPSBbXTtcbiAgICAgIGJhc2VFYWNoKGNvbGxlY3Rpb24sIGZ1bmN0aW9uKHZhbHVlLCBpbmRleCwgY29sbGVjdGlvbikge1xuICAgICAgICBpZiAocHJlZGljYXRlKHZhbHVlLCBpbmRleCwgY29sbGVjdGlvbikpIHtcbiAgICAgICAgICByZXN1bHQucHVzaCh2YWx1ZSk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5mbGF0dGVuYCB3aXRoIHN1cHBvcnQgZm9yIHJlc3RyaWN0aW5nIGZsYXR0ZW5pbmcuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBmbGF0dGVuLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBkZXB0aCBUaGUgbWF4aW11bSByZWN1cnNpb24gZGVwdGguXG4gICAgICogQHBhcmFtIHtib29sZWFufSBbcHJlZGljYXRlPWlzRmxhdHRlbmFibGVdIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uXG4gICAgICogQHBhcmFtIHtib29sZWFufSBbaXNTdHJpY3RdIFJlc3RyaWN0IHRvIHZhbHVlcyB0aGF0IHBhc3MgYHByZWRpY2F0ZWAgY2hlY2tzLlxuICAgICAqIEBwYXJhbSB7QXJyYXl9IFtyZXN1bHQ9W11dIFRoZSBpbml0aWFsIHJlc3VsdCB2YWx1ZS5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIG5ldyBmbGF0dGVuZWQgYXJyYXkuXG4gICAgICovXG4gICAgZnVuY3Rpb24gYmFzZUZsYXR0ZW4oYXJyYXksIGRlcHRoLCBwcmVkaWNhdGUsIGlzU3RyaWN0LCByZXN1bHQpIHtcbiAgICAgIHZhciBpbmRleCA9IC0xLFxuICAgICAgICAgIGxlbmd0aCA9IGFycmF5Lmxlbmd0aDtcblxuICAgICAgcHJlZGljYXRlIHx8IChwcmVkaWNhdGUgPSBpc0ZsYXR0ZW5hYmxlKTtcbiAgICAgIHJlc3VsdCB8fCAocmVzdWx0ID0gW10pO1xuXG4gICAgICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgICAgICB2YXIgdmFsdWUgPSBhcnJheVtpbmRleF07XG4gICAgICAgIGlmIChkZXB0aCA+IDAgJiYgcHJlZGljYXRlKHZhbHVlKSkge1xuICAgICAgICAgIGlmIChkZXB0aCA+IDEpIHtcbiAgICAgICAgICAgIC8vIFJlY3Vyc2l2ZWx5IGZsYXR0ZW4gYXJyYXlzIChzdXNjZXB0aWJsZSB0byBjYWxsIHN0YWNrIGxpbWl0cykuXG4gICAgICAgICAgICBiYXNlRmxhdHRlbih2YWx1ZSwgZGVwdGggLSAxLCBwcmVkaWNhdGUsIGlzU3RyaWN0LCByZXN1bHQpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBhcnJheVB1c2gocmVzdWx0LCB2YWx1ZSk7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2UgaWYgKCFpc1N0cmljdCkge1xuICAgICAgICAgIHJlc3VsdFtyZXN1bHQubGVuZ3RoXSA9IHZhbHVlO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBiYXNlRm9yT3duYCB3aGljaCBpdGVyYXRlcyBvdmVyIGBvYmplY3RgXG4gICAgICogcHJvcGVydGllcyByZXR1cm5lZCBieSBga2V5c0Z1bmNgIGFuZCBpbnZva2VzIGBpdGVyYXRlZWAgZm9yIGVhY2ggcHJvcGVydHkuXG4gICAgICogSXRlcmF0ZWUgZnVuY3Rpb25zIG1heSBleGl0IGl0ZXJhdGlvbiBlYXJseSBieSBleHBsaWNpdGx5IHJldHVybmluZyBgZmFsc2VgLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gaXRlcmF0ZSBvdmVyLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGl0ZXJhdGVlIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0ga2V5c0Z1bmMgVGhlIGZ1bmN0aW9uIHRvIGdldCB0aGUga2V5cyBvZiBgb2JqZWN0YC5cbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIGBvYmplY3RgLlxuICAgICAqL1xuICAgIHZhciBiYXNlRm9yID0gY3JlYXRlQmFzZUZvcigpO1xuXG4gICAgLyoqXG4gICAgICogVGhpcyBmdW5jdGlvbiBpcyBsaWtlIGBiYXNlRm9yYCBleGNlcHQgdGhhdCBpdCBpdGVyYXRlcyBvdmVyIHByb3BlcnRpZXNcbiAgICAgKiBpbiB0aGUgb3Bwb3NpdGUgb3JkZXIuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBpdGVyYXRlIG92ZXIuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gaXRlcmF0ZWUgVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIGl0ZXJhdGlvbi5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBrZXlzRnVuYyBUaGUgZnVuY3Rpb24gdG8gZ2V0IHRoZSBrZXlzIG9mIGBvYmplY3RgLlxuICAgICAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgYG9iamVjdGAuXG4gICAgICovXG4gICAgdmFyIGJhc2VGb3JSaWdodCA9IGNyZWF0ZUJhc2VGb3IodHJ1ZSk7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5mb3JPd25gIHdpdGhvdXQgc3VwcG9ydCBmb3IgaXRlcmF0ZWUgc2hvcnRoYW5kcy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIGl0ZXJhdGUgb3Zlci5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBpdGVyYXRlZSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICAgICAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgYG9iamVjdGAuXG4gICAgICovXG4gICAgZnVuY3Rpb24gYmFzZUZvck93bihvYmplY3QsIGl0ZXJhdGVlKSB7XG4gICAgICByZXR1cm4gb2JqZWN0ICYmIGJhc2VGb3Iob2JqZWN0LCBpdGVyYXRlZSwga2V5cyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uZm9yT3duUmlnaHRgIHdpdGhvdXQgc3VwcG9ydCBmb3IgaXRlcmF0ZWUgc2hvcnRoYW5kcy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIGl0ZXJhdGUgb3Zlci5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBpdGVyYXRlZSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICAgICAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgYG9iamVjdGAuXG4gICAgICovXG4gICAgZnVuY3Rpb24gYmFzZUZvck93blJpZ2h0KG9iamVjdCwgaXRlcmF0ZWUpIHtcbiAgICAgIHJldHVybiBvYmplY3QgJiYgYmFzZUZvclJpZ2h0KG9iamVjdCwgaXRlcmF0ZWUsIGtleXMpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLmZ1bmN0aW9uc2Agd2hpY2ggY3JlYXRlcyBhbiBhcnJheSBvZlxuICAgICAqIGBvYmplY3RgIGZ1bmN0aW9uIHByb3BlcnR5IG5hbWVzIGZpbHRlcmVkIGZyb20gYHByb3BzYC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIGluc3BlY3QuXG4gICAgICogQHBhcmFtIHtBcnJheX0gcHJvcHMgVGhlIHByb3BlcnR5IG5hbWVzIHRvIGZpbHRlci5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIGZ1bmN0aW9uIG5hbWVzLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGJhc2VGdW5jdGlvbnMob2JqZWN0LCBwcm9wcykge1xuICAgICAgcmV0dXJuIGFycmF5RmlsdGVyKHByb3BzLCBmdW5jdGlvbihrZXkpIHtcbiAgICAgICAgcmV0dXJuIGlzRnVuY3Rpb24ob2JqZWN0W2tleV0pO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uZ2V0YCB3aXRob3V0IHN1cHBvcnQgZm9yIGRlZmF1bHQgdmFsdWVzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gcXVlcnkuXG4gICAgICogQHBhcmFtIHtBcnJheXxzdHJpbmd9IHBhdGggVGhlIHBhdGggb2YgdGhlIHByb3BlcnR5IHRvIGdldC5cbiAgICAgKiBAcmV0dXJucyB7Kn0gUmV0dXJucyB0aGUgcmVzb2x2ZWQgdmFsdWUuXG4gICAgICovXG4gICAgZnVuY3Rpb24gYmFzZUdldChvYmplY3QsIHBhdGgpIHtcbiAgICAgIHBhdGggPSBjYXN0UGF0aChwYXRoLCBvYmplY3QpO1xuXG4gICAgICB2YXIgaW5kZXggPSAwLFxuICAgICAgICAgIGxlbmd0aCA9IHBhdGgubGVuZ3RoO1xuXG4gICAgICB3aGlsZSAob2JqZWN0ICE9IG51bGwgJiYgaW5kZXggPCBsZW5ndGgpIHtcbiAgICAgICAgb2JqZWN0ID0gb2JqZWN0W3RvS2V5KHBhdGhbaW5kZXgrK10pXTtcbiAgICAgIH1cbiAgICAgIHJldHVybiAoaW5kZXggJiYgaW5kZXggPT0gbGVuZ3RoKSA/IG9iamVjdCA6IHVuZGVmaW5lZDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgZ2V0QWxsS2V5c2AgYW5kIGBnZXRBbGxLZXlzSW5gIHdoaWNoIHVzZXNcbiAgICAgKiBga2V5c0Z1bmNgIGFuZCBgc3ltYm9sc0Z1bmNgIHRvIGdldCB0aGUgZW51bWVyYWJsZSBwcm9wZXJ0eSBuYW1lcyBhbmRcbiAgICAgKiBzeW1ib2xzIG9mIGBvYmplY3RgLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gcXVlcnkuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0ga2V5c0Z1bmMgVGhlIGZ1bmN0aW9uIHRvIGdldCB0aGUga2V5cyBvZiBgb2JqZWN0YC5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBzeW1ib2xzRnVuYyBUaGUgZnVuY3Rpb24gdG8gZ2V0IHRoZSBzeW1ib2xzIG9mIGBvYmplY3RgLlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgYXJyYXkgb2YgcHJvcGVydHkgbmFtZXMgYW5kIHN5bWJvbHMuXG4gICAgICovXG4gICAgZnVuY3Rpb24gYmFzZUdldEFsbEtleXMob2JqZWN0LCBrZXlzRnVuYywgc3ltYm9sc0Z1bmMpIHtcbiAgICAgIHZhciByZXN1bHQgPSBrZXlzRnVuYyhvYmplY3QpO1xuICAgICAgcmV0dXJuIGlzQXJyYXkob2JqZWN0KSA/IHJlc3VsdCA6IGFycmF5UHVzaChyZXN1bHQsIHN5bWJvbHNGdW5jKG9iamVjdCkpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBnZXRUYWdgIHdpdGhvdXQgZmFsbGJhY2tzIGZvciBidWdneSBlbnZpcm9ubWVudHMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIHF1ZXJ5LlxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IFJldHVybnMgdGhlIGB0b1N0cmluZ1RhZ2AuXG4gICAgICovXG4gICAgZnVuY3Rpb24gYmFzZUdldFRhZyh2YWx1ZSkge1xuICAgICAgaWYgKHZhbHVlID09IG51bGwpIHtcbiAgICAgICAgcmV0dXJuIHZhbHVlID09PSB1bmRlZmluZWQgPyB1bmRlZmluZWRUYWcgOiBudWxsVGFnO1xuICAgICAgfVxuICAgICAgcmV0dXJuIChzeW1Ub1N0cmluZ1RhZyAmJiBzeW1Ub1N0cmluZ1RhZyBpbiBPYmplY3QodmFsdWUpKVxuICAgICAgICA/IGdldFJhd1RhZyh2YWx1ZSlcbiAgICAgICAgOiBvYmplY3RUb1N0cmluZyh2YWx1ZSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uZ3RgIHdoaWNoIGRvZXNuJ3QgY29lcmNlIGFyZ3VtZW50cy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY29tcGFyZS5cbiAgICAgKiBAcGFyYW0geyp9IG90aGVyIFRoZSBvdGhlciB2YWx1ZSB0byBjb21wYXJlLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGdyZWF0ZXIgdGhhbiBgb3RoZXJgLFxuICAgICAqICBlbHNlIGBmYWxzZWAuXG4gICAgICovXG4gICAgZnVuY3Rpb24gYmFzZUd0KHZhbHVlLCBvdGhlcikge1xuICAgICAgcmV0dXJuIHZhbHVlID4gb3RoZXI7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uaGFzYCB3aXRob3V0IHN1cHBvcnQgZm9yIGRlZXAgcGF0aHMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBbb2JqZWN0XSBUaGUgb2JqZWN0IHRvIHF1ZXJ5LlxuICAgICAqIEBwYXJhbSB7QXJyYXl8c3RyaW5nfSBrZXkgVGhlIGtleSB0byBjaGVjay5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYGtleWAgZXhpc3RzLCBlbHNlIGBmYWxzZWAuXG4gICAgICovXG4gICAgZnVuY3Rpb24gYmFzZUhhcyhvYmplY3QsIGtleSkge1xuICAgICAgcmV0dXJuIG9iamVjdCAhPSBudWxsICYmIGhhc093blByb3BlcnR5LmNhbGwob2JqZWN0LCBrZXkpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLmhhc0luYCB3aXRob3V0IHN1cHBvcnQgZm9yIGRlZXAgcGF0aHMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBbb2JqZWN0XSBUaGUgb2JqZWN0IHRvIHF1ZXJ5LlxuICAgICAqIEBwYXJhbSB7QXJyYXl8c3RyaW5nfSBrZXkgVGhlIGtleSB0byBjaGVjay5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYGtleWAgZXhpc3RzLCBlbHNlIGBmYWxzZWAuXG4gICAgICovXG4gICAgZnVuY3Rpb24gYmFzZUhhc0luKG9iamVjdCwga2V5KSB7XG4gICAgICByZXR1cm4gb2JqZWN0ICE9IG51bGwgJiYga2V5IGluIE9iamVjdChvYmplY3QpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLmluUmFuZ2VgIHdoaWNoIGRvZXNuJ3QgY29lcmNlIGFyZ3VtZW50cy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IG51bWJlciBUaGUgbnVtYmVyIHRvIGNoZWNrLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBzdGFydCBUaGUgc3RhcnQgb2YgdGhlIHJhbmdlLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBlbmQgVGhlIGVuZCBvZiB0aGUgcmFuZ2UuXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGBudW1iZXJgIGlzIGluIHRoZSByYW5nZSwgZWxzZSBgZmFsc2VgLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGJhc2VJblJhbmdlKG51bWJlciwgc3RhcnQsIGVuZCkge1xuICAgICAgcmV0dXJuIG51bWJlciA+PSBuYXRpdmVNaW4oc3RhcnQsIGVuZCkgJiYgbnVtYmVyIDwgbmF0aXZlTWF4KHN0YXJ0LCBlbmQpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIG1ldGhvZHMgbGlrZSBgXy5pbnRlcnNlY3Rpb25gLCB3aXRob3V0IHN1cHBvcnRcbiAgICAgKiBmb3IgaXRlcmF0ZWUgc2hvcnRoYW5kcywgdGhhdCBhY2NlcHRzIGFuIGFycmF5IG9mIGFycmF5cyB0byBpbnNwZWN0LlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheXMgVGhlIGFycmF5cyB0byBpbnNwZWN0LlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IFtpdGVyYXRlZV0gVGhlIGl0ZXJhdGVlIGludm9rZWQgcGVyIGVsZW1lbnQuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW2NvbXBhcmF0b3JdIFRoZSBjb21wYXJhdG9yIGludm9rZWQgcGVyIGVsZW1lbnQuXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBuZXcgYXJyYXkgb2Ygc2hhcmVkIHZhbHVlcy5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBiYXNlSW50ZXJzZWN0aW9uKGFycmF5cywgaXRlcmF0ZWUsIGNvbXBhcmF0b3IpIHtcbiAgICAgIHZhciBpbmNsdWRlcyA9IGNvbXBhcmF0b3IgPyBhcnJheUluY2x1ZGVzV2l0aCA6IGFycmF5SW5jbHVkZXMsXG4gICAgICAgICAgbGVuZ3RoID0gYXJyYXlzWzBdLmxlbmd0aCxcbiAgICAgICAgICBvdGhMZW5ndGggPSBhcnJheXMubGVuZ3RoLFxuICAgICAgICAgIG90aEluZGV4ID0gb3RoTGVuZ3RoLFxuICAgICAgICAgIGNhY2hlcyA9IEFycmF5KG90aExlbmd0aCksXG4gICAgICAgICAgbWF4TGVuZ3RoID0gSW5maW5pdHksXG4gICAgICAgICAgcmVzdWx0ID0gW107XG5cbiAgICAgIHdoaWxlIChvdGhJbmRleC0tKSB7XG4gICAgICAgIHZhciBhcnJheSA9IGFycmF5c1tvdGhJbmRleF07XG4gICAgICAgIGlmIChvdGhJbmRleCAmJiBpdGVyYXRlZSkge1xuICAgICAgICAgIGFycmF5ID0gYXJyYXlNYXAoYXJyYXksIGJhc2VVbmFyeShpdGVyYXRlZSkpO1xuICAgICAgICB9XG4gICAgICAgIG1heExlbmd0aCA9IG5hdGl2ZU1pbihhcnJheS5sZW5ndGgsIG1heExlbmd0aCk7XG4gICAgICAgIGNhY2hlc1tvdGhJbmRleF0gPSAhY29tcGFyYXRvciAmJiAoaXRlcmF0ZWUgfHwgKGxlbmd0aCA+PSAxMjAgJiYgYXJyYXkubGVuZ3RoID49IDEyMCkpXG4gICAgICAgICAgPyBuZXcgU2V0Q2FjaGUob3RoSW5kZXggJiYgYXJyYXkpXG4gICAgICAgICAgOiB1bmRlZmluZWQ7XG4gICAgICB9XG4gICAgICBhcnJheSA9IGFycmF5c1swXTtcblxuICAgICAgdmFyIGluZGV4ID0gLTEsXG4gICAgICAgICAgc2VlbiA9IGNhY2hlc1swXTtcblxuICAgICAgb3V0ZXI6XG4gICAgICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCAmJiByZXN1bHQubGVuZ3RoIDwgbWF4TGVuZ3RoKSB7XG4gICAgICAgIHZhciB2YWx1ZSA9IGFycmF5W2luZGV4XSxcbiAgICAgICAgICAgIGNvbXB1dGVkID0gaXRlcmF0ZWUgPyBpdGVyYXRlZSh2YWx1ZSkgOiB2YWx1ZTtcblxuICAgICAgICB2YWx1ZSA9IChjb21wYXJhdG9yIHx8IHZhbHVlICE9PSAwKSA/IHZhbHVlIDogMDtcbiAgICAgICAgaWYgKCEoc2VlblxuICAgICAgICAgICAgICA/IGNhY2hlSGFzKHNlZW4sIGNvbXB1dGVkKVxuICAgICAgICAgICAgICA6IGluY2x1ZGVzKHJlc3VsdCwgY29tcHV0ZWQsIGNvbXBhcmF0b3IpXG4gICAgICAgICAgICApKSB7XG4gICAgICAgICAgb3RoSW5kZXggPSBvdGhMZW5ndGg7XG4gICAgICAgICAgd2hpbGUgKC0tb3RoSW5kZXgpIHtcbiAgICAgICAgICAgIHZhciBjYWNoZSA9IGNhY2hlc1tvdGhJbmRleF07XG4gICAgICAgICAgICBpZiAoIShjYWNoZVxuICAgICAgICAgICAgICAgICAgPyBjYWNoZUhhcyhjYWNoZSwgY29tcHV0ZWQpXG4gICAgICAgICAgICAgICAgICA6IGluY2x1ZGVzKGFycmF5c1tvdGhJbmRleF0sIGNvbXB1dGVkLCBjb21wYXJhdG9yKSlcbiAgICAgICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgY29udGludWUgb3V0ZXI7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmIChzZWVuKSB7XG4gICAgICAgICAgICBzZWVuLnB1c2goY29tcHV0ZWQpO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXN1bHQucHVzaCh2YWx1ZSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uaW52ZXJ0YCBhbmQgYF8uaW52ZXJ0QnlgIHdoaWNoIGludmVydHNcbiAgICAgKiBgb2JqZWN0YCB3aXRoIHZhbHVlcyB0cmFuc2Zvcm1lZCBieSBgaXRlcmF0ZWVgIGFuZCBzZXQgYnkgYHNldHRlcmAuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBpdGVyYXRlIG92ZXIuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gc2V0dGVyIFRoZSBmdW5jdGlvbiB0byBzZXQgYGFjY3VtdWxhdG9yYCB2YWx1ZXMuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gaXRlcmF0ZWUgVGhlIGl0ZXJhdGVlIHRvIHRyYW5zZm9ybSB2YWx1ZXMuXG4gICAgICogQHBhcmFtIHtPYmplY3R9IGFjY3VtdWxhdG9yIFRoZSBpbml0aWFsIGludmVydGVkIG9iamVjdC5cbiAgICAgKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgYGFjY3VtdWxhdG9yYC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBiYXNlSW52ZXJ0ZXIob2JqZWN0LCBzZXR0ZXIsIGl0ZXJhdGVlLCBhY2N1bXVsYXRvcikge1xuICAgICAgYmFzZUZvck93bihvYmplY3QsIGZ1bmN0aW9uKHZhbHVlLCBrZXksIG9iamVjdCkge1xuICAgICAgICBzZXR0ZXIoYWNjdW11bGF0b3IsIGl0ZXJhdGVlKHZhbHVlKSwga2V5LCBvYmplY3QpO1xuICAgICAgfSk7XG4gICAgICByZXR1cm4gYWNjdW11bGF0b3I7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uaW52b2tlYCB3aXRob3V0IHN1cHBvcnQgZm9yIGluZGl2aWR1YWxcbiAgICAgKiBtZXRob2QgYXJndW1lbnRzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gcXVlcnkuXG4gICAgICogQHBhcmFtIHtBcnJheXxzdHJpbmd9IHBhdGggVGhlIHBhdGggb2YgdGhlIG1ldGhvZCB0byBpbnZva2UuXG4gICAgICogQHBhcmFtIHtBcnJheX0gYXJncyBUaGUgYXJndW1lbnRzIHRvIGludm9rZSB0aGUgbWV0aG9kIHdpdGguXG4gICAgICogQHJldHVybnMgeyp9IFJldHVybnMgdGhlIHJlc3VsdCBvZiB0aGUgaW52b2tlZCBtZXRob2QuXG4gICAgICovXG4gICAgZnVuY3Rpb24gYmFzZUludm9rZShvYmplY3QsIHBhdGgsIGFyZ3MpIHtcbiAgICAgIHBhdGggPSBjYXN0UGF0aChwYXRoLCBvYmplY3QpO1xuICAgICAgb2JqZWN0ID0gcGFyZW50KG9iamVjdCwgcGF0aCk7XG4gICAgICB2YXIgZnVuYyA9IG9iamVjdCA9PSBudWxsID8gb2JqZWN0IDogb2JqZWN0W3RvS2V5KGxhc3QocGF0aCkpXTtcbiAgICAgIHJldHVybiBmdW5jID09IG51bGwgPyB1bmRlZmluZWQgOiBhcHBseShmdW5jLCBvYmplY3QsIGFyZ3MpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLmlzQXJndW1lbnRzYC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgYW4gYGFyZ3VtZW50c2Agb2JqZWN0LFxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGJhc2VJc0FyZ3VtZW50cyh2YWx1ZSkge1xuICAgICAgcmV0dXJuIGlzT2JqZWN0TGlrZSh2YWx1ZSkgJiYgYmFzZUdldFRhZyh2YWx1ZSkgPT0gYXJnc1RhZztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5pc0FycmF5QnVmZmVyYCB3aXRob3V0IE5vZGUuanMgb3B0aW1pemF0aW9ucy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgYW4gYXJyYXkgYnVmZmVyLCBlbHNlIGBmYWxzZWAuXG4gICAgICovXG4gICAgZnVuY3Rpb24gYmFzZUlzQXJyYXlCdWZmZXIodmFsdWUpIHtcbiAgICAgIHJldHVybiBpc09iamVjdExpa2UodmFsdWUpICYmIGJhc2VHZXRUYWcodmFsdWUpID09IGFycmF5QnVmZmVyVGFnO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLmlzRGF0ZWAgd2l0aG91dCBOb2RlLmpzIG9wdGltaXphdGlvbnMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGEgZGF0ZSBvYmplY3QsIGVsc2UgYGZhbHNlYC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBiYXNlSXNEYXRlKHZhbHVlKSB7XG4gICAgICByZXR1cm4gaXNPYmplY3RMaWtlKHZhbHVlKSAmJiBiYXNlR2V0VGFnKHZhbHVlKSA9PSBkYXRlVGFnO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLmlzRXF1YWxgIHdoaWNoIHN1cHBvcnRzIHBhcnRpYWwgY29tcGFyaXNvbnNcbiAgICAgKiBhbmQgdHJhY2tzIHRyYXZlcnNlZCBvYmplY3RzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjb21wYXJlLlxuICAgICAqIEBwYXJhbSB7Kn0gb3RoZXIgVGhlIG90aGVyIHZhbHVlIHRvIGNvbXBhcmUuXG4gICAgICogQHBhcmFtIHtib29sZWFufSBiaXRtYXNrIFRoZSBiaXRtYXNrIGZsYWdzLlxuICAgICAqICAxIC0gVW5vcmRlcmVkIGNvbXBhcmlzb25cbiAgICAgKiAgMiAtIFBhcnRpYWwgY29tcGFyaXNvblxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IFtjdXN0b21pemVyXSBUaGUgZnVuY3Rpb24gdG8gY3VzdG9taXplIGNvbXBhcmlzb25zLlxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBbc3RhY2tdIFRyYWNrcyB0cmF2ZXJzZWQgYHZhbHVlYCBhbmQgYG90aGVyYCBvYmplY3RzLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiB0aGUgdmFsdWVzIGFyZSBlcXVpdmFsZW50LCBlbHNlIGBmYWxzZWAuXG4gICAgICovXG4gICAgZnVuY3Rpb24gYmFzZUlzRXF1YWwodmFsdWUsIG90aGVyLCBiaXRtYXNrLCBjdXN0b21pemVyLCBzdGFjaykge1xuICAgICAgaWYgKHZhbHVlID09PSBvdGhlcikge1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIH1cbiAgICAgIGlmICh2YWx1ZSA9PSBudWxsIHx8IG90aGVyID09IG51bGwgfHwgKCFpc09iamVjdExpa2UodmFsdWUpICYmICFpc09iamVjdExpa2Uob3RoZXIpKSkge1xuICAgICAgICByZXR1cm4gdmFsdWUgIT09IHZhbHVlICYmIG90aGVyICE9PSBvdGhlcjtcbiAgICAgIH1cbiAgICAgIHJldHVybiBiYXNlSXNFcXVhbERlZXAodmFsdWUsIG90aGVyLCBiaXRtYXNrLCBjdXN0b21pemVyLCBiYXNlSXNFcXVhbCwgc3RhY2spO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEEgc3BlY2lhbGl6ZWQgdmVyc2lvbiBvZiBgYmFzZUlzRXF1YWxgIGZvciBhcnJheXMgYW5kIG9iamVjdHMgd2hpY2ggcGVyZm9ybXNcbiAgICAgKiBkZWVwIGNvbXBhcmlzb25zIGFuZCB0cmFja3MgdHJhdmVyc2VkIG9iamVjdHMgZW5hYmxpbmcgb2JqZWN0cyB3aXRoIGNpcmN1bGFyXG4gICAgICogcmVmZXJlbmNlcyB0byBiZSBjb21wYXJlZC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIGNvbXBhcmUuXG4gICAgICogQHBhcmFtIHtPYmplY3R9IG90aGVyIFRoZSBvdGhlciBvYmplY3QgdG8gY29tcGFyZS5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gYml0bWFzayBUaGUgYml0bWFzayBmbGFncy4gU2VlIGBiYXNlSXNFcXVhbGAgZm9yIG1vcmUgZGV0YWlscy5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBjdXN0b21pemVyIFRoZSBmdW5jdGlvbiB0byBjdXN0b21pemUgY29tcGFyaXNvbnMuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gZXF1YWxGdW5jIFRoZSBmdW5jdGlvbiB0byBkZXRlcm1pbmUgZXF1aXZhbGVudHMgb2YgdmFsdWVzLlxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBbc3RhY2tdIFRyYWNrcyB0cmF2ZXJzZWQgYG9iamVjdGAgYW5kIGBvdGhlcmAgb2JqZWN0cy5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgdGhlIG9iamVjdHMgYXJlIGVxdWl2YWxlbnQsIGVsc2UgYGZhbHNlYC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBiYXNlSXNFcXVhbERlZXAob2JqZWN0LCBvdGhlciwgYml0bWFzaywgY3VzdG9taXplciwgZXF1YWxGdW5jLCBzdGFjaykge1xuICAgICAgdmFyIG9iaklzQXJyID0gaXNBcnJheShvYmplY3QpLFxuICAgICAgICAgIG90aElzQXJyID0gaXNBcnJheShvdGhlciksXG4gICAgICAgICAgb2JqVGFnID0gb2JqSXNBcnIgPyBhcnJheVRhZyA6IGdldFRhZyhvYmplY3QpLFxuICAgICAgICAgIG90aFRhZyA9IG90aElzQXJyID8gYXJyYXlUYWcgOiBnZXRUYWcob3RoZXIpO1xuXG4gICAgICBvYmpUYWcgPSBvYmpUYWcgPT0gYXJnc1RhZyA/IG9iamVjdFRhZyA6IG9ialRhZztcbiAgICAgIG90aFRhZyA9IG90aFRhZyA9PSBhcmdzVGFnID8gb2JqZWN0VGFnIDogb3RoVGFnO1xuXG4gICAgICB2YXIgb2JqSXNPYmogPSBvYmpUYWcgPT0gb2JqZWN0VGFnLFxuICAgICAgICAgIG90aElzT2JqID0gb3RoVGFnID09IG9iamVjdFRhZyxcbiAgICAgICAgICBpc1NhbWVUYWcgPSBvYmpUYWcgPT0gb3RoVGFnO1xuXG4gICAgICBpZiAoaXNTYW1lVGFnICYmIGlzQnVmZmVyKG9iamVjdCkpIHtcbiAgICAgICAgaWYgKCFpc0J1ZmZlcihvdGhlcikpIHtcbiAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgICAgb2JqSXNBcnIgPSB0cnVlO1xuICAgICAgICBvYmpJc09iaiA9IGZhbHNlO1xuICAgICAgfVxuICAgICAgaWYgKGlzU2FtZVRhZyAmJiAhb2JqSXNPYmopIHtcbiAgICAgICAgc3RhY2sgfHwgKHN0YWNrID0gbmV3IFN0YWNrKTtcbiAgICAgICAgcmV0dXJuIChvYmpJc0FyciB8fCBpc1R5cGVkQXJyYXkob2JqZWN0KSlcbiAgICAgICAgICA/IGVxdWFsQXJyYXlzKG9iamVjdCwgb3RoZXIsIGJpdG1hc2ssIGN1c3RvbWl6ZXIsIGVxdWFsRnVuYywgc3RhY2spXG4gICAgICAgICAgOiBlcXVhbEJ5VGFnKG9iamVjdCwgb3RoZXIsIG9ialRhZywgYml0bWFzaywgY3VzdG9taXplciwgZXF1YWxGdW5jLCBzdGFjayk7XG4gICAgICB9XG4gICAgICBpZiAoIShiaXRtYXNrICYgQ09NUEFSRV9QQVJUSUFMX0ZMQUcpKSB7XG4gICAgICAgIHZhciBvYmpJc1dyYXBwZWQgPSBvYmpJc09iaiAmJiBoYXNPd25Qcm9wZXJ0eS5jYWxsKG9iamVjdCwgJ19fd3JhcHBlZF9fJyksXG4gICAgICAgICAgICBvdGhJc1dyYXBwZWQgPSBvdGhJc09iaiAmJiBoYXNPd25Qcm9wZXJ0eS5jYWxsKG90aGVyLCAnX193cmFwcGVkX18nKTtcblxuICAgICAgICBpZiAob2JqSXNXcmFwcGVkIHx8IG90aElzV3JhcHBlZCkge1xuICAgICAgICAgIHZhciBvYmpVbndyYXBwZWQgPSBvYmpJc1dyYXBwZWQgPyBvYmplY3QudmFsdWUoKSA6IG9iamVjdCxcbiAgICAgICAgICAgICAgb3RoVW53cmFwcGVkID0gb3RoSXNXcmFwcGVkID8gb3RoZXIudmFsdWUoKSA6IG90aGVyO1xuXG4gICAgICAgICAgc3RhY2sgfHwgKHN0YWNrID0gbmV3IFN0YWNrKTtcbiAgICAgICAgICByZXR1cm4gZXF1YWxGdW5jKG9ialVud3JhcHBlZCwgb3RoVW53cmFwcGVkLCBiaXRtYXNrLCBjdXN0b21pemVyLCBzdGFjayk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmICghaXNTYW1lVGFnKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICAgIHN0YWNrIHx8IChzdGFjayA9IG5ldyBTdGFjayk7XG4gICAgICByZXR1cm4gZXF1YWxPYmplY3RzKG9iamVjdCwgb3RoZXIsIGJpdG1hc2ssIGN1c3RvbWl6ZXIsIGVxdWFsRnVuYywgc3RhY2spO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLmlzTWFwYCB3aXRob3V0IE5vZGUuanMgb3B0aW1pemF0aW9ucy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgYSBtYXAsIGVsc2UgYGZhbHNlYC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBiYXNlSXNNYXAodmFsdWUpIHtcbiAgICAgIHJldHVybiBpc09iamVjdExpa2UodmFsdWUpICYmIGdldFRhZyh2YWx1ZSkgPT0gbWFwVGFnO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLmlzTWF0Y2hgIHdpdGhvdXQgc3VwcG9ydCBmb3IgaXRlcmF0ZWUgc2hvcnRoYW5kcy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIGluc3BlY3QuXG4gICAgICogQHBhcmFtIHtPYmplY3R9IHNvdXJjZSBUaGUgb2JqZWN0IG9mIHByb3BlcnR5IHZhbHVlcyB0byBtYXRjaC5cbiAgICAgKiBAcGFyYW0ge0FycmF5fSBtYXRjaERhdGEgVGhlIHByb3BlcnR5IG5hbWVzLCB2YWx1ZXMsIGFuZCBjb21wYXJlIGZsYWdzIHRvIG1hdGNoLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IFtjdXN0b21pemVyXSBUaGUgZnVuY3Rpb24gdG8gY3VzdG9taXplIGNvbXBhcmlzb25zLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgb2JqZWN0YCBpcyBhIG1hdGNoLCBlbHNlIGBmYWxzZWAuXG4gICAgICovXG4gICAgZnVuY3Rpb24gYmFzZUlzTWF0Y2gob2JqZWN0LCBzb3VyY2UsIG1hdGNoRGF0YSwgY3VzdG9taXplcikge1xuICAgICAgdmFyIGluZGV4ID0gbWF0Y2hEYXRhLmxlbmd0aCxcbiAgICAgICAgICBsZW5ndGggPSBpbmRleCxcbiAgICAgICAgICBub0N1c3RvbWl6ZXIgPSAhY3VzdG9taXplcjtcblxuICAgICAgaWYgKG9iamVjdCA9PSBudWxsKSB7XG4gICAgICAgIHJldHVybiAhbGVuZ3RoO1xuICAgICAgfVxuICAgICAgb2JqZWN0ID0gT2JqZWN0KG9iamVjdCk7XG4gICAgICB3aGlsZSAoaW5kZXgtLSkge1xuICAgICAgICB2YXIgZGF0YSA9IG1hdGNoRGF0YVtpbmRleF07XG4gICAgICAgIGlmICgobm9DdXN0b21pemVyICYmIGRhdGFbMl0pXG4gICAgICAgICAgICAgID8gZGF0YVsxXSAhPT0gb2JqZWN0W2RhdGFbMF1dXG4gICAgICAgICAgICAgIDogIShkYXRhWzBdIGluIG9iamVjdClcbiAgICAgICAgICAgICkge1xuICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHtcbiAgICAgICAgZGF0YSA9IG1hdGNoRGF0YVtpbmRleF07XG4gICAgICAgIHZhciBrZXkgPSBkYXRhWzBdLFxuICAgICAgICAgICAgb2JqVmFsdWUgPSBvYmplY3Rba2V5XSxcbiAgICAgICAgICAgIHNyY1ZhbHVlID0gZGF0YVsxXTtcblxuICAgICAgICBpZiAobm9DdXN0b21pemVyICYmIGRhdGFbMl0pIHtcbiAgICAgICAgICBpZiAob2JqVmFsdWUgPT09IHVuZGVmaW5lZCAmJiAhKGtleSBpbiBvYmplY3QpKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHZhciBzdGFjayA9IG5ldyBTdGFjaztcbiAgICAgICAgICBpZiAoY3VzdG9taXplcikge1xuICAgICAgICAgICAgdmFyIHJlc3VsdCA9IGN1c3RvbWl6ZXIob2JqVmFsdWUsIHNyY1ZhbHVlLCBrZXksIG9iamVjdCwgc291cmNlLCBzdGFjayk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmICghKHJlc3VsdCA9PT0gdW5kZWZpbmVkXG4gICAgICAgICAgICAgICAgPyBiYXNlSXNFcXVhbChzcmNWYWx1ZSwgb2JqVmFsdWUsIENPTVBBUkVfUEFSVElBTF9GTEFHIHwgQ09NUEFSRV9VTk9SREVSRURfRkxBRywgY3VzdG9taXplciwgc3RhY2spXG4gICAgICAgICAgICAgICAgOiByZXN1bHRcbiAgICAgICAgICAgICAgKSkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uaXNOYXRpdmVgIHdpdGhvdXQgYmFkIHNoaW0gY2hlY2tzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhIG5hdGl2ZSBmdW5jdGlvbixcbiAgICAgKiAgZWxzZSBgZmFsc2VgLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGJhc2VJc05hdGl2ZSh2YWx1ZSkge1xuICAgICAgaWYgKCFpc09iamVjdCh2YWx1ZSkgfHwgaXNNYXNrZWQodmFsdWUpKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICAgIHZhciBwYXR0ZXJuID0gaXNGdW5jdGlvbih2YWx1ZSkgPyByZUlzTmF0aXZlIDogcmVJc0hvc3RDdG9yO1xuICAgICAgcmV0dXJuIHBhdHRlcm4udGVzdCh0b1NvdXJjZSh2YWx1ZSkpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLmlzUmVnRXhwYCB3aXRob3V0IE5vZGUuanMgb3B0aW1pemF0aW9ucy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgYSByZWdleHAsIGVsc2UgYGZhbHNlYC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBiYXNlSXNSZWdFeHAodmFsdWUpIHtcbiAgICAgIHJldHVybiBpc09iamVjdExpa2UodmFsdWUpICYmIGJhc2VHZXRUYWcodmFsdWUpID09IHJlZ2V4cFRhZztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5pc1NldGAgd2l0aG91dCBOb2RlLmpzIG9wdGltaXphdGlvbnMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGEgc2V0LCBlbHNlIGBmYWxzZWAuXG4gICAgICovXG4gICAgZnVuY3Rpb24gYmFzZUlzU2V0KHZhbHVlKSB7XG4gICAgICByZXR1cm4gaXNPYmplY3RMaWtlKHZhbHVlKSAmJiBnZXRUYWcodmFsdWUpID09IHNldFRhZztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5pc1R5cGVkQXJyYXlgIHdpdGhvdXQgTm9kZS5qcyBvcHRpbWl6YXRpb25zLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhIHR5cGVkIGFycmF5LCBlbHNlIGBmYWxzZWAuXG4gICAgICovXG4gICAgZnVuY3Rpb24gYmFzZUlzVHlwZWRBcnJheSh2YWx1ZSkge1xuICAgICAgcmV0dXJuIGlzT2JqZWN0TGlrZSh2YWx1ZSkgJiZcbiAgICAgICAgaXNMZW5ndGgodmFsdWUubGVuZ3RoKSAmJiAhIXR5cGVkQXJyYXlUYWdzW2Jhc2VHZXRUYWcodmFsdWUpXTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5pdGVyYXRlZWAuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7Kn0gW3ZhbHVlPV8uaWRlbnRpdHldIFRoZSB2YWx1ZSB0byBjb252ZXJ0IHRvIGFuIGl0ZXJhdGVlLlxuICAgICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgaXRlcmF0ZWUuXG4gICAgICovXG4gICAgZnVuY3Rpb24gYmFzZUl0ZXJhdGVlKHZhbHVlKSB7XG4gICAgICAvLyBEb24ndCBzdG9yZSB0aGUgYHR5cGVvZmAgcmVzdWx0IGluIGEgdmFyaWFibGUgdG8gYXZvaWQgYSBKSVQgYnVnIGluIFNhZmFyaSA5LlxuICAgICAgLy8gU2VlIGh0dHBzOi8vYnVncy53ZWJraXQub3JnL3Nob3dfYnVnLmNnaT9pZD0xNTYwMzQgZm9yIG1vcmUgZGV0YWlscy5cbiAgICAgIGlmICh0eXBlb2YgdmFsdWUgPT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgICB9XG4gICAgICBpZiAodmFsdWUgPT0gbnVsbCkge1xuICAgICAgICByZXR1cm4gaWRlbnRpdHk7XG4gICAgICB9XG4gICAgICBpZiAodHlwZW9mIHZhbHVlID09ICdvYmplY3QnKSB7XG4gICAgICAgIHJldHVybiBpc0FycmF5KHZhbHVlKVxuICAgICAgICAgID8gYmFzZU1hdGNoZXNQcm9wZXJ0eSh2YWx1ZVswXSwgdmFsdWVbMV0pXG4gICAgICAgICAgOiBiYXNlTWF0Y2hlcyh2YWx1ZSk7XG4gICAgICB9XG4gICAgICByZXR1cm4gcHJvcGVydHkodmFsdWUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLmtleXNgIHdoaWNoIGRvZXNuJ3QgdHJlYXQgc3BhcnNlIGFycmF5cyBhcyBkZW5zZS5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIHF1ZXJ5LlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgYXJyYXkgb2YgcHJvcGVydHkgbmFtZXMuXG4gICAgICovXG4gICAgZnVuY3Rpb24gYmFzZUtleXMob2JqZWN0KSB7XG4gICAgICBpZiAoIWlzUHJvdG90eXBlKG9iamVjdCkpIHtcbiAgICAgICAgcmV0dXJuIG5hdGl2ZUtleXMob2JqZWN0KTtcbiAgICAgIH1cbiAgICAgIHZhciByZXN1bHQgPSBbXTtcbiAgICAgIGZvciAodmFyIGtleSBpbiBPYmplY3Qob2JqZWN0KSkge1xuICAgICAgICBpZiAoaGFzT3duUHJvcGVydHkuY2FsbChvYmplY3QsIGtleSkgJiYga2V5ICE9ICdjb25zdHJ1Y3RvcicpIHtcbiAgICAgICAgICByZXN1bHQucHVzaChrZXkpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLmtleXNJbmAgd2hpY2ggZG9lc24ndCB0cmVhdCBzcGFyc2UgYXJyYXlzIGFzIGRlbnNlLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gcXVlcnkuXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBhcnJheSBvZiBwcm9wZXJ0eSBuYW1lcy5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBiYXNlS2V5c0luKG9iamVjdCkge1xuICAgICAgaWYgKCFpc09iamVjdChvYmplY3QpKSB7XG4gICAgICAgIHJldHVybiBuYXRpdmVLZXlzSW4ob2JqZWN0KTtcbiAgICAgIH1cbiAgICAgIHZhciBpc1Byb3RvID0gaXNQcm90b3R5cGUob2JqZWN0KSxcbiAgICAgICAgICByZXN1bHQgPSBbXTtcblxuICAgICAgZm9yICh2YXIga2V5IGluIG9iamVjdCkge1xuICAgICAgICBpZiAoIShrZXkgPT0gJ2NvbnN0cnVjdG9yJyAmJiAoaXNQcm90byB8fCAhaGFzT3duUHJvcGVydHkuY2FsbChvYmplY3QsIGtleSkpKSkge1xuICAgICAgICAgIHJlc3VsdC5wdXNoKGtleSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8ubHRgIHdoaWNoIGRvZXNuJ3QgY29lcmNlIGFyZ3VtZW50cy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY29tcGFyZS5cbiAgICAgKiBAcGFyYW0geyp9IG90aGVyIFRoZSBvdGhlciB2YWx1ZSB0byBjb21wYXJlLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGxlc3MgdGhhbiBgb3RoZXJgLFxuICAgICAqICBlbHNlIGBmYWxzZWAuXG4gICAgICovXG4gICAgZnVuY3Rpb24gYmFzZUx0KHZhbHVlLCBvdGhlcikge1xuICAgICAgcmV0dXJuIHZhbHVlIDwgb3RoZXI7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8ubWFwYCB3aXRob3V0IHN1cHBvcnQgZm9yIGl0ZXJhdGVlIHNob3J0aGFuZHMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7QXJyYXl8T2JqZWN0fSBjb2xsZWN0aW9uIFRoZSBjb2xsZWN0aW9uIHRvIGl0ZXJhdGUgb3Zlci5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBpdGVyYXRlZSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IG1hcHBlZCBhcnJheS5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBiYXNlTWFwKGNvbGxlY3Rpb24sIGl0ZXJhdGVlKSB7XG4gICAgICB2YXIgaW5kZXggPSAtMSxcbiAgICAgICAgICByZXN1bHQgPSBpc0FycmF5TGlrZShjb2xsZWN0aW9uKSA/IEFycmF5KGNvbGxlY3Rpb24ubGVuZ3RoKSA6IFtdO1xuXG4gICAgICBiYXNlRWFjaChjb2xsZWN0aW9uLCBmdW5jdGlvbih2YWx1ZSwga2V5LCBjb2xsZWN0aW9uKSB7XG4gICAgICAgIHJlc3VsdFsrK2luZGV4XSA9IGl0ZXJhdGVlKHZhbHVlLCBrZXksIGNvbGxlY3Rpb24pO1xuICAgICAgfSk7XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLm1hdGNoZXNgIHdoaWNoIGRvZXNuJ3QgY2xvbmUgYHNvdXJjZWAuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBzb3VyY2UgVGhlIG9iamVjdCBvZiBwcm9wZXJ0eSB2YWx1ZXMgdG8gbWF0Y2guXG4gICAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgc3BlYyBmdW5jdGlvbi5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBiYXNlTWF0Y2hlcyhzb3VyY2UpIHtcbiAgICAgIHZhciBtYXRjaERhdGEgPSBnZXRNYXRjaERhdGEoc291cmNlKTtcbiAgICAgIGlmIChtYXRjaERhdGEubGVuZ3RoID09IDEgJiYgbWF0Y2hEYXRhWzBdWzJdKSB7XG4gICAgICAgIHJldHVybiBtYXRjaGVzU3RyaWN0Q29tcGFyYWJsZShtYXRjaERhdGFbMF1bMF0sIG1hdGNoRGF0YVswXVsxXSk7XG4gICAgICB9XG4gICAgICByZXR1cm4gZnVuY3Rpb24ob2JqZWN0KSB7XG4gICAgICAgIHJldHVybiBvYmplY3QgPT09IHNvdXJjZSB8fCBiYXNlSXNNYXRjaChvYmplY3QsIHNvdXJjZSwgbWF0Y2hEYXRhKTtcbiAgICAgIH07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8ubWF0Y2hlc1Byb3BlcnR5YCB3aGljaCBkb2Vzbid0IGNsb25lIGBzcmNWYWx1ZWAuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBwYXRoIFRoZSBwYXRoIG9mIHRoZSBwcm9wZXJ0eSB0byBnZXQuXG4gICAgICogQHBhcmFtIHsqfSBzcmNWYWx1ZSBUaGUgdmFsdWUgdG8gbWF0Y2guXG4gICAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgc3BlYyBmdW5jdGlvbi5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBiYXNlTWF0Y2hlc1Byb3BlcnR5KHBhdGgsIHNyY1ZhbHVlKSB7XG4gICAgICBpZiAoaXNLZXkocGF0aCkgJiYgaXNTdHJpY3RDb21wYXJhYmxlKHNyY1ZhbHVlKSkge1xuICAgICAgICByZXR1cm4gbWF0Y2hlc1N0cmljdENvbXBhcmFibGUodG9LZXkocGF0aCksIHNyY1ZhbHVlKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBmdW5jdGlvbihvYmplY3QpIHtcbiAgICAgICAgdmFyIG9ialZhbHVlID0gZ2V0KG9iamVjdCwgcGF0aCk7XG4gICAgICAgIHJldHVybiAob2JqVmFsdWUgPT09IHVuZGVmaW5lZCAmJiBvYmpWYWx1ZSA9PT0gc3JjVmFsdWUpXG4gICAgICAgICAgPyBoYXNJbihvYmplY3QsIHBhdGgpXG4gICAgICAgICAgOiBiYXNlSXNFcXVhbChzcmNWYWx1ZSwgb2JqVmFsdWUsIENPTVBBUkVfUEFSVElBTF9GTEFHIHwgQ09NUEFSRV9VTk9SREVSRURfRkxBRyk7XG4gICAgICB9O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLm1lcmdlYCB3aXRob3V0IHN1cHBvcnQgZm9yIG11bHRpcGxlIHNvdXJjZXMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIGRlc3RpbmF0aW9uIG9iamVjdC5cbiAgICAgKiBAcGFyYW0ge09iamVjdH0gc291cmNlIFRoZSBzb3VyY2Ugb2JqZWN0LlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBzcmNJbmRleCBUaGUgaW5kZXggb2YgYHNvdXJjZWAuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW2N1c3RvbWl6ZXJdIFRoZSBmdW5jdGlvbiB0byBjdXN0b21pemUgbWVyZ2VkIHZhbHVlcy5cbiAgICAgKiBAcGFyYW0ge09iamVjdH0gW3N0YWNrXSBUcmFja3MgdHJhdmVyc2VkIHNvdXJjZSB2YWx1ZXMgYW5kIHRoZWlyIG1lcmdlZFxuICAgICAqICBjb3VudGVycGFydHMuXG4gICAgICovXG4gICAgZnVuY3Rpb24gYmFzZU1lcmdlKG9iamVjdCwgc291cmNlLCBzcmNJbmRleCwgY3VzdG9taXplciwgc3RhY2spIHtcbiAgICAgIGlmIChvYmplY3QgPT09IHNvdXJjZSkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBiYXNlRm9yKHNvdXJjZSwgZnVuY3Rpb24oc3JjVmFsdWUsIGtleSkge1xuICAgICAgICBzdGFjayB8fCAoc3RhY2sgPSBuZXcgU3RhY2spO1xuICAgICAgICBpZiAoaXNPYmplY3Qoc3JjVmFsdWUpKSB7XG4gICAgICAgICAgYmFzZU1lcmdlRGVlcChvYmplY3QsIHNvdXJjZSwga2V5LCBzcmNJbmRleCwgYmFzZU1lcmdlLCBjdXN0b21pemVyLCBzdGFjayk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgdmFyIG5ld1ZhbHVlID0gY3VzdG9taXplclxuICAgICAgICAgICAgPyBjdXN0b21pemVyKHNhZmVHZXQob2JqZWN0LCBrZXkpLCBzcmNWYWx1ZSwgKGtleSArICcnKSwgb2JqZWN0LCBzb3VyY2UsIHN0YWNrKVxuICAgICAgICAgICAgOiB1bmRlZmluZWQ7XG5cbiAgICAgICAgICBpZiAobmV3VmFsdWUgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgbmV3VmFsdWUgPSBzcmNWYWx1ZTtcbiAgICAgICAgICB9XG4gICAgICAgICAgYXNzaWduTWVyZ2VWYWx1ZShvYmplY3QsIGtleSwgbmV3VmFsdWUpO1xuICAgICAgICB9XG4gICAgICB9LCBrZXlzSW4pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEEgc3BlY2lhbGl6ZWQgdmVyc2lvbiBvZiBgYmFzZU1lcmdlYCBmb3IgYXJyYXlzIGFuZCBvYmplY3RzIHdoaWNoIHBlcmZvcm1zXG4gICAgICogZGVlcCBtZXJnZXMgYW5kIHRyYWNrcyB0cmF2ZXJzZWQgb2JqZWN0cyBlbmFibGluZyBvYmplY3RzIHdpdGggY2lyY3VsYXJcbiAgICAgKiByZWZlcmVuY2VzIHRvIGJlIG1lcmdlZC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgZGVzdGluYXRpb24gb2JqZWN0LlxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBzb3VyY2UgVGhlIHNvdXJjZSBvYmplY3QuXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGtleSBUaGUga2V5IG9mIHRoZSB2YWx1ZSB0byBtZXJnZS5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gc3JjSW5kZXggVGhlIGluZGV4IG9mIGBzb3VyY2VgLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IG1lcmdlRnVuYyBUaGUgZnVuY3Rpb24gdG8gbWVyZ2UgdmFsdWVzLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IFtjdXN0b21pemVyXSBUaGUgZnVuY3Rpb24gdG8gY3VzdG9taXplIGFzc2lnbmVkIHZhbHVlcy5cbiAgICAgKiBAcGFyYW0ge09iamVjdH0gW3N0YWNrXSBUcmFja3MgdHJhdmVyc2VkIHNvdXJjZSB2YWx1ZXMgYW5kIHRoZWlyIG1lcmdlZFxuICAgICAqICBjb3VudGVycGFydHMuXG4gICAgICovXG4gICAgZnVuY3Rpb24gYmFzZU1lcmdlRGVlcChvYmplY3QsIHNvdXJjZSwga2V5LCBzcmNJbmRleCwgbWVyZ2VGdW5jLCBjdXN0b21pemVyLCBzdGFjaykge1xuICAgICAgdmFyIG9ialZhbHVlID0gc2FmZUdldChvYmplY3QsIGtleSksXG4gICAgICAgICAgc3JjVmFsdWUgPSBzYWZlR2V0KHNvdXJjZSwga2V5KSxcbiAgICAgICAgICBzdGFja2VkID0gc3RhY2suZ2V0KHNyY1ZhbHVlKTtcblxuICAgICAgaWYgKHN0YWNrZWQpIHtcbiAgICAgICAgYXNzaWduTWVyZ2VWYWx1ZShvYmplY3QsIGtleSwgc3RhY2tlZCk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIHZhciBuZXdWYWx1ZSA9IGN1c3RvbWl6ZXJcbiAgICAgICAgPyBjdXN0b21pemVyKG9ialZhbHVlLCBzcmNWYWx1ZSwgKGtleSArICcnKSwgb2JqZWN0LCBzb3VyY2UsIHN0YWNrKVxuICAgICAgICA6IHVuZGVmaW5lZDtcblxuICAgICAgdmFyIGlzQ29tbW9uID0gbmV3VmFsdWUgPT09IHVuZGVmaW5lZDtcblxuICAgICAgaWYgKGlzQ29tbW9uKSB7XG4gICAgICAgIHZhciBpc0FyciA9IGlzQXJyYXkoc3JjVmFsdWUpLFxuICAgICAgICAgICAgaXNCdWZmID0gIWlzQXJyICYmIGlzQnVmZmVyKHNyY1ZhbHVlKSxcbiAgICAgICAgICAgIGlzVHlwZWQgPSAhaXNBcnIgJiYgIWlzQnVmZiAmJiBpc1R5cGVkQXJyYXkoc3JjVmFsdWUpO1xuXG4gICAgICAgIG5ld1ZhbHVlID0gc3JjVmFsdWU7XG4gICAgICAgIGlmIChpc0FyciB8fCBpc0J1ZmYgfHwgaXNUeXBlZCkge1xuICAgICAgICAgIGlmIChpc0FycmF5KG9ialZhbHVlKSkge1xuICAgICAgICAgICAgbmV3VmFsdWUgPSBvYmpWYWx1ZTtcbiAgICAgICAgICB9XG4gICAgICAgICAgZWxzZSBpZiAoaXNBcnJheUxpa2VPYmplY3Qob2JqVmFsdWUpKSB7XG4gICAgICAgICAgICBuZXdWYWx1ZSA9IGNvcHlBcnJheShvYmpWYWx1ZSk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGVsc2UgaWYgKGlzQnVmZikge1xuICAgICAgICAgICAgaXNDb21tb24gPSBmYWxzZTtcbiAgICAgICAgICAgIG5ld1ZhbHVlID0gY2xvbmVCdWZmZXIoc3JjVmFsdWUsIHRydWUpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBlbHNlIGlmIChpc1R5cGVkKSB7XG4gICAgICAgICAgICBpc0NvbW1vbiA9IGZhbHNlO1xuICAgICAgICAgICAgbmV3VmFsdWUgPSBjbG9uZVR5cGVkQXJyYXkoc3JjVmFsdWUsIHRydWUpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIG5ld1ZhbHVlID0gW107XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKGlzUGxhaW5PYmplY3Qoc3JjVmFsdWUpIHx8IGlzQXJndW1lbnRzKHNyY1ZhbHVlKSkge1xuICAgICAgICAgIG5ld1ZhbHVlID0gb2JqVmFsdWU7XG4gICAgICAgICAgaWYgKGlzQXJndW1lbnRzKG9ialZhbHVlKSkge1xuICAgICAgICAgICAgbmV3VmFsdWUgPSB0b1BsYWluT2JqZWN0KG9ialZhbHVlKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgZWxzZSBpZiAoIWlzT2JqZWN0KG9ialZhbHVlKSB8fCBpc0Z1bmN0aW9uKG9ialZhbHVlKSkge1xuICAgICAgICAgICAgbmV3VmFsdWUgPSBpbml0Q2xvbmVPYmplY3Qoc3JjVmFsdWUpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICBpc0NvbW1vbiA9IGZhbHNlO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAoaXNDb21tb24pIHtcbiAgICAgICAgLy8gUmVjdXJzaXZlbHkgbWVyZ2Ugb2JqZWN0cyBhbmQgYXJyYXlzIChzdXNjZXB0aWJsZSB0byBjYWxsIHN0YWNrIGxpbWl0cykuXG4gICAgICAgIHN0YWNrLnNldChzcmNWYWx1ZSwgbmV3VmFsdWUpO1xuICAgICAgICBtZXJnZUZ1bmMobmV3VmFsdWUsIHNyY1ZhbHVlLCBzcmNJbmRleCwgY3VzdG9taXplciwgc3RhY2spO1xuICAgICAgICBzdGFja1snZGVsZXRlJ10oc3JjVmFsdWUpO1xuICAgICAgfVxuICAgICAgYXNzaWduTWVyZ2VWYWx1ZShvYmplY3QsIGtleSwgbmV3VmFsdWUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLm50aGAgd2hpY2ggZG9lc24ndCBjb2VyY2UgYXJndW1lbnRzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gcXVlcnkuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IG4gVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi5cbiAgICAgKiBAcmV0dXJucyB7Kn0gUmV0dXJucyB0aGUgbnRoIGVsZW1lbnQgb2YgYGFycmF5YC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBiYXNlTnRoKGFycmF5LCBuKSB7XG4gICAgICB2YXIgbGVuZ3RoID0gYXJyYXkubGVuZ3RoO1xuICAgICAgaWYgKCFsZW5ndGgpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgbiArPSBuIDwgMCA/IGxlbmd0aCA6IDA7XG4gICAgICByZXR1cm4gaXNJbmRleChuLCBsZW5ndGgpID8gYXJyYXlbbl0gOiB1bmRlZmluZWQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8ub3JkZXJCeWAgd2l0aG91dCBwYXJhbSBndWFyZHMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7QXJyYXl8T2JqZWN0fSBjb2xsZWN0aW9uIFRoZSBjb2xsZWN0aW9uIHRvIGl0ZXJhdGUgb3Zlci5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9uW118T2JqZWN0W118c3RyaW5nW119IGl0ZXJhdGVlcyBUaGUgaXRlcmF0ZWVzIHRvIHNvcnQgYnkuXG4gICAgICogQHBhcmFtIHtzdHJpbmdbXX0gb3JkZXJzIFRoZSBzb3J0IG9yZGVycyBvZiBgaXRlcmF0ZWVzYC5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIG5ldyBzb3J0ZWQgYXJyYXkuXG4gICAgICovXG4gICAgZnVuY3Rpb24gYmFzZU9yZGVyQnkoY29sbGVjdGlvbiwgaXRlcmF0ZWVzLCBvcmRlcnMpIHtcbiAgICAgIGlmIChpdGVyYXRlZXMubGVuZ3RoKSB7XG4gICAgICAgIGl0ZXJhdGVlcyA9IGFycmF5TWFwKGl0ZXJhdGVlcywgZnVuY3Rpb24oaXRlcmF0ZWUpIHtcbiAgICAgICAgICBpZiAoaXNBcnJheShpdGVyYXRlZSkpIHtcbiAgICAgICAgICAgIHJldHVybiBmdW5jdGlvbih2YWx1ZSkge1xuICAgICAgICAgICAgICByZXR1cm4gYmFzZUdldCh2YWx1ZSwgaXRlcmF0ZWUubGVuZ3RoID09PSAxID8gaXRlcmF0ZWVbMF0gOiBpdGVyYXRlZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybiBpdGVyYXRlZTtcbiAgICAgICAgfSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBpdGVyYXRlZXMgPSBbaWRlbnRpdHldO1xuICAgICAgfVxuXG4gICAgICB2YXIgaW5kZXggPSAtMTtcbiAgICAgIGl0ZXJhdGVlcyA9IGFycmF5TWFwKGl0ZXJhdGVlcywgYmFzZVVuYXJ5KGdldEl0ZXJhdGVlKCkpKTtcblxuICAgICAgdmFyIHJlc3VsdCA9IGJhc2VNYXAoY29sbGVjdGlvbiwgZnVuY3Rpb24odmFsdWUsIGtleSwgY29sbGVjdGlvbikge1xuICAgICAgICB2YXIgY3JpdGVyaWEgPSBhcnJheU1hcChpdGVyYXRlZXMsIGZ1bmN0aW9uKGl0ZXJhdGVlKSB7XG4gICAgICAgICAgcmV0dXJuIGl0ZXJhdGVlKHZhbHVlKTtcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiB7ICdjcml0ZXJpYSc6IGNyaXRlcmlhLCAnaW5kZXgnOiArK2luZGV4LCAndmFsdWUnOiB2YWx1ZSB9O1xuICAgICAgfSk7XG5cbiAgICAgIHJldHVybiBiYXNlU29ydEJ5KHJlc3VsdCwgZnVuY3Rpb24ob2JqZWN0LCBvdGhlcikge1xuICAgICAgICByZXR1cm4gY29tcGFyZU11bHRpcGxlKG9iamVjdCwgb3RoZXIsIG9yZGVycyk7XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5waWNrYCB3aXRob3V0IHN1cHBvcnQgZm9yIGluZGl2aWR1YWxcbiAgICAgKiBwcm9wZXJ0eSBpZGVudGlmaWVycy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgc291cmNlIG9iamVjdC5cbiAgICAgKiBAcGFyYW0ge3N0cmluZ1tdfSBwYXRocyBUaGUgcHJvcGVydHkgcGF0aHMgdG8gcGljay5cbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIHRoZSBuZXcgb2JqZWN0LlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGJhc2VQaWNrKG9iamVjdCwgcGF0aHMpIHtcbiAgICAgIHJldHVybiBiYXNlUGlja0J5KG9iamVjdCwgcGF0aHMsIGZ1bmN0aW9uKHZhbHVlLCBwYXRoKSB7XG4gICAgICAgIHJldHVybiBoYXNJbihvYmplY3QsIHBhdGgpO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgIGBfLnBpY2tCeWAgd2l0aG91dCBzdXBwb3J0IGZvciBpdGVyYXRlZSBzaG9ydGhhbmRzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBzb3VyY2Ugb2JqZWN0LlxuICAgICAqIEBwYXJhbSB7c3RyaW5nW119IHBhdGhzIFRoZSBwcm9wZXJ0eSBwYXRocyB0byBwaWNrLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IHByZWRpY2F0ZSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgcHJvcGVydHkuXG4gICAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyB0aGUgbmV3IG9iamVjdC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBiYXNlUGlja0J5KG9iamVjdCwgcGF0aHMsIHByZWRpY2F0ZSkge1xuICAgICAgdmFyIGluZGV4ID0gLTEsXG4gICAgICAgICAgbGVuZ3RoID0gcGF0aHMubGVuZ3RoLFxuICAgICAgICAgIHJlc3VsdCA9IHt9O1xuXG4gICAgICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgICAgICB2YXIgcGF0aCA9IHBhdGhzW2luZGV4XSxcbiAgICAgICAgICAgIHZhbHVlID0gYmFzZUdldChvYmplY3QsIHBhdGgpO1xuXG4gICAgICAgIGlmIChwcmVkaWNhdGUodmFsdWUsIHBhdGgpKSB7XG4gICAgICAgICAgYmFzZVNldChyZXN1bHQsIGNhc3RQYXRoKHBhdGgsIG9iamVjdCksIHZhbHVlKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBBIHNwZWNpYWxpemVkIHZlcnNpb24gb2YgYGJhc2VQcm9wZXJ0eWAgd2hpY2ggc3VwcG9ydHMgZGVlcCBwYXRocy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtBcnJheXxzdHJpbmd9IHBhdGggVGhlIHBhdGggb2YgdGhlIHByb3BlcnR5IHRvIGdldC5cbiAgICAgKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBhY2Nlc3NvciBmdW5jdGlvbi5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBiYXNlUHJvcGVydHlEZWVwKHBhdGgpIHtcbiAgICAgIHJldHVybiBmdW5jdGlvbihvYmplY3QpIHtcbiAgICAgICAgcmV0dXJuIGJhc2VHZXQob2JqZWN0LCBwYXRoKTtcbiAgICAgIH07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8ucHVsbEFsbEJ5YCB3aXRob3V0IHN1cHBvcnQgZm9yIGl0ZXJhdGVlXG4gICAgICogc2hvcnRoYW5kcy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIG1vZGlmeS5cbiAgICAgKiBAcGFyYW0ge0FycmF5fSB2YWx1ZXMgVGhlIHZhbHVlcyB0byByZW1vdmUuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW2l0ZXJhdGVlXSBUaGUgaXRlcmF0ZWUgaW52b2tlZCBwZXIgZWxlbWVudC5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbY29tcGFyYXRvcl0gVGhlIGNvbXBhcmF0b3IgaW52b2tlZCBwZXIgZWxlbWVudC5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgYGFycmF5YC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBiYXNlUHVsbEFsbChhcnJheSwgdmFsdWVzLCBpdGVyYXRlZSwgY29tcGFyYXRvcikge1xuICAgICAgdmFyIGluZGV4T2YgPSBjb21wYXJhdG9yID8gYmFzZUluZGV4T2ZXaXRoIDogYmFzZUluZGV4T2YsXG4gICAgICAgICAgaW5kZXggPSAtMSxcbiAgICAgICAgICBsZW5ndGggPSB2YWx1ZXMubGVuZ3RoLFxuICAgICAgICAgIHNlZW4gPSBhcnJheTtcblxuICAgICAgaWYgKGFycmF5ID09PSB2YWx1ZXMpIHtcbiAgICAgICAgdmFsdWVzID0gY29weUFycmF5KHZhbHVlcyk7XG4gICAgICB9XG4gICAgICBpZiAoaXRlcmF0ZWUpIHtcbiAgICAgICAgc2VlbiA9IGFycmF5TWFwKGFycmF5LCBiYXNlVW5hcnkoaXRlcmF0ZWUpKTtcbiAgICAgIH1cbiAgICAgIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XG4gICAgICAgIHZhciBmcm9tSW5kZXggPSAwLFxuICAgICAgICAgICAgdmFsdWUgPSB2YWx1ZXNbaW5kZXhdLFxuICAgICAgICAgICAgY29tcHV0ZWQgPSBpdGVyYXRlZSA/IGl0ZXJhdGVlKHZhbHVlKSA6IHZhbHVlO1xuXG4gICAgICAgIHdoaWxlICgoZnJvbUluZGV4ID0gaW5kZXhPZihzZWVuLCBjb21wdXRlZCwgZnJvbUluZGV4LCBjb21wYXJhdG9yKSkgPiAtMSkge1xuICAgICAgICAgIGlmIChzZWVuICE9PSBhcnJheSkge1xuICAgICAgICAgICAgc3BsaWNlLmNhbGwoc2VlbiwgZnJvbUluZGV4LCAxKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgc3BsaWNlLmNhbGwoYXJyYXksIGZyb21JbmRleCwgMSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiBhcnJheTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5wdWxsQXRgIHdpdGhvdXQgc3VwcG9ydCBmb3IgaW5kaXZpZHVhbFxuICAgICAqIGluZGV4ZXMgb3IgY2FwdHVyaW5nIHRoZSByZW1vdmVkIGVsZW1lbnRzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gbW9kaWZ5LlxuICAgICAqIEBwYXJhbSB7bnVtYmVyW119IGluZGV4ZXMgVGhlIGluZGV4ZXMgb2YgZWxlbWVudHMgdG8gcmVtb3ZlLlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyBgYXJyYXlgLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGJhc2VQdWxsQXQoYXJyYXksIGluZGV4ZXMpIHtcbiAgICAgIHZhciBsZW5ndGggPSBhcnJheSA/IGluZGV4ZXMubGVuZ3RoIDogMCxcbiAgICAgICAgICBsYXN0SW5kZXggPSBsZW5ndGggLSAxO1xuXG4gICAgICB3aGlsZSAobGVuZ3RoLS0pIHtcbiAgICAgICAgdmFyIGluZGV4ID0gaW5kZXhlc1tsZW5ndGhdO1xuICAgICAgICBpZiAobGVuZ3RoID09IGxhc3RJbmRleCB8fCBpbmRleCAhPT0gcHJldmlvdXMpIHtcbiAgICAgICAgICB2YXIgcHJldmlvdXMgPSBpbmRleDtcbiAgICAgICAgICBpZiAoaXNJbmRleChpbmRleCkpIHtcbiAgICAgICAgICAgIHNwbGljZS5jYWxsKGFycmF5LCBpbmRleCwgMSk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGJhc2VVbnNldChhcnJheSwgaW5kZXgpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIGFycmF5O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLnJhbmRvbWAgd2l0aG91dCBzdXBwb3J0IGZvciByZXR1cm5pbmdcbiAgICAgKiBmbG9hdGluZy1wb2ludCBudW1iZXJzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gbG93ZXIgVGhlIGxvd2VyIGJvdW5kLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSB1cHBlciBUaGUgdXBwZXIgYm91bmQuXG4gICAgICogQHJldHVybnMge251bWJlcn0gUmV0dXJucyB0aGUgcmFuZG9tIG51bWJlci5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBiYXNlUmFuZG9tKGxvd2VyLCB1cHBlcikge1xuICAgICAgcmV0dXJuIGxvd2VyICsgbmF0aXZlRmxvb3IobmF0aXZlUmFuZG9tKCkgKiAodXBwZXIgLSBsb3dlciArIDEpKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5yYW5nZWAgYW5kIGBfLnJhbmdlUmlnaHRgIHdoaWNoIGRvZXNuJ3RcbiAgICAgKiBjb2VyY2UgYXJndW1lbnRzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gc3RhcnQgVGhlIHN0YXJ0IG9mIHRoZSByYW5nZS5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gZW5kIFRoZSBlbmQgb2YgdGhlIHJhbmdlLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBzdGVwIFRoZSB2YWx1ZSB0byBpbmNyZW1lbnQgb3IgZGVjcmVtZW50IGJ5LlxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbn0gW2Zyb21SaWdodF0gU3BlY2lmeSBpdGVyYXRpbmcgZnJvbSByaWdodCB0byBsZWZ0LlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgcmFuZ2Ugb2YgbnVtYmVycy5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBiYXNlUmFuZ2Uoc3RhcnQsIGVuZCwgc3RlcCwgZnJvbVJpZ2h0KSB7XG4gICAgICB2YXIgaW5kZXggPSAtMSxcbiAgICAgICAgICBsZW5ndGggPSBuYXRpdmVNYXgobmF0aXZlQ2VpbCgoZW5kIC0gc3RhcnQpIC8gKHN0ZXAgfHwgMSkpLCAwKSxcbiAgICAgICAgICByZXN1bHQgPSBBcnJheShsZW5ndGgpO1xuXG4gICAgICB3aGlsZSAobGVuZ3RoLS0pIHtcbiAgICAgICAgcmVzdWx0W2Zyb21SaWdodCA/IGxlbmd0aCA6ICsraW5kZXhdID0gc3RhcnQ7XG4gICAgICAgIHN0YXJ0ICs9IHN0ZXA7XG4gICAgICB9XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLnJlcGVhdGAgd2hpY2ggZG9lc24ndCBjb2VyY2UgYXJndW1lbnRzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gc3RyaW5nIFRoZSBzdHJpbmcgdG8gcmVwZWF0LlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBuIFRoZSBudW1iZXIgb2YgdGltZXMgdG8gcmVwZWF0IHRoZSBzdHJpbmcuXG4gICAgICogQHJldHVybnMge3N0cmluZ30gUmV0dXJucyB0aGUgcmVwZWF0ZWQgc3RyaW5nLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGJhc2VSZXBlYXQoc3RyaW5nLCBuKSB7XG4gICAgICB2YXIgcmVzdWx0ID0gJyc7XG4gICAgICBpZiAoIXN0cmluZyB8fCBuIDwgMSB8fCBuID4gTUFYX1NBRkVfSU5URUdFUikge1xuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgfVxuICAgICAgLy8gTGV2ZXJhZ2UgdGhlIGV4cG9uZW50aWF0aW9uIGJ5IHNxdWFyaW5nIGFsZ29yaXRobSBmb3IgYSBmYXN0ZXIgcmVwZWF0LlxuICAgICAgLy8gU2VlIGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL0V4cG9uZW50aWF0aW9uX2J5X3NxdWFyaW5nIGZvciBtb3JlIGRldGFpbHMuXG4gICAgICBkbyB7XG4gICAgICAgIGlmIChuICUgMikge1xuICAgICAgICAgIHJlc3VsdCArPSBzdHJpbmc7XG4gICAgICAgIH1cbiAgICAgICAgbiA9IG5hdGl2ZUZsb29yKG4gLyAyKTtcbiAgICAgICAgaWYgKG4pIHtcbiAgICAgICAgICBzdHJpbmcgKz0gc3RyaW5nO1xuICAgICAgICB9XG4gICAgICB9IHdoaWxlIChuKTtcblxuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5yZXN0YCB3aGljaCBkb2Vzbid0IHZhbGlkYXRlIG9yIGNvZXJjZSBhcmd1bWVudHMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIGFwcGx5IGEgcmVzdCBwYXJhbWV0ZXIgdG8uXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtzdGFydD1mdW5jLmxlbmd0aC0xXSBUaGUgc3RhcnQgcG9zaXRpb24gb2YgdGhlIHJlc3QgcGFyYW1ldGVyLlxuICAgICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IGZ1bmN0aW9uLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGJhc2VSZXN0KGZ1bmMsIHN0YXJ0KSB7XG4gICAgICByZXR1cm4gc2V0VG9TdHJpbmcob3ZlclJlc3QoZnVuYywgc3RhcnQsIGlkZW50aXR5KSwgZnVuYyArICcnKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5zYW1wbGVgLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0FycmF5fE9iamVjdH0gY29sbGVjdGlvbiBUaGUgY29sbGVjdGlvbiB0byBzYW1wbGUuXG4gICAgICogQHJldHVybnMgeyp9IFJldHVybnMgdGhlIHJhbmRvbSBlbGVtZW50LlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGJhc2VTYW1wbGUoY29sbGVjdGlvbikge1xuICAgICAgcmV0dXJuIGFycmF5U2FtcGxlKHZhbHVlcyhjb2xsZWN0aW9uKSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uc2FtcGxlU2l6ZWAgd2l0aG91dCBwYXJhbSBndWFyZHMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7QXJyYXl8T2JqZWN0fSBjb2xsZWN0aW9uIFRoZSBjb2xsZWN0aW9uIHRvIHNhbXBsZS5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gbiBUaGUgbnVtYmVyIG9mIGVsZW1lbnRzIHRvIHNhbXBsZS5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIHJhbmRvbSBlbGVtZW50cy5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBiYXNlU2FtcGxlU2l6ZShjb2xsZWN0aW9uLCBuKSB7XG4gICAgICB2YXIgYXJyYXkgPSB2YWx1ZXMoY29sbGVjdGlvbik7XG4gICAgICByZXR1cm4gc2h1ZmZsZVNlbGYoYXJyYXksIGJhc2VDbGFtcChuLCAwLCBhcnJheS5sZW5ndGgpKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5zZXRgLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gbW9kaWZ5LlxuICAgICAqIEBwYXJhbSB7QXJyYXl8c3RyaW5nfSBwYXRoIFRoZSBwYXRoIG9mIHRoZSBwcm9wZXJ0eSB0byBzZXQuXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gc2V0LlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IFtjdXN0b21pemVyXSBUaGUgZnVuY3Rpb24gdG8gY3VzdG9taXplIHBhdGggY3JlYXRpb24uXG4gICAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyBgb2JqZWN0YC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBiYXNlU2V0KG9iamVjdCwgcGF0aCwgdmFsdWUsIGN1c3RvbWl6ZXIpIHtcbiAgICAgIGlmICghaXNPYmplY3Qob2JqZWN0KSkge1xuICAgICAgICByZXR1cm4gb2JqZWN0O1xuICAgICAgfVxuICAgICAgcGF0aCA9IGNhc3RQYXRoKHBhdGgsIG9iamVjdCk7XG5cbiAgICAgIHZhciBpbmRleCA9IC0xLFxuICAgICAgICAgIGxlbmd0aCA9IHBhdGgubGVuZ3RoLFxuICAgICAgICAgIGxhc3RJbmRleCA9IGxlbmd0aCAtIDEsXG4gICAgICAgICAgbmVzdGVkID0gb2JqZWN0O1xuXG4gICAgICB3aGlsZSAobmVzdGVkICE9IG51bGwgJiYgKytpbmRleCA8IGxlbmd0aCkge1xuICAgICAgICB2YXIga2V5ID0gdG9LZXkocGF0aFtpbmRleF0pLFxuICAgICAgICAgICAgbmV3VmFsdWUgPSB2YWx1ZTtcblxuICAgICAgICBpZiAoa2V5ID09PSAnX19wcm90b19fJyB8fCBrZXkgPT09ICdjb25zdHJ1Y3RvcicgfHwga2V5ID09PSAncHJvdG90eXBlJykge1xuICAgICAgICAgIHJldHVybiBvYmplY3Q7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoaW5kZXggIT0gbGFzdEluZGV4KSB7XG4gICAgICAgICAgdmFyIG9ialZhbHVlID0gbmVzdGVkW2tleV07XG4gICAgICAgICAgbmV3VmFsdWUgPSBjdXN0b21pemVyID8gY3VzdG9taXplcihvYmpWYWx1ZSwga2V5LCBuZXN0ZWQpIDogdW5kZWZpbmVkO1xuICAgICAgICAgIGlmIChuZXdWYWx1ZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICBuZXdWYWx1ZSA9IGlzT2JqZWN0KG9ialZhbHVlKVxuICAgICAgICAgICAgICA/IG9ialZhbHVlXG4gICAgICAgICAgICAgIDogKGlzSW5kZXgocGF0aFtpbmRleCArIDFdKSA/IFtdIDoge30pO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBhc3NpZ25WYWx1ZShuZXN0ZWQsIGtleSwgbmV3VmFsdWUpO1xuICAgICAgICBuZXN0ZWQgPSBuZXN0ZWRba2V5XTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBvYmplY3Q7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYHNldERhdGFgIHdpdGhvdXQgc3VwcG9ydCBmb3IgaG90IGxvb3Agc2hvcnRpbmcuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIGFzc29jaWF0ZSBtZXRhZGF0YSB3aXRoLlxuICAgICAqIEBwYXJhbSB7Kn0gZGF0YSBUaGUgbWV0YWRhdGEuXG4gICAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIGBmdW5jYC5cbiAgICAgKi9cbiAgICB2YXIgYmFzZVNldERhdGEgPSAhbWV0YU1hcCA/IGlkZW50aXR5IDogZnVuY3Rpb24oZnVuYywgZGF0YSkge1xuICAgICAgbWV0YU1hcC5zZXQoZnVuYywgZGF0YSk7XG4gICAgICByZXR1cm4gZnVuYztcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYHNldFRvU3RyaW5nYCB3aXRob3V0IHN1cHBvcnQgZm9yIGhvdCBsb29wIHNob3J0aW5nLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byBtb2RpZnkuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gc3RyaW5nIFRoZSBgdG9TdHJpbmdgIHJlc3VsdC5cbiAgICAgKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgYGZ1bmNgLlxuICAgICAqL1xuICAgIHZhciBiYXNlU2V0VG9TdHJpbmcgPSAhZGVmaW5lUHJvcGVydHkgPyBpZGVudGl0eSA6IGZ1bmN0aW9uKGZ1bmMsIHN0cmluZykge1xuICAgICAgcmV0dXJuIGRlZmluZVByb3BlcnR5KGZ1bmMsICd0b1N0cmluZycsIHtcbiAgICAgICAgJ2NvbmZpZ3VyYWJsZSc6IHRydWUsXG4gICAgICAgICdlbnVtZXJhYmxlJzogZmFsc2UsXG4gICAgICAgICd2YWx1ZSc6IGNvbnN0YW50KHN0cmluZyksXG4gICAgICAgICd3cml0YWJsZSc6IHRydWVcbiAgICAgIH0pO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5zaHVmZmxlYC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtBcnJheXxPYmplY3R9IGNvbGxlY3Rpb24gVGhlIGNvbGxlY3Rpb24gdG8gc2h1ZmZsZS5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIG5ldyBzaHVmZmxlZCBhcnJheS5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBiYXNlU2h1ZmZsZShjb2xsZWN0aW9uKSB7XG4gICAgICByZXR1cm4gc2h1ZmZsZVNlbGYodmFsdWVzKGNvbGxlY3Rpb24pKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5zbGljZWAgd2l0aG91dCBhbiBpdGVyYXRlZSBjYWxsIGd1YXJkLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gc2xpY2UuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtzdGFydD0wXSBUaGUgc3RhcnQgcG9zaXRpb24uXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtlbmQ9YXJyYXkubGVuZ3RoXSBUaGUgZW5kIHBvc2l0aW9uLlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgc2xpY2Ugb2YgYGFycmF5YC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBiYXNlU2xpY2UoYXJyYXksIHN0YXJ0LCBlbmQpIHtcbiAgICAgIHZhciBpbmRleCA9IC0xLFxuICAgICAgICAgIGxlbmd0aCA9IGFycmF5Lmxlbmd0aDtcblxuICAgICAgaWYgKHN0YXJ0IDwgMCkge1xuICAgICAgICBzdGFydCA9IC1zdGFydCA+IGxlbmd0aCA/IDAgOiAobGVuZ3RoICsgc3RhcnQpO1xuICAgICAgfVxuICAgICAgZW5kID0gZW5kID4gbGVuZ3RoID8gbGVuZ3RoIDogZW5kO1xuICAgICAgaWYgKGVuZCA8IDApIHtcbiAgICAgICAgZW5kICs9IGxlbmd0aDtcbiAgICAgIH1cbiAgICAgIGxlbmd0aCA9IHN0YXJ0ID4gZW5kID8gMCA6ICgoZW5kIC0gc3RhcnQpID4+PiAwKTtcbiAgICAgIHN0YXJ0ID4+Pj0gMDtcblxuICAgICAgdmFyIHJlc3VsdCA9IEFycmF5KGxlbmd0aCk7XG4gICAgICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgICAgICByZXN1bHRbaW5kZXhdID0gYXJyYXlbaW5kZXggKyBzdGFydF07XG4gICAgICB9XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLnNvbWVgIHdpdGhvdXQgc3VwcG9ydCBmb3IgaXRlcmF0ZWUgc2hvcnRoYW5kcy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtBcnJheXxPYmplY3R9IGNvbGxlY3Rpb24gVGhlIGNvbGxlY3Rpb24gdG8gaXRlcmF0ZSBvdmVyLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IHByZWRpY2F0ZSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBhbnkgZWxlbWVudCBwYXNzZXMgdGhlIHByZWRpY2F0ZSBjaGVjayxcbiAgICAgKiAgZWxzZSBgZmFsc2VgLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGJhc2VTb21lKGNvbGxlY3Rpb24sIHByZWRpY2F0ZSkge1xuICAgICAgdmFyIHJlc3VsdDtcblxuICAgICAgYmFzZUVhY2goY29sbGVjdGlvbiwgZnVuY3Rpb24odmFsdWUsIGluZGV4LCBjb2xsZWN0aW9uKSB7XG4gICAgICAgIHJlc3VsdCA9IHByZWRpY2F0ZSh2YWx1ZSwgaW5kZXgsIGNvbGxlY3Rpb24pO1xuICAgICAgICByZXR1cm4gIXJlc3VsdDtcbiAgICAgIH0pO1xuICAgICAgcmV0dXJuICEhcmVzdWx0O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLnNvcnRlZEluZGV4YCBhbmQgYF8uc29ydGVkTGFzdEluZGV4YCB3aGljaFxuICAgICAqIHBlcmZvcm1zIGEgYmluYXJ5IHNlYXJjaCBvZiBgYXJyYXlgIHRvIGRldGVybWluZSB0aGUgaW5kZXggYXQgd2hpY2ggYHZhbHVlYFxuICAgICAqIHNob3VsZCBiZSBpbnNlcnRlZCBpbnRvIGBhcnJheWAgaW4gb3JkZXIgdG8gbWFpbnRhaW4gaXRzIHNvcnQgb3JkZXIuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBzb3J0ZWQgYXJyYXkgdG8gaW5zcGVjdC5cbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBldmFsdWF0ZS5cbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW59IFtyZXRIaWdoZXN0XSBTcGVjaWZ5IHJldHVybmluZyB0aGUgaGlnaGVzdCBxdWFsaWZpZWQgaW5kZXguXG4gICAgICogQHJldHVybnMge251bWJlcn0gUmV0dXJucyB0aGUgaW5kZXggYXQgd2hpY2ggYHZhbHVlYCBzaG91bGQgYmUgaW5zZXJ0ZWRcbiAgICAgKiAgaW50byBgYXJyYXlgLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGJhc2VTb3J0ZWRJbmRleChhcnJheSwgdmFsdWUsIHJldEhpZ2hlc3QpIHtcbiAgICAgIHZhciBsb3cgPSAwLFxuICAgICAgICAgIGhpZ2ggPSBhcnJheSA9PSBudWxsID8gbG93IDogYXJyYXkubGVuZ3RoO1xuXG4gICAgICBpZiAodHlwZW9mIHZhbHVlID09ICdudW1iZXInICYmIHZhbHVlID09PSB2YWx1ZSAmJiBoaWdoIDw9IEhBTEZfTUFYX0FSUkFZX0xFTkdUSCkge1xuICAgICAgICB3aGlsZSAobG93IDwgaGlnaCkge1xuICAgICAgICAgIHZhciBtaWQgPSAobG93ICsgaGlnaCkgPj4+IDEsXG4gICAgICAgICAgICAgIGNvbXB1dGVkID0gYXJyYXlbbWlkXTtcblxuICAgICAgICAgIGlmIChjb21wdXRlZCAhPT0gbnVsbCAmJiAhaXNTeW1ib2woY29tcHV0ZWQpICYmXG4gICAgICAgICAgICAgIChyZXRIaWdoZXN0ID8gKGNvbXB1dGVkIDw9IHZhbHVlKSA6IChjb21wdXRlZCA8IHZhbHVlKSkpIHtcbiAgICAgICAgICAgIGxvdyA9IG1pZCArIDE7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGhpZ2ggPSBtaWQ7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBoaWdoO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGJhc2VTb3J0ZWRJbmRleEJ5KGFycmF5LCB2YWx1ZSwgaWRlbnRpdHksIHJldEhpZ2hlc3QpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLnNvcnRlZEluZGV4QnlgIGFuZCBgXy5zb3J0ZWRMYXN0SW5kZXhCeWBcbiAgICAgKiB3aGljaCBpbnZva2VzIGBpdGVyYXRlZWAgZm9yIGB2YWx1ZWAgYW5kIGVhY2ggZWxlbWVudCBvZiBgYXJyYXlgIHRvIGNvbXB1dGVcbiAgICAgKiB0aGVpciBzb3J0IHJhbmtpbmcuIFRoZSBpdGVyYXRlZSBpcyBpbnZva2VkIHdpdGggb25lIGFyZ3VtZW50OyAodmFsdWUpLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgc29ydGVkIGFycmF5IHRvIGluc3BlY3QuXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gZXZhbHVhdGUuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gaXRlcmF0ZWUgVGhlIGl0ZXJhdGVlIGludm9rZWQgcGVyIGVsZW1lbnQuXG4gICAgICogQHBhcmFtIHtib29sZWFufSBbcmV0SGlnaGVzdF0gU3BlY2lmeSByZXR1cm5pbmcgdGhlIGhpZ2hlc3QgcXVhbGlmaWVkIGluZGV4LlxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9IFJldHVybnMgdGhlIGluZGV4IGF0IHdoaWNoIGB2YWx1ZWAgc2hvdWxkIGJlIGluc2VydGVkXG4gICAgICogIGludG8gYGFycmF5YC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBiYXNlU29ydGVkSW5kZXhCeShhcnJheSwgdmFsdWUsIGl0ZXJhdGVlLCByZXRIaWdoZXN0KSB7XG4gICAgICB2YXIgbG93ID0gMCxcbiAgICAgICAgICBoaWdoID0gYXJyYXkgPT0gbnVsbCA/IDAgOiBhcnJheS5sZW5ndGg7XG4gICAgICBpZiAoaGlnaCA9PT0gMCkge1xuICAgICAgICByZXR1cm4gMDtcbiAgICAgIH1cblxuICAgICAgdmFsdWUgPSBpdGVyYXRlZSh2YWx1ZSk7XG4gICAgICB2YXIgdmFsSXNOYU4gPSB2YWx1ZSAhPT0gdmFsdWUsXG4gICAgICAgICAgdmFsSXNOdWxsID0gdmFsdWUgPT09IG51bGwsXG4gICAgICAgICAgdmFsSXNTeW1ib2wgPSBpc1N5bWJvbCh2YWx1ZSksXG4gICAgICAgICAgdmFsSXNVbmRlZmluZWQgPSB2YWx1ZSA9PT0gdW5kZWZpbmVkO1xuXG4gICAgICB3aGlsZSAobG93IDwgaGlnaCkge1xuICAgICAgICB2YXIgbWlkID0gbmF0aXZlRmxvb3IoKGxvdyArIGhpZ2gpIC8gMiksXG4gICAgICAgICAgICBjb21wdXRlZCA9IGl0ZXJhdGVlKGFycmF5W21pZF0pLFxuICAgICAgICAgICAgb3RoSXNEZWZpbmVkID0gY29tcHV0ZWQgIT09IHVuZGVmaW5lZCxcbiAgICAgICAgICAgIG90aElzTnVsbCA9IGNvbXB1dGVkID09PSBudWxsLFxuICAgICAgICAgICAgb3RoSXNSZWZsZXhpdmUgPSBjb21wdXRlZCA9PT0gY29tcHV0ZWQsXG4gICAgICAgICAgICBvdGhJc1N5bWJvbCA9IGlzU3ltYm9sKGNvbXB1dGVkKTtcblxuICAgICAgICBpZiAodmFsSXNOYU4pIHtcbiAgICAgICAgICB2YXIgc2V0TG93ID0gcmV0SGlnaGVzdCB8fCBvdGhJc1JlZmxleGl2ZTtcbiAgICAgICAgfSBlbHNlIGlmICh2YWxJc1VuZGVmaW5lZCkge1xuICAgICAgICAgIHNldExvdyA9IG90aElzUmVmbGV4aXZlICYmIChyZXRIaWdoZXN0IHx8IG90aElzRGVmaW5lZCk7XG4gICAgICAgIH0gZWxzZSBpZiAodmFsSXNOdWxsKSB7XG4gICAgICAgICAgc2V0TG93ID0gb3RoSXNSZWZsZXhpdmUgJiYgb3RoSXNEZWZpbmVkICYmIChyZXRIaWdoZXN0IHx8ICFvdGhJc051bGwpO1xuICAgICAgICB9IGVsc2UgaWYgKHZhbElzU3ltYm9sKSB7XG4gICAgICAgICAgc2V0TG93ID0gb3RoSXNSZWZsZXhpdmUgJiYgb3RoSXNEZWZpbmVkICYmICFvdGhJc051bGwgJiYgKHJldEhpZ2hlc3QgfHwgIW90aElzU3ltYm9sKTtcbiAgICAgICAgfSBlbHNlIGlmIChvdGhJc051bGwgfHwgb3RoSXNTeW1ib2wpIHtcbiAgICAgICAgICBzZXRMb3cgPSBmYWxzZTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBzZXRMb3cgPSByZXRIaWdoZXN0ID8gKGNvbXB1dGVkIDw9IHZhbHVlKSA6IChjb21wdXRlZCA8IHZhbHVlKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoc2V0TG93KSB7XG4gICAgICAgICAgbG93ID0gbWlkICsgMTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBoaWdoID0gbWlkO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gbmF0aXZlTWluKGhpZ2gsIE1BWF9BUlJBWV9JTkRFWCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uc29ydGVkVW5pcWAgYW5kIGBfLnNvcnRlZFVuaXFCeWAgd2l0aG91dFxuICAgICAqIHN1cHBvcnQgZm9yIGl0ZXJhdGVlIHNob3J0aGFuZHMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBpbnNwZWN0LlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IFtpdGVyYXRlZV0gVGhlIGl0ZXJhdGVlIGludm9rZWQgcGVyIGVsZW1lbnQuXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBuZXcgZHVwbGljYXRlIGZyZWUgYXJyYXkuXG4gICAgICovXG4gICAgZnVuY3Rpb24gYmFzZVNvcnRlZFVuaXEoYXJyYXksIGl0ZXJhdGVlKSB7XG4gICAgICB2YXIgaW5kZXggPSAtMSxcbiAgICAgICAgICBsZW5ndGggPSBhcnJheS5sZW5ndGgsXG4gICAgICAgICAgcmVzSW5kZXggPSAwLFxuICAgICAgICAgIHJlc3VsdCA9IFtdO1xuXG4gICAgICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgICAgICB2YXIgdmFsdWUgPSBhcnJheVtpbmRleF0sXG4gICAgICAgICAgICBjb21wdXRlZCA9IGl0ZXJhdGVlID8gaXRlcmF0ZWUodmFsdWUpIDogdmFsdWU7XG5cbiAgICAgICAgaWYgKCFpbmRleCB8fCAhZXEoY29tcHV0ZWQsIHNlZW4pKSB7XG4gICAgICAgICAgdmFyIHNlZW4gPSBjb21wdXRlZDtcbiAgICAgICAgICByZXN1bHRbcmVzSW5kZXgrK10gPSB2YWx1ZSA9PT0gMCA/IDAgOiB2YWx1ZTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy50b051bWJlcmAgd2hpY2ggZG9lc24ndCBlbnN1cmUgY29ycmVjdFxuICAgICAqIGNvbnZlcnNpb25zIG9mIGJpbmFyeSwgaGV4YWRlY2ltYWwsIG9yIG9jdGFsIHN0cmluZyB2YWx1ZXMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIHByb2Nlc3MuXG4gICAgICogQHJldHVybnMge251bWJlcn0gUmV0dXJucyB0aGUgbnVtYmVyLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGJhc2VUb051bWJlcih2YWx1ZSkge1xuICAgICAgaWYgKHR5cGVvZiB2YWx1ZSA9PSAnbnVtYmVyJykge1xuICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgICB9XG4gICAgICBpZiAoaXNTeW1ib2wodmFsdWUpKSB7XG4gICAgICAgIHJldHVybiBOQU47XG4gICAgICB9XG4gICAgICByZXR1cm4gK3ZhbHVlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLnRvU3RyaW5nYCB3aGljaCBkb2Vzbid0IGNvbnZlcnQgbnVsbGlzaFxuICAgICAqIHZhbHVlcyB0byBlbXB0eSBzdHJpbmdzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBwcm9jZXNzLlxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IFJldHVybnMgdGhlIHN0cmluZy5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBiYXNlVG9TdHJpbmcodmFsdWUpIHtcbiAgICAgIC8vIEV4aXQgZWFybHkgZm9yIHN0cmluZ3MgdG8gYXZvaWQgYSBwZXJmb3JtYW5jZSBoaXQgaW4gc29tZSBlbnZpcm9ubWVudHMuXG4gICAgICBpZiAodHlwZW9mIHZhbHVlID09ICdzdHJpbmcnKSB7XG4gICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICAgIH1cbiAgICAgIGlmIChpc0FycmF5KHZhbHVlKSkge1xuICAgICAgICAvLyBSZWN1cnNpdmVseSBjb252ZXJ0IHZhbHVlcyAoc3VzY2VwdGlibGUgdG8gY2FsbCBzdGFjayBsaW1pdHMpLlxuICAgICAgICByZXR1cm4gYXJyYXlNYXAodmFsdWUsIGJhc2VUb1N0cmluZykgKyAnJztcbiAgICAgIH1cbiAgICAgIGlmIChpc1N5bWJvbCh2YWx1ZSkpIHtcbiAgICAgICAgcmV0dXJuIHN5bWJvbFRvU3RyaW5nID8gc3ltYm9sVG9TdHJpbmcuY2FsbCh2YWx1ZSkgOiAnJztcbiAgICAgIH1cbiAgICAgIHZhciByZXN1bHQgPSAodmFsdWUgKyAnJyk7XG4gICAgICByZXR1cm4gKHJlc3VsdCA9PSAnMCcgJiYgKDEgLyB2YWx1ZSkgPT0gLUlORklOSVRZKSA/ICctMCcgOiByZXN1bHQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8udW5pcUJ5YCB3aXRob3V0IHN1cHBvcnQgZm9yIGl0ZXJhdGVlIHNob3J0aGFuZHMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBpbnNwZWN0LlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IFtpdGVyYXRlZV0gVGhlIGl0ZXJhdGVlIGludm9rZWQgcGVyIGVsZW1lbnQuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW2NvbXBhcmF0b3JdIFRoZSBjb21wYXJhdG9yIGludm9rZWQgcGVyIGVsZW1lbnQuXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBuZXcgZHVwbGljYXRlIGZyZWUgYXJyYXkuXG4gICAgICovXG4gICAgZnVuY3Rpb24gYmFzZVVuaXEoYXJyYXksIGl0ZXJhdGVlLCBjb21wYXJhdG9yKSB7XG4gICAgICB2YXIgaW5kZXggPSAtMSxcbiAgICAgICAgICBpbmNsdWRlcyA9IGFycmF5SW5jbHVkZXMsXG4gICAgICAgICAgbGVuZ3RoID0gYXJyYXkubGVuZ3RoLFxuICAgICAgICAgIGlzQ29tbW9uID0gdHJ1ZSxcbiAgICAgICAgICByZXN1bHQgPSBbXSxcbiAgICAgICAgICBzZWVuID0gcmVzdWx0O1xuXG4gICAgICBpZiAoY29tcGFyYXRvcikge1xuICAgICAgICBpc0NvbW1vbiA9IGZhbHNlO1xuICAgICAgICBpbmNsdWRlcyA9IGFycmF5SW5jbHVkZXNXaXRoO1xuICAgICAgfVxuICAgICAgZWxzZSBpZiAobGVuZ3RoID49IExBUkdFX0FSUkFZX1NJWkUpIHtcbiAgICAgICAgdmFyIHNldCA9IGl0ZXJhdGVlID8gbnVsbCA6IGNyZWF0ZVNldChhcnJheSk7XG4gICAgICAgIGlmIChzZXQpIHtcbiAgICAgICAgICByZXR1cm4gc2V0VG9BcnJheShzZXQpO1xuICAgICAgICB9XG4gICAgICAgIGlzQ29tbW9uID0gZmFsc2U7XG4gICAgICAgIGluY2x1ZGVzID0gY2FjaGVIYXM7XG4gICAgICAgIHNlZW4gPSBuZXcgU2V0Q2FjaGU7XG4gICAgICB9XG4gICAgICBlbHNlIHtcbiAgICAgICAgc2VlbiA9IGl0ZXJhdGVlID8gW10gOiByZXN1bHQ7XG4gICAgICB9XG4gICAgICBvdXRlcjpcbiAgICAgIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XG4gICAgICAgIHZhciB2YWx1ZSA9IGFycmF5W2luZGV4XSxcbiAgICAgICAgICAgIGNvbXB1dGVkID0gaXRlcmF0ZWUgPyBpdGVyYXRlZSh2YWx1ZSkgOiB2YWx1ZTtcblxuICAgICAgICB2YWx1ZSA9IChjb21wYXJhdG9yIHx8IHZhbHVlICE9PSAwKSA/IHZhbHVlIDogMDtcbiAgICAgICAgaWYgKGlzQ29tbW9uICYmIGNvbXB1dGVkID09PSBjb21wdXRlZCkge1xuICAgICAgICAgIHZhciBzZWVuSW5kZXggPSBzZWVuLmxlbmd0aDtcbiAgICAgICAgICB3aGlsZSAoc2VlbkluZGV4LS0pIHtcbiAgICAgICAgICAgIGlmIChzZWVuW3NlZW5JbmRleF0gPT09IGNvbXB1dGVkKSB7XG4gICAgICAgICAgICAgIGNvbnRpbnVlIG91dGVyO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoaXRlcmF0ZWUpIHtcbiAgICAgICAgICAgIHNlZW4ucHVzaChjb21wdXRlZCk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJlc3VsdC5wdXNoKHZhbHVlKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmICghaW5jbHVkZXMoc2VlbiwgY29tcHV0ZWQsIGNvbXBhcmF0b3IpKSB7XG4gICAgICAgICAgaWYgKHNlZW4gIT09IHJlc3VsdCkge1xuICAgICAgICAgICAgc2Vlbi5wdXNoKGNvbXB1dGVkKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmVzdWx0LnB1c2godmFsdWUpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLnVuc2V0YC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIG1vZGlmeS5cbiAgICAgKiBAcGFyYW0ge0FycmF5fHN0cmluZ30gcGF0aCBUaGUgcHJvcGVydHkgcGF0aCB0byB1bnNldC5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgdGhlIHByb3BlcnR5IGlzIGRlbGV0ZWQsIGVsc2UgYGZhbHNlYC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBiYXNlVW5zZXQob2JqZWN0LCBwYXRoKSB7XG4gICAgICBwYXRoID0gY2FzdFBhdGgocGF0aCwgb2JqZWN0KTtcbiAgICAgIG9iamVjdCA9IHBhcmVudChvYmplY3QsIHBhdGgpO1xuICAgICAgcmV0dXJuIG9iamVjdCA9PSBudWxsIHx8IGRlbGV0ZSBvYmplY3RbdG9LZXkobGFzdChwYXRoKSldO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLnVwZGF0ZWAuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBtb2RpZnkuXG4gICAgICogQHBhcmFtIHtBcnJheXxzdHJpbmd9IHBhdGggVGhlIHBhdGggb2YgdGhlIHByb3BlcnR5IHRvIHVwZGF0ZS5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSB1cGRhdGVyIFRoZSBmdW5jdGlvbiB0byBwcm9kdWNlIHRoZSB1cGRhdGVkIHZhbHVlLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IFtjdXN0b21pemVyXSBUaGUgZnVuY3Rpb24gdG8gY3VzdG9taXplIHBhdGggY3JlYXRpb24uXG4gICAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyBgb2JqZWN0YC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBiYXNlVXBkYXRlKG9iamVjdCwgcGF0aCwgdXBkYXRlciwgY3VzdG9taXplcikge1xuICAgICAgcmV0dXJuIGJhc2VTZXQob2JqZWN0LCBwYXRoLCB1cGRhdGVyKGJhc2VHZXQob2JqZWN0LCBwYXRoKSksIGN1c3RvbWl6ZXIpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIG1ldGhvZHMgbGlrZSBgXy5kcm9wV2hpbGVgIGFuZCBgXy50YWtlV2hpbGVgXG4gICAgICogd2l0aG91dCBzdXBwb3J0IGZvciBpdGVyYXRlZSBzaG9ydGhhbmRzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gcXVlcnkuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gcHJlZGljYXRlIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uXG4gICAgICogQHBhcmFtIHtib29sZWFufSBbaXNEcm9wXSBTcGVjaWZ5IGRyb3BwaW5nIGVsZW1lbnRzIGluc3RlYWQgb2YgdGFraW5nIHRoZW0uXG4gICAgICogQHBhcmFtIHtib29sZWFufSBbZnJvbVJpZ2h0XSBTcGVjaWZ5IGl0ZXJhdGluZyBmcm9tIHJpZ2h0IHRvIGxlZnQuXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBzbGljZSBvZiBgYXJyYXlgLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGJhc2VXaGlsZShhcnJheSwgcHJlZGljYXRlLCBpc0Ryb3AsIGZyb21SaWdodCkge1xuICAgICAgdmFyIGxlbmd0aCA9IGFycmF5Lmxlbmd0aCxcbiAgICAgICAgICBpbmRleCA9IGZyb21SaWdodCA/IGxlbmd0aCA6IC0xO1xuXG4gICAgICB3aGlsZSAoKGZyb21SaWdodCA/IGluZGV4LS0gOiArK2luZGV4IDwgbGVuZ3RoKSAmJlxuICAgICAgICBwcmVkaWNhdGUoYXJyYXlbaW5kZXhdLCBpbmRleCwgYXJyYXkpKSB7fVxuXG4gICAgICByZXR1cm4gaXNEcm9wXG4gICAgICAgID8gYmFzZVNsaWNlKGFycmF5LCAoZnJvbVJpZ2h0ID8gMCA6IGluZGV4KSwgKGZyb21SaWdodCA/IGluZGV4ICsgMSA6IGxlbmd0aCkpXG4gICAgICAgIDogYmFzZVNsaWNlKGFycmF5LCAoZnJvbVJpZ2h0ID8gaW5kZXggKyAxIDogMCksIChmcm9tUmlnaHQgPyBsZW5ndGggOiBpbmRleCkpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGB3cmFwcGVyVmFsdWVgIHdoaWNoIHJldHVybnMgdGhlIHJlc3VsdCBvZlxuICAgICAqIHBlcmZvcm1pbmcgYSBzZXF1ZW5jZSBvZiBhY3Rpb25zIG9uIHRoZSB1bndyYXBwZWQgYHZhbHVlYCwgd2hlcmUgZWFjaFxuICAgICAqIHN1Y2Nlc3NpdmUgYWN0aW9uIGlzIHN1cHBsaWVkIHRoZSByZXR1cm4gdmFsdWUgb2YgdGhlIHByZXZpb3VzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB1bndyYXBwZWQgdmFsdWUuXG4gICAgICogQHBhcmFtIHtBcnJheX0gYWN0aW9ucyBBY3Rpb25zIHRvIHBlcmZvcm0gdG8gcmVzb2x2ZSB0aGUgdW53cmFwcGVkIHZhbHVlLlxuICAgICAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSByZXNvbHZlZCB2YWx1ZS5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBiYXNlV3JhcHBlclZhbHVlKHZhbHVlLCBhY3Rpb25zKSB7XG4gICAgICB2YXIgcmVzdWx0ID0gdmFsdWU7XG4gICAgICBpZiAocmVzdWx0IGluc3RhbmNlb2YgTGF6eVdyYXBwZXIpIHtcbiAgICAgICAgcmVzdWx0ID0gcmVzdWx0LnZhbHVlKCk7XG4gICAgICB9XG4gICAgICByZXR1cm4gYXJyYXlSZWR1Y2UoYWN0aW9ucywgZnVuY3Rpb24ocmVzdWx0LCBhY3Rpb24pIHtcbiAgICAgICAgcmV0dXJuIGFjdGlvbi5mdW5jLmFwcGx5KGFjdGlvbi50aGlzQXJnLCBhcnJheVB1c2goW3Jlc3VsdF0sIGFjdGlvbi5hcmdzKSk7XG4gICAgICB9LCByZXN1bHQpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIG1ldGhvZHMgbGlrZSBgXy54b3JgLCB3aXRob3V0IHN1cHBvcnQgZm9yXG4gICAgICogaXRlcmF0ZWUgc2hvcnRoYW5kcywgdGhhdCBhY2NlcHRzIGFuIGFycmF5IG9mIGFycmF5cyB0byBpbnNwZWN0LlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheXMgVGhlIGFycmF5cyB0byBpbnNwZWN0LlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IFtpdGVyYXRlZV0gVGhlIGl0ZXJhdGVlIGludm9rZWQgcGVyIGVsZW1lbnQuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW2NvbXBhcmF0b3JdIFRoZSBjb21wYXJhdG9yIGludm9rZWQgcGVyIGVsZW1lbnQuXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBuZXcgYXJyYXkgb2YgdmFsdWVzLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGJhc2VYb3IoYXJyYXlzLCBpdGVyYXRlZSwgY29tcGFyYXRvcikge1xuICAgICAgdmFyIGxlbmd0aCA9IGFycmF5cy5sZW5ndGg7XG4gICAgICBpZiAobGVuZ3RoIDwgMikge1xuICAgICAgICByZXR1cm4gbGVuZ3RoID8gYmFzZVVuaXEoYXJyYXlzWzBdKSA6IFtdO1xuICAgICAgfVxuICAgICAgdmFyIGluZGV4ID0gLTEsXG4gICAgICAgICAgcmVzdWx0ID0gQXJyYXkobGVuZ3RoKTtcblxuICAgICAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHtcbiAgICAgICAgdmFyIGFycmF5ID0gYXJyYXlzW2luZGV4XSxcbiAgICAgICAgICAgIG90aEluZGV4ID0gLTE7XG5cbiAgICAgICAgd2hpbGUgKCsrb3RoSW5kZXggPCBsZW5ndGgpIHtcbiAgICAgICAgICBpZiAob3RoSW5kZXggIT0gaW5kZXgpIHtcbiAgICAgICAgICAgIHJlc3VsdFtpbmRleF0gPSBiYXNlRGlmZmVyZW5jZShyZXN1bHRbaW5kZXhdIHx8IGFycmF5LCBhcnJheXNbb3RoSW5kZXhdLCBpdGVyYXRlZSwgY29tcGFyYXRvcik7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gYmFzZVVuaXEoYmFzZUZsYXR0ZW4ocmVzdWx0LCAxKSwgaXRlcmF0ZWUsIGNvbXBhcmF0b3IpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoaXMgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy56aXBPYmplY3RgIHdoaWNoIGFzc2lnbnMgdmFsdWVzIHVzaW5nIGBhc3NpZ25GdW5jYC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtBcnJheX0gcHJvcHMgVGhlIHByb3BlcnR5IGlkZW50aWZpZXJzLlxuICAgICAqIEBwYXJhbSB7QXJyYXl9IHZhbHVlcyBUaGUgcHJvcGVydHkgdmFsdWVzLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGFzc2lnbkZ1bmMgVGhlIGZ1bmN0aW9uIHRvIGFzc2lnbiB2YWx1ZXMuXG4gICAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyB0aGUgbmV3IG9iamVjdC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBiYXNlWmlwT2JqZWN0KHByb3BzLCB2YWx1ZXMsIGFzc2lnbkZ1bmMpIHtcbiAgICAgIHZhciBpbmRleCA9IC0xLFxuICAgICAgICAgIGxlbmd0aCA9IHByb3BzLmxlbmd0aCxcbiAgICAgICAgICB2YWxzTGVuZ3RoID0gdmFsdWVzLmxlbmd0aCxcbiAgICAgICAgICByZXN1bHQgPSB7fTtcblxuICAgICAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHtcbiAgICAgICAgdmFyIHZhbHVlID0gaW5kZXggPCB2YWxzTGVuZ3RoID8gdmFsdWVzW2luZGV4XSA6IHVuZGVmaW5lZDtcbiAgICAgICAgYXNzaWduRnVuYyhyZXN1bHQsIHByb3BzW2luZGV4XSwgdmFsdWUpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDYXN0cyBgdmFsdWVgIHRvIGFuIGVtcHR5IGFycmF5IGlmIGl0J3Mgbm90IGFuIGFycmF5IGxpa2Ugb2JqZWN0LlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBpbnNwZWN0LlxuICAgICAqIEByZXR1cm5zIHtBcnJheXxPYmplY3R9IFJldHVybnMgdGhlIGNhc3QgYXJyYXktbGlrZSBvYmplY3QuXG4gICAgICovXG4gICAgZnVuY3Rpb24gY2FzdEFycmF5TGlrZU9iamVjdCh2YWx1ZSkge1xuICAgICAgcmV0dXJuIGlzQXJyYXlMaWtlT2JqZWN0KHZhbHVlKSA/IHZhbHVlIDogW107XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2FzdHMgYHZhbHVlYCB0byBgaWRlbnRpdHlgIGlmIGl0J3Mgbm90IGEgZnVuY3Rpb24uXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGluc3BlY3QuXG4gICAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIGNhc3QgZnVuY3Rpb24uXG4gICAgICovXG4gICAgZnVuY3Rpb24gY2FzdEZ1bmN0aW9uKHZhbHVlKSB7XG4gICAgICByZXR1cm4gdHlwZW9mIHZhbHVlID09ICdmdW5jdGlvbicgPyB2YWx1ZSA6IGlkZW50aXR5O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENhc3RzIGB2YWx1ZWAgdG8gYSBwYXRoIGFycmF5IGlmIGl0J3Mgbm90IG9uZS5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gaW5zcGVjdC5cbiAgICAgKiBAcGFyYW0ge09iamVjdH0gW29iamVjdF0gVGhlIG9iamVjdCB0byBxdWVyeSBrZXlzIG9uLlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgY2FzdCBwcm9wZXJ0eSBwYXRoIGFycmF5LlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGNhc3RQYXRoKHZhbHVlLCBvYmplY3QpIHtcbiAgICAgIGlmIChpc0FycmF5KHZhbHVlKSkge1xuICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgICB9XG4gICAgICByZXR1cm4gaXNLZXkodmFsdWUsIG9iamVjdCkgPyBbdmFsdWVdIDogc3RyaW5nVG9QYXRoKHRvU3RyaW5nKHZhbHVlKSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQSBgYmFzZVJlc3RgIGFsaWFzIHdoaWNoIGNhbiBiZSByZXBsYWNlZCB3aXRoIGBpZGVudGl0eWAgYnkgbW9kdWxlXG4gICAgICogcmVwbGFjZW1lbnQgcGx1Z2lucy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge0Z1bmN0aW9ufVxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIGFwcGx5IGEgcmVzdCBwYXJhbWV0ZXIgdG8uXG4gICAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgZnVuY3Rpb24uXG4gICAgICovXG4gICAgdmFyIGNhc3RSZXN0ID0gYmFzZVJlc3Q7XG5cbiAgICAvKipcbiAgICAgKiBDYXN0cyBgYXJyYXlgIHRvIGEgc2xpY2UgaWYgaXQncyBuZWVkZWQuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBpbnNwZWN0LlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBzdGFydCBUaGUgc3RhcnQgcG9zaXRpb24uXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtlbmQ9YXJyYXkubGVuZ3RoXSBUaGUgZW5kIHBvc2l0aW9uLlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgY2FzdCBzbGljZS5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBjYXN0U2xpY2UoYXJyYXksIHN0YXJ0LCBlbmQpIHtcbiAgICAgIHZhciBsZW5ndGggPSBhcnJheS5sZW5ndGg7XG4gICAgICBlbmQgPSBlbmQgPT09IHVuZGVmaW5lZCA/IGxlbmd0aCA6IGVuZDtcbiAgICAgIHJldHVybiAoIXN0YXJ0ICYmIGVuZCA+PSBsZW5ndGgpID8gYXJyYXkgOiBiYXNlU2xpY2UoYXJyYXksIHN0YXJ0LCBlbmQpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEEgc2ltcGxlIHdyYXBwZXIgYXJvdW5kIHRoZSBnbG9iYWwgW2BjbGVhclRpbWVvdXRgXShodHRwczovL21kbi5pby9jbGVhclRpbWVvdXQpLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge251bWJlcnxPYmplY3R9IGlkIFRoZSB0aW1lciBpZCBvciB0aW1lb3V0IG9iamVjdCBvZiB0aGUgdGltZXIgdG8gY2xlYXIuXG4gICAgICovXG4gICAgdmFyIGNsZWFyVGltZW91dCA9IGN0eENsZWFyVGltZW91dCB8fCBmdW5jdGlvbihpZCkge1xuICAgICAgcmV0dXJuIHJvb3QuY2xlYXJUaW1lb3V0KGlkKTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIGNsb25lIG9mICBgYnVmZmVyYC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtCdWZmZXJ9IGJ1ZmZlciBUaGUgYnVmZmVyIHRvIGNsb25lLlxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbn0gW2lzRGVlcF0gU3BlY2lmeSBhIGRlZXAgY2xvbmUuXG4gICAgICogQHJldHVybnMge0J1ZmZlcn0gUmV0dXJucyB0aGUgY2xvbmVkIGJ1ZmZlci5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBjbG9uZUJ1ZmZlcihidWZmZXIsIGlzRGVlcCkge1xuICAgICAgaWYgKGlzRGVlcCkge1xuICAgICAgICByZXR1cm4gYnVmZmVyLnNsaWNlKCk7XG4gICAgICB9XG4gICAgICB2YXIgbGVuZ3RoID0gYnVmZmVyLmxlbmd0aCxcbiAgICAgICAgICByZXN1bHQgPSBhbGxvY1Vuc2FmZSA/IGFsbG9jVW5zYWZlKGxlbmd0aCkgOiBuZXcgYnVmZmVyLmNvbnN0cnVjdG9yKGxlbmd0aCk7XG5cbiAgICAgIGJ1ZmZlci5jb3B5KHJlc3VsdCk7XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBjbG9uZSBvZiBgYXJyYXlCdWZmZXJgLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0FycmF5QnVmZmVyfSBhcnJheUJ1ZmZlciBUaGUgYXJyYXkgYnVmZmVyIHRvIGNsb25lLlxuICAgICAqIEByZXR1cm5zIHtBcnJheUJ1ZmZlcn0gUmV0dXJucyB0aGUgY2xvbmVkIGFycmF5IGJ1ZmZlci5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBjbG9uZUFycmF5QnVmZmVyKGFycmF5QnVmZmVyKSB7XG4gICAgICB2YXIgcmVzdWx0ID0gbmV3IGFycmF5QnVmZmVyLmNvbnN0cnVjdG9yKGFycmF5QnVmZmVyLmJ5dGVMZW5ndGgpO1xuICAgICAgbmV3IFVpbnQ4QXJyYXkocmVzdWx0KS5zZXQobmV3IFVpbnQ4QXJyYXkoYXJyYXlCdWZmZXIpKTtcbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIGNsb25lIG9mIGBkYXRhVmlld2AuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBkYXRhVmlldyBUaGUgZGF0YSB2aWV3IHRvIGNsb25lLlxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbn0gW2lzRGVlcF0gU3BlY2lmeSBhIGRlZXAgY2xvbmUuXG4gICAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyB0aGUgY2xvbmVkIGRhdGEgdmlldy5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBjbG9uZURhdGFWaWV3KGRhdGFWaWV3LCBpc0RlZXApIHtcbiAgICAgIHZhciBidWZmZXIgPSBpc0RlZXAgPyBjbG9uZUFycmF5QnVmZmVyKGRhdGFWaWV3LmJ1ZmZlcikgOiBkYXRhVmlldy5idWZmZXI7XG4gICAgICByZXR1cm4gbmV3IGRhdGFWaWV3LmNvbnN0cnVjdG9yKGJ1ZmZlciwgZGF0YVZpZXcuYnl0ZU9mZnNldCwgZGF0YVZpZXcuYnl0ZUxlbmd0aCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIGNsb25lIG9mIGByZWdleHBgLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gcmVnZXhwIFRoZSByZWdleHAgdG8gY2xvbmUuXG4gICAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyB0aGUgY2xvbmVkIHJlZ2V4cC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBjbG9uZVJlZ0V4cChyZWdleHApIHtcbiAgICAgIHZhciByZXN1bHQgPSBuZXcgcmVnZXhwLmNvbnN0cnVjdG9yKHJlZ2V4cC5zb3VyY2UsIHJlRmxhZ3MuZXhlYyhyZWdleHApKTtcbiAgICAgIHJlc3VsdC5sYXN0SW5kZXggPSByZWdleHAubGFzdEluZGV4O1xuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgY2xvbmUgb2YgdGhlIGBzeW1ib2xgIG9iamVjdC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtPYmplY3R9IHN5bWJvbCBUaGUgc3ltYm9sIG9iamVjdCB0byBjbG9uZS5cbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIHRoZSBjbG9uZWQgc3ltYm9sIG9iamVjdC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBjbG9uZVN5bWJvbChzeW1ib2wpIHtcbiAgICAgIHJldHVybiBzeW1ib2xWYWx1ZU9mID8gT2JqZWN0KHN5bWJvbFZhbHVlT2YuY2FsbChzeW1ib2wpKSA6IHt9O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBjbG9uZSBvZiBgdHlwZWRBcnJheWAuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSB0eXBlZEFycmF5IFRoZSB0eXBlZCBhcnJheSB0byBjbG9uZS5cbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW59IFtpc0RlZXBdIFNwZWNpZnkgYSBkZWVwIGNsb25lLlxuICAgICAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgdGhlIGNsb25lZCB0eXBlZCBhcnJheS5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBjbG9uZVR5cGVkQXJyYXkodHlwZWRBcnJheSwgaXNEZWVwKSB7XG4gICAgICB2YXIgYnVmZmVyID0gaXNEZWVwID8gY2xvbmVBcnJheUJ1ZmZlcih0eXBlZEFycmF5LmJ1ZmZlcikgOiB0eXBlZEFycmF5LmJ1ZmZlcjtcbiAgICAgIHJldHVybiBuZXcgdHlwZWRBcnJheS5jb25zdHJ1Y3RvcihidWZmZXIsIHR5cGVkQXJyYXkuYnl0ZU9mZnNldCwgdHlwZWRBcnJheS5sZW5ndGgpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENvbXBhcmVzIHZhbHVlcyB0byBzb3J0IHRoZW0gaW4gYXNjZW5kaW5nIG9yZGVyLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjb21wYXJlLlxuICAgICAqIEBwYXJhbSB7Kn0gb3RoZXIgVGhlIG90aGVyIHZhbHVlIHRvIGNvbXBhcmUuXG4gICAgICogQHJldHVybnMge251bWJlcn0gUmV0dXJucyB0aGUgc29ydCBvcmRlciBpbmRpY2F0b3IgZm9yIGB2YWx1ZWAuXG4gICAgICovXG4gICAgZnVuY3Rpb24gY29tcGFyZUFzY2VuZGluZyh2YWx1ZSwgb3RoZXIpIHtcbiAgICAgIGlmICh2YWx1ZSAhPT0gb3RoZXIpIHtcbiAgICAgICAgdmFyIHZhbElzRGVmaW5lZCA9IHZhbHVlICE9PSB1bmRlZmluZWQsXG4gICAgICAgICAgICB2YWxJc051bGwgPSB2YWx1ZSA9PT0gbnVsbCxcbiAgICAgICAgICAgIHZhbElzUmVmbGV4aXZlID0gdmFsdWUgPT09IHZhbHVlLFxuICAgICAgICAgICAgdmFsSXNTeW1ib2wgPSBpc1N5bWJvbCh2YWx1ZSk7XG5cbiAgICAgICAgdmFyIG90aElzRGVmaW5lZCA9IG90aGVyICE9PSB1bmRlZmluZWQsXG4gICAgICAgICAgICBvdGhJc051bGwgPSBvdGhlciA9PT0gbnVsbCxcbiAgICAgICAgICAgIG90aElzUmVmbGV4aXZlID0gb3RoZXIgPT09IG90aGVyLFxuICAgICAgICAgICAgb3RoSXNTeW1ib2wgPSBpc1N5bWJvbChvdGhlcik7XG5cbiAgICAgICAgaWYgKCghb3RoSXNOdWxsICYmICFvdGhJc1N5bWJvbCAmJiAhdmFsSXNTeW1ib2wgJiYgdmFsdWUgPiBvdGhlcikgfHxcbiAgICAgICAgICAgICh2YWxJc1N5bWJvbCAmJiBvdGhJc0RlZmluZWQgJiYgb3RoSXNSZWZsZXhpdmUgJiYgIW90aElzTnVsbCAmJiAhb3RoSXNTeW1ib2wpIHx8XG4gICAgICAgICAgICAodmFsSXNOdWxsICYmIG90aElzRGVmaW5lZCAmJiBvdGhJc1JlZmxleGl2ZSkgfHxcbiAgICAgICAgICAgICghdmFsSXNEZWZpbmVkICYmIG90aElzUmVmbGV4aXZlKSB8fFxuICAgICAgICAgICAgIXZhbElzUmVmbGV4aXZlKSB7XG4gICAgICAgICAgcmV0dXJuIDE7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCghdmFsSXNOdWxsICYmICF2YWxJc1N5bWJvbCAmJiAhb3RoSXNTeW1ib2wgJiYgdmFsdWUgPCBvdGhlcikgfHxcbiAgICAgICAgICAgIChvdGhJc1N5bWJvbCAmJiB2YWxJc0RlZmluZWQgJiYgdmFsSXNSZWZsZXhpdmUgJiYgIXZhbElzTnVsbCAmJiAhdmFsSXNTeW1ib2wpIHx8XG4gICAgICAgICAgICAob3RoSXNOdWxsICYmIHZhbElzRGVmaW5lZCAmJiB2YWxJc1JlZmxleGl2ZSkgfHxcbiAgICAgICAgICAgICghb3RoSXNEZWZpbmVkICYmIHZhbElzUmVmbGV4aXZlKSB8fFxuICAgICAgICAgICAgIW90aElzUmVmbGV4aXZlKSB7XG4gICAgICAgICAgcmV0dXJuIC0xO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gMDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBVc2VkIGJ5IGBfLm9yZGVyQnlgIHRvIGNvbXBhcmUgbXVsdGlwbGUgcHJvcGVydGllcyBvZiBhIHZhbHVlIHRvIGFub3RoZXJcbiAgICAgKiBhbmQgc3RhYmxlIHNvcnQgdGhlbS5cbiAgICAgKlxuICAgICAqIElmIGBvcmRlcnNgIGlzIHVuc3BlY2lmaWVkLCBhbGwgdmFsdWVzIGFyZSBzb3J0ZWQgaW4gYXNjZW5kaW5nIG9yZGVyLiBPdGhlcndpc2UsXG4gICAgICogc3BlY2lmeSBhbiBvcmRlciBvZiBcImRlc2NcIiBmb3IgZGVzY2VuZGluZyBvciBcImFzY1wiIGZvciBhc2NlbmRpbmcgc29ydCBvcmRlclxuICAgICAqIG9mIGNvcnJlc3BvbmRpbmcgdmFsdWVzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gY29tcGFyZS5cbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb3RoZXIgVGhlIG90aGVyIG9iamVjdCB0byBjb21wYXJlLlxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbltdfHN0cmluZ1tdfSBvcmRlcnMgVGhlIG9yZGVyIHRvIHNvcnQgYnkgZm9yIGVhY2ggcHJvcGVydHkuXG4gICAgICogQHJldHVybnMge251bWJlcn0gUmV0dXJucyB0aGUgc29ydCBvcmRlciBpbmRpY2F0b3IgZm9yIGBvYmplY3RgLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGNvbXBhcmVNdWx0aXBsZShvYmplY3QsIG90aGVyLCBvcmRlcnMpIHtcbiAgICAgIHZhciBpbmRleCA9IC0xLFxuICAgICAgICAgIG9iakNyaXRlcmlhID0gb2JqZWN0LmNyaXRlcmlhLFxuICAgICAgICAgIG90aENyaXRlcmlhID0gb3RoZXIuY3JpdGVyaWEsXG4gICAgICAgICAgbGVuZ3RoID0gb2JqQ3JpdGVyaWEubGVuZ3RoLFxuICAgICAgICAgIG9yZGVyc0xlbmd0aCA9IG9yZGVycy5sZW5ndGg7XG5cbiAgICAgIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XG4gICAgICAgIHZhciByZXN1bHQgPSBjb21wYXJlQXNjZW5kaW5nKG9iakNyaXRlcmlhW2luZGV4XSwgb3RoQ3JpdGVyaWFbaW5kZXhdKTtcbiAgICAgICAgaWYgKHJlc3VsdCkge1xuICAgICAgICAgIGlmIChpbmRleCA+PSBvcmRlcnNMZW5ndGgpIHtcbiAgICAgICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICAgICAgfVxuICAgICAgICAgIHZhciBvcmRlciA9IG9yZGVyc1tpbmRleF07XG4gICAgICAgICAgcmV0dXJuIHJlc3VsdCAqIChvcmRlciA9PSAnZGVzYycgPyAtMSA6IDEpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICAvLyBGaXhlcyBhbiBgQXJyYXkjc29ydGAgYnVnIGluIHRoZSBKUyBlbmdpbmUgZW1iZWRkZWQgaW4gQWRvYmUgYXBwbGljYXRpb25zXG4gICAgICAvLyB0aGF0IGNhdXNlcyBpdCwgdW5kZXIgY2VydGFpbiBjaXJjdW1zdGFuY2VzLCB0byBwcm92aWRlIHRoZSBzYW1lIHZhbHVlIGZvclxuICAgICAgLy8gYG9iamVjdGAgYW5kIGBvdGhlcmAuIFNlZSBodHRwczovL2dpdGh1Yi5jb20vamFzaGtlbmFzL3VuZGVyc2NvcmUvcHVsbC8xMjQ3XG4gICAgICAvLyBmb3IgbW9yZSBkZXRhaWxzLlxuICAgICAgLy9cbiAgICAgIC8vIFRoaXMgYWxzbyBlbnN1cmVzIGEgc3RhYmxlIHNvcnQgaW4gVjggYW5kIG90aGVyIGVuZ2luZXMuXG4gICAgICAvLyBTZWUgaHR0cHM6Ly9idWdzLmNocm9taXVtLm9yZy9wL3Y4L2lzc3Vlcy9kZXRhaWw/aWQ9OTAgZm9yIG1vcmUgZGV0YWlscy5cbiAgICAgIHJldHVybiBvYmplY3QuaW5kZXggLSBvdGhlci5pbmRleDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGFuIGFycmF5IHRoYXQgaXMgdGhlIGNvbXBvc2l0aW9uIG9mIHBhcnRpYWxseSBhcHBsaWVkIGFyZ3VtZW50cyxcbiAgICAgKiBwbGFjZWhvbGRlcnMsIGFuZCBwcm92aWRlZCBhcmd1bWVudHMgaW50byBhIHNpbmdsZSBhcnJheSBvZiBhcmd1bWVudHMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGFyZ3MgVGhlIHByb3ZpZGVkIGFyZ3VtZW50cy5cbiAgICAgKiBAcGFyYW0ge0FycmF5fSBwYXJ0aWFscyBUaGUgYXJndW1lbnRzIHRvIHByZXBlbmQgdG8gdGhvc2UgcHJvdmlkZWQuXG4gICAgICogQHBhcmFtIHtBcnJheX0gaG9sZGVycyBUaGUgYHBhcnRpYWxzYCBwbGFjZWhvbGRlciBpbmRleGVzLlxuICAgICAqIEBwYXJhbXMge2Jvb2xlYW59IFtpc0N1cnJpZWRdIFNwZWNpZnkgY29tcG9zaW5nIGZvciBhIGN1cnJpZWQgZnVuY3Rpb24uXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBuZXcgYXJyYXkgb2YgY29tcG9zZWQgYXJndW1lbnRzLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGNvbXBvc2VBcmdzKGFyZ3MsIHBhcnRpYWxzLCBob2xkZXJzLCBpc0N1cnJpZWQpIHtcbiAgICAgIHZhciBhcmdzSW5kZXggPSAtMSxcbiAgICAgICAgICBhcmdzTGVuZ3RoID0gYXJncy5sZW5ndGgsXG4gICAgICAgICAgaG9sZGVyc0xlbmd0aCA9IGhvbGRlcnMubGVuZ3RoLFxuICAgICAgICAgIGxlZnRJbmRleCA9IC0xLFxuICAgICAgICAgIGxlZnRMZW5ndGggPSBwYXJ0aWFscy5sZW5ndGgsXG4gICAgICAgICAgcmFuZ2VMZW5ndGggPSBuYXRpdmVNYXgoYXJnc0xlbmd0aCAtIGhvbGRlcnNMZW5ndGgsIDApLFxuICAgICAgICAgIHJlc3VsdCA9IEFycmF5KGxlZnRMZW5ndGggKyByYW5nZUxlbmd0aCksXG4gICAgICAgICAgaXNVbmN1cnJpZWQgPSAhaXNDdXJyaWVkO1xuXG4gICAgICB3aGlsZSAoKytsZWZ0SW5kZXggPCBsZWZ0TGVuZ3RoKSB7XG4gICAgICAgIHJlc3VsdFtsZWZ0SW5kZXhdID0gcGFydGlhbHNbbGVmdEluZGV4XTtcbiAgICAgIH1cbiAgICAgIHdoaWxlICgrK2FyZ3NJbmRleCA8IGhvbGRlcnNMZW5ndGgpIHtcbiAgICAgICAgaWYgKGlzVW5jdXJyaWVkIHx8IGFyZ3NJbmRleCA8IGFyZ3NMZW5ndGgpIHtcbiAgICAgICAgICByZXN1bHRbaG9sZGVyc1thcmdzSW5kZXhdXSA9IGFyZ3NbYXJnc0luZGV4XTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgd2hpbGUgKHJhbmdlTGVuZ3RoLS0pIHtcbiAgICAgICAgcmVzdWx0W2xlZnRJbmRleCsrXSA9IGFyZ3NbYXJnc0luZGV4KytdO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIGZ1bmN0aW9uIGlzIGxpa2UgYGNvbXBvc2VBcmdzYCBleGNlcHQgdGhhdCB0aGUgYXJndW1lbnRzIGNvbXBvc2l0aW9uXG4gICAgICogaXMgdGFpbG9yZWQgZm9yIGBfLnBhcnRpYWxSaWdodGAuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGFyZ3MgVGhlIHByb3ZpZGVkIGFyZ3VtZW50cy5cbiAgICAgKiBAcGFyYW0ge0FycmF5fSBwYXJ0aWFscyBUaGUgYXJndW1lbnRzIHRvIGFwcGVuZCB0byB0aG9zZSBwcm92aWRlZC5cbiAgICAgKiBAcGFyYW0ge0FycmF5fSBob2xkZXJzIFRoZSBgcGFydGlhbHNgIHBsYWNlaG9sZGVyIGluZGV4ZXMuXG4gICAgICogQHBhcmFtcyB7Ym9vbGVhbn0gW2lzQ3VycmllZF0gU3BlY2lmeSBjb21wb3NpbmcgZm9yIGEgY3VycmllZCBmdW5jdGlvbi5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIG5ldyBhcnJheSBvZiBjb21wb3NlZCBhcmd1bWVudHMuXG4gICAgICovXG4gICAgZnVuY3Rpb24gY29tcG9zZUFyZ3NSaWdodChhcmdzLCBwYXJ0aWFscywgaG9sZGVycywgaXNDdXJyaWVkKSB7XG4gICAgICB2YXIgYXJnc0luZGV4ID0gLTEsXG4gICAgICAgICAgYXJnc0xlbmd0aCA9IGFyZ3MubGVuZ3RoLFxuICAgICAgICAgIGhvbGRlcnNJbmRleCA9IC0xLFxuICAgICAgICAgIGhvbGRlcnNMZW5ndGggPSBob2xkZXJzLmxlbmd0aCxcbiAgICAgICAgICByaWdodEluZGV4ID0gLTEsXG4gICAgICAgICAgcmlnaHRMZW5ndGggPSBwYXJ0aWFscy5sZW5ndGgsXG4gICAgICAgICAgcmFuZ2VMZW5ndGggPSBuYXRpdmVNYXgoYXJnc0xlbmd0aCAtIGhvbGRlcnNMZW5ndGgsIDApLFxuICAgICAgICAgIHJlc3VsdCA9IEFycmF5KHJhbmdlTGVuZ3RoICsgcmlnaHRMZW5ndGgpLFxuICAgICAgICAgIGlzVW5jdXJyaWVkID0gIWlzQ3VycmllZDtcblxuICAgICAgd2hpbGUgKCsrYXJnc0luZGV4IDwgcmFuZ2VMZW5ndGgpIHtcbiAgICAgICAgcmVzdWx0W2FyZ3NJbmRleF0gPSBhcmdzW2FyZ3NJbmRleF07XG4gICAgICB9XG4gICAgICB2YXIgb2Zmc2V0ID0gYXJnc0luZGV4O1xuICAgICAgd2hpbGUgKCsrcmlnaHRJbmRleCA8IHJpZ2h0TGVuZ3RoKSB7XG4gICAgICAgIHJlc3VsdFtvZmZzZXQgKyByaWdodEluZGV4XSA9IHBhcnRpYWxzW3JpZ2h0SW5kZXhdO1xuICAgICAgfVxuICAgICAgd2hpbGUgKCsraG9sZGVyc0luZGV4IDwgaG9sZGVyc0xlbmd0aCkge1xuICAgICAgICBpZiAoaXNVbmN1cnJpZWQgfHwgYXJnc0luZGV4IDwgYXJnc0xlbmd0aCkge1xuICAgICAgICAgIHJlc3VsdFtvZmZzZXQgKyBob2xkZXJzW2hvbGRlcnNJbmRleF1dID0gYXJnc1thcmdzSW5kZXgrK107XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ29waWVzIHRoZSB2YWx1ZXMgb2YgYHNvdXJjZWAgdG8gYGFycmF5YC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtBcnJheX0gc291cmNlIFRoZSBhcnJheSB0byBjb3B5IHZhbHVlcyBmcm9tLlxuICAgICAqIEBwYXJhbSB7QXJyYXl9IFthcnJheT1bXV0gVGhlIGFycmF5IHRvIGNvcHkgdmFsdWVzIHRvLlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyBgYXJyYXlgLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGNvcHlBcnJheShzb3VyY2UsIGFycmF5KSB7XG4gICAgICB2YXIgaW5kZXggPSAtMSxcbiAgICAgICAgICBsZW5ndGggPSBzb3VyY2UubGVuZ3RoO1xuXG4gICAgICBhcnJheSB8fCAoYXJyYXkgPSBBcnJheShsZW5ndGgpKTtcbiAgICAgIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XG4gICAgICAgIGFycmF5W2luZGV4XSA9IHNvdXJjZVtpbmRleF07XG4gICAgICB9XG4gICAgICByZXR1cm4gYXJyYXk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ29waWVzIHByb3BlcnRpZXMgb2YgYHNvdXJjZWAgdG8gYG9iamVjdGAuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBzb3VyY2UgVGhlIG9iamVjdCB0byBjb3B5IHByb3BlcnRpZXMgZnJvbS5cbiAgICAgKiBAcGFyYW0ge0FycmF5fSBwcm9wcyBUaGUgcHJvcGVydHkgaWRlbnRpZmllcnMgdG8gY29weS5cbiAgICAgKiBAcGFyYW0ge09iamVjdH0gW29iamVjdD17fV0gVGhlIG9iamVjdCB0byBjb3B5IHByb3BlcnRpZXMgdG8uXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW2N1c3RvbWl6ZXJdIFRoZSBmdW5jdGlvbiB0byBjdXN0b21pemUgY29waWVkIHZhbHVlcy5cbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIGBvYmplY3RgLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGNvcHlPYmplY3Qoc291cmNlLCBwcm9wcywgb2JqZWN0LCBjdXN0b21pemVyKSB7XG4gICAgICB2YXIgaXNOZXcgPSAhb2JqZWN0O1xuICAgICAgb2JqZWN0IHx8IChvYmplY3QgPSB7fSk7XG5cbiAgICAgIHZhciBpbmRleCA9IC0xLFxuICAgICAgICAgIGxlbmd0aCA9IHByb3BzLmxlbmd0aDtcblxuICAgICAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHtcbiAgICAgICAgdmFyIGtleSA9IHByb3BzW2luZGV4XTtcblxuICAgICAgICB2YXIgbmV3VmFsdWUgPSBjdXN0b21pemVyXG4gICAgICAgICAgPyBjdXN0b21pemVyKG9iamVjdFtrZXldLCBzb3VyY2Vba2V5XSwga2V5LCBvYmplY3QsIHNvdXJjZSlcbiAgICAgICAgICA6IHVuZGVmaW5lZDtcblxuICAgICAgICBpZiAobmV3VmFsdWUgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIG5ld1ZhbHVlID0gc291cmNlW2tleV07XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGlzTmV3KSB7XG4gICAgICAgICAgYmFzZUFzc2lnblZhbHVlKG9iamVjdCwga2V5LCBuZXdWYWx1ZSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgYXNzaWduVmFsdWUob2JqZWN0LCBrZXksIG5ld1ZhbHVlKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIG9iamVjdDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDb3BpZXMgb3duIHN5bWJvbHMgb2YgYHNvdXJjZWAgdG8gYG9iamVjdGAuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBzb3VyY2UgVGhlIG9iamVjdCB0byBjb3B5IHN5bWJvbHMgZnJvbS5cbiAgICAgKiBAcGFyYW0ge09iamVjdH0gW29iamVjdD17fV0gVGhlIG9iamVjdCB0byBjb3B5IHN5bWJvbHMgdG8uXG4gICAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyBgb2JqZWN0YC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBjb3B5U3ltYm9scyhzb3VyY2UsIG9iamVjdCkge1xuICAgICAgcmV0dXJuIGNvcHlPYmplY3Qoc291cmNlLCBnZXRTeW1ib2xzKHNvdXJjZSksIG9iamVjdCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ29waWVzIG93biBhbmQgaW5oZXJpdGVkIHN5bWJvbHMgb2YgYHNvdXJjZWAgdG8gYG9iamVjdGAuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBzb3VyY2UgVGhlIG9iamVjdCB0byBjb3B5IHN5bWJvbHMgZnJvbS5cbiAgICAgKiBAcGFyYW0ge09iamVjdH0gW29iamVjdD17fV0gVGhlIG9iamVjdCB0byBjb3B5IHN5bWJvbHMgdG8uXG4gICAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyBgb2JqZWN0YC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBjb3B5U3ltYm9sc0luKHNvdXJjZSwgb2JqZWN0KSB7XG4gICAgICByZXR1cm4gY29weU9iamVjdChzb3VyY2UsIGdldFN5bWJvbHNJbihzb3VyY2UpLCBvYmplY3QpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBmdW5jdGlvbiBsaWtlIGBfLmdyb3VwQnlgLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBzZXR0ZXIgVGhlIGZ1bmN0aW9uIHRvIHNldCBhY2N1bXVsYXRvciB2YWx1ZXMuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW2luaXRpYWxpemVyXSBUaGUgYWNjdW11bGF0b3Igb2JqZWN0IGluaXRpYWxpemVyLlxuICAgICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IGFnZ3JlZ2F0b3IgZnVuY3Rpb24uXG4gICAgICovXG4gICAgZnVuY3Rpb24gY3JlYXRlQWdncmVnYXRvcihzZXR0ZXIsIGluaXRpYWxpemVyKSB7XG4gICAgICByZXR1cm4gZnVuY3Rpb24oY29sbGVjdGlvbiwgaXRlcmF0ZWUpIHtcbiAgICAgICAgdmFyIGZ1bmMgPSBpc0FycmF5KGNvbGxlY3Rpb24pID8gYXJyYXlBZ2dyZWdhdG9yIDogYmFzZUFnZ3JlZ2F0b3IsXG4gICAgICAgICAgICBhY2N1bXVsYXRvciA9IGluaXRpYWxpemVyID8gaW5pdGlhbGl6ZXIoKSA6IHt9O1xuXG4gICAgICAgIHJldHVybiBmdW5jKGNvbGxlY3Rpb24sIHNldHRlciwgZ2V0SXRlcmF0ZWUoaXRlcmF0ZWUsIDIpLCBhY2N1bXVsYXRvcik7XG4gICAgICB9O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBmdW5jdGlvbiBsaWtlIGBfLmFzc2lnbmAuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGFzc2lnbmVyIFRoZSBmdW5jdGlvbiB0byBhc3NpZ24gdmFsdWVzLlxuICAgICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IGFzc2lnbmVyIGZ1bmN0aW9uLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGNyZWF0ZUFzc2lnbmVyKGFzc2lnbmVyKSB7XG4gICAgICByZXR1cm4gYmFzZVJlc3QoZnVuY3Rpb24ob2JqZWN0LCBzb3VyY2VzKSB7XG4gICAgICAgIHZhciBpbmRleCA9IC0xLFxuICAgICAgICAgICAgbGVuZ3RoID0gc291cmNlcy5sZW5ndGgsXG4gICAgICAgICAgICBjdXN0b21pemVyID0gbGVuZ3RoID4gMSA/IHNvdXJjZXNbbGVuZ3RoIC0gMV0gOiB1bmRlZmluZWQsXG4gICAgICAgICAgICBndWFyZCA9IGxlbmd0aCA+IDIgPyBzb3VyY2VzWzJdIDogdW5kZWZpbmVkO1xuXG4gICAgICAgIGN1c3RvbWl6ZXIgPSAoYXNzaWduZXIubGVuZ3RoID4gMyAmJiB0eXBlb2YgY3VzdG9taXplciA9PSAnZnVuY3Rpb24nKVxuICAgICAgICAgID8gKGxlbmd0aC0tLCBjdXN0b21pemVyKVxuICAgICAgICAgIDogdW5kZWZpbmVkO1xuXG4gICAgICAgIGlmIChndWFyZCAmJiBpc0l0ZXJhdGVlQ2FsbChzb3VyY2VzWzBdLCBzb3VyY2VzWzFdLCBndWFyZCkpIHtcbiAgICAgICAgICBjdXN0b21pemVyID0gbGVuZ3RoIDwgMyA/IHVuZGVmaW5lZCA6IGN1c3RvbWl6ZXI7XG4gICAgICAgICAgbGVuZ3RoID0gMTtcbiAgICAgICAgfVxuICAgICAgICBvYmplY3QgPSBPYmplY3Qob2JqZWN0KTtcbiAgICAgICAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHtcbiAgICAgICAgICB2YXIgc291cmNlID0gc291cmNlc1tpbmRleF07XG4gICAgICAgICAgaWYgKHNvdXJjZSkge1xuICAgICAgICAgICAgYXNzaWduZXIob2JqZWN0LCBzb3VyY2UsIGluZGV4LCBjdXN0b21pemVyKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG9iamVjdDtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBgYmFzZUVhY2hgIG9yIGBiYXNlRWFjaFJpZ2h0YCBmdW5jdGlvbi5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gZWFjaEZ1bmMgVGhlIGZ1bmN0aW9uIHRvIGl0ZXJhdGUgb3ZlciBhIGNvbGxlY3Rpb24uXG4gICAgICogQHBhcmFtIHtib29sZWFufSBbZnJvbVJpZ2h0XSBTcGVjaWZ5IGl0ZXJhdGluZyBmcm9tIHJpZ2h0IHRvIGxlZnQuXG4gICAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgYmFzZSBmdW5jdGlvbi5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBjcmVhdGVCYXNlRWFjaChlYWNoRnVuYywgZnJvbVJpZ2h0KSB7XG4gICAgICByZXR1cm4gZnVuY3Rpb24oY29sbGVjdGlvbiwgaXRlcmF0ZWUpIHtcbiAgICAgICAgaWYgKGNvbGxlY3Rpb24gPT0gbnVsbCkge1xuICAgICAgICAgIHJldHVybiBjb2xsZWN0aW9uO1xuICAgICAgICB9XG4gICAgICAgIGlmICghaXNBcnJheUxpa2UoY29sbGVjdGlvbikpIHtcbiAgICAgICAgICByZXR1cm4gZWFjaEZ1bmMoY29sbGVjdGlvbiwgaXRlcmF0ZWUpO1xuICAgICAgICB9XG4gICAgICAgIHZhciBsZW5ndGggPSBjb2xsZWN0aW9uLmxlbmd0aCxcbiAgICAgICAgICAgIGluZGV4ID0gZnJvbVJpZ2h0ID8gbGVuZ3RoIDogLTEsXG4gICAgICAgICAgICBpdGVyYWJsZSA9IE9iamVjdChjb2xsZWN0aW9uKTtcblxuICAgICAgICB3aGlsZSAoKGZyb21SaWdodCA/IGluZGV4LS0gOiArK2luZGV4IDwgbGVuZ3RoKSkge1xuICAgICAgICAgIGlmIChpdGVyYXRlZShpdGVyYWJsZVtpbmRleF0sIGluZGV4LCBpdGVyYWJsZSkgPT09IGZhbHNlKSB7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGNvbGxlY3Rpb247XG4gICAgICB9O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBiYXNlIGZ1bmN0aW9uIGZvciBtZXRob2RzIGxpa2UgYF8uZm9ySW5gIGFuZCBgXy5mb3JPd25gLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW59IFtmcm9tUmlnaHRdIFNwZWNpZnkgaXRlcmF0aW5nIGZyb20gcmlnaHQgdG8gbGVmdC5cbiAgICAgKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBiYXNlIGZ1bmN0aW9uLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGNyZWF0ZUJhc2VGb3IoZnJvbVJpZ2h0KSB7XG4gICAgICByZXR1cm4gZnVuY3Rpb24ob2JqZWN0LCBpdGVyYXRlZSwga2V5c0Z1bmMpIHtcbiAgICAgICAgdmFyIGluZGV4ID0gLTEsXG4gICAgICAgICAgICBpdGVyYWJsZSA9IE9iamVjdChvYmplY3QpLFxuICAgICAgICAgICAgcHJvcHMgPSBrZXlzRnVuYyhvYmplY3QpLFxuICAgICAgICAgICAgbGVuZ3RoID0gcHJvcHMubGVuZ3RoO1xuXG4gICAgICAgIHdoaWxlIChsZW5ndGgtLSkge1xuICAgICAgICAgIHZhciBrZXkgPSBwcm9wc1tmcm9tUmlnaHQgPyBsZW5ndGggOiArK2luZGV4XTtcbiAgICAgICAgICBpZiAoaXRlcmF0ZWUoaXRlcmFibGVba2V5XSwga2V5LCBpdGVyYWJsZSkgPT09IGZhbHNlKSB7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG9iamVjdDtcbiAgICAgIH07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIGZ1bmN0aW9uIHRoYXQgd3JhcHMgYGZ1bmNgIHRvIGludm9rZSBpdCB3aXRoIHRoZSBvcHRpb25hbCBgdGhpc2BcbiAgICAgKiBiaW5kaW5nIG9mIGB0aGlzQXJnYC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gZnVuYyBUaGUgZnVuY3Rpb24gdG8gd3JhcC5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gYml0bWFzayBUaGUgYml0bWFzayBmbGFncy4gU2VlIGBjcmVhdGVXcmFwYCBmb3IgbW9yZSBkZXRhaWxzLlxuICAgICAqIEBwYXJhbSB7Kn0gW3RoaXNBcmddIFRoZSBgdGhpc2AgYmluZGluZyBvZiBgZnVuY2AuXG4gICAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgd3JhcHBlZCBmdW5jdGlvbi5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBjcmVhdGVCaW5kKGZ1bmMsIGJpdG1hc2ssIHRoaXNBcmcpIHtcbiAgICAgIHZhciBpc0JpbmQgPSBiaXRtYXNrICYgV1JBUF9CSU5EX0ZMQUcsXG4gICAgICAgICAgQ3RvciA9IGNyZWF0ZUN0b3IoZnVuYyk7XG5cbiAgICAgIGZ1bmN0aW9uIHdyYXBwZXIoKSB7XG4gICAgICAgIHZhciBmbiA9ICh0aGlzICYmIHRoaXMgIT09IHJvb3QgJiYgdGhpcyBpbnN0YW5jZW9mIHdyYXBwZXIpID8gQ3RvciA6IGZ1bmM7XG4gICAgICAgIHJldHVybiBmbi5hcHBseShpc0JpbmQgPyB0aGlzQXJnIDogdGhpcywgYXJndW1lbnRzKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiB3cmFwcGVyO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBmdW5jdGlvbiBsaWtlIGBfLmxvd2VyRmlyc3RgLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gbWV0aG9kTmFtZSBUaGUgbmFtZSBvZiB0aGUgYFN0cmluZ2AgY2FzZSBtZXRob2QgdG8gdXNlLlxuICAgICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IGNhc2UgZnVuY3Rpb24uXG4gICAgICovXG4gICAgZnVuY3Rpb24gY3JlYXRlQ2FzZUZpcnN0KG1ldGhvZE5hbWUpIHtcbiAgICAgIHJldHVybiBmdW5jdGlvbihzdHJpbmcpIHtcbiAgICAgICAgc3RyaW5nID0gdG9TdHJpbmcoc3RyaW5nKTtcblxuICAgICAgICB2YXIgc3RyU3ltYm9scyA9IGhhc1VuaWNvZGUoc3RyaW5nKVxuICAgICAgICAgID8gc3RyaW5nVG9BcnJheShzdHJpbmcpXG4gICAgICAgICAgOiB1bmRlZmluZWQ7XG5cbiAgICAgICAgdmFyIGNociA9IHN0clN5bWJvbHNcbiAgICAgICAgICA/IHN0clN5bWJvbHNbMF1cbiAgICAgICAgICA6IHN0cmluZy5jaGFyQXQoMCk7XG5cbiAgICAgICAgdmFyIHRyYWlsaW5nID0gc3RyU3ltYm9sc1xuICAgICAgICAgID8gY2FzdFNsaWNlKHN0clN5bWJvbHMsIDEpLmpvaW4oJycpXG4gICAgICAgICAgOiBzdHJpbmcuc2xpY2UoMSk7XG5cbiAgICAgICAgcmV0dXJuIGNoclttZXRob2ROYW1lXSgpICsgdHJhaWxpbmc7XG4gICAgICB9O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBmdW5jdGlvbiBsaWtlIGBfLmNhbWVsQ2FzZWAuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGNhbGxiYWNrIFRoZSBmdW5jdGlvbiB0byBjb21iaW5lIGVhY2ggd29yZC5cbiAgICAgKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBjb21wb3VuZGVyIGZ1bmN0aW9uLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGNyZWF0ZUNvbXBvdW5kZXIoY2FsbGJhY2spIHtcbiAgICAgIHJldHVybiBmdW5jdGlvbihzdHJpbmcpIHtcbiAgICAgICAgcmV0dXJuIGFycmF5UmVkdWNlKHdvcmRzKGRlYnVycihzdHJpbmcpLnJlcGxhY2UocmVBcG9zLCAnJykpLCBjYWxsYmFjaywgJycpO1xuICAgICAgfTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgZnVuY3Rpb24gdGhhdCBwcm9kdWNlcyBhbiBpbnN0YW5jZSBvZiBgQ3RvcmAgcmVnYXJkbGVzcyBvZlxuICAgICAqIHdoZXRoZXIgaXQgd2FzIGludm9rZWQgYXMgcGFydCBvZiBhIGBuZXdgIGV4cHJlc3Npb24gb3IgYnkgYGNhbGxgIG9yIGBhcHBseWAuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IEN0b3IgVGhlIGNvbnN0cnVjdG9yIHRvIHdyYXAuXG4gICAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgd3JhcHBlZCBmdW5jdGlvbi5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBjcmVhdGVDdG9yKEN0b3IpIHtcbiAgICAgIHJldHVybiBmdW5jdGlvbigpIHtcbiAgICAgICAgLy8gVXNlIGEgYHN3aXRjaGAgc3RhdGVtZW50IHRvIHdvcmsgd2l0aCBjbGFzcyBjb25zdHJ1Y3RvcnMuIFNlZVxuICAgICAgICAvLyBodHRwOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi83LjAvI3NlYy1lY21hc2NyaXB0LWZ1bmN0aW9uLW9iamVjdHMtY2FsbC10aGlzYXJndW1lbnQtYXJndW1lbnRzbGlzdFxuICAgICAgICAvLyBmb3IgbW9yZSBkZXRhaWxzLlxuICAgICAgICB2YXIgYXJncyA9IGFyZ3VtZW50cztcbiAgICAgICAgc3dpdGNoIChhcmdzLmxlbmd0aCkge1xuICAgICAgICAgIGNhc2UgMDogcmV0dXJuIG5ldyBDdG9yO1xuICAgICAgICAgIGNhc2UgMTogcmV0dXJuIG5ldyBDdG9yKGFyZ3NbMF0pO1xuICAgICAgICAgIGNhc2UgMjogcmV0dXJuIG5ldyBDdG9yKGFyZ3NbMF0sIGFyZ3NbMV0pO1xuICAgICAgICAgIGNhc2UgMzogcmV0dXJuIG5ldyBDdG9yKGFyZ3NbMF0sIGFyZ3NbMV0sIGFyZ3NbMl0pO1xuICAgICAgICAgIGNhc2UgNDogcmV0dXJuIG5ldyBDdG9yKGFyZ3NbMF0sIGFyZ3NbMV0sIGFyZ3NbMl0sIGFyZ3NbM10pO1xuICAgICAgICAgIGNhc2UgNTogcmV0dXJuIG5ldyBDdG9yKGFyZ3NbMF0sIGFyZ3NbMV0sIGFyZ3NbMl0sIGFyZ3NbM10sIGFyZ3NbNF0pO1xuICAgICAgICAgIGNhc2UgNjogcmV0dXJuIG5ldyBDdG9yKGFyZ3NbMF0sIGFyZ3NbMV0sIGFyZ3NbMl0sIGFyZ3NbM10sIGFyZ3NbNF0sIGFyZ3NbNV0pO1xuICAgICAgICAgIGNhc2UgNzogcmV0dXJuIG5ldyBDdG9yKGFyZ3NbMF0sIGFyZ3NbMV0sIGFyZ3NbMl0sIGFyZ3NbM10sIGFyZ3NbNF0sIGFyZ3NbNV0sIGFyZ3NbNl0pO1xuICAgICAgICB9XG4gICAgICAgIHZhciB0aGlzQmluZGluZyA9IGJhc2VDcmVhdGUoQ3Rvci5wcm90b3R5cGUpLFxuICAgICAgICAgICAgcmVzdWx0ID0gQ3Rvci5hcHBseSh0aGlzQmluZGluZywgYXJncyk7XG5cbiAgICAgICAgLy8gTWltaWMgdGhlIGNvbnN0cnVjdG9yJ3MgYHJldHVybmAgYmVoYXZpb3IuXG4gICAgICAgIC8vIFNlZSBodHRwczovL2VzNS5naXRodWIuaW8vI3gxMy4yLjIgZm9yIG1vcmUgZGV0YWlscy5cbiAgICAgICAgcmV0dXJuIGlzT2JqZWN0KHJlc3VsdCkgPyByZXN1bHQgOiB0aGlzQmluZGluZztcbiAgICAgIH07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIGZ1bmN0aW9uIHRoYXQgd3JhcHMgYGZ1bmNgIHRvIGVuYWJsZSBjdXJyeWluZy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gZnVuYyBUaGUgZnVuY3Rpb24gdG8gd3JhcC5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gYml0bWFzayBUaGUgYml0bWFzayBmbGFncy4gU2VlIGBjcmVhdGVXcmFwYCBmb3IgbW9yZSBkZXRhaWxzLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBhcml0eSBUaGUgYXJpdHkgb2YgYGZ1bmNgLlxuICAgICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IHdyYXBwZWQgZnVuY3Rpb24uXG4gICAgICovXG4gICAgZnVuY3Rpb24gY3JlYXRlQ3VycnkoZnVuYywgYml0bWFzaywgYXJpdHkpIHtcbiAgICAgIHZhciBDdG9yID0gY3JlYXRlQ3RvcihmdW5jKTtcblxuICAgICAgZnVuY3Rpb24gd3JhcHBlcigpIHtcbiAgICAgICAgdmFyIGxlbmd0aCA9IGFyZ3VtZW50cy5sZW5ndGgsXG4gICAgICAgICAgICBhcmdzID0gQXJyYXkobGVuZ3RoKSxcbiAgICAgICAgICAgIGluZGV4ID0gbGVuZ3RoLFxuICAgICAgICAgICAgcGxhY2Vob2xkZXIgPSBnZXRIb2xkZXIod3JhcHBlcik7XG5cbiAgICAgICAgd2hpbGUgKGluZGV4LS0pIHtcbiAgICAgICAgICBhcmdzW2luZGV4XSA9IGFyZ3VtZW50c1tpbmRleF07XG4gICAgICAgIH1cbiAgICAgICAgdmFyIGhvbGRlcnMgPSAobGVuZ3RoIDwgMyAmJiBhcmdzWzBdICE9PSBwbGFjZWhvbGRlciAmJiBhcmdzW2xlbmd0aCAtIDFdICE9PSBwbGFjZWhvbGRlcilcbiAgICAgICAgICA/IFtdXG4gICAgICAgICAgOiByZXBsYWNlSG9sZGVycyhhcmdzLCBwbGFjZWhvbGRlcik7XG5cbiAgICAgICAgbGVuZ3RoIC09IGhvbGRlcnMubGVuZ3RoO1xuICAgICAgICBpZiAobGVuZ3RoIDwgYXJpdHkpIHtcbiAgICAgICAgICByZXR1cm4gY3JlYXRlUmVjdXJyeShcbiAgICAgICAgICAgIGZ1bmMsIGJpdG1hc2ssIGNyZWF0ZUh5YnJpZCwgd3JhcHBlci5wbGFjZWhvbGRlciwgdW5kZWZpbmVkLFxuICAgICAgICAgICAgYXJncywgaG9sZGVycywgdW5kZWZpbmVkLCB1bmRlZmluZWQsIGFyaXR5IC0gbGVuZ3RoKTtcbiAgICAgICAgfVxuICAgICAgICB2YXIgZm4gPSAodGhpcyAmJiB0aGlzICE9PSByb290ICYmIHRoaXMgaW5zdGFuY2VvZiB3cmFwcGVyKSA/IEN0b3IgOiBmdW5jO1xuICAgICAgICByZXR1cm4gYXBwbHkoZm4sIHRoaXMsIGFyZ3MpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHdyYXBwZXI7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIGBfLmZpbmRgIG9yIGBfLmZpbmRMYXN0YCBmdW5jdGlvbi5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gZmluZEluZGV4RnVuYyBUaGUgZnVuY3Rpb24gdG8gZmluZCB0aGUgY29sbGVjdGlvbiBpbmRleC5cbiAgICAgKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBmaW5kIGZ1bmN0aW9uLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGNyZWF0ZUZpbmQoZmluZEluZGV4RnVuYykge1xuICAgICAgcmV0dXJuIGZ1bmN0aW9uKGNvbGxlY3Rpb24sIHByZWRpY2F0ZSwgZnJvbUluZGV4KSB7XG4gICAgICAgIHZhciBpdGVyYWJsZSA9IE9iamVjdChjb2xsZWN0aW9uKTtcbiAgICAgICAgaWYgKCFpc0FycmF5TGlrZShjb2xsZWN0aW9uKSkge1xuICAgICAgICAgIHZhciBpdGVyYXRlZSA9IGdldEl0ZXJhdGVlKHByZWRpY2F0ZSwgMyk7XG4gICAgICAgICAgY29sbGVjdGlvbiA9IGtleXMoY29sbGVjdGlvbik7XG4gICAgICAgICAgcHJlZGljYXRlID0gZnVuY3Rpb24oa2V5KSB7IHJldHVybiBpdGVyYXRlZShpdGVyYWJsZVtrZXldLCBrZXksIGl0ZXJhYmxlKTsgfTtcbiAgICAgICAgfVxuICAgICAgICB2YXIgaW5kZXggPSBmaW5kSW5kZXhGdW5jKGNvbGxlY3Rpb24sIHByZWRpY2F0ZSwgZnJvbUluZGV4KTtcbiAgICAgICAgcmV0dXJuIGluZGV4ID4gLTEgPyBpdGVyYWJsZVtpdGVyYXRlZSA/IGNvbGxlY3Rpb25baW5kZXhdIDogaW5kZXhdIDogdW5kZWZpbmVkO1xuICAgICAgfTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgYF8uZmxvd2Agb3IgYF8uZmxvd1JpZ2h0YCBmdW5jdGlvbi5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtib29sZWFufSBbZnJvbVJpZ2h0XSBTcGVjaWZ5IGl0ZXJhdGluZyBmcm9tIHJpZ2h0IHRvIGxlZnQuXG4gICAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgZmxvdyBmdW5jdGlvbi5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBjcmVhdGVGbG93KGZyb21SaWdodCkge1xuICAgICAgcmV0dXJuIGZsYXRSZXN0KGZ1bmN0aW9uKGZ1bmNzKSB7XG4gICAgICAgIHZhciBsZW5ndGggPSBmdW5jcy5sZW5ndGgsXG4gICAgICAgICAgICBpbmRleCA9IGxlbmd0aCxcbiAgICAgICAgICAgIHByZXJlcSA9IExvZGFzaFdyYXBwZXIucHJvdG90eXBlLnRocnU7XG5cbiAgICAgICAgaWYgKGZyb21SaWdodCkge1xuICAgICAgICAgIGZ1bmNzLnJldmVyc2UoKTtcbiAgICAgICAgfVxuICAgICAgICB3aGlsZSAoaW5kZXgtLSkge1xuICAgICAgICAgIHZhciBmdW5jID0gZnVuY3NbaW5kZXhdO1xuICAgICAgICAgIGlmICh0eXBlb2YgZnVuYyAhPSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKEZVTkNfRVJST1JfVEVYVCk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmIChwcmVyZXEgJiYgIXdyYXBwZXIgJiYgZ2V0RnVuY05hbWUoZnVuYykgPT0gJ3dyYXBwZXInKSB7XG4gICAgICAgICAgICB2YXIgd3JhcHBlciA9IG5ldyBMb2Rhc2hXcmFwcGVyKFtdLCB0cnVlKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaW5kZXggPSB3cmFwcGVyID8gaW5kZXggOiBsZW5ndGg7XG4gICAgICAgIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XG4gICAgICAgICAgZnVuYyA9IGZ1bmNzW2luZGV4XTtcblxuICAgICAgICAgIHZhciBmdW5jTmFtZSA9IGdldEZ1bmNOYW1lKGZ1bmMpLFxuICAgICAgICAgICAgICBkYXRhID0gZnVuY05hbWUgPT0gJ3dyYXBwZXInID8gZ2V0RGF0YShmdW5jKSA6IHVuZGVmaW5lZDtcblxuICAgICAgICAgIGlmIChkYXRhICYmIGlzTGF6aWFibGUoZGF0YVswXSkgJiZcbiAgICAgICAgICAgICAgICBkYXRhWzFdID09IChXUkFQX0FSWV9GTEFHIHwgV1JBUF9DVVJSWV9GTEFHIHwgV1JBUF9QQVJUSUFMX0ZMQUcgfCBXUkFQX1JFQVJHX0ZMQUcpICYmXG4gICAgICAgICAgICAgICAgIWRhdGFbNF0ubGVuZ3RoICYmIGRhdGFbOV0gPT0gMVxuICAgICAgICAgICAgICApIHtcbiAgICAgICAgICAgIHdyYXBwZXIgPSB3cmFwcGVyW2dldEZ1bmNOYW1lKGRhdGFbMF0pXS5hcHBseSh3cmFwcGVyLCBkYXRhWzNdKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgd3JhcHBlciA9IChmdW5jLmxlbmd0aCA9PSAxICYmIGlzTGF6aWFibGUoZnVuYykpXG4gICAgICAgICAgICAgID8gd3JhcHBlcltmdW5jTmFtZV0oKVxuICAgICAgICAgICAgICA6IHdyYXBwZXIudGhydShmdW5jKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgICAgICAgIHZhciBhcmdzID0gYXJndW1lbnRzLFxuICAgICAgICAgICAgICB2YWx1ZSA9IGFyZ3NbMF07XG5cbiAgICAgICAgICBpZiAod3JhcHBlciAmJiBhcmdzLmxlbmd0aCA9PSAxICYmIGlzQXJyYXkodmFsdWUpKSB7XG4gICAgICAgICAgICByZXR1cm4gd3JhcHBlci5wbGFudCh2YWx1ZSkudmFsdWUoKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgdmFyIGluZGV4ID0gMCxcbiAgICAgICAgICAgICAgcmVzdWx0ID0gbGVuZ3RoID8gZnVuY3NbaW5kZXhdLmFwcGx5KHRoaXMsIGFyZ3MpIDogdmFsdWU7XG5cbiAgICAgICAgICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgICAgICAgICAgcmVzdWx0ID0gZnVuY3NbaW5kZXhdLmNhbGwodGhpcywgcmVzdWx0KTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgICAgfTtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBmdW5jdGlvbiB0aGF0IHdyYXBzIGBmdW5jYCB0byBpbnZva2UgaXQgd2l0aCBvcHRpb25hbCBgdGhpc2BcbiAgICAgKiBiaW5kaW5nIG9mIGB0aGlzQXJnYCwgcGFydGlhbCBhcHBsaWNhdGlvbiwgYW5kIGN1cnJ5aW5nLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufHN0cmluZ30gZnVuYyBUaGUgZnVuY3Rpb24gb3IgbWV0aG9kIG5hbWUgdG8gd3JhcC5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gYml0bWFzayBUaGUgYml0bWFzayBmbGFncy4gU2VlIGBjcmVhdGVXcmFwYCBmb3IgbW9yZSBkZXRhaWxzLlxuICAgICAqIEBwYXJhbSB7Kn0gW3RoaXNBcmddIFRoZSBgdGhpc2AgYmluZGluZyBvZiBgZnVuY2AuXG4gICAgICogQHBhcmFtIHtBcnJheX0gW3BhcnRpYWxzXSBUaGUgYXJndW1lbnRzIHRvIHByZXBlbmQgdG8gdGhvc2UgcHJvdmlkZWQgdG9cbiAgICAgKiAgdGhlIG5ldyBmdW5jdGlvbi5cbiAgICAgKiBAcGFyYW0ge0FycmF5fSBbaG9sZGVyc10gVGhlIGBwYXJ0aWFsc2AgcGxhY2Vob2xkZXIgaW5kZXhlcy5cbiAgICAgKiBAcGFyYW0ge0FycmF5fSBbcGFydGlhbHNSaWdodF0gVGhlIGFyZ3VtZW50cyB0byBhcHBlbmQgdG8gdGhvc2UgcHJvdmlkZWRcbiAgICAgKiAgdG8gdGhlIG5ldyBmdW5jdGlvbi5cbiAgICAgKiBAcGFyYW0ge0FycmF5fSBbaG9sZGVyc1JpZ2h0XSBUaGUgYHBhcnRpYWxzUmlnaHRgIHBsYWNlaG9sZGVyIGluZGV4ZXMuXG4gICAgICogQHBhcmFtIHtBcnJheX0gW2FyZ1Bvc10gVGhlIGFyZ3VtZW50IHBvc2l0aW9ucyBvZiB0aGUgbmV3IGZ1bmN0aW9uLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbYXJ5XSBUaGUgYXJpdHkgY2FwIG9mIGBmdW5jYC5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW2FyaXR5XSBUaGUgYXJpdHkgb2YgYGZ1bmNgLlxuICAgICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IHdyYXBwZWQgZnVuY3Rpb24uXG4gICAgICovXG4gICAgZnVuY3Rpb24gY3JlYXRlSHlicmlkKGZ1bmMsIGJpdG1hc2ssIHRoaXNBcmcsIHBhcnRpYWxzLCBob2xkZXJzLCBwYXJ0aWFsc1JpZ2h0LCBob2xkZXJzUmlnaHQsIGFyZ1BvcywgYXJ5LCBhcml0eSkge1xuICAgICAgdmFyIGlzQXJ5ID0gYml0bWFzayAmIFdSQVBfQVJZX0ZMQUcsXG4gICAgICAgICAgaXNCaW5kID0gYml0bWFzayAmIFdSQVBfQklORF9GTEFHLFxuICAgICAgICAgIGlzQmluZEtleSA9IGJpdG1hc2sgJiBXUkFQX0JJTkRfS0VZX0ZMQUcsXG4gICAgICAgICAgaXNDdXJyaWVkID0gYml0bWFzayAmIChXUkFQX0NVUlJZX0ZMQUcgfCBXUkFQX0NVUlJZX1JJR0hUX0ZMQUcpLFxuICAgICAgICAgIGlzRmxpcCA9IGJpdG1hc2sgJiBXUkFQX0ZMSVBfRkxBRyxcbiAgICAgICAgICBDdG9yID0gaXNCaW5kS2V5ID8gdW5kZWZpbmVkIDogY3JlYXRlQ3RvcihmdW5jKTtcblxuICAgICAgZnVuY3Rpb24gd3JhcHBlcigpIHtcbiAgICAgICAgdmFyIGxlbmd0aCA9IGFyZ3VtZW50cy5sZW5ndGgsXG4gICAgICAgICAgICBhcmdzID0gQXJyYXkobGVuZ3RoKSxcbiAgICAgICAgICAgIGluZGV4ID0gbGVuZ3RoO1xuXG4gICAgICAgIHdoaWxlIChpbmRleC0tKSB7XG4gICAgICAgICAgYXJnc1tpbmRleF0gPSBhcmd1bWVudHNbaW5kZXhdO1xuICAgICAgICB9XG4gICAgICAgIGlmIChpc0N1cnJpZWQpIHtcbiAgICAgICAgICB2YXIgcGxhY2Vob2xkZXIgPSBnZXRIb2xkZXIod3JhcHBlciksXG4gICAgICAgICAgICAgIGhvbGRlcnNDb3VudCA9IGNvdW50SG9sZGVycyhhcmdzLCBwbGFjZWhvbGRlcik7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHBhcnRpYWxzKSB7XG4gICAgICAgICAgYXJncyA9IGNvbXBvc2VBcmdzKGFyZ3MsIHBhcnRpYWxzLCBob2xkZXJzLCBpc0N1cnJpZWQpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChwYXJ0aWFsc1JpZ2h0KSB7XG4gICAgICAgICAgYXJncyA9IGNvbXBvc2VBcmdzUmlnaHQoYXJncywgcGFydGlhbHNSaWdodCwgaG9sZGVyc1JpZ2h0LCBpc0N1cnJpZWQpO1xuICAgICAgICB9XG4gICAgICAgIGxlbmd0aCAtPSBob2xkZXJzQ291bnQ7XG4gICAgICAgIGlmIChpc0N1cnJpZWQgJiYgbGVuZ3RoIDwgYXJpdHkpIHtcbiAgICAgICAgICB2YXIgbmV3SG9sZGVycyA9IHJlcGxhY2VIb2xkZXJzKGFyZ3MsIHBsYWNlaG9sZGVyKTtcbiAgICAgICAgICByZXR1cm4gY3JlYXRlUmVjdXJyeShcbiAgICAgICAgICAgIGZ1bmMsIGJpdG1hc2ssIGNyZWF0ZUh5YnJpZCwgd3JhcHBlci5wbGFjZWhvbGRlciwgdGhpc0FyZyxcbiAgICAgICAgICAgIGFyZ3MsIG5ld0hvbGRlcnMsIGFyZ1BvcywgYXJ5LCBhcml0eSAtIGxlbmd0aFxuICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgICAgdmFyIHRoaXNCaW5kaW5nID0gaXNCaW5kID8gdGhpc0FyZyA6IHRoaXMsXG4gICAgICAgICAgICBmbiA9IGlzQmluZEtleSA/IHRoaXNCaW5kaW5nW2Z1bmNdIDogZnVuYztcblxuICAgICAgICBsZW5ndGggPSBhcmdzLmxlbmd0aDtcbiAgICAgICAgaWYgKGFyZ1Bvcykge1xuICAgICAgICAgIGFyZ3MgPSByZW9yZGVyKGFyZ3MsIGFyZ1Bvcyk7XG4gICAgICAgIH0gZWxzZSBpZiAoaXNGbGlwICYmIGxlbmd0aCA+IDEpIHtcbiAgICAgICAgICBhcmdzLnJldmVyc2UoKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoaXNBcnkgJiYgYXJ5IDwgbGVuZ3RoKSB7XG4gICAgICAgICAgYXJncy5sZW5ndGggPSBhcnk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMgJiYgdGhpcyAhPT0gcm9vdCAmJiB0aGlzIGluc3RhbmNlb2Ygd3JhcHBlcikge1xuICAgICAgICAgIGZuID0gQ3RvciB8fCBjcmVhdGVDdG9yKGZuKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZm4uYXBwbHkodGhpc0JpbmRpbmcsIGFyZ3MpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHdyYXBwZXI7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIGZ1bmN0aW9uIGxpa2UgYF8uaW52ZXJ0QnlgLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBzZXR0ZXIgVGhlIGZ1bmN0aW9uIHRvIHNldCBhY2N1bXVsYXRvciB2YWx1ZXMuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gdG9JdGVyYXRlZSBUaGUgZnVuY3Rpb24gdG8gcmVzb2x2ZSBpdGVyYXRlZXMuXG4gICAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgaW52ZXJ0ZXIgZnVuY3Rpb24uXG4gICAgICovXG4gICAgZnVuY3Rpb24gY3JlYXRlSW52ZXJ0ZXIoc2V0dGVyLCB0b0l0ZXJhdGVlKSB7XG4gICAgICByZXR1cm4gZnVuY3Rpb24ob2JqZWN0LCBpdGVyYXRlZSkge1xuICAgICAgICByZXR1cm4gYmFzZUludmVydGVyKG9iamVjdCwgc2V0dGVyLCB0b0l0ZXJhdGVlKGl0ZXJhdGVlKSwge30pO1xuICAgICAgfTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgZnVuY3Rpb24gdGhhdCBwZXJmb3JtcyBhIG1hdGhlbWF0aWNhbCBvcGVyYXRpb24gb24gdHdvIHZhbHVlcy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gb3BlcmF0b3IgVGhlIGZ1bmN0aW9uIHRvIHBlcmZvcm0gdGhlIG9wZXJhdGlvbi5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW2RlZmF1bHRWYWx1ZV0gVGhlIHZhbHVlIHVzZWQgZm9yIGB1bmRlZmluZWRgIGFyZ3VtZW50cy5cbiAgICAgKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBtYXRoZW1hdGljYWwgb3BlcmF0aW9uIGZ1bmN0aW9uLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGNyZWF0ZU1hdGhPcGVyYXRpb24ob3BlcmF0b3IsIGRlZmF1bHRWYWx1ZSkge1xuICAgICAgcmV0dXJuIGZ1bmN0aW9uKHZhbHVlLCBvdGhlcikge1xuICAgICAgICB2YXIgcmVzdWx0O1xuICAgICAgICBpZiAodmFsdWUgPT09IHVuZGVmaW5lZCAmJiBvdGhlciA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgcmV0dXJuIGRlZmF1bHRWYWx1ZTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodmFsdWUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIHJlc3VsdCA9IHZhbHVlO1xuICAgICAgICB9XG4gICAgICAgIGlmIChvdGhlciAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgaWYgKHJlc3VsdCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICByZXR1cm4gb3RoZXI7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmICh0eXBlb2YgdmFsdWUgPT0gJ3N0cmluZycgfHwgdHlwZW9mIG90aGVyID09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICB2YWx1ZSA9IGJhc2VUb1N0cmluZyh2YWx1ZSk7XG4gICAgICAgICAgICBvdGhlciA9IGJhc2VUb1N0cmluZyhvdGhlcik7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHZhbHVlID0gYmFzZVRvTnVtYmVyKHZhbHVlKTtcbiAgICAgICAgICAgIG90aGVyID0gYmFzZVRvTnVtYmVyKG90aGVyKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmVzdWx0ID0gb3BlcmF0b3IodmFsdWUsIG90aGVyKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgfTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgZnVuY3Rpb24gbGlrZSBgXy5vdmVyYC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gYXJyYXlGdW5jIFRoZSBmdW5jdGlvbiB0byBpdGVyYXRlIG92ZXIgaXRlcmF0ZWVzLlxuICAgICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IG92ZXIgZnVuY3Rpb24uXG4gICAgICovXG4gICAgZnVuY3Rpb24gY3JlYXRlT3ZlcihhcnJheUZ1bmMpIHtcbiAgICAgIHJldHVybiBmbGF0UmVzdChmdW5jdGlvbihpdGVyYXRlZXMpIHtcbiAgICAgICAgaXRlcmF0ZWVzID0gYXJyYXlNYXAoaXRlcmF0ZWVzLCBiYXNlVW5hcnkoZ2V0SXRlcmF0ZWUoKSkpO1xuICAgICAgICByZXR1cm4gYmFzZVJlc3QoZnVuY3Rpb24oYXJncykge1xuICAgICAgICAgIHZhciB0aGlzQXJnID0gdGhpcztcbiAgICAgICAgICByZXR1cm4gYXJyYXlGdW5jKGl0ZXJhdGVlcywgZnVuY3Rpb24oaXRlcmF0ZWUpIHtcbiAgICAgICAgICAgIHJldHVybiBhcHBseShpdGVyYXRlZSwgdGhpc0FyZywgYXJncyk7XG4gICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyB0aGUgcGFkZGluZyBmb3IgYHN0cmluZ2AgYmFzZWQgb24gYGxlbmd0aGAuIFRoZSBgY2hhcnNgIHN0cmluZ1xuICAgICAqIGlzIHRydW5jYXRlZCBpZiB0aGUgbnVtYmVyIG9mIGNoYXJhY3RlcnMgZXhjZWVkcyBgbGVuZ3RoYC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IGxlbmd0aCBUaGUgcGFkZGluZyBsZW5ndGguXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IFtjaGFycz0nICddIFRoZSBzdHJpbmcgdXNlZCBhcyBwYWRkaW5nLlxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IFJldHVybnMgdGhlIHBhZGRpbmcgZm9yIGBzdHJpbmdgLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGNyZWF0ZVBhZGRpbmcobGVuZ3RoLCBjaGFycykge1xuICAgICAgY2hhcnMgPSBjaGFycyA9PT0gdW5kZWZpbmVkID8gJyAnIDogYmFzZVRvU3RyaW5nKGNoYXJzKTtcblxuICAgICAgdmFyIGNoYXJzTGVuZ3RoID0gY2hhcnMubGVuZ3RoO1xuICAgICAgaWYgKGNoYXJzTGVuZ3RoIDwgMikge1xuICAgICAgICByZXR1cm4gY2hhcnNMZW5ndGggPyBiYXNlUmVwZWF0KGNoYXJzLCBsZW5ndGgpIDogY2hhcnM7XG4gICAgICB9XG4gICAgICB2YXIgcmVzdWx0ID0gYmFzZVJlcGVhdChjaGFycywgbmF0aXZlQ2VpbChsZW5ndGggLyBzdHJpbmdTaXplKGNoYXJzKSkpO1xuICAgICAgcmV0dXJuIGhhc1VuaWNvZGUoY2hhcnMpXG4gICAgICAgID8gY2FzdFNsaWNlKHN0cmluZ1RvQXJyYXkocmVzdWx0KSwgMCwgbGVuZ3RoKS5qb2luKCcnKVxuICAgICAgICA6IHJlc3VsdC5zbGljZSgwLCBsZW5ndGgpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBmdW5jdGlvbiB0aGF0IHdyYXBzIGBmdW5jYCB0byBpbnZva2UgaXQgd2l0aCB0aGUgYHRoaXNgIGJpbmRpbmdcbiAgICAgKiBvZiBgdGhpc0FyZ2AgYW5kIGBwYXJ0aWFsc2AgcHJlcGVuZGVkIHRvIHRoZSBhcmd1bWVudHMgaXQgcmVjZWl2ZXMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIHdyYXAuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IGJpdG1hc2sgVGhlIGJpdG1hc2sgZmxhZ3MuIFNlZSBgY3JlYXRlV3JhcGAgZm9yIG1vcmUgZGV0YWlscy5cbiAgICAgKiBAcGFyYW0geyp9IHRoaXNBcmcgVGhlIGB0aGlzYCBiaW5kaW5nIG9mIGBmdW5jYC5cbiAgICAgKiBAcGFyYW0ge0FycmF5fSBwYXJ0aWFscyBUaGUgYXJndW1lbnRzIHRvIHByZXBlbmQgdG8gdGhvc2UgcHJvdmlkZWQgdG9cbiAgICAgKiAgdGhlIG5ldyBmdW5jdGlvbi5cbiAgICAgKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyB3cmFwcGVkIGZ1bmN0aW9uLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGNyZWF0ZVBhcnRpYWwoZnVuYywgYml0bWFzaywgdGhpc0FyZywgcGFydGlhbHMpIHtcbiAgICAgIHZhciBpc0JpbmQgPSBiaXRtYXNrICYgV1JBUF9CSU5EX0ZMQUcsXG4gICAgICAgICAgQ3RvciA9IGNyZWF0ZUN0b3IoZnVuYyk7XG5cbiAgICAgIGZ1bmN0aW9uIHdyYXBwZXIoKSB7XG4gICAgICAgIHZhciBhcmdzSW5kZXggPSAtMSxcbiAgICAgICAgICAgIGFyZ3NMZW5ndGggPSBhcmd1bWVudHMubGVuZ3RoLFxuICAgICAgICAgICAgbGVmdEluZGV4ID0gLTEsXG4gICAgICAgICAgICBsZWZ0TGVuZ3RoID0gcGFydGlhbHMubGVuZ3RoLFxuICAgICAgICAgICAgYXJncyA9IEFycmF5KGxlZnRMZW5ndGggKyBhcmdzTGVuZ3RoKSxcbiAgICAgICAgICAgIGZuID0gKHRoaXMgJiYgdGhpcyAhPT0gcm9vdCAmJiB0aGlzIGluc3RhbmNlb2Ygd3JhcHBlcikgPyBDdG9yIDogZnVuYztcblxuICAgICAgICB3aGlsZSAoKytsZWZ0SW5kZXggPCBsZWZ0TGVuZ3RoKSB7XG4gICAgICAgICAgYXJnc1tsZWZ0SW5kZXhdID0gcGFydGlhbHNbbGVmdEluZGV4XTtcbiAgICAgICAgfVxuICAgICAgICB3aGlsZSAoYXJnc0xlbmd0aC0tKSB7XG4gICAgICAgICAgYXJnc1tsZWZ0SW5kZXgrK10gPSBhcmd1bWVudHNbKythcmdzSW5kZXhdO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBhcHBseShmbiwgaXNCaW5kID8gdGhpc0FyZyA6IHRoaXMsIGFyZ3MpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHdyYXBwZXI7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIGBfLnJhbmdlYCBvciBgXy5yYW5nZVJpZ2h0YCBmdW5jdGlvbi5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtib29sZWFufSBbZnJvbVJpZ2h0XSBTcGVjaWZ5IGl0ZXJhdGluZyBmcm9tIHJpZ2h0IHRvIGxlZnQuXG4gICAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgcmFuZ2UgZnVuY3Rpb24uXG4gICAgICovXG4gICAgZnVuY3Rpb24gY3JlYXRlUmFuZ2UoZnJvbVJpZ2h0KSB7XG4gICAgICByZXR1cm4gZnVuY3Rpb24oc3RhcnQsIGVuZCwgc3RlcCkge1xuICAgICAgICBpZiAoc3RlcCAmJiB0eXBlb2Ygc3RlcCAhPSAnbnVtYmVyJyAmJiBpc0l0ZXJhdGVlQ2FsbChzdGFydCwgZW5kLCBzdGVwKSkge1xuICAgICAgICAgIGVuZCA9IHN0ZXAgPSB1bmRlZmluZWQ7XG4gICAgICAgIH1cbiAgICAgICAgLy8gRW5zdXJlIHRoZSBzaWduIG9mIGAtMGAgaXMgcHJlc2VydmVkLlxuICAgICAgICBzdGFydCA9IHRvRmluaXRlKHN0YXJ0KTtcbiAgICAgICAgaWYgKGVuZCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgZW5kID0gc3RhcnQ7XG4gICAgICAgICAgc3RhcnQgPSAwO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGVuZCA9IHRvRmluaXRlKGVuZCk7XG4gICAgICAgIH1cbiAgICAgICAgc3RlcCA9IHN0ZXAgPT09IHVuZGVmaW5lZCA/IChzdGFydCA8IGVuZCA/IDEgOiAtMSkgOiB0b0Zpbml0ZShzdGVwKTtcbiAgICAgICAgcmV0dXJuIGJhc2VSYW5nZShzdGFydCwgZW5kLCBzdGVwLCBmcm9tUmlnaHQpO1xuICAgICAgfTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgZnVuY3Rpb24gdGhhdCBwZXJmb3JtcyBhIHJlbGF0aW9uYWwgb3BlcmF0aW9uIG9uIHR3byB2YWx1ZXMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IG9wZXJhdG9yIFRoZSBmdW5jdGlvbiB0byBwZXJmb3JtIHRoZSBvcGVyYXRpb24uXG4gICAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgcmVsYXRpb25hbCBvcGVyYXRpb24gZnVuY3Rpb24uXG4gICAgICovXG4gICAgZnVuY3Rpb24gY3JlYXRlUmVsYXRpb25hbE9wZXJhdGlvbihvcGVyYXRvcikge1xuICAgICAgcmV0dXJuIGZ1bmN0aW9uKHZhbHVlLCBvdGhlcikge1xuICAgICAgICBpZiAoISh0eXBlb2YgdmFsdWUgPT0gJ3N0cmluZycgJiYgdHlwZW9mIG90aGVyID09ICdzdHJpbmcnKSkge1xuICAgICAgICAgIHZhbHVlID0gdG9OdW1iZXIodmFsdWUpO1xuICAgICAgICAgIG90aGVyID0gdG9OdW1iZXIob3RoZXIpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBvcGVyYXRvcih2YWx1ZSwgb3RoZXIpO1xuICAgICAgfTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgZnVuY3Rpb24gdGhhdCB3cmFwcyBgZnVuY2AgdG8gY29udGludWUgY3VycnlpbmcuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIHdyYXAuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IGJpdG1hc2sgVGhlIGJpdG1hc2sgZmxhZ3MuIFNlZSBgY3JlYXRlV3JhcGAgZm9yIG1vcmUgZGV0YWlscy5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSB3cmFwRnVuYyBUaGUgZnVuY3Rpb24gdG8gY3JlYXRlIHRoZSBgZnVuY2Agd3JhcHBlci5cbiAgICAgKiBAcGFyYW0geyp9IHBsYWNlaG9sZGVyIFRoZSBwbGFjZWhvbGRlciB2YWx1ZS5cbiAgICAgKiBAcGFyYW0geyp9IFt0aGlzQXJnXSBUaGUgYHRoaXNgIGJpbmRpbmcgb2YgYGZ1bmNgLlxuICAgICAqIEBwYXJhbSB7QXJyYXl9IFtwYXJ0aWFsc10gVGhlIGFyZ3VtZW50cyB0byBwcmVwZW5kIHRvIHRob3NlIHByb3ZpZGVkIHRvXG4gICAgICogIHRoZSBuZXcgZnVuY3Rpb24uXG4gICAgICogQHBhcmFtIHtBcnJheX0gW2hvbGRlcnNdIFRoZSBgcGFydGlhbHNgIHBsYWNlaG9sZGVyIGluZGV4ZXMuXG4gICAgICogQHBhcmFtIHtBcnJheX0gW2FyZ1Bvc10gVGhlIGFyZ3VtZW50IHBvc2l0aW9ucyBvZiB0aGUgbmV3IGZ1bmN0aW9uLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbYXJ5XSBUaGUgYXJpdHkgY2FwIG9mIGBmdW5jYC5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW2FyaXR5XSBUaGUgYXJpdHkgb2YgYGZ1bmNgLlxuICAgICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IHdyYXBwZWQgZnVuY3Rpb24uXG4gICAgICovXG4gICAgZnVuY3Rpb24gY3JlYXRlUmVjdXJyeShmdW5jLCBiaXRtYXNrLCB3cmFwRnVuYywgcGxhY2Vob2xkZXIsIHRoaXNBcmcsIHBhcnRpYWxzLCBob2xkZXJzLCBhcmdQb3MsIGFyeSwgYXJpdHkpIHtcbiAgICAgIHZhciBpc0N1cnJ5ID0gYml0bWFzayAmIFdSQVBfQ1VSUllfRkxBRyxcbiAgICAgICAgICBuZXdIb2xkZXJzID0gaXNDdXJyeSA/IGhvbGRlcnMgOiB1bmRlZmluZWQsXG4gICAgICAgICAgbmV3SG9sZGVyc1JpZ2h0ID0gaXNDdXJyeSA/IHVuZGVmaW5lZCA6IGhvbGRlcnMsXG4gICAgICAgICAgbmV3UGFydGlhbHMgPSBpc0N1cnJ5ID8gcGFydGlhbHMgOiB1bmRlZmluZWQsXG4gICAgICAgICAgbmV3UGFydGlhbHNSaWdodCA9IGlzQ3VycnkgPyB1bmRlZmluZWQgOiBwYXJ0aWFscztcblxuICAgICAgYml0bWFzayB8PSAoaXNDdXJyeSA/IFdSQVBfUEFSVElBTF9GTEFHIDogV1JBUF9QQVJUSUFMX1JJR0hUX0ZMQUcpO1xuICAgICAgYml0bWFzayAmPSB+KGlzQ3VycnkgPyBXUkFQX1BBUlRJQUxfUklHSFRfRkxBRyA6IFdSQVBfUEFSVElBTF9GTEFHKTtcblxuICAgICAgaWYgKCEoYml0bWFzayAmIFdSQVBfQ1VSUllfQk9VTkRfRkxBRykpIHtcbiAgICAgICAgYml0bWFzayAmPSB+KFdSQVBfQklORF9GTEFHIHwgV1JBUF9CSU5EX0tFWV9GTEFHKTtcbiAgICAgIH1cbiAgICAgIHZhciBuZXdEYXRhID0gW1xuICAgICAgICBmdW5jLCBiaXRtYXNrLCB0aGlzQXJnLCBuZXdQYXJ0aWFscywgbmV3SG9sZGVycywgbmV3UGFydGlhbHNSaWdodCxcbiAgICAgICAgbmV3SG9sZGVyc1JpZ2h0LCBhcmdQb3MsIGFyeSwgYXJpdHlcbiAgICAgIF07XG5cbiAgICAgIHZhciByZXN1bHQgPSB3cmFwRnVuYy5hcHBseSh1bmRlZmluZWQsIG5ld0RhdGEpO1xuICAgICAgaWYgKGlzTGF6aWFibGUoZnVuYykpIHtcbiAgICAgICAgc2V0RGF0YShyZXN1bHQsIG5ld0RhdGEpO1xuICAgICAgfVxuICAgICAgcmVzdWx0LnBsYWNlaG9sZGVyID0gcGxhY2Vob2xkZXI7XG4gICAgICByZXR1cm4gc2V0V3JhcFRvU3RyaW5nKHJlc3VsdCwgZnVuYywgYml0bWFzayk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIGZ1bmN0aW9uIGxpa2UgYF8ucm91bmRgLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gbWV0aG9kTmFtZSBUaGUgbmFtZSBvZiB0aGUgYE1hdGhgIG1ldGhvZCB0byB1c2Ugd2hlbiByb3VuZGluZy5cbiAgICAgKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyByb3VuZCBmdW5jdGlvbi5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBjcmVhdGVSb3VuZChtZXRob2ROYW1lKSB7XG4gICAgICB2YXIgZnVuYyA9IE1hdGhbbWV0aG9kTmFtZV07XG4gICAgICByZXR1cm4gZnVuY3Rpb24obnVtYmVyLCBwcmVjaXNpb24pIHtcbiAgICAgICAgbnVtYmVyID0gdG9OdW1iZXIobnVtYmVyKTtcbiAgICAgICAgcHJlY2lzaW9uID0gcHJlY2lzaW9uID09IG51bGwgPyAwIDogbmF0aXZlTWluKHRvSW50ZWdlcihwcmVjaXNpb24pLCAyOTIpO1xuICAgICAgICBpZiAocHJlY2lzaW9uICYmIG5hdGl2ZUlzRmluaXRlKG51bWJlcikpIHtcbiAgICAgICAgICAvLyBTaGlmdCB3aXRoIGV4cG9uZW50aWFsIG5vdGF0aW9uIHRvIGF2b2lkIGZsb2F0aW5nLXBvaW50IGlzc3Vlcy5cbiAgICAgICAgICAvLyBTZWUgW01ETl0oaHR0cHM6Ly9tZG4uaW8vcm91bmQjRXhhbXBsZXMpIGZvciBtb3JlIGRldGFpbHMuXG4gICAgICAgICAgdmFyIHBhaXIgPSAodG9TdHJpbmcobnVtYmVyKSArICdlJykuc3BsaXQoJ2UnKSxcbiAgICAgICAgICAgICAgdmFsdWUgPSBmdW5jKHBhaXJbMF0gKyAnZScgKyAoK3BhaXJbMV0gKyBwcmVjaXNpb24pKTtcblxuICAgICAgICAgIHBhaXIgPSAodG9TdHJpbmcodmFsdWUpICsgJ2UnKS5zcGxpdCgnZScpO1xuICAgICAgICAgIHJldHVybiArKHBhaXJbMF0gKyAnZScgKyAoK3BhaXJbMV0gLSBwcmVjaXNpb24pKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZnVuYyhudW1iZXIpO1xuICAgICAgfTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgc2V0IG9iamVjdCBvZiBgdmFsdWVzYC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtBcnJheX0gdmFsdWVzIFRoZSB2YWx1ZXMgdG8gYWRkIHRvIHRoZSBzZXQuXG4gICAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyB0aGUgbmV3IHNldC5cbiAgICAgKi9cbiAgICB2YXIgY3JlYXRlU2V0ID0gIShTZXQgJiYgKDEgLyBzZXRUb0FycmF5KG5ldyBTZXQoWywtMF0pKVsxXSkgPT0gSU5GSU5JVFkpID8gbm9vcCA6IGZ1bmN0aW9uKHZhbHVlcykge1xuICAgICAgcmV0dXJuIG5ldyBTZXQodmFsdWVzKTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIGBfLnRvUGFpcnNgIG9yIGBfLnRvUGFpcnNJbmAgZnVuY3Rpb24uXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGtleXNGdW5jIFRoZSBmdW5jdGlvbiB0byBnZXQgdGhlIGtleXMgb2YgYSBnaXZlbiBvYmplY3QuXG4gICAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgcGFpcnMgZnVuY3Rpb24uXG4gICAgICovXG4gICAgZnVuY3Rpb24gY3JlYXRlVG9QYWlycyhrZXlzRnVuYykge1xuICAgICAgcmV0dXJuIGZ1bmN0aW9uKG9iamVjdCkge1xuICAgICAgICB2YXIgdGFnID0gZ2V0VGFnKG9iamVjdCk7XG4gICAgICAgIGlmICh0YWcgPT0gbWFwVGFnKSB7XG4gICAgICAgICAgcmV0dXJuIG1hcFRvQXJyYXkob2JqZWN0KTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodGFnID09IHNldFRhZykge1xuICAgICAgICAgIHJldHVybiBzZXRUb1BhaXJzKG9iamVjdCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGJhc2VUb1BhaXJzKG9iamVjdCwga2V5c0Z1bmMob2JqZWN0KSk7XG4gICAgICB9O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBmdW5jdGlvbiB0aGF0IGVpdGhlciBjdXJyaWVzIG9yIGludm9rZXMgYGZ1bmNgIHdpdGggb3B0aW9uYWxcbiAgICAgKiBgdGhpc2AgYmluZGluZyBhbmQgcGFydGlhbGx5IGFwcGxpZWQgYXJndW1lbnRzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufHN0cmluZ30gZnVuYyBUaGUgZnVuY3Rpb24gb3IgbWV0aG9kIG5hbWUgdG8gd3JhcC5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gYml0bWFzayBUaGUgYml0bWFzayBmbGFncy5cbiAgICAgKiAgICAxIC0gYF8uYmluZGBcbiAgICAgKiAgICAyIC0gYF8uYmluZEtleWBcbiAgICAgKiAgICA0IC0gYF8uY3VycnlgIG9yIGBfLmN1cnJ5UmlnaHRgIG9mIGEgYm91bmQgZnVuY3Rpb25cbiAgICAgKiAgICA4IC0gYF8uY3VycnlgXG4gICAgICogICAxNiAtIGBfLmN1cnJ5UmlnaHRgXG4gICAgICogICAzMiAtIGBfLnBhcnRpYWxgXG4gICAgICogICA2NCAtIGBfLnBhcnRpYWxSaWdodGBcbiAgICAgKiAgMTI4IC0gYF8ucmVhcmdgXG4gICAgICogIDI1NiAtIGBfLmFyeWBcbiAgICAgKiAgNTEyIC0gYF8uZmxpcGBcbiAgICAgKiBAcGFyYW0geyp9IFt0aGlzQXJnXSBUaGUgYHRoaXNgIGJpbmRpbmcgb2YgYGZ1bmNgLlxuICAgICAqIEBwYXJhbSB7QXJyYXl9IFtwYXJ0aWFsc10gVGhlIGFyZ3VtZW50cyB0byBiZSBwYXJ0aWFsbHkgYXBwbGllZC5cbiAgICAgKiBAcGFyYW0ge0FycmF5fSBbaG9sZGVyc10gVGhlIGBwYXJ0aWFsc2AgcGxhY2Vob2xkZXIgaW5kZXhlcy5cbiAgICAgKiBAcGFyYW0ge0FycmF5fSBbYXJnUG9zXSBUaGUgYXJndW1lbnQgcG9zaXRpb25zIG9mIHRoZSBuZXcgZnVuY3Rpb24uXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFthcnldIFRoZSBhcml0eSBjYXAgb2YgYGZ1bmNgLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbYXJpdHldIFRoZSBhcml0eSBvZiBgZnVuY2AuXG4gICAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgd3JhcHBlZCBmdW5jdGlvbi5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBjcmVhdGVXcmFwKGZ1bmMsIGJpdG1hc2ssIHRoaXNBcmcsIHBhcnRpYWxzLCBob2xkZXJzLCBhcmdQb3MsIGFyeSwgYXJpdHkpIHtcbiAgICAgIHZhciBpc0JpbmRLZXkgPSBiaXRtYXNrICYgV1JBUF9CSU5EX0tFWV9GTEFHO1xuICAgICAgaWYgKCFpc0JpbmRLZXkgJiYgdHlwZW9mIGZ1bmMgIT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKEZVTkNfRVJST1JfVEVYVCk7XG4gICAgICB9XG4gICAgICB2YXIgbGVuZ3RoID0gcGFydGlhbHMgPyBwYXJ0aWFscy5sZW5ndGggOiAwO1xuICAgICAgaWYgKCFsZW5ndGgpIHtcbiAgICAgICAgYml0bWFzayAmPSB+KFdSQVBfUEFSVElBTF9GTEFHIHwgV1JBUF9QQVJUSUFMX1JJR0hUX0ZMQUcpO1xuICAgICAgICBwYXJ0aWFscyA9IGhvbGRlcnMgPSB1bmRlZmluZWQ7XG4gICAgICB9XG4gICAgICBhcnkgPSBhcnkgPT09IHVuZGVmaW5lZCA/IGFyeSA6IG5hdGl2ZU1heCh0b0ludGVnZXIoYXJ5KSwgMCk7XG4gICAgICBhcml0eSA9IGFyaXR5ID09PSB1bmRlZmluZWQgPyBhcml0eSA6IHRvSW50ZWdlcihhcml0eSk7XG4gICAgICBsZW5ndGggLT0gaG9sZGVycyA/IGhvbGRlcnMubGVuZ3RoIDogMDtcblxuICAgICAgaWYgKGJpdG1hc2sgJiBXUkFQX1BBUlRJQUxfUklHSFRfRkxBRykge1xuICAgICAgICB2YXIgcGFydGlhbHNSaWdodCA9IHBhcnRpYWxzLFxuICAgICAgICAgICAgaG9sZGVyc1JpZ2h0ID0gaG9sZGVycztcblxuICAgICAgICBwYXJ0aWFscyA9IGhvbGRlcnMgPSB1bmRlZmluZWQ7XG4gICAgICB9XG4gICAgICB2YXIgZGF0YSA9IGlzQmluZEtleSA/IHVuZGVmaW5lZCA6IGdldERhdGEoZnVuYyk7XG5cbiAgICAgIHZhciBuZXdEYXRhID0gW1xuICAgICAgICBmdW5jLCBiaXRtYXNrLCB0aGlzQXJnLCBwYXJ0aWFscywgaG9sZGVycywgcGFydGlhbHNSaWdodCwgaG9sZGVyc1JpZ2h0LFxuICAgICAgICBhcmdQb3MsIGFyeSwgYXJpdHlcbiAgICAgIF07XG5cbiAgICAgIGlmIChkYXRhKSB7XG4gICAgICAgIG1lcmdlRGF0YShuZXdEYXRhLCBkYXRhKTtcbiAgICAgIH1cbiAgICAgIGZ1bmMgPSBuZXdEYXRhWzBdO1xuICAgICAgYml0bWFzayA9IG5ld0RhdGFbMV07XG4gICAgICB0aGlzQXJnID0gbmV3RGF0YVsyXTtcbiAgICAgIHBhcnRpYWxzID0gbmV3RGF0YVszXTtcbiAgICAgIGhvbGRlcnMgPSBuZXdEYXRhWzRdO1xuICAgICAgYXJpdHkgPSBuZXdEYXRhWzldID0gbmV3RGF0YVs5XSA9PT0gdW5kZWZpbmVkXG4gICAgICAgID8gKGlzQmluZEtleSA/IDAgOiBmdW5jLmxlbmd0aClcbiAgICAgICAgOiBuYXRpdmVNYXgobmV3RGF0YVs5XSAtIGxlbmd0aCwgMCk7XG5cbiAgICAgIGlmICghYXJpdHkgJiYgYml0bWFzayAmIChXUkFQX0NVUlJZX0ZMQUcgfCBXUkFQX0NVUlJZX1JJR0hUX0ZMQUcpKSB7XG4gICAgICAgIGJpdG1hc2sgJj0gfihXUkFQX0NVUlJZX0ZMQUcgfCBXUkFQX0NVUlJZX1JJR0hUX0ZMQUcpO1xuICAgICAgfVxuICAgICAgaWYgKCFiaXRtYXNrIHx8IGJpdG1hc2sgPT0gV1JBUF9CSU5EX0ZMQUcpIHtcbiAgICAgICAgdmFyIHJlc3VsdCA9IGNyZWF0ZUJpbmQoZnVuYywgYml0bWFzaywgdGhpc0FyZyk7XG4gICAgICB9IGVsc2UgaWYgKGJpdG1hc2sgPT0gV1JBUF9DVVJSWV9GTEFHIHx8IGJpdG1hc2sgPT0gV1JBUF9DVVJSWV9SSUdIVF9GTEFHKSB7XG4gICAgICAgIHJlc3VsdCA9IGNyZWF0ZUN1cnJ5KGZ1bmMsIGJpdG1hc2ssIGFyaXR5KTtcbiAgICAgIH0gZWxzZSBpZiAoKGJpdG1hc2sgPT0gV1JBUF9QQVJUSUFMX0ZMQUcgfHwgYml0bWFzayA9PSAoV1JBUF9CSU5EX0ZMQUcgfCBXUkFQX1BBUlRJQUxfRkxBRykpICYmICFob2xkZXJzLmxlbmd0aCkge1xuICAgICAgICByZXN1bHQgPSBjcmVhdGVQYXJ0aWFsKGZ1bmMsIGJpdG1hc2ssIHRoaXNBcmcsIHBhcnRpYWxzKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJlc3VsdCA9IGNyZWF0ZUh5YnJpZC5hcHBseSh1bmRlZmluZWQsIG5ld0RhdGEpO1xuICAgICAgfVxuICAgICAgdmFyIHNldHRlciA9IGRhdGEgPyBiYXNlU2V0RGF0YSA6IHNldERhdGE7XG4gICAgICByZXR1cm4gc2V0V3JhcFRvU3RyaW5nKHNldHRlcihyZXN1bHQsIG5ld0RhdGEpLCBmdW5jLCBiaXRtYXNrKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBVc2VkIGJ5IGBfLmRlZmF1bHRzYCB0byBjdXN0b21pemUgaXRzIGBfLmFzc2lnbkluYCB1c2UgdG8gYXNzaWduIHByb3BlcnRpZXNcbiAgICAgKiBvZiBzb3VyY2Ugb2JqZWN0cyB0byB0aGUgZGVzdGluYXRpb24gb2JqZWN0IGZvciBhbGwgZGVzdGluYXRpb24gcHJvcGVydGllc1xuICAgICAqIHRoYXQgcmVzb2x2ZSB0byBgdW5kZWZpbmVkYC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHsqfSBvYmpWYWx1ZSBUaGUgZGVzdGluYXRpb24gdmFsdWUuXG4gICAgICogQHBhcmFtIHsqfSBzcmNWYWx1ZSBUaGUgc291cmNlIHZhbHVlLlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgVGhlIGtleSBvZiB0aGUgcHJvcGVydHkgdG8gYXNzaWduLlxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIHBhcmVudCBvYmplY3Qgb2YgYG9ialZhbHVlYC5cbiAgICAgKiBAcmV0dXJucyB7Kn0gUmV0dXJucyB0aGUgdmFsdWUgdG8gYXNzaWduLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGN1c3RvbURlZmF1bHRzQXNzaWduSW4ob2JqVmFsdWUsIHNyY1ZhbHVlLCBrZXksIG9iamVjdCkge1xuICAgICAgaWYgKG9ialZhbHVlID09PSB1bmRlZmluZWQgfHxcbiAgICAgICAgICAoZXEob2JqVmFsdWUsIG9iamVjdFByb3RvW2tleV0pICYmICFoYXNPd25Qcm9wZXJ0eS5jYWxsKG9iamVjdCwga2V5KSkpIHtcbiAgICAgICAgcmV0dXJuIHNyY1ZhbHVlO1xuICAgICAgfVxuICAgICAgcmV0dXJuIG9ialZhbHVlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFVzZWQgYnkgYF8uZGVmYXVsdHNEZWVwYCB0byBjdXN0b21pemUgaXRzIGBfLm1lcmdlYCB1c2UgdG8gbWVyZ2Ugc291cmNlXG4gICAgICogb2JqZWN0cyBpbnRvIGRlc3RpbmF0aW9uIG9iamVjdHMgdGhhdCBhcmUgcGFzc2VkIHRocnUuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7Kn0gb2JqVmFsdWUgVGhlIGRlc3RpbmF0aW9uIHZhbHVlLlxuICAgICAqIEBwYXJhbSB7Kn0gc3JjVmFsdWUgVGhlIHNvdXJjZSB2YWx1ZS5cbiAgICAgKiBAcGFyYW0ge3N0cmluZ30ga2V5IFRoZSBrZXkgb2YgdGhlIHByb3BlcnR5IHRvIG1lcmdlLlxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIHBhcmVudCBvYmplY3Qgb2YgYG9ialZhbHVlYC5cbiAgICAgKiBAcGFyYW0ge09iamVjdH0gc291cmNlIFRoZSBwYXJlbnQgb2JqZWN0IG9mIGBzcmNWYWx1ZWAuXG4gICAgICogQHBhcmFtIHtPYmplY3R9IFtzdGFja10gVHJhY2tzIHRyYXZlcnNlZCBzb3VyY2UgdmFsdWVzIGFuZCB0aGVpciBtZXJnZWRcbiAgICAgKiAgY291bnRlcnBhcnRzLlxuICAgICAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSB2YWx1ZSB0byBhc3NpZ24uXG4gICAgICovXG4gICAgZnVuY3Rpb24gY3VzdG9tRGVmYXVsdHNNZXJnZShvYmpWYWx1ZSwgc3JjVmFsdWUsIGtleSwgb2JqZWN0LCBzb3VyY2UsIHN0YWNrKSB7XG4gICAgICBpZiAoaXNPYmplY3Qob2JqVmFsdWUpICYmIGlzT2JqZWN0KHNyY1ZhbHVlKSkge1xuICAgICAgICAvLyBSZWN1cnNpdmVseSBtZXJnZSBvYmplY3RzIGFuZCBhcnJheXMgKHN1c2NlcHRpYmxlIHRvIGNhbGwgc3RhY2sgbGltaXRzKS5cbiAgICAgICAgc3RhY2suc2V0KHNyY1ZhbHVlLCBvYmpWYWx1ZSk7XG4gICAgICAgIGJhc2VNZXJnZShvYmpWYWx1ZSwgc3JjVmFsdWUsIHVuZGVmaW5lZCwgY3VzdG9tRGVmYXVsdHNNZXJnZSwgc3RhY2spO1xuICAgICAgICBzdGFja1snZGVsZXRlJ10oc3JjVmFsdWUpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIG9ialZhbHVlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFVzZWQgYnkgYF8ub21pdGAgdG8gY3VzdG9taXplIGl0cyBgXy5jbG9uZURlZXBgIHVzZSB0byBvbmx5IGNsb25lIHBsYWluXG4gICAgICogb2JqZWN0cy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gaW5zcGVjdC5cbiAgICAgKiBAcGFyYW0ge3N0cmluZ30ga2V5IFRoZSBrZXkgb2YgdGhlIHByb3BlcnR5IHRvIGluc3BlY3QuXG4gICAgICogQHJldHVybnMgeyp9IFJldHVybnMgdGhlIHVuY2xvbmVkIHZhbHVlIG9yIGB1bmRlZmluZWRgIHRvIGRlZmVyIGNsb25pbmcgdG8gYF8uY2xvbmVEZWVwYC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBjdXN0b21PbWl0Q2xvbmUodmFsdWUpIHtcbiAgICAgIHJldHVybiBpc1BsYWluT2JqZWN0KHZhbHVlKSA/IHVuZGVmaW5lZCA6IHZhbHVlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEEgc3BlY2lhbGl6ZWQgdmVyc2lvbiBvZiBgYmFzZUlzRXF1YWxEZWVwYCBmb3IgYXJyYXlzIHdpdGggc3VwcG9ydCBmb3JcbiAgICAgKiBwYXJ0aWFsIGRlZXAgY29tcGFyaXNvbnMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBjb21wYXJlLlxuICAgICAqIEBwYXJhbSB7QXJyYXl9IG90aGVyIFRoZSBvdGhlciBhcnJheSB0byBjb21wYXJlLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBiaXRtYXNrIFRoZSBiaXRtYXNrIGZsYWdzLiBTZWUgYGJhc2VJc0VxdWFsYCBmb3IgbW9yZSBkZXRhaWxzLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGN1c3RvbWl6ZXIgVGhlIGZ1bmN0aW9uIHRvIGN1c3RvbWl6ZSBjb21wYXJpc29ucy5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBlcXVhbEZ1bmMgVGhlIGZ1bmN0aW9uIHRvIGRldGVybWluZSBlcXVpdmFsZW50cyBvZiB2YWx1ZXMuXG4gICAgICogQHBhcmFtIHtPYmplY3R9IHN0YWNrIFRyYWNrcyB0cmF2ZXJzZWQgYGFycmF5YCBhbmQgYG90aGVyYCBvYmplY3RzLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiB0aGUgYXJyYXlzIGFyZSBlcXVpdmFsZW50LCBlbHNlIGBmYWxzZWAuXG4gICAgICovXG4gICAgZnVuY3Rpb24gZXF1YWxBcnJheXMoYXJyYXksIG90aGVyLCBiaXRtYXNrLCBjdXN0b21pemVyLCBlcXVhbEZ1bmMsIHN0YWNrKSB7XG4gICAgICB2YXIgaXNQYXJ0aWFsID0gYml0bWFzayAmIENPTVBBUkVfUEFSVElBTF9GTEFHLFxuICAgICAgICAgIGFyckxlbmd0aCA9IGFycmF5Lmxlbmd0aCxcbiAgICAgICAgICBvdGhMZW5ndGggPSBvdGhlci5sZW5ndGg7XG5cbiAgICAgIGlmIChhcnJMZW5ndGggIT0gb3RoTGVuZ3RoICYmICEoaXNQYXJ0aWFsICYmIG90aExlbmd0aCA+IGFyckxlbmd0aCkpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgICAgLy8gQ2hlY2sgdGhhdCBjeWNsaWMgdmFsdWVzIGFyZSBlcXVhbC5cbiAgICAgIHZhciBhcnJTdGFja2VkID0gc3RhY2suZ2V0KGFycmF5KTtcbiAgICAgIHZhciBvdGhTdGFja2VkID0gc3RhY2suZ2V0KG90aGVyKTtcbiAgICAgIGlmIChhcnJTdGFja2VkICYmIG90aFN0YWNrZWQpIHtcbiAgICAgICAgcmV0dXJuIGFyclN0YWNrZWQgPT0gb3RoZXIgJiYgb3RoU3RhY2tlZCA9PSBhcnJheTtcbiAgICAgIH1cbiAgICAgIHZhciBpbmRleCA9IC0xLFxuICAgICAgICAgIHJlc3VsdCA9IHRydWUsXG4gICAgICAgICAgc2VlbiA9IChiaXRtYXNrICYgQ09NUEFSRV9VTk9SREVSRURfRkxBRykgPyBuZXcgU2V0Q2FjaGUgOiB1bmRlZmluZWQ7XG5cbiAgICAgIHN0YWNrLnNldChhcnJheSwgb3RoZXIpO1xuICAgICAgc3RhY2suc2V0KG90aGVyLCBhcnJheSk7XG5cbiAgICAgIC8vIElnbm9yZSBub24taW5kZXggcHJvcGVydGllcy5cbiAgICAgIHdoaWxlICgrK2luZGV4IDwgYXJyTGVuZ3RoKSB7XG4gICAgICAgIHZhciBhcnJWYWx1ZSA9IGFycmF5W2luZGV4XSxcbiAgICAgICAgICAgIG90aFZhbHVlID0gb3RoZXJbaW5kZXhdO1xuXG4gICAgICAgIGlmIChjdXN0b21pemVyKSB7XG4gICAgICAgICAgdmFyIGNvbXBhcmVkID0gaXNQYXJ0aWFsXG4gICAgICAgICAgICA/IGN1c3RvbWl6ZXIob3RoVmFsdWUsIGFyclZhbHVlLCBpbmRleCwgb3RoZXIsIGFycmF5LCBzdGFjaylcbiAgICAgICAgICAgIDogY3VzdG9taXplcihhcnJWYWx1ZSwgb3RoVmFsdWUsIGluZGV4LCBhcnJheSwgb3RoZXIsIHN0YWNrKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoY29tcGFyZWQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIGlmIChjb21wYXJlZCkge1xuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJlc3VsdCA9IGZhbHNlO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICAgIC8vIFJlY3Vyc2l2ZWx5IGNvbXBhcmUgYXJyYXlzIChzdXNjZXB0aWJsZSB0byBjYWxsIHN0YWNrIGxpbWl0cykuXG4gICAgICAgIGlmIChzZWVuKSB7XG4gICAgICAgICAgaWYgKCFhcnJheVNvbWUob3RoZXIsIGZ1bmN0aW9uKG90aFZhbHVlLCBvdGhJbmRleCkge1xuICAgICAgICAgICAgICAgIGlmICghY2FjaGVIYXMoc2Vlbiwgb3RoSW5kZXgpICYmXG4gICAgICAgICAgICAgICAgICAgIChhcnJWYWx1ZSA9PT0gb3RoVmFsdWUgfHwgZXF1YWxGdW5jKGFyclZhbHVlLCBvdGhWYWx1ZSwgYml0bWFzaywgY3VzdG9taXplciwgc3RhY2spKSkge1xuICAgICAgICAgICAgICAgICAgcmV0dXJuIHNlZW4ucHVzaChvdGhJbmRleCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9KSkge1xuICAgICAgICAgICAgcmVzdWx0ID0gZmFsc2U7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSBpZiAoIShcbiAgICAgICAgICAgICAgYXJyVmFsdWUgPT09IG90aFZhbHVlIHx8XG4gICAgICAgICAgICAgICAgZXF1YWxGdW5jKGFyclZhbHVlLCBvdGhWYWx1ZSwgYml0bWFzaywgY3VzdG9taXplciwgc3RhY2spXG4gICAgICAgICAgICApKSB7XG4gICAgICAgICAgcmVzdWx0ID0gZmFsc2U7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHN0YWNrWydkZWxldGUnXShhcnJheSk7XG4gICAgICBzdGFja1snZGVsZXRlJ10ob3RoZXIpO1xuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBBIHNwZWNpYWxpemVkIHZlcnNpb24gb2YgYGJhc2VJc0VxdWFsRGVlcGAgZm9yIGNvbXBhcmluZyBvYmplY3RzIG9mXG4gICAgICogdGhlIHNhbWUgYHRvU3RyaW5nVGFnYC5cbiAgICAgKlxuICAgICAqICoqTm90ZToqKiBUaGlzIGZ1bmN0aW9uIG9ubHkgc3VwcG9ydHMgY29tcGFyaW5nIHZhbHVlcyB3aXRoIHRhZ3Mgb2ZcbiAgICAgKiBgQm9vbGVhbmAsIGBEYXRlYCwgYEVycm9yYCwgYE51bWJlcmAsIGBSZWdFeHBgLCBvciBgU3RyaW5nYC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIGNvbXBhcmUuXG4gICAgICogQHBhcmFtIHtPYmplY3R9IG90aGVyIFRoZSBvdGhlciBvYmplY3QgdG8gY29tcGFyZS5cbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gdGFnIFRoZSBgdG9TdHJpbmdUYWdgIG9mIHRoZSBvYmplY3RzIHRvIGNvbXBhcmUuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IGJpdG1hc2sgVGhlIGJpdG1hc2sgZmxhZ3MuIFNlZSBgYmFzZUlzRXF1YWxgIGZvciBtb3JlIGRldGFpbHMuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gY3VzdG9taXplciBUaGUgZnVuY3Rpb24gdG8gY3VzdG9taXplIGNvbXBhcmlzb25zLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGVxdWFsRnVuYyBUaGUgZnVuY3Rpb24gdG8gZGV0ZXJtaW5lIGVxdWl2YWxlbnRzIG9mIHZhbHVlcy5cbiAgICAgKiBAcGFyYW0ge09iamVjdH0gc3RhY2sgVHJhY2tzIHRyYXZlcnNlZCBgb2JqZWN0YCBhbmQgYG90aGVyYCBvYmplY3RzLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiB0aGUgb2JqZWN0cyBhcmUgZXF1aXZhbGVudCwgZWxzZSBgZmFsc2VgLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGVxdWFsQnlUYWcob2JqZWN0LCBvdGhlciwgdGFnLCBiaXRtYXNrLCBjdXN0b21pemVyLCBlcXVhbEZ1bmMsIHN0YWNrKSB7XG4gICAgICBzd2l0Y2ggKHRhZykge1xuICAgICAgICBjYXNlIGRhdGFWaWV3VGFnOlxuICAgICAgICAgIGlmICgob2JqZWN0LmJ5dGVMZW5ndGggIT0gb3RoZXIuYnl0ZUxlbmd0aCkgfHxcbiAgICAgICAgICAgICAgKG9iamVjdC5ieXRlT2Zmc2V0ICE9IG90aGVyLmJ5dGVPZmZzZXQpKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgfVxuICAgICAgICAgIG9iamVjdCA9IG9iamVjdC5idWZmZXI7XG4gICAgICAgICAgb3RoZXIgPSBvdGhlci5idWZmZXI7XG5cbiAgICAgICAgY2FzZSBhcnJheUJ1ZmZlclRhZzpcbiAgICAgICAgICBpZiAoKG9iamVjdC5ieXRlTGVuZ3RoICE9IG90aGVyLmJ5dGVMZW5ndGgpIHx8XG4gICAgICAgICAgICAgICFlcXVhbEZ1bmMobmV3IFVpbnQ4QXJyYXkob2JqZWN0KSwgbmV3IFVpbnQ4QXJyYXkob3RoZXIpKSkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4gdHJ1ZTtcblxuICAgICAgICBjYXNlIGJvb2xUYWc6XG4gICAgICAgIGNhc2UgZGF0ZVRhZzpcbiAgICAgICAgY2FzZSBudW1iZXJUYWc6XG4gICAgICAgICAgLy8gQ29lcmNlIGJvb2xlYW5zIHRvIGAxYCBvciBgMGAgYW5kIGRhdGVzIHRvIG1pbGxpc2Vjb25kcy5cbiAgICAgICAgICAvLyBJbnZhbGlkIGRhdGVzIGFyZSBjb2VyY2VkIHRvIGBOYU5gLlxuICAgICAgICAgIHJldHVybiBlcSgrb2JqZWN0LCArb3RoZXIpO1xuXG4gICAgICAgIGNhc2UgZXJyb3JUYWc6XG4gICAgICAgICAgcmV0dXJuIG9iamVjdC5uYW1lID09IG90aGVyLm5hbWUgJiYgb2JqZWN0Lm1lc3NhZ2UgPT0gb3RoZXIubWVzc2FnZTtcblxuICAgICAgICBjYXNlIHJlZ2V4cFRhZzpcbiAgICAgICAgY2FzZSBzdHJpbmdUYWc6XG4gICAgICAgICAgLy8gQ29lcmNlIHJlZ2V4ZXMgdG8gc3RyaW5ncyBhbmQgdHJlYXQgc3RyaW5ncywgcHJpbWl0aXZlcyBhbmQgb2JqZWN0cyxcbiAgICAgICAgICAvLyBhcyBlcXVhbC4gU2VlIGh0dHA6Ly93d3cuZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi83LjAvI3NlYy1yZWdleHAucHJvdG90eXBlLnRvc3RyaW5nXG4gICAgICAgICAgLy8gZm9yIG1vcmUgZGV0YWlscy5cbiAgICAgICAgICByZXR1cm4gb2JqZWN0ID09IChvdGhlciArICcnKTtcblxuICAgICAgICBjYXNlIG1hcFRhZzpcbiAgICAgICAgICB2YXIgY29udmVydCA9IG1hcFRvQXJyYXk7XG5cbiAgICAgICAgY2FzZSBzZXRUYWc6XG4gICAgICAgICAgdmFyIGlzUGFydGlhbCA9IGJpdG1hc2sgJiBDT01QQVJFX1BBUlRJQUxfRkxBRztcbiAgICAgICAgICBjb252ZXJ0IHx8IChjb252ZXJ0ID0gc2V0VG9BcnJheSk7XG5cbiAgICAgICAgICBpZiAob2JqZWN0LnNpemUgIT0gb3RoZXIuc2l6ZSAmJiAhaXNQYXJ0aWFsKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgfVxuICAgICAgICAgIC8vIEFzc3VtZSBjeWNsaWMgdmFsdWVzIGFyZSBlcXVhbC5cbiAgICAgICAgICB2YXIgc3RhY2tlZCA9IHN0YWNrLmdldChvYmplY3QpO1xuICAgICAgICAgIGlmIChzdGFja2VkKSB7XG4gICAgICAgICAgICByZXR1cm4gc3RhY2tlZCA9PSBvdGhlcjtcbiAgICAgICAgICB9XG4gICAgICAgICAgYml0bWFzayB8PSBDT01QQVJFX1VOT1JERVJFRF9GTEFHO1xuXG4gICAgICAgICAgLy8gUmVjdXJzaXZlbHkgY29tcGFyZSBvYmplY3RzIChzdXNjZXB0aWJsZSB0byBjYWxsIHN0YWNrIGxpbWl0cykuXG4gICAgICAgICAgc3RhY2suc2V0KG9iamVjdCwgb3RoZXIpO1xuICAgICAgICAgIHZhciByZXN1bHQgPSBlcXVhbEFycmF5cyhjb252ZXJ0KG9iamVjdCksIGNvbnZlcnQob3RoZXIpLCBiaXRtYXNrLCBjdXN0b21pemVyLCBlcXVhbEZ1bmMsIHN0YWNrKTtcbiAgICAgICAgICBzdGFja1snZGVsZXRlJ10ob2JqZWN0KTtcbiAgICAgICAgICByZXR1cm4gcmVzdWx0O1xuXG4gICAgICAgIGNhc2Ugc3ltYm9sVGFnOlxuICAgICAgICAgIGlmIChzeW1ib2xWYWx1ZU9mKSB7XG4gICAgICAgICAgICByZXR1cm4gc3ltYm9sVmFsdWVPZi5jYWxsKG9iamVjdCkgPT0gc3ltYm9sVmFsdWVPZi5jYWxsKG90aGVyKTtcbiAgICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQSBzcGVjaWFsaXplZCB2ZXJzaW9uIG9mIGBiYXNlSXNFcXVhbERlZXBgIGZvciBvYmplY3RzIHdpdGggc3VwcG9ydCBmb3JcbiAgICAgKiBwYXJ0aWFsIGRlZXAgY29tcGFyaXNvbnMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBjb21wYXJlLlxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvdGhlciBUaGUgb3RoZXIgb2JqZWN0IHRvIGNvbXBhcmUuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IGJpdG1hc2sgVGhlIGJpdG1hc2sgZmxhZ3MuIFNlZSBgYmFzZUlzRXF1YWxgIGZvciBtb3JlIGRldGFpbHMuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gY3VzdG9taXplciBUaGUgZnVuY3Rpb24gdG8gY3VzdG9taXplIGNvbXBhcmlzb25zLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGVxdWFsRnVuYyBUaGUgZnVuY3Rpb24gdG8gZGV0ZXJtaW5lIGVxdWl2YWxlbnRzIG9mIHZhbHVlcy5cbiAgICAgKiBAcGFyYW0ge09iamVjdH0gc3RhY2sgVHJhY2tzIHRyYXZlcnNlZCBgb2JqZWN0YCBhbmQgYG90aGVyYCBvYmplY3RzLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiB0aGUgb2JqZWN0cyBhcmUgZXF1aXZhbGVudCwgZWxzZSBgZmFsc2VgLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGVxdWFsT2JqZWN0cyhvYmplY3QsIG90aGVyLCBiaXRtYXNrLCBjdXN0b21pemVyLCBlcXVhbEZ1bmMsIHN0YWNrKSB7XG4gICAgICB2YXIgaXNQYXJ0aWFsID0gYml0bWFzayAmIENPTVBBUkVfUEFSVElBTF9GTEFHLFxuICAgICAgICAgIG9ialByb3BzID0gZ2V0QWxsS2V5cyhvYmplY3QpLFxuICAgICAgICAgIG9iakxlbmd0aCA9IG9ialByb3BzLmxlbmd0aCxcbiAgICAgICAgICBvdGhQcm9wcyA9IGdldEFsbEtleXMob3RoZXIpLFxuICAgICAgICAgIG90aExlbmd0aCA9IG90aFByb3BzLmxlbmd0aDtcblxuICAgICAgaWYgKG9iakxlbmd0aCAhPSBvdGhMZW5ndGggJiYgIWlzUGFydGlhbCkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgICB2YXIgaW5kZXggPSBvYmpMZW5ndGg7XG4gICAgICB3aGlsZSAoaW5kZXgtLSkge1xuICAgICAgICB2YXIga2V5ID0gb2JqUHJvcHNbaW5kZXhdO1xuICAgICAgICBpZiAoIShpc1BhcnRpYWwgPyBrZXkgaW4gb3RoZXIgOiBoYXNPd25Qcm9wZXJ0eS5jYWxsKG90aGVyLCBrZXkpKSkge1xuICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgLy8gQ2hlY2sgdGhhdCBjeWNsaWMgdmFsdWVzIGFyZSBlcXVhbC5cbiAgICAgIHZhciBvYmpTdGFja2VkID0gc3RhY2suZ2V0KG9iamVjdCk7XG4gICAgICB2YXIgb3RoU3RhY2tlZCA9IHN0YWNrLmdldChvdGhlcik7XG4gICAgICBpZiAob2JqU3RhY2tlZCAmJiBvdGhTdGFja2VkKSB7XG4gICAgICAgIHJldHVybiBvYmpTdGFja2VkID09IG90aGVyICYmIG90aFN0YWNrZWQgPT0gb2JqZWN0O1xuICAgICAgfVxuICAgICAgdmFyIHJlc3VsdCA9IHRydWU7XG4gICAgICBzdGFjay5zZXQob2JqZWN0LCBvdGhlcik7XG4gICAgICBzdGFjay5zZXQob3RoZXIsIG9iamVjdCk7XG5cbiAgICAgIHZhciBza2lwQ3RvciA9IGlzUGFydGlhbDtcbiAgICAgIHdoaWxlICgrK2luZGV4IDwgb2JqTGVuZ3RoKSB7XG4gICAgICAgIGtleSA9IG9ialByb3BzW2luZGV4XTtcbiAgICAgICAgdmFyIG9ialZhbHVlID0gb2JqZWN0W2tleV0sXG4gICAgICAgICAgICBvdGhWYWx1ZSA9IG90aGVyW2tleV07XG5cbiAgICAgICAgaWYgKGN1c3RvbWl6ZXIpIHtcbiAgICAgICAgICB2YXIgY29tcGFyZWQgPSBpc1BhcnRpYWxcbiAgICAgICAgICAgID8gY3VzdG9taXplcihvdGhWYWx1ZSwgb2JqVmFsdWUsIGtleSwgb3RoZXIsIG9iamVjdCwgc3RhY2spXG4gICAgICAgICAgICA6IGN1c3RvbWl6ZXIob2JqVmFsdWUsIG90aFZhbHVlLCBrZXksIG9iamVjdCwgb3RoZXIsIHN0YWNrKTtcbiAgICAgICAgfVxuICAgICAgICAvLyBSZWN1cnNpdmVseSBjb21wYXJlIG9iamVjdHMgKHN1c2NlcHRpYmxlIHRvIGNhbGwgc3RhY2sgbGltaXRzKS5cbiAgICAgICAgaWYgKCEoY29tcGFyZWQgPT09IHVuZGVmaW5lZFxuICAgICAgICAgICAgICA/IChvYmpWYWx1ZSA9PT0gb3RoVmFsdWUgfHwgZXF1YWxGdW5jKG9ialZhbHVlLCBvdGhWYWx1ZSwgYml0bWFzaywgY3VzdG9taXplciwgc3RhY2spKVxuICAgICAgICAgICAgICA6IGNvbXBhcmVkXG4gICAgICAgICAgICApKSB7XG4gICAgICAgICAgcmVzdWx0ID0gZmFsc2U7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgICAgc2tpcEN0b3IgfHwgKHNraXBDdG9yID0ga2V5ID09ICdjb25zdHJ1Y3RvcicpO1xuICAgICAgfVxuICAgICAgaWYgKHJlc3VsdCAmJiAhc2tpcEN0b3IpIHtcbiAgICAgICAgdmFyIG9iakN0b3IgPSBvYmplY3QuY29uc3RydWN0b3IsXG4gICAgICAgICAgICBvdGhDdG9yID0gb3RoZXIuY29uc3RydWN0b3I7XG5cbiAgICAgICAgLy8gTm9uIGBPYmplY3RgIG9iamVjdCBpbnN0YW5jZXMgd2l0aCBkaWZmZXJlbnQgY29uc3RydWN0b3JzIGFyZSBub3QgZXF1YWwuXG4gICAgICAgIGlmIChvYmpDdG9yICE9IG90aEN0b3IgJiZcbiAgICAgICAgICAgICgnY29uc3RydWN0b3InIGluIG9iamVjdCAmJiAnY29uc3RydWN0b3InIGluIG90aGVyKSAmJlxuICAgICAgICAgICAgISh0eXBlb2Ygb2JqQ3RvciA9PSAnZnVuY3Rpb24nICYmIG9iakN0b3IgaW5zdGFuY2VvZiBvYmpDdG9yICYmXG4gICAgICAgICAgICAgIHR5cGVvZiBvdGhDdG9yID09ICdmdW5jdGlvbicgJiYgb3RoQ3RvciBpbnN0YW5jZW9mIG90aEN0b3IpKSB7XG4gICAgICAgICAgcmVzdWx0ID0gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHN0YWNrWydkZWxldGUnXShvYmplY3QpO1xuICAgICAgc3RhY2tbJ2RlbGV0ZSddKG90aGVyKTtcbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQSBzcGVjaWFsaXplZCB2ZXJzaW9uIG9mIGBiYXNlUmVzdGAgd2hpY2ggZmxhdHRlbnMgdGhlIHJlc3QgYXJyYXkuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIGFwcGx5IGEgcmVzdCBwYXJhbWV0ZXIgdG8uXG4gICAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgZnVuY3Rpb24uXG4gICAgICovXG4gICAgZnVuY3Rpb24gZmxhdFJlc3QoZnVuYykge1xuICAgICAgcmV0dXJuIHNldFRvU3RyaW5nKG92ZXJSZXN0KGZ1bmMsIHVuZGVmaW5lZCwgZmxhdHRlbiksIGZ1bmMgKyAnJyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhbiBhcnJheSBvZiBvd24gZW51bWVyYWJsZSBwcm9wZXJ0eSBuYW1lcyBhbmQgc3ltYm9scyBvZiBgb2JqZWN0YC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIHF1ZXJ5LlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgYXJyYXkgb2YgcHJvcGVydHkgbmFtZXMgYW5kIHN5bWJvbHMuXG4gICAgICovXG4gICAgZnVuY3Rpb24gZ2V0QWxsS2V5cyhvYmplY3QpIHtcbiAgICAgIHJldHVybiBiYXNlR2V0QWxsS2V5cyhvYmplY3QsIGtleXMsIGdldFN5bWJvbHMpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYW4gYXJyYXkgb2Ygb3duIGFuZCBpbmhlcml0ZWQgZW51bWVyYWJsZSBwcm9wZXJ0eSBuYW1lcyBhbmRcbiAgICAgKiBzeW1ib2xzIG9mIGBvYmplY3RgLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gcXVlcnkuXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBhcnJheSBvZiBwcm9wZXJ0eSBuYW1lcyBhbmQgc3ltYm9scy5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBnZXRBbGxLZXlzSW4ob2JqZWN0KSB7XG4gICAgICByZXR1cm4gYmFzZUdldEFsbEtleXMob2JqZWN0LCBrZXlzSW4sIGdldFN5bWJvbHNJbik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0cyBtZXRhZGF0YSBmb3IgYGZ1bmNgLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byBxdWVyeS5cbiAgICAgKiBAcmV0dXJucyB7Kn0gUmV0dXJucyB0aGUgbWV0YWRhdGEgZm9yIGBmdW5jYC5cbiAgICAgKi9cbiAgICB2YXIgZ2V0RGF0YSA9ICFtZXRhTWFwID8gbm9vcCA6IGZ1bmN0aW9uKGZ1bmMpIHtcbiAgICAgIHJldHVybiBtZXRhTWFwLmdldChmdW5jKTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogR2V0cyB0aGUgbmFtZSBvZiBgZnVuY2AuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIHF1ZXJ5LlxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IFJldHVybnMgdGhlIGZ1bmN0aW9uIG5hbWUuXG4gICAgICovXG4gICAgZnVuY3Rpb24gZ2V0RnVuY05hbWUoZnVuYykge1xuICAgICAgdmFyIHJlc3VsdCA9IChmdW5jLm5hbWUgKyAnJyksXG4gICAgICAgICAgYXJyYXkgPSByZWFsTmFtZXNbcmVzdWx0XSxcbiAgICAgICAgICBsZW5ndGggPSBoYXNPd25Qcm9wZXJ0eS5jYWxsKHJlYWxOYW1lcywgcmVzdWx0KSA/IGFycmF5Lmxlbmd0aCA6IDA7XG5cbiAgICAgIHdoaWxlIChsZW5ndGgtLSkge1xuICAgICAgICB2YXIgZGF0YSA9IGFycmF5W2xlbmd0aF0sXG4gICAgICAgICAgICBvdGhlckZ1bmMgPSBkYXRhLmZ1bmM7XG4gICAgICAgIGlmIChvdGhlckZ1bmMgPT0gbnVsbCB8fCBvdGhlckZ1bmMgPT0gZnVuYykge1xuICAgICAgICAgIHJldHVybiBkYXRhLm5hbWU7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0cyB0aGUgYXJndW1lbnQgcGxhY2Vob2xkZXIgdmFsdWUgZm9yIGBmdW5jYC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gZnVuYyBUaGUgZnVuY3Rpb24gdG8gaW5zcGVjdC5cbiAgICAgKiBAcmV0dXJucyB7Kn0gUmV0dXJucyB0aGUgcGxhY2Vob2xkZXIgdmFsdWUuXG4gICAgICovXG4gICAgZnVuY3Rpb24gZ2V0SG9sZGVyKGZ1bmMpIHtcbiAgICAgIHZhciBvYmplY3QgPSBoYXNPd25Qcm9wZXJ0eS5jYWxsKGxvZGFzaCwgJ3BsYWNlaG9sZGVyJykgPyBsb2Rhc2ggOiBmdW5jO1xuICAgICAgcmV0dXJuIG9iamVjdC5wbGFjZWhvbGRlcjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXRzIHRoZSBhcHByb3ByaWF0ZSBcIml0ZXJhdGVlXCIgZnVuY3Rpb24uIElmIGBfLml0ZXJhdGVlYCBpcyBjdXN0b21pemVkLFxuICAgICAqIHRoaXMgZnVuY3Rpb24gcmV0dXJucyB0aGUgY3VzdG9tIG1ldGhvZCwgb3RoZXJ3aXNlIGl0IHJldHVybnMgYGJhc2VJdGVyYXRlZWAuXG4gICAgICogSWYgYXJndW1lbnRzIGFyZSBwcm92aWRlZCwgdGhlIGNob3NlbiBmdW5jdGlvbiBpcyBpbnZva2VkIHdpdGggdGhlbSBhbmRcbiAgICAgKiBpdHMgcmVzdWx0IGlzIHJldHVybmVkLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0geyp9IFt2YWx1ZV0gVGhlIHZhbHVlIHRvIGNvbnZlcnQgdG8gYW4gaXRlcmF0ZWUuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFthcml0eV0gVGhlIGFyaXR5IG9mIHRoZSBjcmVhdGVkIGl0ZXJhdGVlLlxuICAgICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgY2hvc2VuIGZ1bmN0aW9uIG9yIGl0cyByZXN1bHQuXG4gICAgICovXG4gICAgZnVuY3Rpb24gZ2V0SXRlcmF0ZWUoKSB7XG4gICAgICB2YXIgcmVzdWx0ID0gbG9kYXNoLml0ZXJhdGVlIHx8IGl0ZXJhdGVlO1xuICAgICAgcmVzdWx0ID0gcmVzdWx0ID09PSBpdGVyYXRlZSA/IGJhc2VJdGVyYXRlZSA6IHJlc3VsdDtcbiAgICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gcmVzdWx0KGFyZ3VtZW50c1swXSwgYXJndW1lbnRzWzFdKSA6IHJlc3VsdDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXRzIHRoZSBkYXRhIGZvciBgbWFwYC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtPYmplY3R9IG1hcCBUaGUgbWFwIHRvIHF1ZXJ5LlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgVGhlIHJlZmVyZW5jZSBrZXkuXG4gICAgICogQHJldHVybnMgeyp9IFJldHVybnMgdGhlIG1hcCBkYXRhLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGdldE1hcERhdGEobWFwLCBrZXkpIHtcbiAgICAgIHZhciBkYXRhID0gbWFwLl9fZGF0YV9fO1xuICAgICAgcmV0dXJuIGlzS2V5YWJsZShrZXkpXG4gICAgICAgID8gZGF0YVt0eXBlb2Yga2V5ID09ICdzdHJpbmcnID8gJ3N0cmluZycgOiAnaGFzaCddXG4gICAgICAgIDogZGF0YS5tYXA7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0cyB0aGUgcHJvcGVydHkgbmFtZXMsIHZhbHVlcywgYW5kIGNvbXBhcmUgZmxhZ3Mgb2YgYG9iamVjdGAuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBxdWVyeS5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIG1hdGNoIGRhdGEgb2YgYG9iamVjdGAuXG4gICAgICovXG4gICAgZnVuY3Rpb24gZ2V0TWF0Y2hEYXRhKG9iamVjdCkge1xuICAgICAgdmFyIHJlc3VsdCA9IGtleXMob2JqZWN0KSxcbiAgICAgICAgICBsZW5ndGggPSByZXN1bHQubGVuZ3RoO1xuXG4gICAgICB3aGlsZSAobGVuZ3RoLS0pIHtcbiAgICAgICAgdmFyIGtleSA9IHJlc3VsdFtsZW5ndGhdLFxuICAgICAgICAgICAgdmFsdWUgPSBvYmplY3Rba2V5XTtcblxuICAgICAgICByZXN1bHRbbGVuZ3RoXSA9IFtrZXksIHZhbHVlLCBpc1N0cmljdENvbXBhcmFibGUodmFsdWUpXTtcbiAgICAgIH1cbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0cyB0aGUgbmF0aXZlIGZ1bmN0aW9uIGF0IGBrZXlgIG9mIGBvYmplY3RgLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gcXVlcnkuXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGtleSBUaGUga2V5IG9mIHRoZSBtZXRob2QgdG8gZ2V0LlxuICAgICAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSBmdW5jdGlvbiBpZiBpdCdzIG5hdGl2ZSwgZWxzZSBgdW5kZWZpbmVkYC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBnZXROYXRpdmUob2JqZWN0LCBrZXkpIHtcbiAgICAgIHZhciB2YWx1ZSA9IGdldFZhbHVlKG9iamVjdCwga2V5KTtcbiAgICAgIHJldHVybiBiYXNlSXNOYXRpdmUodmFsdWUpID8gdmFsdWUgOiB1bmRlZmluZWQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQSBzcGVjaWFsaXplZCB2ZXJzaW9uIG9mIGBiYXNlR2V0VGFnYCB3aGljaCBpZ25vcmVzIGBTeW1ib2wudG9TdHJpbmdUYWdgIHZhbHVlcy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gcXVlcnkuXG4gICAgICogQHJldHVybnMge3N0cmluZ30gUmV0dXJucyB0aGUgcmF3IGB0b1N0cmluZ1RhZ2AuXG4gICAgICovXG4gICAgZnVuY3Rpb24gZ2V0UmF3VGFnKHZhbHVlKSB7XG4gICAgICB2YXIgaXNPd24gPSBoYXNPd25Qcm9wZXJ0eS5jYWxsKHZhbHVlLCBzeW1Ub1N0cmluZ1RhZyksXG4gICAgICAgICAgdGFnID0gdmFsdWVbc3ltVG9TdHJpbmdUYWddO1xuXG4gICAgICB0cnkge1xuICAgICAgICB2YWx1ZVtzeW1Ub1N0cmluZ1RhZ10gPSB1bmRlZmluZWQ7XG4gICAgICAgIHZhciB1bm1hc2tlZCA9IHRydWU7XG4gICAgICB9IGNhdGNoIChlKSB7fVxuXG4gICAgICB2YXIgcmVzdWx0ID0gbmF0aXZlT2JqZWN0VG9TdHJpbmcuY2FsbCh2YWx1ZSk7XG4gICAgICBpZiAodW5tYXNrZWQpIHtcbiAgICAgICAgaWYgKGlzT3duKSB7XG4gICAgICAgICAgdmFsdWVbc3ltVG9TdHJpbmdUYWddID0gdGFnO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGRlbGV0ZSB2YWx1ZVtzeW1Ub1N0cmluZ1RhZ107XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhbiBhcnJheSBvZiB0aGUgb3duIGVudW1lcmFibGUgc3ltYm9scyBvZiBgb2JqZWN0YC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIHF1ZXJ5LlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgYXJyYXkgb2Ygc3ltYm9scy5cbiAgICAgKi9cbiAgICB2YXIgZ2V0U3ltYm9scyA9ICFuYXRpdmVHZXRTeW1ib2xzID8gc3R1YkFycmF5IDogZnVuY3Rpb24ob2JqZWN0KSB7XG4gICAgICBpZiAob2JqZWN0ID09IG51bGwpIHtcbiAgICAgICAgcmV0dXJuIFtdO1xuICAgICAgfVxuICAgICAgb2JqZWN0ID0gT2JqZWN0KG9iamVjdCk7XG4gICAgICByZXR1cm4gYXJyYXlGaWx0ZXIobmF0aXZlR2V0U3ltYm9scyhvYmplY3QpLCBmdW5jdGlvbihzeW1ib2wpIHtcbiAgICAgICAgcmV0dXJuIHByb3BlcnR5SXNFbnVtZXJhYmxlLmNhbGwob2JqZWN0LCBzeW1ib2wpO1xuICAgICAgfSk7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYW4gYXJyYXkgb2YgdGhlIG93biBhbmQgaW5oZXJpdGVkIGVudW1lcmFibGUgc3ltYm9scyBvZiBgb2JqZWN0YC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIHF1ZXJ5LlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgYXJyYXkgb2Ygc3ltYm9scy5cbiAgICAgKi9cbiAgICB2YXIgZ2V0U3ltYm9sc0luID0gIW5hdGl2ZUdldFN5bWJvbHMgPyBzdHViQXJyYXkgOiBmdW5jdGlvbihvYmplY3QpIHtcbiAgICAgIHZhciByZXN1bHQgPSBbXTtcbiAgICAgIHdoaWxlIChvYmplY3QpIHtcbiAgICAgICAgYXJyYXlQdXNoKHJlc3VsdCwgZ2V0U3ltYm9scyhvYmplY3QpKTtcbiAgICAgICAgb2JqZWN0ID0gZ2V0UHJvdG90eXBlKG9iamVjdCk7XG4gICAgICB9XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBHZXRzIHRoZSBgdG9TdHJpbmdUYWdgIG9mIGB2YWx1ZWAuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIHF1ZXJ5LlxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IFJldHVybnMgdGhlIGB0b1N0cmluZ1RhZ2AuXG4gICAgICovXG4gICAgdmFyIGdldFRhZyA9IGJhc2VHZXRUYWc7XG5cbiAgICAvLyBGYWxsYmFjayBmb3IgZGF0YSB2aWV3cywgbWFwcywgc2V0cywgYW5kIHdlYWsgbWFwcyBpbiBJRSAxMSBhbmQgcHJvbWlzZXMgaW4gTm9kZS5qcyA8IDYuXG4gICAgaWYgKChEYXRhVmlldyAmJiBnZXRUYWcobmV3IERhdGFWaWV3KG5ldyBBcnJheUJ1ZmZlcigxKSkpICE9IGRhdGFWaWV3VGFnKSB8fFxuICAgICAgICAoTWFwICYmIGdldFRhZyhuZXcgTWFwKSAhPSBtYXBUYWcpIHx8XG4gICAgICAgIChQcm9taXNlICYmIGdldFRhZyhQcm9taXNlLnJlc29sdmUoKSkgIT0gcHJvbWlzZVRhZykgfHxcbiAgICAgICAgKFNldCAmJiBnZXRUYWcobmV3IFNldCkgIT0gc2V0VGFnKSB8fFxuICAgICAgICAoV2Vha01hcCAmJiBnZXRUYWcobmV3IFdlYWtNYXApICE9IHdlYWtNYXBUYWcpKSB7XG4gICAgICBnZXRUYWcgPSBmdW5jdGlvbih2YWx1ZSkge1xuICAgICAgICB2YXIgcmVzdWx0ID0gYmFzZUdldFRhZyh2YWx1ZSksXG4gICAgICAgICAgICBDdG9yID0gcmVzdWx0ID09IG9iamVjdFRhZyA/IHZhbHVlLmNvbnN0cnVjdG9yIDogdW5kZWZpbmVkLFxuICAgICAgICAgICAgY3RvclN0cmluZyA9IEN0b3IgPyB0b1NvdXJjZShDdG9yKSA6ICcnO1xuXG4gICAgICAgIGlmIChjdG9yU3RyaW5nKSB7XG4gICAgICAgICAgc3dpdGNoIChjdG9yU3RyaW5nKSB7XG4gICAgICAgICAgICBjYXNlIGRhdGFWaWV3Q3RvclN0cmluZzogcmV0dXJuIGRhdGFWaWV3VGFnO1xuICAgICAgICAgICAgY2FzZSBtYXBDdG9yU3RyaW5nOiByZXR1cm4gbWFwVGFnO1xuICAgICAgICAgICAgY2FzZSBwcm9taXNlQ3RvclN0cmluZzogcmV0dXJuIHByb21pc2VUYWc7XG4gICAgICAgICAgICBjYXNlIHNldEN0b3JTdHJpbmc6IHJldHVybiBzZXRUYWc7XG4gICAgICAgICAgICBjYXNlIHdlYWtNYXBDdG9yU3RyaW5nOiByZXR1cm4gd2Vha01hcFRhZztcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgIH07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0cyB0aGUgdmlldywgYXBwbHlpbmcgYW55IGB0cmFuc2Zvcm1zYCB0byB0aGUgYHN0YXJ0YCBhbmQgYGVuZGAgcG9zaXRpb25zLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gc3RhcnQgVGhlIHN0YXJ0IG9mIHRoZSB2aWV3LlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBlbmQgVGhlIGVuZCBvZiB0aGUgdmlldy5cbiAgICAgKiBAcGFyYW0ge0FycmF5fSB0cmFuc2Zvcm1zIFRoZSB0cmFuc2Zvcm1hdGlvbnMgdG8gYXBwbHkgdG8gdGhlIHZpZXcuXG4gICAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyBhbiBvYmplY3QgY29udGFpbmluZyB0aGUgYHN0YXJ0YCBhbmQgYGVuZGBcbiAgICAgKiAgcG9zaXRpb25zIG9mIHRoZSB2aWV3LlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGdldFZpZXcoc3RhcnQsIGVuZCwgdHJhbnNmb3Jtcykge1xuICAgICAgdmFyIGluZGV4ID0gLTEsXG4gICAgICAgICAgbGVuZ3RoID0gdHJhbnNmb3Jtcy5sZW5ndGg7XG5cbiAgICAgIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XG4gICAgICAgIHZhciBkYXRhID0gdHJhbnNmb3Jtc1tpbmRleF0sXG4gICAgICAgICAgICBzaXplID0gZGF0YS5zaXplO1xuXG4gICAgICAgIHN3aXRjaCAoZGF0YS50eXBlKSB7XG4gICAgICAgICAgY2FzZSAnZHJvcCc6ICAgICAgc3RhcnQgKz0gc2l6ZTsgYnJlYWs7XG4gICAgICAgICAgY2FzZSAnZHJvcFJpZ2h0JzogZW5kIC09IHNpemU7IGJyZWFrO1xuICAgICAgICAgIGNhc2UgJ3Rha2UnOiAgICAgIGVuZCA9IG5hdGl2ZU1pbihlbmQsIHN0YXJ0ICsgc2l6ZSk7IGJyZWFrO1xuICAgICAgICAgIGNhc2UgJ3Rha2VSaWdodCc6IHN0YXJ0ID0gbmF0aXZlTWF4KHN0YXJ0LCBlbmQgLSBzaXplKTsgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiB7ICdzdGFydCc6IHN0YXJ0LCAnZW5kJzogZW5kIH07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRXh0cmFjdHMgd3JhcHBlciBkZXRhaWxzIGZyb20gdGhlIGBzb3VyY2VgIGJvZHkgY29tbWVudC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IHNvdXJjZSBUaGUgc291cmNlIHRvIGluc3BlY3QuXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSB3cmFwcGVyIGRldGFpbHMuXG4gICAgICovXG4gICAgZnVuY3Rpb24gZ2V0V3JhcERldGFpbHMoc291cmNlKSB7XG4gICAgICB2YXIgbWF0Y2ggPSBzb3VyY2UubWF0Y2gocmVXcmFwRGV0YWlscyk7XG4gICAgICByZXR1cm4gbWF0Y2ggPyBtYXRjaFsxXS5zcGxpdChyZVNwbGl0RGV0YWlscykgOiBbXTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDaGVja3MgaWYgYHBhdGhgIGV4aXN0cyBvbiBgb2JqZWN0YC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIHF1ZXJ5LlxuICAgICAqIEBwYXJhbSB7QXJyYXl8c3RyaW5nfSBwYXRoIFRoZSBwYXRoIHRvIGNoZWNrLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGhhc0Z1bmMgVGhlIGZ1bmN0aW9uIHRvIGNoZWNrIHByb3BlcnRpZXMuXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGBwYXRoYCBleGlzdHMsIGVsc2UgYGZhbHNlYC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBoYXNQYXRoKG9iamVjdCwgcGF0aCwgaGFzRnVuYykge1xuICAgICAgcGF0aCA9IGNhc3RQYXRoKHBhdGgsIG9iamVjdCk7XG5cbiAgICAgIHZhciBpbmRleCA9IC0xLFxuICAgICAgICAgIGxlbmd0aCA9IHBhdGgubGVuZ3RoLFxuICAgICAgICAgIHJlc3VsdCA9IGZhbHNlO1xuXG4gICAgICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgICAgICB2YXIga2V5ID0gdG9LZXkocGF0aFtpbmRleF0pO1xuICAgICAgICBpZiAoIShyZXN1bHQgPSBvYmplY3QgIT0gbnVsbCAmJiBoYXNGdW5jKG9iamVjdCwga2V5KSkpIHtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgICBvYmplY3QgPSBvYmplY3Rba2V5XTtcbiAgICAgIH1cbiAgICAgIGlmIChyZXN1bHQgfHwgKytpbmRleCAhPSBsZW5ndGgpIHtcbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgIH1cbiAgICAgIGxlbmd0aCA9IG9iamVjdCA9PSBudWxsID8gMCA6IG9iamVjdC5sZW5ndGg7XG4gICAgICByZXR1cm4gISFsZW5ndGggJiYgaXNMZW5ndGgobGVuZ3RoKSAmJiBpc0luZGV4KGtleSwgbGVuZ3RoKSAmJlxuICAgICAgICAoaXNBcnJheShvYmplY3QpIHx8IGlzQXJndW1lbnRzKG9iamVjdCkpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEluaXRpYWxpemVzIGFuIGFycmF5IGNsb25lLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gY2xvbmUuXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBpbml0aWFsaXplZCBjbG9uZS5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBpbml0Q2xvbmVBcnJheShhcnJheSkge1xuICAgICAgdmFyIGxlbmd0aCA9IGFycmF5Lmxlbmd0aCxcbiAgICAgICAgICByZXN1bHQgPSBuZXcgYXJyYXkuY29uc3RydWN0b3IobGVuZ3RoKTtcblxuICAgICAgLy8gQWRkIHByb3BlcnRpZXMgYXNzaWduZWQgYnkgYFJlZ0V4cCNleGVjYC5cbiAgICAgIGlmIChsZW5ndGggJiYgdHlwZW9mIGFycmF5WzBdID09ICdzdHJpbmcnICYmIGhhc093blByb3BlcnR5LmNhbGwoYXJyYXksICdpbmRleCcpKSB7XG4gICAgICAgIHJlc3VsdC5pbmRleCA9IGFycmF5LmluZGV4O1xuICAgICAgICByZXN1bHQuaW5wdXQgPSBhcnJheS5pbnB1dDtcbiAgICAgIH1cbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogSW5pdGlhbGl6ZXMgYW4gb2JqZWN0IGNsb25lLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gY2xvbmUuXG4gICAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyB0aGUgaW5pdGlhbGl6ZWQgY2xvbmUuXG4gICAgICovXG4gICAgZnVuY3Rpb24gaW5pdENsb25lT2JqZWN0KG9iamVjdCkge1xuICAgICAgcmV0dXJuICh0eXBlb2Ygb2JqZWN0LmNvbnN0cnVjdG9yID09ICdmdW5jdGlvbicgJiYgIWlzUHJvdG90eXBlKG9iamVjdCkpXG4gICAgICAgID8gYmFzZUNyZWF0ZShnZXRQcm90b3R5cGUob2JqZWN0KSlcbiAgICAgICAgOiB7fTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBJbml0aWFsaXplcyBhbiBvYmplY3QgY2xvbmUgYmFzZWQgb24gaXRzIGB0b1N0cmluZ1RhZ2AuXG4gICAgICpcbiAgICAgKiAqKk5vdGU6KiogVGhpcyBmdW5jdGlvbiBvbmx5IHN1cHBvcnRzIGNsb25pbmcgdmFsdWVzIHdpdGggdGFncyBvZlxuICAgICAqIGBCb29sZWFuYCwgYERhdGVgLCBgRXJyb3JgLCBgTWFwYCwgYE51bWJlcmAsIGBSZWdFeHBgLCBgU2V0YCwgb3IgYFN0cmluZ2AuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBjbG9uZS5cbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gdGFnIFRoZSBgdG9TdHJpbmdUYWdgIG9mIHRoZSBvYmplY3QgdG8gY2xvbmUuXG4gICAgICogQHBhcmFtIHtib29sZWFufSBbaXNEZWVwXSBTcGVjaWZ5IGEgZGVlcCBjbG9uZS5cbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIHRoZSBpbml0aWFsaXplZCBjbG9uZS5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBpbml0Q2xvbmVCeVRhZyhvYmplY3QsIHRhZywgaXNEZWVwKSB7XG4gICAgICB2YXIgQ3RvciA9IG9iamVjdC5jb25zdHJ1Y3RvcjtcbiAgICAgIHN3aXRjaCAodGFnKSB7XG4gICAgICAgIGNhc2UgYXJyYXlCdWZmZXJUYWc6XG4gICAgICAgICAgcmV0dXJuIGNsb25lQXJyYXlCdWZmZXIob2JqZWN0KTtcblxuICAgICAgICBjYXNlIGJvb2xUYWc6XG4gICAgICAgIGNhc2UgZGF0ZVRhZzpcbiAgICAgICAgICByZXR1cm4gbmV3IEN0b3IoK29iamVjdCk7XG5cbiAgICAgICAgY2FzZSBkYXRhVmlld1RhZzpcbiAgICAgICAgICByZXR1cm4gY2xvbmVEYXRhVmlldyhvYmplY3QsIGlzRGVlcCk7XG5cbiAgICAgICAgY2FzZSBmbG9hdDMyVGFnOiBjYXNlIGZsb2F0NjRUYWc6XG4gICAgICAgIGNhc2UgaW50OFRhZzogY2FzZSBpbnQxNlRhZzogY2FzZSBpbnQzMlRhZzpcbiAgICAgICAgY2FzZSB1aW50OFRhZzogY2FzZSB1aW50OENsYW1wZWRUYWc6IGNhc2UgdWludDE2VGFnOiBjYXNlIHVpbnQzMlRhZzpcbiAgICAgICAgICByZXR1cm4gY2xvbmVUeXBlZEFycmF5KG9iamVjdCwgaXNEZWVwKTtcblxuICAgICAgICBjYXNlIG1hcFRhZzpcbiAgICAgICAgICByZXR1cm4gbmV3IEN0b3I7XG5cbiAgICAgICAgY2FzZSBudW1iZXJUYWc6XG4gICAgICAgIGNhc2Ugc3RyaW5nVGFnOlxuICAgICAgICAgIHJldHVybiBuZXcgQ3RvcihvYmplY3QpO1xuXG4gICAgICAgIGNhc2UgcmVnZXhwVGFnOlxuICAgICAgICAgIHJldHVybiBjbG9uZVJlZ0V4cChvYmplY3QpO1xuXG4gICAgICAgIGNhc2Ugc2V0VGFnOlxuICAgICAgICAgIHJldHVybiBuZXcgQ3RvcjtcblxuICAgICAgICBjYXNlIHN5bWJvbFRhZzpcbiAgICAgICAgICByZXR1cm4gY2xvbmVTeW1ib2wob2JqZWN0KTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBJbnNlcnRzIHdyYXBwZXIgYGRldGFpbHNgIGluIGEgY29tbWVudCBhdCB0aGUgdG9wIG9mIHRoZSBgc291cmNlYCBib2R5LlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gc291cmNlIFRoZSBzb3VyY2UgdG8gbW9kaWZ5LlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gZGV0YWlscyBUaGUgZGV0YWlscyB0byBpbnNlcnQuXG4gICAgICogQHJldHVybnMge3N0cmluZ30gUmV0dXJucyB0aGUgbW9kaWZpZWQgc291cmNlLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGluc2VydFdyYXBEZXRhaWxzKHNvdXJjZSwgZGV0YWlscykge1xuICAgICAgdmFyIGxlbmd0aCA9IGRldGFpbHMubGVuZ3RoO1xuICAgICAgaWYgKCFsZW5ndGgpIHtcbiAgICAgICAgcmV0dXJuIHNvdXJjZTtcbiAgICAgIH1cbiAgICAgIHZhciBsYXN0SW5kZXggPSBsZW5ndGggLSAxO1xuICAgICAgZGV0YWlsc1tsYXN0SW5kZXhdID0gKGxlbmd0aCA+IDEgPyAnJiAnIDogJycpICsgZGV0YWlsc1tsYXN0SW5kZXhdO1xuICAgICAgZGV0YWlscyA9IGRldGFpbHMuam9pbihsZW5ndGggPiAyID8gJywgJyA6ICcgJyk7XG4gICAgICByZXR1cm4gc291cmNlLnJlcGxhY2UocmVXcmFwQ29tbWVudCwgJ3tcXG4vKiBbd3JhcHBlZCB3aXRoICcgKyBkZXRhaWxzICsgJ10gKi9cXG4nKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBhIGZsYXR0ZW5hYmxlIGBhcmd1bWVudHNgIG9iamVjdCBvciBhcnJheS5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgZmxhdHRlbmFibGUsIGVsc2UgYGZhbHNlYC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBpc0ZsYXR0ZW5hYmxlKHZhbHVlKSB7XG4gICAgICByZXR1cm4gaXNBcnJheSh2YWx1ZSkgfHwgaXNBcmd1bWVudHModmFsdWUpIHx8XG4gICAgICAgICEhKHNwcmVhZGFibGVTeW1ib2wgJiYgdmFsdWUgJiYgdmFsdWVbc3ByZWFkYWJsZVN5bWJvbF0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIGEgdmFsaWQgYXJyYXktbGlrZSBpbmRleC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtsZW5ndGg9TUFYX1NBRkVfSU5URUdFUl0gVGhlIHVwcGVyIGJvdW5kcyBvZiBhIHZhbGlkIGluZGV4LlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGEgdmFsaWQgaW5kZXgsIGVsc2UgYGZhbHNlYC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBpc0luZGV4KHZhbHVlLCBsZW5ndGgpIHtcbiAgICAgIHZhciB0eXBlID0gdHlwZW9mIHZhbHVlO1xuICAgICAgbGVuZ3RoID0gbGVuZ3RoID09IG51bGwgPyBNQVhfU0FGRV9JTlRFR0VSIDogbGVuZ3RoO1xuXG4gICAgICByZXR1cm4gISFsZW5ndGggJiZcbiAgICAgICAgKHR5cGUgPT0gJ251bWJlcicgfHxcbiAgICAgICAgICAodHlwZSAhPSAnc3ltYm9sJyAmJiByZUlzVWludC50ZXN0KHZhbHVlKSkpICYmXG4gICAgICAgICAgICAodmFsdWUgPiAtMSAmJiB2YWx1ZSAlIDEgPT0gMCAmJiB2YWx1ZSA8IGxlbmd0aCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2hlY2tzIGlmIHRoZSBnaXZlbiBhcmd1bWVudHMgYXJlIGZyb20gYW4gaXRlcmF0ZWUgY2FsbC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgcG90ZW50aWFsIGl0ZXJhdGVlIHZhbHVlIGFyZ3VtZW50LlxuICAgICAqIEBwYXJhbSB7Kn0gaW5kZXggVGhlIHBvdGVudGlhbCBpdGVyYXRlZSBpbmRleCBvciBrZXkgYXJndW1lbnQuXG4gICAgICogQHBhcmFtIHsqfSBvYmplY3QgVGhlIHBvdGVudGlhbCBpdGVyYXRlZSBvYmplY3QgYXJndW1lbnQuXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIHRoZSBhcmd1bWVudHMgYXJlIGZyb20gYW4gaXRlcmF0ZWUgY2FsbCxcbiAgICAgKiAgZWxzZSBgZmFsc2VgLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGlzSXRlcmF0ZWVDYWxsKHZhbHVlLCBpbmRleCwgb2JqZWN0KSB7XG4gICAgICBpZiAoIWlzT2JqZWN0KG9iamVjdCkpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgICAgdmFyIHR5cGUgPSB0eXBlb2YgaW5kZXg7XG4gICAgICBpZiAodHlwZSA9PSAnbnVtYmVyJ1xuICAgICAgICAgICAgPyAoaXNBcnJheUxpa2Uob2JqZWN0KSAmJiBpc0luZGV4KGluZGV4LCBvYmplY3QubGVuZ3RoKSlcbiAgICAgICAgICAgIDogKHR5cGUgPT0gJ3N0cmluZycgJiYgaW5kZXggaW4gb2JqZWN0KVxuICAgICAgICAgICkge1xuICAgICAgICByZXR1cm4gZXEob2JqZWN0W2luZGV4XSwgdmFsdWUpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIGEgcHJvcGVydHkgbmFtZSBhbmQgbm90IGEgcHJvcGVydHkgcGF0aC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gICAgICogQHBhcmFtIHtPYmplY3R9IFtvYmplY3RdIFRoZSBvYmplY3QgdG8gcXVlcnkga2V5cyBvbi5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhIHByb3BlcnR5IG5hbWUsIGVsc2UgYGZhbHNlYC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBpc0tleSh2YWx1ZSwgb2JqZWN0KSB7XG4gICAgICBpZiAoaXNBcnJheSh2YWx1ZSkpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgICAgdmFyIHR5cGUgPSB0eXBlb2YgdmFsdWU7XG4gICAgICBpZiAodHlwZSA9PSAnbnVtYmVyJyB8fCB0eXBlID09ICdzeW1ib2wnIHx8IHR5cGUgPT0gJ2Jvb2xlYW4nIHx8XG4gICAgICAgICAgdmFsdWUgPT0gbnVsbCB8fCBpc1N5bWJvbCh2YWx1ZSkpIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9XG4gICAgICByZXR1cm4gcmVJc1BsYWluUHJvcC50ZXN0KHZhbHVlKSB8fCAhcmVJc0RlZXBQcm9wLnRlc3QodmFsdWUpIHx8XG4gICAgICAgIChvYmplY3QgIT0gbnVsbCAmJiB2YWx1ZSBpbiBPYmplY3Qob2JqZWN0KSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgc3VpdGFibGUgZm9yIHVzZSBhcyB1bmlxdWUgb2JqZWN0IGtleS5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgc3VpdGFibGUsIGVsc2UgYGZhbHNlYC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBpc0tleWFibGUodmFsdWUpIHtcbiAgICAgIHZhciB0eXBlID0gdHlwZW9mIHZhbHVlO1xuICAgICAgcmV0dXJuICh0eXBlID09ICdzdHJpbmcnIHx8IHR5cGUgPT0gJ251bWJlcicgfHwgdHlwZSA9PSAnc3ltYm9sJyB8fCB0eXBlID09ICdib29sZWFuJylcbiAgICAgICAgPyAodmFsdWUgIT09ICdfX3Byb3RvX18nKVxuICAgICAgICA6ICh2YWx1ZSA9PT0gbnVsbCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2hlY2tzIGlmIGBmdW5jYCBoYXMgYSBsYXp5IGNvdW50ZXJwYXJ0LlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byBjaGVjay5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYGZ1bmNgIGhhcyBhIGxhenkgY291bnRlcnBhcnQsXG4gICAgICogIGVsc2UgYGZhbHNlYC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBpc0xhemlhYmxlKGZ1bmMpIHtcbiAgICAgIHZhciBmdW5jTmFtZSA9IGdldEZ1bmNOYW1lKGZ1bmMpLFxuICAgICAgICAgIG90aGVyID0gbG9kYXNoW2Z1bmNOYW1lXTtcblxuICAgICAgaWYgKHR5cGVvZiBvdGhlciAhPSAnZnVuY3Rpb24nIHx8ICEoZnVuY05hbWUgaW4gTGF6eVdyYXBwZXIucHJvdG90eXBlKSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgICBpZiAoZnVuYyA9PT0gb3RoZXIpIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9XG4gICAgICB2YXIgZGF0YSA9IGdldERhdGEob3RoZXIpO1xuICAgICAgcmV0dXJuICEhZGF0YSAmJiBmdW5jID09PSBkYXRhWzBdO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENoZWNrcyBpZiBgZnVuY2AgaGFzIGl0cyBzb3VyY2UgbWFza2VkLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byBjaGVjay5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYGZ1bmNgIGlzIG1hc2tlZCwgZWxzZSBgZmFsc2VgLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGlzTWFza2VkKGZ1bmMpIHtcbiAgICAgIHJldHVybiAhIW1hc2tTcmNLZXkgJiYgKG1hc2tTcmNLZXkgaW4gZnVuYyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2hlY2tzIGlmIGBmdW5jYCBpcyBjYXBhYmxlIG9mIGJlaW5nIG1hc2tlZC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGBmdW5jYCBpcyBtYXNrYWJsZSwgZWxzZSBgZmFsc2VgLlxuICAgICAqL1xuICAgIHZhciBpc01hc2thYmxlID0gY29yZUpzRGF0YSA/IGlzRnVuY3Rpb24gOiBzdHViRmFsc2U7XG5cbiAgICAvKipcbiAgICAgKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBsaWtlbHkgYSBwcm90b3R5cGUgb2JqZWN0LlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhIHByb3RvdHlwZSwgZWxzZSBgZmFsc2VgLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGlzUHJvdG90eXBlKHZhbHVlKSB7XG4gICAgICB2YXIgQ3RvciA9IHZhbHVlICYmIHZhbHVlLmNvbnN0cnVjdG9yLFxuICAgICAgICAgIHByb3RvID0gKHR5cGVvZiBDdG9yID09ICdmdW5jdGlvbicgJiYgQ3Rvci5wcm90b3R5cGUpIHx8IG9iamVjdFByb3RvO1xuXG4gICAgICByZXR1cm4gdmFsdWUgPT09IHByb3RvO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIHN1aXRhYmxlIGZvciBzdHJpY3QgZXF1YWxpdHkgY29tcGFyaXNvbnMsIGkuZS4gYD09PWAuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlmIHN1aXRhYmxlIGZvciBzdHJpY3RcbiAgICAgKiAgZXF1YWxpdHkgY29tcGFyaXNvbnMsIGVsc2UgYGZhbHNlYC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBpc1N0cmljdENvbXBhcmFibGUodmFsdWUpIHtcbiAgICAgIHJldHVybiB2YWx1ZSA9PT0gdmFsdWUgJiYgIWlzT2JqZWN0KHZhbHVlKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBBIHNwZWNpYWxpemVkIHZlcnNpb24gb2YgYG1hdGNoZXNQcm9wZXJ0eWAgZm9yIHNvdXJjZSB2YWx1ZXMgc3VpdGFibGVcbiAgICAgKiBmb3Igc3RyaWN0IGVxdWFsaXR5IGNvbXBhcmlzb25zLCBpLmUuIGA9PT1gLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30ga2V5IFRoZSBrZXkgb2YgdGhlIHByb3BlcnR5IHRvIGdldC5cbiAgICAgKiBAcGFyYW0geyp9IHNyY1ZhbHVlIFRoZSB2YWx1ZSB0byBtYXRjaC5cbiAgICAgKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBzcGVjIGZ1bmN0aW9uLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIG1hdGNoZXNTdHJpY3RDb21wYXJhYmxlKGtleSwgc3JjVmFsdWUpIHtcbiAgICAgIHJldHVybiBmdW5jdGlvbihvYmplY3QpIHtcbiAgICAgICAgaWYgKG9iamVjdCA9PSBudWxsKSB7XG4gICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBvYmplY3Rba2V5XSA9PT0gc3JjVmFsdWUgJiZcbiAgICAgICAgICAoc3JjVmFsdWUgIT09IHVuZGVmaW5lZCB8fCAoa2V5IGluIE9iamVjdChvYmplY3QpKSk7XG4gICAgICB9O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEEgc3BlY2lhbGl6ZWQgdmVyc2lvbiBvZiBgXy5tZW1vaXplYCB3aGljaCBjbGVhcnMgdGhlIG1lbW9pemVkIGZ1bmN0aW9uJ3NcbiAgICAgKiBjYWNoZSB3aGVuIGl0IGV4Y2VlZHMgYE1BWF9NRU1PSVpFX1NJWkVgLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byBoYXZlIGl0cyBvdXRwdXQgbWVtb2l6ZWQuXG4gICAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgbWVtb2l6ZWQgZnVuY3Rpb24uXG4gICAgICovXG4gICAgZnVuY3Rpb24gbWVtb2l6ZUNhcHBlZChmdW5jKSB7XG4gICAgICB2YXIgcmVzdWx0ID0gbWVtb2l6ZShmdW5jLCBmdW5jdGlvbihrZXkpIHtcbiAgICAgICAgaWYgKGNhY2hlLnNpemUgPT09IE1BWF9NRU1PSVpFX1NJWkUpIHtcbiAgICAgICAgICBjYWNoZS5jbGVhcigpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBrZXk7XG4gICAgICB9KTtcblxuICAgICAgdmFyIGNhY2hlID0gcmVzdWx0LmNhY2hlO1xuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBNZXJnZXMgdGhlIGZ1bmN0aW9uIG1ldGFkYXRhIG9mIGBzb3VyY2VgIGludG8gYGRhdGFgLlxuICAgICAqXG4gICAgICogTWVyZ2luZyBtZXRhZGF0YSByZWR1Y2VzIHRoZSBudW1iZXIgb2Ygd3JhcHBlcnMgdXNlZCB0byBpbnZva2UgYSBmdW5jdGlvbi5cbiAgICAgKiBUaGlzIGlzIHBvc3NpYmxlIGJlY2F1c2UgbWV0aG9kcyBsaWtlIGBfLmJpbmRgLCBgXy5jdXJyeWAsIGFuZCBgXy5wYXJ0aWFsYFxuICAgICAqIG1heSBiZSBhcHBsaWVkIHJlZ2FyZGxlc3Mgb2YgZXhlY3V0aW9uIG9yZGVyLiBNZXRob2RzIGxpa2UgYF8uYXJ5YCBhbmRcbiAgICAgKiBgXy5yZWFyZ2AgbW9kaWZ5IGZ1bmN0aW9uIGFyZ3VtZW50cywgbWFraW5nIHRoZSBvcmRlciBpbiB3aGljaCB0aGV5IGFyZVxuICAgICAqIGV4ZWN1dGVkIGltcG9ydGFudCwgcHJldmVudGluZyB0aGUgbWVyZ2luZyBvZiBtZXRhZGF0YS4gSG93ZXZlciwgd2UgbWFrZVxuICAgICAqIGFuIGV4Y2VwdGlvbiBmb3IgYSBzYWZlIGNvbWJpbmVkIGNhc2Ugd2hlcmUgY3VycmllZCBmdW5jdGlvbnMgaGF2ZSBgXy5hcnlgXG4gICAgICogYW5kIG9yIGBfLnJlYXJnYCBhcHBsaWVkLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBkYXRhIFRoZSBkZXN0aW5hdGlvbiBtZXRhZGF0YS5cbiAgICAgKiBAcGFyYW0ge0FycmF5fSBzb3VyY2UgVGhlIHNvdXJjZSBtZXRhZGF0YS5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgYGRhdGFgLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIG1lcmdlRGF0YShkYXRhLCBzb3VyY2UpIHtcbiAgICAgIHZhciBiaXRtYXNrID0gZGF0YVsxXSxcbiAgICAgICAgICBzcmNCaXRtYXNrID0gc291cmNlWzFdLFxuICAgICAgICAgIG5ld0JpdG1hc2sgPSBiaXRtYXNrIHwgc3JjQml0bWFzayxcbiAgICAgICAgICBpc0NvbW1vbiA9IG5ld0JpdG1hc2sgPCAoV1JBUF9CSU5EX0ZMQUcgfCBXUkFQX0JJTkRfS0VZX0ZMQUcgfCBXUkFQX0FSWV9GTEFHKTtcblxuICAgICAgdmFyIGlzQ29tYm8gPVxuICAgICAgICAoKHNyY0JpdG1hc2sgPT0gV1JBUF9BUllfRkxBRykgJiYgKGJpdG1hc2sgPT0gV1JBUF9DVVJSWV9GTEFHKSkgfHxcbiAgICAgICAgKChzcmNCaXRtYXNrID09IFdSQVBfQVJZX0ZMQUcpICYmIChiaXRtYXNrID09IFdSQVBfUkVBUkdfRkxBRykgJiYgKGRhdGFbN10ubGVuZ3RoIDw9IHNvdXJjZVs4XSkpIHx8XG4gICAgICAgICgoc3JjQml0bWFzayA9PSAoV1JBUF9BUllfRkxBRyB8IFdSQVBfUkVBUkdfRkxBRykpICYmIChzb3VyY2VbN10ubGVuZ3RoIDw9IHNvdXJjZVs4XSkgJiYgKGJpdG1hc2sgPT0gV1JBUF9DVVJSWV9GTEFHKSk7XG5cbiAgICAgIC8vIEV4aXQgZWFybHkgaWYgbWV0YWRhdGEgY2FuJ3QgYmUgbWVyZ2VkLlxuICAgICAgaWYgKCEoaXNDb21tb24gfHwgaXNDb21ibykpIHtcbiAgICAgICAgcmV0dXJuIGRhdGE7XG4gICAgICB9XG4gICAgICAvLyBVc2Ugc291cmNlIGB0aGlzQXJnYCBpZiBhdmFpbGFibGUuXG4gICAgICBpZiAoc3JjQml0bWFzayAmIFdSQVBfQklORF9GTEFHKSB7XG4gICAgICAgIGRhdGFbMl0gPSBzb3VyY2VbMl07XG4gICAgICAgIC8vIFNldCB3aGVuIGN1cnJ5aW5nIGEgYm91bmQgZnVuY3Rpb24uXG4gICAgICAgIG5ld0JpdG1hc2sgfD0gYml0bWFzayAmIFdSQVBfQklORF9GTEFHID8gMCA6IFdSQVBfQ1VSUllfQk9VTkRfRkxBRztcbiAgICAgIH1cbiAgICAgIC8vIENvbXBvc2UgcGFydGlhbCBhcmd1bWVudHMuXG4gICAgICB2YXIgdmFsdWUgPSBzb3VyY2VbM107XG4gICAgICBpZiAodmFsdWUpIHtcbiAgICAgICAgdmFyIHBhcnRpYWxzID0gZGF0YVszXTtcbiAgICAgICAgZGF0YVszXSA9IHBhcnRpYWxzID8gY29tcG9zZUFyZ3MocGFydGlhbHMsIHZhbHVlLCBzb3VyY2VbNF0pIDogdmFsdWU7XG4gICAgICAgIGRhdGFbNF0gPSBwYXJ0aWFscyA/IHJlcGxhY2VIb2xkZXJzKGRhdGFbM10sIFBMQUNFSE9MREVSKSA6IHNvdXJjZVs0XTtcbiAgICAgIH1cbiAgICAgIC8vIENvbXBvc2UgcGFydGlhbCByaWdodCBhcmd1bWVudHMuXG4gICAgICB2YWx1ZSA9IHNvdXJjZVs1XTtcbiAgICAgIGlmICh2YWx1ZSkge1xuICAgICAgICBwYXJ0aWFscyA9IGRhdGFbNV07XG4gICAgICAgIGRhdGFbNV0gPSBwYXJ0aWFscyA/IGNvbXBvc2VBcmdzUmlnaHQocGFydGlhbHMsIHZhbHVlLCBzb3VyY2VbNl0pIDogdmFsdWU7XG4gICAgICAgIGRhdGFbNl0gPSBwYXJ0aWFscyA/IHJlcGxhY2VIb2xkZXJzKGRhdGFbNV0sIFBMQUNFSE9MREVSKSA6IHNvdXJjZVs2XTtcbiAgICAgIH1cbiAgICAgIC8vIFVzZSBzb3VyY2UgYGFyZ1Bvc2AgaWYgYXZhaWxhYmxlLlxuICAgICAgdmFsdWUgPSBzb3VyY2VbN107XG4gICAgICBpZiAodmFsdWUpIHtcbiAgICAgICAgZGF0YVs3XSA9IHZhbHVlO1xuICAgICAgfVxuICAgICAgLy8gVXNlIHNvdXJjZSBgYXJ5YCBpZiBpdCdzIHNtYWxsZXIuXG4gICAgICBpZiAoc3JjQml0bWFzayAmIFdSQVBfQVJZX0ZMQUcpIHtcbiAgICAgICAgZGF0YVs4XSA9IGRhdGFbOF0gPT0gbnVsbCA/IHNvdXJjZVs4XSA6IG5hdGl2ZU1pbihkYXRhWzhdLCBzb3VyY2VbOF0pO1xuICAgICAgfVxuICAgICAgLy8gVXNlIHNvdXJjZSBgYXJpdHlgIGlmIG9uZSBpcyBub3QgcHJvdmlkZWQuXG4gICAgICBpZiAoZGF0YVs5XSA9PSBudWxsKSB7XG4gICAgICAgIGRhdGFbOV0gPSBzb3VyY2VbOV07XG4gICAgICB9XG4gICAgICAvLyBVc2Ugc291cmNlIGBmdW5jYCBhbmQgbWVyZ2UgYml0bWFza3MuXG4gICAgICBkYXRhWzBdID0gc291cmNlWzBdO1xuICAgICAgZGF0YVsxXSA9IG5ld0JpdG1hc2s7XG5cbiAgICAgIHJldHVybiBkYXRhO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoaXMgZnVuY3Rpb24gaXMgbGlrZVxuICAgICAqIFtgT2JqZWN0LmtleXNgXShodHRwOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi83LjAvI3NlYy1vYmplY3Qua2V5cylcbiAgICAgKiBleGNlcHQgdGhhdCBpdCBpbmNsdWRlcyBpbmhlcml0ZWQgZW51bWVyYWJsZSBwcm9wZXJ0aWVzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gcXVlcnkuXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBhcnJheSBvZiBwcm9wZXJ0eSBuYW1lcy5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBuYXRpdmVLZXlzSW4ob2JqZWN0KSB7XG4gICAgICB2YXIgcmVzdWx0ID0gW107XG4gICAgICBpZiAob2JqZWN0ICE9IG51bGwpIHtcbiAgICAgICAgZm9yICh2YXIga2V5IGluIE9iamVjdChvYmplY3QpKSB7XG4gICAgICAgICAgcmVzdWx0LnB1c2goa2V5KTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDb252ZXJ0cyBgdmFsdWVgIHRvIGEgc3RyaW5nIHVzaW5nIGBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nYC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY29udmVydC5cbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfSBSZXR1cm5zIHRoZSBjb252ZXJ0ZWQgc3RyaW5nLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIG9iamVjdFRvU3RyaW5nKHZhbHVlKSB7XG4gICAgICByZXR1cm4gbmF0aXZlT2JqZWN0VG9TdHJpbmcuY2FsbCh2YWx1ZSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQSBzcGVjaWFsaXplZCB2ZXJzaW9uIG9mIGBiYXNlUmVzdGAgd2hpY2ggdHJhbnNmb3JtcyB0aGUgcmVzdCBhcnJheS5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gZnVuYyBUaGUgZnVuY3Rpb24gdG8gYXBwbHkgYSByZXN0IHBhcmFtZXRlciB0by5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW3N0YXJ0PWZ1bmMubGVuZ3RoLTFdIFRoZSBzdGFydCBwb3NpdGlvbiBvZiB0aGUgcmVzdCBwYXJhbWV0ZXIuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gdHJhbnNmb3JtIFRoZSByZXN0IGFycmF5IHRyYW5zZm9ybS5cbiAgICAgKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBmdW5jdGlvbi5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBvdmVyUmVzdChmdW5jLCBzdGFydCwgdHJhbnNmb3JtKSB7XG4gICAgICBzdGFydCA9IG5hdGl2ZU1heChzdGFydCA9PT0gdW5kZWZpbmVkID8gKGZ1bmMubGVuZ3RoIC0gMSkgOiBzdGFydCwgMCk7XG4gICAgICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgICAgIHZhciBhcmdzID0gYXJndW1lbnRzLFxuICAgICAgICAgICAgaW5kZXggPSAtMSxcbiAgICAgICAgICAgIGxlbmd0aCA9IG5hdGl2ZU1heChhcmdzLmxlbmd0aCAtIHN0YXJ0LCAwKSxcbiAgICAgICAgICAgIGFycmF5ID0gQXJyYXkobGVuZ3RoKTtcblxuICAgICAgICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgICAgICAgIGFycmF5W2luZGV4XSA9IGFyZ3Nbc3RhcnQgKyBpbmRleF07XG4gICAgICAgIH1cbiAgICAgICAgaW5kZXggPSAtMTtcbiAgICAgICAgdmFyIG90aGVyQXJncyA9IEFycmF5KHN0YXJ0ICsgMSk7XG4gICAgICAgIHdoaWxlICgrK2luZGV4IDwgc3RhcnQpIHtcbiAgICAgICAgICBvdGhlckFyZ3NbaW5kZXhdID0gYXJnc1tpbmRleF07XG4gICAgICAgIH1cbiAgICAgICAgb3RoZXJBcmdzW3N0YXJ0XSA9IHRyYW5zZm9ybShhcnJheSk7XG4gICAgICAgIHJldHVybiBhcHBseShmdW5jLCB0aGlzLCBvdGhlckFyZ3MpO1xuICAgICAgfTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXRzIHRoZSBwYXJlbnQgdmFsdWUgYXQgYHBhdGhgIG9mIGBvYmplY3RgLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gcXVlcnkuXG4gICAgICogQHBhcmFtIHtBcnJheX0gcGF0aCBUaGUgcGF0aCB0byBnZXQgdGhlIHBhcmVudCB2YWx1ZSBvZi5cbiAgICAgKiBAcmV0dXJucyB7Kn0gUmV0dXJucyB0aGUgcGFyZW50IHZhbHVlLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIHBhcmVudChvYmplY3QsIHBhdGgpIHtcbiAgICAgIHJldHVybiBwYXRoLmxlbmd0aCA8IDIgPyBvYmplY3QgOiBiYXNlR2V0KG9iamVjdCwgYmFzZVNsaWNlKHBhdGgsIDAsIC0xKSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmVvcmRlciBgYXJyYXlgIGFjY29yZGluZyB0byB0aGUgc3BlY2lmaWVkIGluZGV4ZXMgd2hlcmUgdGhlIGVsZW1lbnQgYXRcbiAgICAgKiB0aGUgZmlyc3QgaW5kZXggaXMgYXNzaWduZWQgYXMgdGhlIGZpcnN0IGVsZW1lbnQsIHRoZSBlbGVtZW50IGF0XG4gICAgICogdGhlIHNlY29uZCBpbmRleCBpcyBhc3NpZ25lZCBhcyB0aGUgc2Vjb25kIGVsZW1lbnQsIGFuZCBzbyBvbi5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIHJlb3JkZXIuXG4gICAgICogQHBhcmFtIHtBcnJheX0gaW5kZXhlcyBUaGUgYXJyYW5nZWQgYXJyYXkgaW5kZXhlcy5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgYGFycmF5YC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiByZW9yZGVyKGFycmF5LCBpbmRleGVzKSB7XG4gICAgICB2YXIgYXJyTGVuZ3RoID0gYXJyYXkubGVuZ3RoLFxuICAgICAgICAgIGxlbmd0aCA9IG5hdGl2ZU1pbihpbmRleGVzLmxlbmd0aCwgYXJyTGVuZ3RoKSxcbiAgICAgICAgICBvbGRBcnJheSA9IGNvcHlBcnJheShhcnJheSk7XG5cbiAgICAgIHdoaWxlIChsZW5ndGgtLSkge1xuICAgICAgICB2YXIgaW5kZXggPSBpbmRleGVzW2xlbmd0aF07XG4gICAgICAgIGFycmF5W2xlbmd0aF0gPSBpc0luZGV4KGluZGV4LCBhcnJMZW5ndGgpID8gb2xkQXJyYXlbaW5kZXhdIDogdW5kZWZpbmVkO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGFycmF5O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldHMgdGhlIHZhbHVlIGF0IGBrZXlgLCB1bmxlc3MgYGtleWAgaXMgXCJfX3Byb3RvX19cIiBvciBcImNvbnN0cnVjdG9yXCIuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBxdWVyeS5cbiAgICAgKiBAcGFyYW0ge3N0cmluZ30ga2V5IFRoZSBrZXkgb2YgdGhlIHByb3BlcnR5IHRvIGdldC5cbiAgICAgKiBAcmV0dXJucyB7Kn0gUmV0dXJucyB0aGUgcHJvcGVydHkgdmFsdWUuXG4gICAgICovXG4gICAgZnVuY3Rpb24gc2FmZUdldChvYmplY3QsIGtleSkge1xuICAgICAgaWYgKGtleSA9PT0gJ2NvbnN0cnVjdG9yJyAmJiB0eXBlb2Ygb2JqZWN0W2tleV0gPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBpZiAoa2V5ID09ICdfX3Byb3RvX18nKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIG9iamVjdFtrZXldO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFNldHMgbWV0YWRhdGEgZm9yIGBmdW5jYC5cbiAgICAgKlxuICAgICAqICoqTm90ZToqKiBJZiB0aGlzIGZ1bmN0aW9uIGJlY29tZXMgaG90LCBpLmUuIGlzIGludm9rZWQgYSBsb3QgaW4gYSBzaG9ydFxuICAgICAqIHBlcmlvZCBvZiB0aW1lLCBpdCB3aWxsIHRyaXAgaXRzIGJyZWFrZXIgYW5kIHRyYW5zaXRpb24gdG8gYW4gaWRlbnRpdHlcbiAgICAgKiBmdW5jdGlvbiB0byBhdm9pZCBnYXJiYWdlIGNvbGxlY3Rpb24gcGF1c2VzIGluIFY4LiBTZWVcbiAgICAgKiBbVjggaXNzdWUgMjA3MF0oaHR0cHM6Ly9idWdzLmNocm9taXVtLm9yZy9wL3Y4L2lzc3Vlcy9kZXRhaWw/aWQ9MjA3MClcbiAgICAgKiBmb3IgbW9yZSBkZXRhaWxzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byBhc3NvY2lhdGUgbWV0YWRhdGEgd2l0aC5cbiAgICAgKiBAcGFyYW0geyp9IGRhdGEgVGhlIG1ldGFkYXRhLlxuICAgICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyBgZnVuY2AuXG4gICAgICovXG4gICAgdmFyIHNldERhdGEgPSBzaG9ydE91dChiYXNlU2V0RGF0YSk7XG5cbiAgICAvKipcbiAgICAgKiBBIHNpbXBsZSB3cmFwcGVyIGFyb3VuZCB0aGUgZ2xvYmFsIFtgc2V0VGltZW91dGBdKGh0dHBzOi8vbWRuLmlvL3NldFRpbWVvdXQpLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byBkZWxheS5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gd2FpdCBUaGUgbnVtYmVyIG9mIG1pbGxpc2Vjb25kcyB0byBkZWxheSBpbnZvY2F0aW9uLlxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ8T2JqZWN0fSBSZXR1cm5zIHRoZSB0aW1lciBpZCBvciB0aW1lb3V0IG9iamVjdC5cbiAgICAgKi9cbiAgICB2YXIgc2V0VGltZW91dCA9IGN0eFNldFRpbWVvdXQgfHwgZnVuY3Rpb24oZnVuYywgd2FpdCkge1xuICAgICAgcmV0dXJuIHJvb3Quc2V0VGltZW91dChmdW5jLCB3YWl0KTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogU2V0cyB0aGUgYHRvU3RyaW5nYCBtZXRob2Qgb2YgYGZ1bmNgIHRvIHJldHVybiBgc3RyaW5nYC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gZnVuYyBUaGUgZnVuY3Rpb24gdG8gbW9kaWZ5LlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IHN0cmluZyBUaGUgYHRvU3RyaW5nYCByZXN1bHQuXG4gICAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIGBmdW5jYC5cbiAgICAgKi9cbiAgICB2YXIgc2V0VG9TdHJpbmcgPSBzaG9ydE91dChiYXNlU2V0VG9TdHJpbmcpO1xuXG4gICAgLyoqXG4gICAgICogU2V0cyB0aGUgYHRvU3RyaW5nYCBtZXRob2Qgb2YgYHdyYXBwZXJgIHRvIG1pbWljIHRoZSBzb3VyY2Ugb2YgYHJlZmVyZW5jZWBcbiAgICAgKiB3aXRoIHdyYXBwZXIgZGV0YWlscyBpbiBhIGNvbW1lbnQgYXQgdGhlIHRvcCBvZiB0aGUgc291cmNlIGJvZHkuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IHdyYXBwZXIgVGhlIGZ1bmN0aW9uIHRvIG1vZGlmeS5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSByZWZlcmVuY2UgVGhlIHJlZmVyZW5jZSBmdW5jdGlvbi5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gYml0bWFzayBUaGUgYml0bWFzayBmbGFncy4gU2VlIGBjcmVhdGVXcmFwYCBmb3IgbW9yZSBkZXRhaWxzLlxuICAgICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyBgd3JhcHBlcmAuXG4gICAgICovXG4gICAgZnVuY3Rpb24gc2V0V3JhcFRvU3RyaW5nKHdyYXBwZXIsIHJlZmVyZW5jZSwgYml0bWFzaykge1xuICAgICAgdmFyIHNvdXJjZSA9IChyZWZlcmVuY2UgKyAnJyk7XG4gICAgICByZXR1cm4gc2V0VG9TdHJpbmcod3JhcHBlciwgaW5zZXJ0V3JhcERldGFpbHMoc291cmNlLCB1cGRhdGVXcmFwRGV0YWlscyhnZXRXcmFwRGV0YWlscyhzb3VyY2UpLCBiaXRtYXNrKSkpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBmdW5jdGlvbiB0aGF0J2xsIHNob3J0IG91dCBhbmQgaW52b2tlIGBpZGVudGl0eWAgaW5zdGVhZFxuICAgICAqIG9mIGBmdW5jYCB3aGVuIGl0J3MgY2FsbGVkIGBIT1RfQ09VTlRgIG9yIG1vcmUgdGltZXMgaW4gYEhPVF9TUEFOYFxuICAgICAqIG1pbGxpc2Vjb25kcy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gZnVuYyBUaGUgZnVuY3Rpb24gdG8gcmVzdHJpY3QuXG4gICAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgc2hvcnRhYmxlIGZ1bmN0aW9uLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIHNob3J0T3V0KGZ1bmMpIHtcbiAgICAgIHZhciBjb3VudCA9IDAsXG4gICAgICAgICAgbGFzdENhbGxlZCA9IDA7XG5cbiAgICAgIHJldHVybiBmdW5jdGlvbigpIHtcbiAgICAgICAgdmFyIHN0YW1wID0gbmF0aXZlTm93KCksXG4gICAgICAgICAgICByZW1haW5pbmcgPSBIT1RfU1BBTiAtIChzdGFtcCAtIGxhc3RDYWxsZWQpO1xuXG4gICAgICAgIGxhc3RDYWxsZWQgPSBzdGFtcDtcbiAgICAgICAgaWYgKHJlbWFpbmluZyA+IDApIHtcbiAgICAgICAgICBpZiAoKytjb3VudCA+PSBIT1RfQ09VTlQpIHtcbiAgICAgICAgICAgIHJldHVybiBhcmd1bWVudHNbMF07XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGNvdW50ID0gMDtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZnVuYy5hcHBseSh1bmRlZmluZWQsIGFyZ3VtZW50cyk7XG4gICAgICB9O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEEgc3BlY2lhbGl6ZWQgdmVyc2lvbiBvZiBgXy5zaHVmZmxlYCB3aGljaCBtdXRhdGVzIGFuZCBzZXRzIHRoZSBzaXplIG9mIGBhcnJheWAuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBzaHVmZmxlLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbc2l6ZT1hcnJheS5sZW5ndGhdIFRoZSBzaXplIG9mIGBhcnJheWAuXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIGBhcnJheWAuXG4gICAgICovXG4gICAgZnVuY3Rpb24gc2h1ZmZsZVNlbGYoYXJyYXksIHNpemUpIHtcbiAgICAgIHZhciBpbmRleCA9IC0xLFxuICAgICAgICAgIGxlbmd0aCA9IGFycmF5Lmxlbmd0aCxcbiAgICAgICAgICBsYXN0SW5kZXggPSBsZW5ndGggLSAxO1xuXG4gICAgICBzaXplID0gc2l6ZSA9PT0gdW5kZWZpbmVkID8gbGVuZ3RoIDogc2l6ZTtcbiAgICAgIHdoaWxlICgrK2luZGV4IDwgc2l6ZSkge1xuICAgICAgICB2YXIgcmFuZCA9IGJhc2VSYW5kb20oaW5kZXgsIGxhc3RJbmRleCksXG4gICAgICAgICAgICB2YWx1ZSA9IGFycmF5W3JhbmRdO1xuXG4gICAgICAgIGFycmF5W3JhbmRdID0gYXJyYXlbaW5kZXhdO1xuICAgICAgICBhcnJheVtpbmRleF0gPSB2YWx1ZTtcbiAgICAgIH1cbiAgICAgIGFycmF5Lmxlbmd0aCA9IHNpemU7XG4gICAgICByZXR1cm4gYXJyYXk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ29udmVydHMgYHN0cmluZ2AgdG8gYSBwcm9wZXJ0eSBwYXRoIGFycmF5LlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gc3RyaW5nIFRoZSBzdHJpbmcgdG8gY29udmVydC5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIHByb3BlcnR5IHBhdGggYXJyYXkuXG4gICAgICovXG4gICAgdmFyIHN0cmluZ1RvUGF0aCA9IG1lbW9pemVDYXBwZWQoZnVuY3Rpb24oc3RyaW5nKSB7XG4gICAgICB2YXIgcmVzdWx0ID0gW107XG4gICAgICBpZiAoc3RyaW5nLmNoYXJDb2RlQXQoMCkgPT09IDQ2IC8qIC4gKi8pIHtcbiAgICAgICAgcmVzdWx0LnB1c2goJycpO1xuICAgICAgfVxuICAgICAgc3RyaW5nLnJlcGxhY2UocmVQcm9wTmFtZSwgZnVuY3Rpb24obWF0Y2gsIG51bWJlciwgcXVvdGUsIHN1YlN0cmluZykge1xuICAgICAgICByZXN1bHQucHVzaChxdW90ZSA/IHN1YlN0cmluZy5yZXBsYWNlKHJlRXNjYXBlQ2hhciwgJyQxJykgOiAobnVtYmVyIHx8IG1hdGNoKSk7XG4gICAgICB9KTtcbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfSk7XG5cbiAgICAvKipcbiAgICAgKiBDb252ZXJ0cyBgdmFsdWVgIHRvIGEgc3RyaW5nIGtleSBpZiBpdCdzIG5vdCBhIHN0cmluZyBvciBzeW1ib2wuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGluc3BlY3QuXG4gICAgICogQHJldHVybnMge3N0cmluZ3xzeW1ib2x9IFJldHVybnMgdGhlIGtleS5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiB0b0tleSh2YWx1ZSkge1xuICAgICAgaWYgKHR5cGVvZiB2YWx1ZSA9PSAnc3RyaW5nJyB8fCBpc1N5bWJvbCh2YWx1ZSkpIHtcbiAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgICAgfVxuICAgICAgdmFyIHJlc3VsdCA9ICh2YWx1ZSArICcnKTtcbiAgICAgIHJldHVybiAocmVzdWx0ID09ICcwJyAmJiAoMSAvIHZhbHVlKSA9PSAtSU5GSU5JVFkpID8gJy0wJyA6IHJlc3VsdDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDb252ZXJ0cyBgZnVuY2AgdG8gaXRzIHNvdXJjZSBjb2RlLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byBjb252ZXJ0LlxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IFJldHVybnMgdGhlIHNvdXJjZSBjb2RlLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIHRvU291cmNlKGZ1bmMpIHtcbiAgICAgIGlmIChmdW5jICE9IG51bGwpIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICByZXR1cm4gZnVuY1RvU3RyaW5nLmNhbGwoZnVuYyk7XG4gICAgICAgIH0gY2F0Y2ggKGUpIHt9XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgcmV0dXJuIChmdW5jICsgJycpO1xuICAgICAgICB9IGNhdGNoIChlKSB7fVxuICAgICAgfVxuICAgICAgcmV0dXJuICcnO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFVwZGF0ZXMgd3JhcHBlciBgZGV0YWlsc2AgYmFzZWQgb24gYGJpdG1hc2tgIGZsYWdzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IGRldGFpbHMgVGhlIGRldGFpbHMgdG8gbW9kaWZ5LlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBiaXRtYXNrIFRoZSBiaXRtYXNrIGZsYWdzLiBTZWUgYGNyZWF0ZVdyYXBgIGZvciBtb3JlIGRldGFpbHMuXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIGBkZXRhaWxzYC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiB1cGRhdGVXcmFwRGV0YWlscyhkZXRhaWxzLCBiaXRtYXNrKSB7XG4gICAgICBhcnJheUVhY2god3JhcEZsYWdzLCBmdW5jdGlvbihwYWlyKSB7XG4gICAgICAgIHZhciB2YWx1ZSA9ICdfLicgKyBwYWlyWzBdO1xuICAgICAgICBpZiAoKGJpdG1hc2sgJiBwYWlyWzFdKSAmJiAhYXJyYXlJbmNsdWRlcyhkZXRhaWxzLCB2YWx1ZSkpIHtcbiAgICAgICAgICBkZXRhaWxzLnB1c2godmFsdWUpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICAgIHJldHVybiBkZXRhaWxzLnNvcnQoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgY2xvbmUgb2YgYHdyYXBwZXJgLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gd3JhcHBlciBUaGUgd3JhcHBlciB0byBjbG9uZS5cbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIHRoZSBjbG9uZWQgd3JhcHBlci5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiB3cmFwcGVyQ2xvbmUod3JhcHBlcikge1xuICAgICAgaWYgKHdyYXBwZXIgaW5zdGFuY2VvZiBMYXp5V3JhcHBlcikge1xuICAgICAgICByZXR1cm4gd3JhcHBlci5jbG9uZSgpO1xuICAgICAgfVxuICAgICAgdmFyIHJlc3VsdCA9IG5ldyBMb2Rhc2hXcmFwcGVyKHdyYXBwZXIuX193cmFwcGVkX18sIHdyYXBwZXIuX19jaGFpbl9fKTtcbiAgICAgIHJlc3VsdC5fX2FjdGlvbnNfXyA9IGNvcHlBcnJheSh3cmFwcGVyLl9fYWN0aW9uc19fKTtcbiAgICAgIHJlc3VsdC5fX2luZGV4X18gID0gd3JhcHBlci5fX2luZGV4X187XG4gICAgICByZXN1bHQuX192YWx1ZXNfXyA9IHdyYXBwZXIuX192YWx1ZXNfXztcbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhbiBhcnJheSBvZiBlbGVtZW50cyBzcGxpdCBpbnRvIGdyb3VwcyB0aGUgbGVuZ3RoIG9mIGBzaXplYC5cbiAgICAgKiBJZiBgYXJyYXlgIGNhbid0IGJlIHNwbGl0IGV2ZW5seSwgdGhlIGZpbmFsIGNodW5rIHdpbGwgYmUgdGhlIHJlbWFpbmluZ1xuICAgICAqIGVsZW1lbnRzLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDMuMC4wXG4gICAgICogQGNhdGVnb3J5IEFycmF5XG4gICAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIHByb2Nlc3MuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtzaXplPTFdIFRoZSBsZW5ndGggb2YgZWFjaCBjaHVua1xuICAgICAqIEBwYXJhbS0ge09iamVjdH0gW2d1YXJkXSBFbmFibGVzIHVzZSBhcyBhbiBpdGVyYXRlZSBmb3IgbWV0aG9kcyBsaWtlIGBfLm1hcGAuXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBuZXcgYXJyYXkgb2YgY2h1bmtzLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLmNodW5rKFsnYScsICdiJywgJ2MnLCAnZCddLCAyKTtcbiAgICAgKiAvLyA9PiBbWydhJywgJ2InXSwgWydjJywgJ2QnXV1cbiAgICAgKlxuICAgICAqIF8uY2h1bmsoWydhJywgJ2InLCAnYycsICdkJ10sIDMpO1xuICAgICAqIC8vID0+IFtbJ2EnLCAnYicsICdjJ10sIFsnZCddXVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGNodW5rKGFycmF5LCBzaXplLCBndWFyZCkge1xuICAgICAgaWYgKChndWFyZCA/IGlzSXRlcmF0ZWVDYWxsKGFycmF5LCBzaXplLCBndWFyZCkgOiBzaXplID09PSB1bmRlZmluZWQpKSB7XG4gICAgICAgIHNpemUgPSAxO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgc2l6ZSA9IG5hdGl2ZU1heCh0b0ludGVnZXIoc2l6ZSksIDApO1xuICAgICAgfVxuICAgICAgdmFyIGxlbmd0aCA9IGFycmF5ID09IG51bGwgPyAwIDogYXJyYXkubGVuZ3RoO1xuICAgICAgaWYgKCFsZW5ndGggfHwgc2l6ZSA8IDEpIHtcbiAgICAgICAgcmV0dXJuIFtdO1xuICAgICAgfVxuICAgICAgdmFyIGluZGV4ID0gMCxcbiAgICAgICAgICByZXNJbmRleCA9IDAsXG4gICAgICAgICAgcmVzdWx0ID0gQXJyYXkobmF0aXZlQ2VpbChsZW5ndGggLyBzaXplKSk7XG5cbiAgICAgIHdoaWxlIChpbmRleCA8IGxlbmd0aCkge1xuICAgICAgICByZXN1bHRbcmVzSW5kZXgrK10gPSBiYXNlU2xpY2UoYXJyYXksIGluZGV4LCAoaW5kZXggKz0gc2l6ZSkpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGFuIGFycmF5IHdpdGggYWxsIGZhbHNleSB2YWx1ZXMgcmVtb3ZlZC4gVGhlIHZhbHVlcyBgZmFsc2VgLCBgbnVsbGAsXG4gICAgICogYDBgLCBgXCJcImAsIGB1bmRlZmluZWRgLCBhbmQgYE5hTmAgYXJlIGZhbHNleS5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAwLjEuMFxuICAgICAqIEBjYXRlZ29yeSBBcnJheVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBjb21wYWN0LlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IGFycmF5IG9mIGZpbHRlcmVkIHZhbHVlcy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5jb21wYWN0KFswLCAxLCBmYWxzZSwgMiwgJycsIDNdKTtcbiAgICAgKiAvLyA9PiBbMSwgMiwgM11cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBjb21wYWN0KGFycmF5KSB7XG4gICAgICB2YXIgaW5kZXggPSAtMSxcbiAgICAgICAgICBsZW5ndGggPSBhcnJheSA9PSBudWxsID8gMCA6IGFycmF5Lmxlbmd0aCxcbiAgICAgICAgICByZXNJbmRleCA9IDAsXG4gICAgICAgICAgcmVzdWx0ID0gW107XG5cbiAgICAgIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XG4gICAgICAgIHZhciB2YWx1ZSA9IGFycmF5W2luZGV4XTtcbiAgICAgICAgaWYgKHZhbHVlKSB7XG4gICAgICAgICAgcmVzdWx0W3Jlc0luZGV4KytdID0gdmFsdWU7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIG5ldyBhcnJheSBjb25jYXRlbmF0aW5nIGBhcnJheWAgd2l0aCBhbnkgYWRkaXRpb25hbCBhcnJheXNcbiAgICAgKiBhbmQvb3IgdmFsdWVzLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMC4wXG4gICAgICogQGNhdGVnb3J5IEFycmF5XG4gICAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIGNvbmNhdGVuYXRlLlxuICAgICAqIEBwYXJhbSB7Li4uKn0gW3ZhbHVlc10gVGhlIHZhbHVlcyB0byBjb25jYXRlbmF0ZS5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIG5ldyBjb25jYXRlbmF0ZWQgYXJyYXkuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciBhcnJheSA9IFsxXTtcbiAgICAgKiB2YXIgb3RoZXIgPSBfLmNvbmNhdChhcnJheSwgMiwgWzNdLCBbWzRdXSk7XG4gICAgICpcbiAgICAgKiBjb25zb2xlLmxvZyhvdGhlcik7XG4gICAgICogLy8gPT4gWzEsIDIsIDMsIFs0XV1cbiAgICAgKlxuICAgICAqIGNvbnNvbGUubG9nKGFycmF5KTtcbiAgICAgKiAvLyA9PiBbMV1cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBjb25jYXQoKSB7XG4gICAgICB2YXIgbGVuZ3RoID0gYXJndW1lbnRzLmxlbmd0aDtcbiAgICAgIGlmICghbGVuZ3RoKSB7XG4gICAgICAgIHJldHVybiBbXTtcbiAgICAgIH1cbiAgICAgIHZhciBhcmdzID0gQXJyYXkobGVuZ3RoIC0gMSksXG4gICAgICAgICAgYXJyYXkgPSBhcmd1bWVudHNbMF0sXG4gICAgICAgICAgaW5kZXggPSBsZW5ndGg7XG5cbiAgICAgIHdoaWxlIChpbmRleC0tKSB7XG4gICAgICAgIGFyZ3NbaW5kZXggLSAxXSA9IGFyZ3VtZW50c1tpbmRleF07XG4gICAgICB9XG4gICAgICByZXR1cm4gYXJyYXlQdXNoKGlzQXJyYXkoYXJyYXkpID8gY29weUFycmF5KGFycmF5KSA6IFthcnJheV0sIGJhc2VGbGF0dGVuKGFyZ3MsIDEpKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGFuIGFycmF5IG9mIGBhcnJheWAgdmFsdWVzIG5vdCBpbmNsdWRlZCBpbiB0aGUgb3RoZXIgZ2l2ZW4gYXJyYXlzXG4gICAgICogdXNpbmcgW2BTYW1lVmFsdWVaZXJvYF0oaHR0cDovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNy4wLyNzZWMtc2FtZXZhbHVlemVybylcbiAgICAgKiBmb3IgZXF1YWxpdHkgY29tcGFyaXNvbnMuIFRoZSBvcmRlciBhbmQgcmVmZXJlbmNlcyBvZiByZXN1bHQgdmFsdWVzIGFyZVxuICAgICAqIGRldGVybWluZWQgYnkgdGhlIGZpcnN0IGFycmF5LlxuICAgICAqXG4gICAgICogKipOb3RlOioqIFVubGlrZSBgXy5wdWxsQWxsYCwgdGhpcyBtZXRob2QgcmV0dXJucyBhIG5ldyBhcnJheS5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAwLjEuMFxuICAgICAqIEBjYXRlZ29yeSBBcnJheVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBpbnNwZWN0LlxuICAgICAqIEBwYXJhbSB7Li4uQXJyYXl9IFt2YWx1ZXNdIFRoZSB2YWx1ZXMgdG8gZXhjbHVkZS5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIG5ldyBhcnJheSBvZiBmaWx0ZXJlZCB2YWx1ZXMuXG4gICAgICogQHNlZSBfLndpdGhvdXQsIF8ueG9yXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uZGlmZmVyZW5jZShbMiwgMV0sIFsyLCAzXSk7XG4gICAgICogLy8gPT4gWzFdXG4gICAgICovXG4gICAgdmFyIGRpZmZlcmVuY2UgPSBiYXNlUmVzdChmdW5jdGlvbihhcnJheSwgdmFsdWVzKSB7XG4gICAgICByZXR1cm4gaXNBcnJheUxpa2VPYmplY3QoYXJyYXkpXG4gICAgICAgID8gYmFzZURpZmZlcmVuY2UoYXJyYXksIGJhc2VGbGF0dGVuKHZhbHVlcywgMSwgaXNBcnJheUxpa2VPYmplY3QsIHRydWUpKVxuICAgICAgICA6IFtdO1xuICAgIH0pO1xuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgaXMgbGlrZSBgXy5kaWZmZXJlbmNlYCBleGNlcHQgdGhhdCBpdCBhY2NlcHRzIGBpdGVyYXRlZWAgd2hpY2hcbiAgICAgKiBpcyBpbnZva2VkIGZvciBlYWNoIGVsZW1lbnQgb2YgYGFycmF5YCBhbmQgYHZhbHVlc2AgdG8gZ2VuZXJhdGUgdGhlIGNyaXRlcmlvblxuICAgICAqIGJ5IHdoaWNoIHRoZXkncmUgY29tcGFyZWQuIFRoZSBvcmRlciBhbmQgcmVmZXJlbmNlcyBvZiByZXN1bHQgdmFsdWVzIGFyZVxuICAgICAqIGRldGVybWluZWQgYnkgdGhlIGZpcnN0IGFycmF5LiBUaGUgaXRlcmF0ZWUgaXMgaW52b2tlZCB3aXRoIG9uZSBhcmd1bWVudDpcbiAgICAgKiAodmFsdWUpLlxuICAgICAqXG4gICAgICogKipOb3RlOioqIFVubGlrZSBgXy5wdWxsQWxsQnlgLCB0aGlzIG1ldGhvZCByZXR1cm5zIGEgbmV3IGFycmF5LlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMC4wXG4gICAgICogQGNhdGVnb3J5IEFycmF5XG4gICAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIGluc3BlY3QuXG4gICAgICogQHBhcmFtIHsuLi5BcnJheX0gW3ZhbHVlc10gVGhlIHZhbHVlcyB0byBleGNsdWRlLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IFtpdGVyYXRlZT1fLmlkZW50aXR5XSBUaGUgaXRlcmF0ZWUgaW52b2tlZCBwZXIgZWxlbWVudC5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIG5ldyBhcnJheSBvZiBmaWx0ZXJlZCB2YWx1ZXMuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uZGlmZmVyZW5jZUJ5KFsyLjEsIDEuMl0sIFsyLjMsIDMuNF0sIE1hdGguZmxvb3IpO1xuICAgICAqIC8vID0+IFsxLjJdXG4gICAgICpcbiAgICAgKiAvLyBUaGUgYF8ucHJvcGVydHlgIGl0ZXJhdGVlIHNob3J0aGFuZC5cbiAgICAgKiBfLmRpZmZlcmVuY2VCeShbeyAneCc6IDIgfSwgeyAneCc6IDEgfV0sIFt7ICd4JzogMSB9XSwgJ3gnKTtcbiAgICAgKiAvLyA9PiBbeyAneCc6IDIgfV1cbiAgICAgKi9cbiAgICB2YXIgZGlmZmVyZW5jZUJ5ID0gYmFzZVJlc3QoZnVuY3Rpb24oYXJyYXksIHZhbHVlcykge1xuICAgICAgdmFyIGl0ZXJhdGVlID0gbGFzdCh2YWx1ZXMpO1xuICAgICAgaWYgKGlzQXJyYXlMaWtlT2JqZWN0KGl0ZXJhdGVlKSkge1xuICAgICAgICBpdGVyYXRlZSA9IHVuZGVmaW5lZDtcbiAgICAgIH1cbiAgICAgIHJldHVybiBpc0FycmF5TGlrZU9iamVjdChhcnJheSlcbiAgICAgICAgPyBiYXNlRGlmZmVyZW5jZShhcnJheSwgYmFzZUZsYXR0ZW4odmFsdWVzLCAxLCBpc0FycmF5TGlrZU9iamVjdCwgdHJ1ZSksIGdldEl0ZXJhdGVlKGl0ZXJhdGVlLCAyKSlcbiAgICAgICAgOiBbXTtcbiAgICB9KTtcblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIGlzIGxpa2UgYF8uZGlmZmVyZW5jZWAgZXhjZXB0IHRoYXQgaXQgYWNjZXB0cyBgY29tcGFyYXRvcmBcbiAgICAgKiB3aGljaCBpcyBpbnZva2VkIHRvIGNvbXBhcmUgZWxlbWVudHMgb2YgYGFycmF5YCB0byBgdmFsdWVzYC4gVGhlIG9yZGVyIGFuZFxuICAgICAqIHJlZmVyZW5jZXMgb2YgcmVzdWx0IHZhbHVlcyBhcmUgZGV0ZXJtaW5lZCBieSB0aGUgZmlyc3QgYXJyYXkuIFRoZSBjb21wYXJhdG9yXG4gICAgICogaXMgaW52b2tlZCB3aXRoIHR3byBhcmd1bWVudHM6IChhcnJWYWwsIG90aFZhbCkuXG4gICAgICpcbiAgICAgKiAqKk5vdGU6KiogVW5saWtlIGBfLnB1bGxBbGxXaXRoYCwgdGhpcyBtZXRob2QgcmV0dXJucyBhIG5ldyBhcnJheS5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjAuMFxuICAgICAqIEBjYXRlZ29yeSBBcnJheVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBpbnNwZWN0LlxuICAgICAqIEBwYXJhbSB7Li4uQXJyYXl9IFt2YWx1ZXNdIFRoZSB2YWx1ZXMgdG8gZXhjbHVkZS5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbY29tcGFyYXRvcl0gVGhlIGNvbXBhcmF0b3IgaW52b2tlZCBwZXIgZWxlbWVudC5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIG5ldyBhcnJheSBvZiBmaWx0ZXJlZCB2YWx1ZXMuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciBvYmplY3RzID0gW3sgJ3gnOiAxLCAneSc6IDIgfSwgeyAneCc6IDIsICd5JzogMSB9XTtcbiAgICAgKlxuICAgICAqIF8uZGlmZmVyZW5jZVdpdGgob2JqZWN0cywgW3sgJ3gnOiAxLCAneSc6IDIgfV0sIF8uaXNFcXVhbCk7XG4gICAgICogLy8gPT4gW3sgJ3gnOiAyLCAneSc6IDEgfV1cbiAgICAgKi9cbiAgICB2YXIgZGlmZmVyZW5jZVdpdGggPSBiYXNlUmVzdChmdW5jdGlvbihhcnJheSwgdmFsdWVzKSB7XG4gICAgICB2YXIgY29tcGFyYXRvciA9IGxhc3QodmFsdWVzKTtcbiAgICAgIGlmIChpc0FycmF5TGlrZU9iamVjdChjb21wYXJhdG9yKSkge1xuICAgICAgICBjb21wYXJhdG9yID0gdW5kZWZpbmVkO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGlzQXJyYXlMaWtlT2JqZWN0KGFycmF5KVxuICAgICAgICA/IGJhc2VEaWZmZXJlbmNlKGFycmF5LCBiYXNlRmxhdHRlbih2YWx1ZXMsIDEsIGlzQXJyYXlMaWtlT2JqZWN0LCB0cnVlKSwgdW5kZWZpbmVkLCBjb21wYXJhdG9yKVxuICAgICAgICA6IFtdO1xuICAgIH0pO1xuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIHNsaWNlIG9mIGBhcnJheWAgd2l0aCBgbmAgZWxlbWVudHMgZHJvcHBlZCBmcm9tIHRoZSBiZWdpbm5pbmcuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMC41LjBcbiAgICAgKiBAY2F0ZWdvcnkgQXJyYXlcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gcXVlcnkuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtuPTFdIFRoZSBudW1iZXIgb2YgZWxlbWVudHMgdG8gZHJvcC5cbiAgICAgKiBAcGFyYW0tIHtPYmplY3R9IFtndWFyZF0gRW5hYmxlcyB1c2UgYXMgYW4gaXRlcmF0ZWUgZm9yIG1ldGhvZHMgbGlrZSBgXy5tYXBgLlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgc2xpY2Ugb2YgYGFycmF5YC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5kcm9wKFsxLCAyLCAzXSk7XG4gICAgICogLy8gPT4gWzIsIDNdXG4gICAgICpcbiAgICAgKiBfLmRyb3AoWzEsIDIsIDNdLCAyKTtcbiAgICAgKiAvLyA9PiBbM11cbiAgICAgKlxuICAgICAqIF8uZHJvcChbMSwgMiwgM10sIDUpO1xuICAgICAqIC8vID0+IFtdXG4gICAgICpcbiAgICAgKiBfLmRyb3AoWzEsIDIsIDNdLCAwKTtcbiAgICAgKiAvLyA9PiBbMSwgMiwgM11cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBkcm9wKGFycmF5LCBuLCBndWFyZCkge1xuICAgICAgdmFyIGxlbmd0aCA9IGFycmF5ID09IG51bGwgPyAwIDogYXJyYXkubGVuZ3RoO1xuICAgICAgaWYgKCFsZW5ndGgpIHtcbiAgICAgICAgcmV0dXJuIFtdO1xuICAgICAgfVxuICAgICAgbiA9IChndWFyZCB8fCBuID09PSB1bmRlZmluZWQpID8gMSA6IHRvSW50ZWdlcihuKTtcbiAgICAgIHJldHVybiBiYXNlU2xpY2UoYXJyYXksIG4gPCAwID8gMCA6IG4sIGxlbmd0aCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIHNsaWNlIG9mIGBhcnJheWAgd2l0aCBgbmAgZWxlbWVudHMgZHJvcHBlZCBmcm9tIHRoZSBlbmQuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMy4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgQXJyYXlcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gcXVlcnkuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtuPTFdIFRoZSBudW1iZXIgb2YgZWxlbWVudHMgdG8gZHJvcC5cbiAgICAgKiBAcGFyYW0tIHtPYmplY3R9IFtndWFyZF0gRW5hYmxlcyB1c2UgYXMgYW4gaXRlcmF0ZWUgZm9yIG1ldGhvZHMgbGlrZSBgXy5tYXBgLlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgc2xpY2Ugb2YgYGFycmF5YC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5kcm9wUmlnaHQoWzEsIDIsIDNdKTtcbiAgICAgKiAvLyA9PiBbMSwgMl1cbiAgICAgKlxuICAgICAqIF8uZHJvcFJpZ2h0KFsxLCAyLCAzXSwgMik7XG4gICAgICogLy8gPT4gWzFdXG4gICAgICpcbiAgICAgKiBfLmRyb3BSaWdodChbMSwgMiwgM10sIDUpO1xuICAgICAqIC8vID0+IFtdXG4gICAgICpcbiAgICAgKiBfLmRyb3BSaWdodChbMSwgMiwgM10sIDApO1xuICAgICAqIC8vID0+IFsxLCAyLCAzXVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGRyb3BSaWdodChhcnJheSwgbiwgZ3VhcmQpIHtcbiAgICAgIHZhciBsZW5ndGggPSBhcnJheSA9PSBudWxsID8gMCA6IGFycmF5Lmxlbmd0aDtcbiAgICAgIGlmICghbGVuZ3RoKSB7XG4gICAgICAgIHJldHVybiBbXTtcbiAgICAgIH1cbiAgICAgIG4gPSAoZ3VhcmQgfHwgbiA9PT0gdW5kZWZpbmVkKSA/IDEgOiB0b0ludGVnZXIobik7XG4gICAgICBuID0gbGVuZ3RoIC0gbjtcbiAgICAgIHJldHVybiBiYXNlU2xpY2UoYXJyYXksIDAsIG4gPCAwID8gMCA6IG4pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBzbGljZSBvZiBgYXJyYXlgIGV4Y2x1ZGluZyBlbGVtZW50cyBkcm9wcGVkIGZyb20gdGhlIGVuZC5cbiAgICAgKiBFbGVtZW50cyBhcmUgZHJvcHBlZCB1bnRpbCBgcHJlZGljYXRlYCByZXR1cm5zIGZhbHNleS4gVGhlIHByZWRpY2F0ZSBpc1xuICAgICAqIGludm9rZWQgd2l0aCB0aHJlZSBhcmd1bWVudHM6ICh2YWx1ZSwgaW5kZXgsIGFycmF5KS5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAzLjAuMFxuICAgICAqIEBjYXRlZ29yeSBBcnJheVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBxdWVyeS5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbcHJlZGljYXRlPV8uaWRlbnRpdHldIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBzbGljZSBvZiBgYXJyYXlgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgdXNlcnMgPSBbXG4gICAgICogICB7ICd1c2VyJzogJ2Jhcm5leScsICAnYWN0aXZlJzogdHJ1ZSB9LFxuICAgICAqICAgeyAndXNlcic6ICdmcmVkJywgICAgJ2FjdGl2ZSc6IGZhbHNlIH0sXG4gICAgICogICB7ICd1c2VyJzogJ3BlYmJsZXMnLCAnYWN0aXZlJzogZmFsc2UgfVxuICAgICAqIF07XG4gICAgICpcbiAgICAgKiBfLmRyb3BSaWdodFdoaWxlKHVzZXJzLCBmdW5jdGlvbihvKSB7IHJldHVybiAhby5hY3RpdmU7IH0pO1xuICAgICAqIC8vID0+IG9iamVjdHMgZm9yIFsnYmFybmV5J11cbiAgICAgKlxuICAgICAqIC8vIFRoZSBgXy5tYXRjaGVzYCBpdGVyYXRlZSBzaG9ydGhhbmQuXG4gICAgICogXy5kcm9wUmlnaHRXaGlsZSh1c2VycywgeyAndXNlcic6ICdwZWJibGVzJywgJ2FjdGl2ZSc6IGZhbHNlIH0pO1xuICAgICAqIC8vID0+IG9iamVjdHMgZm9yIFsnYmFybmV5JywgJ2ZyZWQnXVxuICAgICAqXG4gICAgICogLy8gVGhlIGBfLm1hdGNoZXNQcm9wZXJ0eWAgaXRlcmF0ZWUgc2hvcnRoYW5kLlxuICAgICAqIF8uZHJvcFJpZ2h0V2hpbGUodXNlcnMsIFsnYWN0aXZlJywgZmFsc2VdKTtcbiAgICAgKiAvLyA9PiBvYmplY3RzIGZvciBbJ2Jhcm5leSddXG4gICAgICpcbiAgICAgKiAvLyBUaGUgYF8ucHJvcGVydHlgIGl0ZXJhdGVlIHNob3J0aGFuZC5cbiAgICAgKiBfLmRyb3BSaWdodFdoaWxlKHVzZXJzLCAnYWN0aXZlJyk7XG4gICAgICogLy8gPT4gb2JqZWN0cyBmb3IgWydiYXJuZXknLCAnZnJlZCcsICdwZWJibGVzJ11cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBkcm9wUmlnaHRXaGlsZShhcnJheSwgcHJlZGljYXRlKSB7XG4gICAgICByZXR1cm4gKGFycmF5ICYmIGFycmF5Lmxlbmd0aClcbiAgICAgICAgPyBiYXNlV2hpbGUoYXJyYXksIGdldEl0ZXJhdGVlKHByZWRpY2F0ZSwgMyksIHRydWUsIHRydWUpXG4gICAgICAgIDogW107XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIHNsaWNlIG9mIGBhcnJheWAgZXhjbHVkaW5nIGVsZW1lbnRzIGRyb3BwZWQgZnJvbSB0aGUgYmVnaW5uaW5nLlxuICAgICAqIEVsZW1lbnRzIGFyZSBkcm9wcGVkIHVudGlsIGBwcmVkaWNhdGVgIHJldHVybnMgZmFsc2V5LiBUaGUgcHJlZGljYXRlIGlzXG4gICAgICogaW52b2tlZCB3aXRoIHRocmVlIGFyZ3VtZW50czogKHZhbHVlLCBpbmRleCwgYXJyYXkpLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDMuMC4wXG4gICAgICogQGNhdGVnb3J5IEFycmF5XG4gICAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIHF1ZXJ5LlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IFtwcmVkaWNhdGU9Xy5pZGVudGl0eV0gVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIGl0ZXJhdGlvbi5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIHNsaWNlIG9mIGBhcnJheWAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciB1c2VycyA9IFtcbiAgICAgKiAgIHsgJ3VzZXInOiAnYmFybmV5JywgICdhY3RpdmUnOiBmYWxzZSB9LFxuICAgICAqICAgeyAndXNlcic6ICdmcmVkJywgICAgJ2FjdGl2ZSc6IGZhbHNlIH0sXG4gICAgICogICB7ICd1c2VyJzogJ3BlYmJsZXMnLCAnYWN0aXZlJzogdHJ1ZSB9XG4gICAgICogXTtcbiAgICAgKlxuICAgICAqIF8uZHJvcFdoaWxlKHVzZXJzLCBmdW5jdGlvbihvKSB7IHJldHVybiAhby5hY3RpdmU7IH0pO1xuICAgICAqIC8vID0+IG9iamVjdHMgZm9yIFsncGViYmxlcyddXG4gICAgICpcbiAgICAgKiAvLyBUaGUgYF8ubWF0Y2hlc2AgaXRlcmF0ZWUgc2hvcnRoYW5kLlxuICAgICAqIF8uZHJvcFdoaWxlKHVzZXJzLCB7ICd1c2VyJzogJ2Jhcm5leScsICdhY3RpdmUnOiBmYWxzZSB9KTtcbiAgICAgKiAvLyA9PiBvYmplY3RzIGZvciBbJ2ZyZWQnLCAncGViYmxlcyddXG4gICAgICpcbiAgICAgKiAvLyBUaGUgYF8ubWF0Y2hlc1Byb3BlcnR5YCBpdGVyYXRlZSBzaG9ydGhhbmQuXG4gICAgICogXy5kcm9wV2hpbGUodXNlcnMsIFsnYWN0aXZlJywgZmFsc2VdKTtcbiAgICAgKiAvLyA9PiBvYmplY3RzIGZvciBbJ3BlYmJsZXMnXVxuICAgICAqXG4gICAgICogLy8gVGhlIGBfLnByb3BlcnR5YCBpdGVyYXRlZSBzaG9ydGhhbmQuXG4gICAgICogXy5kcm9wV2hpbGUodXNlcnMsICdhY3RpdmUnKTtcbiAgICAgKiAvLyA9PiBvYmplY3RzIGZvciBbJ2Jhcm5leScsICdmcmVkJywgJ3BlYmJsZXMnXVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGRyb3BXaGlsZShhcnJheSwgcHJlZGljYXRlKSB7XG4gICAgICByZXR1cm4gKGFycmF5ICYmIGFycmF5Lmxlbmd0aClcbiAgICAgICAgPyBiYXNlV2hpbGUoYXJyYXksIGdldEl0ZXJhdGVlKHByZWRpY2F0ZSwgMyksIHRydWUpXG4gICAgICAgIDogW107XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRmlsbHMgZWxlbWVudHMgb2YgYGFycmF5YCB3aXRoIGB2YWx1ZWAgZnJvbSBgc3RhcnRgIHVwIHRvLCBidXQgbm90XG4gICAgICogaW5jbHVkaW5nLCBgZW5kYC5cbiAgICAgKlxuICAgICAqICoqTm90ZToqKiBUaGlzIG1ldGhvZCBtdXRhdGVzIGBhcnJheWAuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMy4yLjBcbiAgICAgKiBAY2F0ZWdvcnkgQXJyYXlcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gZmlsbC5cbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBmaWxsIGBhcnJheWAgd2l0aC5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW3N0YXJ0PTBdIFRoZSBzdGFydCBwb3NpdGlvbi5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW2VuZD1hcnJheS5sZW5ndGhdIFRoZSBlbmQgcG9zaXRpb24uXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIGBhcnJheWAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciBhcnJheSA9IFsxLCAyLCAzXTtcbiAgICAgKlxuICAgICAqIF8uZmlsbChhcnJheSwgJ2EnKTtcbiAgICAgKiBjb25zb2xlLmxvZyhhcnJheSk7XG4gICAgICogLy8gPT4gWydhJywgJ2EnLCAnYSddXG4gICAgICpcbiAgICAgKiBfLmZpbGwoQXJyYXkoMyksIDIpO1xuICAgICAqIC8vID0+IFsyLCAyLCAyXVxuICAgICAqXG4gICAgICogXy5maWxsKFs0LCA2LCA4LCAxMF0sICcqJywgMSwgMyk7XG4gICAgICogLy8gPT4gWzQsICcqJywgJyonLCAxMF1cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBmaWxsKGFycmF5LCB2YWx1ZSwgc3RhcnQsIGVuZCkge1xuICAgICAgdmFyIGxlbmd0aCA9IGFycmF5ID09IG51bGwgPyAwIDogYXJyYXkubGVuZ3RoO1xuICAgICAgaWYgKCFsZW5ndGgpIHtcbiAgICAgICAgcmV0dXJuIFtdO1xuICAgICAgfVxuICAgICAgaWYgKHN0YXJ0ICYmIHR5cGVvZiBzdGFydCAhPSAnbnVtYmVyJyAmJiBpc0l0ZXJhdGVlQ2FsbChhcnJheSwgdmFsdWUsIHN0YXJ0KSkge1xuICAgICAgICBzdGFydCA9IDA7XG4gICAgICAgIGVuZCA9IGxlbmd0aDtcbiAgICAgIH1cbiAgICAgIHJldHVybiBiYXNlRmlsbChhcnJheSwgdmFsdWUsIHN0YXJ0LCBlbmQpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIGlzIGxpa2UgYF8uZmluZGAgZXhjZXB0IHRoYXQgaXQgcmV0dXJucyB0aGUgaW5kZXggb2YgdGhlIGZpcnN0XG4gICAgICogZWxlbWVudCBgcHJlZGljYXRlYCByZXR1cm5zIHRydXRoeSBmb3IgaW5zdGVhZCBvZiB0aGUgZWxlbWVudCBpdHNlbGYuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMS4xLjBcbiAgICAgKiBAY2F0ZWdvcnkgQXJyYXlcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gaW5zcGVjdC5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbcHJlZGljYXRlPV8uaWRlbnRpdHldIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtmcm9tSW5kZXg9MF0gVGhlIGluZGV4IHRvIHNlYXJjaCBmcm9tLlxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9IFJldHVybnMgdGhlIGluZGV4IG9mIHRoZSBmb3VuZCBlbGVtZW50LCBlbHNlIGAtMWAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciB1c2VycyA9IFtcbiAgICAgKiAgIHsgJ3VzZXInOiAnYmFybmV5JywgICdhY3RpdmUnOiBmYWxzZSB9LFxuICAgICAqICAgeyAndXNlcic6ICdmcmVkJywgICAgJ2FjdGl2ZSc6IGZhbHNlIH0sXG4gICAgICogICB7ICd1c2VyJzogJ3BlYmJsZXMnLCAnYWN0aXZlJzogdHJ1ZSB9XG4gICAgICogXTtcbiAgICAgKlxuICAgICAqIF8uZmluZEluZGV4KHVzZXJzLCBmdW5jdGlvbihvKSB7IHJldHVybiBvLnVzZXIgPT0gJ2Jhcm5leSc7IH0pO1xuICAgICAqIC8vID0+IDBcbiAgICAgKlxuICAgICAqIC8vIFRoZSBgXy5tYXRjaGVzYCBpdGVyYXRlZSBzaG9ydGhhbmQuXG4gICAgICogXy5maW5kSW5kZXgodXNlcnMsIHsgJ3VzZXInOiAnZnJlZCcsICdhY3RpdmUnOiBmYWxzZSB9KTtcbiAgICAgKiAvLyA9PiAxXG4gICAgICpcbiAgICAgKiAvLyBUaGUgYF8ubWF0Y2hlc1Byb3BlcnR5YCBpdGVyYXRlZSBzaG9ydGhhbmQuXG4gICAgICogXy5maW5kSW5kZXgodXNlcnMsIFsnYWN0aXZlJywgZmFsc2VdKTtcbiAgICAgKiAvLyA9PiAwXG4gICAgICpcbiAgICAgKiAvLyBUaGUgYF8ucHJvcGVydHlgIGl0ZXJhdGVlIHNob3J0aGFuZC5cbiAgICAgKiBfLmZpbmRJbmRleCh1c2VycywgJ2FjdGl2ZScpO1xuICAgICAqIC8vID0+IDJcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBmaW5kSW5kZXgoYXJyYXksIHByZWRpY2F0ZSwgZnJvbUluZGV4KSB7XG4gICAgICB2YXIgbGVuZ3RoID0gYXJyYXkgPT0gbnVsbCA/IDAgOiBhcnJheS5sZW5ndGg7XG4gICAgICBpZiAoIWxlbmd0aCkge1xuICAgICAgICByZXR1cm4gLTE7XG4gICAgICB9XG4gICAgICB2YXIgaW5kZXggPSBmcm9tSW5kZXggPT0gbnVsbCA/IDAgOiB0b0ludGVnZXIoZnJvbUluZGV4KTtcbiAgICAgIGlmIChpbmRleCA8IDApIHtcbiAgICAgICAgaW5kZXggPSBuYXRpdmVNYXgobGVuZ3RoICsgaW5kZXgsIDApO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGJhc2VGaW5kSW5kZXgoYXJyYXksIGdldEl0ZXJhdGVlKHByZWRpY2F0ZSwgMyksIGluZGV4KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIG1ldGhvZCBpcyBsaWtlIGBfLmZpbmRJbmRleGAgZXhjZXB0IHRoYXQgaXQgaXRlcmF0ZXMgb3ZlciBlbGVtZW50c1xuICAgICAqIG9mIGBjb2xsZWN0aW9uYCBmcm9tIHJpZ2h0IHRvIGxlZnQuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMi4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgQXJyYXlcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gaW5zcGVjdC5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbcHJlZGljYXRlPV8uaWRlbnRpdHldIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtmcm9tSW5kZXg9YXJyYXkubGVuZ3RoLTFdIFRoZSBpbmRleCB0byBzZWFyY2ggZnJvbS5cbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBSZXR1cm5zIHRoZSBpbmRleCBvZiB0aGUgZm91bmQgZWxlbWVudCwgZWxzZSBgLTFgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgdXNlcnMgPSBbXG4gICAgICogICB7ICd1c2VyJzogJ2Jhcm5leScsICAnYWN0aXZlJzogdHJ1ZSB9LFxuICAgICAqICAgeyAndXNlcic6ICdmcmVkJywgICAgJ2FjdGl2ZSc6IGZhbHNlIH0sXG4gICAgICogICB7ICd1c2VyJzogJ3BlYmJsZXMnLCAnYWN0aXZlJzogZmFsc2UgfVxuICAgICAqIF07XG4gICAgICpcbiAgICAgKiBfLmZpbmRMYXN0SW5kZXgodXNlcnMsIGZ1bmN0aW9uKG8pIHsgcmV0dXJuIG8udXNlciA9PSAncGViYmxlcyc7IH0pO1xuICAgICAqIC8vID0+IDJcbiAgICAgKlxuICAgICAqIC8vIFRoZSBgXy5tYXRjaGVzYCBpdGVyYXRlZSBzaG9ydGhhbmQuXG4gICAgICogXy5maW5kTGFzdEluZGV4KHVzZXJzLCB7ICd1c2VyJzogJ2Jhcm5leScsICdhY3RpdmUnOiB0cnVlIH0pO1xuICAgICAqIC8vID0+IDBcbiAgICAgKlxuICAgICAqIC8vIFRoZSBgXy5tYXRjaGVzUHJvcGVydHlgIGl0ZXJhdGVlIHNob3J0aGFuZC5cbiAgICAgKiBfLmZpbmRMYXN0SW5kZXgodXNlcnMsIFsnYWN0aXZlJywgZmFsc2VdKTtcbiAgICAgKiAvLyA9PiAyXG4gICAgICpcbiAgICAgKiAvLyBUaGUgYF8ucHJvcGVydHlgIGl0ZXJhdGVlIHNob3J0aGFuZC5cbiAgICAgKiBfLmZpbmRMYXN0SW5kZXgodXNlcnMsICdhY3RpdmUnKTtcbiAgICAgKiAvLyA9PiAwXG4gICAgICovXG4gICAgZnVuY3Rpb24gZmluZExhc3RJbmRleChhcnJheSwgcHJlZGljYXRlLCBmcm9tSW5kZXgpIHtcbiAgICAgIHZhciBsZW5ndGggPSBhcnJheSA9PSBudWxsID8gMCA6IGFycmF5Lmxlbmd0aDtcbiAgICAgIGlmICghbGVuZ3RoKSB7XG4gICAgICAgIHJldHVybiAtMTtcbiAgICAgIH1cbiAgICAgIHZhciBpbmRleCA9IGxlbmd0aCAtIDE7XG4gICAgICBpZiAoZnJvbUluZGV4ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgaW5kZXggPSB0b0ludGVnZXIoZnJvbUluZGV4KTtcbiAgICAgICAgaW5kZXggPSBmcm9tSW5kZXggPCAwXG4gICAgICAgICAgPyBuYXRpdmVNYXgobGVuZ3RoICsgaW5kZXgsIDApXG4gICAgICAgICAgOiBuYXRpdmVNaW4oaW5kZXgsIGxlbmd0aCAtIDEpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGJhc2VGaW5kSW5kZXgoYXJyYXksIGdldEl0ZXJhdGVlKHByZWRpY2F0ZSwgMyksIGluZGV4LCB0cnVlKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBGbGF0dGVucyBgYXJyYXlgIGEgc2luZ2xlIGxldmVsIGRlZXAuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMC4xLjBcbiAgICAgKiBAY2F0ZWdvcnkgQXJyYXlcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gZmxhdHRlbi5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIG5ldyBmbGF0dGVuZWQgYXJyYXkuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uZmxhdHRlbihbMSwgWzIsIFszLCBbNF1dLCA1XV0pO1xuICAgICAqIC8vID0+IFsxLCAyLCBbMywgWzRdXSwgNV1cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBmbGF0dGVuKGFycmF5KSB7XG4gICAgICB2YXIgbGVuZ3RoID0gYXJyYXkgPT0gbnVsbCA/IDAgOiBhcnJheS5sZW5ndGg7XG4gICAgICByZXR1cm4gbGVuZ3RoID8gYmFzZUZsYXR0ZW4oYXJyYXksIDEpIDogW107XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmVjdXJzaXZlbHkgZmxhdHRlbnMgYGFycmF5YC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAzLjAuMFxuICAgICAqIEBjYXRlZ29yeSBBcnJheVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBmbGF0dGVuLlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IGZsYXR0ZW5lZCBhcnJheS5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5mbGF0dGVuRGVlcChbMSwgWzIsIFszLCBbNF1dLCA1XV0pO1xuICAgICAqIC8vID0+IFsxLCAyLCAzLCA0LCA1XVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGZsYXR0ZW5EZWVwKGFycmF5KSB7XG4gICAgICB2YXIgbGVuZ3RoID0gYXJyYXkgPT0gbnVsbCA/IDAgOiBhcnJheS5sZW5ndGg7XG4gICAgICByZXR1cm4gbGVuZ3RoID8gYmFzZUZsYXR0ZW4oYXJyYXksIElORklOSVRZKSA6IFtdO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJlY3Vyc2l2ZWx5IGZsYXR0ZW4gYGFycmF5YCB1cCB0byBgZGVwdGhgIHRpbWVzLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuNC4wXG4gICAgICogQGNhdGVnb3J5IEFycmF5XG4gICAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIGZsYXR0ZW4uXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtkZXB0aD0xXSBUaGUgbWF4aW11bSByZWN1cnNpb24gZGVwdGguXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBuZXcgZmxhdHRlbmVkIGFycmF5LlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgYXJyYXkgPSBbMSwgWzIsIFszLCBbNF1dLCA1XV07XG4gICAgICpcbiAgICAgKiBfLmZsYXR0ZW5EZXB0aChhcnJheSwgMSk7XG4gICAgICogLy8gPT4gWzEsIDIsIFszLCBbNF1dLCA1XVxuICAgICAqXG4gICAgICogXy5mbGF0dGVuRGVwdGgoYXJyYXksIDIpO1xuICAgICAqIC8vID0+IFsxLCAyLCAzLCBbNF0sIDVdXG4gICAgICovXG4gICAgZnVuY3Rpb24gZmxhdHRlbkRlcHRoKGFycmF5LCBkZXB0aCkge1xuICAgICAgdmFyIGxlbmd0aCA9IGFycmF5ID09IG51bGwgPyAwIDogYXJyYXkubGVuZ3RoO1xuICAgICAgaWYgKCFsZW5ndGgpIHtcbiAgICAgICAgcmV0dXJuIFtdO1xuICAgICAgfVxuICAgICAgZGVwdGggPSBkZXB0aCA9PT0gdW5kZWZpbmVkID8gMSA6IHRvSW50ZWdlcihkZXB0aCk7XG4gICAgICByZXR1cm4gYmFzZUZsYXR0ZW4oYXJyYXksIGRlcHRoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgaW52ZXJzZSBvZiBgXy50b1BhaXJzYDsgdGhpcyBtZXRob2QgcmV0dXJucyBhbiBvYmplY3QgY29tcG9zZWRcbiAgICAgKiBmcm9tIGtleS12YWx1ZSBgcGFpcnNgLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMC4wXG4gICAgICogQGNhdGVnb3J5IEFycmF5XG4gICAgICogQHBhcmFtIHtBcnJheX0gcGFpcnMgVGhlIGtleS12YWx1ZSBwYWlycy5cbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIHRoZSBuZXcgb2JqZWN0LlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLmZyb21QYWlycyhbWydhJywgMV0sIFsnYicsIDJdXSk7XG4gICAgICogLy8gPT4geyAnYSc6IDEsICdiJzogMiB9XG4gICAgICovXG4gICAgZnVuY3Rpb24gZnJvbVBhaXJzKHBhaXJzKSB7XG4gICAgICB2YXIgaW5kZXggPSAtMSxcbiAgICAgICAgICBsZW5ndGggPSBwYWlycyA9PSBudWxsID8gMCA6IHBhaXJzLmxlbmd0aCxcbiAgICAgICAgICByZXN1bHQgPSB7fTtcblxuICAgICAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHtcbiAgICAgICAgdmFyIHBhaXIgPSBwYWlyc1tpbmRleF07XG4gICAgICAgIHJlc3VsdFtwYWlyWzBdXSA9IHBhaXJbMV07XG4gICAgICB9XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldHMgdGhlIGZpcnN0IGVsZW1lbnQgb2YgYGFycmF5YC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAwLjEuMFxuICAgICAqIEBhbGlhcyBmaXJzdFxuICAgICAqIEBjYXRlZ29yeSBBcnJheVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBxdWVyeS5cbiAgICAgKiBAcmV0dXJucyB7Kn0gUmV0dXJucyB0aGUgZmlyc3QgZWxlbWVudCBvZiBgYXJyYXlgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLmhlYWQoWzEsIDIsIDNdKTtcbiAgICAgKiAvLyA9PiAxXG4gICAgICpcbiAgICAgKiBfLmhlYWQoW10pO1xuICAgICAqIC8vID0+IHVuZGVmaW5lZFxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGhlYWQoYXJyYXkpIHtcbiAgICAgIHJldHVybiAoYXJyYXkgJiYgYXJyYXkubGVuZ3RoKSA/IGFycmF5WzBdIDogdW5kZWZpbmVkO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldHMgdGhlIGluZGV4IGF0IHdoaWNoIHRoZSBmaXJzdCBvY2N1cnJlbmNlIG9mIGB2YWx1ZWAgaXMgZm91bmQgaW4gYGFycmF5YFxuICAgICAqIHVzaW5nIFtgU2FtZVZhbHVlWmVyb2BdKGh0dHA6Ly9lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzcuMC8jc2VjLXNhbWV2YWx1ZXplcm8pXG4gICAgICogZm9yIGVxdWFsaXR5IGNvbXBhcmlzb25zLiBJZiBgZnJvbUluZGV4YCBpcyBuZWdhdGl2ZSwgaXQncyB1c2VkIGFzIHRoZVxuICAgICAqIG9mZnNldCBmcm9tIHRoZSBlbmQgb2YgYGFycmF5YC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAwLjEuMFxuICAgICAqIEBjYXRlZ29yeSBBcnJheVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBpbnNwZWN0LlxuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIHNlYXJjaCBmb3IuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtmcm9tSW5kZXg9MF0gVGhlIGluZGV4IHRvIHNlYXJjaCBmcm9tLlxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9IFJldHVybnMgdGhlIGluZGV4IG9mIHRoZSBtYXRjaGVkIHZhbHVlLCBlbHNlIGAtMWAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uaW5kZXhPZihbMSwgMiwgMSwgMl0sIDIpO1xuICAgICAqIC8vID0+IDFcbiAgICAgKlxuICAgICAqIC8vIFNlYXJjaCBmcm9tIHRoZSBgZnJvbUluZGV4YC5cbiAgICAgKiBfLmluZGV4T2YoWzEsIDIsIDEsIDJdLCAyLCAyKTtcbiAgICAgKiAvLyA9PiAzXG4gICAgICovXG4gICAgZnVuY3Rpb24gaW5kZXhPZihhcnJheSwgdmFsdWUsIGZyb21JbmRleCkge1xuICAgICAgdmFyIGxlbmd0aCA9IGFycmF5ID09IG51bGwgPyAwIDogYXJyYXkubGVuZ3RoO1xuICAgICAgaWYgKCFsZW5ndGgpIHtcbiAgICAgICAgcmV0dXJuIC0xO1xuICAgICAgfVxuICAgICAgdmFyIGluZGV4ID0gZnJvbUluZGV4ID09IG51bGwgPyAwIDogdG9JbnRlZ2VyKGZyb21JbmRleCk7XG4gICAgICBpZiAoaW5kZXggPCAwKSB7XG4gICAgICAgIGluZGV4ID0gbmF0aXZlTWF4KGxlbmd0aCArIGluZGV4LCAwKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBiYXNlSW5kZXhPZihhcnJheSwgdmFsdWUsIGluZGV4KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXRzIGFsbCBidXQgdGhlIGxhc3QgZWxlbWVudCBvZiBgYXJyYXlgLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDAuMS4wXG4gICAgICogQGNhdGVnb3J5IEFycmF5XG4gICAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIHF1ZXJ5LlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgc2xpY2Ugb2YgYGFycmF5YC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5pbml0aWFsKFsxLCAyLCAzXSk7XG4gICAgICogLy8gPT4gWzEsIDJdXG4gICAgICovXG4gICAgZnVuY3Rpb24gaW5pdGlhbChhcnJheSkge1xuICAgICAgdmFyIGxlbmd0aCA9IGFycmF5ID09IG51bGwgPyAwIDogYXJyYXkubGVuZ3RoO1xuICAgICAgcmV0dXJuIGxlbmd0aCA/IGJhc2VTbGljZShhcnJheSwgMCwgLTEpIDogW107XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhbiBhcnJheSBvZiB1bmlxdWUgdmFsdWVzIHRoYXQgYXJlIGluY2x1ZGVkIGluIGFsbCBnaXZlbiBhcnJheXNcbiAgICAgKiB1c2luZyBbYFNhbWVWYWx1ZVplcm9gXShodHRwOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi83LjAvI3NlYy1zYW1ldmFsdWV6ZXJvKVxuICAgICAqIGZvciBlcXVhbGl0eSBjb21wYXJpc29ucy4gVGhlIG9yZGVyIGFuZCByZWZlcmVuY2VzIG9mIHJlc3VsdCB2YWx1ZXMgYXJlXG4gICAgICogZGV0ZXJtaW5lZCBieSB0aGUgZmlyc3QgYXJyYXkuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMC4xLjBcbiAgICAgKiBAY2F0ZWdvcnkgQXJyYXlcbiAgICAgKiBAcGFyYW0gey4uLkFycmF5fSBbYXJyYXlzXSBUaGUgYXJyYXlzIHRvIGluc3BlY3QuXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBuZXcgYXJyYXkgb2YgaW50ZXJzZWN0aW5nIHZhbHVlcy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5pbnRlcnNlY3Rpb24oWzIsIDFdLCBbMiwgM10pO1xuICAgICAqIC8vID0+IFsyXVxuICAgICAqL1xuICAgIHZhciBpbnRlcnNlY3Rpb24gPSBiYXNlUmVzdChmdW5jdGlvbihhcnJheXMpIHtcbiAgICAgIHZhciBtYXBwZWQgPSBhcnJheU1hcChhcnJheXMsIGNhc3RBcnJheUxpa2VPYmplY3QpO1xuICAgICAgcmV0dXJuIChtYXBwZWQubGVuZ3RoICYmIG1hcHBlZFswXSA9PT0gYXJyYXlzWzBdKVxuICAgICAgICA/IGJhc2VJbnRlcnNlY3Rpb24obWFwcGVkKVxuICAgICAgICA6IFtdO1xuICAgIH0pO1xuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgaXMgbGlrZSBgXy5pbnRlcnNlY3Rpb25gIGV4Y2VwdCB0aGF0IGl0IGFjY2VwdHMgYGl0ZXJhdGVlYFxuICAgICAqIHdoaWNoIGlzIGludm9rZWQgZm9yIGVhY2ggZWxlbWVudCBvZiBlYWNoIGBhcnJheXNgIHRvIGdlbmVyYXRlIHRoZSBjcml0ZXJpb25cbiAgICAgKiBieSB3aGljaCB0aGV5J3JlIGNvbXBhcmVkLiBUaGUgb3JkZXIgYW5kIHJlZmVyZW5jZXMgb2YgcmVzdWx0IHZhbHVlcyBhcmVcbiAgICAgKiBkZXRlcm1pbmVkIGJ5IHRoZSBmaXJzdCBhcnJheS4gVGhlIGl0ZXJhdGVlIGlzIGludm9rZWQgd2l0aCBvbmUgYXJndW1lbnQ6XG4gICAgICogKHZhbHVlKS5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjAuMFxuICAgICAqIEBjYXRlZ29yeSBBcnJheVxuICAgICAqIEBwYXJhbSB7Li4uQXJyYXl9IFthcnJheXNdIFRoZSBhcnJheXMgdG8gaW5zcGVjdC5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbaXRlcmF0ZWU9Xy5pZGVudGl0eV0gVGhlIGl0ZXJhdGVlIGludm9rZWQgcGVyIGVsZW1lbnQuXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBuZXcgYXJyYXkgb2YgaW50ZXJzZWN0aW5nIHZhbHVlcy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5pbnRlcnNlY3Rpb25CeShbMi4xLCAxLjJdLCBbMi4zLCAzLjRdLCBNYXRoLmZsb29yKTtcbiAgICAgKiAvLyA9PiBbMi4xXVxuICAgICAqXG4gICAgICogLy8gVGhlIGBfLnByb3BlcnR5YCBpdGVyYXRlZSBzaG9ydGhhbmQuXG4gICAgICogXy5pbnRlcnNlY3Rpb25CeShbeyAneCc6IDEgfV0sIFt7ICd4JzogMiB9LCB7ICd4JzogMSB9XSwgJ3gnKTtcbiAgICAgKiAvLyA9PiBbeyAneCc6IDEgfV1cbiAgICAgKi9cbiAgICB2YXIgaW50ZXJzZWN0aW9uQnkgPSBiYXNlUmVzdChmdW5jdGlvbihhcnJheXMpIHtcbiAgICAgIHZhciBpdGVyYXRlZSA9IGxhc3QoYXJyYXlzKSxcbiAgICAgICAgICBtYXBwZWQgPSBhcnJheU1hcChhcnJheXMsIGNhc3RBcnJheUxpa2VPYmplY3QpO1xuXG4gICAgICBpZiAoaXRlcmF0ZWUgPT09IGxhc3QobWFwcGVkKSkge1xuICAgICAgICBpdGVyYXRlZSA9IHVuZGVmaW5lZDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIG1hcHBlZC5wb3AoKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiAobWFwcGVkLmxlbmd0aCAmJiBtYXBwZWRbMF0gPT09IGFycmF5c1swXSlcbiAgICAgICAgPyBiYXNlSW50ZXJzZWN0aW9uKG1hcHBlZCwgZ2V0SXRlcmF0ZWUoaXRlcmF0ZWUsIDIpKVxuICAgICAgICA6IFtdO1xuICAgIH0pO1xuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgaXMgbGlrZSBgXy5pbnRlcnNlY3Rpb25gIGV4Y2VwdCB0aGF0IGl0IGFjY2VwdHMgYGNvbXBhcmF0b3JgXG4gICAgICogd2hpY2ggaXMgaW52b2tlZCB0byBjb21wYXJlIGVsZW1lbnRzIG9mIGBhcnJheXNgLiBUaGUgb3JkZXIgYW5kIHJlZmVyZW5jZXNcbiAgICAgKiBvZiByZXN1bHQgdmFsdWVzIGFyZSBkZXRlcm1pbmVkIGJ5IHRoZSBmaXJzdCBhcnJheS4gVGhlIGNvbXBhcmF0b3IgaXNcbiAgICAgKiBpbnZva2VkIHdpdGggdHdvIGFyZ3VtZW50czogKGFyclZhbCwgb3RoVmFsKS5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjAuMFxuICAgICAqIEBjYXRlZ29yeSBBcnJheVxuICAgICAqIEBwYXJhbSB7Li4uQXJyYXl9IFthcnJheXNdIFRoZSBhcnJheXMgdG8gaW5zcGVjdC5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbY29tcGFyYXRvcl0gVGhlIGNvbXBhcmF0b3IgaW52b2tlZCBwZXIgZWxlbWVudC5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIG5ldyBhcnJheSBvZiBpbnRlcnNlY3RpbmcgdmFsdWVzLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgb2JqZWN0cyA9IFt7ICd4JzogMSwgJ3knOiAyIH0sIHsgJ3gnOiAyLCAneSc6IDEgfV07XG4gICAgICogdmFyIG90aGVycyA9IFt7ICd4JzogMSwgJ3knOiAxIH0sIHsgJ3gnOiAxLCAneSc6IDIgfV07XG4gICAgICpcbiAgICAgKiBfLmludGVyc2VjdGlvbldpdGgob2JqZWN0cywgb3RoZXJzLCBfLmlzRXF1YWwpO1xuICAgICAqIC8vID0+IFt7ICd4JzogMSwgJ3knOiAyIH1dXG4gICAgICovXG4gICAgdmFyIGludGVyc2VjdGlvbldpdGggPSBiYXNlUmVzdChmdW5jdGlvbihhcnJheXMpIHtcbiAgICAgIHZhciBjb21wYXJhdG9yID0gbGFzdChhcnJheXMpLFxuICAgICAgICAgIG1hcHBlZCA9IGFycmF5TWFwKGFycmF5cywgY2FzdEFycmF5TGlrZU9iamVjdCk7XG5cbiAgICAgIGNvbXBhcmF0b3IgPSB0eXBlb2YgY29tcGFyYXRvciA9PSAnZnVuY3Rpb24nID8gY29tcGFyYXRvciA6IHVuZGVmaW5lZDtcbiAgICAgIGlmIChjb21wYXJhdG9yKSB7XG4gICAgICAgIG1hcHBlZC5wb3AoKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiAobWFwcGVkLmxlbmd0aCAmJiBtYXBwZWRbMF0gPT09IGFycmF5c1swXSlcbiAgICAgICAgPyBiYXNlSW50ZXJzZWN0aW9uKG1hcHBlZCwgdW5kZWZpbmVkLCBjb21wYXJhdG9yKVxuICAgICAgICA6IFtdO1xuICAgIH0pO1xuXG4gICAgLyoqXG4gICAgICogQ29udmVydHMgYWxsIGVsZW1lbnRzIGluIGBhcnJheWAgaW50byBhIHN0cmluZyBzZXBhcmF0ZWQgYnkgYHNlcGFyYXRvcmAuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgQXJyYXlcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gY29udmVydC5cbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gW3NlcGFyYXRvcj0nLCddIFRoZSBlbGVtZW50IHNlcGFyYXRvci5cbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfSBSZXR1cm5zIHRoZSBqb2luZWQgc3RyaW5nLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLmpvaW4oWydhJywgJ2InLCAnYyddLCAnficpO1xuICAgICAqIC8vID0+ICdhfmJ+YydcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBqb2luKGFycmF5LCBzZXBhcmF0b3IpIHtcbiAgICAgIHJldHVybiBhcnJheSA9PSBudWxsID8gJycgOiBuYXRpdmVKb2luLmNhbGwoYXJyYXksIHNlcGFyYXRvcik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0cyB0aGUgbGFzdCBlbGVtZW50IG9mIGBhcnJheWAuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMC4xLjBcbiAgICAgKiBAY2F0ZWdvcnkgQXJyYXlcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gcXVlcnkuXG4gICAgICogQHJldHVybnMgeyp9IFJldHVybnMgdGhlIGxhc3QgZWxlbWVudCBvZiBgYXJyYXlgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLmxhc3QoWzEsIDIsIDNdKTtcbiAgICAgKiAvLyA9PiAzXG4gICAgICovXG4gICAgZnVuY3Rpb24gbGFzdChhcnJheSkge1xuICAgICAgdmFyIGxlbmd0aCA9IGFycmF5ID09IG51bGwgPyAwIDogYXJyYXkubGVuZ3RoO1xuICAgICAgcmV0dXJuIGxlbmd0aCA/IGFycmF5W2xlbmd0aCAtIDFdIDogdW5kZWZpbmVkO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIGlzIGxpa2UgYF8uaW5kZXhPZmAgZXhjZXB0IHRoYXQgaXQgaXRlcmF0ZXMgb3ZlciBlbGVtZW50cyBvZlxuICAgICAqIGBhcnJheWAgZnJvbSByaWdodCB0byBsZWZ0LlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDAuMS4wXG4gICAgICogQGNhdGVnb3J5IEFycmF5XG4gICAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIGluc3BlY3QuXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gc2VhcmNoIGZvci5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW2Zyb21JbmRleD1hcnJheS5sZW5ndGgtMV0gVGhlIGluZGV4IHRvIHNlYXJjaCBmcm9tLlxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9IFJldHVybnMgdGhlIGluZGV4IG9mIHRoZSBtYXRjaGVkIHZhbHVlLCBlbHNlIGAtMWAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8ubGFzdEluZGV4T2YoWzEsIDIsIDEsIDJdLCAyKTtcbiAgICAgKiAvLyA9PiAzXG4gICAgICpcbiAgICAgKiAvLyBTZWFyY2ggZnJvbSB0aGUgYGZyb21JbmRleGAuXG4gICAgICogXy5sYXN0SW5kZXhPZihbMSwgMiwgMSwgMl0sIDIsIDIpO1xuICAgICAqIC8vID0+IDFcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBsYXN0SW5kZXhPZihhcnJheSwgdmFsdWUsIGZyb21JbmRleCkge1xuICAgICAgdmFyIGxlbmd0aCA9IGFycmF5ID09IG51bGwgPyAwIDogYXJyYXkubGVuZ3RoO1xuICAgICAgaWYgKCFsZW5ndGgpIHtcbiAgICAgICAgcmV0dXJuIC0xO1xuICAgICAgfVxuICAgICAgdmFyIGluZGV4ID0gbGVuZ3RoO1xuICAgICAgaWYgKGZyb21JbmRleCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGluZGV4ID0gdG9JbnRlZ2VyKGZyb21JbmRleCk7XG4gICAgICAgIGluZGV4ID0gaW5kZXggPCAwID8gbmF0aXZlTWF4KGxlbmd0aCArIGluZGV4LCAwKSA6IG5hdGl2ZU1pbihpbmRleCwgbGVuZ3RoIC0gMSk7XG4gICAgICB9XG4gICAgICByZXR1cm4gdmFsdWUgPT09IHZhbHVlXG4gICAgICAgID8gc3RyaWN0TGFzdEluZGV4T2YoYXJyYXksIHZhbHVlLCBpbmRleClcbiAgICAgICAgOiBiYXNlRmluZEluZGV4KGFycmF5LCBiYXNlSXNOYU4sIGluZGV4LCB0cnVlKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXRzIHRoZSBlbGVtZW50IGF0IGluZGV4IGBuYCBvZiBgYXJyYXlgLiBJZiBgbmAgaXMgbmVnYXRpdmUsIHRoZSBudGhcbiAgICAgKiBlbGVtZW50IGZyb20gdGhlIGVuZCBpcyByZXR1cm5lZC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjExLjBcbiAgICAgKiBAY2F0ZWdvcnkgQXJyYXlcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gcXVlcnkuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtuPTBdIFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uXG4gICAgICogQHJldHVybnMgeyp9IFJldHVybnMgdGhlIG50aCBlbGVtZW50IG9mIGBhcnJheWAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciBhcnJheSA9IFsnYScsICdiJywgJ2MnLCAnZCddO1xuICAgICAqXG4gICAgICogXy5udGgoYXJyYXksIDEpO1xuICAgICAqIC8vID0+ICdiJ1xuICAgICAqXG4gICAgICogXy5udGgoYXJyYXksIC0yKTtcbiAgICAgKiAvLyA9PiAnYyc7XG4gICAgICovXG4gICAgZnVuY3Rpb24gbnRoKGFycmF5LCBuKSB7XG4gICAgICByZXR1cm4gKGFycmF5ICYmIGFycmF5Lmxlbmd0aCkgPyBiYXNlTnRoKGFycmF5LCB0b0ludGVnZXIobikpIDogdW5kZWZpbmVkO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJlbW92ZXMgYWxsIGdpdmVuIHZhbHVlcyBmcm9tIGBhcnJheWAgdXNpbmdcbiAgICAgKiBbYFNhbWVWYWx1ZVplcm9gXShodHRwOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi83LjAvI3NlYy1zYW1ldmFsdWV6ZXJvKVxuICAgICAqIGZvciBlcXVhbGl0eSBjb21wYXJpc29ucy5cbiAgICAgKlxuICAgICAqICoqTm90ZToqKiBVbmxpa2UgYF8ud2l0aG91dGAsIHRoaXMgbWV0aG9kIG11dGF0ZXMgYGFycmF5YC4gVXNlIGBfLnJlbW92ZWBcbiAgICAgKiB0byByZW1vdmUgZWxlbWVudHMgZnJvbSBhbiBhcnJheSBieSBwcmVkaWNhdGUuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMi4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgQXJyYXlcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gbW9kaWZ5LlxuICAgICAqIEBwYXJhbSB7Li4uKn0gW3ZhbHVlc10gVGhlIHZhbHVlcyB0byByZW1vdmUuXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIGBhcnJheWAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciBhcnJheSA9IFsnYScsICdiJywgJ2MnLCAnYScsICdiJywgJ2MnXTtcbiAgICAgKlxuICAgICAqIF8ucHVsbChhcnJheSwgJ2EnLCAnYycpO1xuICAgICAqIGNvbnNvbGUubG9nKGFycmF5KTtcbiAgICAgKiAvLyA9PiBbJ2InLCAnYiddXG4gICAgICovXG4gICAgdmFyIHB1bGwgPSBiYXNlUmVzdChwdWxsQWxsKTtcblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIGlzIGxpa2UgYF8ucHVsbGAgZXhjZXB0IHRoYXQgaXQgYWNjZXB0cyBhbiBhcnJheSBvZiB2YWx1ZXMgdG8gcmVtb3ZlLlxuICAgICAqXG4gICAgICogKipOb3RlOioqIFVubGlrZSBgXy5kaWZmZXJlbmNlYCwgdGhpcyBtZXRob2QgbXV0YXRlcyBgYXJyYXlgLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMC4wXG4gICAgICogQGNhdGVnb3J5IEFycmF5XG4gICAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIG1vZGlmeS5cbiAgICAgKiBAcGFyYW0ge0FycmF5fSB2YWx1ZXMgVGhlIHZhbHVlcyB0byByZW1vdmUuXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIGBhcnJheWAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciBhcnJheSA9IFsnYScsICdiJywgJ2MnLCAnYScsICdiJywgJ2MnXTtcbiAgICAgKlxuICAgICAqIF8ucHVsbEFsbChhcnJheSwgWydhJywgJ2MnXSk7XG4gICAgICogY29uc29sZS5sb2coYXJyYXkpO1xuICAgICAqIC8vID0+IFsnYicsICdiJ11cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBwdWxsQWxsKGFycmF5LCB2YWx1ZXMpIHtcbiAgICAgIHJldHVybiAoYXJyYXkgJiYgYXJyYXkubGVuZ3RoICYmIHZhbHVlcyAmJiB2YWx1ZXMubGVuZ3RoKVxuICAgICAgICA/IGJhc2VQdWxsQWxsKGFycmF5LCB2YWx1ZXMpXG4gICAgICAgIDogYXJyYXk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgaXMgbGlrZSBgXy5wdWxsQWxsYCBleGNlcHQgdGhhdCBpdCBhY2NlcHRzIGBpdGVyYXRlZWAgd2hpY2ggaXNcbiAgICAgKiBpbnZva2VkIGZvciBlYWNoIGVsZW1lbnQgb2YgYGFycmF5YCBhbmQgYHZhbHVlc2AgdG8gZ2VuZXJhdGUgdGhlIGNyaXRlcmlvblxuICAgICAqIGJ5IHdoaWNoIHRoZXkncmUgY29tcGFyZWQuIFRoZSBpdGVyYXRlZSBpcyBpbnZva2VkIHdpdGggb25lIGFyZ3VtZW50OiAodmFsdWUpLlxuICAgICAqXG4gICAgICogKipOb3RlOioqIFVubGlrZSBgXy5kaWZmZXJlbmNlQnlgLCB0aGlzIG1ldGhvZCBtdXRhdGVzIGBhcnJheWAuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgQXJyYXlcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gbW9kaWZ5LlxuICAgICAqIEBwYXJhbSB7QXJyYXl9IHZhbHVlcyBUaGUgdmFsdWVzIHRvIHJlbW92ZS5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbaXRlcmF0ZWU9Xy5pZGVudGl0eV0gVGhlIGl0ZXJhdGVlIGludm9rZWQgcGVyIGVsZW1lbnQuXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIGBhcnJheWAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciBhcnJheSA9IFt7ICd4JzogMSB9LCB7ICd4JzogMiB9LCB7ICd4JzogMyB9LCB7ICd4JzogMSB9XTtcbiAgICAgKlxuICAgICAqIF8ucHVsbEFsbEJ5KGFycmF5LCBbeyAneCc6IDEgfSwgeyAneCc6IDMgfV0sICd4Jyk7XG4gICAgICogY29uc29sZS5sb2coYXJyYXkpO1xuICAgICAqIC8vID0+IFt7ICd4JzogMiB9XVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIHB1bGxBbGxCeShhcnJheSwgdmFsdWVzLCBpdGVyYXRlZSkge1xuICAgICAgcmV0dXJuIChhcnJheSAmJiBhcnJheS5sZW5ndGggJiYgdmFsdWVzICYmIHZhbHVlcy5sZW5ndGgpXG4gICAgICAgID8gYmFzZVB1bGxBbGwoYXJyYXksIHZhbHVlcywgZ2V0SXRlcmF0ZWUoaXRlcmF0ZWUsIDIpKVxuICAgICAgICA6IGFycmF5O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIGlzIGxpa2UgYF8ucHVsbEFsbGAgZXhjZXB0IHRoYXQgaXQgYWNjZXB0cyBgY29tcGFyYXRvcmAgd2hpY2hcbiAgICAgKiBpcyBpbnZva2VkIHRvIGNvbXBhcmUgZWxlbWVudHMgb2YgYGFycmF5YCB0byBgdmFsdWVzYC4gVGhlIGNvbXBhcmF0b3IgaXNcbiAgICAgKiBpbnZva2VkIHdpdGggdHdvIGFyZ3VtZW50czogKGFyclZhbCwgb3RoVmFsKS5cbiAgICAgKlxuICAgICAqICoqTm90ZToqKiBVbmxpa2UgYF8uZGlmZmVyZW5jZVdpdGhgLCB0aGlzIG1ldGhvZCBtdXRhdGVzIGBhcnJheWAuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC42LjBcbiAgICAgKiBAY2F0ZWdvcnkgQXJyYXlcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gbW9kaWZ5LlxuICAgICAqIEBwYXJhbSB7QXJyYXl9IHZhbHVlcyBUaGUgdmFsdWVzIHRvIHJlbW92ZS5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbY29tcGFyYXRvcl0gVGhlIGNvbXBhcmF0b3IgaW52b2tlZCBwZXIgZWxlbWVudC5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgYGFycmF5YC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIGFycmF5ID0gW3sgJ3gnOiAxLCAneSc6IDIgfSwgeyAneCc6IDMsICd5JzogNCB9LCB7ICd4JzogNSwgJ3knOiA2IH1dO1xuICAgICAqXG4gICAgICogXy5wdWxsQWxsV2l0aChhcnJheSwgW3sgJ3gnOiAzLCAneSc6IDQgfV0sIF8uaXNFcXVhbCk7XG4gICAgICogY29uc29sZS5sb2coYXJyYXkpO1xuICAgICAqIC8vID0+IFt7ICd4JzogMSwgJ3knOiAyIH0sIHsgJ3gnOiA1LCAneSc6IDYgfV1cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBwdWxsQWxsV2l0aChhcnJheSwgdmFsdWVzLCBjb21wYXJhdG9yKSB7XG4gICAgICByZXR1cm4gKGFycmF5ICYmIGFycmF5Lmxlbmd0aCAmJiB2YWx1ZXMgJiYgdmFsdWVzLmxlbmd0aClcbiAgICAgICAgPyBiYXNlUHVsbEFsbChhcnJheSwgdmFsdWVzLCB1bmRlZmluZWQsIGNvbXBhcmF0b3IpXG4gICAgICAgIDogYXJyYXk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmVtb3ZlcyBlbGVtZW50cyBmcm9tIGBhcnJheWAgY29ycmVzcG9uZGluZyB0byBgaW5kZXhlc2AgYW5kIHJldHVybnMgYW5cbiAgICAgKiBhcnJheSBvZiByZW1vdmVkIGVsZW1lbnRzLlxuICAgICAqXG4gICAgICogKipOb3RlOioqIFVubGlrZSBgXy5hdGAsIHRoaXMgbWV0aG9kIG11dGF0ZXMgYGFycmF5YC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAzLjAuMFxuICAgICAqIEBjYXRlZ29yeSBBcnJheVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBtb2RpZnkuXG4gICAgICogQHBhcmFtIHsuLi4obnVtYmVyfG51bWJlcltdKX0gW2luZGV4ZXNdIFRoZSBpbmRleGVzIG9mIGVsZW1lbnRzIHRvIHJlbW92ZS5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIG5ldyBhcnJheSBvZiByZW1vdmVkIGVsZW1lbnRzLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgYXJyYXkgPSBbJ2EnLCAnYicsICdjJywgJ2QnXTtcbiAgICAgKiB2YXIgcHVsbGVkID0gXy5wdWxsQXQoYXJyYXksIFsxLCAzXSk7XG4gICAgICpcbiAgICAgKiBjb25zb2xlLmxvZyhhcnJheSk7XG4gICAgICogLy8gPT4gWydhJywgJ2MnXVxuICAgICAqXG4gICAgICogY29uc29sZS5sb2cocHVsbGVkKTtcbiAgICAgKiAvLyA9PiBbJ2InLCAnZCddXG4gICAgICovXG4gICAgdmFyIHB1bGxBdCA9IGZsYXRSZXN0KGZ1bmN0aW9uKGFycmF5LCBpbmRleGVzKSB7XG4gICAgICB2YXIgbGVuZ3RoID0gYXJyYXkgPT0gbnVsbCA/IDAgOiBhcnJheS5sZW5ndGgsXG4gICAgICAgICAgcmVzdWx0ID0gYmFzZUF0KGFycmF5LCBpbmRleGVzKTtcblxuICAgICAgYmFzZVB1bGxBdChhcnJheSwgYXJyYXlNYXAoaW5kZXhlcywgZnVuY3Rpb24oaW5kZXgpIHtcbiAgICAgICAgcmV0dXJuIGlzSW5kZXgoaW5kZXgsIGxlbmd0aCkgPyAraW5kZXggOiBpbmRleDtcbiAgICAgIH0pLnNvcnQoY29tcGFyZUFzY2VuZGluZykpO1xuXG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH0pO1xuXG4gICAgLyoqXG4gICAgICogUmVtb3ZlcyBhbGwgZWxlbWVudHMgZnJvbSBgYXJyYXlgIHRoYXQgYHByZWRpY2F0ZWAgcmV0dXJucyB0cnV0aHkgZm9yXG4gICAgICogYW5kIHJldHVybnMgYW4gYXJyYXkgb2YgdGhlIHJlbW92ZWQgZWxlbWVudHMuIFRoZSBwcmVkaWNhdGUgaXMgaW52b2tlZFxuICAgICAqIHdpdGggdGhyZWUgYXJndW1lbnRzOiAodmFsdWUsIGluZGV4LCBhcnJheSkuXG4gICAgICpcbiAgICAgKiAqKk5vdGU6KiogVW5saWtlIGBfLmZpbHRlcmAsIHRoaXMgbWV0aG9kIG11dGF0ZXMgYGFycmF5YC4gVXNlIGBfLnB1bGxgXG4gICAgICogdG8gcHVsbCBlbGVtZW50cyBmcm9tIGFuIGFycmF5IGJ5IHZhbHVlLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDIuMC4wXG4gICAgICogQGNhdGVnb3J5IEFycmF5XG4gICAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIG1vZGlmeS5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbcHJlZGljYXRlPV8uaWRlbnRpdHldIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBuZXcgYXJyYXkgb2YgcmVtb3ZlZCBlbGVtZW50cy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIGFycmF5ID0gWzEsIDIsIDMsIDRdO1xuICAgICAqIHZhciBldmVucyA9IF8ucmVtb3ZlKGFycmF5LCBmdW5jdGlvbihuKSB7XG4gICAgICogICByZXR1cm4gbiAlIDIgPT0gMDtcbiAgICAgKiB9KTtcbiAgICAgKlxuICAgICAqIGNvbnNvbGUubG9nKGFycmF5KTtcbiAgICAgKiAvLyA9PiBbMSwgM11cbiAgICAgKlxuICAgICAqIGNvbnNvbGUubG9nKGV2ZW5zKTtcbiAgICAgKiAvLyA9PiBbMiwgNF1cbiAgICAgKi9cbiAgICBmdW5jdGlvbiByZW1vdmUoYXJyYXksIHByZWRpY2F0ZSkge1xuICAgICAgdmFyIHJlc3VsdCA9IFtdO1xuICAgICAgaWYgKCEoYXJyYXkgJiYgYXJyYXkubGVuZ3RoKSkge1xuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgfVxuICAgICAgdmFyIGluZGV4ID0gLTEsXG4gICAgICAgICAgaW5kZXhlcyA9IFtdLFxuICAgICAgICAgIGxlbmd0aCA9IGFycmF5Lmxlbmd0aDtcblxuICAgICAgcHJlZGljYXRlID0gZ2V0SXRlcmF0ZWUocHJlZGljYXRlLCAzKTtcbiAgICAgIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XG4gICAgICAgIHZhciB2YWx1ZSA9IGFycmF5W2luZGV4XTtcbiAgICAgICAgaWYgKHByZWRpY2F0ZSh2YWx1ZSwgaW5kZXgsIGFycmF5KSkge1xuICAgICAgICAgIHJlc3VsdC5wdXNoKHZhbHVlKTtcbiAgICAgICAgICBpbmRleGVzLnB1c2goaW5kZXgpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBiYXNlUHVsbEF0KGFycmF5LCBpbmRleGVzKTtcbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmV2ZXJzZXMgYGFycmF5YCBzbyB0aGF0IHRoZSBmaXJzdCBlbGVtZW50IGJlY29tZXMgdGhlIGxhc3QsIHRoZSBzZWNvbmRcbiAgICAgKiBlbGVtZW50IGJlY29tZXMgdGhlIHNlY29uZCB0byBsYXN0LCBhbmQgc28gb24uXG4gICAgICpcbiAgICAgKiAqKk5vdGU6KiogVGhpcyBtZXRob2QgbXV0YXRlcyBgYXJyYXlgIGFuZCBpcyBiYXNlZCBvblxuICAgICAqIFtgQXJyYXkjcmV2ZXJzZWBdKGh0dHBzOi8vbWRuLmlvL0FycmF5L3JldmVyc2UpLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMC4wXG4gICAgICogQGNhdGVnb3J5IEFycmF5XG4gICAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIG1vZGlmeS5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgYGFycmF5YC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIGFycmF5ID0gWzEsIDIsIDNdO1xuICAgICAqXG4gICAgICogXy5yZXZlcnNlKGFycmF5KTtcbiAgICAgKiAvLyA9PiBbMywgMiwgMV1cbiAgICAgKlxuICAgICAqIGNvbnNvbGUubG9nKGFycmF5KTtcbiAgICAgKiAvLyA9PiBbMywgMiwgMV1cbiAgICAgKi9cbiAgICBmdW5jdGlvbiByZXZlcnNlKGFycmF5KSB7XG4gICAgICByZXR1cm4gYXJyYXkgPT0gbnVsbCA/IGFycmF5IDogbmF0aXZlUmV2ZXJzZS5jYWxsKGFycmF5KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgc2xpY2Ugb2YgYGFycmF5YCBmcm9tIGBzdGFydGAgdXAgdG8sIGJ1dCBub3QgaW5jbHVkaW5nLCBgZW5kYC5cbiAgICAgKlxuICAgICAqICoqTm90ZToqKiBUaGlzIG1ldGhvZCBpcyB1c2VkIGluc3RlYWQgb2ZcbiAgICAgKiBbYEFycmF5I3NsaWNlYF0oaHR0cHM6Ly9tZG4uaW8vQXJyYXkvc2xpY2UpIHRvIGVuc3VyZSBkZW5zZSBhcnJheXMgYXJlXG4gICAgICogcmV0dXJuZWQuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMy4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgQXJyYXlcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gc2xpY2UuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtzdGFydD0wXSBUaGUgc3RhcnQgcG9zaXRpb24uXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtlbmQ9YXJyYXkubGVuZ3RoXSBUaGUgZW5kIHBvc2l0aW9uLlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgc2xpY2Ugb2YgYGFycmF5YC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBzbGljZShhcnJheSwgc3RhcnQsIGVuZCkge1xuICAgICAgdmFyIGxlbmd0aCA9IGFycmF5ID09IG51bGwgPyAwIDogYXJyYXkubGVuZ3RoO1xuICAgICAgaWYgKCFsZW5ndGgpIHtcbiAgICAgICAgcmV0dXJuIFtdO1xuICAgICAgfVxuICAgICAgaWYgKGVuZCAmJiB0eXBlb2YgZW5kICE9ICdudW1iZXInICYmIGlzSXRlcmF0ZWVDYWxsKGFycmF5LCBzdGFydCwgZW5kKSkge1xuICAgICAgICBzdGFydCA9IDA7XG4gICAgICAgIGVuZCA9IGxlbmd0aDtcbiAgICAgIH1cbiAgICAgIGVsc2Uge1xuICAgICAgICBzdGFydCA9IHN0YXJ0ID09IG51bGwgPyAwIDogdG9JbnRlZ2VyKHN0YXJ0KTtcbiAgICAgICAgZW5kID0gZW5kID09PSB1bmRlZmluZWQgPyBsZW5ndGggOiB0b0ludGVnZXIoZW5kKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBiYXNlU2xpY2UoYXJyYXksIHN0YXJ0LCBlbmQpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFVzZXMgYSBiaW5hcnkgc2VhcmNoIHRvIGRldGVybWluZSB0aGUgbG93ZXN0IGluZGV4IGF0IHdoaWNoIGB2YWx1ZWBcbiAgICAgKiBzaG91bGQgYmUgaW5zZXJ0ZWQgaW50byBgYXJyYXlgIGluIG9yZGVyIHRvIG1haW50YWluIGl0cyBzb3J0IG9yZGVyLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDAuMS4wXG4gICAgICogQGNhdGVnb3J5IEFycmF5XG4gICAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIHNvcnRlZCBhcnJheSB0byBpbnNwZWN0LlxuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGV2YWx1YXRlLlxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9IFJldHVybnMgdGhlIGluZGV4IGF0IHdoaWNoIGB2YWx1ZWAgc2hvdWxkIGJlIGluc2VydGVkXG4gICAgICogIGludG8gYGFycmF5YC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5zb3J0ZWRJbmRleChbMzAsIDUwXSwgNDApO1xuICAgICAqIC8vID0+IDFcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBzb3J0ZWRJbmRleChhcnJheSwgdmFsdWUpIHtcbiAgICAgIHJldHVybiBiYXNlU29ydGVkSW5kZXgoYXJyYXksIHZhbHVlKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIG1ldGhvZCBpcyBsaWtlIGBfLnNvcnRlZEluZGV4YCBleGNlcHQgdGhhdCBpdCBhY2NlcHRzIGBpdGVyYXRlZWBcbiAgICAgKiB3aGljaCBpcyBpbnZva2VkIGZvciBgdmFsdWVgIGFuZCBlYWNoIGVsZW1lbnQgb2YgYGFycmF5YCB0byBjb21wdXRlIHRoZWlyXG4gICAgICogc29ydCByYW5raW5nLiBUaGUgaXRlcmF0ZWUgaXMgaW52b2tlZCB3aXRoIG9uZSBhcmd1bWVudDogKHZhbHVlKS5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjAuMFxuICAgICAqIEBjYXRlZ29yeSBBcnJheVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBzb3J0ZWQgYXJyYXkgdG8gaW5zcGVjdC5cbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBldmFsdWF0ZS5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbaXRlcmF0ZWU9Xy5pZGVudGl0eV0gVGhlIGl0ZXJhdGVlIGludm9rZWQgcGVyIGVsZW1lbnQuXG4gICAgICogQHJldHVybnMge251bWJlcn0gUmV0dXJucyB0aGUgaW5kZXggYXQgd2hpY2ggYHZhbHVlYCBzaG91bGQgYmUgaW5zZXJ0ZWRcbiAgICAgKiAgaW50byBgYXJyYXlgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgb2JqZWN0cyA9IFt7ICd4JzogNCB9LCB7ICd4JzogNSB9XTtcbiAgICAgKlxuICAgICAqIF8uc29ydGVkSW5kZXhCeShvYmplY3RzLCB7ICd4JzogNCB9LCBmdW5jdGlvbihvKSB7IHJldHVybiBvLng7IH0pO1xuICAgICAqIC8vID0+IDBcbiAgICAgKlxuICAgICAqIC8vIFRoZSBgXy5wcm9wZXJ0eWAgaXRlcmF0ZWUgc2hvcnRoYW5kLlxuICAgICAqIF8uc29ydGVkSW5kZXhCeShvYmplY3RzLCB7ICd4JzogNCB9LCAneCcpO1xuICAgICAqIC8vID0+IDBcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBzb3J0ZWRJbmRleEJ5KGFycmF5LCB2YWx1ZSwgaXRlcmF0ZWUpIHtcbiAgICAgIHJldHVybiBiYXNlU29ydGVkSW5kZXhCeShhcnJheSwgdmFsdWUsIGdldEl0ZXJhdGVlKGl0ZXJhdGVlLCAyKSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgaXMgbGlrZSBgXy5pbmRleE9mYCBleGNlcHQgdGhhdCBpdCBwZXJmb3JtcyBhIGJpbmFyeVxuICAgICAqIHNlYXJjaCBvbiBhIHNvcnRlZCBgYXJyYXlgLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMC4wXG4gICAgICogQGNhdGVnb3J5IEFycmF5XG4gICAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIGluc3BlY3QuXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gc2VhcmNoIGZvci5cbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBSZXR1cm5zIHRoZSBpbmRleCBvZiB0aGUgbWF0Y2hlZCB2YWx1ZSwgZWxzZSBgLTFgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLnNvcnRlZEluZGV4T2YoWzQsIDUsIDUsIDUsIDZdLCA1KTtcbiAgICAgKiAvLyA9PiAxXG4gICAgICovXG4gICAgZnVuY3Rpb24gc29ydGVkSW5kZXhPZihhcnJheSwgdmFsdWUpIHtcbiAgICAgIHZhciBsZW5ndGggPSBhcnJheSA9PSBudWxsID8gMCA6IGFycmF5Lmxlbmd0aDtcbiAgICAgIGlmIChsZW5ndGgpIHtcbiAgICAgICAgdmFyIGluZGV4ID0gYmFzZVNvcnRlZEluZGV4KGFycmF5LCB2YWx1ZSk7XG4gICAgICAgIGlmIChpbmRleCA8IGxlbmd0aCAmJiBlcShhcnJheVtpbmRleF0sIHZhbHVlKSkge1xuICAgICAgICAgIHJldHVybiBpbmRleDtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIC0xO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIGlzIGxpa2UgYF8uc29ydGVkSW5kZXhgIGV4Y2VwdCB0aGF0IGl0IHJldHVybnMgdGhlIGhpZ2hlc3RcbiAgICAgKiBpbmRleCBhdCB3aGljaCBgdmFsdWVgIHNob3VsZCBiZSBpbnNlcnRlZCBpbnRvIGBhcnJheWAgaW4gb3JkZXIgdG9cbiAgICAgKiBtYWludGFpbiBpdHMgc29ydCBvcmRlci5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAzLjAuMFxuICAgICAqIEBjYXRlZ29yeSBBcnJheVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBzb3J0ZWQgYXJyYXkgdG8gaW5zcGVjdC5cbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBldmFsdWF0ZS5cbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBSZXR1cm5zIHRoZSBpbmRleCBhdCB3aGljaCBgdmFsdWVgIHNob3VsZCBiZSBpbnNlcnRlZFxuICAgICAqICBpbnRvIGBhcnJheWAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uc29ydGVkTGFzdEluZGV4KFs0LCA1LCA1LCA1LCA2XSwgNSk7XG4gICAgICogLy8gPT4gNFxuICAgICAqL1xuICAgIGZ1bmN0aW9uIHNvcnRlZExhc3RJbmRleChhcnJheSwgdmFsdWUpIHtcbiAgICAgIHJldHVybiBiYXNlU29ydGVkSW5kZXgoYXJyYXksIHZhbHVlLCB0cnVlKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIG1ldGhvZCBpcyBsaWtlIGBfLnNvcnRlZExhc3RJbmRleGAgZXhjZXB0IHRoYXQgaXQgYWNjZXB0cyBgaXRlcmF0ZWVgXG4gICAgICogd2hpY2ggaXMgaW52b2tlZCBmb3IgYHZhbHVlYCBhbmQgZWFjaCBlbGVtZW50IG9mIGBhcnJheWAgdG8gY29tcHV0ZSB0aGVpclxuICAgICAqIHNvcnQgcmFua2luZy4gVGhlIGl0ZXJhdGVlIGlzIGludm9rZWQgd2l0aCBvbmUgYXJndW1lbnQ6ICh2YWx1ZSkuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgQXJyYXlcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgc29ydGVkIGFycmF5IHRvIGluc3BlY3QuXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gZXZhbHVhdGUuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW2l0ZXJhdGVlPV8uaWRlbnRpdHldIFRoZSBpdGVyYXRlZSBpbnZva2VkIHBlciBlbGVtZW50LlxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9IFJldHVybnMgdGhlIGluZGV4IGF0IHdoaWNoIGB2YWx1ZWAgc2hvdWxkIGJlIGluc2VydGVkXG4gICAgICogIGludG8gYGFycmF5YC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIG9iamVjdHMgPSBbeyAneCc6IDQgfSwgeyAneCc6IDUgfV07XG4gICAgICpcbiAgICAgKiBfLnNvcnRlZExhc3RJbmRleEJ5KG9iamVjdHMsIHsgJ3gnOiA0IH0sIGZ1bmN0aW9uKG8pIHsgcmV0dXJuIG8ueDsgfSk7XG4gICAgICogLy8gPT4gMVxuICAgICAqXG4gICAgICogLy8gVGhlIGBfLnByb3BlcnR5YCBpdGVyYXRlZSBzaG9ydGhhbmQuXG4gICAgICogXy5zb3J0ZWRMYXN0SW5kZXhCeShvYmplY3RzLCB7ICd4JzogNCB9LCAneCcpO1xuICAgICAqIC8vID0+IDFcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBzb3J0ZWRMYXN0SW5kZXhCeShhcnJheSwgdmFsdWUsIGl0ZXJhdGVlKSB7XG4gICAgICByZXR1cm4gYmFzZVNvcnRlZEluZGV4QnkoYXJyYXksIHZhbHVlLCBnZXRJdGVyYXRlZShpdGVyYXRlZSwgMiksIHRydWUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIGlzIGxpa2UgYF8ubGFzdEluZGV4T2ZgIGV4Y2VwdCB0aGF0IGl0IHBlcmZvcm1zIGEgYmluYXJ5XG4gICAgICogc2VhcmNoIG9uIGEgc29ydGVkIGBhcnJheWAuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgQXJyYXlcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gaW5zcGVjdC5cbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBzZWFyY2ggZm9yLlxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9IFJldHVybnMgdGhlIGluZGV4IG9mIHRoZSBtYXRjaGVkIHZhbHVlLCBlbHNlIGAtMWAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uc29ydGVkTGFzdEluZGV4T2YoWzQsIDUsIDUsIDUsIDZdLCA1KTtcbiAgICAgKiAvLyA9PiAzXG4gICAgICovXG4gICAgZnVuY3Rpb24gc29ydGVkTGFzdEluZGV4T2YoYXJyYXksIHZhbHVlKSB7XG4gICAgICB2YXIgbGVuZ3RoID0gYXJyYXkgPT0gbnVsbCA/IDAgOiBhcnJheS5sZW5ndGg7XG4gICAgICBpZiAobGVuZ3RoKSB7XG4gICAgICAgIHZhciBpbmRleCA9IGJhc2VTb3J0ZWRJbmRleChhcnJheSwgdmFsdWUsIHRydWUpIC0gMTtcbiAgICAgICAgaWYgKGVxKGFycmF5W2luZGV4XSwgdmFsdWUpKSB7XG4gICAgICAgICAgcmV0dXJuIGluZGV4O1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gLTE7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgaXMgbGlrZSBgXy51bmlxYCBleGNlcHQgdGhhdCBpdCdzIGRlc2lnbmVkIGFuZCBvcHRpbWl6ZWRcbiAgICAgKiBmb3Igc29ydGVkIGFycmF5cy5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjAuMFxuICAgICAqIEBjYXRlZ29yeSBBcnJheVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBpbnNwZWN0LlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IGR1cGxpY2F0ZSBmcmVlIGFycmF5LlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLnNvcnRlZFVuaXEoWzEsIDEsIDJdKTtcbiAgICAgKiAvLyA9PiBbMSwgMl1cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBzb3J0ZWRVbmlxKGFycmF5KSB7XG4gICAgICByZXR1cm4gKGFycmF5ICYmIGFycmF5Lmxlbmd0aClcbiAgICAgICAgPyBiYXNlU29ydGVkVW5pcShhcnJheSlcbiAgICAgICAgOiBbXTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIG1ldGhvZCBpcyBsaWtlIGBfLnVuaXFCeWAgZXhjZXB0IHRoYXQgaXQncyBkZXNpZ25lZCBhbmQgb3B0aW1pemVkXG4gICAgICogZm9yIHNvcnRlZCBhcnJheXMuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgQXJyYXlcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gaW5zcGVjdC5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbaXRlcmF0ZWVdIFRoZSBpdGVyYXRlZSBpbnZva2VkIHBlciBlbGVtZW50LlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IGR1cGxpY2F0ZSBmcmVlIGFycmF5LlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLnNvcnRlZFVuaXFCeShbMS4xLCAxLjIsIDIuMywgMi40XSwgTWF0aC5mbG9vcik7XG4gICAgICogLy8gPT4gWzEuMSwgMi4zXVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIHNvcnRlZFVuaXFCeShhcnJheSwgaXRlcmF0ZWUpIHtcbiAgICAgIHJldHVybiAoYXJyYXkgJiYgYXJyYXkubGVuZ3RoKVxuICAgICAgICA/IGJhc2VTb3J0ZWRVbmlxKGFycmF5LCBnZXRJdGVyYXRlZShpdGVyYXRlZSwgMikpXG4gICAgICAgIDogW107XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0cyBhbGwgYnV0IHRoZSBmaXJzdCBlbGVtZW50IG9mIGBhcnJheWAuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgQXJyYXlcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gcXVlcnkuXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBzbGljZSBvZiBgYXJyYXlgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLnRhaWwoWzEsIDIsIDNdKTtcbiAgICAgKiAvLyA9PiBbMiwgM11cbiAgICAgKi9cbiAgICBmdW5jdGlvbiB0YWlsKGFycmF5KSB7XG4gICAgICB2YXIgbGVuZ3RoID0gYXJyYXkgPT0gbnVsbCA/IDAgOiBhcnJheS5sZW5ndGg7XG4gICAgICByZXR1cm4gbGVuZ3RoID8gYmFzZVNsaWNlKGFycmF5LCAxLCBsZW5ndGgpIDogW107XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIHNsaWNlIG9mIGBhcnJheWAgd2l0aCBgbmAgZWxlbWVudHMgdGFrZW4gZnJvbSB0aGUgYmVnaW5uaW5nLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDAuMS4wXG4gICAgICogQGNhdGVnb3J5IEFycmF5XG4gICAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIHF1ZXJ5LlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbbj0xXSBUaGUgbnVtYmVyIG9mIGVsZW1lbnRzIHRvIHRha2UuXG4gICAgICogQHBhcmFtLSB7T2JqZWN0fSBbZ3VhcmRdIEVuYWJsZXMgdXNlIGFzIGFuIGl0ZXJhdGVlIGZvciBtZXRob2RzIGxpa2UgYF8ubWFwYC5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIHNsaWNlIG9mIGBhcnJheWAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8udGFrZShbMSwgMiwgM10pO1xuICAgICAqIC8vID0+IFsxXVxuICAgICAqXG4gICAgICogXy50YWtlKFsxLCAyLCAzXSwgMik7XG4gICAgICogLy8gPT4gWzEsIDJdXG4gICAgICpcbiAgICAgKiBfLnRha2UoWzEsIDIsIDNdLCA1KTtcbiAgICAgKiAvLyA9PiBbMSwgMiwgM11cbiAgICAgKlxuICAgICAqIF8udGFrZShbMSwgMiwgM10sIDApO1xuICAgICAqIC8vID0+IFtdXG4gICAgICovXG4gICAgZnVuY3Rpb24gdGFrZShhcnJheSwgbiwgZ3VhcmQpIHtcbiAgICAgIGlmICghKGFycmF5ICYmIGFycmF5Lmxlbmd0aCkpIHtcbiAgICAgICAgcmV0dXJuIFtdO1xuICAgICAgfVxuICAgICAgbiA9IChndWFyZCB8fCBuID09PSB1bmRlZmluZWQpID8gMSA6IHRvSW50ZWdlcihuKTtcbiAgICAgIHJldHVybiBiYXNlU2xpY2UoYXJyYXksIDAsIG4gPCAwID8gMCA6IG4pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBzbGljZSBvZiBgYXJyYXlgIHdpdGggYG5gIGVsZW1lbnRzIHRha2VuIGZyb20gdGhlIGVuZC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAzLjAuMFxuICAgICAqIEBjYXRlZ29yeSBBcnJheVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBxdWVyeS5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW249MV0gVGhlIG51bWJlciBvZiBlbGVtZW50cyB0byB0YWtlLlxuICAgICAqIEBwYXJhbS0ge09iamVjdH0gW2d1YXJkXSBFbmFibGVzIHVzZSBhcyBhbiBpdGVyYXRlZSBmb3IgbWV0aG9kcyBsaWtlIGBfLm1hcGAuXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBzbGljZSBvZiBgYXJyYXlgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLnRha2VSaWdodChbMSwgMiwgM10pO1xuICAgICAqIC8vID0+IFszXVxuICAgICAqXG4gICAgICogXy50YWtlUmlnaHQoWzEsIDIsIDNdLCAyKTtcbiAgICAgKiAvLyA9PiBbMiwgM11cbiAgICAgKlxuICAgICAqIF8udGFrZVJpZ2h0KFsxLCAyLCAzXSwgNSk7XG4gICAgICogLy8gPT4gWzEsIDIsIDNdXG4gICAgICpcbiAgICAgKiBfLnRha2VSaWdodChbMSwgMiwgM10sIDApO1xuICAgICAqIC8vID0+IFtdXG4gICAgICovXG4gICAgZnVuY3Rpb24gdGFrZVJpZ2h0KGFycmF5LCBuLCBndWFyZCkge1xuICAgICAgdmFyIGxlbmd0aCA9IGFycmF5ID09IG51bGwgPyAwIDogYXJyYXkubGVuZ3RoO1xuICAgICAgaWYgKCFsZW5ndGgpIHtcbiAgICAgICAgcmV0dXJuIFtdO1xuICAgICAgfVxuICAgICAgbiA9IChndWFyZCB8fCBuID09PSB1bmRlZmluZWQpID8gMSA6IHRvSW50ZWdlcihuKTtcbiAgICAgIG4gPSBsZW5ndGggLSBuO1xuICAgICAgcmV0dXJuIGJhc2VTbGljZShhcnJheSwgbiA8IDAgPyAwIDogbiwgbGVuZ3RoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgc2xpY2Ugb2YgYGFycmF5YCB3aXRoIGVsZW1lbnRzIHRha2VuIGZyb20gdGhlIGVuZC4gRWxlbWVudHMgYXJlXG4gICAgICogdGFrZW4gdW50aWwgYHByZWRpY2F0ZWAgcmV0dXJucyBmYWxzZXkuIFRoZSBwcmVkaWNhdGUgaXMgaW52b2tlZCB3aXRoXG4gICAgICogdGhyZWUgYXJndW1lbnRzOiAodmFsdWUsIGluZGV4LCBhcnJheSkuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMy4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgQXJyYXlcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gcXVlcnkuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW3ByZWRpY2F0ZT1fLmlkZW50aXR5XSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgc2xpY2Ugb2YgYGFycmF5YC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIHVzZXJzID0gW1xuICAgICAqICAgeyAndXNlcic6ICdiYXJuZXknLCAgJ2FjdGl2ZSc6IHRydWUgfSxcbiAgICAgKiAgIHsgJ3VzZXInOiAnZnJlZCcsICAgICdhY3RpdmUnOiBmYWxzZSB9LFxuICAgICAqICAgeyAndXNlcic6ICdwZWJibGVzJywgJ2FjdGl2ZSc6IGZhbHNlIH1cbiAgICAgKiBdO1xuICAgICAqXG4gICAgICogXy50YWtlUmlnaHRXaGlsZSh1c2VycywgZnVuY3Rpb24obykgeyByZXR1cm4gIW8uYWN0aXZlOyB9KTtcbiAgICAgKiAvLyA9PiBvYmplY3RzIGZvciBbJ2ZyZWQnLCAncGViYmxlcyddXG4gICAgICpcbiAgICAgKiAvLyBUaGUgYF8ubWF0Y2hlc2AgaXRlcmF0ZWUgc2hvcnRoYW5kLlxuICAgICAqIF8udGFrZVJpZ2h0V2hpbGUodXNlcnMsIHsgJ3VzZXInOiAncGViYmxlcycsICdhY3RpdmUnOiBmYWxzZSB9KTtcbiAgICAgKiAvLyA9PiBvYmplY3RzIGZvciBbJ3BlYmJsZXMnXVxuICAgICAqXG4gICAgICogLy8gVGhlIGBfLm1hdGNoZXNQcm9wZXJ0eWAgaXRlcmF0ZWUgc2hvcnRoYW5kLlxuICAgICAqIF8udGFrZVJpZ2h0V2hpbGUodXNlcnMsIFsnYWN0aXZlJywgZmFsc2VdKTtcbiAgICAgKiAvLyA9PiBvYmplY3RzIGZvciBbJ2ZyZWQnLCAncGViYmxlcyddXG4gICAgICpcbiAgICAgKiAvLyBUaGUgYF8ucHJvcGVydHlgIGl0ZXJhdGVlIHNob3J0aGFuZC5cbiAgICAgKiBfLnRha2VSaWdodFdoaWxlKHVzZXJzLCAnYWN0aXZlJyk7XG4gICAgICogLy8gPT4gW11cbiAgICAgKi9cbiAgICBmdW5jdGlvbiB0YWtlUmlnaHRXaGlsZShhcnJheSwgcHJlZGljYXRlKSB7XG4gICAgICByZXR1cm4gKGFycmF5ICYmIGFycmF5Lmxlbmd0aClcbiAgICAgICAgPyBiYXNlV2hpbGUoYXJyYXksIGdldEl0ZXJhdGVlKHByZWRpY2F0ZSwgMyksIGZhbHNlLCB0cnVlKVxuICAgICAgICA6IFtdO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBzbGljZSBvZiBgYXJyYXlgIHdpdGggZWxlbWVudHMgdGFrZW4gZnJvbSB0aGUgYmVnaW5uaW5nLiBFbGVtZW50c1xuICAgICAqIGFyZSB0YWtlbiB1bnRpbCBgcHJlZGljYXRlYCByZXR1cm5zIGZhbHNleS4gVGhlIHByZWRpY2F0ZSBpcyBpbnZva2VkIHdpdGhcbiAgICAgKiB0aHJlZSBhcmd1bWVudHM6ICh2YWx1ZSwgaW5kZXgsIGFycmF5KS5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAzLjAuMFxuICAgICAqIEBjYXRlZ29yeSBBcnJheVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBxdWVyeS5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbcHJlZGljYXRlPV8uaWRlbnRpdHldIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBzbGljZSBvZiBgYXJyYXlgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgdXNlcnMgPSBbXG4gICAgICogICB7ICd1c2VyJzogJ2Jhcm5leScsICAnYWN0aXZlJzogZmFsc2UgfSxcbiAgICAgKiAgIHsgJ3VzZXInOiAnZnJlZCcsICAgICdhY3RpdmUnOiBmYWxzZSB9LFxuICAgICAqICAgeyAndXNlcic6ICdwZWJibGVzJywgJ2FjdGl2ZSc6IHRydWUgfVxuICAgICAqIF07XG4gICAgICpcbiAgICAgKiBfLnRha2VXaGlsZSh1c2VycywgZnVuY3Rpb24obykgeyByZXR1cm4gIW8uYWN0aXZlOyB9KTtcbiAgICAgKiAvLyA9PiBvYmplY3RzIGZvciBbJ2Jhcm5leScsICdmcmVkJ11cbiAgICAgKlxuICAgICAqIC8vIFRoZSBgXy5tYXRjaGVzYCBpdGVyYXRlZSBzaG9ydGhhbmQuXG4gICAgICogXy50YWtlV2hpbGUodXNlcnMsIHsgJ3VzZXInOiAnYmFybmV5JywgJ2FjdGl2ZSc6IGZhbHNlIH0pO1xuICAgICAqIC8vID0+IG9iamVjdHMgZm9yIFsnYmFybmV5J11cbiAgICAgKlxuICAgICAqIC8vIFRoZSBgXy5tYXRjaGVzUHJvcGVydHlgIGl0ZXJhdGVlIHNob3J0aGFuZC5cbiAgICAgKiBfLnRha2VXaGlsZSh1c2VycywgWydhY3RpdmUnLCBmYWxzZV0pO1xuICAgICAqIC8vID0+IG9iamVjdHMgZm9yIFsnYmFybmV5JywgJ2ZyZWQnXVxuICAgICAqXG4gICAgICogLy8gVGhlIGBfLnByb3BlcnR5YCBpdGVyYXRlZSBzaG9ydGhhbmQuXG4gICAgICogXy50YWtlV2hpbGUodXNlcnMsICdhY3RpdmUnKTtcbiAgICAgKiAvLyA9PiBbXVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIHRha2VXaGlsZShhcnJheSwgcHJlZGljYXRlKSB7XG4gICAgICByZXR1cm4gKGFycmF5ICYmIGFycmF5Lmxlbmd0aClcbiAgICAgICAgPyBiYXNlV2hpbGUoYXJyYXksIGdldEl0ZXJhdGVlKHByZWRpY2F0ZSwgMykpXG4gICAgICAgIDogW107XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhbiBhcnJheSBvZiB1bmlxdWUgdmFsdWVzLCBpbiBvcmRlciwgZnJvbSBhbGwgZ2l2ZW4gYXJyYXlzIHVzaW5nXG4gICAgICogW2BTYW1lVmFsdWVaZXJvYF0oaHR0cDovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNy4wLyNzZWMtc2FtZXZhbHVlemVybylcbiAgICAgKiBmb3IgZXF1YWxpdHkgY29tcGFyaXNvbnMuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMC4xLjBcbiAgICAgKiBAY2F0ZWdvcnkgQXJyYXlcbiAgICAgKiBAcGFyYW0gey4uLkFycmF5fSBbYXJyYXlzXSBUaGUgYXJyYXlzIHRvIGluc3BlY3QuXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBuZXcgYXJyYXkgb2YgY29tYmluZWQgdmFsdWVzLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLnVuaW9uKFsyXSwgWzEsIDJdKTtcbiAgICAgKiAvLyA9PiBbMiwgMV1cbiAgICAgKi9cbiAgICB2YXIgdW5pb24gPSBiYXNlUmVzdChmdW5jdGlvbihhcnJheXMpIHtcbiAgICAgIHJldHVybiBiYXNlVW5pcShiYXNlRmxhdHRlbihhcnJheXMsIDEsIGlzQXJyYXlMaWtlT2JqZWN0LCB0cnVlKSk7XG4gICAgfSk7XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIG1ldGhvZCBpcyBsaWtlIGBfLnVuaW9uYCBleGNlcHQgdGhhdCBpdCBhY2NlcHRzIGBpdGVyYXRlZWAgd2hpY2ggaXNcbiAgICAgKiBpbnZva2VkIGZvciBlYWNoIGVsZW1lbnQgb2YgZWFjaCBgYXJyYXlzYCB0byBnZW5lcmF0ZSB0aGUgY3JpdGVyaW9uIGJ5XG4gICAgICogd2hpY2ggdW5pcXVlbmVzcyBpcyBjb21wdXRlZC4gUmVzdWx0IHZhbHVlcyBhcmUgY2hvc2VuIGZyb20gdGhlIGZpcnN0XG4gICAgICogYXJyYXkgaW4gd2hpY2ggdGhlIHZhbHVlIG9jY3Vycy4gVGhlIGl0ZXJhdGVlIGlzIGludm9rZWQgd2l0aCBvbmUgYXJndW1lbnQ6XG4gICAgICogKHZhbHVlKS5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjAuMFxuICAgICAqIEBjYXRlZ29yeSBBcnJheVxuICAgICAqIEBwYXJhbSB7Li4uQXJyYXl9IFthcnJheXNdIFRoZSBhcnJheXMgdG8gaW5zcGVjdC5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbaXRlcmF0ZWU9Xy5pZGVudGl0eV0gVGhlIGl0ZXJhdGVlIGludm9rZWQgcGVyIGVsZW1lbnQuXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBuZXcgYXJyYXkgb2YgY29tYmluZWQgdmFsdWVzLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLnVuaW9uQnkoWzIuMV0sIFsxLjIsIDIuM10sIE1hdGguZmxvb3IpO1xuICAgICAqIC8vID0+IFsyLjEsIDEuMl1cbiAgICAgKlxuICAgICAqIC8vIFRoZSBgXy5wcm9wZXJ0eWAgaXRlcmF0ZWUgc2hvcnRoYW5kLlxuICAgICAqIF8udW5pb25CeShbeyAneCc6IDEgfV0sIFt7ICd4JzogMiB9LCB7ICd4JzogMSB9XSwgJ3gnKTtcbiAgICAgKiAvLyA9PiBbeyAneCc6IDEgfSwgeyAneCc6IDIgfV1cbiAgICAgKi9cbiAgICB2YXIgdW5pb25CeSA9IGJhc2VSZXN0KGZ1bmN0aW9uKGFycmF5cykge1xuICAgICAgdmFyIGl0ZXJhdGVlID0gbGFzdChhcnJheXMpO1xuICAgICAgaWYgKGlzQXJyYXlMaWtlT2JqZWN0KGl0ZXJhdGVlKSkge1xuICAgICAgICBpdGVyYXRlZSA9IHVuZGVmaW5lZDtcbiAgICAgIH1cbiAgICAgIHJldHVybiBiYXNlVW5pcShiYXNlRmxhdHRlbihhcnJheXMsIDEsIGlzQXJyYXlMaWtlT2JqZWN0LCB0cnVlKSwgZ2V0SXRlcmF0ZWUoaXRlcmF0ZWUsIDIpKTtcbiAgICB9KTtcblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIGlzIGxpa2UgYF8udW5pb25gIGV4Y2VwdCB0aGF0IGl0IGFjY2VwdHMgYGNvbXBhcmF0b3JgIHdoaWNoXG4gICAgICogaXMgaW52b2tlZCB0byBjb21wYXJlIGVsZW1lbnRzIG9mIGBhcnJheXNgLiBSZXN1bHQgdmFsdWVzIGFyZSBjaG9zZW4gZnJvbVxuICAgICAqIHRoZSBmaXJzdCBhcnJheSBpbiB3aGljaCB0aGUgdmFsdWUgb2NjdXJzLiBUaGUgY29tcGFyYXRvciBpcyBpbnZva2VkXG4gICAgICogd2l0aCB0d28gYXJndW1lbnRzOiAoYXJyVmFsLCBvdGhWYWwpLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMC4wXG4gICAgICogQGNhdGVnb3J5IEFycmF5XG4gICAgICogQHBhcmFtIHsuLi5BcnJheX0gW2FycmF5c10gVGhlIGFycmF5cyB0byBpbnNwZWN0LlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IFtjb21wYXJhdG9yXSBUaGUgY29tcGFyYXRvciBpbnZva2VkIHBlciBlbGVtZW50LlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IGFycmF5IG9mIGNvbWJpbmVkIHZhbHVlcy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIG9iamVjdHMgPSBbeyAneCc6IDEsICd5JzogMiB9LCB7ICd4JzogMiwgJ3knOiAxIH1dO1xuICAgICAqIHZhciBvdGhlcnMgPSBbeyAneCc6IDEsICd5JzogMSB9LCB7ICd4JzogMSwgJ3knOiAyIH1dO1xuICAgICAqXG4gICAgICogXy51bmlvbldpdGgob2JqZWN0cywgb3RoZXJzLCBfLmlzRXF1YWwpO1xuICAgICAqIC8vID0+IFt7ICd4JzogMSwgJ3knOiAyIH0sIHsgJ3gnOiAyLCAneSc6IDEgfSwgeyAneCc6IDEsICd5JzogMSB9XVxuICAgICAqL1xuICAgIHZhciB1bmlvbldpdGggPSBiYXNlUmVzdChmdW5jdGlvbihhcnJheXMpIHtcbiAgICAgIHZhciBjb21wYXJhdG9yID0gbGFzdChhcnJheXMpO1xuICAgICAgY29tcGFyYXRvciA9IHR5cGVvZiBjb21wYXJhdG9yID09ICdmdW5jdGlvbicgPyBjb21wYXJhdG9yIDogdW5kZWZpbmVkO1xuICAgICAgcmV0dXJuIGJhc2VVbmlxKGJhc2VGbGF0dGVuKGFycmF5cywgMSwgaXNBcnJheUxpa2VPYmplY3QsIHRydWUpLCB1bmRlZmluZWQsIGNvbXBhcmF0b3IpO1xuICAgIH0pO1xuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIGR1cGxpY2F0ZS1mcmVlIHZlcnNpb24gb2YgYW4gYXJyYXksIHVzaW5nXG4gICAgICogW2BTYW1lVmFsdWVaZXJvYF0oaHR0cDovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNy4wLyNzZWMtc2FtZXZhbHVlemVybylcbiAgICAgKiBmb3IgZXF1YWxpdHkgY29tcGFyaXNvbnMsIGluIHdoaWNoIG9ubHkgdGhlIGZpcnN0IG9jY3VycmVuY2Ugb2YgZWFjaCBlbGVtZW50XG4gICAgICogaXMga2VwdC4gVGhlIG9yZGVyIG9mIHJlc3VsdCB2YWx1ZXMgaXMgZGV0ZXJtaW5lZCBieSB0aGUgb3JkZXIgdGhleSBvY2N1clxuICAgICAqIGluIHRoZSBhcnJheS5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAwLjEuMFxuICAgICAqIEBjYXRlZ29yeSBBcnJheVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBpbnNwZWN0LlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IGR1cGxpY2F0ZSBmcmVlIGFycmF5LlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLnVuaXEoWzIsIDEsIDJdKTtcbiAgICAgKiAvLyA9PiBbMiwgMV1cbiAgICAgKi9cbiAgICBmdW5jdGlvbiB1bmlxKGFycmF5KSB7XG4gICAgICByZXR1cm4gKGFycmF5ICYmIGFycmF5Lmxlbmd0aCkgPyBiYXNlVW5pcShhcnJheSkgOiBbXTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIG1ldGhvZCBpcyBsaWtlIGBfLnVuaXFgIGV4Y2VwdCB0aGF0IGl0IGFjY2VwdHMgYGl0ZXJhdGVlYCB3aGljaCBpc1xuICAgICAqIGludm9rZWQgZm9yIGVhY2ggZWxlbWVudCBpbiBgYXJyYXlgIHRvIGdlbmVyYXRlIHRoZSBjcml0ZXJpb24gYnkgd2hpY2hcbiAgICAgKiB1bmlxdWVuZXNzIGlzIGNvbXB1dGVkLiBUaGUgb3JkZXIgb2YgcmVzdWx0IHZhbHVlcyBpcyBkZXRlcm1pbmVkIGJ5IHRoZVxuICAgICAqIG9yZGVyIHRoZXkgb2NjdXIgaW4gdGhlIGFycmF5LiBUaGUgaXRlcmF0ZWUgaXMgaW52b2tlZCB3aXRoIG9uZSBhcmd1bWVudDpcbiAgICAgKiAodmFsdWUpLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMC4wXG4gICAgICogQGNhdGVnb3J5IEFycmF5XG4gICAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIGluc3BlY3QuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW2l0ZXJhdGVlPV8uaWRlbnRpdHldIFRoZSBpdGVyYXRlZSBpbnZva2VkIHBlciBlbGVtZW50LlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IGR1cGxpY2F0ZSBmcmVlIGFycmF5LlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLnVuaXFCeShbMi4xLCAxLjIsIDIuM10sIE1hdGguZmxvb3IpO1xuICAgICAqIC8vID0+IFsyLjEsIDEuMl1cbiAgICAgKlxuICAgICAqIC8vIFRoZSBgXy5wcm9wZXJ0eWAgaXRlcmF0ZWUgc2hvcnRoYW5kLlxuICAgICAqIF8udW5pcUJ5KFt7ICd4JzogMSB9LCB7ICd4JzogMiB9LCB7ICd4JzogMSB9XSwgJ3gnKTtcbiAgICAgKiAvLyA9PiBbeyAneCc6IDEgfSwgeyAneCc6IDIgfV1cbiAgICAgKi9cbiAgICBmdW5jdGlvbiB1bmlxQnkoYXJyYXksIGl0ZXJhdGVlKSB7XG4gICAgICByZXR1cm4gKGFycmF5ICYmIGFycmF5Lmxlbmd0aCkgPyBiYXNlVW5pcShhcnJheSwgZ2V0SXRlcmF0ZWUoaXRlcmF0ZWUsIDIpKSA6IFtdO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIGlzIGxpa2UgYF8udW5pcWAgZXhjZXB0IHRoYXQgaXQgYWNjZXB0cyBgY29tcGFyYXRvcmAgd2hpY2hcbiAgICAgKiBpcyBpbnZva2VkIHRvIGNvbXBhcmUgZWxlbWVudHMgb2YgYGFycmF5YC4gVGhlIG9yZGVyIG9mIHJlc3VsdCB2YWx1ZXMgaXNcbiAgICAgKiBkZXRlcm1pbmVkIGJ5IHRoZSBvcmRlciB0aGV5IG9jY3VyIGluIHRoZSBhcnJheS5UaGUgY29tcGFyYXRvciBpcyBpbnZva2VkXG4gICAgICogd2l0aCB0d28gYXJndW1lbnRzOiAoYXJyVmFsLCBvdGhWYWwpLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMC4wXG4gICAgICogQGNhdGVnb3J5IEFycmF5XG4gICAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIGluc3BlY3QuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW2NvbXBhcmF0b3JdIFRoZSBjb21wYXJhdG9yIGludm9rZWQgcGVyIGVsZW1lbnQuXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBuZXcgZHVwbGljYXRlIGZyZWUgYXJyYXkuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciBvYmplY3RzID0gW3sgJ3gnOiAxLCAneSc6IDIgfSwgeyAneCc6IDIsICd5JzogMSB9LCB7ICd4JzogMSwgJ3knOiAyIH1dO1xuICAgICAqXG4gICAgICogXy51bmlxV2l0aChvYmplY3RzLCBfLmlzRXF1YWwpO1xuICAgICAqIC8vID0+IFt7ICd4JzogMSwgJ3knOiAyIH0sIHsgJ3gnOiAyLCAneSc6IDEgfV1cbiAgICAgKi9cbiAgICBmdW5jdGlvbiB1bmlxV2l0aChhcnJheSwgY29tcGFyYXRvcikge1xuICAgICAgY29tcGFyYXRvciA9IHR5cGVvZiBjb21wYXJhdG9yID09ICdmdW5jdGlvbicgPyBjb21wYXJhdG9yIDogdW5kZWZpbmVkO1xuICAgICAgcmV0dXJuIChhcnJheSAmJiBhcnJheS5sZW5ndGgpID8gYmFzZVVuaXEoYXJyYXksIHVuZGVmaW5lZCwgY29tcGFyYXRvcikgOiBbXTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIG1ldGhvZCBpcyBsaWtlIGBfLnppcGAgZXhjZXB0IHRoYXQgaXQgYWNjZXB0cyBhbiBhcnJheSBvZiBncm91cGVkXG4gICAgICogZWxlbWVudHMgYW5kIGNyZWF0ZXMgYW4gYXJyYXkgcmVncm91cGluZyB0aGUgZWxlbWVudHMgdG8gdGhlaXIgcHJlLXppcFxuICAgICAqIGNvbmZpZ3VyYXRpb24uXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMS4yLjBcbiAgICAgKiBAY2F0ZWdvcnkgQXJyYXlcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgb2YgZ3JvdXBlZCBlbGVtZW50cyB0byBwcm9jZXNzLlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IGFycmF5IG9mIHJlZ3JvdXBlZCBlbGVtZW50cy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIHppcHBlZCA9IF8uemlwKFsnYScsICdiJ10sIFsxLCAyXSwgW3RydWUsIGZhbHNlXSk7XG4gICAgICogLy8gPT4gW1snYScsIDEsIHRydWVdLCBbJ2InLCAyLCBmYWxzZV1dXG4gICAgICpcbiAgICAgKiBfLnVuemlwKHppcHBlZCk7XG4gICAgICogLy8gPT4gW1snYScsICdiJ10sIFsxLCAyXSwgW3RydWUsIGZhbHNlXV1cbiAgICAgKi9cbiAgICBmdW5jdGlvbiB1bnppcChhcnJheSkge1xuICAgICAgaWYgKCEoYXJyYXkgJiYgYXJyYXkubGVuZ3RoKSkge1xuICAgICAgICByZXR1cm4gW107XG4gICAgICB9XG4gICAgICB2YXIgbGVuZ3RoID0gMDtcbiAgICAgIGFycmF5ID0gYXJyYXlGaWx0ZXIoYXJyYXksIGZ1bmN0aW9uKGdyb3VwKSB7XG4gICAgICAgIGlmIChpc0FycmF5TGlrZU9iamVjdChncm91cCkpIHtcbiAgICAgICAgICBsZW5ndGggPSBuYXRpdmVNYXgoZ3JvdXAubGVuZ3RoLCBsZW5ndGgpO1xuICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICAgIHJldHVybiBiYXNlVGltZXMobGVuZ3RoLCBmdW5jdGlvbihpbmRleCkge1xuICAgICAgICByZXR1cm4gYXJyYXlNYXAoYXJyYXksIGJhc2VQcm9wZXJ0eShpbmRleCkpO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgaXMgbGlrZSBgXy51bnppcGAgZXhjZXB0IHRoYXQgaXQgYWNjZXB0cyBgaXRlcmF0ZWVgIHRvIHNwZWNpZnlcbiAgICAgKiBob3cgcmVncm91cGVkIHZhbHVlcyBzaG91bGQgYmUgY29tYmluZWQuIFRoZSBpdGVyYXRlZSBpcyBpbnZva2VkIHdpdGggdGhlXG4gICAgICogZWxlbWVudHMgb2YgZWFjaCBncm91cDogKC4uLmdyb3VwKS5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAzLjguMFxuICAgICAqIEBjYXRlZ29yeSBBcnJheVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSBvZiBncm91cGVkIGVsZW1lbnRzIHRvIHByb2Nlc3MuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW2l0ZXJhdGVlPV8uaWRlbnRpdHldIFRoZSBmdW5jdGlvbiB0byBjb21iaW5lXG4gICAgICogIHJlZ3JvdXBlZCB2YWx1ZXMuXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBuZXcgYXJyYXkgb2YgcmVncm91cGVkIGVsZW1lbnRzLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgemlwcGVkID0gXy56aXAoWzEsIDJdLCBbMTAsIDIwXSwgWzEwMCwgMjAwXSk7XG4gICAgICogLy8gPT4gW1sxLCAxMCwgMTAwXSwgWzIsIDIwLCAyMDBdXVxuICAgICAqXG4gICAgICogXy51bnppcFdpdGgoemlwcGVkLCBfLmFkZCk7XG4gICAgICogLy8gPT4gWzMsIDMwLCAzMDBdXG4gICAgICovXG4gICAgZnVuY3Rpb24gdW56aXBXaXRoKGFycmF5LCBpdGVyYXRlZSkge1xuICAgICAgaWYgKCEoYXJyYXkgJiYgYXJyYXkubGVuZ3RoKSkge1xuICAgICAgICByZXR1cm4gW107XG4gICAgICB9XG4gICAgICB2YXIgcmVzdWx0ID0gdW56aXAoYXJyYXkpO1xuICAgICAgaWYgKGl0ZXJhdGVlID09IG51bGwpIHtcbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgIH1cbiAgICAgIHJldHVybiBhcnJheU1hcChyZXN1bHQsIGZ1bmN0aW9uKGdyb3VwKSB7XG4gICAgICAgIHJldHVybiBhcHBseShpdGVyYXRlZSwgdW5kZWZpbmVkLCBncm91cCk7XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGFuIGFycmF5IGV4Y2x1ZGluZyBhbGwgZ2l2ZW4gdmFsdWVzIHVzaW5nXG4gICAgICogW2BTYW1lVmFsdWVaZXJvYF0oaHR0cDovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNy4wLyNzZWMtc2FtZXZhbHVlemVybylcbiAgICAgKiBmb3IgZXF1YWxpdHkgY29tcGFyaXNvbnMuXG4gICAgICpcbiAgICAgKiAqKk5vdGU6KiogVW5saWtlIGBfLnB1bGxgLCB0aGlzIG1ldGhvZCByZXR1cm5zIGEgbmV3IGFycmF5LlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDAuMS4wXG4gICAgICogQGNhdGVnb3J5IEFycmF5XG4gICAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIGluc3BlY3QuXG4gICAgICogQHBhcmFtIHsuLi4qfSBbdmFsdWVzXSBUaGUgdmFsdWVzIHRvIGV4Y2x1ZGUuXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBuZXcgYXJyYXkgb2YgZmlsdGVyZWQgdmFsdWVzLlxuICAgICAqIEBzZWUgXy5kaWZmZXJlbmNlLCBfLnhvclxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLndpdGhvdXQoWzIsIDEsIDIsIDNdLCAxLCAyKTtcbiAgICAgKiAvLyA9PiBbM11cbiAgICAgKi9cbiAgICB2YXIgd2l0aG91dCA9IGJhc2VSZXN0KGZ1bmN0aW9uKGFycmF5LCB2YWx1ZXMpIHtcbiAgICAgIHJldHVybiBpc0FycmF5TGlrZU9iamVjdChhcnJheSlcbiAgICAgICAgPyBiYXNlRGlmZmVyZW5jZShhcnJheSwgdmFsdWVzKVxuICAgICAgICA6IFtdO1xuICAgIH0pO1xuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhbiBhcnJheSBvZiB1bmlxdWUgdmFsdWVzIHRoYXQgaXMgdGhlXG4gICAgICogW3N5bW1ldHJpYyBkaWZmZXJlbmNlXShodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9TeW1tZXRyaWNfZGlmZmVyZW5jZSlcbiAgICAgKiBvZiB0aGUgZ2l2ZW4gYXJyYXlzLiBUaGUgb3JkZXIgb2YgcmVzdWx0IHZhbHVlcyBpcyBkZXRlcm1pbmVkIGJ5IHRoZSBvcmRlclxuICAgICAqIHRoZXkgb2NjdXIgaW4gdGhlIGFycmF5cy5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAyLjQuMFxuICAgICAqIEBjYXRlZ29yeSBBcnJheVxuICAgICAqIEBwYXJhbSB7Li4uQXJyYXl9IFthcnJheXNdIFRoZSBhcnJheXMgdG8gaW5zcGVjdC5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIG5ldyBhcnJheSBvZiBmaWx0ZXJlZCB2YWx1ZXMuXG4gICAgICogQHNlZSBfLmRpZmZlcmVuY2UsIF8ud2l0aG91dFxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLnhvcihbMiwgMV0sIFsyLCAzXSk7XG4gICAgICogLy8gPT4gWzEsIDNdXG4gICAgICovXG4gICAgdmFyIHhvciA9IGJhc2VSZXN0KGZ1bmN0aW9uKGFycmF5cykge1xuICAgICAgcmV0dXJuIGJhc2VYb3IoYXJyYXlGaWx0ZXIoYXJyYXlzLCBpc0FycmF5TGlrZU9iamVjdCkpO1xuICAgIH0pO1xuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgaXMgbGlrZSBgXy54b3JgIGV4Y2VwdCB0aGF0IGl0IGFjY2VwdHMgYGl0ZXJhdGVlYCB3aGljaCBpc1xuICAgICAqIGludm9rZWQgZm9yIGVhY2ggZWxlbWVudCBvZiBlYWNoIGBhcnJheXNgIHRvIGdlbmVyYXRlIHRoZSBjcml0ZXJpb24gYnlcbiAgICAgKiB3aGljaCBieSB3aGljaCB0aGV5J3JlIGNvbXBhcmVkLiBUaGUgb3JkZXIgb2YgcmVzdWx0IHZhbHVlcyBpcyBkZXRlcm1pbmVkXG4gICAgICogYnkgdGhlIG9yZGVyIHRoZXkgb2NjdXIgaW4gdGhlIGFycmF5cy4gVGhlIGl0ZXJhdGVlIGlzIGludm9rZWQgd2l0aCBvbmVcbiAgICAgKiBhcmd1bWVudDogKHZhbHVlKS5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjAuMFxuICAgICAqIEBjYXRlZ29yeSBBcnJheVxuICAgICAqIEBwYXJhbSB7Li4uQXJyYXl9IFthcnJheXNdIFRoZSBhcnJheXMgdG8gaW5zcGVjdC5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbaXRlcmF0ZWU9Xy5pZGVudGl0eV0gVGhlIGl0ZXJhdGVlIGludm9rZWQgcGVyIGVsZW1lbnQuXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBuZXcgYXJyYXkgb2YgZmlsdGVyZWQgdmFsdWVzLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLnhvckJ5KFsyLjEsIDEuMl0sIFsyLjMsIDMuNF0sIE1hdGguZmxvb3IpO1xuICAgICAqIC8vID0+IFsxLjIsIDMuNF1cbiAgICAgKlxuICAgICAqIC8vIFRoZSBgXy5wcm9wZXJ0eWAgaXRlcmF0ZWUgc2hvcnRoYW5kLlxuICAgICAqIF8ueG9yQnkoW3sgJ3gnOiAxIH1dLCBbeyAneCc6IDIgfSwgeyAneCc6IDEgfV0sICd4Jyk7XG4gICAgICogLy8gPT4gW3sgJ3gnOiAyIH1dXG4gICAgICovXG4gICAgdmFyIHhvckJ5ID0gYmFzZVJlc3QoZnVuY3Rpb24oYXJyYXlzKSB7XG4gICAgICB2YXIgaXRlcmF0ZWUgPSBsYXN0KGFycmF5cyk7XG4gICAgICBpZiAoaXNBcnJheUxpa2VPYmplY3QoaXRlcmF0ZWUpKSB7XG4gICAgICAgIGl0ZXJhdGVlID0gdW5kZWZpbmVkO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGJhc2VYb3IoYXJyYXlGaWx0ZXIoYXJyYXlzLCBpc0FycmF5TGlrZU9iamVjdCksIGdldEl0ZXJhdGVlKGl0ZXJhdGVlLCAyKSk7XG4gICAgfSk7XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIG1ldGhvZCBpcyBsaWtlIGBfLnhvcmAgZXhjZXB0IHRoYXQgaXQgYWNjZXB0cyBgY29tcGFyYXRvcmAgd2hpY2ggaXNcbiAgICAgKiBpbnZva2VkIHRvIGNvbXBhcmUgZWxlbWVudHMgb2YgYGFycmF5c2AuIFRoZSBvcmRlciBvZiByZXN1bHQgdmFsdWVzIGlzXG4gICAgICogZGV0ZXJtaW5lZCBieSB0aGUgb3JkZXIgdGhleSBvY2N1ciBpbiB0aGUgYXJyYXlzLiBUaGUgY29tcGFyYXRvciBpcyBpbnZva2VkXG4gICAgICogd2l0aCB0d28gYXJndW1lbnRzOiAoYXJyVmFsLCBvdGhWYWwpLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMC4wXG4gICAgICogQGNhdGVnb3J5IEFycmF5XG4gICAgICogQHBhcmFtIHsuLi5BcnJheX0gW2FycmF5c10gVGhlIGFycmF5cyB0byBpbnNwZWN0LlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IFtjb21wYXJhdG9yXSBUaGUgY29tcGFyYXRvciBpbnZva2VkIHBlciBlbGVtZW50LlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IGFycmF5IG9mIGZpbHRlcmVkIHZhbHVlcy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIG9iamVjdHMgPSBbeyAneCc6IDEsICd5JzogMiB9LCB7ICd4JzogMiwgJ3knOiAxIH1dO1xuICAgICAqIHZhciBvdGhlcnMgPSBbeyAneCc6IDEsICd5JzogMSB9LCB7ICd4JzogMSwgJ3knOiAyIH1dO1xuICAgICAqXG4gICAgICogXy54b3JXaXRoKG9iamVjdHMsIG90aGVycywgXy5pc0VxdWFsKTtcbiAgICAgKiAvLyA9PiBbeyAneCc6IDIsICd5JzogMSB9LCB7ICd4JzogMSwgJ3knOiAxIH1dXG4gICAgICovXG4gICAgdmFyIHhvcldpdGggPSBiYXNlUmVzdChmdW5jdGlvbihhcnJheXMpIHtcbiAgICAgIHZhciBjb21wYXJhdG9yID0gbGFzdChhcnJheXMpO1xuICAgICAgY29tcGFyYXRvciA9IHR5cGVvZiBjb21wYXJhdG9yID09ICdmdW5jdGlvbicgPyBjb21wYXJhdG9yIDogdW5kZWZpbmVkO1xuICAgICAgcmV0dXJuIGJhc2VYb3IoYXJyYXlGaWx0ZXIoYXJyYXlzLCBpc0FycmF5TGlrZU9iamVjdCksIHVuZGVmaW5lZCwgY29tcGFyYXRvcik7XG4gICAgfSk7XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGFuIGFycmF5IG9mIGdyb3VwZWQgZWxlbWVudHMsIHRoZSBmaXJzdCBvZiB3aGljaCBjb250YWlucyB0aGVcbiAgICAgKiBmaXJzdCBlbGVtZW50cyBvZiB0aGUgZ2l2ZW4gYXJyYXlzLCB0aGUgc2Vjb25kIG9mIHdoaWNoIGNvbnRhaW5zIHRoZVxuICAgICAqIHNlY29uZCBlbGVtZW50cyBvZiB0aGUgZ2l2ZW4gYXJyYXlzLCBhbmQgc28gb24uXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMC4xLjBcbiAgICAgKiBAY2F0ZWdvcnkgQXJyYXlcbiAgICAgKiBAcGFyYW0gey4uLkFycmF5fSBbYXJyYXlzXSBUaGUgYXJyYXlzIHRvIHByb2Nlc3MuXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBuZXcgYXJyYXkgb2YgZ3JvdXBlZCBlbGVtZW50cy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy56aXAoWydhJywgJ2InXSwgWzEsIDJdLCBbdHJ1ZSwgZmFsc2VdKTtcbiAgICAgKiAvLyA9PiBbWydhJywgMSwgdHJ1ZV0sIFsnYicsIDIsIGZhbHNlXV1cbiAgICAgKi9cbiAgICB2YXIgemlwID0gYmFzZVJlc3QodW56aXApO1xuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgaXMgbGlrZSBgXy5mcm9tUGFpcnNgIGV4Y2VwdCB0aGF0IGl0IGFjY2VwdHMgdHdvIGFycmF5cyxcbiAgICAgKiBvbmUgb2YgcHJvcGVydHkgaWRlbnRpZmllcnMgYW5kIG9uZSBvZiBjb3JyZXNwb25kaW5nIHZhbHVlcy5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAwLjQuMFxuICAgICAqIEBjYXRlZ29yeSBBcnJheVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IFtwcm9wcz1bXV0gVGhlIHByb3BlcnR5IGlkZW50aWZpZXJzLlxuICAgICAqIEBwYXJhbSB7QXJyYXl9IFt2YWx1ZXM9W11dIFRoZSBwcm9wZXJ0eSB2YWx1ZXMuXG4gICAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyB0aGUgbmV3IG9iamVjdC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy56aXBPYmplY3QoWydhJywgJ2InXSwgWzEsIDJdKTtcbiAgICAgKiAvLyA9PiB7ICdhJzogMSwgJ2InOiAyIH1cbiAgICAgKi9cbiAgICBmdW5jdGlvbiB6aXBPYmplY3QocHJvcHMsIHZhbHVlcykge1xuICAgICAgcmV0dXJuIGJhc2VaaXBPYmplY3QocHJvcHMgfHwgW10sIHZhbHVlcyB8fCBbXSwgYXNzaWduVmFsdWUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIGlzIGxpa2UgYF8uemlwT2JqZWN0YCBleGNlcHQgdGhhdCBpdCBzdXBwb3J0cyBwcm9wZXJ0eSBwYXRocy5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjEuMFxuICAgICAqIEBjYXRlZ29yeSBBcnJheVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IFtwcm9wcz1bXV0gVGhlIHByb3BlcnR5IGlkZW50aWZpZXJzLlxuICAgICAqIEBwYXJhbSB7QXJyYXl9IFt2YWx1ZXM9W11dIFRoZSBwcm9wZXJ0eSB2YWx1ZXMuXG4gICAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyB0aGUgbmV3IG9iamVjdC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy56aXBPYmplY3REZWVwKFsnYS5iWzBdLmMnLCAnYS5iWzFdLmQnXSwgWzEsIDJdKTtcbiAgICAgKiAvLyA9PiB7ICdhJzogeyAnYic6IFt7ICdjJzogMSB9LCB7ICdkJzogMiB9XSB9IH1cbiAgICAgKi9cbiAgICBmdW5jdGlvbiB6aXBPYmplY3REZWVwKHByb3BzLCB2YWx1ZXMpIHtcbiAgICAgIHJldHVybiBiYXNlWmlwT2JqZWN0KHByb3BzIHx8IFtdLCB2YWx1ZXMgfHwgW10sIGJhc2VTZXQpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIGlzIGxpa2UgYF8uemlwYCBleGNlcHQgdGhhdCBpdCBhY2NlcHRzIGBpdGVyYXRlZWAgdG8gc3BlY2lmeVxuICAgICAqIGhvdyBncm91cGVkIHZhbHVlcyBzaG91bGQgYmUgY29tYmluZWQuIFRoZSBpdGVyYXRlZSBpcyBpbnZva2VkIHdpdGggdGhlXG4gICAgICogZWxlbWVudHMgb2YgZWFjaCBncm91cDogKC4uLmdyb3VwKS5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAzLjguMFxuICAgICAqIEBjYXRlZ29yeSBBcnJheVxuICAgICAqIEBwYXJhbSB7Li4uQXJyYXl9IFthcnJheXNdIFRoZSBhcnJheXMgdG8gcHJvY2Vzcy5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbaXRlcmF0ZWU9Xy5pZGVudGl0eV0gVGhlIGZ1bmN0aW9uIHRvIGNvbWJpbmVcbiAgICAgKiAgZ3JvdXBlZCB2YWx1ZXMuXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBuZXcgYXJyYXkgb2YgZ3JvdXBlZCBlbGVtZW50cy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy56aXBXaXRoKFsxLCAyXSwgWzEwLCAyMF0sIFsxMDAsIDIwMF0sIGZ1bmN0aW9uKGEsIGIsIGMpIHtcbiAgICAgKiAgIHJldHVybiBhICsgYiArIGM7XG4gICAgICogfSk7XG4gICAgICogLy8gPT4gWzExMSwgMjIyXVxuICAgICAqL1xuICAgIHZhciB6aXBXaXRoID0gYmFzZVJlc3QoZnVuY3Rpb24oYXJyYXlzKSB7XG4gICAgICB2YXIgbGVuZ3RoID0gYXJyYXlzLmxlbmd0aCxcbiAgICAgICAgICBpdGVyYXRlZSA9IGxlbmd0aCA+IDEgPyBhcnJheXNbbGVuZ3RoIC0gMV0gOiB1bmRlZmluZWQ7XG5cbiAgICAgIGl0ZXJhdGVlID0gdHlwZW9mIGl0ZXJhdGVlID09ICdmdW5jdGlvbicgPyAoYXJyYXlzLnBvcCgpLCBpdGVyYXRlZSkgOiB1bmRlZmluZWQ7XG4gICAgICByZXR1cm4gdW56aXBXaXRoKGFycmF5cywgaXRlcmF0ZWUpO1xuICAgIH0pO1xuXG4gICAgLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIGBsb2Rhc2hgIHdyYXBwZXIgaW5zdGFuY2UgdGhhdCB3cmFwcyBgdmFsdWVgIHdpdGggZXhwbGljaXQgbWV0aG9kXG4gICAgICogY2hhaW4gc2VxdWVuY2VzIGVuYWJsZWQuIFRoZSByZXN1bHQgb2Ygc3VjaCBzZXF1ZW5jZXMgbXVzdCBiZSB1bndyYXBwZWRcbiAgICAgKiB3aXRoIGBfI3ZhbHVlYC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAxLjMuMFxuICAgICAqIEBjYXRlZ29yeSBTZXFcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byB3cmFwLlxuICAgICAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgdGhlIG5ldyBgbG9kYXNoYCB3cmFwcGVyIGluc3RhbmNlLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgdXNlcnMgPSBbXG4gICAgICogICB7ICd1c2VyJzogJ2Jhcm5leScsICAnYWdlJzogMzYgfSxcbiAgICAgKiAgIHsgJ3VzZXInOiAnZnJlZCcsICAgICdhZ2UnOiA0MCB9LFxuICAgICAqICAgeyAndXNlcic6ICdwZWJibGVzJywgJ2FnZSc6IDEgfVxuICAgICAqIF07XG4gICAgICpcbiAgICAgKiB2YXIgeW91bmdlc3QgPSBfXG4gICAgICogICAuY2hhaW4odXNlcnMpXG4gICAgICogICAuc29ydEJ5KCdhZ2UnKVxuICAgICAqICAgLm1hcChmdW5jdGlvbihvKSB7XG4gICAgICogICAgIHJldHVybiBvLnVzZXIgKyAnIGlzICcgKyBvLmFnZTtcbiAgICAgKiAgIH0pXG4gICAgICogICAuaGVhZCgpXG4gICAgICogICAudmFsdWUoKTtcbiAgICAgKiAvLyA9PiAncGViYmxlcyBpcyAxJ1xuICAgICAqL1xuICAgIGZ1bmN0aW9uIGNoYWluKHZhbHVlKSB7XG4gICAgICB2YXIgcmVzdWx0ID0gbG9kYXNoKHZhbHVlKTtcbiAgICAgIHJlc3VsdC5fX2NoYWluX18gPSB0cnVlO1xuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIG1ldGhvZCBpbnZva2VzIGBpbnRlcmNlcHRvcmAgYW5kIHJldHVybnMgYHZhbHVlYC4gVGhlIGludGVyY2VwdG9yXG4gICAgICogaXMgaW52b2tlZCB3aXRoIG9uZSBhcmd1bWVudDsgKHZhbHVlKS4gVGhlIHB1cnBvc2Ugb2YgdGhpcyBtZXRob2QgaXMgdG9cbiAgICAgKiBcInRhcCBpbnRvXCIgYSBtZXRob2QgY2hhaW4gc2VxdWVuY2UgaW4gb3JkZXIgdG8gbW9kaWZ5IGludGVybWVkaWF0ZSByZXN1bHRzLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDAuMS4wXG4gICAgICogQGNhdGVnb3J5IFNlcVxuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIHByb3ZpZGUgdG8gYGludGVyY2VwdG9yYC5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBpbnRlcmNlcHRvciBUaGUgZnVuY3Rpb24gdG8gaW52b2tlLlxuICAgICAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIGB2YWx1ZWAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8oWzEsIDIsIDNdKVxuICAgICAqICAudGFwKGZ1bmN0aW9uKGFycmF5KSB7XG4gICAgICogICAgLy8gTXV0YXRlIGlucHV0IGFycmF5LlxuICAgICAqICAgIGFycmF5LnBvcCgpO1xuICAgICAqICB9KVxuICAgICAqICAucmV2ZXJzZSgpXG4gICAgICogIC52YWx1ZSgpO1xuICAgICAqIC8vID0+IFsyLCAxXVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIHRhcCh2YWx1ZSwgaW50ZXJjZXB0b3IpIHtcbiAgICAgIGludGVyY2VwdG9yKHZhbHVlKTtcbiAgICAgIHJldHVybiB2YWx1ZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIG1ldGhvZCBpcyBsaWtlIGBfLnRhcGAgZXhjZXB0IHRoYXQgaXQgcmV0dXJucyB0aGUgcmVzdWx0IG9mIGBpbnRlcmNlcHRvcmAuXG4gICAgICogVGhlIHB1cnBvc2Ugb2YgdGhpcyBtZXRob2QgaXMgdG8gXCJwYXNzIHRocnVcIiB2YWx1ZXMgcmVwbGFjaW5nIGludGVybWVkaWF0ZVxuICAgICAqIHJlc3VsdHMgaW4gYSBtZXRob2QgY2hhaW4gc2VxdWVuY2UuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMy4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgU2VxXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gcHJvdmlkZSB0byBgaW50ZXJjZXB0b3JgLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGludGVyY2VwdG9yIFRoZSBmdW5jdGlvbiB0byBpbnZva2UuXG4gICAgICogQHJldHVybnMgeyp9IFJldHVybnMgdGhlIHJlc3VsdCBvZiBgaW50ZXJjZXB0b3JgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfKCcgIGFiYyAgJylcbiAgICAgKiAgLmNoYWluKClcbiAgICAgKiAgLnRyaW0oKVxuICAgICAqICAudGhydShmdW5jdGlvbih2YWx1ZSkge1xuICAgICAqICAgIHJldHVybiBbdmFsdWVdO1xuICAgICAqICB9KVxuICAgICAqICAudmFsdWUoKTtcbiAgICAgKiAvLyA9PiBbJ2FiYyddXG4gICAgICovXG4gICAgZnVuY3Rpb24gdGhydSh2YWx1ZSwgaW50ZXJjZXB0b3IpIHtcbiAgICAgIHJldHVybiBpbnRlcmNlcHRvcih2YWx1ZSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgaXMgdGhlIHdyYXBwZXIgdmVyc2lvbiBvZiBgXy5hdGAuXG4gICAgICpcbiAgICAgKiBAbmFtZSBhdFxuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDEuMC4wXG4gICAgICogQGNhdGVnb3J5IFNlcVxuICAgICAqIEBwYXJhbSB7Li4uKHN0cmluZ3xzdHJpbmdbXSl9IFtwYXRoc10gVGhlIHByb3BlcnR5IHBhdGhzIHRvIHBpY2suXG4gICAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyB0aGUgbmV3IGBsb2Rhc2hgIHdyYXBwZXIgaW5zdGFuY2UuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciBvYmplY3QgPSB7ICdhJzogW3sgJ2InOiB7ICdjJzogMyB9IH0sIDRdIH07XG4gICAgICpcbiAgICAgKiBfKG9iamVjdCkuYXQoWydhWzBdLmIuYycsICdhWzFdJ10pLnZhbHVlKCk7XG4gICAgICogLy8gPT4gWzMsIDRdXG4gICAgICovXG4gICAgdmFyIHdyYXBwZXJBdCA9IGZsYXRSZXN0KGZ1bmN0aW9uKHBhdGhzKSB7XG4gICAgICB2YXIgbGVuZ3RoID0gcGF0aHMubGVuZ3RoLFxuICAgICAgICAgIHN0YXJ0ID0gbGVuZ3RoID8gcGF0aHNbMF0gOiAwLFxuICAgICAgICAgIHZhbHVlID0gdGhpcy5fX3dyYXBwZWRfXyxcbiAgICAgICAgICBpbnRlcmNlcHRvciA9IGZ1bmN0aW9uKG9iamVjdCkgeyByZXR1cm4gYmFzZUF0KG9iamVjdCwgcGF0aHMpOyB9O1xuXG4gICAgICBpZiAobGVuZ3RoID4gMSB8fCB0aGlzLl9fYWN0aW9uc19fLmxlbmd0aCB8fFxuICAgICAgICAgICEodmFsdWUgaW5zdGFuY2VvZiBMYXp5V3JhcHBlcikgfHwgIWlzSW5kZXgoc3RhcnQpKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnRocnUoaW50ZXJjZXB0b3IpO1xuICAgICAgfVxuICAgICAgdmFsdWUgPSB2YWx1ZS5zbGljZShzdGFydCwgK3N0YXJ0ICsgKGxlbmd0aCA/IDEgOiAwKSk7XG4gICAgICB2YWx1ZS5fX2FjdGlvbnNfXy5wdXNoKHtcbiAgICAgICAgJ2Z1bmMnOiB0aHJ1LFxuICAgICAgICAnYXJncyc6IFtpbnRlcmNlcHRvcl0sXG4gICAgICAgICd0aGlzQXJnJzogdW5kZWZpbmVkXG4gICAgICB9KTtcbiAgICAgIHJldHVybiBuZXcgTG9kYXNoV3JhcHBlcih2YWx1ZSwgdGhpcy5fX2NoYWluX18pLnRocnUoZnVuY3Rpb24oYXJyYXkpIHtcbiAgICAgICAgaWYgKGxlbmd0aCAmJiAhYXJyYXkubGVuZ3RoKSB7XG4gICAgICAgICAgYXJyYXkucHVzaCh1bmRlZmluZWQpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBhcnJheTtcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIGBsb2Rhc2hgIHdyYXBwZXIgaW5zdGFuY2Ugd2l0aCBleHBsaWNpdCBtZXRob2QgY2hhaW4gc2VxdWVuY2VzIGVuYWJsZWQuXG4gICAgICpcbiAgICAgKiBAbmFtZSBjaGFpblxuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDAuMS4wXG4gICAgICogQGNhdGVnb3J5IFNlcVxuICAgICAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgdGhlIG5ldyBgbG9kYXNoYCB3cmFwcGVyIGluc3RhbmNlLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgdXNlcnMgPSBbXG4gICAgICogICB7ICd1c2VyJzogJ2Jhcm5leScsICdhZ2UnOiAzNiB9LFxuICAgICAqICAgeyAndXNlcic6ICdmcmVkJywgICAnYWdlJzogNDAgfVxuICAgICAqIF07XG4gICAgICpcbiAgICAgKiAvLyBBIHNlcXVlbmNlIHdpdGhvdXQgZXhwbGljaXQgY2hhaW5pbmcuXG4gICAgICogXyh1c2VycykuaGVhZCgpO1xuICAgICAqIC8vID0+IHsgJ3VzZXInOiAnYmFybmV5JywgJ2FnZSc6IDM2IH1cbiAgICAgKlxuICAgICAqIC8vIEEgc2VxdWVuY2Ugd2l0aCBleHBsaWNpdCBjaGFpbmluZy5cbiAgICAgKiBfKHVzZXJzKVxuICAgICAqICAgLmNoYWluKClcbiAgICAgKiAgIC5oZWFkKClcbiAgICAgKiAgIC5waWNrKCd1c2VyJylcbiAgICAgKiAgIC52YWx1ZSgpO1xuICAgICAqIC8vID0+IHsgJ3VzZXInOiAnYmFybmV5JyB9XG4gICAgICovXG4gICAgZnVuY3Rpb24gd3JhcHBlckNoYWluKCkge1xuICAgICAgcmV0dXJuIGNoYWluKHRoaXMpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEV4ZWN1dGVzIHRoZSBjaGFpbiBzZXF1ZW5jZSBhbmQgcmV0dXJucyB0aGUgd3JhcHBlZCByZXN1bHQuXG4gICAgICpcbiAgICAgKiBAbmFtZSBjb21taXRcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAzLjIuMFxuICAgICAqIEBjYXRlZ29yeSBTZXFcbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIHRoZSBuZXcgYGxvZGFzaGAgd3JhcHBlciBpbnN0YW5jZS5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIGFycmF5ID0gWzEsIDJdO1xuICAgICAqIHZhciB3cmFwcGVkID0gXyhhcnJheSkucHVzaCgzKTtcbiAgICAgKlxuICAgICAqIGNvbnNvbGUubG9nKGFycmF5KTtcbiAgICAgKiAvLyA9PiBbMSwgMl1cbiAgICAgKlxuICAgICAqIHdyYXBwZWQgPSB3cmFwcGVkLmNvbW1pdCgpO1xuICAgICAqIGNvbnNvbGUubG9nKGFycmF5KTtcbiAgICAgKiAvLyA9PiBbMSwgMiwgM11cbiAgICAgKlxuICAgICAqIHdyYXBwZWQubGFzdCgpO1xuICAgICAqIC8vID0+IDNcbiAgICAgKlxuICAgICAqIGNvbnNvbGUubG9nKGFycmF5KTtcbiAgICAgKiAvLyA9PiBbMSwgMiwgM11cbiAgICAgKi9cbiAgICBmdW5jdGlvbiB3cmFwcGVyQ29tbWl0KCkge1xuICAgICAgcmV0dXJuIG5ldyBMb2Rhc2hXcmFwcGVyKHRoaXMudmFsdWUoKSwgdGhpcy5fX2NoYWluX18pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldHMgdGhlIG5leHQgdmFsdWUgb24gYSB3cmFwcGVkIG9iamVjdCBmb2xsb3dpbmcgdGhlXG4gICAgICogW2l0ZXJhdG9yIHByb3RvY29sXShodHRwczovL21kbi5pby9pdGVyYXRpb25fcHJvdG9jb2xzI2l0ZXJhdG9yKS5cbiAgICAgKlxuICAgICAqIEBuYW1lIG5leHRcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjAuMFxuICAgICAqIEBjYXRlZ29yeSBTZXFcbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIHRoZSBuZXh0IGl0ZXJhdG9yIHZhbHVlLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgd3JhcHBlZCA9IF8oWzEsIDJdKTtcbiAgICAgKlxuICAgICAqIHdyYXBwZWQubmV4dCgpO1xuICAgICAqIC8vID0+IHsgJ2RvbmUnOiBmYWxzZSwgJ3ZhbHVlJzogMSB9XG4gICAgICpcbiAgICAgKiB3cmFwcGVkLm5leHQoKTtcbiAgICAgKiAvLyA9PiB7ICdkb25lJzogZmFsc2UsICd2YWx1ZSc6IDIgfVxuICAgICAqXG4gICAgICogd3JhcHBlZC5uZXh0KCk7XG4gICAgICogLy8gPT4geyAnZG9uZSc6IHRydWUsICd2YWx1ZSc6IHVuZGVmaW5lZCB9XG4gICAgICovXG4gICAgZnVuY3Rpb24gd3JhcHBlck5leHQoKSB7XG4gICAgICBpZiAodGhpcy5fX3ZhbHVlc19fID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgdGhpcy5fX3ZhbHVlc19fID0gdG9BcnJheSh0aGlzLnZhbHVlKCkpO1xuICAgICAgfVxuICAgICAgdmFyIGRvbmUgPSB0aGlzLl9faW5kZXhfXyA+PSB0aGlzLl9fdmFsdWVzX18ubGVuZ3RoLFxuICAgICAgICAgIHZhbHVlID0gZG9uZSA/IHVuZGVmaW5lZCA6IHRoaXMuX192YWx1ZXNfX1t0aGlzLl9faW5kZXhfXysrXTtcblxuICAgICAgcmV0dXJuIHsgJ2RvbmUnOiBkb25lLCAndmFsdWUnOiB2YWx1ZSB9O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEVuYWJsZXMgdGhlIHdyYXBwZXIgdG8gYmUgaXRlcmFibGUuXG4gICAgICpcbiAgICAgKiBAbmFtZSBTeW1ib2wuaXRlcmF0b3JcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjAuMFxuICAgICAqIEBjYXRlZ29yeSBTZXFcbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIHRoZSB3cmFwcGVyIG9iamVjdC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIHdyYXBwZWQgPSBfKFsxLCAyXSk7XG4gICAgICpcbiAgICAgKiB3cmFwcGVkW1N5bWJvbC5pdGVyYXRvcl0oKSA9PT0gd3JhcHBlZDtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICpcbiAgICAgKiBBcnJheS5mcm9tKHdyYXBwZWQpO1xuICAgICAqIC8vID0+IFsxLCAyXVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIHdyYXBwZXJUb0l0ZXJhdG9yKCkge1xuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIGNsb25lIG9mIHRoZSBjaGFpbiBzZXF1ZW5jZSBwbGFudGluZyBgdmFsdWVgIGFzIHRoZSB3cmFwcGVkIHZhbHVlLlxuICAgICAqXG4gICAgICogQG5hbWUgcGxhbnRcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAzLjIuMFxuICAgICAqIEBjYXRlZ29yeSBTZXFcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBwbGFudC5cbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIHRoZSBuZXcgYGxvZGFzaGAgd3JhcHBlciBpbnN0YW5jZS5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogZnVuY3Rpb24gc3F1YXJlKG4pIHtcbiAgICAgKiAgIHJldHVybiBuICogbjtcbiAgICAgKiB9XG4gICAgICpcbiAgICAgKiB2YXIgd3JhcHBlZCA9IF8oWzEsIDJdKS5tYXAoc3F1YXJlKTtcbiAgICAgKiB2YXIgb3RoZXIgPSB3cmFwcGVkLnBsYW50KFszLCA0XSk7XG4gICAgICpcbiAgICAgKiBvdGhlci52YWx1ZSgpO1xuICAgICAqIC8vID0+IFs5LCAxNl1cbiAgICAgKlxuICAgICAqIHdyYXBwZWQudmFsdWUoKTtcbiAgICAgKiAvLyA9PiBbMSwgNF1cbiAgICAgKi9cbiAgICBmdW5jdGlvbiB3cmFwcGVyUGxhbnQodmFsdWUpIHtcbiAgICAgIHZhciByZXN1bHQsXG4gICAgICAgICAgcGFyZW50ID0gdGhpcztcblxuICAgICAgd2hpbGUgKHBhcmVudCBpbnN0YW5jZW9mIGJhc2VMb2Rhc2gpIHtcbiAgICAgICAgdmFyIGNsb25lID0gd3JhcHBlckNsb25lKHBhcmVudCk7XG4gICAgICAgIGNsb25lLl9faW5kZXhfXyA9IDA7XG4gICAgICAgIGNsb25lLl9fdmFsdWVzX18gPSB1bmRlZmluZWQ7XG4gICAgICAgIGlmIChyZXN1bHQpIHtcbiAgICAgICAgICBwcmV2aW91cy5fX3dyYXBwZWRfXyA9IGNsb25lO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJlc3VsdCA9IGNsb25lO1xuICAgICAgICB9XG4gICAgICAgIHZhciBwcmV2aW91cyA9IGNsb25lO1xuICAgICAgICBwYXJlbnQgPSBwYXJlbnQuX193cmFwcGVkX187XG4gICAgICB9XG4gICAgICBwcmV2aW91cy5fX3dyYXBwZWRfXyA9IHZhbHVlO1xuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIG1ldGhvZCBpcyB0aGUgd3JhcHBlciB2ZXJzaW9uIG9mIGBfLnJldmVyc2VgLlxuICAgICAqXG4gICAgICogKipOb3RlOioqIFRoaXMgbWV0aG9kIG11dGF0ZXMgdGhlIHdyYXBwZWQgYXJyYXkuXG4gICAgICpcbiAgICAgKiBAbmFtZSByZXZlcnNlXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMC4xLjBcbiAgICAgKiBAY2F0ZWdvcnkgU2VxXG4gICAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyB0aGUgbmV3IGBsb2Rhc2hgIHdyYXBwZXIgaW5zdGFuY2UuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciBhcnJheSA9IFsxLCAyLCAzXTtcbiAgICAgKlxuICAgICAqIF8oYXJyYXkpLnJldmVyc2UoKS52YWx1ZSgpXG4gICAgICogLy8gPT4gWzMsIDIsIDFdXG4gICAgICpcbiAgICAgKiBjb25zb2xlLmxvZyhhcnJheSk7XG4gICAgICogLy8gPT4gWzMsIDIsIDFdXG4gICAgICovXG4gICAgZnVuY3Rpb24gd3JhcHBlclJldmVyc2UoKSB7XG4gICAgICB2YXIgdmFsdWUgPSB0aGlzLl9fd3JhcHBlZF9fO1xuICAgICAgaWYgKHZhbHVlIGluc3RhbmNlb2YgTGF6eVdyYXBwZXIpIHtcbiAgICAgICAgdmFyIHdyYXBwZWQgPSB2YWx1ZTtcbiAgICAgICAgaWYgKHRoaXMuX19hY3Rpb25zX18ubGVuZ3RoKSB7XG4gICAgICAgICAgd3JhcHBlZCA9IG5ldyBMYXp5V3JhcHBlcih0aGlzKTtcbiAgICAgICAgfVxuICAgICAgICB3cmFwcGVkID0gd3JhcHBlZC5yZXZlcnNlKCk7XG4gICAgICAgIHdyYXBwZWQuX19hY3Rpb25zX18ucHVzaCh7XG4gICAgICAgICAgJ2Z1bmMnOiB0aHJ1LFxuICAgICAgICAgICdhcmdzJzogW3JldmVyc2VdLFxuICAgICAgICAgICd0aGlzQXJnJzogdW5kZWZpbmVkXG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gbmV3IExvZGFzaFdyYXBwZXIod3JhcHBlZCwgdGhpcy5fX2NoYWluX18pO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHRoaXMudGhydShyZXZlcnNlKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBFeGVjdXRlcyB0aGUgY2hhaW4gc2VxdWVuY2UgdG8gcmVzb2x2ZSB0aGUgdW53cmFwcGVkIHZhbHVlLlxuICAgICAqXG4gICAgICogQG5hbWUgdmFsdWVcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAwLjEuMFxuICAgICAqIEBhbGlhcyB0b0pTT04sIHZhbHVlT2ZcbiAgICAgKiBAY2F0ZWdvcnkgU2VxXG4gICAgICogQHJldHVybnMgeyp9IFJldHVybnMgdGhlIHJlc29sdmVkIHVud3JhcHBlZCB2YWx1ZS5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXyhbMSwgMiwgM10pLnZhbHVlKCk7XG4gICAgICogLy8gPT4gWzEsIDIsIDNdXG4gICAgICovXG4gICAgZnVuY3Rpb24gd3JhcHBlclZhbHVlKCkge1xuICAgICAgcmV0dXJuIGJhc2VXcmFwcGVyVmFsdWUodGhpcy5fX3dyYXBwZWRfXywgdGhpcy5fX2FjdGlvbnNfXyk7XG4gICAgfVxuXG4gICAgLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhbiBvYmplY3QgY29tcG9zZWQgb2Yga2V5cyBnZW5lcmF0ZWQgZnJvbSB0aGUgcmVzdWx0cyBvZiBydW5uaW5nXG4gICAgICogZWFjaCBlbGVtZW50IG9mIGBjb2xsZWN0aW9uYCB0aHJ1IGBpdGVyYXRlZWAuIFRoZSBjb3JyZXNwb25kaW5nIHZhbHVlIG9mXG4gICAgICogZWFjaCBrZXkgaXMgdGhlIG51bWJlciBvZiB0aW1lcyB0aGUga2V5IHdhcyByZXR1cm5lZCBieSBgaXRlcmF0ZWVgLiBUaGVcbiAgICAgKiBpdGVyYXRlZSBpcyBpbnZva2VkIHdpdGggb25lIGFyZ3VtZW50OiAodmFsdWUpLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDAuNS4wXG4gICAgICogQGNhdGVnb3J5IENvbGxlY3Rpb25cbiAgICAgKiBAcGFyYW0ge0FycmF5fE9iamVjdH0gY29sbGVjdGlvbiBUaGUgY29sbGVjdGlvbiB0byBpdGVyYXRlIG92ZXIuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW2l0ZXJhdGVlPV8uaWRlbnRpdHldIFRoZSBpdGVyYXRlZSB0byB0cmFuc2Zvcm0ga2V5cy5cbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIHRoZSBjb21wb3NlZCBhZ2dyZWdhdGUgb2JqZWN0LlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLmNvdW50QnkoWzYuMSwgNC4yLCA2LjNdLCBNYXRoLmZsb29yKTtcbiAgICAgKiAvLyA9PiB7ICc0JzogMSwgJzYnOiAyIH1cbiAgICAgKlxuICAgICAqIC8vIFRoZSBgXy5wcm9wZXJ0eWAgaXRlcmF0ZWUgc2hvcnRoYW5kLlxuICAgICAqIF8uY291bnRCeShbJ29uZScsICd0d28nLCAndGhyZWUnXSwgJ2xlbmd0aCcpO1xuICAgICAqIC8vID0+IHsgJzMnOiAyLCAnNSc6IDEgfVxuICAgICAqL1xuICAgIHZhciBjb3VudEJ5ID0gY3JlYXRlQWdncmVnYXRvcihmdW5jdGlvbihyZXN1bHQsIHZhbHVlLCBrZXkpIHtcbiAgICAgIGlmIChoYXNPd25Qcm9wZXJ0eS5jYWxsKHJlc3VsdCwga2V5KSkge1xuICAgICAgICArK3Jlc3VsdFtrZXldO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgYmFzZUFzc2lnblZhbHVlKHJlc3VsdCwga2V5LCAxKTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIC8qKlxuICAgICAqIENoZWNrcyBpZiBgcHJlZGljYXRlYCByZXR1cm5zIHRydXRoeSBmb3IgKiphbGwqKiBlbGVtZW50cyBvZiBgY29sbGVjdGlvbmAuXG4gICAgICogSXRlcmF0aW9uIGlzIHN0b3BwZWQgb25jZSBgcHJlZGljYXRlYCByZXR1cm5zIGZhbHNleS4gVGhlIHByZWRpY2F0ZSBpc1xuICAgICAqIGludm9rZWQgd2l0aCB0aHJlZSBhcmd1bWVudHM6ICh2YWx1ZSwgaW5kZXh8a2V5LCBjb2xsZWN0aW9uKS5cbiAgICAgKlxuICAgICAqICoqTm90ZToqKiBUaGlzIG1ldGhvZCByZXR1cm5zIGB0cnVlYCBmb3JcbiAgICAgKiBbZW1wdHkgY29sbGVjdGlvbnNdKGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL0VtcHR5X3NldCkgYmVjYXVzZVxuICAgICAqIFtldmVyeXRoaW5nIGlzIHRydWVdKGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL1ZhY3VvdXNfdHJ1dGgpIG9mXG4gICAgICogZWxlbWVudHMgb2YgZW1wdHkgY29sbGVjdGlvbnMuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMC4xLjBcbiAgICAgKiBAY2F0ZWdvcnkgQ29sbGVjdGlvblxuICAgICAqIEBwYXJhbSB7QXJyYXl8T2JqZWN0fSBjb2xsZWN0aW9uIFRoZSBjb2xsZWN0aW9uIHRvIGl0ZXJhdGUgb3Zlci5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbcHJlZGljYXRlPV8uaWRlbnRpdHldIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uXG4gICAgICogQHBhcmFtLSB7T2JqZWN0fSBbZ3VhcmRdIEVuYWJsZXMgdXNlIGFzIGFuIGl0ZXJhdGVlIGZvciBtZXRob2RzIGxpa2UgYF8ubWFwYC5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYWxsIGVsZW1lbnRzIHBhc3MgdGhlIHByZWRpY2F0ZSBjaGVjayxcbiAgICAgKiAgZWxzZSBgZmFsc2VgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLmV2ZXJ5KFt0cnVlLCAxLCBudWxsLCAneWVzJ10sIEJvb2xlYW4pO1xuICAgICAqIC8vID0+IGZhbHNlXG4gICAgICpcbiAgICAgKiB2YXIgdXNlcnMgPSBbXG4gICAgICogICB7ICd1c2VyJzogJ2Jhcm5leScsICdhZ2UnOiAzNiwgJ2FjdGl2ZSc6IGZhbHNlIH0sXG4gICAgICogICB7ICd1c2VyJzogJ2ZyZWQnLCAgICdhZ2UnOiA0MCwgJ2FjdGl2ZSc6IGZhbHNlIH1cbiAgICAgKiBdO1xuICAgICAqXG4gICAgICogLy8gVGhlIGBfLm1hdGNoZXNgIGl0ZXJhdGVlIHNob3J0aGFuZC5cbiAgICAgKiBfLmV2ZXJ5KHVzZXJzLCB7ICd1c2VyJzogJ2Jhcm5leScsICdhY3RpdmUnOiBmYWxzZSB9KTtcbiAgICAgKiAvLyA9PiBmYWxzZVxuICAgICAqXG4gICAgICogLy8gVGhlIGBfLm1hdGNoZXNQcm9wZXJ0eWAgaXRlcmF0ZWUgc2hvcnRoYW5kLlxuICAgICAqIF8uZXZlcnkodXNlcnMsIFsnYWN0aXZlJywgZmFsc2VdKTtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICpcbiAgICAgKiAvLyBUaGUgYF8ucHJvcGVydHlgIGl0ZXJhdGVlIHNob3J0aGFuZC5cbiAgICAgKiBfLmV2ZXJ5KHVzZXJzLCAnYWN0aXZlJyk7XG4gICAgICogLy8gPT4gZmFsc2VcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBldmVyeShjb2xsZWN0aW9uLCBwcmVkaWNhdGUsIGd1YXJkKSB7XG4gICAgICB2YXIgZnVuYyA9IGlzQXJyYXkoY29sbGVjdGlvbikgPyBhcnJheUV2ZXJ5IDogYmFzZUV2ZXJ5O1xuICAgICAgaWYgKGd1YXJkICYmIGlzSXRlcmF0ZWVDYWxsKGNvbGxlY3Rpb24sIHByZWRpY2F0ZSwgZ3VhcmQpKSB7XG4gICAgICAgIHByZWRpY2F0ZSA9IHVuZGVmaW5lZDtcbiAgICAgIH1cbiAgICAgIHJldHVybiBmdW5jKGNvbGxlY3Rpb24sIGdldEl0ZXJhdGVlKHByZWRpY2F0ZSwgMykpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEl0ZXJhdGVzIG92ZXIgZWxlbWVudHMgb2YgYGNvbGxlY3Rpb25gLCByZXR1cm5pbmcgYW4gYXJyYXkgb2YgYWxsIGVsZW1lbnRzXG4gICAgICogYHByZWRpY2F0ZWAgcmV0dXJucyB0cnV0aHkgZm9yLiBUaGUgcHJlZGljYXRlIGlzIGludm9rZWQgd2l0aCB0aHJlZVxuICAgICAqIGFyZ3VtZW50czogKHZhbHVlLCBpbmRleHxrZXksIGNvbGxlY3Rpb24pLlxuICAgICAqXG4gICAgICogKipOb3RlOioqIFVubGlrZSBgXy5yZW1vdmVgLCB0aGlzIG1ldGhvZCByZXR1cm5zIGEgbmV3IGFycmF5LlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDAuMS4wXG4gICAgICogQGNhdGVnb3J5IENvbGxlY3Rpb25cbiAgICAgKiBAcGFyYW0ge0FycmF5fE9iamVjdH0gY29sbGVjdGlvbiBUaGUgY29sbGVjdGlvbiB0byBpdGVyYXRlIG92ZXIuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW3ByZWRpY2F0ZT1fLmlkZW50aXR5XSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IGZpbHRlcmVkIGFycmF5LlxuICAgICAqIEBzZWUgXy5yZWplY3RcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIHVzZXJzID0gW1xuICAgICAqICAgeyAndXNlcic6ICdiYXJuZXknLCAnYWdlJzogMzYsICdhY3RpdmUnOiB0cnVlIH0sXG4gICAgICogICB7ICd1c2VyJzogJ2ZyZWQnLCAgICdhZ2UnOiA0MCwgJ2FjdGl2ZSc6IGZhbHNlIH1cbiAgICAgKiBdO1xuICAgICAqXG4gICAgICogXy5maWx0ZXIodXNlcnMsIGZ1bmN0aW9uKG8pIHsgcmV0dXJuICFvLmFjdGl2ZTsgfSk7XG4gICAgICogLy8gPT4gb2JqZWN0cyBmb3IgWydmcmVkJ11cbiAgICAgKlxuICAgICAqIC8vIFRoZSBgXy5tYXRjaGVzYCBpdGVyYXRlZSBzaG9ydGhhbmQuXG4gICAgICogXy5maWx0ZXIodXNlcnMsIHsgJ2FnZSc6IDM2LCAnYWN0aXZlJzogdHJ1ZSB9KTtcbiAgICAgKiAvLyA9PiBvYmplY3RzIGZvciBbJ2Jhcm5leSddXG4gICAgICpcbiAgICAgKiAvLyBUaGUgYF8ubWF0Y2hlc1Byb3BlcnR5YCBpdGVyYXRlZSBzaG9ydGhhbmQuXG4gICAgICogXy5maWx0ZXIodXNlcnMsIFsnYWN0aXZlJywgZmFsc2VdKTtcbiAgICAgKiAvLyA9PiBvYmplY3RzIGZvciBbJ2ZyZWQnXVxuICAgICAqXG4gICAgICogLy8gVGhlIGBfLnByb3BlcnR5YCBpdGVyYXRlZSBzaG9ydGhhbmQuXG4gICAgICogXy5maWx0ZXIodXNlcnMsICdhY3RpdmUnKTtcbiAgICAgKiAvLyA9PiBvYmplY3RzIGZvciBbJ2Jhcm5leSddXG4gICAgICpcbiAgICAgKiAvLyBDb21iaW5pbmcgc2V2ZXJhbCBwcmVkaWNhdGVzIHVzaW5nIGBfLm92ZXJFdmVyeWAgb3IgYF8ub3ZlclNvbWVgLlxuICAgICAqIF8uZmlsdGVyKHVzZXJzLCBfLm92ZXJTb21lKFt7ICdhZ2UnOiAzNiB9LCBbJ2FnZScsIDQwXV0pKTtcbiAgICAgKiAvLyA9PiBvYmplY3RzIGZvciBbJ2ZyZWQnLCAnYmFybmV5J11cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBmaWx0ZXIoY29sbGVjdGlvbiwgcHJlZGljYXRlKSB7XG4gICAgICB2YXIgZnVuYyA9IGlzQXJyYXkoY29sbGVjdGlvbikgPyBhcnJheUZpbHRlciA6IGJhc2VGaWx0ZXI7XG4gICAgICByZXR1cm4gZnVuYyhjb2xsZWN0aW9uLCBnZXRJdGVyYXRlZShwcmVkaWNhdGUsIDMpKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBJdGVyYXRlcyBvdmVyIGVsZW1lbnRzIG9mIGBjb2xsZWN0aW9uYCwgcmV0dXJuaW5nIHRoZSBmaXJzdCBlbGVtZW50XG4gICAgICogYHByZWRpY2F0ZWAgcmV0dXJucyB0cnV0aHkgZm9yLiBUaGUgcHJlZGljYXRlIGlzIGludm9rZWQgd2l0aCB0aHJlZVxuICAgICAqIGFyZ3VtZW50czogKHZhbHVlLCBpbmRleHxrZXksIGNvbGxlY3Rpb24pLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDAuMS4wXG4gICAgICogQGNhdGVnb3J5IENvbGxlY3Rpb25cbiAgICAgKiBAcGFyYW0ge0FycmF5fE9iamVjdH0gY29sbGVjdGlvbiBUaGUgY29sbGVjdGlvbiB0byBpbnNwZWN0LlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IFtwcmVkaWNhdGU9Xy5pZGVudGl0eV0gVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIGl0ZXJhdGlvbi5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW2Zyb21JbmRleD0wXSBUaGUgaW5kZXggdG8gc2VhcmNoIGZyb20uXG4gICAgICogQHJldHVybnMgeyp9IFJldHVybnMgdGhlIG1hdGNoZWQgZWxlbWVudCwgZWxzZSBgdW5kZWZpbmVkYC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIHVzZXJzID0gW1xuICAgICAqICAgeyAndXNlcic6ICdiYXJuZXknLCAgJ2FnZSc6IDM2LCAnYWN0aXZlJzogdHJ1ZSB9LFxuICAgICAqICAgeyAndXNlcic6ICdmcmVkJywgICAgJ2FnZSc6IDQwLCAnYWN0aXZlJzogZmFsc2UgfSxcbiAgICAgKiAgIHsgJ3VzZXInOiAncGViYmxlcycsICdhZ2UnOiAxLCAgJ2FjdGl2ZSc6IHRydWUgfVxuICAgICAqIF07XG4gICAgICpcbiAgICAgKiBfLmZpbmQodXNlcnMsIGZ1bmN0aW9uKG8pIHsgcmV0dXJuIG8uYWdlIDwgNDA7IH0pO1xuICAgICAqIC8vID0+IG9iamVjdCBmb3IgJ2Jhcm5leSdcbiAgICAgKlxuICAgICAqIC8vIFRoZSBgXy5tYXRjaGVzYCBpdGVyYXRlZSBzaG9ydGhhbmQuXG4gICAgICogXy5maW5kKHVzZXJzLCB7ICdhZ2UnOiAxLCAnYWN0aXZlJzogdHJ1ZSB9KTtcbiAgICAgKiAvLyA9PiBvYmplY3QgZm9yICdwZWJibGVzJ1xuICAgICAqXG4gICAgICogLy8gVGhlIGBfLm1hdGNoZXNQcm9wZXJ0eWAgaXRlcmF0ZWUgc2hvcnRoYW5kLlxuICAgICAqIF8uZmluZCh1c2VycywgWydhY3RpdmUnLCBmYWxzZV0pO1xuICAgICAqIC8vID0+IG9iamVjdCBmb3IgJ2ZyZWQnXG4gICAgICpcbiAgICAgKiAvLyBUaGUgYF8ucHJvcGVydHlgIGl0ZXJhdGVlIHNob3J0aGFuZC5cbiAgICAgKiBfLmZpbmQodXNlcnMsICdhY3RpdmUnKTtcbiAgICAgKiAvLyA9PiBvYmplY3QgZm9yICdiYXJuZXknXG4gICAgICovXG4gICAgdmFyIGZpbmQgPSBjcmVhdGVGaW5kKGZpbmRJbmRleCk7XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIG1ldGhvZCBpcyBsaWtlIGBfLmZpbmRgIGV4Y2VwdCB0aGF0IGl0IGl0ZXJhdGVzIG92ZXIgZWxlbWVudHMgb2ZcbiAgICAgKiBgY29sbGVjdGlvbmAgZnJvbSByaWdodCB0byBsZWZ0LlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDIuMC4wXG4gICAgICogQGNhdGVnb3J5IENvbGxlY3Rpb25cbiAgICAgKiBAcGFyYW0ge0FycmF5fE9iamVjdH0gY29sbGVjdGlvbiBUaGUgY29sbGVjdGlvbiB0byBpbnNwZWN0LlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IFtwcmVkaWNhdGU9Xy5pZGVudGl0eV0gVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIGl0ZXJhdGlvbi5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW2Zyb21JbmRleD1jb2xsZWN0aW9uLmxlbmd0aC0xXSBUaGUgaW5kZXggdG8gc2VhcmNoIGZyb20uXG4gICAgICogQHJldHVybnMgeyp9IFJldHVybnMgdGhlIG1hdGNoZWQgZWxlbWVudCwgZWxzZSBgdW5kZWZpbmVkYC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5maW5kTGFzdChbMSwgMiwgMywgNF0sIGZ1bmN0aW9uKG4pIHtcbiAgICAgKiAgIHJldHVybiBuICUgMiA9PSAxO1xuICAgICAqIH0pO1xuICAgICAqIC8vID0+IDNcbiAgICAgKi9cbiAgICB2YXIgZmluZExhc3QgPSBjcmVhdGVGaW5kKGZpbmRMYXN0SW5kZXgpO1xuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIGZsYXR0ZW5lZCBhcnJheSBvZiB2YWx1ZXMgYnkgcnVubmluZyBlYWNoIGVsZW1lbnQgaW4gYGNvbGxlY3Rpb25gXG4gICAgICogdGhydSBgaXRlcmF0ZWVgIGFuZCBmbGF0dGVuaW5nIHRoZSBtYXBwZWQgcmVzdWx0cy4gVGhlIGl0ZXJhdGVlIGlzIGludm9rZWRcbiAgICAgKiB3aXRoIHRocmVlIGFyZ3VtZW50czogKHZhbHVlLCBpbmRleHxrZXksIGNvbGxlY3Rpb24pLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMC4wXG4gICAgICogQGNhdGVnb3J5IENvbGxlY3Rpb25cbiAgICAgKiBAcGFyYW0ge0FycmF5fE9iamVjdH0gY29sbGVjdGlvbiBUaGUgY29sbGVjdGlvbiB0byBpdGVyYXRlIG92ZXIuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW2l0ZXJhdGVlPV8uaWRlbnRpdHldIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBuZXcgZmxhdHRlbmVkIGFycmF5LlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBmdW5jdGlvbiBkdXBsaWNhdGUobikge1xuICAgICAqICAgcmV0dXJuIFtuLCBuXTtcbiAgICAgKiB9XG4gICAgICpcbiAgICAgKiBfLmZsYXRNYXAoWzEsIDJdLCBkdXBsaWNhdGUpO1xuICAgICAqIC8vID0+IFsxLCAxLCAyLCAyXVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGZsYXRNYXAoY29sbGVjdGlvbiwgaXRlcmF0ZWUpIHtcbiAgICAgIHJldHVybiBiYXNlRmxhdHRlbihtYXAoY29sbGVjdGlvbiwgaXRlcmF0ZWUpLCAxKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIG1ldGhvZCBpcyBsaWtlIGBfLmZsYXRNYXBgIGV4Y2VwdCB0aGF0IGl0IHJlY3Vyc2l2ZWx5IGZsYXR0ZW5zIHRoZVxuICAgICAqIG1hcHBlZCByZXN1bHRzLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuNy4wXG4gICAgICogQGNhdGVnb3J5IENvbGxlY3Rpb25cbiAgICAgKiBAcGFyYW0ge0FycmF5fE9iamVjdH0gY29sbGVjdGlvbiBUaGUgY29sbGVjdGlvbiB0byBpdGVyYXRlIG92ZXIuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW2l0ZXJhdGVlPV8uaWRlbnRpdHldIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBuZXcgZmxhdHRlbmVkIGFycmF5LlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBmdW5jdGlvbiBkdXBsaWNhdGUobikge1xuICAgICAqICAgcmV0dXJuIFtbW24sIG5dXV07XG4gICAgICogfVxuICAgICAqXG4gICAgICogXy5mbGF0TWFwRGVlcChbMSwgMl0sIGR1cGxpY2F0ZSk7XG4gICAgICogLy8gPT4gWzEsIDEsIDIsIDJdXG4gICAgICovXG4gICAgZnVuY3Rpb24gZmxhdE1hcERlZXAoY29sbGVjdGlvbiwgaXRlcmF0ZWUpIHtcbiAgICAgIHJldHVybiBiYXNlRmxhdHRlbihtYXAoY29sbGVjdGlvbiwgaXRlcmF0ZWUpLCBJTkZJTklUWSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgaXMgbGlrZSBgXy5mbGF0TWFwYCBleGNlcHQgdGhhdCBpdCByZWN1cnNpdmVseSBmbGF0dGVucyB0aGVcbiAgICAgKiBtYXBwZWQgcmVzdWx0cyB1cCB0byBgZGVwdGhgIHRpbWVzLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuNy4wXG4gICAgICogQGNhdGVnb3J5IENvbGxlY3Rpb25cbiAgICAgKiBAcGFyYW0ge0FycmF5fE9iamVjdH0gY29sbGVjdGlvbiBUaGUgY29sbGVjdGlvbiB0byBpdGVyYXRlIG92ZXIuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW2l0ZXJhdGVlPV8uaWRlbnRpdHldIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtkZXB0aD0xXSBUaGUgbWF4aW11bSByZWN1cnNpb24gZGVwdGguXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBuZXcgZmxhdHRlbmVkIGFycmF5LlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBmdW5jdGlvbiBkdXBsaWNhdGUobikge1xuICAgICAqICAgcmV0dXJuIFtbW24sIG5dXV07XG4gICAgICogfVxuICAgICAqXG4gICAgICogXy5mbGF0TWFwRGVwdGgoWzEsIDJdLCBkdXBsaWNhdGUsIDIpO1xuICAgICAqIC8vID0+IFtbMSwgMV0sIFsyLCAyXV1cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBmbGF0TWFwRGVwdGgoY29sbGVjdGlvbiwgaXRlcmF0ZWUsIGRlcHRoKSB7XG4gICAgICBkZXB0aCA9IGRlcHRoID09PSB1bmRlZmluZWQgPyAxIDogdG9JbnRlZ2VyKGRlcHRoKTtcbiAgICAgIHJldHVybiBiYXNlRmxhdHRlbihtYXAoY29sbGVjdGlvbiwgaXRlcmF0ZWUpLCBkZXB0aCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogSXRlcmF0ZXMgb3ZlciBlbGVtZW50cyBvZiBgY29sbGVjdGlvbmAgYW5kIGludm9rZXMgYGl0ZXJhdGVlYCBmb3IgZWFjaCBlbGVtZW50LlxuICAgICAqIFRoZSBpdGVyYXRlZSBpcyBpbnZva2VkIHdpdGggdGhyZWUgYXJndW1lbnRzOiAodmFsdWUsIGluZGV4fGtleSwgY29sbGVjdGlvbikuXG4gICAgICogSXRlcmF0ZWUgZnVuY3Rpb25zIG1heSBleGl0IGl0ZXJhdGlvbiBlYXJseSBieSBleHBsaWNpdGx5IHJldHVybmluZyBgZmFsc2VgLlxuICAgICAqXG4gICAgICogKipOb3RlOioqIEFzIHdpdGggb3RoZXIgXCJDb2xsZWN0aW9uc1wiIG1ldGhvZHMsIG9iamVjdHMgd2l0aCBhIFwibGVuZ3RoXCJcbiAgICAgKiBwcm9wZXJ0eSBhcmUgaXRlcmF0ZWQgbGlrZSBhcnJheXMuIFRvIGF2b2lkIHRoaXMgYmVoYXZpb3IgdXNlIGBfLmZvckluYFxuICAgICAqIG9yIGBfLmZvck93bmAgZm9yIG9iamVjdCBpdGVyYXRpb24uXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMC4xLjBcbiAgICAgKiBAYWxpYXMgZWFjaFxuICAgICAqIEBjYXRlZ29yeSBDb2xsZWN0aW9uXG4gICAgICogQHBhcmFtIHtBcnJheXxPYmplY3R9IGNvbGxlY3Rpb24gVGhlIGNvbGxlY3Rpb24gdG8gaXRlcmF0ZSBvdmVyLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IFtpdGVyYXRlZT1fLmlkZW50aXR5XSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICAgICAqIEByZXR1cm5zIHtBcnJheXxPYmplY3R9IFJldHVybnMgYGNvbGxlY3Rpb25gLlxuICAgICAqIEBzZWUgXy5mb3JFYWNoUmlnaHRcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5mb3JFYWNoKFsxLCAyXSwgZnVuY3Rpb24odmFsdWUpIHtcbiAgICAgKiAgIGNvbnNvbGUubG9nKHZhbHVlKTtcbiAgICAgKiB9KTtcbiAgICAgKiAvLyA9PiBMb2dzIGAxYCB0aGVuIGAyYC5cbiAgICAgKlxuICAgICAqIF8uZm9yRWFjaCh7ICdhJzogMSwgJ2InOiAyIH0sIGZ1bmN0aW9uKHZhbHVlLCBrZXkpIHtcbiAgICAgKiAgIGNvbnNvbGUubG9nKGtleSk7XG4gICAgICogfSk7XG4gICAgICogLy8gPT4gTG9ncyAnYScgdGhlbiAnYicgKGl0ZXJhdGlvbiBvcmRlciBpcyBub3QgZ3VhcmFudGVlZCkuXG4gICAgICovXG4gICAgZnVuY3Rpb24gZm9yRWFjaChjb2xsZWN0aW9uLCBpdGVyYXRlZSkge1xuICAgICAgdmFyIGZ1bmMgPSBpc0FycmF5KGNvbGxlY3Rpb24pID8gYXJyYXlFYWNoIDogYmFzZUVhY2g7XG4gICAgICByZXR1cm4gZnVuYyhjb2xsZWN0aW9uLCBnZXRJdGVyYXRlZShpdGVyYXRlZSwgMykpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIGlzIGxpa2UgYF8uZm9yRWFjaGAgZXhjZXB0IHRoYXQgaXQgaXRlcmF0ZXMgb3ZlciBlbGVtZW50cyBvZlxuICAgICAqIGBjb2xsZWN0aW9uYCBmcm9tIHJpZ2h0IHRvIGxlZnQuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMi4wLjBcbiAgICAgKiBAYWxpYXMgZWFjaFJpZ2h0XG4gICAgICogQGNhdGVnb3J5IENvbGxlY3Rpb25cbiAgICAgKiBAcGFyYW0ge0FycmF5fE9iamVjdH0gY29sbGVjdGlvbiBUaGUgY29sbGVjdGlvbiB0byBpdGVyYXRlIG92ZXIuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW2l0ZXJhdGVlPV8uaWRlbnRpdHldIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uXG4gICAgICogQHJldHVybnMge0FycmF5fE9iamVjdH0gUmV0dXJucyBgY29sbGVjdGlvbmAuXG4gICAgICogQHNlZSBfLmZvckVhY2hcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5mb3JFYWNoUmlnaHQoWzEsIDJdLCBmdW5jdGlvbih2YWx1ZSkge1xuICAgICAqICAgY29uc29sZS5sb2codmFsdWUpO1xuICAgICAqIH0pO1xuICAgICAqIC8vID0+IExvZ3MgYDJgIHRoZW4gYDFgLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGZvckVhY2hSaWdodChjb2xsZWN0aW9uLCBpdGVyYXRlZSkge1xuICAgICAgdmFyIGZ1bmMgPSBpc0FycmF5KGNvbGxlY3Rpb24pID8gYXJyYXlFYWNoUmlnaHQgOiBiYXNlRWFjaFJpZ2h0O1xuICAgICAgcmV0dXJuIGZ1bmMoY29sbGVjdGlvbiwgZ2V0SXRlcmF0ZWUoaXRlcmF0ZWUsIDMpKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGFuIG9iamVjdCBjb21wb3NlZCBvZiBrZXlzIGdlbmVyYXRlZCBmcm9tIHRoZSByZXN1bHRzIG9mIHJ1bm5pbmdcbiAgICAgKiBlYWNoIGVsZW1lbnQgb2YgYGNvbGxlY3Rpb25gIHRocnUgYGl0ZXJhdGVlYC4gVGhlIG9yZGVyIG9mIGdyb3VwZWQgdmFsdWVzXG4gICAgICogaXMgZGV0ZXJtaW5lZCBieSB0aGUgb3JkZXIgdGhleSBvY2N1ciBpbiBgY29sbGVjdGlvbmAuIFRoZSBjb3JyZXNwb25kaW5nXG4gICAgICogdmFsdWUgb2YgZWFjaCBrZXkgaXMgYW4gYXJyYXkgb2YgZWxlbWVudHMgcmVzcG9uc2libGUgZm9yIGdlbmVyYXRpbmcgdGhlXG4gICAgICoga2V5LiBUaGUgaXRlcmF0ZWUgaXMgaW52b2tlZCB3aXRoIG9uZSBhcmd1bWVudDogKHZhbHVlKS5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAwLjEuMFxuICAgICAqIEBjYXRlZ29yeSBDb2xsZWN0aW9uXG4gICAgICogQHBhcmFtIHtBcnJheXxPYmplY3R9IGNvbGxlY3Rpb24gVGhlIGNvbGxlY3Rpb24gdG8gaXRlcmF0ZSBvdmVyLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IFtpdGVyYXRlZT1fLmlkZW50aXR5XSBUaGUgaXRlcmF0ZWUgdG8gdHJhbnNmb3JtIGtleXMuXG4gICAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyB0aGUgY29tcG9zZWQgYWdncmVnYXRlIG9iamVjdC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5ncm91cEJ5KFs2LjEsIDQuMiwgNi4zXSwgTWF0aC5mbG9vcik7XG4gICAgICogLy8gPT4geyAnNCc6IFs0LjJdLCAnNic6IFs2LjEsIDYuM10gfVxuICAgICAqXG4gICAgICogLy8gVGhlIGBfLnByb3BlcnR5YCBpdGVyYXRlZSBzaG9ydGhhbmQuXG4gICAgICogXy5ncm91cEJ5KFsnb25lJywgJ3R3bycsICd0aHJlZSddLCAnbGVuZ3RoJyk7XG4gICAgICogLy8gPT4geyAnMyc6IFsnb25lJywgJ3R3byddLCAnNSc6IFsndGhyZWUnXSB9XG4gICAgICovXG4gICAgdmFyIGdyb3VwQnkgPSBjcmVhdGVBZ2dyZWdhdG9yKGZ1bmN0aW9uKHJlc3VsdCwgdmFsdWUsIGtleSkge1xuICAgICAgaWYgKGhhc093blByb3BlcnR5LmNhbGwocmVzdWx0LCBrZXkpKSB7XG4gICAgICAgIHJlc3VsdFtrZXldLnB1c2godmFsdWUpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgYmFzZUFzc2lnblZhbHVlKHJlc3VsdCwga2V5LCBbdmFsdWVdKTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIC8qKlxuICAgICAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIGluIGBjb2xsZWN0aW9uYC4gSWYgYGNvbGxlY3Rpb25gIGlzIGEgc3RyaW5nLCBpdCdzXG4gICAgICogY2hlY2tlZCBmb3IgYSBzdWJzdHJpbmcgb2YgYHZhbHVlYCwgb3RoZXJ3aXNlXG4gICAgICogW2BTYW1lVmFsdWVaZXJvYF0oaHR0cDovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNy4wLyNzZWMtc2FtZXZhbHVlemVybylcbiAgICAgKiBpcyB1c2VkIGZvciBlcXVhbGl0eSBjb21wYXJpc29ucy4gSWYgYGZyb21JbmRleGAgaXMgbmVnYXRpdmUsIGl0J3MgdXNlZCBhc1xuICAgICAqIHRoZSBvZmZzZXQgZnJvbSB0aGUgZW5kIG9mIGBjb2xsZWN0aW9uYC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAwLjEuMFxuICAgICAqIEBjYXRlZ29yeSBDb2xsZWN0aW9uXG4gICAgICogQHBhcmFtIHtBcnJheXxPYmplY3R8c3RyaW5nfSBjb2xsZWN0aW9uIFRoZSBjb2xsZWN0aW9uIHRvIGluc3BlY3QuXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gc2VhcmNoIGZvci5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW2Zyb21JbmRleD0wXSBUaGUgaW5kZXggdG8gc2VhcmNoIGZyb20uXG4gICAgICogQHBhcmFtLSB7T2JqZWN0fSBbZ3VhcmRdIEVuYWJsZXMgdXNlIGFzIGFuIGl0ZXJhdGVlIGZvciBtZXRob2RzIGxpa2UgYF8ucmVkdWNlYC5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBmb3VuZCwgZWxzZSBgZmFsc2VgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLmluY2x1ZGVzKFsxLCAyLCAzXSwgMSk7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqXG4gICAgICogXy5pbmNsdWRlcyhbMSwgMiwgM10sIDEsIDIpO1xuICAgICAqIC8vID0+IGZhbHNlXG4gICAgICpcbiAgICAgKiBfLmluY2x1ZGVzKHsgJ2EnOiAxLCAnYic6IDIgfSwgMSk7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqXG4gICAgICogXy5pbmNsdWRlcygnYWJjZCcsICdiYycpO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBpbmNsdWRlcyhjb2xsZWN0aW9uLCB2YWx1ZSwgZnJvbUluZGV4LCBndWFyZCkge1xuICAgICAgY29sbGVjdGlvbiA9IGlzQXJyYXlMaWtlKGNvbGxlY3Rpb24pID8gY29sbGVjdGlvbiA6IHZhbHVlcyhjb2xsZWN0aW9uKTtcbiAgICAgIGZyb21JbmRleCA9IChmcm9tSW5kZXggJiYgIWd1YXJkKSA/IHRvSW50ZWdlcihmcm9tSW5kZXgpIDogMDtcblxuICAgICAgdmFyIGxlbmd0aCA9IGNvbGxlY3Rpb24ubGVuZ3RoO1xuICAgICAgaWYgKGZyb21JbmRleCA8IDApIHtcbiAgICAgICAgZnJvbUluZGV4ID0gbmF0aXZlTWF4KGxlbmd0aCArIGZyb21JbmRleCwgMCk7XG4gICAgICB9XG4gICAgICByZXR1cm4gaXNTdHJpbmcoY29sbGVjdGlvbilcbiAgICAgICAgPyAoZnJvbUluZGV4IDw9IGxlbmd0aCAmJiBjb2xsZWN0aW9uLmluZGV4T2YodmFsdWUsIGZyb21JbmRleCkgPiAtMSlcbiAgICAgICAgOiAoISFsZW5ndGggJiYgYmFzZUluZGV4T2YoY29sbGVjdGlvbiwgdmFsdWUsIGZyb21JbmRleCkgPiAtMSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogSW52b2tlcyB0aGUgbWV0aG9kIGF0IGBwYXRoYCBvZiBlYWNoIGVsZW1lbnQgaW4gYGNvbGxlY3Rpb25gLCByZXR1cm5pbmdcbiAgICAgKiBhbiBhcnJheSBvZiB0aGUgcmVzdWx0cyBvZiBlYWNoIGludm9rZWQgbWV0aG9kLiBBbnkgYWRkaXRpb25hbCBhcmd1bWVudHNcbiAgICAgKiBhcmUgcHJvdmlkZWQgdG8gZWFjaCBpbnZva2VkIG1ldGhvZC4gSWYgYHBhdGhgIGlzIGEgZnVuY3Rpb24sIGl0J3MgaW52b2tlZFxuICAgICAqIGZvciwgYW5kIGB0aGlzYCBib3VuZCB0bywgZWFjaCBlbGVtZW50IGluIGBjb2xsZWN0aW9uYC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjAuMFxuICAgICAqIEBjYXRlZ29yeSBDb2xsZWN0aW9uXG4gICAgICogQHBhcmFtIHtBcnJheXxPYmplY3R9IGNvbGxlY3Rpb24gVGhlIGNvbGxlY3Rpb24gdG8gaXRlcmF0ZSBvdmVyLlxuICAgICAqIEBwYXJhbSB7QXJyYXl8RnVuY3Rpb258c3RyaW5nfSBwYXRoIFRoZSBwYXRoIG9mIHRoZSBtZXRob2QgdG8gaW52b2tlIG9yXG4gICAgICogIHRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uXG4gICAgICogQHBhcmFtIHsuLi4qfSBbYXJnc10gVGhlIGFyZ3VtZW50cyB0byBpbnZva2UgZWFjaCBtZXRob2Qgd2l0aC5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIGFycmF5IG9mIHJlc3VsdHMuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uaW52b2tlTWFwKFtbNSwgMSwgN10sIFszLCAyLCAxXV0sICdzb3J0Jyk7XG4gICAgICogLy8gPT4gW1sxLCA1LCA3XSwgWzEsIDIsIDNdXVxuICAgICAqXG4gICAgICogXy5pbnZva2VNYXAoWzEyMywgNDU2XSwgU3RyaW5nLnByb3RvdHlwZS5zcGxpdCwgJycpO1xuICAgICAqIC8vID0+IFtbJzEnLCAnMicsICczJ10sIFsnNCcsICc1JywgJzYnXV1cbiAgICAgKi9cbiAgICB2YXIgaW52b2tlTWFwID0gYmFzZVJlc3QoZnVuY3Rpb24oY29sbGVjdGlvbiwgcGF0aCwgYXJncykge1xuICAgICAgdmFyIGluZGV4ID0gLTEsXG4gICAgICAgICAgaXNGdW5jID0gdHlwZW9mIHBhdGggPT0gJ2Z1bmN0aW9uJyxcbiAgICAgICAgICByZXN1bHQgPSBpc0FycmF5TGlrZShjb2xsZWN0aW9uKSA/IEFycmF5KGNvbGxlY3Rpb24ubGVuZ3RoKSA6IFtdO1xuXG4gICAgICBiYXNlRWFjaChjb2xsZWN0aW9uLCBmdW5jdGlvbih2YWx1ZSkge1xuICAgICAgICByZXN1bHRbKytpbmRleF0gPSBpc0Z1bmMgPyBhcHBseShwYXRoLCB2YWx1ZSwgYXJncykgOiBiYXNlSW52b2tlKHZhbHVlLCBwYXRoLCBhcmdzKTtcbiAgICAgIH0pO1xuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9KTtcblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYW4gb2JqZWN0IGNvbXBvc2VkIG9mIGtleXMgZ2VuZXJhdGVkIGZyb20gdGhlIHJlc3VsdHMgb2YgcnVubmluZ1xuICAgICAqIGVhY2ggZWxlbWVudCBvZiBgY29sbGVjdGlvbmAgdGhydSBgaXRlcmF0ZWVgLiBUaGUgY29ycmVzcG9uZGluZyB2YWx1ZSBvZlxuICAgICAqIGVhY2gga2V5IGlzIHRoZSBsYXN0IGVsZW1lbnQgcmVzcG9uc2libGUgZm9yIGdlbmVyYXRpbmcgdGhlIGtleS4gVGhlXG4gICAgICogaXRlcmF0ZWUgaXMgaW52b2tlZCB3aXRoIG9uZSBhcmd1bWVudDogKHZhbHVlKS5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjAuMFxuICAgICAqIEBjYXRlZ29yeSBDb2xsZWN0aW9uXG4gICAgICogQHBhcmFtIHtBcnJheXxPYmplY3R9IGNvbGxlY3Rpb24gVGhlIGNvbGxlY3Rpb24gdG8gaXRlcmF0ZSBvdmVyLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IFtpdGVyYXRlZT1fLmlkZW50aXR5XSBUaGUgaXRlcmF0ZWUgdG8gdHJhbnNmb3JtIGtleXMuXG4gICAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyB0aGUgY29tcG9zZWQgYWdncmVnYXRlIG9iamVjdC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIGFycmF5ID0gW1xuICAgICAqICAgeyAnZGlyJzogJ2xlZnQnLCAnY29kZSc6IDk3IH0sXG4gICAgICogICB7ICdkaXInOiAncmlnaHQnLCAnY29kZSc6IDEwMCB9XG4gICAgICogXTtcbiAgICAgKlxuICAgICAqIF8ua2V5QnkoYXJyYXksIGZ1bmN0aW9uKG8pIHtcbiAgICAgKiAgIHJldHVybiBTdHJpbmcuZnJvbUNoYXJDb2RlKG8uY29kZSk7XG4gICAgICogfSk7XG4gICAgICogLy8gPT4geyAnYSc6IHsgJ2Rpcic6ICdsZWZ0JywgJ2NvZGUnOiA5NyB9LCAnZCc6IHsgJ2Rpcic6ICdyaWdodCcsICdjb2RlJzogMTAwIH0gfVxuICAgICAqXG4gICAgICogXy5rZXlCeShhcnJheSwgJ2RpcicpO1xuICAgICAqIC8vID0+IHsgJ2xlZnQnOiB7ICdkaXInOiAnbGVmdCcsICdjb2RlJzogOTcgfSwgJ3JpZ2h0JzogeyAnZGlyJzogJ3JpZ2h0JywgJ2NvZGUnOiAxMDAgfSB9XG4gICAgICovXG4gICAgdmFyIGtleUJ5ID0gY3JlYXRlQWdncmVnYXRvcihmdW5jdGlvbihyZXN1bHQsIHZhbHVlLCBrZXkpIHtcbiAgICAgIGJhc2VBc3NpZ25WYWx1ZShyZXN1bHQsIGtleSwgdmFsdWUpO1xuICAgIH0pO1xuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhbiBhcnJheSBvZiB2YWx1ZXMgYnkgcnVubmluZyBlYWNoIGVsZW1lbnQgaW4gYGNvbGxlY3Rpb25gIHRocnVcbiAgICAgKiBgaXRlcmF0ZWVgLiBUaGUgaXRlcmF0ZWUgaXMgaW52b2tlZCB3aXRoIHRocmVlIGFyZ3VtZW50czpcbiAgICAgKiAodmFsdWUsIGluZGV4fGtleSwgY29sbGVjdGlvbikuXG4gICAgICpcbiAgICAgKiBNYW55IGxvZGFzaCBtZXRob2RzIGFyZSBndWFyZGVkIHRvIHdvcmsgYXMgaXRlcmF0ZWVzIGZvciBtZXRob2RzIGxpa2VcbiAgICAgKiBgXy5ldmVyeWAsIGBfLmZpbHRlcmAsIGBfLm1hcGAsIGBfLm1hcFZhbHVlc2AsIGBfLnJlamVjdGAsIGFuZCBgXy5zb21lYC5cbiAgICAgKlxuICAgICAqIFRoZSBndWFyZGVkIG1ldGhvZHMgYXJlOlxuICAgICAqIGBhcnlgLCBgY2h1bmtgLCBgY3VycnlgLCBgY3VycnlSaWdodGAsIGBkcm9wYCwgYGRyb3BSaWdodGAsIGBldmVyeWAsXG4gICAgICogYGZpbGxgLCBgaW52ZXJ0YCwgYHBhcnNlSW50YCwgYHJhbmRvbWAsIGByYW5nZWAsIGByYW5nZVJpZ2h0YCwgYHJlcGVhdGAsXG4gICAgICogYHNhbXBsZVNpemVgLCBgc2xpY2VgLCBgc29tZWAsIGBzb3J0QnlgLCBgc3BsaXRgLCBgdGFrZWAsIGB0YWtlUmlnaHRgLFxuICAgICAqIGB0ZW1wbGF0ZWAsIGB0cmltYCwgYHRyaW1FbmRgLCBgdHJpbVN0YXJ0YCwgYW5kIGB3b3Jkc2BcbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAwLjEuMFxuICAgICAqIEBjYXRlZ29yeSBDb2xsZWN0aW9uXG4gICAgICogQHBhcmFtIHtBcnJheXxPYmplY3R9IGNvbGxlY3Rpb24gVGhlIGNvbGxlY3Rpb24gdG8gaXRlcmF0ZSBvdmVyLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IFtpdGVyYXRlZT1fLmlkZW50aXR5XSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IG1hcHBlZCBhcnJheS5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogZnVuY3Rpb24gc3F1YXJlKG4pIHtcbiAgICAgKiAgIHJldHVybiBuICogbjtcbiAgICAgKiB9XG4gICAgICpcbiAgICAgKiBfLm1hcChbNCwgOF0sIHNxdWFyZSk7XG4gICAgICogLy8gPT4gWzE2LCA2NF1cbiAgICAgKlxuICAgICAqIF8ubWFwKHsgJ2EnOiA0LCAnYic6IDggfSwgc3F1YXJlKTtcbiAgICAgKiAvLyA9PiBbMTYsIDY0XSAoaXRlcmF0aW9uIG9yZGVyIGlzIG5vdCBndWFyYW50ZWVkKVxuICAgICAqXG4gICAgICogdmFyIHVzZXJzID0gW1xuICAgICAqICAgeyAndXNlcic6ICdiYXJuZXknIH0sXG4gICAgICogICB7ICd1c2VyJzogJ2ZyZWQnIH1cbiAgICAgKiBdO1xuICAgICAqXG4gICAgICogLy8gVGhlIGBfLnByb3BlcnR5YCBpdGVyYXRlZSBzaG9ydGhhbmQuXG4gICAgICogXy5tYXAodXNlcnMsICd1c2VyJyk7XG4gICAgICogLy8gPT4gWydiYXJuZXknLCAnZnJlZCddXG4gICAgICovXG4gICAgZnVuY3Rpb24gbWFwKGNvbGxlY3Rpb24sIGl0ZXJhdGVlKSB7XG4gICAgICB2YXIgZnVuYyA9IGlzQXJyYXkoY29sbGVjdGlvbikgPyBhcnJheU1hcCA6IGJhc2VNYXA7XG4gICAgICByZXR1cm4gZnVuYyhjb2xsZWN0aW9uLCBnZXRJdGVyYXRlZShpdGVyYXRlZSwgMykpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIGlzIGxpa2UgYF8uc29ydEJ5YCBleGNlcHQgdGhhdCBpdCBhbGxvd3Mgc3BlY2lmeWluZyB0aGUgc29ydFxuICAgICAqIG9yZGVycyBvZiB0aGUgaXRlcmF0ZWVzIHRvIHNvcnQgYnkuIElmIGBvcmRlcnNgIGlzIHVuc3BlY2lmaWVkLCBhbGwgdmFsdWVzXG4gICAgICogYXJlIHNvcnRlZCBpbiBhc2NlbmRpbmcgb3JkZXIuIE90aGVyd2lzZSwgc3BlY2lmeSBhbiBvcmRlciBvZiBcImRlc2NcIiBmb3JcbiAgICAgKiBkZXNjZW5kaW5nIG9yIFwiYXNjXCIgZm9yIGFzY2VuZGluZyBzb3J0IG9yZGVyIG9mIGNvcnJlc3BvbmRpbmcgdmFsdWVzLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMC4wXG4gICAgICogQGNhdGVnb3J5IENvbGxlY3Rpb25cbiAgICAgKiBAcGFyYW0ge0FycmF5fE9iamVjdH0gY29sbGVjdGlvbiBUaGUgY29sbGVjdGlvbiB0byBpdGVyYXRlIG92ZXIuXG4gICAgICogQHBhcmFtIHtBcnJheVtdfEZ1bmN0aW9uW118T2JqZWN0W118c3RyaW5nW119IFtpdGVyYXRlZXM9W18uaWRlbnRpdHldXVxuICAgICAqICBUaGUgaXRlcmF0ZWVzIHRvIHNvcnQgYnkuXG4gICAgICogQHBhcmFtIHtzdHJpbmdbXX0gW29yZGVyc10gVGhlIHNvcnQgb3JkZXJzIG9mIGBpdGVyYXRlZXNgLlxuICAgICAqIEBwYXJhbS0ge09iamVjdH0gW2d1YXJkXSBFbmFibGVzIHVzZSBhcyBhbiBpdGVyYXRlZSBmb3IgbWV0aG9kcyBsaWtlIGBfLnJlZHVjZWAuXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBuZXcgc29ydGVkIGFycmF5LlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgdXNlcnMgPSBbXG4gICAgICogICB7ICd1c2VyJzogJ2ZyZWQnLCAgICdhZ2UnOiA0OCB9LFxuICAgICAqICAgeyAndXNlcic6ICdiYXJuZXknLCAnYWdlJzogMzQgfSxcbiAgICAgKiAgIHsgJ3VzZXInOiAnZnJlZCcsICAgJ2FnZSc6IDQwIH0sXG4gICAgICogICB7ICd1c2VyJzogJ2Jhcm5leScsICdhZ2UnOiAzNiB9XG4gICAgICogXTtcbiAgICAgKlxuICAgICAqIC8vIFNvcnQgYnkgYHVzZXJgIGluIGFzY2VuZGluZyBvcmRlciBhbmQgYnkgYGFnZWAgaW4gZGVzY2VuZGluZyBvcmRlci5cbiAgICAgKiBfLm9yZGVyQnkodXNlcnMsIFsndXNlcicsICdhZ2UnXSwgWydhc2MnLCAnZGVzYyddKTtcbiAgICAgKiAvLyA9PiBvYmplY3RzIGZvciBbWydiYXJuZXknLCAzNl0sIFsnYmFybmV5JywgMzRdLCBbJ2ZyZWQnLCA0OF0sIFsnZnJlZCcsIDQwXV1cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBvcmRlckJ5KGNvbGxlY3Rpb24sIGl0ZXJhdGVlcywgb3JkZXJzLCBndWFyZCkge1xuICAgICAgaWYgKGNvbGxlY3Rpb24gPT0gbnVsbCkge1xuICAgICAgICByZXR1cm4gW107XG4gICAgICB9XG4gICAgICBpZiAoIWlzQXJyYXkoaXRlcmF0ZWVzKSkge1xuICAgICAgICBpdGVyYXRlZXMgPSBpdGVyYXRlZXMgPT0gbnVsbCA/IFtdIDogW2l0ZXJhdGVlc107XG4gICAgICB9XG4gICAgICBvcmRlcnMgPSBndWFyZCA/IHVuZGVmaW5lZCA6IG9yZGVycztcbiAgICAgIGlmICghaXNBcnJheShvcmRlcnMpKSB7XG4gICAgICAgIG9yZGVycyA9IG9yZGVycyA9PSBudWxsID8gW10gOiBbb3JkZXJzXTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBiYXNlT3JkZXJCeShjb2xsZWN0aW9uLCBpdGVyYXRlZXMsIG9yZGVycyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhbiBhcnJheSBvZiBlbGVtZW50cyBzcGxpdCBpbnRvIHR3byBncm91cHMsIHRoZSBmaXJzdCBvZiB3aGljaFxuICAgICAqIGNvbnRhaW5zIGVsZW1lbnRzIGBwcmVkaWNhdGVgIHJldHVybnMgdHJ1dGh5IGZvciwgdGhlIHNlY29uZCBvZiB3aGljaFxuICAgICAqIGNvbnRhaW5zIGVsZW1lbnRzIGBwcmVkaWNhdGVgIHJldHVybnMgZmFsc2V5IGZvci4gVGhlIHByZWRpY2F0ZSBpc1xuICAgICAqIGludm9rZWQgd2l0aCBvbmUgYXJndW1lbnQ6ICh2YWx1ZSkuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMy4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgQ29sbGVjdGlvblxuICAgICAqIEBwYXJhbSB7QXJyYXl8T2JqZWN0fSBjb2xsZWN0aW9uIFRoZSBjb2xsZWN0aW9uIHRvIGl0ZXJhdGUgb3Zlci5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbcHJlZGljYXRlPV8uaWRlbnRpdHldIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBhcnJheSBvZiBncm91cGVkIGVsZW1lbnRzLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgdXNlcnMgPSBbXG4gICAgICogICB7ICd1c2VyJzogJ2Jhcm5leScsICAnYWdlJzogMzYsICdhY3RpdmUnOiBmYWxzZSB9LFxuICAgICAqICAgeyAndXNlcic6ICdmcmVkJywgICAgJ2FnZSc6IDQwLCAnYWN0aXZlJzogdHJ1ZSB9LFxuICAgICAqICAgeyAndXNlcic6ICdwZWJibGVzJywgJ2FnZSc6IDEsICAnYWN0aXZlJzogZmFsc2UgfVxuICAgICAqIF07XG4gICAgICpcbiAgICAgKiBfLnBhcnRpdGlvbih1c2VycywgZnVuY3Rpb24obykgeyByZXR1cm4gby5hY3RpdmU7IH0pO1xuICAgICAqIC8vID0+IG9iamVjdHMgZm9yIFtbJ2ZyZWQnXSwgWydiYXJuZXknLCAncGViYmxlcyddXVxuICAgICAqXG4gICAgICogLy8gVGhlIGBfLm1hdGNoZXNgIGl0ZXJhdGVlIHNob3J0aGFuZC5cbiAgICAgKiBfLnBhcnRpdGlvbih1c2VycywgeyAnYWdlJzogMSwgJ2FjdGl2ZSc6IGZhbHNlIH0pO1xuICAgICAqIC8vID0+IG9iamVjdHMgZm9yIFtbJ3BlYmJsZXMnXSwgWydiYXJuZXknLCAnZnJlZCddXVxuICAgICAqXG4gICAgICogLy8gVGhlIGBfLm1hdGNoZXNQcm9wZXJ0eWAgaXRlcmF0ZWUgc2hvcnRoYW5kLlxuICAgICAqIF8ucGFydGl0aW9uKHVzZXJzLCBbJ2FjdGl2ZScsIGZhbHNlXSk7XG4gICAgICogLy8gPT4gb2JqZWN0cyBmb3IgW1snYmFybmV5JywgJ3BlYmJsZXMnXSwgWydmcmVkJ11dXG4gICAgICpcbiAgICAgKiAvLyBUaGUgYF8ucHJvcGVydHlgIGl0ZXJhdGVlIHNob3J0aGFuZC5cbiAgICAgKiBfLnBhcnRpdGlvbih1c2VycywgJ2FjdGl2ZScpO1xuICAgICAqIC8vID0+IG9iamVjdHMgZm9yIFtbJ2ZyZWQnXSwgWydiYXJuZXknLCAncGViYmxlcyddXVxuICAgICAqL1xuICAgIHZhciBwYXJ0aXRpb24gPSBjcmVhdGVBZ2dyZWdhdG9yKGZ1bmN0aW9uKHJlc3VsdCwgdmFsdWUsIGtleSkge1xuICAgICAgcmVzdWx0W2tleSA/IDAgOiAxXS5wdXNoKHZhbHVlKTtcbiAgICB9LCBmdW5jdGlvbigpIHsgcmV0dXJuIFtbXSwgW11dOyB9KTtcblxuICAgIC8qKlxuICAgICAqIFJlZHVjZXMgYGNvbGxlY3Rpb25gIHRvIGEgdmFsdWUgd2hpY2ggaXMgdGhlIGFjY3VtdWxhdGVkIHJlc3VsdCBvZiBydW5uaW5nXG4gICAgICogZWFjaCBlbGVtZW50IGluIGBjb2xsZWN0aW9uYCB0aHJ1IGBpdGVyYXRlZWAsIHdoZXJlIGVhY2ggc3VjY2Vzc2l2ZVxuICAgICAqIGludm9jYXRpb24gaXMgc3VwcGxpZWQgdGhlIHJldHVybiB2YWx1ZSBvZiB0aGUgcHJldmlvdXMuIElmIGBhY2N1bXVsYXRvcmBcbiAgICAgKiBpcyBub3QgZ2l2ZW4sIHRoZSBmaXJzdCBlbGVtZW50IG9mIGBjb2xsZWN0aW9uYCBpcyB1c2VkIGFzIHRoZSBpbml0aWFsXG4gICAgICogdmFsdWUuIFRoZSBpdGVyYXRlZSBpcyBpbnZva2VkIHdpdGggZm91ciBhcmd1bWVudHM6XG4gICAgICogKGFjY3VtdWxhdG9yLCB2YWx1ZSwgaW5kZXh8a2V5LCBjb2xsZWN0aW9uKS5cbiAgICAgKlxuICAgICAqIE1hbnkgbG9kYXNoIG1ldGhvZHMgYXJlIGd1YXJkZWQgdG8gd29yayBhcyBpdGVyYXRlZXMgZm9yIG1ldGhvZHMgbGlrZVxuICAgICAqIGBfLnJlZHVjZWAsIGBfLnJlZHVjZVJpZ2h0YCwgYW5kIGBfLnRyYW5zZm9ybWAuXG4gICAgICpcbiAgICAgKiBUaGUgZ3VhcmRlZCBtZXRob2RzIGFyZTpcbiAgICAgKiBgYXNzaWduYCwgYGRlZmF1bHRzYCwgYGRlZmF1bHRzRGVlcGAsIGBpbmNsdWRlc2AsIGBtZXJnZWAsIGBvcmRlckJ5YCxcbiAgICAgKiBhbmQgYHNvcnRCeWBcbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAwLjEuMFxuICAgICAqIEBjYXRlZ29yeSBDb2xsZWN0aW9uXG4gICAgICogQHBhcmFtIHtBcnJheXxPYmplY3R9IGNvbGxlY3Rpb24gVGhlIGNvbGxlY3Rpb24gdG8gaXRlcmF0ZSBvdmVyLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IFtpdGVyYXRlZT1fLmlkZW50aXR5XSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICAgICAqIEBwYXJhbSB7Kn0gW2FjY3VtdWxhdG9yXSBUaGUgaW5pdGlhbCB2YWx1ZS5cbiAgICAgKiBAcmV0dXJucyB7Kn0gUmV0dXJucyB0aGUgYWNjdW11bGF0ZWQgdmFsdWUuXG4gICAgICogQHNlZSBfLnJlZHVjZVJpZ2h0XG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8ucmVkdWNlKFsxLCAyXSwgZnVuY3Rpb24oc3VtLCBuKSB7XG4gICAgICogICByZXR1cm4gc3VtICsgbjtcbiAgICAgKiB9LCAwKTtcbiAgICAgKiAvLyA9PiAzXG4gICAgICpcbiAgICAgKiBfLnJlZHVjZSh7ICdhJzogMSwgJ2InOiAyLCAnYyc6IDEgfSwgZnVuY3Rpb24ocmVzdWx0LCB2YWx1ZSwga2V5KSB7XG4gICAgICogICAocmVzdWx0W3ZhbHVlXSB8fCAocmVzdWx0W3ZhbHVlXSA9IFtdKSkucHVzaChrZXkpO1xuICAgICAqICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgKiB9LCB7fSk7XG4gICAgICogLy8gPT4geyAnMSc6IFsnYScsICdjJ10sICcyJzogWydiJ10gfSAoaXRlcmF0aW9uIG9yZGVyIGlzIG5vdCBndWFyYW50ZWVkKVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIHJlZHVjZShjb2xsZWN0aW9uLCBpdGVyYXRlZSwgYWNjdW11bGF0b3IpIHtcbiAgICAgIHZhciBmdW5jID0gaXNBcnJheShjb2xsZWN0aW9uKSA/IGFycmF5UmVkdWNlIDogYmFzZVJlZHVjZSxcbiAgICAgICAgICBpbml0QWNjdW0gPSBhcmd1bWVudHMubGVuZ3RoIDwgMztcblxuICAgICAgcmV0dXJuIGZ1bmMoY29sbGVjdGlvbiwgZ2V0SXRlcmF0ZWUoaXRlcmF0ZWUsIDQpLCBhY2N1bXVsYXRvciwgaW5pdEFjY3VtLCBiYXNlRWFjaCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgaXMgbGlrZSBgXy5yZWR1Y2VgIGV4Y2VwdCB0aGF0IGl0IGl0ZXJhdGVzIG92ZXIgZWxlbWVudHMgb2ZcbiAgICAgKiBgY29sbGVjdGlvbmAgZnJvbSByaWdodCB0byBsZWZ0LlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDAuMS4wXG4gICAgICogQGNhdGVnb3J5IENvbGxlY3Rpb25cbiAgICAgKiBAcGFyYW0ge0FycmF5fE9iamVjdH0gY29sbGVjdGlvbiBUaGUgY29sbGVjdGlvbiB0byBpdGVyYXRlIG92ZXIuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW2l0ZXJhdGVlPV8uaWRlbnRpdHldIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uXG4gICAgICogQHBhcmFtIHsqfSBbYWNjdW11bGF0b3JdIFRoZSBpbml0aWFsIHZhbHVlLlxuICAgICAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSBhY2N1bXVsYXRlZCB2YWx1ZS5cbiAgICAgKiBAc2VlIF8ucmVkdWNlXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciBhcnJheSA9IFtbMCwgMV0sIFsyLCAzXSwgWzQsIDVdXTtcbiAgICAgKlxuICAgICAqIF8ucmVkdWNlUmlnaHQoYXJyYXksIGZ1bmN0aW9uKGZsYXR0ZW5lZCwgb3RoZXIpIHtcbiAgICAgKiAgIHJldHVybiBmbGF0dGVuZWQuY29uY2F0KG90aGVyKTtcbiAgICAgKiB9LCBbXSk7XG4gICAgICogLy8gPT4gWzQsIDUsIDIsIDMsIDAsIDFdXG4gICAgICovXG4gICAgZnVuY3Rpb24gcmVkdWNlUmlnaHQoY29sbGVjdGlvbiwgaXRlcmF0ZWUsIGFjY3VtdWxhdG9yKSB7XG4gICAgICB2YXIgZnVuYyA9IGlzQXJyYXkoY29sbGVjdGlvbikgPyBhcnJheVJlZHVjZVJpZ2h0IDogYmFzZVJlZHVjZSxcbiAgICAgICAgICBpbml0QWNjdW0gPSBhcmd1bWVudHMubGVuZ3RoIDwgMztcblxuICAgICAgcmV0dXJuIGZ1bmMoY29sbGVjdGlvbiwgZ2V0SXRlcmF0ZWUoaXRlcmF0ZWUsIDQpLCBhY2N1bXVsYXRvciwgaW5pdEFjY3VtLCBiYXNlRWFjaFJpZ2h0KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgb3Bwb3NpdGUgb2YgYF8uZmlsdGVyYDsgdGhpcyBtZXRob2QgcmV0dXJucyB0aGUgZWxlbWVudHMgb2YgYGNvbGxlY3Rpb25gXG4gICAgICogdGhhdCBgcHJlZGljYXRlYCBkb2VzICoqbm90KiogcmV0dXJuIHRydXRoeSBmb3IuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMC4xLjBcbiAgICAgKiBAY2F0ZWdvcnkgQ29sbGVjdGlvblxuICAgICAqIEBwYXJhbSB7QXJyYXl8T2JqZWN0fSBjb2xsZWN0aW9uIFRoZSBjb2xsZWN0aW9uIHRvIGl0ZXJhdGUgb3Zlci5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbcHJlZGljYXRlPV8uaWRlbnRpdHldIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBuZXcgZmlsdGVyZWQgYXJyYXkuXG4gICAgICogQHNlZSBfLmZpbHRlclxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgdXNlcnMgPSBbXG4gICAgICogICB7ICd1c2VyJzogJ2Jhcm5leScsICdhZ2UnOiAzNiwgJ2FjdGl2ZSc6IGZhbHNlIH0sXG4gICAgICogICB7ICd1c2VyJzogJ2ZyZWQnLCAgICdhZ2UnOiA0MCwgJ2FjdGl2ZSc6IHRydWUgfVxuICAgICAqIF07XG4gICAgICpcbiAgICAgKiBfLnJlamVjdCh1c2VycywgZnVuY3Rpb24obykgeyByZXR1cm4gIW8uYWN0aXZlOyB9KTtcbiAgICAgKiAvLyA9PiBvYmplY3RzIGZvciBbJ2ZyZWQnXVxuICAgICAqXG4gICAgICogLy8gVGhlIGBfLm1hdGNoZXNgIGl0ZXJhdGVlIHNob3J0aGFuZC5cbiAgICAgKiBfLnJlamVjdCh1c2VycywgeyAnYWdlJzogNDAsICdhY3RpdmUnOiB0cnVlIH0pO1xuICAgICAqIC8vID0+IG9iamVjdHMgZm9yIFsnYmFybmV5J11cbiAgICAgKlxuICAgICAqIC8vIFRoZSBgXy5tYXRjaGVzUHJvcGVydHlgIGl0ZXJhdGVlIHNob3J0aGFuZC5cbiAgICAgKiBfLnJlamVjdCh1c2VycywgWydhY3RpdmUnLCBmYWxzZV0pO1xuICAgICAqIC8vID0+IG9iamVjdHMgZm9yIFsnZnJlZCddXG4gICAgICpcbiAgICAgKiAvLyBUaGUgYF8ucHJvcGVydHlgIGl0ZXJhdGVlIHNob3J0aGFuZC5cbiAgICAgKiBfLnJlamVjdCh1c2VycywgJ2FjdGl2ZScpO1xuICAgICAqIC8vID0+IG9iamVjdHMgZm9yIFsnYmFybmV5J11cbiAgICAgKi9cbiAgICBmdW5jdGlvbiByZWplY3QoY29sbGVjdGlvbiwgcHJlZGljYXRlKSB7XG4gICAgICB2YXIgZnVuYyA9IGlzQXJyYXkoY29sbGVjdGlvbikgPyBhcnJheUZpbHRlciA6IGJhc2VGaWx0ZXI7XG4gICAgICByZXR1cm4gZnVuYyhjb2xsZWN0aW9uLCBuZWdhdGUoZ2V0SXRlcmF0ZWUocHJlZGljYXRlLCAzKSkpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldHMgYSByYW5kb20gZWxlbWVudCBmcm9tIGBjb2xsZWN0aW9uYC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAyLjAuMFxuICAgICAqIEBjYXRlZ29yeSBDb2xsZWN0aW9uXG4gICAgICogQHBhcmFtIHtBcnJheXxPYmplY3R9IGNvbGxlY3Rpb24gVGhlIGNvbGxlY3Rpb24gdG8gc2FtcGxlLlxuICAgICAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSByYW5kb20gZWxlbWVudC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5zYW1wbGUoWzEsIDIsIDMsIDRdKTtcbiAgICAgKiAvLyA9PiAyXG4gICAgICovXG4gICAgZnVuY3Rpb24gc2FtcGxlKGNvbGxlY3Rpb24pIHtcbiAgICAgIHZhciBmdW5jID0gaXNBcnJheShjb2xsZWN0aW9uKSA/IGFycmF5U2FtcGxlIDogYmFzZVNhbXBsZTtcbiAgICAgIHJldHVybiBmdW5jKGNvbGxlY3Rpb24pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldHMgYG5gIHJhbmRvbSBlbGVtZW50cyBhdCB1bmlxdWUga2V5cyBmcm9tIGBjb2xsZWN0aW9uYCB1cCB0byB0aGVcbiAgICAgKiBzaXplIG9mIGBjb2xsZWN0aW9uYC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjAuMFxuICAgICAqIEBjYXRlZ29yeSBDb2xsZWN0aW9uXG4gICAgICogQHBhcmFtIHtBcnJheXxPYmplY3R9IGNvbGxlY3Rpb24gVGhlIGNvbGxlY3Rpb24gdG8gc2FtcGxlLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbbj0xXSBUaGUgbnVtYmVyIG9mIGVsZW1lbnRzIHRvIHNhbXBsZS5cbiAgICAgKiBAcGFyYW0tIHtPYmplY3R9IFtndWFyZF0gRW5hYmxlcyB1c2UgYXMgYW4gaXRlcmF0ZWUgZm9yIG1ldGhvZHMgbGlrZSBgXy5tYXBgLlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgcmFuZG9tIGVsZW1lbnRzLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLnNhbXBsZVNpemUoWzEsIDIsIDNdLCAyKTtcbiAgICAgKiAvLyA9PiBbMywgMV1cbiAgICAgKlxuICAgICAqIF8uc2FtcGxlU2l6ZShbMSwgMiwgM10sIDQpO1xuICAgICAqIC8vID0+IFsyLCAzLCAxXVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIHNhbXBsZVNpemUoY29sbGVjdGlvbiwgbiwgZ3VhcmQpIHtcbiAgICAgIGlmICgoZ3VhcmQgPyBpc0l0ZXJhdGVlQ2FsbChjb2xsZWN0aW9uLCBuLCBndWFyZCkgOiBuID09PSB1bmRlZmluZWQpKSB7XG4gICAgICAgIG4gPSAxO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgbiA9IHRvSW50ZWdlcihuKTtcbiAgICAgIH1cbiAgICAgIHZhciBmdW5jID0gaXNBcnJheShjb2xsZWN0aW9uKSA/IGFycmF5U2FtcGxlU2l6ZSA6IGJhc2VTYW1wbGVTaXplO1xuICAgICAgcmV0dXJuIGZ1bmMoY29sbGVjdGlvbiwgbik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhbiBhcnJheSBvZiBzaHVmZmxlZCB2YWx1ZXMsIHVzaW5nIGEgdmVyc2lvbiBvZiB0aGVcbiAgICAgKiBbRmlzaGVyLVlhdGVzIHNodWZmbGVdKGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL0Zpc2hlci1ZYXRlc19zaHVmZmxlKS5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAwLjEuMFxuICAgICAqIEBjYXRlZ29yeSBDb2xsZWN0aW9uXG4gICAgICogQHBhcmFtIHtBcnJheXxPYmplY3R9IGNvbGxlY3Rpb24gVGhlIGNvbGxlY3Rpb24gdG8gc2h1ZmZsZS5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIG5ldyBzaHVmZmxlZCBhcnJheS5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5zaHVmZmxlKFsxLCAyLCAzLCA0XSk7XG4gICAgICogLy8gPT4gWzQsIDEsIDMsIDJdXG4gICAgICovXG4gICAgZnVuY3Rpb24gc2h1ZmZsZShjb2xsZWN0aW9uKSB7XG4gICAgICB2YXIgZnVuYyA9IGlzQXJyYXkoY29sbGVjdGlvbikgPyBhcnJheVNodWZmbGUgOiBiYXNlU2h1ZmZsZTtcbiAgICAgIHJldHVybiBmdW5jKGNvbGxlY3Rpb24pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldHMgdGhlIHNpemUgb2YgYGNvbGxlY3Rpb25gIGJ5IHJldHVybmluZyBpdHMgbGVuZ3RoIGZvciBhcnJheS1saWtlXG4gICAgICogdmFsdWVzIG9yIHRoZSBudW1iZXIgb2Ygb3duIGVudW1lcmFibGUgc3RyaW5nIGtleWVkIHByb3BlcnRpZXMgZm9yIG9iamVjdHMuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMC4xLjBcbiAgICAgKiBAY2F0ZWdvcnkgQ29sbGVjdGlvblxuICAgICAqIEBwYXJhbSB7QXJyYXl8T2JqZWN0fHN0cmluZ30gY29sbGVjdGlvbiBUaGUgY29sbGVjdGlvbiB0byBpbnNwZWN0LlxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9IFJldHVybnMgdGhlIGNvbGxlY3Rpb24gc2l6ZS5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5zaXplKFsxLCAyLCAzXSk7XG4gICAgICogLy8gPT4gM1xuICAgICAqXG4gICAgICogXy5zaXplKHsgJ2EnOiAxLCAnYic6IDIgfSk7XG4gICAgICogLy8gPT4gMlxuICAgICAqXG4gICAgICogXy5zaXplKCdwZWJibGVzJyk7XG4gICAgICogLy8gPT4gN1xuICAgICAqL1xuICAgIGZ1bmN0aW9uIHNpemUoY29sbGVjdGlvbikge1xuICAgICAgaWYgKGNvbGxlY3Rpb24gPT0gbnVsbCkge1xuICAgICAgICByZXR1cm4gMDtcbiAgICAgIH1cbiAgICAgIGlmIChpc0FycmF5TGlrZShjb2xsZWN0aW9uKSkge1xuICAgICAgICByZXR1cm4gaXNTdHJpbmcoY29sbGVjdGlvbikgPyBzdHJpbmdTaXplKGNvbGxlY3Rpb24pIDogY29sbGVjdGlvbi5sZW5ndGg7XG4gICAgICB9XG4gICAgICB2YXIgdGFnID0gZ2V0VGFnKGNvbGxlY3Rpb24pO1xuICAgICAgaWYgKHRhZyA9PSBtYXBUYWcgfHwgdGFnID09IHNldFRhZykge1xuICAgICAgICByZXR1cm4gY29sbGVjdGlvbi5zaXplO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGJhc2VLZXlzKGNvbGxlY3Rpb24pLmxlbmd0aDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDaGVja3MgaWYgYHByZWRpY2F0ZWAgcmV0dXJucyB0cnV0aHkgZm9yICoqYW55KiogZWxlbWVudCBvZiBgY29sbGVjdGlvbmAuXG4gICAgICogSXRlcmF0aW9uIGlzIHN0b3BwZWQgb25jZSBgcHJlZGljYXRlYCByZXR1cm5zIHRydXRoeS4gVGhlIHByZWRpY2F0ZSBpc1xuICAgICAqIGludm9rZWQgd2l0aCB0aHJlZSBhcmd1bWVudHM6ICh2YWx1ZSwgaW5kZXh8a2V5LCBjb2xsZWN0aW9uKS5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAwLjEuMFxuICAgICAqIEBjYXRlZ29yeSBDb2xsZWN0aW9uXG4gICAgICogQHBhcmFtIHtBcnJheXxPYmplY3R9IGNvbGxlY3Rpb24gVGhlIGNvbGxlY3Rpb24gdG8gaXRlcmF0ZSBvdmVyLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IFtwcmVkaWNhdGU9Xy5pZGVudGl0eV0gVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIGl0ZXJhdGlvbi5cbiAgICAgKiBAcGFyYW0tIHtPYmplY3R9IFtndWFyZF0gRW5hYmxlcyB1c2UgYXMgYW4gaXRlcmF0ZWUgZm9yIG1ldGhvZHMgbGlrZSBgXy5tYXBgLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBhbnkgZWxlbWVudCBwYXNzZXMgdGhlIHByZWRpY2F0ZSBjaGVjayxcbiAgICAgKiAgZWxzZSBgZmFsc2VgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLnNvbWUoW251bGwsIDAsICd5ZXMnLCBmYWxzZV0sIEJvb2xlYW4pO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKlxuICAgICAqIHZhciB1c2VycyA9IFtcbiAgICAgKiAgIHsgJ3VzZXInOiAnYmFybmV5JywgJ2FjdGl2ZSc6IHRydWUgfSxcbiAgICAgKiAgIHsgJ3VzZXInOiAnZnJlZCcsICAgJ2FjdGl2ZSc6IGZhbHNlIH1cbiAgICAgKiBdO1xuICAgICAqXG4gICAgICogLy8gVGhlIGBfLm1hdGNoZXNgIGl0ZXJhdGVlIHNob3J0aGFuZC5cbiAgICAgKiBfLnNvbWUodXNlcnMsIHsgJ3VzZXInOiAnYmFybmV5JywgJ2FjdGl2ZSc6IGZhbHNlIH0pO1xuICAgICAqIC8vID0+IGZhbHNlXG4gICAgICpcbiAgICAgKiAvLyBUaGUgYF8ubWF0Y2hlc1Byb3BlcnR5YCBpdGVyYXRlZSBzaG9ydGhhbmQuXG4gICAgICogXy5zb21lKHVzZXJzLCBbJ2FjdGl2ZScsIGZhbHNlXSk7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqXG4gICAgICogLy8gVGhlIGBfLnByb3BlcnR5YCBpdGVyYXRlZSBzaG9ydGhhbmQuXG4gICAgICogXy5zb21lKHVzZXJzLCAnYWN0aXZlJyk7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIHNvbWUoY29sbGVjdGlvbiwgcHJlZGljYXRlLCBndWFyZCkge1xuICAgICAgdmFyIGZ1bmMgPSBpc0FycmF5KGNvbGxlY3Rpb24pID8gYXJyYXlTb21lIDogYmFzZVNvbWU7XG4gICAgICBpZiAoZ3VhcmQgJiYgaXNJdGVyYXRlZUNhbGwoY29sbGVjdGlvbiwgcHJlZGljYXRlLCBndWFyZCkpIHtcbiAgICAgICAgcHJlZGljYXRlID0gdW5kZWZpbmVkO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGZ1bmMoY29sbGVjdGlvbiwgZ2V0SXRlcmF0ZWUocHJlZGljYXRlLCAzKSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhbiBhcnJheSBvZiBlbGVtZW50cywgc29ydGVkIGluIGFzY2VuZGluZyBvcmRlciBieSB0aGUgcmVzdWx0cyBvZlxuICAgICAqIHJ1bm5pbmcgZWFjaCBlbGVtZW50IGluIGEgY29sbGVjdGlvbiB0aHJ1IGVhY2ggaXRlcmF0ZWUuIFRoaXMgbWV0aG9kXG4gICAgICogcGVyZm9ybXMgYSBzdGFibGUgc29ydCwgdGhhdCBpcywgaXQgcHJlc2VydmVzIHRoZSBvcmlnaW5hbCBzb3J0IG9yZGVyIG9mXG4gICAgICogZXF1YWwgZWxlbWVudHMuIFRoZSBpdGVyYXRlZXMgYXJlIGludm9rZWQgd2l0aCBvbmUgYXJndW1lbnQ6ICh2YWx1ZSkuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMC4xLjBcbiAgICAgKiBAY2F0ZWdvcnkgQ29sbGVjdGlvblxuICAgICAqIEBwYXJhbSB7QXJyYXl8T2JqZWN0fSBjb2xsZWN0aW9uIFRoZSBjb2xsZWN0aW9uIHRvIGl0ZXJhdGUgb3Zlci5cbiAgICAgKiBAcGFyYW0gey4uLihGdW5jdGlvbnxGdW5jdGlvbltdKX0gW2l0ZXJhdGVlcz1bXy5pZGVudGl0eV1dXG4gICAgICogIFRoZSBpdGVyYXRlZXMgdG8gc29ydCBieS5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIG5ldyBzb3J0ZWQgYXJyYXkuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciB1c2VycyA9IFtcbiAgICAgKiAgIHsgJ3VzZXInOiAnZnJlZCcsICAgJ2FnZSc6IDQ4IH0sXG4gICAgICogICB7ICd1c2VyJzogJ2Jhcm5leScsICdhZ2UnOiAzNiB9LFxuICAgICAqICAgeyAndXNlcic6ICdmcmVkJywgICAnYWdlJzogMzAgfSxcbiAgICAgKiAgIHsgJ3VzZXInOiAnYmFybmV5JywgJ2FnZSc6IDM0IH1cbiAgICAgKiBdO1xuICAgICAqXG4gICAgICogXy5zb3J0QnkodXNlcnMsIFtmdW5jdGlvbihvKSB7IHJldHVybiBvLnVzZXI7IH1dKTtcbiAgICAgKiAvLyA9PiBvYmplY3RzIGZvciBbWydiYXJuZXknLCAzNl0sIFsnYmFybmV5JywgMzRdLCBbJ2ZyZWQnLCA0OF0sIFsnZnJlZCcsIDMwXV1cbiAgICAgKlxuICAgICAqIF8uc29ydEJ5KHVzZXJzLCBbJ3VzZXInLCAnYWdlJ10pO1xuICAgICAqIC8vID0+IG9iamVjdHMgZm9yIFtbJ2Jhcm5leScsIDM0XSwgWydiYXJuZXknLCAzNl0sIFsnZnJlZCcsIDMwXSwgWydmcmVkJywgNDhdXVxuICAgICAqL1xuICAgIHZhciBzb3J0QnkgPSBiYXNlUmVzdChmdW5jdGlvbihjb2xsZWN0aW9uLCBpdGVyYXRlZXMpIHtcbiAgICAgIGlmIChjb2xsZWN0aW9uID09IG51bGwpIHtcbiAgICAgICAgcmV0dXJuIFtdO1xuICAgICAgfVxuICAgICAgdmFyIGxlbmd0aCA9IGl0ZXJhdGVlcy5sZW5ndGg7XG4gICAgICBpZiAobGVuZ3RoID4gMSAmJiBpc0l0ZXJhdGVlQ2FsbChjb2xsZWN0aW9uLCBpdGVyYXRlZXNbMF0sIGl0ZXJhdGVlc1sxXSkpIHtcbiAgICAgICAgaXRlcmF0ZWVzID0gW107XG4gICAgICB9IGVsc2UgaWYgKGxlbmd0aCA+IDIgJiYgaXNJdGVyYXRlZUNhbGwoaXRlcmF0ZWVzWzBdLCBpdGVyYXRlZXNbMV0sIGl0ZXJhdGVlc1syXSkpIHtcbiAgICAgICAgaXRlcmF0ZWVzID0gW2l0ZXJhdGVlc1swXV07XG4gICAgICB9XG4gICAgICByZXR1cm4gYmFzZU9yZGVyQnkoY29sbGVjdGlvbiwgYmFzZUZsYXR0ZW4oaXRlcmF0ZWVzLCAxKSwgW10pO1xuICAgIH0pO1xuXG4gICAgLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuXG4gICAgLyoqXG4gICAgICogR2V0cyB0aGUgdGltZXN0YW1wIG9mIHRoZSBudW1iZXIgb2YgbWlsbGlzZWNvbmRzIHRoYXQgaGF2ZSBlbGFwc2VkIHNpbmNlXG4gICAgICogdGhlIFVuaXggZXBvY2ggKDEgSmFudWFyeSAxOTcwIDAwOjAwOjAwIFVUQykuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMi40LjBcbiAgICAgKiBAY2F0ZWdvcnkgRGF0ZVxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9IFJldHVybnMgdGhlIHRpbWVzdGFtcC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5kZWZlcihmdW5jdGlvbihzdGFtcCkge1xuICAgICAqICAgY29uc29sZS5sb2coXy5ub3coKSAtIHN0YW1wKTtcbiAgICAgKiB9LCBfLm5vdygpKTtcbiAgICAgKiAvLyA9PiBMb2dzIHRoZSBudW1iZXIgb2YgbWlsbGlzZWNvbmRzIGl0IHRvb2sgZm9yIHRoZSBkZWZlcnJlZCBpbnZvY2F0aW9uLlxuICAgICAqL1xuICAgIHZhciBub3cgPSBjdHhOb3cgfHwgZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gcm9vdC5EYXRlLm5vdygpO1xuICAgIH07XG5cbiAgICAvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovXG5cbiAgICAvKipcbiAgICAgKiBUaGUgb3Bwb3NpdGUgb2YgYF8uYmVmb3JlYDsgdGhpcyBtZXRob2QgY3JlYXRlcyBhIGZ1bmN0aW9uIHRoYXQgaW52b2tlc1xuICAgICAqIGBmdW5jYCBvbmNlIGl0J3MgY2FsbGVkIGBuYCBvciBtb3JlIHRpbWVzLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDAuMS4wXG4gICAgICogQGNhdGVnb3J5IEZ1bmN0aW9uXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IG4gVGhlIG51bWJlciBvZiBjYWxscyBiZWZvcmUgYGZ1bmNgIGlzIGludm9rZWQuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gZnVuYyBUaGUgZnVuY3Rpb24gdG8gcmVzdHJpY3QuXG4gICAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgcmVzdHJpY3RlZCBmdW5jdGlvbi5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIHNhdmVzID0gWydwcm9maWxlJywgJ3NldHRpbmdzJ107XG4gICAgICpcbiAgICAgKiB2YXIgZG9uZSA9IF8uYWZ0ZXIoc2F2ZXMubGVuZ3RoLCBmdW5jdGlvbigpIHtcbiAgICAgKiAgIGNvbnNvbGUubG9nKCdkb25lIHNhdmluZyEnKTtcbiAgICAgKiB9KTtcbiAgICAgKlxuICAgICAqIF8uZm9yRWFjaChzYXZlcywgZnVuY3Rpb24odHlwZSkge1xuICAgICAqICAgYXN5bmNTYXZlKHsgJ3R5cGUnOiB0eXBlLCAnY29tcGxldGUnOiBkb25lIH0pO1xuICAgICAqIH0pO1xuICAgICAqIC8vID0+IExvZ3MgJ2RvbmUgc2F2aW5nIScgYWZ0ZXIgdGhlIHR3byBhc3luYyBzYXZlcyBoYXZlIGNvbXBsZXRlZC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBhZnRlcihuLCBmdW5jKSB7XG4gICAgICBpZiAodHlwZW9mIGZ1bmMgIT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKEZVTkNfRVJST1JfVEVYVCk7XG4gICAgICB9XG4gICAgICBuID0gdG9JbnRlZ2VyKG4pO1xuICAgICAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgICAgICBpZiAoLS1uIDwgMSkge1xuICAgICAgICAgIHJldHVybiBmdW5jLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgICAgIH1cbiAgICAgIH07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIGZ1bmN0aW9uIHRoYXQgaW52b2tlcyBgZnVuY2AsIHdpdGggdXAgdG8gYG5gIGFyZ3VtZW50cyxcbiAgICAgKiBpZ25vcmluZyBhbnkgYWRkaXRpb25hbCBhcmd1bWVudHMuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMy4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgRnVuY3Rpb25cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byBjYXAgYXJndW1lbnRzIGZvci5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW249ZnVuYy5sZW5ndGhdIFRoZSBhcml0eSBjYXAuXG4gICAgICogQHBhcmFtLSB7T2JqZWN0fSBbZ3VhcmRdIEVuYWJsZXMgdXNlIGFzIGFuIGl0ZXJhdGVlIGZvciBtZXRob2RzIGxpa2UgYF8ubWFwYC5cbiAgICAgKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBjYXBwZWQgZnVuY3Rpb24uXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8ubWFwKFsnNicsICc4JywgJzEwJ10sIF8uYXJ5KHBhcnNlSW50LCAxKSk7XG4gICAgICogLy8gPT4gWzYsIDgsIDEwXVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGFyeShmdW5jLCBuLCBndWFyZCkge1xuICAgICAgbiA9IGd1YXJkID8gdW5kZWZpbmVkIDogbjtcbiAgICAgIG4gPSAoZnVuYyAmJiBuID09IG51bGwpID8gZnVuYy5sZW5ndGggOiBuO1xuICAgICAgcmV0dXJuIGNyZWF0ZVdyYXAoZnVuYywgV1JBUF9BUllfRkxBRywgdW5kZWZpbmVkLCB1bmRlZmluZWQsIHVuZGVmaW5lZCwgdW5kZWZpbmVkLCBuKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgZnVuY3Rpb24gdGhhdCBpbnZva2VzIGBmdW5jYCwgd2l0aCB0aGUgYHRoaXNgIGJpbmRpbmcgYW5kIGFyZ3VtZW50c1xuICAgICAqIG9mIHRoZSBjcmVhdGVkIGZ1bmN0aW9uLCB3aGlsZSBpdCdzIGNhbGxlZCBsZXNzIHRoYW4gYG5gIHRpbWVzLiBTdWJzZXF1ZW50XG4gICAgICogY2FsbHMgdG8gdGhlIGNyZWF0ZWQgZnVuY3Rpb24gcmV0dXJuIHRoZSByZXN1bHQgb2YgdGhlIGxhc3QgYGZ1bmNgIGludm9jYXRpb24uXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMy4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgRnVuY3Rpb25cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gbiBUaGUgbnVtYmVyIG9mIGNhbGxzIGF0IHdoaWNoIGBmdW5jYCBpcyBubyBsb25nZXIgaW52b2tlZC5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byByZXN0cmljdC5cbiAgICAgKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyByZXN0cmljdGVkIGZ1bmN0aW9uLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBqUXVlcnkoZWxlbWVudCkub24oJ2NsaWNrJywgXy5iZWZvcmUoNSwgYWRkQ29udGFjdFRvTGlzdCkpO1xuICAgICAqIC8vID0+IEFsbG93cyBhZGRpbmcgdXAgdG8gNCBjb250YWN0cyB0byB0aGUgbGlzdC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBiZWZvcmUobiwgZnVuYykge1xuICAgICAgdmFyIHJlc3VsdDtcbiAgICAgIGlmICh0eXBlb2YgZnVuYyAhPSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoRlVOQ19FUlJPUl9URVhUKTtcbiAgICAgIH1cbiAgICAgIG4gPSB0b0ludGVnZXIobik7XG4gICAgICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgICAgIGlmICgtLW4gPiAwKSB7XG4gICAgICAgICAgcmVzdWx0ID0gZnVuYy5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChuIDw9IDEpIHtcbiAgICAgICAgICBmdW5jID0gdW5kZWZpbmVkO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICB9O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBmdW5jdGlvbiB0aGF0IGludm9rZXMgYGZ1bmNgIHdpdGggdGhlIGB0aGlzYCBiaW5kaW5nIG9mIGB0aGlzQXJnYFxuICAgICAqIGFuZCBgcGFydGlhbHNgIHByZXBlbmRlZCB0byB0aGUgYXJndW1lbnRzIGl0IHJlY2VpdmVzLlxuICAgICAqXG4gICAgICogVGhlIGBfLmJpbmQucGxhY2Vob2xkZXJgIHZhbHVlLCB3aGljaCBkZWZhdWx0cyB0byBgX2AgaW4gbW9ub2xpdGhpYyBidWlsZHMsXG4gICAgICogbWF5IGJlIHVzZWQgYXMgYSBwbGFjZWhvbGRlciBmb3IgcGFydGlhbGx5IGFwcGxpZWQgYXJndW1lbnRzLlxuICAgICAqXG4gICAgICogKipOb3RlOioqIFVubGlrZSBuYXRpdmUgYEZ1bmN0aW9uI2JpbmRgLCB0aGlzIG1ldGhvZCBkb2Vzbid0IHNldCB0aGUgXCJsZW5ndGhcIlxuICAgICAqIHByb3BlcnR5IG9mIGJvdW5kIGZ1bmN0aW9ucy5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAwLjEuMFxuICAgICAqIEBjYXRlZ29yeSBGdW5jdGlvblxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIGJpbmQuXG4gICAgICogQHBhcmFtIHsqfSB0aGlzQXJnIFRoZSBgdGhpc2AgYmluZGluZyBvZiBgZnVuY2AuXG4gICAgICogQHBhcmFtIHsuLi4qfSBbcGFydGlhbHNdIFRoZSBhcmd1bWVudHMgdG8gYmUgcGFydGlhbGx5IGFwcGxpZWQuXG4gICAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgYm91bmQgZnVuY3Rpb24uXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIGZ1bmN0aW9uIGdyZWV0KGdyZWV0aW5nLCBwdW5jdHVhdGlvbikge1xuICAgICAqICAgcmV0dXJuIGdyZWV0aW5nICsgJyAnICsgdGhpcy51c2VyICsgcHVuY3R1YXRpb247XG4gICAgICogfVxuICAgICAqXG4gICAgICogdmFyIG9iamVjdCA9IHsgJ3VzZXInOiAnZnJlZCcgfTtcbiAgICAgKlxuICAgICAqIHZhciBib3VuZCA9IF8uYmluZChncmVldCwgb2JqZWN0LCAnaGknKTtcbiAgICAgKiBib3VuZCgnIScpO1xuICAgICAqIC8vID0+ICdoaSBmcmVkISdcbiAgICAgKlxuICAgICAqIC8vIEJvdW5kIHdpdGggcGxhY2Vob2xkZXJzLlxuICAgICAqIHZhciBib3VuZCA9IF8uYmluZChncmVldCwgb2JqZWN0LCBfLCAnIScpO1xuICAgICAqIGJvdW5kKCdoaScpO1xuICAgICAqIC8vID0+ICdoaSBmcmVkISdcbiAgICAgKi9cbiAgICB2YXIgYmluZCA9IGJhc2VSZXN0KGZ1bmN0aW9uKGZ1bmMsIHRoaXNBcmcsIHBhcnRpYWxzKSB7XG4gICAgICB2YXIgYml0bWFzayA9IFdSQVBfQklORF9GTEFHO1xuICAgICAgaWYgKHBhcnRpYWxzLmxlbmd0aCkge1xuICAgICAgICB2YXIgaG9sZGVycyA9IHJlcGxhY2VIb2xkZXJzKHBhcnRpYWxzLCBnZXRIb2xkZXIoYmluZCkpO1xuICAgICAgICBiaXRtYXNrIHw9IFdSQVBfUEFSVElBTF9GTEFHO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGNyZWF0ZVdyYXAoZnVuYywgYml0bWFzaywgdGhpc0FyZywgcGFydGlhbHMsIGhvbGRlcnMpO1xuICAgIH0pO1xuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIGZ1bmN0aW9uIHRoYXQgaW52b2tlcyB0aGUgbWV0aG9kIGF0IGBvYmplY3Rba2V5XWAgd2l0aCBgcGFydGlhbHNgXG4gICAgICogcHJlcGVuZGVkIHRvIHRoZSBhcmd1bWVudHMgaXQgcmVjZWl2ZXMuXG4gICAgICpcbiAgICAgKiBUaGlzIG1ldGhvZCBkaWZmZXJzIGZyb20gYF8uYmluZGAgYnkgYWxsb3dpbmcgYm91bmQgZnVuY3Rpb25zIHRvIHJlZmVyZW5jZVxuICAgICAqIG1ldGhvZHMgdGhhdCBtYXkgYmUgcmVkZWZpbmVkIG9yIGRvbid0IHlldCBleGlzdC4gU2VlXG4gICAgICogW1BldGVyIE1pY2hhdXgncyBhcnRpY2xlXShodHRwOi8vcGV0ZXIubWljaGF1eC5jYS9hcnRpY2xlcy9sYXp5LWZ1bmN0aW9uLWRlZmluaXRpb24tcGF0dGVybilcbiAgICAgKiBmb3IgbW9yZSBkZXRhaWxzLlxuICAgICAqXG4gICAgICogVGhlIGBfLmJpbmRLZXkucGxhY2Vob2xkZXJgIHZhbHVlLCB3aGljaCBkZWZhdWx0cyB0byBgX2AgaW4gbW9ub2xpdGhpY1xuICAgICAqIGJ1aWxkcywgbWF5IGJlIHVzZWQgYXMgYSBwbGFjZWhvbGRlciBmb3IgcGFydGlhbGx5IGFwcGxpZWQgYXJndW1lbnRzLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDAuMTAuMFxuICAgICAqIEBjYXRlZ29yeSBGdW5jdGlvblxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBpbnZva2UgdGhlIG1ldGhvZCBvbi5cbiAgICAgKiBAcGFyYW0ge3N0cmluZ30ga2V5IFRoZSBrZXkgb2YgdGhlIG1ldGhvZC5cbiAgICAgKiBAcGFyYW0gey4uLip9IFtwYXJ0aWFsc10gVGhlIGFyZ3VtZW50cyB0byBiZSBwYXJ0aWFsbHkgYXBwbGllZC5cbiAgICAgKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBib3VuZCBmdW5jdGlvbi5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIG9iamVjdCA9IHtcbiAgICAgKiAgICd1c2VyJzogJ2ZyZWQnLFxuICAgICAqICAgJ2dyZWV0JzogZnVuY3Rpb24oZ3JlZXRpbmcsIHB1bmN0dWF0aW9uKSB7XG4gICAgICogICAgIHJldHVybiBncmVldGluZyArICcgJyArIHRoaXMudXNlciArIHB1bmN0dWF0aW9uO1xuICAgICAqICAgfVxuICAgICAqIH07XG4gICAgICpcbiAgICAgKiB2YXIgYm91bmQgPSBfLmJpbmRLZXkob2JqZWN0LCAnZ3JlZXQnLCAnaGknKTtcbiAgICAgKiBib3VuZCgnIScpO1xuICAgICAqIC8vID0+ICdoaSBmcmVkISdcbiAgICAgKlxuICAgICAqIG9iamVjdC5ncmVldCA9IGZ1bmN0aW9uKGdyZWV0aW5nLCBwdW5jdHVhdGlvbikge1xuICAgICAqICAgcmV0dXJuIGdyZWV0aW5nICsgJ3lhICcgKyB0aGlzLnVzZXIgKyBwdW5jdHVhdGlvbjtcbiAgICAgKiB9O1xuICAgICAqXG4gICAgICogYm91bmQoJyEnKTtcbiAgICAgKiAvLyA9PiAnaGl5YSBmcmVkISdcbiAgICAgKlxuICAgICAqIC8vIEJvdW5kIHdpdGggcGxhY2Vob2xkZXJzLlxuICAgICAqIHZhciBib3VuZCA9IF8uYmluZEtleShvYmplY3QsICdncmVldCcsIF8sICchJyk7XG4gICAgICogYm91bmQoJ2hpJyk7XG4gICAgICogLy8gPT4gJ2hpeWEgZnJlZCEnXG4gICAgICovXG4gICAgdmFyIGJpbmRLZXkgPSBiYXNlUmVzdChmdW5jdGlvbihvYmplY3QsIGtleSwgcGFydGlhbHMpIHtcbiAgICAgIHZhciBiaXRtYXNrID0gV1JBUF9CSU5EX0ZMQUcgfCBXUkFQX0JJTkRfS0VZX0ZMQUc7XG4gICAgICBpZiAocGFydGlhbHMubGVuZ3RoKSB7XG4gICAgICAgIHZhciBob2xkZXJzID0gcmVwbGFjZUhvbGRlcnMocGFydGlhbHMsIGdldEhvbGRlcihiaW5kS2V5KSk7XG4gICAgICAgIGJpdG1hc2sgfD0gV1JBUF9QQVJUSUFMX0ZMQUc7XG4gICAgICB9XG4gICAgICByZXR1cm4gY3JlYXRlV3JhcChrZXksIGJpdG1hc2ssIG9iamVjdCwgcGFydGlhbHMsIGhvbGRlcnMpO1xuICAgIH0pO1xuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIGZ1bmN0aW9uIHRoYXQgYWNjZXB0cyBhcmd1bWVudHMgb2YgYGZ1bmNgIGFuZCBlaXRoZXIgaW52b2tlc1xuICAgICAqIGBmdW5jYCByZXR1cm5pbmcgaXRzIHJlc3VsdCwgaWYgYXQgbGVhc3QgYGFyaXR5YCBudW1iZXIgb2YgYXJndW1lbnRzIGhhdmVcbiAgICAgKiBiZWVuIHByb3ZpZGVkLCBvciByZXR1cm5zIGEgZnVuY3Rpb24gdGhhdCBhY2NlcHRzIHRoZSByZW1haW5pbmcgYGZ1bmNgXG4gICAgICogYXJndW1lbnRzLCBhbmQgc28gb24uIFRoZSBhcml0eSBvZiBgZnVuY2AgbWF5IGJlIHNwZWNpZmllZCBpZiBgZnVuYy5sZW5ndGhgXG4gICAgICogaXMgbm90IHN1ZmZpY2llbnQuXG4gICAgICpcbiAgICAgKiBUaGUgYF8uY3VycnkucGxhY2Vob2xkZXJgIHZhbHVlLCB3aGljaCBkZWZhdWx0cyB0byBgX2AgaW4gbW9ub2xpdGhpYyBidWlsZHMsXG4gICAgICogbWF5IGJlIHVzZWQgYXMgYSBwbGFjZWhvbGRlciBmb3IgcHJvdmlkZWQgYXJndW1lbnRzLlxuICAgICAqXG4gICAgICogKipOb3RlOioqIFRoaXMgbWV0aG9kIGRvZXNuJ3Qgc2V0IHRoZSBcImxlbmd0aFwiIHByb3BlcnR5IG9mIGN1cnJpZWQgZnVuY3Rpb25zLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDIuMC4wXG4gICAgICogQGNhdGVnb3J5IEZ1bmN0aW9uXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gZnVuYyBUaGUgZnVuY3Rpb24gdG8gY3VycnkuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFthcml0eT1mdW5jLmxlbmd0aF0gVGhlIGFyaXR5IG9mIGBmdW5jYC5cbiAgICAgKiBAcGFyYW0tIHtPYmplY3R9IFtndWFyZF0gRW5hYmxlcyB1c2UgYXMgYW4gaXRlcmF0ZWUgZm9yIG1ldGhvZHMgbGlrZSBgXy5tYXBgLlxuICAgICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IGN1cnJpZWQgZnVuY3Rpb24uXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciBhYmMgPSBmdW5jdGlvbihhLCBiLCBjKSB7XG4gICAgICogICByZXR1cm4gW2EsIGIsIGNdO1xuICAgICAqIH07XG4gICAgICpcbiAgICAgKiB2YXIgY3VycmllZCA9IF8uY3VycnkoYWJjKTtcbiAgICAgKlxuICAgICAqIGN1cnJpZWQoMSkoMikoMyk7XG4gICAgICogLy8gPT4gWzEsIDIsIDNdXG4gICAgICpcbiAgICAgKiBjdXJyaWVkKDEsIDIpKDMpO1xuICAgICAqIC8vID0+IFsxLCAyLCAzXVxuICAgICAqXG4gICAgICogY3VycmllZCgxLCAyLCAzKTtcbiAgICAgKiAvLyA9PiBbMSwgMiwgM11cbiAgICAgKlxuICAgICAqIC8vIEN1cnJpZWQgd2l0aCBwbGFjZWhvbGRlcnMuXG4gICAgICogY3VycmllZCgxKShfLCAzKSgyKTtcbiAgICAgKiAvLyA9PiBbMSwgMiwgM11cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBjdXJyeShmdW5jLCBhcml0eSwgZ3VhcmQpIHtcbiAgICAgIGFyaXR5ID0gZ3VhcmQgPyB1bmRlZmluZWQgOiBhcml0eTtcbiAgICAgIHZhciByZXN1bHQgPSBjcmVhdGVXcmFwKGZ1bmMsIFdSQVBfQ1VSUllfRkxBRywgdW5kZWZpbmVkLCB1bmRlZmluZWQsIHVuZGVmaW5lZCwgdW5kZWZpbmVkLCB1bmRlZmluZWQsIGFyaXR5KTtcbiAgICAgIHJlc3VsdC5wbGFjZWhvbGRlciA9IGN1cnJ5LnBsYWNlaG9sZGVyO1xuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIG1ldGhvZCBpcyBsaWtlIGBfLmN1cnJ5YCBleGNlcHQgdGhhdCBhcmd1bWVudHMgYXJlIGFwcGxpZWQgdG8gYGZ1bmNgXG4gICAgICogaW4gdGhlIG1hbm5lciBvZiBgXy5wYXJ0aWFsUmlnaHRgIGluc3RlYWQgb2YgYF8ucGFydGlhbGAuXG4gICAgICpcbiAgICAgKiBUaGUgYF8uY3VycnlSaWdodC5wbGFjZWhvbGRlcmAgdmFsdWUsIHdoaWNoIGRlZmF1bHRzIHRvIGBfYCBpbiBtb25vbGl0aGljXG4gICAgICogYnVpbGRzLCBtYXkgYmUgdXNlZCBhcyBhIHBsYWNlaG9sZGVyIGZvciBwcm92aWRlZCBhcmd1bWVudHMuXG4gICAgICpcbiAgICAgKiAqKk5vdGU6KiogVGhpcyBtZXRob2QgZG9lc24ndCBzZXQgdGhlIFwibGVuZ3RoXCIgcHJvcGVydHkgb2YgY3VycmllZCBmdW5jdGlvbnMuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMy4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgRnVuY3Rpb25cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byBjdXJyeS5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW2FyaXR5PWZ1bmMubGVuZ3RoXSBUaGUgYXJpdHkgb2YgYGZ1bmNgLlxuICAgICAqIEBwYXJhbS0ge09iamVjdH0gW2d1YXJkXSBFbmFibGVzIHVzZSBhcyBhbiBpdGVyYXRlZSBmb3IgbWV0aG9kcyBsaWtlIGBfLm1hcGAuXG4gICAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgY3VycmllZCBmdW5jdGlvbi5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIGFiYyA9IGZ1bmN0aW9uKGEsIGIsIGMpIHtcbiAgICAgKiAgIHJldHVybiBbYSwgYiwgY107XG4gICAgICogfTtcbiAgICAgKlxuICAgICAqIHZhciBjdXJyaWVkID0gXy5jdXJyeVJpZ2h0KGFiYyk7XG4gICAgICpcbiAgICAgKiBjdXJyaWVkKDMpKDIpKDEpO1xuICAgICAqIC8vID0+IFsxLCAyLCAzXVxuICAgICAqXG4gICAgICogY3VycmllZCgyLCAzKSgxKTtcbiAgICAgKiAvLyA9PiBbMSwgMiwgM11cbiAgICAgKlxuICAgICAqIGN1cnJpZWQoMSwgMiwgMyk7XG4gICAgICogLy8gPT4gWzEsIDIsIDNdXG4gICAgICpcbiAgICAgKiAvLyBDdXJyaWVkIHdpdGggcGxhY2Vob2xkZXJzLlxuICAgICAqIGN1cnJpZWQoMykoMSwgXykoMik7XG4gICAgICogLy8gPT4gWzEsIDIsIDNdXG4gICAgICovXG4gICAgZnVuY3Rpb24gY3VycnlSaWdodChmdW5jLCBhcml0eSwgZ3VhcmQpIHtcbiAgICAgIGFyaXR5ID0gZ3VhcmQgPyB1bmRlZmluZWQgOiBhcml0eTtcbiAgICAgIHZhciByZXN1bHQgPSBjcmVhdGVXcmFwKGZ1bmMsIFdSQVBfQ1VSUllfUklHSFRfRkxBRywgdW5kZWZpbmVkLCB1bmRlZmluZWQsIHVuZGVmaW5lZCwgdW5kZWZpbmVkLCB1bmRlZmluZWQsIGFyaXR5KTtcbiAgICAgIHJlc3VsdC5wbGFjZWhvbGRlciA9IGN1cnJ5UmlnaHQucGxhY2Vob2xkZXI7XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBkZWJvdW5jZWQgZnVuY3Rpb24gdGhhdCBkZWxheXMgaW52b2tpbmcgYGZ1bmNgIHVudGlsIGFmdGVyIGB3YWl0YFxuICAgICAqIG1pbGxpc2Vjb25kcyBoYXZlIGVsYXBzZWQgc2luY2UgdGhlIGxhc3QgdGltZSB0aGUgZGVib3VuY2VkIGZ1bmN0aW9uIHdhc1xuICAgICAqIGludm9rZWQuIFRoZSBkZWJvdW5jZWQgZnVuY3Rpb24gY29tZXMgd2l0aCBhIGBjYW5jZWxgIG1ldGhvZCB0byBjYW5jZWxcbiAgICAgKiBkZWxheWVkIGBmdW5jYCBpbnZvY2F0aW9ucyBhbmQgYSBgZmx1c2hgIG1ldGhvZCB0byBpbW1lZGlhdGVseSBpbnZva2UgdGhlbS5cbiAgICAgKiBQcm92aWRlIGBvcHRpb25zYCB0byBpbmRpY2F0ZSB3aGV0aGVyIGBmdW5jYCBzaG91bGQgYmUgaW52b2tlZCBvbiB0aGVcbiAgICAgKiBsZWFkaW5nIGFuZC9vciB0cmFpbGluZyBlZGdlIG9mIHRoZSBgd2FpdGAgdGltZW91dC4gVGhlIGBmdW5jYCBpcyBpbnZva2VkXG4gICAgICogd2l0aCB0aGUgbGFzdCBhcmd1bWVudHMgcHJvdmlkZWQgdG8gdGhlIGRlYm91bmNlZCBmdW5jdGlvbi4gU3Vic2VxdWVudFxuICAgICAqIGNhbGxzIHRvIHRoZSBkZWJvdW5jZWQgZnVuY3Rpb24gcmV0dXJuIHRoZSByZXN1bHQgb2YgdGhlIGxhc3QgYGZ1bmNgXG4gICAgICogaW52b2NhdGlvbi5cbiAgICAgKlxuICAgICAqICoqTm90ZToqKiBJZiBgbGVhZGluZ2AgYW5kIGB0cmFpbGluZ2Agb3B0aW9ucyBhcmUgYHRydWVgLCBgZnVuY2AgaXNcbiAgICAgKiBpbnZva2VkIG9uIHRoZSB0cmFpbGluZyBlZGdlIG9mIHRoZSB0aW1lb3V0IG9ubHkgaWYgdGhlIGRlYm91bmNlZCBmdW5jdGlvblxuICAgICAqIGlzIGludm9rZWQgbW9yZSB0aGFuIG9uY2UgZHVyaW5nIHRoZSBgd2FpdGAgdGltZW91dC5cbiAgICAgKlxuICAgICAqIElmIGB3YWl0YCBpcyBgMGAgYW5kIGBsZWFkaW5nYCBpcyBgZmFsc2VgLCBgZnVuY2AgaW52b2NhdGlvbiBpcyBkZWZlcnJlZFxuICAgICAqIHVudGlsIHRvIHRoZSBuZXh0IHRpY2ssIHNpbWlsYXIgdG8gYHNldFRpbWVvdXRgIHdpdGggYSB0aW1lb3V0IG9mIGAwYC5cbiAgICAgKlxuICAgICAqIFNlZSBbRGF2aWQgQ29yYmFjaG8ncyBhcnRpY2xlXShodHRwczovL2Nzcy10cmlja3MuY29tL2RlYm91bmNpbmctdGhyb3R0bGluZy1leHBsYWluZWQtZXhhbXBsZXMvKVxuICAgICAqIGZvciBkZXRhaWxzIG92ZXIgdGhlIGRpZmZlcmVuY2VzIGJldHdlZW4gYF8uZGVib3VuY2VgIGFuZCBgXy50aHJvdHRsZWAuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMC4xLjBcbiAgICAgKiBAY2F0ZWdvcnkgRnVuY3Rpb25cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byBkZWJvdW5jZS5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW3dhaXQ9MF0gVGhlIG51bWJlciBvZiBtaWxsaXNlY29uZHMgdG8gZGVsYXkuXG4gICAgICogQHBhcmFtIHtPYmplY3R9IFtvcHRpb25zPXt9XSBUaGUgb3B0aW9ucyBvYmplY3QuXG4gICAgICogQHBhcmFtIHtib29sZWFufSBbb3B0aW9ucy5sZWFkaW5nPWZhbHNlXVxuICAgICAqICBTcGVjaWZ5IGludm9raW5nIG9uIHRoZSBsZWFkaW5nIGVkZ2Ugb2YgdGhlIHRpbWVvdXQuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtvcHRpb25zLm1heFdhaXRdXG4gICAgICogIFRoZSBtYXhpbXVtIHRpbWUgYGZ1bmNgIGlzIGFsbG93ZWQgdG8gYmUgZGVsYXllZCBiZWZvcmUgaXQncyBpbnZva2VkLlxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbn0gW29wdGlvbnMudHJhaWxpbmc9dHJ1ZV1cbiAgICAgKiAgU3BlY2lmeSBpbnZva2luZyBvbiB0aGUgdHJhaWxpbmcgZWRnZSBvZiB0aGUgdGltZW91dC5cbiAgICAgKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBkZWJvdW5jZWQgZnVuY3Rpb24uXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIC8vIEF2b2lkIGNvc3RseSBjYWxjdWxhdGlvbnMgd2hpbGUgdGhlIHdpbmRvdyBzaXplIGlzIGluIGZsdXguXG4gICAgICogalF1ZXJ5KHdpbmRvdykub24oJ3Jlc2l6ZScsIF8uZGVib3VuY2UoY2FsY3VsYXRlTGF5b3V0LCAxNTApKTtcbiAgICAgKlxuICAgICAqIC8vIEludm9rZSBgc2VuZE1haWxgIHdoZW4gY2xpY2tlZCwgZGVib3VuY2luZyBzdWJzZXF1ZW50IGNhbGxzLlxuICAgICAqIGpRdWVyeShlbGVtZW50KS5vbignY2xpY2snLCBfLmRlYm91bmNlKHNlbmRNYWlsLCAzMDAsIHtcbiAgICAgKiAgICdsZWFkaW5nJzogdHJ1ZSxcbiAgICAgKiAgICd0cmFpbGluZyc6IGZhbHNlXG4gICAgICogfSkpO1xuICAgICAqXG4gICAgICogLy8gRW5zdXJlIGBiYXRjaExvZ2AgaXMgaW52b2tlZCBvbmNlIGFmdGVyIDEgc2Vjb25kIG9mIGRlYm91bmNlZCBjYWxscy5cbiAgICAgKiB2YXIgZGVib3VuY2VkID0gXy5kZWJvdW5jZShiYXRjaExvZywgMjUwLCB7ICdtYXhXYWl0JzogMTAwMCB9KTtcbiAgICAgKiB2YXIgc291cmNlID0gbmV3IEV2ZW50U291cmNlKCcvc3RyZWFtJyk7XG4gICAgICogalF1ZXJ5KHNvdXJjZSkub24oJ21lc3NhZ2UnLCBkZWJvdW5jZWQpO1xuICAgICAqXG4gICAgICogLy8gQ2FuY2VsIHRoZSB0cmFpbGluZyBkZWJvdW5jZWQgaW52b2NhdGlvbi5cbiAgICAgKiBqUXVlcnkod2luZG93KS5vbigncG9wc3RhdGUnLCBkZWJvdW5jZWQuY2FuY2VsKTtcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBkZWJvdW5jZShmdW5jLCB3YWl0LCBvcHRpb25zKSB7XG4gICAgICB2YXIgbGFzdEFyZ3MsXG4gICAgICAgICAgbGFzdFRoaXMsXG4gICAgICAgICAgbWF4V2FpdCxcbiAgICAgICAgICByZXN1bHQsXG4gICAgICAgICAgdGltZXJJZCxcbiAgICAgICAgICBsYXN0Q2FsbFRpbWUsXG4gICAgICAgICAgbGFzdEludm9rZVRpbWUgPSAwLFxuICAgICAgICAgIGxlYWRpbmcgPSBmYWxzZSxcbiAgICAgICAgICBtYXhpbmcgPSBmYWxzZSxcbiAgICAgICAgICB0cmFpbGluZyA9IHRydWU7XG5cbiAgICAgIGlmICh0eXBlb2YgZnVuYyAhPSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoRlVOQ19FUlJPUl9URVhUKTtcbiAgICAgIH1cbiAgICAgIHdhaXQgPSB0b051bWJlcih3YWl0KSB8fCAwO1xuICAgICAgaWYgKGlzT2JqZWN0KG9wdGlvbnMpKSB7XG4gICAgICAgIGxlYWRpbmcgPSAhIW9wdGlvbnMubGVhZGluZztcbiAgICAgICAgbWF4aW5nID0gJ21heFdhaXQnIGluIG9wdGlvbnM7XG4gICAgICAgIG1heFdhaXQgPSBtYXhpbmcgPyBuYXRpdmVNYXgodG9OdW1iZXIob3B0aW9ucy5tYXhXYWl0KSB8fCAwLCB3YWl0KSA6IG1heFdhaXQ7XG4gICAgICAgIHRyYWlsaW5nID0gJ3RyYWlsaW5nJyBpbiBvcHRpb25zID8gISFvcHRpb25zLnRyYWlsaW5nIDogdHJhaWxpbmc7XG4gICAgICB9XG5cbiAgICAgIGZ1bmN0aW9uIGludm9rZUZ1bmModGltZSkge1xuICAgICAgICB2YXIgYXJncyA9IGxhc3RBcmdzLFxuICAgICAgICAgICAgdGhpc0FyZyA9IGxhc3RUaGlzO1xuXG4gICAgICAgIGxhc3RBcmdzID0gbGFzdFRoaXMgPSB1bmRlZmluZWQ7XG4gICAgICAgIGxhc3RJbnZva2VUaW1lID0gdGltZTtcbiAgICAgICAgcmVzdWx0ID0gZnVuYy5hcHBseSh0aGlzQXJnLCBhcmdzKTtcbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgIH1cblxuICAgICAgZnVuY3Rpb24gbGVhZGluZ0VkZ2UodGltZSkge1xuICAgICAgICAvLyBSZXNldCBhbnkgYG1heFdhaXRgIHRpbWVyLlxuICAgICAgICBsYXN0SW52b2tlVGltZSA9IHRpbWU7XG4gICAgICAgIC8vIFN0YXJ0IHRoZSB0aW1lciBmb3IgdGhlIHRyYWlsaW5nIGVkZ2UuXG4gICAgICAgIHRpbWVySWQgPSBzZXRUaW1lb3V0KHRpbWVyRXhwaXJlZCwgd2FpdCk7XG4gICAgICAgIC8vIEludm9rZSB0aGUgbGVhZGluZyBlZGdlLlxuICAgICAgICByZXR1cm4gbGVhZGluZyA/IGludm9rZUZ1bmModGltZSkgOiByZXN1bHQ7XG4gICAgICB9XG5cbiAgICAgIGZ1bmN0aW9uIHJlbWFpbmluZ1dhaXQodGltZSkge1xuICAgICAgICB2YXIgdGltZVNpbmNlTGFzdENhbGwgPSB0aW1lIC0gbGFzdENhbGxUaW1lLFxuICAgICAgICAgICAgdGltZVNpbmNlTGFzdEludm9rZSA9IHRpbWUgLSBsYXN0SW52b2tlVGltZSxcbiAgICAgICAgICAgIHRpbWVXYWl0aW5nID0gd2FpdCAtIHRpbWVTaW5jZUxhc3RDYWxsO1xuXG4gICAgICAgIHJldHVybiBtYXhpbmdcbiAgICAgICAgICA/IG5hdGl2ZU1pbih0aW1lV2FpdGluZywgbWF4V2FpdCAtIHRpbWVTaW5jZUxhc3RJbnZva2UpXG4gICAgICAgICAgOiB0aW1lV2FpdGluZztcbiAgICAgIH1cblxuICAgICAgZnVuY3Rpb24gc2hvdWxkSW52b2tlKHRpbWUpIHtcbiAgICAgICAgdmFyIHRpbWVTaW5jZUxhc3RDYWxsID0gdGltZSAtIGxhc3RDYWxsVGltZSxcbiAgICAgICAgICAgIHRpbWVTaW5jZUxhc3RJbnZva2UgPSB0aW1lIC0gbGFzdEludm9rZVRpbWU7XG5cbiAgICAgICAgLy8gRWl0aGVyIHRoaXMgaXMgdGhlIGZpcnN0IGNhbGwsIGFjdGl2aXR5IGhhcyBzdG9wcGVkIGFuZCB3ZSdyZSBhdCB0aGVcbiAgICAgICAgLy8gdHJhaWxpbmcgZWRnZSwgdGhlIHN5c3RlbSB0aW1lIGhhcyBnb25lIGJhY2t3YXJkcyBhbmQgd2UncmUgdHJlYXRpbmdcbiAgICAgICAgLy8gaXQgYXMgdGhlIHRyYWlsaW5nIGVkZ2UsIG9yIHdlJ3ZlIGhpdCB0aGUgYG1heFdhaXRgIGxpbWl0LlxuICAgICAgICByZXR1cm4gKGxhc3RDYWxsVGltZSA9PT0gdW5kZWZpbmVkIHx8ICh0aW1lU2luY2VMYXN0Q2FsbCA+PSB3YWl0KSB8fFxuICAgICAgICAgICh0aW1lU2luY2VMYXN0Q2FsbCA8IDApIHx8IChtYXhpbmcgJiYgdGltZVNpbmNlTGFzdEludm9rZSA+PSBtYXhXYWl0KSk7XG4gICAgICB9XG5cbiAgICAgIGZ1bmN0aW9uIHRpbWVyRXhwaXJlZCgpIHtcbiAgICAgICAgdmFyIHRpbWUgPSBub3coKTtcbiAgICAgICAgaWYgKHNob3VsZEludm9rZSh0aW1lKSkge1xuICAgICAgICAgIHJldHVybiB0cmFpbGluZ0VkZ2UodGltZSk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gUmVzdGFydCB0aGUgdGltZXIuXG4gICAgICAgIHRpbWVySWQgPSBzZXRUaW1lb3V0KHRpbWVyRXhwaXJlZCwgcmVtYWluaW5nV2FpdCh0aW1lKSk7XG4gICAgICB9XG5cbiAgICAgIGZ1bmN0aW9uIHRyYWlsaW5nRWRnZSh0aW1lKSB7XG4gICAgICAgIHRpbWVySWQgPSB1bmRlZmluZWQ7XG5cbiAgICAgICAgLy8gT25seSBpbnZva2UgaWYgd2UgaGF2ZSBgbGFzdEFyZ3NgIHdoaWNoIG1lYW5zIGBmdW5jYCBoYXMgYmVlblxuICAgICAgICAvLyBkZWJvdW5jZWQgYXQgbGVhc3Qgb25jZS5cbiAgICAgICAgaWYgKHRyYWlsaW5nICYmIGxhc3RBcmdzKSB7XG4gICAgICAgICAgcmV0dXJuIGludm9rZUZ1bmModGltZSk7XG4gICAgICAgIH1cbiAgICAgICAgbGFzdEFyZ3MgPSBsYXN0VGhpcyA9IHVuZGVmaW5lZDtcbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgIH1cblxuICAgICAgZnVuY3Rpb24gY2FuY2VsKCkge1xuICAgICAgICBpZiAodGltZXJJZCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgY2xlYXJUaW1lb3V0KHRpbWVySWQpO1xuICAgICAgICB9XG4gICAgICAgIGxhc3RJbnZva2VUaW1lID0gMDtcbiAgICAgICAgbGFzdEFyZ3MgPSBsYXN0Q2FsbFRpbWUgPSBsYXN0VGhpcyA9IHRpbWVySWQgPSB1bmRlZmluZWQ7XG4gICAgICB9XG5cbiAgICAgIGZ1bmN0aW9uIGZsdXNoKCkge1xuICAgICAgICByZXR1cm4gdGltZXJJZCA9PT0gdW5kZWZpbmVkID8gcmVzdWx0IDogdHJhaWxpbmdFZGdlKG5vdygpKTtcbiAgICAgIH1cblxuICAgICAgZnVuY3Rpb24gZGVib3VuY2VkKCkge1xuICAgICAgICB2YXIgdGltZSA9IG5vdygpLFxuICAgICAgICAgICAgaXNJbnZva2luZyA9IHNob3VsZEludm9rZSh0aW1lKTtcblxuICAgICAgICBsYXN0QXJncyA9IGFyZ3VtZW50cztcbiAgICAgICAgbGFzdFRoaXMgPSB0aGlzO1xuICAgICAgICBsYXN0Q2FsbFRpbWUgPSB0aW1lO1xuXG4gICAgICAgIGlmIChpc0ludm9raW5nKSB7XG4gICAgICAgICAgaWYgKHRpbWVySWQgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgcmV0dXJuIGxlYWRpbmdFZGdlKGxhc3RDYWxsVGltZSk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmIChtYXhpbmcpIHtcbiAgICAgICAgICAgIC8vIEhhbmRsZSBpbnZvY2F0aW9ucyBpbiBhIHRpZ2h0IGxvb3AuXG4gICAgICAgICAgICBjbGVhclRpbWVvdXQodGltZXJJZCk7XG4gICAgICAgICAgICB0aW1lcklkID0gc2V0VGltZW91dCh0aW1lckV4cGlyZWQsIHdhaXQpO1xuICAgICAgICAgICAgcmV0dXJuIGludm9rZUZ1bmMobGFzdENhbGxUaW1lKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRpbWVySWQgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIHRpbWVySWQgPSBzZXRUaW1lb3V0KHRpbWVyRXhwaXJlZCwgd2FpdCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgIH1cbiAgICAgIGRlYm91bmNlZC5jYW5jZWwgPSBjYW5jZWw7XG4gICAgICBkZWJvdW5jZWQuZmx1c2ggPSBmbHVzaDtcbiAgICAgIHJldHVybiBkZWJvdW5jZWQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRGVmZXJzIGludm9raW5nIHRoZSBgZnVuY2AgdW50aWwgdGhlIGN1cnJlbnQgY2FsbCBzdGFjayBoYXMgY2xlYXJlZC4gQW55XG4gICAgICogYWRkaXRpb25hbCBhcmd1bWVudHMgYXJlIHByb3ZpZGVkIHRvIGBmdW5jYCB3aGVuIGl0J3MgaW52b2tlZC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAwLjEuMFxuICAgICAqIEBjYXRlZ29yeSBGdW5jdGlvblxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIGRlZmVyLlxuICAgICAqIEBwYXJhbSB7Li4uKn0gW2FyZ3NdIFRoZSBhcmd1bWVudHMgdG8gaW52b2tlIGBmdW5jYCB3aXRoLlxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9IFJldHVybnMgdGhlIHRpbWVyIGlkLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLmRlZmVyKGZ1bmN0aW9uKHRleHQpIHtcbiAgICAgKiAgIGNvbnNvbGUubG9nKHRleHQpO1xuICAgICAqIH0sICdkZWZlcnJlZCcpO1xuICAgICAqIC8vID0+IExvZ3MgJ2RlZmVycmVkJyBhZnRlciBvbmUgbWlsbGlzZWNvbmQuXG4gICAgICovXG4gICAgdmFyIGRlZmVyID0gYmFzZVJlc3QoZnVuY3Rpb24oZnVuYywgYXJncykge1xuICAgICAgcmV0dXJuIGJhc2VEZWxheShmdW5jLCAxLCBhcmdzKTtcbiAgICB9KTtcblxuICAgIC8qKlxuICAgICAqIEludm9rZXMgYGZ1bmNgIGFmdGVyIGB3YWl0YCBtaWxsaXNlY29uZHMuIEFueSBhZGRpdGlvbmFsIGFyZ3VtZW50cyBhcmVcbiAgICAgKiBwcm92aWRlZCB0byBgZnVuY2Agd2hlbiBpdCdzIGludm9rZWQuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMC4xLjBcbiAgICAgKiBAY2F0ZWdvcnkgRnVuY3Rpb25cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byBkZWxheS5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gd2FpdCBUaGUgbnVtYmVyIG9mIG1pbGxpc2Vjb25kcyB0byBkZWxheSBpbnZvY2F0aW9uLlxuICAgICAqIEBwYXJhbSB7Li4uKn0gW2FyZ3NdIFRoZSBhcmd1bWVudHMgdG8gaW52b2tlIGBmdW5jYCB3aXRoLlxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9IFJldHVybnMgdGhlIHRpbWVyIGlkLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLmRlbGF5KGZ1bmN0aW9uKHRleHQpIHtcbiAgICAgKiAgIGNvbnNvbGUubG9nKHRleHQpO1xuICAgICAqIH0sIDEwMDAsICdsYXRlcicpO1xuICAgICAqIC8vID0+IExvZ3MgJ2xhdGVyJyBhZnRlciBvbmUgc2Vjb25kLlxuICAgICAqL1xuICAgIHZhciBkZWxheSA9IGJhc2VSZXN0KGZ1bmN0aW9uKGZ1bmMsIHdhaXQsIGFyZ3MpIHtcbiAgICAgIHJldHVybiBiYXNlRGVsYXkoZnVuYywgdG9OdW1iZXIod2FpdCkgfHwgMCwgYXJncyk7XG4gICAgfSk7XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgZnVuY3Rpb24gdGhhdCBpbnZva2VzIGBmdW5jYCB3aXRoIGFyZ3VtZW50cyByZXZlcnNlZC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjAuMFxuICAgICAqIEBjYXRlZ29yeSBGdW5jdGlvblxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIGZsaXAgYXJndW1lbnRzIGZvci5cbiAgICAgKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBmbGlwcGVkIGZ1bmN0aW9uLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgZmxpcHBlZCA9IF8uZmxpcChmdW5jdGlvbigpIHtcbiAgICAgKiAgIHJldHVybiBfLnRvQXJyYXkoYXJndW1lbnRzKTtcbiAgICAgKiB9KTtcbiAgICAgKlxuICAgICAqIGZsaXBwZWQoJ2EnLCAnYicsICdjJywgJ2QnKTtcbiAgICAgKiAvLyA9PiBbJ2QnLCAnYycsICdiJywgJ2EnXVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGZsaXAoZnVuYykge1xuICAgICAgcmV0dXJuIGNyZWF0ZVdyYXAoZnVuYywgV1JBUF9GTElQX0ZMQUcpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBmdW5jdGlvbiB0aGF0IG1lbW9pemVzIHRoZSByZXN1bHQgb2YgYGZ1bmNgLiBJZiBgcmVzb2x2ZXJgIGlzXG4gICAgICogcHJvdmlkZWQsIGl0IGRldGVybWluZXMgdGhlIGNhY2hlIGtleSBmb3Igc3RvcmluZyB0aGUgcmVzdWx0IGJhc2VkIG9uIHRoZVxuICAgICAqIGFyZ3VtZW50cyBwcm92aWRlZCB0byB0aGUgbWVtb2l6ZWQgZnVuY3Rpb24uIEJ5IGRlZmF1bHQsIHRoZSBmaXJzdCBhcmd1bWVudFxuICAgICAqIHByb3ZpZGVkIHRvIHRoZSBtZW1vaXplZCBmdW5jdGlvbiBpcyB1c2VkIGFzIHRoZSBtYXAgY2FjaGUga2V5LiBUaGUgYGZ1bmNgXG4gICAgICogaXMgaW52b2tlZCB3aXRoIHRoZSBgdGhpc2AgYmluZGluZyBvZiB0aGUgbWVtb2l6ZWQgZnVuY3Rpb24uXG4gICAgICpcbiAgICAgKiAqKk5vdGU6KiogVGhlIGNhY2hlIGlzIGV4cG9zZWQgYXMgdGhlIGBjYWNoZWAgcHJvcGVydHkgb24gdGhlIG1lbW9pemVkXG4gICAgICogZnVuY3Rpb24uIEl0cyBjcmVhdGlvbiBtYXkgYmUgY3VzdG9taXplZCBieSByZXBsYWNpbmcgdGhlIGBfLm1lbW9pemUuQ2FjaGVgXG4gICAgICogY29uc3RydWN0b3Igd2l0aCBvbmUgd2hvc2UgaW5zdGFuY2VzIGltcGxlbWVudCB0aGVcbiAgICAgKiBbYE1hcGBdKGh0dHA6Ly9lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzcuMC8jc2VjLXByb3BlcnRpZXMtb2YtdGhlLW1hcC1wcm90b3R5cGUtb2JqZWN0KVxuICAgICAqIG1ldGhvZCBpbnRlcmZhY2Ugb2YgYGNsZWFyYCwgYGRlbGV0ZWAsIGBnZXRgLCBgaGFzYCwgYW5kIGBzZXRgLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDAuMS4wXG4gICAgICogQGNhdGVnb3J5IEZ1bmN0aW9uXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gZnVuYyBUaGUgZnVuY3Rpb24gdG8gaGF2ZSBpdHMgb3V0cHV0IG1lbW9pemVkLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IFtyZXNvbHZlcl0gVGhlIGZ1bmN0aW9uIHRvIHJlc29sdmUgdGhlIGNhY2hlIGtleS5cbiAgICAgKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBtZW1vaXplZCBmdW5jdGlvbi5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIG9iamVjdCA9IHsgJ2EnOiAxLCAnYic6IDIgfTtcbiAgICAgKiB2YXIgb3RoZXIgPSB7ICdjJzogMywgJ2QnOiA0IH07XG4gICAgICpcbiAgICAgKiB2YXIgdmFsdWVzID0gXy5tZW1vaXplKF8udmFsdWVzKTtcbiAgICAgKiB2YWx1ZXMob2JqZWN0KTtcbiAgICAgKiAvLyA9PiBbMSwgMl1cbiAgICAgKlxuICAgICAqIHZhbHVlcyhvdGhlcik7XG4gICAgICogLy8gPT4gWzMsIDRdXG4gICAgICpcbiAgICAgKiBvYmplY3QuYSA9IDI7XG4gICAgICogdmFsdWVzKG9iamVjdCk7XG4gICAgICogLy8gPT4gWzEsIDJdXG4gICAgICpcbiAgICAgKiAvLyBNb2RpZnkgdGhlIHJlc3VsdCBjYWNoZS5cbiAgICAgKiB2YWx1ZXMuY2FjaGUuc2V0KG9iamVjdCwgWydhJywgJ2InXSk7XG4gICAgICogdmFsdWVzKG9iamVjdCk7XG4gICAgICogLy8gPT4gWydhJywgJ2InXVxuICAgICAqXG4gICAgICogLy8gUmVwbGFjZSBgXy5tZW1vaXplLkNhY2hlYC5cbiAgICAgKiBfLm1lbW9pemUuQ2FjaGUgPSBXZWFrTWFwO1xuICAgICAqL1xuICAgIGZ1bmN0aW9uIG1lbW9pemUoZnVuYywgcmVzb2x2ZXIpIHtcbiAgICAgIGlmICh0eXBlb2YgZnVuYyAhPSAnZnVuY3Rpb24nIHx8IChyZXNvbHZlciAhPSBudWxsICYmIHR5cGVvZiByZXNvbHZlciAhPSAnZnVuY3Rpb24nKSkge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKEZVTkNfRVJST1JfVEVYVCk7XG4gICAgICB9XG4gICAgICB2YXIgbWVtb2l6ZWQgPSBmdW5jdGlvbigpIHtcbiAgICAgICAgdmFyIGFyZ3MgPSBhcmd1bWVudHMsXG4gICAgICAgICAgICBrZXkgPSByZXNvbHZlciA/IHJlc29sdmVyLmFwcGx5KHRoaXMsIGFyZ3MpIDogYXJnc1swXSxcbiAgICAgICAgICAgIGNhY2hlID0gbWVtb2l6ZWQuY2FjaGU7XG5cbiAgICAgICAgaWYgKGNhY2hlLmhhcyhrZXkpKSB7XG4gICAgICAgICAgcmV0dXJuIGNhY2hlLmdldChrZXkpO1xuICAgICAgICB9XG4gICAgICAgIHZhciByZXN1bHQgPSBmdW5jLmFwcGx5KHRoaXMsIGFyZ3MpO1xuICAgICAgICBtZW1vaXplZC5jYWNoZSA9IGNhY2hlLnNldChrZXksIHJlc3VsdCkgfHwgY2FjaGU7XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICB9O1xuICAgICAgbWVtb2l6ZWQuY2FjaGUgPSBuZXcgKG1lbW9pemUuQ2FjaGUgfHwgTWFwQ2FjaGUpO1xuICAgICAgcmV0dXJuIG1lbW9pemVkO1xuICAgIH1cblxuICAgIC8vIEV4cG9zZSBgTWFwQ2FjaGVgLlxuICAgIG1lbW9pemUuQ2FjaGUgPSBNYXBDYWNoZTtcblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBmdW5jdGlvbiB0aGF0IG5lZ2F0ZXMgdGhlIHJlc3VsdCBvZiB0aGUgcHJlZGljYXRlIGBmdW5jYC4gVGhlXG4gICAgICogYGZ1bmNgIHByZWRpY2F0ZSBpcyBpbnZva2VkIHdpdGggdGhlIGB0aGlzYCBiaW5kaW5nIGFuZCBhcmd1bWVudHMgb2YgdGhlXG4gICAgICogY3JlYXRlZCBmdW5jdGlvbi5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAzLjAuMFxuICAgICAqIEBjYXRlZ29yeSBGdW5jdGlvblxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IHByZWRpY2F0ZSBUaGUgcHJlZGljYXRlIHRvIG5lZ2F0ZS5cbiAgICAgKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBuZWdhdGVkIGZ1bmN0aW9uLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBmdW5jdGlvbiBpc0V2ZW4obikge1xuICAgICAqICAgcmV0dXJuIG4gJSAyID09IDA7XG4gICAgICogfVxuICAgICAqXG4gICAgICogXy5maWx0ZXIoWzEsIDIsIDMsIDQsIDUsIDZdLCBfLm5lZ2F0ZShpc0V2ZW4pKTtcbiAgICAgKiAvLyA9PiBbMSwgMywgNV1cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBuZWdhdGUocHJlZGljYXRlKSB7XG4gICAgICBpZiAodHlwZW9mIHByZWRpY2F0ZSAhPSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoRlVOQ19FUlJPUl9URVhUKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBmdW5jdGlvbigpIHtcbiAgICAgICAgdmFyIGFyZ3MgPSBhcmd1bWVudHM7XG4gICAgICAgIHN3aXRjaCAoYXJncy5sZW5ndGgpIHtcbiAgICAgICAgICBjYXNlIDA6IHJldHVybiAhcHJlZGljYXRlLmNhbGwodGhpcyk7XG4gICAgICAgICAgY2FzZSAxOiByZXR1cm4gIXByZWRpY2F0ZS5jYWxsKHRoaXMsIGFyZ3NbMF0pO1xuICAgICAgICAgIGNhc2UgMjogcmV0dXJuICFwcmVkaWNhdGUuY2FsbCh0aGlzLCBhcmdzWzBdLCBhcmdzWzFdKTtcbiAgICAgICAgICBjYXNlIDM6IHJldHVybiAhcHJlZGljYXRlLmNhbGwodGhpcywgYXJnc1swXSwgYXJnc1sxXSwgYXJnc1syXSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuICFwcmVkaWNhdGUuYXBwbHkodGhpcywgYXJncyk7XG4gICAgICB9O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBmdW5jdGlvbiB0aGF0IGlzIHJlc3RyaWN0ZWQgdG8gaW52b2tpbmcgYGZ1bmNgIG9uY2UuIFJlcGVhdCBjYWxsc1xuICAgICAqIHRvIHRoZSBmdW5jdGlvbiByZXR1cm4gdGhlIHZhbHVlIG9mIHRoZSBmaXJzdCBpbnZvY2F0aW9uLiBUaGUgYGZ1bmNgIGlzXG4gICAgICogaW52b2tlZCB3aXRoIHRoZSBgdGhpc2AgYmluZGluZyBhbmQgYXJndW1lbnRzIG9mIHRoZSBjcmVhdGVkIGZ1bmN0aW9uLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDAuMS4wXG4gICAgICogQGNhdGVnb3J5IEZ1bmN0aW9uXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gZnVuYyBUaGUgZnVuY3Rpb24gdG8gcmVzdHJpY3QuXG4gICAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgcmVzdHJpY3RlZCBmdW5jdGlvbi5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIGluaXRpYWxpemUgPSBfLm9uY2UoY3JlYXRlQXBwbGljYXRpb24pO1xuICAgICAqIGluaXRpYWxpemUoKTtcbiAgICAgKiBpbml0aWFsaXplKCk7XG4gICAgICogLy8gPT4gYGNyZWF0ZUFwcGxpY2F0aW9uYCBpcyBpbnZva2VkIG9uY2VcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBvbmNlKGZ1bmMpIHtcbiAgICAgIHJldHVybiBiZWZvcmUoMiwgZnVuYyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIGZ1bmN0aW9uIHRoYXQgaW52b2tlcyBgZnVuY2Agd2l0aCBpdHMgYXJndW1lbnRzIHRyYW5zZm9ybWVkLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBzaW5jZSA0LjAuMFxuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQGNhdGVnb3J5IEZ1bmN0aW9uXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gZnVuYyBUaGUgZnVuY3Rpb24gdG8gd3JhcC5cbiAgICAgKiBAcGFyYW0gey4uLihGdW5jdGlvbnxGdW5jdGlvbltdKX0gW3RyYW5zZm9ybXM9W18uaWRlbnRpdHldXVxuICAgICAqICBUaGUgYXJndW1lbnQgdHJhbnNmb3Jtcy5cbiAgICAgKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBmdW5jdGlvbi5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogZnVuY3Rpb24gZG91YmxlZChuKSB7XG4gICAgICogICByZXR1cm4gbiAqIDI7XG4gICAgICogfVxuICAgICAqXG4gICAgICogZnVuY3Rpb24gc3F1YXJlKG4pIHtcbiAgICAgKiAgIHJldHVybiBuICogbjtcbiAgICAgKiB9XG4gICAgICpcbiAgICAgKiB2YXIgZnVuYyA9IF8ub3ZlckFyZ3MoZnVuY3Rpb24oeCwgeSkge1xuICAgICAqICAgcmV0dXJuIFt4LCB5XTtcbiAgICAgKiB9LCBbc3F1YXJlLCBkb3VibGVkXSk7XG4gICAgICpcbiAgICAgKiBmdW5jKDksIDMpO1xuICAgICAqIC8vID0+IFs4MSwgNl1cbiAgICAgKlxuICAgICAqIGZ1bmMoMTAsIDUpO1xuICAgICAqIC8vID0+IFsxMDAsIDEwXVxuICAgICAqL1xuICAgIHZhciBvdmVyQXJncyA9IGNhc3RSZXN0KGZ1bmN0aW9uKGZ1bmMsIHRyYW5zZm9ybXMpIHtcbiAgICAgIHRyYW5zZm9ybXMgPSAodHJhbnNmb3Jtcy5sZW5ndGggPT0gMSAmJiBpc0FycmF5KHRyYW5zZm9ybXNbMF0pKVxuICAgICAgICA/IGFycmF5TWFwKHRyYW5zZm9ybXNbMF0sIGJhc2VVbmFyeShnZXRJdGVyYXRlZSgpKSlcbiAgICAgICAgOiBhcnJheU1hcChiYXNlRmxhdHRlbih0cmFuc2Zvcm1zLCAxKSwgYmFzZVVuYXJ5KGdldEl0ZXJhdGVlKCkpKTtcblxuICAgICAgdmFyIGZ1bmNzTGVuZ3RoID0gdHJhbnNmb3Jtcy5sZW5ndGg7XG4gICAgICByZXR1cm4gYmFzZVJlc3QoZnVuY3Rpb24oYXJncykge1xuICAgICAgICB2YXIgaW5kZXggPSAtMSxcbiAgICAgICAgICAgIGxlbmd0aCA9IG5hdGl2ZU1pbihhcmdzLmxlbmd0aCwgZnVuY3NMZW5ndGgpO1xuXG4gICAgICAgIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XG4gICAgICAgICAgYXJnc1tpbmRleF0gPSB0cmFuc2Zvcm1zW2luZGV4XS5jYWxsKHRoaXMsIGFyZ3NbaW5kZXhdKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gYXBwbHkoZnVuYywgdGhpcywgYXJncyk7XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBmdW5jdGlvbiB0aGF0IGludm9rZXMgYGZ1bmNgIHdpdGggYHBhcnRpYWxzYCBwcmVwZW5kZWQgdG8gdGhlXG4gICAgICogYXJndW1lbnRzIGl0IHJlY2VpdmVzLiBUaGlzIG1ldGhvZCBpcyBsaWtlIGBfLmJpbmRgIGV4Y2VwdCBpdCBkb2VzICoqbm90KipcbiAgICAgKiBhbHRlciB0aGUgYHRoaXNgIGJpbmRpbmcuXG4gICAgICpcbiAgICAgKiBUaGUgYF8ucGFydGlhbC5wbGFjZWhvbGRlcmAgdmFsdWUsIHdoaWNoIGRlZmF1bHRzIHRvIGBfYCBpbiBtb25vbGl0aGljXG4gICAgICogYnVpbGRzLCBtYXkgYmUgdXNlZCBhcyBhIHBsYWNlaG9sZGVyIGZvciBwYXJ0aWFsbHkgYXBwbGllZCBhcmd1bWVudHMuXG4gICAgICpcbiAgICAgKiAqKk5vdGU6KiogVGhpcyBtZXRob2QgZG9lc24ndCBzZXQgdGhlIFwibGVuZ3RoXCIgcHJvcGVydHkgb2YgcGFydGlhbGx5XG4gICAgICogYXBwbGllZCBmdW5jdGlvbnMuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMC4yLjBcbiAgICAgKiBAY2F0ZWdvcnkgRnVuY3Rpb25cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byBwYXJ0aWFsbHkgYXBwbHkgYXJndW1lbnRzIHRvLlxuICAgICAqIEBwYXJhbSB7Li4uKn0gW3BhcnRpYWxzXSBUaGUgYXJndW1lbnRzIHRvIGJlIHBhcnRpYWxseSBhcHBsaWVkLlxuICAgICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IHBhcnRpYWxseSBhcHBsaWVkIGZ1bmN0aW9uLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBmdW5jdGlvbiBncmVldChncmVldGluZywgbmFtZSkge1xuICAgICAqICAgcmV0dXJuIGdyZWV0aW5nICsgJyAnICsgbmFtZTtcbiAgICAgKiB9XG4gICAgICpcbiAgICAgKiB2YXIgc2F5SGVsbG9UbyA9IF8ucGFydGlhbChncmVldCwgJ2hlbGxvJyk7XG4gICAgICogc2F5SGVsbG9UbygnZnJlZCcpO1xuICAgICAqIC8vID0+ICdoZWxsbyBmcmVkJ1xuICAgICAqXG4gICAgICogLy8gUGFydGlhbGx5IGFwcGxpZWQgd2l0aCBwbGFjZWhvbGRlcnMuXG4gICAgICogdmFyIGdyZWV0RnJlZCA9IF8ucGFydGlhbChncmVldCwgXywgJ2ZyZWQnKTtcbiAgICAgKiBncmVldEZyZWQoJ2hpJyk7XG4gICAgICogLy8gPT4gJ2hpIGZyZWQnXG4gICAgICovXG4gICAgdmFyIHBhcnRpYWwgPSBiYXNlUmVzdChmdW5jdGlvbihmdW5jLCBwYXJ0aWFscykge1xuICAgICAgdmFyIGhvbGRlcnMgPSByZXBsYWNlSG9sZGVycyhwYXJ0aWFscywgZ2V0SG9sZGVyKHBhcnRpYWwpKTtcbiAgICAgIHJldHVybiBjcmVhdGVXcmFwKGZ1bmMsIFdSQVBfUEFSVElBTF9GTEFHLCB1bmRlZmluZWQsIHBhcnRpYWxzLCBob2xkZXJzKTtcbiAgICB9KTtcblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIGlzIGxpa2UgYF8ucGFydGlhbGAgZXhjZXB0IHRoYXQgcGFydGlhbGx5IGFwcGxpZWQgYXJndW1lbnRzXG4gICAgICogYXJlIGFwcGVuZGVkIHRvIHRoZSBhcmd1bWVudHMgaXQgcmVjZWl2ZXMuXG4gICAgICpcbiAgICAgKiBUaGUgYF8ucGFydGlhbFJpZ2h0LnBsYWNlaG9sZGVyYCB2YWx1ZSwgd2hpY2ggZGVmYXVsdHMgdG8gYF9gIGluIG1vbm9saXRoaWNcbiAgICAgKiBidWlsZHMsIG1heSBiZSB1c2VkIGFzIGEgcGxhY2Vob2xkZXIgZm9yIHBhcnRpYWxseSBhcHBsaWVkIGFyZ3VtZW50cy5cbiAgICAgKlxuICAgICAqICoqTm90ZToqKiBUaGlzIG1ldGhvZCBkb2Vzbid0IHNldCB0aGUgXCJsZW5ndGhcIiBwcm9wZXJ0eSBvZiBwYXJ0aWFsbHlcbiAgICAgKiBhcHBsaWVkIGZ1bmN0aW9ucy5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAxLjAuMFxuICAgICAqIEBjYXRlZ29yeSBGdW5jdGlvblxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIHBhcnRpYWxseSBhcHBseSBhcmd1bWVudHMgdG8uXG4gICAgICogQHBhcmFtIHsuLi4qfSBbcGFydGlhbHNdIFRoZSBhcmd1bWVudHMgdG8gYmUgcGFydGlhbGx5IGFwcGxpZWQuXG4gICAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgcGFydGlhbGx5IGFwcGxpZWQgZnVuY3Rpb24uXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIGZ1bmN0aW9uIGdyZWV0KGdyZWV0aW5nLCBuYW1lKSB7XG4gICAgICogICByZXR1cm4gZ3JlZXRpbmcgKyAnICcgKyBuYW1lO1xuICAgICAqIH1cbiAgICAgKlxuICAgICAqIHZhciBncmVldEZyZWQgPSBfLnBhcnRpYWxSaWdodChncmVldCwgJ2ZyZWQnKTtcbiAgICAgKiBncmVldEZyZWQoJ2hpJyk7XG4gICAgICogLy8gPT4gJ2hpIGZyZWQnXG4gICAgICpcbiAgICAgKiAvLyBQYXJ0aWFsbHkgYXBwbGllZCB3aXRoIHBsYWNlaG9sZGVycy5cbiAgICAgKiB2YXIgc2F5SGVsbG9UbyA9IF8ucGFydGlhbFJpZ2h0KGdyZWV0LCAnaGVsbG8nLCBfKTtcbiAgICAgKiBzYXlIZWxsb1RvKCdmcmVkJyk7XG4gICAgICogLy8gPT4gJ2hlbGxvIGZyZWQnXG4gICAgICovXG4gICAgdmFyIHBhcnRpYWxSaWdodCA9IGJhc2VSZXN0KGZ1bmN0aW9uKGZ1bmMsIHBhcnRpYWxzKSB7XG4gICAgICB2YXIgaG9sZGVycyA9IHJlcGxhY2VIb2xkZXJzKHBhcnRpYWxzLCBnZXRIb2xkZXIocGFydGlhbFJpZ2h0KSk7XG4gICAgICByZXR1cm4gY3JlYXRlV3JhcChmdW5jLCBXUkFQX1BBUlRJQUxfUklHSFRfRkxBRywgdW5kZWZpbmVkLCBwYXJ0aWFscywgaG9sZGVycyk7XG4gICAgfSk7XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgZnVuY3Rpb24gdGhhdCBpbnZva2VzIGBmdW5jYCB3aXRoIGFyZ3VtZW50cyBhcnJhbmdlZCBhY2NvcmRpbmdcbiAgICAgKiB0byB0aGUgc3BlY2lmaWVkIGBpbmRleGVzYCB3aGVyZSB0aGUgYXJndW1lbnQgdmFsdWUgYXQgdGhlIGZpcnN0IGluZGV4IGlzXG4gICAgICogcHJvdmlkZWQgYXMgdGhlIGZpcnN0IGFyZ3VtZW50LCB0aGUgYXJndW1lbnQgdmFsdWUgYXQgdGhlIHNlY29uZCBpbmRleCBpc1xuICAgICAqIHByb3ZpZGVkIGFzIHRoZSBzZWNvbmQgYXJndW1lbnQsIGFuZCBzbyBvbi5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAzLjAuMFxuICAgICAqIEBjYXRlZ29yeSBGdW5jdGlvblxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIHJlYXJyYW5nZSBhcmd1bWVudHMgZm9yLlxuICAgICAqIEBwYXJhbSB7Li4uKG51bWJlcnxudW1iZXJbXSl9IGluZGV4ZXMgVGhlIGFycmFuZ2VkIGFyZ3VtZW50IGluZGV4ZXMuXG4gICAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgZnVuY3Rpb24uXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciByZWFyZ2VkID0gXy5yZWFyZyhmdW5jdGlvbihhLCBiLCBjKSB7XG4gICAgICogICByZXR1cm4gW2EsIGIsIGNdO1xuICAgICAqIH0sIFsyLCAwLCAxXSk7XG4gICAgICpcbiAgICAgKiByZWFyZ2VkKCdiJywgJ2MnLCAnYScpXG4gICAgICogLy8gPT4gWydhJywgJ2InLCAnYyddXG4gICAgICovXG4gICAgdmFyIHJlYXJnID0gZmxhdFJlc3QoZnVuY3Rpb24oZnVuYywgaW5kZXhlcykge1xuICAgICAgcmV0dXJuIGNyZWF0ZVdyYXAoZnVuYywgV1JBUF9SRUFSR19GTEFHLCB1bmRlZmluZWQsIHVuZGVmaW5lZCwgdW5kZWZpbmVkLCBpbmRleGVzKTtcbiAgICB9KTtcblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBmdW5jdGlvbiB0aGF0IGludm9rZXMgYGZ1bmNgIHdpdGggdGhlIGB0aGlzYCBiaW5kaW5nIG9mIHRoZVxuICAgICAqIGNyZWF0ZWQgZnVuY3Rpb24gYW5kIGFyZ3VtZW50cyBmcm9tIGBzdGFydGAgYW5kIGJleW9uZCBwcm92aWRlZCBhc1xuICAgICAqIGFuIGFycmF5LlxuICAgICAqXG4gICAgICogKipOb3RlOioqIFRoaXMgbWV0aG9kIGlzIGJhc2VkIG9uIHRoZVxuICAgICAqIFtyZXN0IHBhcmFtZXRlcl0oaHR0cHM6Ly9tZG4uaW8vcmVzdF9wYXJhbWV0ZXJzKS5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjAuMFxuICAgICAqIEBjYXRlZ29yeSBGdW5jdGlvblxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIGFwcGx5IGEgcmVzdCBwYXJhbWV0ZXIgdG8uXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtzdGFydD1mdW5jLmxlbmd0aC0xXSBUaGUgc3RhcnQgcG9zaXRpb24gb2YgdGhlIHJlc3QgcGFyYW1ldGVyLlxuICAgICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IGZ1bmN0aW9uLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgc2F5ID0gXy5yZXN0KGZ1bmN0aW9uKHdoYXQsIG5hbWVzKSB7XG4gICAgICogICByZXR1cm4gd2hhdCArICcgJyArIF8uaW5pdGlhbChuYW1lcykuam9pbignLCAnKSArXG4gICAgICogICAgIChfLnNpemUobmFtZXMpID4gMSA/ICcsICYgJyA6ICcnKSArIF8ubGFzdChuYW1lcyk7XG4gICAgICogfSk7XG4gICAgICpcbiAgICAgKiBzYXkoJ2hlbGxvJywgJ2ZyZWQnLCAnYmFybmV5JywgJ3BlYmJsZXMnKTtcbiAgICAgKiAvLyA9PiAnaGVsbG8gZnJlZCwgYmFybmV5LCAmIHBlYmJsZXMnXG4gICAgICovXG4gICAgZnVuY3Rpb24gcmVzdChmdW5jLCBzdGFydCkge1xuICAgICAgaWYgKHR5cGVvZiBmdW5jICE9ICdmdW5jdGlvbicpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihGVU5DX0VSUk9SX1RFWFQpO1xuICAgICAgfVxuICAgICAgc3RhcnQgPSBzdGFydCA9PT0gdW5kZWZpbmVkID8gc3RhcnQgOiB0b0ludGVnZXIoc3RhcnQpO1xuICAgICAgcmV0dXJuIGJhc2VSZXN0KGZ1bmMsIHN0YXJ0KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgZnVuY3Rpb24gdGhhdCBpbnZva2VzIGBmdW5jYCB3aXRoIHRoZSBgdGhpc2AgYmluZGluZyBvZiB0aGVcbiAgICAgKiBjcmVhdGUgZnVuY3Rpb24gYW5kIGFuIGFycmF5IG9mIGFyZ3VtZW50cyBtdWNoIGxpa2VcbiAgICAgKiBbYEZ1bmN0aW9uI2FwcGx5YF0oaHR0cDovL3d3dy5lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzcuMC8jc2VjLWZ1bmN0aW9uLnByb3RvdHlwZS5hcHBseSkuXG4gICAgICpcbiAgICAgKiAqKk5vdGU6KiogVGhpcyBtZXRob2QgaXMgYmFzZWQgb24gdGhlXG4gICAgICogW3NwcmVhZCBvcGVyYXRvcl0oaHR0cHM6Ly9tZG4uaW8vc3ByZWFkX29wZXJhdG9yKS5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAzLjIuMFxuICAgICAqIEBjYXRlZ29yeSBGdW5jdGlvblxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIHNwcmVhZCBhcmd1bWVudHMgb3Zlci5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW3N0YXJ0PTBdIFRoZSBzdGFydCBwb3NpdGlvbiBvZiB0aGUgc3ByZWFkLlxuICAgICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IGZ1bmN0aW9uLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgc2F5ID0gXy5zcHJlYWQoZnVuY3Rpb24od2hvLCB3aGF0KSB7XG4gICAgICogICByZXR1cm4gd2hvICsgJyBzYXlzICcgKyB3aGF0O1xuICAgICAqIH0pO1xuICAgICAqXG4gICAgICogc2F5KFsnZnJlZCcsICdoZWxsbyddKTtcbiAgICAgKiAvLyA9PiAnZnJlZCBzYXlzIGhlbGxvJ1xuICAgICAqXG4gICAgICogdmFyIG51bWJlcnMgPSBQcm9taXNlLmFsbChbXG4gICAgICogICBQcm9taXNlLnJlc29sdmUoNDApLFxuICAgICAqICAgUHJvbWlzZS5yZXNvbHZlKDM2KVxuICAgICAqIF0pO1xuICAgICAqXG4gICAgICogbnVtYmVycy50aGVuKF8uc3ByZWFkKGZ1bmN0aW9uKHgsIHkpIHtcbiAgICAgKiAgIHJldHVybiB4ICsgeTtcbiAgICAgKiB9KSk7XG4gICAgICogLy8gPT4gYSBQcm9taXNlIG9mIDc2XG4gICAgICovXG4gICAgZnVuY3Rpb24gc3ByZWFkKGZ1bmMsIHN0YXJ0KSB7XG4gICAgICBpZiAodHlwZW9mIGZ1bmMgIT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKEZVTkNfRVJST1JfVEVYVCk7XG4gICAgICB9XG4gICAgICBzdGFydCA9IHN0YXJ0ID09IG51bGwgPyAwIDogbmF0aXZlTWF4KHRvSW50ZWdlcihzdGFydCksIDApO1xuICAgICAgcmV0dXJuIGJhc2VSZXN0KGZ1bmN0aW9uKGFyZ3MpIHtcbiAgICAgICAgdmFyIGFycmF5ID0gYXJnc1tzdGFydF0sXG4gICAgICAgICAgICBvdGhlckFyZ3MgPSBjYXN0U2xpY2UoYXJncywgMCwgc3RhcnQpO1xuXG4gICAgICAgIGlmIChhcnJheSkge1xuICAgICAgICAgIGFycmF5UHVzaChvdGhlckFyZ3MsIGFycmF5KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gYXBwbHkoZnVuYywgdGhpcywgb3RoZXJBcmdzKTtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSB0aHJvdHRsZWQgZnVuY3Rpb24gdGhhdCBvbmx5IGludm9rZXMgYGZ1bmNgIGF0IG1vc3Qgb25jZSBwZXJcbiAgICAgKiBldmVyeSBgd2FpdGAgbWlsbGlzZWNvbmRzLiBUaGUgdGhyb3R0bGVkIGZ1bmN0aW9uIGNvbWVzIHdpdGggYSBgY2FuY2VsYFxuICAgICAqIG1ldGhvZCB0byBjYW5jZWwgZGVsYXllZCBgZnVuY2AgaW52b2NhdGlvbnMgYW5kIGEgYGZsdXNoYCBtZXRob2QgdG9cbiAgICAgKiBpbW1lZGlhdGVseSBpbnZva2UgdGhlbS4gUHJvdmlkZSBgb3B0aW9uc2AgdG8gaW5kaWNhdGUgd2hldGhlciBgZnVuY2BcbiAgICAgKiBzaG91bGQgYmUgaW52b2tlZCBvbiB0aGUgbGVhZGluZyBhbmQvb3IgdHJhaWxpbmcgZWRnZSBvZiB0aGUgYHdhaXRgXG4gICAgICogdGltZW91dC4gVGhlIGBmdW5jYCBpcyBpbnZva2VkIHdpdGggdGhlIGxhc3QgYXJndW1lbnRzIHByb3ZpZGVkIHRvIHRoZVxuICAgICAqIHRocm90dGxlZCBmdW5jdGlvbi4gU3Vic2VxdWVudCBjYWxscyB0byB0aGUgdGhyb3R0bGVkIGZ1bmN0aW9uIHJldHVybiB0aGVcbiAgICAgKiByZXN1bHQgb2YgdGhlIGxhc3QgYGZ1bmNgIGludm9jYXRpb24uXG4gICAgICpcbiAgICAgKiAqKk5vdGU6KiogSWYgYGxlYWRpbmdgIGFuZCBgdHJhaWxpbmdgIG9wdGlvbnMgYXJlIGB0cnVlYCwgYGZ1bmNgIGlzXG4gICAgICogaW52b2tlZCBvbiB0aGUgdHJhaWxpbmcgZWRnZSBvZiB0aGUgdGltZW91dCBvbmx5IGlmIHRoZSB0aHJvdHRsZWQgZnVuY3Rpb25cbiAgICAgKiBpcyBpbnZva2VkIG1vcmUgdGhhbiBvbmNlIGR1cmluZyB0aGUgYHdhaXRgIHRpbWVvdXQuXG4gICAgICpcbiAgICAgKiBJZiBgd2FpdGAgaXMgYDBgIGFuZCBgbGVhZGluZ2AgaXMgYGZhbHNlYCwgYGZ1bmNgIGludm9jYXRpb24gaXMgZGVmZXJyZWRcbiAgICAgKiB1bnRpbCB0byB0aGUgbmV4dCB0aWNrLCBzaW1pbGFyIHRvIGBzZXRUaW1lb3V0YCB3aXRoIGEgdGltZW91dCBvZiBgMGAuXG4gICAgICpcbiAgICAgKiBTZWUgW0RhdmlkIENvcmJhY2hvJ3MgYXJ0aWNsZV0oaHR0cHM6Ly9jc3MtdHJpY2tzLmNvbS9kZWJvdW5jaW5nLXRocm90dGxpbmctZXhwbGFpbmVkLWV4YW1wbGVzLylcbiAgICAgKiBmb3IgZGV0YWlscyBvdmVyIHRoZSBkaWZmZXJlbmNlcyBiZXR3ZWVuIGBfLnRocm90dGxlYCBhbmQgYF8uZGVib3VuY2VgLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDAuMS4wXG4gICAgICogQGNhdGVnb3J5IEZ1bmN0aW9uXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gZnVuYyBUaGUgZnVuY3Rpb24gdG8gdGhyb3R0bGUuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFt3YWl0PTBdIFRoZSBudW1iZXIgb2YgbWlsbGlzZWNvbmRzIHRvIHRocm90dGxlIGludm9jYXRpb25zIHRvLlxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBbb3B0aW9ucz17fV0gVGhlIG9wdGlvbnMgb2JqZWN0LlxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbn0gW29wdGlvbnMubGVhZGluZz10cnVlXVxuICAgICAqICBTcGVjaWZ5IGludm9raW5nIG9uIHRoZSBsZWFkaW5nIGVkZ2Ugb2YgdGhlIHRpbWVvdXQuXG4gICAgICogQHBhcmFtIHtib29sZWFufSBbb3B0aW9ucy50cmFpbGluZz10cnVlXVxuICAgICAqICBTcGVjaWZ5IGludm9raW5nIG9uIHRoZSB0cmFpbGluZyBlZGdlIG9mIHRoZSB0aW1lb3V0LlxuICAgICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IHRocm90dGxlZCBmdW5jdGlvbi5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogLy8gQXZvaWQgZXhjZXNzaXZlbHkgdXBkYXRpbmcgdGhlIHBvc2l0aW9uIHdoaWxlIHNjcm9sbGluZy5cbiAgICAgKiBqUXVlcnkod2luZG93KS5vbignc2Nyb2xsJywgXy50aHJvdHRsZSh1cGRhdGVQb3NpdGlvbiwgMTAwKSk7XG4gICAgICpcbiAgICAgKiAvLyBJbnZva2UgYHJlbmV3VG9rZW5gIHdoZW4gdGhlIGNsaWNrIGV2ZW50IGlzIGZpcmVkLCBidXQgbm90IG1vcmUgdGhhbiBvbmNlIGV2ZXJ5IDUgbWludXRlcy5cbiAgICAgKiB2YXIgdGhyb3R0bGVkID0gXy50aHJvdHRsZShyZW5ld1Rva2VuLCAzMDAwMDAsIHsgJ3RyYWlsaW5nJzogZmFsc2UgfSk7XG4gICAgICogalF1ZXJ5KGVsZW1lbnQpLm9uKCdjbGljaycsIHRocm90dGxlZCk7XG4gICAgICpcbiAgICAgKiAvLyBDYW5jZWwgdGhlIHRyYWlsaW5nIHRocm90dGxlZCBpbnZvY2F0aW9uLlxuICAgICAqIGpRdWVyeSh3aW5kb3cpLm9uKCdwb3BzdGF0ZScsIHRocm90dGxlZC5jYW5jZWwpO1xuICAgICAqL1xuICAgIGZ1bmN0aW9uIHRocm90dGxlKGZ1bmMsIHdhaXQsIG9wdGlvbnMpIHtcbiAgICAgIHZhciBsZWFkaW5nID0gdHJ1ZSxcbiAgICAgICAgICB0cmFpbGluZyA9IHRydWU7XG5cbiAgICAgIGlmICh0eXBlb2YgZnVuYyAhPSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoRlVOQ19FUlJPUl9URVhUKTtcbiAgICAgIH1cbiAgICAgIGlmIChpc09iamVjdChvcHRpb25zKSkge1xuICAgICAgICBsZWFkaW5nID0gJ2xlYWRpbmcnIGluIG9wdGlvbnMgPyAhIW9wdGlvbnMubGVhZGluZyA6IGxlYWRpbmc7XG4gICAgICAgIHRyYWlsaW5nID0gJ3RyYWlsaW5nJyBpbiBvcHRpb25zID8gISFvcHRpb25zLnRyYWlsaW5nIDogdHJhaWxpbmc7XG4gICAgICB9XG4gICAgICByZXR1cm4gZGVib3VuY2UoZnVuYywgd2FpdCwge1xuICAgICAgICAnbGVhZGluZyc6IGxlYWRpbmcsXG4gICAgICAgICdtYXhXYWl0Jzogd2FpdCxcbiAgICAgICAgJ3RyYWlsaW5nJzogdHJhaWxpbmdcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBmdW5jdGlvbiB0aGF0IGFjY2VwdHMgdXAgdG8gb25lIGFyZ3VtZW50LCBpZ25vcmluZyBhbnlcbiAgICAgKiBhZGRpdGlvbmFsIGFyZ3VtZW50cy5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjAuMFxuICAgICAqIEBjYXRlZ29yeSBGdW5jdGlvblxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIGNhcCBhcmd1bWVudHMgZm9yLlxuICAgICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IGNhcHBlZCBmdW5jdGlvbi5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5tYXAoWyc2JywgJzgnLCAnMTAnXSwgXy51bmFyeShwYXJzZUludCkpO1xuICAgICAqIC8vID0+IFs2LCA4LCAxMF1cbiAgICAgKi9cbiAgICBmdW5jdGlvbiB1bmFyeShmdW5jKSB7XG4gICAgICByZXR1cm4gYXJ5KGZ1bmMsIDEpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBmdW5jdGlvbiB0aGF0IHByb3ZpZGVzIGB2YWx1ZWAgdG8gYHdyYXBwZXJgIGFzIGl0cyBmaXJzdFxuICAgICAqIGFyZ3VtZW50LiBBbnkgYWRkaXRpb25hbCBhcmd1bWVudHMgcHJvdmlkZWQgdG8gdGhlIGZ1bmN0aW9uIGFyZSBhcHBlbmRlZFxuICAgICAqIHRvIHRob3NlIHByb3ZpZGVkIHRvIHRoZSBgd3JhcHBlcmAuIFRoZSB3cmFwcGVyIGlzIGludm9rZWQgd2l0aCB0aGUgYHRoaXNgXG4gICAgICogYmluZGluZyBvZiB0aGUgY3JlYXRlZCBmdW5jdGlvbi5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAwLjEuMFxuICAgICAqIEBjYXRlZ29yeSBGdW5jdGlvblxuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIHdyYXAuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW3dyYXBwZXI9aWRlbnRpdHldIFRoZSB3cmFwcGVyIGZ1bmN0aW9uLlxuICAgICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IGZ1bmN0aW9uLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgcCA9IF8ud3JhcChfLmVzY2FwZSwgZnVuY3Rpb24oZnVuYywgdGV4dCkge1xuICAgICAqICAgcmV0dXJuICc8cD4nICsgZnVuYyh0ZXh0KSArICc8L3A+JztcbiAgICAgKiB9KTtcbiAgICAgKlxuICAgICAqIHAoJ2ZyZWQsIGJhcm5leSwgJiBwZWJibGVzJyk7XG4gICAgICogLy8gPT4gJzxwPmZyZWQsIGJhcm5leSwgJmFtcDsgcGViYmxlczwvcD4nXG4gICAgICovXG4gICAgZnVuY3Rpb24gd3JhcCh2YWx1ZSwgd3JhcHBlcikge1xuICAgICAgcmV0dXJuIHBhcnRpYWwoY2FzdEZ1bmN0aW9uKHdyYXBwZXIpLCB2YWx1ZSk7XG4gICAgfVxuXG4gICAgLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuXG4gICAgLyoqXG4gICAgICogQ2FzdHMgYHZhbHVlYCBhcyBhbiBhcnJheSBpZiBpdCdzIG5vdCBvbmUuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC40LjBcbiAgICAgKiBAY2F0ZWdvcnkgTGFuZ1xuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGluc3BlY3QuXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBjYXN0IGFycmF5LlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLmNhc3RBcnJheSgxKTtcbiAgICAgKiAvLyA9PiBbMV1cbiAgICAgKlxuICAgICAqIF8uY2FzdEFycmF5KHsgJ2EnOiAxIH0pO1xuICAgICAqIC8vID0+IFt7ICdhJzogMSB9XVxuICAgICAqXG4gICAgICogXy5jYXN0QXJyYXkoJ2FiYycpO1xuICAgICAqIC8vID0+IFsnYWJjJ11cbiAgICAgKlxuICAgICAqIF8uY2FzdEFycmF5KG51bGwpO1xuICAgICAqIC8vID0+IFtudWxsXVxuICAgICAqXG4gICAgICogXy5jYXN0QXJyYXkodW5kZWZpbmVkKTtcbiAgICAgKiAvLyA9PiBbdW5kZWZpbmVkXVxuICAgICAqXG4gICAgICogXy5jYXN0QXJyYXkoKTtcbiAgICAgKiAvLyA9PiBbXVxuICAgICAqXG4gICAgICogdmFyIGFycmF5ID0gWzEsIDIsIDNdO1xuICAgICAqIGNvbnNvbGUubG9nKF8uY2FzdEFycmF5KGFycmF5KSA9PT0gYXJyYXkpO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBjYXN0QXJyYXkoKSB7XG4gICAgICBpZiAoIWFyZ3VtZW50cy5sZW5ndGgpIHtcbiAgICAgICAgcmV0dXJuIFtdO1xuICAgICAgfVxuICAgICAgdmFyIHZhbHVlID0gYXJndW1lbnRzWzBdO1xuICAgICAgcmV0dXJuIGlzQXJyYXkodmFsdWUpID8gdmFsdWUgOiBbdmFsdWVdO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBzaGFsbG93IGNsb25lIG9mIGB2YWx1ZWAuXG4gICAgICpcbiAgICAgKiAqKk5vdGU6KiogVGhpcyBtZXRob2QgaXMgbG9vc2VseSBiYXNlZCBvbiB0aGVcbiAgICAgKiBbc3RydWN0dXJlZCBjbG9uZSBhbGdvcml0aG1dKGh0dHBzOi8vbWRuLmlvL1N0cnVjdHVyZWRfY2xvbmVfYWxnb3JpdGhtKVxuICAgICAqIGFuZCBzdXBwb3J0cyBjbG9uaW5nIGFycmF5cywgYXJyYXkgYnVmZmVycywgYm9vbGVhbnMsIGRhdGUgb2JqZWN0cywgbWFwcyxcbiAgICAgKiBudW1iZXJzLCBgT2JqZWN0YCBvYmplY3RzLCByZWdleGVzLCBzZXRzLCBzdHJpbmdzLCBzeW1ib2xzLCBhbmQgdHlwZWRcbiAgICAgKiBhcnJheXMuIFRoZSBvd24gZW51bWVyYWJsZSBwcm9wZXJ0aWVzIG9mIGBhcmd1bWVudHNgIG9iamVjdHMgYXJlIGNsb25lZFxuICAgICAqIGFzIHBsYWluIG9iamVjdHMuIEFuIGVtcHR5IG9iamVjdCBpcyByZXR1cm5lZCBmb3IgdW5jbG9uZWFibGUgdmFsdWVzIHN1Y2hcbiAgICAgKiBhcyBlcnJvciBvYmplY3RzLCBmdW5jdGlvbnMsIERPTSBub2RlcywgYW5kIFdlYWtNYXBzLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDAuMS4wXG4gICAgICogQGNhdGVnb3J5IExhbmdcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjbG9uZS5cbiAgICAgKiBAcmV0dXJucyB7Kn0gUmV0dXJucyB0aGUgY2xvbmVkIHZhbHVlLlxuICAgICAqIEBzZWUgXy5jbG9uZURlZXBcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIG9iamVjdHMgPSBbeyAnYSc6IDEgfSwgeyAnYic6IDIgfV07XG4gICAgICpcbiAgICAgKiB2YXIgc2hhbGxvdyA9IF8uY2xvbmUob2JqZWN0cyk7XG4gICAgICogY29uc29sZS5sb2coc2hhbGxvd1swXSA9PT0gb2JqZWN0c1swXSk7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGNsb25lKHZhbHVlKSB7XG4gICAgICByZXR1cm4gYmFzZUNsb25lKHZhbHVlLCBDTE9ORV9TWU1CT0xTX0ZMQUcpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIGlzIGxpa2UgYF8uY2xvbmVgIGV4Y2VwdCB0aGF0IGl0IGFjY2VwdHMgYGN1c3RvbWl6ZXJgIHdoaWNoXG4gICAgICogaXMgaW52b2tlZCB0byBwcm9kdWNlIHRoZSBjbG9uZWQgdmFsdWUuIElmIGBjdXN0b21pemVyYCByZXR1cm5zIGB1bmRlZmluZWRgLFxuICAgICAqIGNsb25pbmcgaXMgaGFuZGxlZCBieSB0aGUgbWV0aG9kIGluc3RlYWQuIFRoZSBgY3VzdG9taXplcmAgaXMgaW52b2tlZCB3aXRoXG4gICAgICogdXAgdG8gZm91ciBhcmd1bWVudHM7ICh2YWx1ZSBbLCBpbmRleHxrZXksIG9iamVjdCwgc3RhY2tdKS5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjAuMFxuICAgICAqIEBjYXRlZ29yeSBMYW5nXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2xvbmUuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW2N1c3RvbWl6ZXJdIFRoZSBmdW5jdGlvbiB0byBjdXN0b21pemUgY2xvbmluZy5cbiAgICAgKiBAcmV0dXJucyB7Kn0gUmV0dXJucyB0aGUgY2xvbmVkIHZhbHVlLlxuICAgICAqIEBzZWUgXy5jbG9uZURlZXBXaXRoXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIGZ1bmN0aW9uIGN1c3RvbWl6ZXIodmFsdWUpIHtcbiAgICAgKiAgIGlmIChfLmlzRWxlbWVudCh2YWx1ZSkpIHtcbiAgICAgKiAgICAgcmV0dXJuIHZhbHVlLmNsb25lTm9kZShmYWxzZSk7XG4gICAgICogICB9XG4gICAgICogfVxuICAgICAqXG4gICAgICogdmFyIGVsID0gXy5jbG9uZVdpdGgoZG9jdW1lbnQuYm9keSwgY3VzdG9taXplcik7XG4gICAgICpcbiAgICAgKiBjb25zb2xlLmxvZyhlbCA9PT0gZG9jdW1lbnQuYm9keSk7XG4gICAgICogLy8gPT4gZmFsc2VcbiAgICAgKiBjb25zb2xlLmxvZyhlbC5ub2RlTmFtZSk7XG4gICAgICogLy8gPT4gJ0JPRFknXG4gICAgICogY29uc29sZS5sb2coZWwuY2hpbGROb2Rlcy5sZW5ndGgpO1xuICAgICAqIC8vID0+IDBcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBjbG9uZVdpdGgodmFsdWUsIGN1c3RvbWl6ZXIpIHtcbiAgICAgIGN1c3RvbWl6ZXIgPSB0eXBlb2YgY3VzdG9taXplciA9PSAnZnVuY3Rpb24nID8gY3VzdG9taXplciA6IHVuZGVmaW5lZDtcbiAgICAgIHJldHVybiBiYXNlQ2xvbmUodmFsdWUsIENMT05FX1NZTUJPTFNfRkxBRywgY3VzdG9taXplcik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgaXMgbGlrZSBgXy5jbG9uZWAgZXhjZXB0IHRoYXQgaXQgcmVjdXJzaXZlbHkgY2xvbmVzIGB2YWx1ZWAuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMS4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgTGFuZ1xuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIHJlY3Vyc2l2ZWx5IGNsb25lLlxuICAgICAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSBkZWVwIGNsb25lZCB2YWx1ZS5cbiAgICAgKiBAc2VlIF8uY2xvbmVcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIG9iamVjdHMgPSBbeyAnYSc6IDEgfSwgeyAnYic6IDIgfV07XG4gICAgICpcbiAgICAgKiB2YXIgZGVlcCA9IF8uY2xvbmVEZWVwKG9iamVjdHMpO1xuICAgICAqIGNvbnNvbGUubG9nKGRlZXBbMF0gPT09IG9iamVjdHNbMF0pO1xuICAgICAqIC8vID0+IGZhbHNlXG4gICAgICovXG4gICAgZnVuY3Rpb24gY2xvbmVEZWVwKHZhbHVlKSB7XG4gICAgICByZXR1cm4gYmFzZUNsb25lKHZhbHVlLCBDTE9ORV9ERUVQX0ZMQUcgfCBDTE9ORV9TWU1CT0xTX0ZMQUcpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIGlzIGxpa2UgYF8uY2xvbmVXaXRoYCBleGNlcHQgdGhhdCBpdCByZWN1cnNpdmVseSBjbG9uZXMgYHZhbHVlYC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjAuMFxuICAgICAqIEBjYXRlZ29yeSBMYW5nXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gcmVjdXJzaXZlbHkgY2xvbmUuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW2N1c3RvbWl6ZXJdIFRoZSBmdW5jdGlvbiB0byBjdXN0b21pemUgY2xvbmluZy5cbiAgICAgKiBAcmV0dXJucyB7Kn0gUmV0dXJucyB0aGUgZGVlcCBjbG9uZWQgdmFsdWUuXG4gICAgICogQHNlZSBfLmNsb25lV2l0aFxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBmdW5jdGlvbiBjdXN0b21pemVyKHZhbHVlKSB7XG4gICAgICogICBpZiAoXy5pc0VsZW1lbnQodmFsdWUpKSB7XG4gICAgICogICAgIHJldHVybiB2YWx1ZS5jbG9uZU5vZGUodHJ1ZSk7XG4gICAgICogICB9XG4gICAgICogfVxuICAgICAqXG4gICAgICogdmFyIGVsID0gXy5jbG9uZURlZXBXaXRoKGRvY3VtZW50LmJvZHksIGN1c3RvbWl6ZXIpO1xuICAgICAqXG4gICAgICogY29uc29sZS5sb2coZWwgPT09IGRvY3VtZW50LmJvZHkpO1xuICAgICAqIC8vID0+IGZhbHNlXG4gICAgICogY29uc29sZS5sb2coZWwubm9kZU5hbWUpO1xuICAgICAqIC8vID0+ICdCT0RZJ1xuICAgICAqIGNvbnNvbGUubG9nKGVsLmNoaWxkTm9kZXMubGVuZ3RoKTtcbiAgICAgKiAvLyA9PiAyMFxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGNsb25lRGVlcFdpdGgodmFsdWUsIGN1c3RvbWl6ZXIpIHtcbiAgICAgIGN1c3RvbWl6ZXIgPSB0eXBlb2YgY3VzdG9taXplciA9PSAnZnVuY3Rpb24nID8gY3VzdG9taXplciA6IHVuZGVmaW5lZDtcbiAgICAgIHJldHVybiBiYXNlQ2xvbmUodmFsdWUsIENMT05FX0RFRVBfRkxBRyB8IENMT05FX1NZTUJPTFNfRkxBRywgY3VzdG9taXplcik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2hlY2tzIGlmIGBvYmplY3RgIGNvbmZvcm1zIHRvIGBzb3VyY2VgIGJ5IGludm9raW5nIHRoZSBwcmVkaWNhdGVcbiAgICAgKiBwcm9wZXJ0aWVzIG9mIGBzb3VyY2VgIHdpdGggdGhlIGNvcnJlc3BvbmRpbmcgcHJvcGVydHkgdmFsdWVzIG9mIGBvYmplY3RgLlxuICAgICAqXG4gICAgICogKipOb3RlOioqIFRoaXMgbWV0aG9kIGlzIGVxdWl2YWxlbnQgdG8gYF8uY29uZm9ybXNgIHdoZW4gYHNvdXJjZWAgaXNcbiAgICAgKiBwYXJ0aWFsbHkgYXBwbGllZC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjE0LjBcbiAgICAgKiBAY2F0ZWdvcnkgTGFuZ1xuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBpbnNwZWN0LlxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBzb3VyY2UgVGhlIG9iamVjdCBvZiBwcm9wZXJ0eSBwcmVkaWNhdGVzIHRvIGNvbmZvcm0gdG8uXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGBvYmplY3RgIGNvbmZvcm1zLCBlbHNlIGBmYWxzZWAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciBvYmplY3QgPSB7ICdhJzogMSwgJ2InOiAyIH07XG4gICAgICpcbiAgICAgKiBfLmNvbmZvcm1zVG8ob2JqZWN0LCB7ICdiJzogZnVuY3Rpb24obikgeyByZXR1cm4gbiA+IDE7IH0gfSk7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqXG4gICAgICogXy5jb25mb3Jtc1RvKG9iamVjdCwgeyAnYic6IGZ1bmN0aW9uKG4pIHsgcmV0dXJuIG4gPiAyOyB9IH0pO1xuICAgICAqIC8vID0+IGZhbHNlXG4gICAgICovXG4gICAgZnVuY3Rpb24gY29uZm9ybXNUbyhvYmplY3QsIHNvdXJjZSkge1xuICAgICAgcmV0dXJuIHNvdXJjZSA9PSBudWxsIHx8IGJhc2VDb25mb3Jtc1RvKG9iamVjdCwgc291cmNlLCBrZXlzKHNvdXJjZSkpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFBlcmZvcm1zIGFcbiAgICAgKiBbYFNhbWVWYWx1ZVplcm9gXShodHRwOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi83LjAvI3NlYy1zYW1ldmFsdWV6ZXJvKVxuICAgICAqIGNvbXBhcmlzb24gYmV0d2VlbiB0d28gdmFsdWVzIHRvIGRldGVybWluZSBpZiB0aGV5IGFyZSBlcXVpdmFsZW50LlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMC4wXG4gICAgICogQGNhdGVnb3J5IExhbmdcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjb21wYXJlLlxuICAgICAqIEBwYXJhbSB7Kn0gb3RoZXIgVGhlIG90aGVyIHZhbHVlIHRvIGNvbXBhcmUuXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIHRoZSB2YWx1ZXMgYXJlIGVxdWl2YWxlbnQsIGVsc2UgYGZhbHNlYC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIG9iamVjdCA9IHsgJ2EnOiAxIH07XG4gICAgICogdmFyIG90aGVyID0geyAnYSc6IDEgfTtcbiAgICAgKlxuICAgICAqIF8uZXEob2JqZWN0LCBvYmplY3QpO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKlxuICAgICAqIF8uZXEob2JqZWN0LCBvdGhlcik7XG4gICAgICogLy8gPT4gZmFsc2VcbiAgICAgKlxuICAgICAqIF8uZXEoJ2EnLCAnYScpO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKlxuICAgICAqIF8uZXEoJ2EnLCBPYmplY3QoJ2EnKSk7XG4gICAgICogLy8gPT4gZmFsc2VcbiAgICAgKlxuICAgICAqIF8uZXEoTmFOLCBOYU4pO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBlcSh2YWx1ZSwgb3RoZXIpIHtcbiAgICAgIHJldHVybiB2YWx1ZSA9PT0gb3RoZXIgfHwgKHZhbHVlICE9PSB2YWx1ZSAmJiBvdGhlciAhPT0gb3RoZXIpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIGdyZWF0ZXIgdGhhbiBgb3RoZXJgLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDMuOS4wXG4gICAgICogQGNhdGVnb3J5IExhbmdcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjb21wYXJlLlxuICAgICAqIEBwYXJhbSB7Kn0gb3RoZXIgVGhlIG90aGVyIHZhbHVlIHRvIGNvbXBhcmUuXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgZ3JlYXRlciB0aGFuIGBvdGhlcmAsXG4gICAgICogIGVsc2UgYGZhbHNlYC5cbiAgICAgKiBAc2VlIF8ubHRcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5ndCgzLCAxKTtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICpcbiAgICAgKiBfLmd0KDMsIDMpO1xuICAgICAqIC8vID0+IGZhbHNlXG4gICAgICpcbiAgICAgKiBfLmd0KDEsIDMpO1xuICAgICAqIC8vID0+IGZhbHNlXG4gICAgICovXG4gICAgdmFyIGd0ID0gY3JlYXRlUmVsYXRpb25hbE9wZXJhdGlvbihiYXNlR3QpO1xuXG4gICAgLyoqXG4gICAgICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvIGBvdGhlcmAuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMy45LjBcbiAgICAgKiBAY2F0ZWdvcnkgTGFuZ1xuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNvbXBhcmUuXG4gICAgICogQHBhcmFtIHsqfSBvdGhlciBUaGUgb3RoZXIgdmFsdWUgdG8gY29tcGFyZS5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG9cbiAgICAgKiAgYG90aGVyYCwgZWxzZSBgZmFsc2VgLlxuICAgICAqIEBzZWUgXy5sdGVcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5ndGUoMywgMSk7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqXG4gICAgICogXy5ndGUoMywgMyk7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqXG4gICAgICogXy5ndGUoMSwgMyk7XG4gICAgICogLy8gPT4gZmFsc2VcbiAgICAgKi9cbiAgICB2YXIgZ3RlID0gY3JlYXRlUmVsYXRpb25hbE9wZXJhdGlvbihmdW5jdGlvbih2YWx1ZSwgb3RoZXIpIHtcbiAgICAgIHJldHVybiB2YWx1ZSA+PSBvdGhlcjtcbiAgICB9KTtcblxuICAgIC8qKlxuICAgICAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIGxpa2VseSBhbiBgYXJndW1lbnRzYCBvYmplY3QuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMC4xLjBcbiAgICAgKiBAY2F0ZWdvcnkgTGFuZ1xuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGFuIGBhcmd1bWVudHNgIG9iamVjdCxcbiAgICAgKiAgZWxzZSBgZmFsc2VgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLmlzQXJndW1lbnRzKGZ1bmN0aW9uKCkgeyByZXR1cm4gYXJndW1lbnRzOyB9KCkpO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKlxuICAgICAqIF8uaXNBcmd1bWVudHMoWzEsIDIsIDNdKTtcbiAgICAgKiAvLyA9PiBmYWxzZVxuICAgICAqL1xuICAgIHZhciBpc0FyZ3VtZW50cyA9IGJhc2VJc0FyZ3VtZW50cyhmdW5jdGlvbigpIHsgcmV0dXJuIGFyZ3VtZW50czsgfSgpKSA/IGJhc2VJc0FyZ3VtZW50cyA6IGZ1bmN0aW9uKHZhbHVlKSB7XG4gICAgICByZXR1cm4gaXNPYmplY3RMaWtlKHZhbHVlKSAmJiBoYXNPd25Qcm9wZXJ0eS5jYWxsKHZhbHVlLCAnY2FsbGVlJykgJiZcbiAgICAgICAgIXByb3BlcnR5SXNFbnVtZXJhYmxlLmNhbGwodmFsdWUsICdjYWxsZWUnKTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgY2xhc3NpZmllZCBhcyBhbiBgQXJyYXlgIG9iamVjdC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAwLjEuMFxuICAgICAqIEBjYXRlZ29yeSBMYW5nXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgYW4gYXJyYXksIGVsc2UgYGZhbHNlYC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5pc0FycmF5KFsxLCAyLCAzXSk7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqXG4gICAgICogXy5pc0FycmF5KGRvY3VtZW50LmJvZHkuY2hpbGRyZW4pO1xuICAgICAqIC8vID0+IGZhbHNlXG4gICAgICpcbiAgICAgKiBfLmlzQXJyYXkoJ2FiYycpO1xuICAgICAqIC8vID0+IGZhbHNlXG4gICAgICpcbiAgICAgKiBfLmlzQXJyYXkoXy5ub29wKTtcbiAgICAgKiAvLyA9PiBmYWxzZVxuICAgICAqL1xuICAgIHZhciBpc0FycmF5ID0gQXJyYXkuaXNBcnJheTtcblxuICAgIC8qKlxuICAgICAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIGNsYXNzaWZpZWQgYXMgYW4gYEFycmF5QnVmZmVyYCBvYmplY3QuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4zLjBcbiAgICAgKiBAY2F0ZWdvcnkgTGFuZ1xuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGFuIGFycmF5IGJ1ZmZlciwgZWxzZSBgZmFsc2VgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLmlzQXJyYXlCdWZmZXIobmV3IEFycmF5QnVmZmVyKDIpKTtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICpcbiAgICAgKiBfLmlzQXJyYXlCdWZmZXIobmV3IEFycmF5KDIpKTtcbiAgICAgKiAvLyA9PiBmYWxzZVxuICAgICAqL1xuICAgIHZhciBpc0FycmF5QnVmZmVyID0gbm9kZUlzQXJyYXlCdWZmZXIgPyBiYXNlVW5hcnkobm9kZUlzQXJyYXlCdWZmZXIpIDogYmFzZUlzQXJyYXlCdWZmZXI7XG5cbiAgICAvKipcbiAgICAgKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBhcnJheS1saWtlLiBBIHZhbHVlIGlzIGNvbnNpZGVyZWQgYXJyYXktbGlrZSBpZiBpdCdzXG4gICAgICogbm90IGEgZnVuY3Rpb24gYW5kIGhhcyBhIGB2YWx1ZS5sZW5ndGhgIHRoYXQncyBhbiBpbnRlZ2VyIGdyZWF0ZXIgdGhhbiBvclxuICAgICAqIGVxdWFsIHRvIGAwYCBhbmQgbGVzcyB0aGFuIG9yIGVxdWFsIHRvIGBOdW1iZXIuTUFYX1NBRkVfSU5URUdFUmAuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgTGFuZ1xuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGFycmF5LWxpa2UsIGVsc2UgYGZhbHNlYC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5pc0FycmF5TGlrZShbMSwgMiwgM10pO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKlxuICAgICAqIF8uaXNBcnJheUxpa2UoZG9jdW1lbnQuYm9keS5jaGlsZHJlbik7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqXG4gICAgICogXy5pc0FycmF5TGlrZSgnYWJjJyk7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqXG4gICAgICogXy5pc0FycmF5TGlrZShfLm5vb3ApO1xuICAgICAqIC8vID0+IGZhbHNlXG4gICAgICovXG4gICAgZnVuY3Rpb24gaXNBcnJheUxpa2UodmFsdWUpIHtcbiAgICAgIHJldHVybiB2YWx1ZSAhPSBudWxsICYmIGlzTGVuZ3RoKHZhbHVlLmxlbmd0aCkgJiYgIWlzRnVuY3Rpb24odmFsdWUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIGlzIGxpa2UgYF8uaXNBcnJheUxpa2VgIGV4Y2VwdCB0aGF0IGl0IGFsc28gY2hlY2tzIGlmIGB2YWx1ZWBcbiAgICAgKiBpcyBhbiBvYmplY3QuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgTGFuZ1xuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGFuIGFycmF5LWxpa2Ugb2JqZWN0LFxuICAgICAqICBlbHNlIGBmYWxzZWAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uaXNBcnJheUxpa2VPYmplY3QoWzEsIDIsIDNdKTtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICpcbiAgICAgKiBfLmlzQXJyYXlMaWtlT2JqZWN0KGRvY3VtZW50LmJvZHkuY2hpbGRyZW4pO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKlxuICAgICAqIF8uaXNBcnJheUxpa2VPYmplY3QoJ2FiYycpO1xuICAgICAqIC8vID0+IGZhbHNlXG4gICAgICpcbiAgICAgKiBfLmlzQXJyYXlMaWtlT2JqZWN0KF8ubm9vcCk7XG4gICAgICogLy8gPT4gZmFsc2VcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBpc0FycmF5TGlrZU9iamVjdCh2YWx1ZSkge1xuICAgICAgcmV0dXJuIGlzT2JqZWN0TGlrZSh2YWx1ZSkgJiYgaXNBcnJheUxpa2UodmFsdWUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIGNsYXNzaWZpZWQgYXMgYSBib29sZWFuIHByaW1pdGl2ZSBvciBvYmplY3QuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMC4xLjBcbiAgICAgKiBAY2F0ZWdvcnkgTGFuZ1xuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGEgYm9vbGVhbiwgZWxzZSBgZmFsc2VgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLmlzQm9vbGVhbihmYWxzZSk7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqXG4gICAgICogXy5pc0Jvb2xlYW4obnVsbCk7XG4gICAgICogLy8gPT4gZmFsc2VcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBpc0Jvb2xlYW4odmFsdWUpIHtcbiAgICAgIHJldHVybiB2YWx1ZSA9PT0gdHJ1ZSB8fCB2YWx1ZSA9PT0gZmFsc2UgfHxcbiAgICAgICAgKGlzT2JqZWN0TGlrZSh2YWx1ZSkgJiYgYmFzZUdldFRhZyh2YWx1ZSkgPT0gYm9vbFRhZyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgYSBidWZmZXIuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4zLjBcbiAgICAgKiBAY2F0ZWdvcnkgTGFuZ1xuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGEgYnVmZmVyLCBlbHNlIGBmYWxzZWAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uaXNCdWZmZXIobmV3IEJ1ZmZlcigyKSk7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqXG4gICAgICogXy5pc0J1ZmZlcihuZXcgVWludDhBcnJheSgyKSk7XG4gICAgICogLy8gPT4gZmFsc2VcbiAgICAgKi9cbiAgICB2YXIgaXNCdWZmZXIgPSBuYXRpdmVJc0J1ZmZlciB8fCBzdHViRmFsc2U7XG5cbiAgICAvKipcbiAgICAgKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBjbGFzc2lmaWVkIGFzIGEgYERhdGVgIG9iamVjdC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAwLjEuMFxuICAgICAqIEBjYXRlZ29yeSBMYW5nXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgYSBkYXRlIG9iamVjdCwgZWxzZSBgZmFsc2VgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLmlzRGF0ZShuZXcgRGF0ZSk7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqXG4gICAgICogXy5pc0RhdGUoJ01vbiBBcHJpbCAyMyAyMDEyJyk7XG4gICAgICogLy8gPT4gZmFsc2VcbiAgICAgKi9cbiAgICB2YXIgaXNEYXRlID0gbm9kZUlzRGF0ZSA/IGJhc2VVbmFyeShub2RlSXNEYXRlKSA6IGJhc2VJc0RhdGU7XG5cbiAgICAvKipcbiAgICAgKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBsaWtlbHkgYSBET00gZWxlbWVudC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAwLjEuMFxuICAgICAqIEBjYXRlZ29yeSBMYW5nXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgYSBET00gZWxlbWVudCwgZWxzZSBgZmFsc2VgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLmlzRWxlbWVudChkb2N1bWVudC5ib2R5KTtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICpcbiAgICAgKiBfLmlzRWxlbWVudCgnPGJvZHk+Jyk7XG4gICAgICogLy8gPT4gZmFsc2VcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBpc0VsZW1lbnQodmFsdWUpIHtcbiAgICAgIHJldHVybiBpc09iamVjdExpa2UodmFsdWUpICYmIHZhbHVlLm5vZGVUeXBlID09PSAxICYmICFpc1BsYWluT2JqZWN0KHZhbHVlKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBhbiBlbXB0eSBvYmplY3QsIGNvbGxlY3Rpb24sIG1hcCwgb3Igc2V0LlxuICAgICAqXG4gICAgICogT2JqZWN0cyBhcmUgY29uc2lkZXJlZCBlbXB0eSBpZiB0aGV5IGhhdmUgbm8gb3duIGVudW1lcmFibGUgc3RyaW5nIGtleWVkXG4gICAgICogcHJvcGVydGllcy5cbiAgICAgKlxuICAgICAqIEFycmF5LWxpa2UgdmFsdWVzIHN1Y2ggYXMgYGFyZ3VtZW50c2Agb2JqZWN0cywgYXJyYXlzLCBidWZmZXJzLCBzdHJpbmdzLCBvclxuICAgICAqIGpRdWVyeS1saWtlIGNvbGxlY3Rpb25zIGFyZSBjb25zaWRlcmVkIGVtcHR5IGlmIHRoZXkgaGF2ZSBhIGBsZW5ndGhgIG9mIGAwYC5cbiAgICAgKiBTaW1pbGFybHksIG1hcHMgYW5kIHNldHMgYXJlIGNvbnNpZGVyZWQgZW1wdHkgaWYgdGhleSBoYXZlIGEgYHNpemVgIG9mIGAwYC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAwLjEuMFxuICAgICAqIEBjYXRlZ29yeSBMYW5nXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgZW1wdHksIGVsc2UgYGZhbHNlYC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5pc0VtcHR5KG51bGwpO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKlxuICAgICAqIF8uaXNFbXB0eSh0cnVlKTtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICpcbiAgICAgKiBfLmlzRW1wdHkoMSk7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqXG4gICAgICogXy5pc0VtcHR5KFsxLCAyLCAzXSk7XG4gICAgICogLy8gPT4gZmFsc2VcbiAgICAgKlxuICAgICAqIF8uaXNFbXB0eSh7ICdhJzogMSB9KTtcbiAgICAgKiAvLyA9PiBmYWxzZVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGlzRW1wdHkodmFsdWUpIHtcbiAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgfVxuICAgICAgaWYgKGlzQXJyYXlMaWtlKHZhbHVlKSAmJlxuICAgICAgICAgIChpc0FycmF5KHZhbHVlKSB8fCB0eXBlb2YgdmFsdWUgPT0gJ3N0cmluZycgfHwgdHlwZW9mIHZhbHVlLnNwbGljZSA9PSAnZnVuY3Rpb24nIHx8XG4gICAgICAgICAgICBpc0J1ZmZlcih2YWx1ZSkgfHwgaXNUeXBlZEFycmF5KHZhbHVlKSB8fCBpc0FyZ3VtZW50cyh2YWx1ZSkpKSB7XG4gICAgICAgIHJldHVybiAhdmFsdWUubGVuZ3RoO1xuICAgICAgfVxuICAgICAgdmFyIHRhZyA9IGdldFRhZyh2YWx1ZSk7XG4gICAgICBpZiAodGFnID09IG1hcFRhZyB8fCB0YWcgPT0gc2V0VGFnKSB7XG4gICAgICAgIHJldHVybiAhdmFsdWUuc2l6ZTtcbiAgICAgIH1cbiAgICAgIGlmIChpc1Byb3RvdHlwZSh2YWx1ZSkpIHtcbiAgICAgICAgcmV0dXJuICFiYXNlS2V5cyh2YWx1ZSkubGVuZ3RoO1xuICAgICAgfVxuICAgICAgZm9yICh2YXIga2V5IGluIHZhbHVlKSB7XG4gICAgICAgIGlmIChoYXNPd25Qcm9wZXJ0eS5jYWxsKHZhbHVlLCBrZXkpKSB7XG4gICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBQZXJmb3JtcyBhIGRlZXAgY29tcGFyaXNvbiBiZXR3ZWVuIHR3byB2YWx1ZXMgdG8gZGV0ZXJtaW5lIGlmIHRoZXkgYXJlXG4gICAgICogZXF1aXZhbGVudC5cbiAgICAgKlxuICAgICAqICoqTm90ZToqKiBUaGlzIG1ldGhvZCBzdXBwb3J0cyBjb21wYXJpbmcgYXJyYXlzLCBhcnJheSBidWZmZXJzLCBib29sZWFucyxcbiAgICAgKiBkYXRlIG9iamVjdHMsIGVycm9yIG9iamVjdHMsIG1hcHMsIG51bWJlcnMsIGBPYmplY3RgIG9iamVjdHMsIHJlZ2V4ZXMsXG4gICAgICogc2V0cywgc3RyaW5ncywgc3ltYm9scywgYW5kIHR5cGVkIGFycmF5cy4gYE9iamVjdGAgb2JqZWN0cyBhcmUgY29tcGFyZWRcbiAgICAgKiBieSB0aGVpciBvd24sIG5vdCBpbmhlcml0ZWQsIGVudW1lcmFibGUgcHJvcGVydGllcy4gRnVuY3Rpb25zIGFuZCBET01cbiAgICAgKiBub2RlcyBhcmUgY29tcGFyZWQgYnkgc3RyaWN0IGVxdWFsaXR5LCBpLmUuIGA9PT1gLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDAuMS4wXG4gICAgICogQGNhdGVnb3J5IExhbmdcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjb21wYXJlLlxuICAgICAqIEBwYXJhbSB7Kn0gb3RoZXIgVGhlIG90aGVyIHZhbHVlIHRvIGNvbXBhcmUuXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIHRoZSB2YWx1ZXMgYXJlIGVxdWl2YWxlbnQsIGVsc2UgYGZhbHNlYC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIG9iamVjdCA9IHsgJ2EnOiAxIH07XG4gICAgICogdmFyIG90aGVyID0geyAnYSc6IDEgfTtcbiAgICAgKlxuICAgICAqIF8uaXNFcXVhbChvYmplY3QsIG90aGVyKTtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICpcbiAgICAgKiBvYmplY3QgPT09IG90aGVyO1xuICAgICAqIC8vID0+IGZhbHNlXG4gICAgICovXG4gICAgZnVuY3Rpb24gaXNFcXVhbCh2YWx1ZSwgb3RoZXIpIHtcbiAgICAgIHJldHVybiBiYXNlSXNFcXVhbCh2YWx1ZSwgb3RoZXIpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIGlzIGxpa2UgYF8uaXNFcXVhbGAgZXhjZXB0IHRoYXQgaXQgYWNjZXB0cyBgY3VzdG9taXplcmAgd2hpY2hcbiAgICAgKiBpcyBpbnZva2VkIHRvIGNvbXBhcmUgdmFsdWVzLiBJZiBgY3VzdG9taXplcmAgcmV0dXJucyBgdW5kZWZpbmVkYCwgY29tcGFyaXNvbnNcbiAgICAgKiBhcmUgaGFuZGxlZCBieSB0aGUgbWV0aG9kIGluc3RlYWQuIFRoZSBgY3VzdG9taXplcmAgaXMgaW52b2tlZCB3aXRoIHVwIHRvXG4gICAgICogc2l4IGFyZ3VtZW50czogKG9ialZhbHVlLCBvdGhWYWx1ZSBbLCBpbmRleHxrZXksIG9iamVjdCwgb3RoZXIsIHN0YWNrXSkuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgTGFuZ1xuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNvbXBhcmUuXG4gICAgICogQHBhcmFtIHsqfSBvdGhlciBUaGUgb3RoZXIgdmFsdWUgdG8gY29tcGFyZS5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbY3VzdG9taXplcl0gVGhlIGZ1bmN0aW9uIHRvIGN1c3RvbWl6ZSBjb21wYXJpc29ucy5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgdGhlIHZhbHVlcyBhcmUgZXF1aXZhbGVudCwgZWxzZSBgZmFsc2VgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBmdW5jdGlvbiBpc0dyZWV0aW5nKHZhbHVlKSB7XG4gICAgICogICByZXR1cm4gL15oKD86aXxlbGxvKSQvLnRlc3QodmFsdWUpO1xuICAgICAqIH1cbiAgICAgKlxuICAgICAqIGZ1bmN0aW9uIGN1c3RvbWl6ZXIob2JqVmFsdWUsIG90aFZhbHVlKSB7XG4gICAgICogICBpZiAoaXNHcmVldGluZyhvYmpWYWx1ZSkgJiYgaXNHcmVldGluZyhvdGhWYWx1ZSkpIHtcbiAgICAgKiAgICAgcmV0dXJuIHRydWU7XG4gICAgICogICB9XG4gICAgICogfVxuICAgICAqXG4gICAgICogdmFyIGFycmF5ID0gWydoZWxsbycsICdnb29kYnllJ107XG4gICAgICogdmFyIG90aGVyID0gWydoaScsICdnb29kYnllJ107XG4gICAgICpcbiAgICAgKiBfLmlzRXF1YWxXaXRoKGFycmF5LCBvdGhlciwgY3VzdG9taXplcik7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGlzRXF1YWxXaXRoKHZhbHVlLCBvdGhlciwgY3VzdG9taXplcikge1xuICAgICAgY3VzdG9taXplciA9IHR5cGVvZiBjdXN0b21pemVyID09ICdmdW5jdGlvbicgPyBjdXN0b21pemVyIDogdW5kZWZpbmVkO1xuICAgICAgdmFyIHJlc3VsdCA9IGN1c3RvbWl6ZXIgPyBjdXN0b21pemVyKHZhbHVlLCBvdGhlcikgOiB1bmRlZmluZWQ7XG4gICAgICByZXR1cm4gcmVzdWx0ID09PSB1bmRlZmluZWQgPyBiYXNlSXNFcXVhbCh2YWx1ZSwgb3RoZXIsIHVuZGVmaW5lZCwgY3VzdG9taXplcikgOiAhIXJlc3VsdDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBhbiBgRXJyb3JgLCBgRXZhbEVycm9yYCwgYFJhbmdlRXJyb3JgLCBgUmVmZXJlbmNlRXJyb3JgLFxuICAgICAqIGBTeW50YXhFcnJvcmAsIGBUeXBlRXJyb3JgLCBvciBgVVJJRXJyb3JgIG9iamVjdC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAzLjAuMFxuICAgICAqIEBjYXRlZ29yeSBMYW5nXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgYW4gZXJyb3Igb2JqZWN0LCBlbHNlIGBmYWxzZWAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uaXNFcnJvcihuZXcgRXJyb3IpO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKlxuICAgICAqIF8uaXNFcnJvcihFcnJvcik7XG4gICAgICogLy8gPT4gZmFsc2VcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBpc0Vycm9yKHZhbHVlKSB7XG4gICAgICBpZiAoIWlzT2JqZWN0TGlrZSh2YWx1ZSkpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgICAgdmFyIHRhZyA9IGJhc2VHZXRUYWcodmFsdWUpO1xuICAgICAgcmV0dXJuIHRhZyA9PSBlcnJvclRhZyB8fCB0YWcgPT0gZG9tRXhjVGFnIHx8XG4gICAgICAgICh0eXBlb2YgdmFsdWUubWVzc2FnZSA9PSAnc3RyaW5nJyAmJiB0eXBlb2YgdmFsdWUubmFtZSA9PSAnc3RyaW5nJyAmJiAhaXNQbGFpbk9iamVjdCh2YWx1ZSkpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIGEgZmluaXRlIHByaW1pdGl2ZSBudW1iZXIuXG4gICAgICpcbiAgICAgKiAqKk5vdGU6KiogVGhpcyBtZXRob2QgaXMgYmFzZWQgb25cbiAgICAgKiBbYE51bWJlci5pc0Zpbml0ZWBdKGh0dHBzOi8vbWRuLmlvL051bWJlci9pc0Zpbml0ZSkuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMC4xLjBcbiAgICAgKiBAY2F0ZWdvcnkgTGFuZ1xuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGEgZmluaXRlIG51bWJlciwgZWxzZSBgZmFsc2VgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLmlzRmluaXRlKDMpO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKlxuICAgICAqIF8uaXNGaW5pdGUoTnVtYmVyLk1JTl9WQUxVRSk7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqXG4gICAgICogXy5pc0Zpbml0ZShJbmZpbml0eSk7XG4gICAgICogLy8gPT4gZmFsc2VcbiAgICAgKlxuICAgICAqIF8uaXNGaW5pdGUoJzMnKTtcbiAgICAgKiAvLyA9PiBmYWxzZVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGlzRmluaXRlKHZhbHVlKSB7XG4gICAgICByZXR1cm4gdHlwZW9mIHZhbHVlID09ICdudW1iZXInICYmIG5hdGl2ZUlzRmluaXRlKHZhbHVlKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBjbGFzc2lmaWVkIGFzIGEgYEZ1bmN0aW9uYCBvYmplY3QuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMC4xLjBcbiAgICAgKiBAY2F0ZWdvcnkgTGFuZ1xuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGEgZnVuY3Rpb24sIGVsc2UgYGZhbHNlYC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5pc0Z1bmN0aW9uKF8pO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKlxuICAgICAqIF8uaXNGdW5jdGlvbigvYWJjLyk7XG4gICAgICogLy8gPT4gZmFsc2VcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBpc0Z1bmN0aW9uKHZhbHVlKSB7XG4gICAgICBpZiAoIWlzT2JqZWN0KHZhbHVlKSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgICAvLyBUaGUgdXNlIG9mIGBPYmplY3QjdG9TdHJpbmdgIGF2b2lkcyBpc3N1ZXMgd2l0aCB0aGUgYHR5cGVvZmAgb3BlcmF0b3JcbiAgICAgIC8vIGluIFNhZmFyaSA5IHdoaWNoIHJldHVybnMgJ29iamVjdCcgZm9yIHR5cGVkIGFycmF5cyBhbmQgb3RoZXIgY29uc3RydWN0b3JzLlxuICAgICAgdmFyIHRhZyA9IGJhc2VHZXRUYWcodmFsdWUpO1xuICAgICAgcmV0dXJuIHRhZyA9PSBmdW5jVGFnIHx8IHRhZyA9PSBnZW5UYWcgfHwgdGFnID09IGFzeW5jVGFnIHx8IHRhZyA9PSBwcm94eVRhZztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBhbiBpbnRlZ2VyLlxuICAgICAqXG4gICAgICogKipOb3RlOioqIFRoaXMgbWV0aG9kIGlzIGJhc2VkIG9uXG4gICAgICogW2BOdW1iZXIuaXNJbnRlZ2VyYF0oaHR0cHM6Ly9tZG4uaW8vTnVtYmVyL2lzSW50ZWdlcikuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgTGFuZ1xuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGFuIGludGVnZXIsIGVsc2UgYGZhbHNlYC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5pc0ludGVnZXIoMyk7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqXG4gICAgICogXy5pc0ludGVnZXIoTnVtYmVyLk1JTl9WQUxVRSk7XG4gICAgICogLy8gPT4gZmFsc2VcbiAgICAgKlxuICAgICAqIF8uaXNJbnRlZ2VyKEluZmluaXR5KTtcbiAgICAgKiAvLyA9PiBmYWxzZVxuICAgICAqXG4gICAgICogXy5pc0ludGVnZXIoJzMnKTtcbiAgICAgKiAvLyA9PiBmYWxzZVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGlzSW50ZWdlcih2YWx1ZSkge1xuICAgICAgcmV0dXJuIHR5cGVvZiB2YWx1ZSA9PSAnbnVtYmVyJyAmJiB2YWx1ZSA9PSB0b0ludGVnZXIodmFsdWUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIGEgdmFsaWQgYXJyYXktbGlrZSBsZW5ndGguXG4gICAgICpcbiAgICAgKiAqKk5vdGU6KiogVGhpcyBtZXRob2QgaXMgbG9vc2VseSBiYXNlZCBvblxuICAgICAqIFtgVG9MZW5ndGhgXShodHRwOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi83LjAvI3NlYy10b2xlbmd0aCkuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgTGFuZ1xuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGEgdmFsaWQgbGVuZ3RoLCBlbHNlIGBmYWxzZWAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uaXNMZW5ndGgoMyk7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqXG4gICAgICogXy5pc0xlbmd0aChOdW1iZXIuTUlOX1ZBTFVFKTtcbiAgICAgKiAvLyA9PiBmYWxzZVxuICAgICAqXG4gICAgICogXy5pc0xlbmd0aChJbmZpbml0eSk7XG4gICAgICogLy8gPT4gZmFsc2VcbiAgICAgKlxuICAgICAqIF8uaXNMZW5ndGgoJzMnKTtcbiAgICAgKiAvLyA9PiBmYWxzZVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGlzTGVuZ3RoKHZhbHVlKSB7XG4gICAgICByZXR1cm4gdHlwZW9mIHZhbHVlID09ICdudW1iZXInICYmXG4gICAgICAgIHZhbHVlID4gLTEgJiYgdmFsdWUgJSAxID09IDAgJiYgdmFsdWUgPD0gTUFYX1NBRkVfSU5URUdFUjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDaGVja3MgaWYgYHZhbHVlYCBpcyB0aGVcbiAgICAgKiBbbGFuZ3VhZ2UgdHlwZV0oaHR0cDovL3d3dy5lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzcuMC8jc2VjLWVjbWFzY3JpcHQtbGFuZ3VhZ2UtdHlwZXMpXG4gICAgICogb2YgYE9iamVjdGAuIChlLmcuIGFycmF5cywgZnVuY3Rpb25zLCBvYmplY3RzLCByZWdleGVzLCBgbmV3IE51bWJlcigwKWAsIGFuZCBgbmV3IFN0cmluZygnJylgKVxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDAuMS4wXG4gICAgICogQGNhdGVnb3J5IExhbmdcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhbiBvYmplY3QsIGVsc2UgYGZhbHNlYC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5pc09iamVjdCh7fSk7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqXG4gICAgICogXy5pc09iamVjdChbMSwgMiwgM10pO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKlxuICAgICAqIF8uaXNPYmplY3QoXy5ub29wKTtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICpcbiAgICAgKiBfLmlzT2JqZWN0KG51bGwpO1xuICAgICAqIC8vID0+IGZhbHNlXG4gICAgICovXG4gICAgZnVuY3Rpb24gaXNPYmplY3QodmFsdWUpIHtcbiAgICAgIHZhciB0eXBlID0gdHlwZW9mIHZhbHVlO1xuICAgICAgcmV0dXJuIHZhbHVlICE9IG51bGwgJiYgKHR5cGUgPT0gJ29iamVjdCcgfHwgdHlwZSA9PSAnZnVuY3Rpb24nKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBvYmplY3QtbGlrZS4gQSB2YWx1ZSBpcyBvYmplY3QtbGlrZSBpZiBpdCdzIG5vdCBgbnVsbGBcbiAgICAgKiBhbmQgaGFzIGEgYHR5cGVvZmAgcmVzdWx0IG9mIFwib2JqZWN0XCIuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgTGFuZ1xuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIG9iamVjdC1saWtlLCBlbHNlIGBmYWxzZWAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uaXNPYmplY3RMaWtlKHt9KTtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICpcbiAgICAgKiBfLmlzT2JqZWN0TGlrZShbMSwgMiwgM10pO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKlxuICAgICAqIF8uaXNPYmplY3RMaWtlKF8ubm9vcCk7XG4gICAgICogLy8gPT4gZmFsc2VcbiAgICAgKlxuICAgICAqIF8uaXNPYmplY3RMaWtlKG51bGwpO1xuICAgICAqIC8vID0+IGZhbHNlXG4gICAgICovXG4gICAgZnVuY3Rpb24gaXNPYmplY3RMaWtlKHZhbHVlKSB7XG4gICAgICByZXR1cm4gdmFsdWUgIT0gbnVsbCAmJiB0eXBlb2YgdmFsdWUgPT0gJ29iamVjdCc7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgY2xhc3NpZmllZCBhcyBhIGBNYXBgIG9iamVjdC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjMuMFxuICAgICAqIEBjYXRlZ29yeSBMYW5nXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgYSBtYXAsIGVsc2UgYGZhbHNlYC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5pc01hcChuZXcgTWFwKTtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICpcbiAgICAgKiBfLmlzTWFwKG5ldyBXZWFrTWFwKTtcbiAgICAgKiAvLyA9PiBmYWxzZVxuICAgICAqL1xuICAgIHZhciBpc01hcCA9IG5vZGVJc01hcCA/IGJhc2VVbmFyeShub2RlSXNNYXApIDogYmFzZUlzTWFwO1xuXG4gICAgLyoqXG4gICAgICogUGVyZm9ybXMgYSBwYXJ0aWFsIGRlZXAgY29tcGFyaXNvbiBiZXR3ZWVuIGBvYmplY3RgIGFuZCBgc291cmNlYCB0b1xuICAgICAqIGRldGVybWluZSBpZiBgb2JqZWN0YCBjb250YWlucyBlcXVpdmFsZW50IHByb3BlcnR5IHZhbHVlcy5cbiAgICAgKlxuICAgICAqICoqTm90ZToqKiBUaGlzIG1ldGhvZCBpcyBlcXVpdmFsZW50IHRvIGBfLm1hdGNoZXNgIHdoZW4gYHNvdXJjZWAgaXNcbiAgICAgKiBwYXJ0aWFsbHkgYXBwbGllZC5cbiAgICAgKlxuICAgICAqIFBhcnRpYWwgY29tcGFyaXNvbnMgd2lsbCBtYXRjaCBlbXB0eSBhcnJheSBhbmQgZW1wdHkgb2JqZWN0IGBzb3VyY2VgXG4gICAgICogdmFsdWVzIGFnYWluc3QgYW55IGFycmF5IG9yIG9iamVjdCB2YWx1ZSwgcmVzcGVjdGl2ZWx5LiBTZWUgYF8uaXNFcXVhbGBcbiAgICAgKiBmb3IgYSBsaXN0IG9mIHN1cHBvcnRlZCB2YWx1ZSBjb21wYXJpc29ucy5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAzLjAuMFxuICAgICAqIEBjYXRlZ29yeSBMYW5nXG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIGluc3BlY3QuXG4gICAgICogQHBhcmFtIHtPYmplY3R9IHNvdXJjZSBUaGUgb2JqZWN0IG9mIHByb3BlcnR5IHZhbHVlcyB0byBtYXRjaC5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYG9iamVjdGAgaXMgYSBtYXRjaCwgZWxzZSBgZmFsc2VgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgb2JqZWN0ID0geyAnYSc6IDEsICdiJzogMiB9O1xuICAgICAqXG4gICAgICogXy5pc01hdGNoKG9iamVjdCwgeyAnYic6IDIgfSk7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqXG4gICAgICogXy5pc01hdGNoKG9iamVjdCwgeyAnYic6IDEgfSk7XG4gICAgICogLy8gPT4gZmFsc2VcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBpc01hdGNoKG9iamVjdCwgc291cmNlKSB7XG4gICAgICByZXR1cm4gb2JqZWN0ID09PSBzb3VyY2UgfHwgYmFzZUlzTWF0Y2gob2JqZWN0LCBzb3VyY2UsIGdldE1hdGNoRGF0YShzb3VyY2UpKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIG1ldGhvZCBpcyBsaWtlIGBfLmlzTWF0Y2hgIGV4Y2VwdCB0aGF0IGl0IGFjY2VwdHMgYGN1c3RvbWl6ZXJgIHdoaWNoXG4gICAgICogaXMgaW52b2tlZCB0byBjb21wYXJlIHZhbHVlcy4gSWYgYGN1c3RvbWl6ZXJgIHJldHVybnMgYHVuZGVmaW5lZGAsIGNvbXBhcmlzb25zXG4gICAgICogYXJlIGhhbmRsZWQgYnkgdGhlIG1ldGhvZCBpbnN0ZWFkLiBUaGUgYGN1c3RvbWl6ZXJgIGlzIGludm9rZWQgd2l0aCBmaXZlXG4gICAgICogYXJndW1lbnRzOiAob2JqVmFsdWUsIHNyY1ZhbHVlLCBpbmRleHxrZXksIG9iamVjdCwgc291cmNlKS5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjAuMFxuICAgICAqIEBjYXRlZ29yeSBMYW5nXG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIGluc3BlY3QuXG4gICAgICogQHBhcmFtIHtPYmplY3R9IHNvdXJjZSBUaGUgb2JqZWN0IG9mIHByb3BlcnR5IHZhbHVlcyB0byBtYXRjaC5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbY3VzdG9taXplcl0gVGhlIGZ1bmN0aW9uIHRvIGN1c3RvbWl6ZSBjb21wYXJpc29ucy5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYG9iamVjdGAgaXMgYSBtYXRjaCwgZWxzZSBgZmFsc2VgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBmdW5jdGlvbiBpc0dyZWV0aW5nKHZhbHVlKSB7XG4gICAgICogICByZXR1cm4gL15oKD86aXxlbGxvKSQvLnRlc3QodmFsdWUpO1xuICAgICAqIH1cbiAgICAgKlxuICAgICAqIGZ1bmN0aW9uIGN1c3RvbWl6ZXIob2JqVmFsdWUsIHNyY1ZhbHVlKSB7XG4gICAgICogICBpZiAoaXNHcmVldGluZyhvYmpWYWx1ZSkgJiYgaXNHcmVldGluZyhzcmNWYWx1ZSkpIHtcbiAgICAgKiAgICAgcmV0dXJuIHRydWU7XG4gICAgICogICB9XG4gICAgICogfVxuICAgICAqXG4gICAgICogdmFyIG9iamVjdCA9IHsgJ2dyZWV0aW5nJzogJ2hlbGxvJyB9O1xuICAgICAqIHZhciBzb3VyY2UgPSB7ICdncmVldGluZyc6ICdoaScgfTtcbiAgICAgKlxuICAgICAqIF8uaXNNYXRjaFdpdGgob2JqZWN0LCBzb3VyY2UsIGN1c3RvbWl6ZXIpO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBpc01hdGNoV2l0aChvYmplY3QsIHNvdXJjZSwgY3VzdG9taXplcikge1xuICAgICAgY3VzdG9taXplciA9IHR5cGVvZiBjdXN0b21pemVyID09ICdmdW5jdGlvbicgPyBjdXN0b21pemVyIDogdW5kZWZpbmVkO1xuICAgICAgcmV0dXJuIGJhc2VJc01hdGNoKG9iamVjdCwgc291cmNlLCBnZXRNYXRjaERhdGEoc291cmNlKSwgY3VzdG9taXplcik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgYE5hTmAuXG4gICAgICpcbiAgICAgKiAqKk5vdGU6KiogVGhpcyBtZXRob2QgaXMgYmFzZWQgb25cbiAgICAgKiBbYE51bWJlci5pc05hTmBdKGh0dHBzOi8vbWRuLmlvL051bWJlci9pc05hTikgYW5kIGlzIG5vdCB0aGUgc2FtZSBhc1xuICAgICAqIGdsb2JhbCBbYGlzTmFOYF0oaHR0cHM6Ly9tZG4uaW8vaXNOYU4pIHdoaWNoIHJldHVybnMgYHRydWVgIGZvclxuICAgICAqIGB1bmRlZmluZWRgIGFuZCBvdGhlciBub24tbnVtYmVyIHZhbHVlcy5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAwLjEuMFxuICAgICAqIEBjYXRlZ29yeSBMYW5nXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgYE5hTmAsIGVsc2UgYGZhbHNlYC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5pc05hTihOYU4pO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKlxuICAgICAqIF8uaXNOYU4obmV3IE51bWJlcihOYU4pKTtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICpcbiAgICAgKiBpc05hTih1bmRlZmluZWQpO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKlxuICAgICAqIF8uaXNOYU4odW5kZWZpbmVkKTtcbiAgICAgKiAvLyA9PiBmYWxzZVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGlzTmFOKHZhbHVlKSB7XG4gICAgICAvLyBBbiBgTmFOYCBwcmltaXRpdmUgaXMgdGhlIG9ubHkgdmFsdWUgdGhhdCBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLlxuICAgICAgLy8gUGVyZm9ybSB0aGUgYHRvU3RyaW5nVGFnYCBjaGVjayBmaXJzdCB0byBhdm9pZCBlcnJvcnMgd2l0aCBzb21lXG4gICAgICAvLyBBY3RpdmVYIG9iamVjdHMgaW4gSUUuXG4gICAgICByZXR1cm4gaXNOdW1iZXIodmFsdWUpICYmIHZhbHVlICE9ICt2YWx1ZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBhIHByaXN0aW5lIG5hdGl2ZSBmdW5jdGlvbi5cbiAgICAgKlxuICAgICAqICoqTm90ZToqKiBUaGlzIG1ldGhvZCBjYW4ndCByZWxpYWJseSBkZXRlY3QgbmF0aXZlIGZ1bmN0aW9ucyBpbiB0aGUgcHJlc2VuY2VcbiAgICAgKiBvZiB0aGUgY29yZS1qcyBwYWNrYWdlIGJlY2F1c2UgY29yZS1qcyBjaXJjdW12ZW50cyB0aGlzIGtpbmQgb2YgZGV0ZWN0aW9uLlxuICAgICAqIERlc3BpdGUgbXVsdGlwbGUgcmVxdWVzdHMsIHRoZSBjb3JlLWpzIG1haW50YWluZXIgaGFzIG1hZGUgaXQgY2xlYXI6IGFueVxuICAgICAqIGF0dGVtcHQgdG8gZml4IHRoZSBkZXRlY3Rpb24gd2lsbCBiZSBvYnN0cnVjdGVkLiBBcyBhIHJlc3VsdCwgd2UncmUgbGVmdFxuICAgICAqIHdpdGggbGl0dGxlIGNob2ljZSBidXQgdG8gdGhyb3cgYW4gZXJyb3IuIFVuZm9ydHVuYXRlbHksIHRoaXMgYWxzbyBhZmZlY3RzXG4gICAgICogcGFja2FnZXMsIGxpa2UgW2JhYmVsLXBvbHlmaWxsXShodHRwczovL3d3dy5ucG1qcy5jb20vcGFja2FnZS9iYWJlbC1wb2x5ZmlsbCksXG4gICAgICogd2hpY2ggcmVseSBvbiBjb3JlLWpzLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDMuMC4wXG4gICAgICogQGNhdGVnb3J5IExhbmdcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhIG5hdGl2ZSBmdW5jdGlvbixcbiAgICAgKiAgZWxzZSBgZmFsc2VgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLmlzTmF0aXZlKEFycmF5LnByb3RvdHlwZS5wdXNoKTtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICpcbiAgICAgKiBfLmlzTmF0aXZlKF8pO1xuICAgICAqIC8vID0+IGZhbHNlXG4gICAgICovXG4gICAgZnVuY3Rpb24gaXNOYXRpdmUodmFsdWUpIHtcbiAgICAgIGlmIChpc01hc2thYmxlKHZhbHVlKSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoQ09SRV9FUlJPUl9URVhUKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBiYXNlSXNOYXRpdmUodmFsdWUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIGBudWxsYC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAwLjEuMFxuICAgICAqIEBjYXRlZ29yeSBMYW5nXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgYG51bGxgLCBlbHNlIGBmYWxzZWAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uaXNOdWxsKG51bGwpO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKlxuICAgICAqIF8uaXNOdWxsKHZvaWQgMCk7XG4gICAgICogLy8gPT4gZmFsc2VcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBpc051bGwodmFsdWUpIHtcbiAgICAgIHJldHVybiB2YWx1ZSA9PT0gbnVsbDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBgbnVsbGAgb3IgYHVuZGVmaW5lZGAuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgTGFuZ1xuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIG51bGxpc2gsIGVsc2UgYGZhbHNlYC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5pc05pbChudWxsKTtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICpcbiAgICAgKiBfLmlzTmlsKHZvaWQgMCk7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqXG4gICAgICogXy5pc05pbChOYU4pO1xuICAgICAqIC8vID0+IGZhbHNlXG4gICAgICovXG4gICAgZnVuY3Rpb24gaXNOaWwodmFsdWUpIHtcbiAgICAgIHJldHVybiB2YWx1ZSA9PSBudWxsO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIGNsYXNzaWZpZWQgYXMgYSBgTnVtYmVyYCBwcmltaXRpdmUgb3Igb2JqZWN0LlxuICAgICAqXG4gICAgICogKipOb3RlOioqIFRvIGV4Y2x1ZGUgYEluZmluaXR5YCwgYC1JbmZpbml0eWAsIGFuZCBgTmFOYCwgd2hpY2ggYXJlXG4gICAgICogY2xhc3NpZmllZCBhcyBudW1iZXJzLCB1c2UgdGhlIGBfLmlzRmluaXRlYCBtZXRob2QuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMC4xLjBcbiAgICAgKiBAY2F0ZWdvcnkgTGFuZ1xuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGEgbnVtYmVyLCBlbHNlIGBmYWxzZWAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uaXNOdW1iZXIoMyk7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqXG4gICAgICogXy5pc051bWJlcihOdW1iZXIuTUlOX1ZBTFVFKTtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICpcbiAgICAgKiBfLmlzTnVtYmVyKEluZmluaXR5KTtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICpcbiAgICAgKiBfLmlzTnVtYmVyKCczJyk7XG4gICAgICogLy8gPT4gZmFsc2VcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBpc051bWJlcih2YWx1ZSkge1xuICAgICAgcmV0dXJuIHR5cGVvZiB2YWx1ZSA9PSAnbnVtYmVyJyB8fFxuICAgICAgICAoaXNPYmplY3RMaWtlKHZhbHVlKSAmJiBiYXNlR2V0VGFnKHZhbHVlKSA9PSBudW1iZXJUYWcpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIGEgcGxhaW4gb2JqZWN0LCB0aGF0IGlzLCBhbiBvYmplY3QgY3JlYXRlZCBieSB0aGVcbiAgICAgKiBgT2JqZWN0YCBjb25zdHJ1Y3RvciBvciBvbmUgd2l0aCBhIGBbW1Byb3RvdHlwZV1dYCBvZiBgbnVsbGAuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMC44LjBcbiAgICAgKiBAY2F0ZWdvcnkgTGFuZ1xuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGEgcGxhaW4gb2JqZWN0LCBlbHNlIGBmYWxzZWAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIGZ1bmN0aW9uIEZvbygpIHtcbiAgICAgKiAgIHRoaXMuYSA9IDE7XG4gICAgICogfVxuICAgICAqXG4gICAgICogXy5pc1BsYWluT2JqZWN0KG5ldyBGb28pO1xuICAgICAqIC8vID0+IGZhbHNlXG4gICAgICpcbiAgICAgKiBfLmlzUGxhaW5PYmplY3QoWzEsIDIsIDNdKTtcbiAgICAgKiAvLyA9PiBmYWxzZVxuICAgICAqXG4gICAgICogXy5pc1BsYWluT2JqZWN0KHsgJ3gnOiAwLCAneSc6IDAgfSk7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqXG4gICAgICogXy5pc1BsYWluT2JqZWN0KE9iamVjdC5jcmVhdGUobnVsbCkpO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBpc1BsYWluT2JqZWN0KHZhbHVlKSB7XG4gICAgICBpZiAoIWlzT2JqZWN0TGlrZSh2YWx1ZSkgfHwgYmFzZUdldFRhZyh2YWx1ZSkgIT0gb2JqZWN0VGFnKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICAgIHZhciBwcm90byA9IGdldFByb3RvdHlwZSh2YWx1ZSk7XG4gICAgICBpZiAocHJvdG8gPT09IG51bGwpIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9XG4gICAgICB2YXIgQ3RvciA9IGhhc093blByb3BlcnR5LmNhbGwocHJvdG8sICdjb25zdHJ1Y3RvcicpICYmIHByb3RvLmNvbnN0cnVjdG9yO1xuICAgICAgcmV0dXJuIHR5cGVvZiBDdG9yID09ICdmdW5jdGlvbicgJiYgQ3RvciBpbnN0YW5jZW9mIEN0b3IgJiZcbiAgICAgICAgZnVuY1RvU3RyaW5nLmNhbGwoQ3RvcikgPT0gb2JqZWN0Q3RvclN0cmluZztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBjbGFzc2lmaWVkIGFzIGEgYFJlZ0V4cGAgb2JqZWN0LlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDAuMS4wXG4gICAgICogQGNhdGVnb3J5IExhbmdcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhIHJlZ2V4cCwgZWxzZSBgZmFsc2VgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLmlzUmVnRXhwKC9hYmMvKTtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICpcbiAgICAgKiBfLmlzUmVnRXhwKCcvYWJjLycpO1xuICAgICAqIC8vID0+IGZhbHNlXG4gICAgICovXG4gICAgdmFyIGlzUmVnRXhwID0gbm9kZUlzUmVnRXhwID8gYmFzZVVuYXJ5KG5vZGVJc1JlZ0V4cCkgOiBiYXNlSXNSZWdFeHA7XG5cbiAgICAvKipcbiAgICAgKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBhIHNhZmUgaW50ZWdlci4gQW4gaW50ZWdlciBpcyBzYWZlIGlmIGl0J3MgYW4gSUVFRS03NTRcbiAgICAgKiBkb3VibGUgcHJlY2lzaW9uIG51bWJlciB3aGljaCBpc24ndCB0aGUgcmVzdWx0IG9mIGEgcm91bmRlZCB1bnNhZmUgaW50ZWdlci5cbiAgICAgKlxuICAgICAqICoqTm90ZToqKiBUaGlzIG1ldGhvZCBpcyBiYXNlZCBvblxuICAgICAqIFtgTnVtYmVyLmlzU2FmZUludGVnZXJgXShodHRwczovL21kbi5pby9OdW1iZXIvaXNTYWZlSW50ZWdlcikuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgTGFuZ1xuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGEgc2FmZSBpbnRlZ2VyLCBlbHNlIGBmYWxzZWAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uaXNTYWZlSW50ZWdlcigzKTtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICpcbiAgICAgKiBfLmlzU2FmZUludGVnZXIoTnVtYmVyLk1JTl9WQUxVRSk7XG4gICAgICogLy8gPT4gZmFsc2VcbiAgICAgKlxuICAgICAqIF8uaXNTYWZlSW50ZWdlcihJbmZpbml0eSk7XG4gICAgICogLy8gPT4gZmFsc2VcbiAgICAgKlxuICAgICAqIF8uaXNTYWZlSW50ZWdlcignMycpO1xuICAgICAqIC8vID0+IGZhbHNlXG4gICAgICovXG4gICAgZnVuY3Rpb24gaXNTYWZlSW50ZWdlcih2YWx1ZSkge1xuICAgICAgcmV0dXJuIGlzSW50ZWdlcih2YWx1ZSkgJiYgdmFsdWUgPj0gLU1BWF9TQUZFX0lOVEVHRVIgJiYgdmFsdWUgPD0gTUFYX1NBRkVfSU5URUdFUjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBjbGFzc2lmaWVkIGFzIGEgYFNldGAgb2JqZWN0LlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMy4wXG4gICAgICogQGNhdGVnb3J5IExhbmdcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhIHNldCwgZWxzZSBgZmFsc2VgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLmlzU2V0KG5ldyBTZXQpO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKlxuICAgICAqIF8uaXNTZXQobmV3IFdlYWtTZXQpO1xuICAgICAqIC8vID0+IGZhbHNlXG4gICAgICovXG4gICAgdmFyIGlzU2V0ID0gbm9kZUlzU2V0ID8gYmFzZVVuYXJ5KG5vZGVJc1NldCkgOiBiYXNlSXNTZXQ7XG5cbiAgICAvKipcbiAgICAgKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBjbGFzc2lmaWVkIGFzIGEgYFN0cmluZ2AgcHJpbWl0aXZlIG9yIG9iamVjdC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAc2luY2UgMC4xLjBcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBjYXRlZ29yeSBMYW5nXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgYSBzdHJpbmcsIGVsc2UgYGZhbHNlYC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5pc1N0cmluZygnYWJjJyk7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqXG4gICAgICogXy5pc1N0cmluZygxKTtcbiAgICAgKiAvLyA9PiBmYWxzZVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGlzU3RyaW5nKHZhbHVlKSB7XG4gICAgICByZXR1cm4gdHlwZW9mIHZhbHVlID09ICdzdHJpbmcnIHx8XG4gICAgICAgICghaXNBcnJheSh2YWx1ZSkgJiYgaXNPYmplY3RMaWtlKHZhbHVlKSAmJiBiYXNlR2V0VGFnKHZhbHVlKSA9PSBzdHJpbmdUYWcpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIGNsYXNzaWZpZWQgYXMgYSBgU3ltYm9sYCBwcmltaXRpdmUgb3Igb2JqZWN0LlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMC4wXG4gICAgICogQGNhdGVnb3J5IExhbmdcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhIHN5bWJvbCwgZWxzZSBgZmFsc2VgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLmlzU3ltYm9sKFN5bWJvbC5pdGVyYXRvcik7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqXG4gICAgICogXy5pc1N5bWJvbCgnYWJjJyk7XG4gICAgICogLy8gPT4gZmFsc2VcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBpc1N5bWJvbCh2YWx1ZSkge1xuICAgICAgcmV0dXJuIHR5cGVvZiB2YWx1ZSA9PSAnc3ltYm9sJyB8fFxuICAgICAgICAoaXNPYmplY3RMaWtlKHZhbHVlKSAmJiBiYXNlR2V0VGFnKHZhbHVlKSA9PSBzeW1ib2xUYWcpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIGNsYXNzaWZpZWQgYXMgYSB0eXBlZCBhcnJheS5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAzLjAuMFxuICAgICAqIEBjYXRlZ29yeSBMYW5nXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgYSB0eXBlZCBhcnJheSwgZWxzZSBgZmFsc2VgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLmlzVHlwZWRBcnJheShuZXcgVWludDhBcnJheSk7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqXG4gICAgICogXy5pc1R5cGVkQXJyYXkoW10pO1xuICAgICAqIC8vID0+IGZhbHNlXG4gICAgICovXG4gICAgdmFyIGlzVHlwZWRBcnJheSA9IG5vZGVJc1R5cGVkQXJyYXkgPyBiYXNlVW5hcnkobm9kZUlzVHlwZWRBcnJheSkgOiBiYXNlSXNUeXBlZEFycmF5O1xuXG4gICAgLyoqXG4gICAgICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgYHVuZGVmaW5lZGAuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQHNpbmNlIDAuMS4wXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAY2F0ZWdvcnkgTGFuZ1xuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGB1bmRlZmluZWRgLCBlbHNlIGBmYWxzZWAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uaXNVbmRlZmluZWQodm9pZCAwKTtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICpcbiAgICAgKiBfLmlzVW5kZWZpbmVkKG51bGwpO1xuICAgICAqIC8vID0+IGZhbHNlXG4gICAgICovXG4gICAgZnVuY3Rpb24gaXNVbmRlZmluZWQodmFsdWUpIHtcbiAgICAgIHJldHVybiB2YWx1ZSA9PT0gdW5kZWZpbmVkO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIGNsYXNzaWZpZWQgYXMgYSBgV2Vha01hcGAgb2JqZWN0LlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMy4wXG4gICAgICogQGNhdGVnb3J5IExhbmdcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhIHdlYWsgbWFwLCBlbHNlIGBmYWxzZWAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uaXNXZWFrTWFwKG5ldyBXZWFrTWFwKTtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICpcbiAgICAgKiBfLmlzV2Vha01hcChuZXcgTWFwKTtcbiAgICAgKiAvLyA9PiBmYWxzZVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGlzV2Vha01hcCh2YWx1ZSkge1xuICAgICAgcmV0dXJuIGlzT2JqZWN0TGlrZSh2YWx1ZSkgJiYgZ2V0VGFnKHZhbHVlKSA9PSB3ZWFrTWFwVGFnO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIGNsYXNzaWZpZWQgYXMgYSBgV2Vha1NldGAgb2JqZWN0LlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMy4wXG4gICAgICogQGNhdGVnb3J5IExhbmdcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhIHdlYWsgc2V0LCBlbHNlIGBmYWxzZWAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uaXNXZWFrU2V0KG5ldyBXZWFrU2V0KTtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICpcbiAgICAgKiBfLmlzV2Vha1NldChuZXcgU2V0KTtcbiAgICAgKiAvLyA9PiBmYWxzZVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGlzV2Vha1NldCh2YWx1ZSkge1xuICAgICAgcmV0dXJuIGlzT2JqZWN0TGlrZSh2YWx1ZSkgJiYgYmFzZUdldFRhZyh2YWx1ZSkgPT0gd2Vha1NldFRhZztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBsZXNzIHRoYW4gYG90aGVyYC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAzLjkuMFxuICAgICAqIEBjYXRlZ29yeSBMYW5nXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY29tcGFyZS5cbiAgICAgKiBAcGFyYW0geyp9IG90aGVyIFRoZSBvdGhlciB2YWx1ZSB0byBjb21wYXJlLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGxlc3MgdGhhbiBgb3RoZXJgLFxuICAgICAqICBlbHNlIGBmYWxzZWAuXG4gICAgICogQHNlZSBfLmd0XG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8ubHQoMSwgMyk7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqXG4gICAgICogXy5sdCgzLCAzKTtcbiAgICAgKiAvLyA9PiBmYWxzZVxuICAgICAqXG4gICAgICogXy5sdCgzLCAxKTtcbiAgICAgKiAvLyA9PiBmYWxzZVxuICAgICAqL1xuICAgIHZhciBsdCA9IGNyZWF0ZVJlbGF0aW9uYWxPcGVyYXRpb24oYmFzZUx0KTtcblxuICAgIC8qKlxuICAgICAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIGxlc3MgdGhhbiBvciBlcXVhbCB0byBgb3RoZXJgLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDMuOS4wXG4gICAgICogQGNhdGVnb3J5IExhbmdcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjb21wYXJlLlxuICAgICAqIEBwYXJhbSB7Kn0gb3RoZXIgVGhlIG90aGVyIHZhbHVlIHRvIGNvbXBhcmUuXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgbGVzcyB0aGFuIG9yIGVxdWFsIHRvXG4gICAgICogIGBvdGhlcmAsIGVsc2UgYGZhbHNlYC5cbiAgICAgKiBAc2VlIF8uZ3RlXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8ubHRlKDEsIDMpO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKlxuICAgICAqIF8ubHRlKDMsIDMpO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKlxuICAgICAqIF8ubHRlKDMsIDEpO1xuICAgICAqIC8vID0+IGZhbHNlXG4gICAgICovXG4gICAgdmFyIGx0ZSA9IGNyZWF0ZVJlbGF0aW9uYWxPcGVyYXRpb24oZnVuY3Rpb24odmFsdWUsIG90aGVyKSB7XG4gICAgICByZXR1cm4gdmFsdWUgPD0gb3RoZXI7XG4gICAgfSk7XG5cbiAgICAvKipcbiAgICAgKiBDb252ZXJ0cyBgdmFsdWVgIHRvIGFuIGFycmF5LlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBzaW5jZSAwLjEuMFxuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQGNhdGVnb3J5IExhbmdcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjb252ZXJ0LlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgY29udmVydGVkIGFycmF5LlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLnRvQXJyYXkoeyAnYSc6IDEsICdiJzogMiB9KTtcbiAgICAgKiAvLyA9PiBbMSwgMl1cbiAgICAgKlxuICAgICAqIF8udG9BcnJheSgnYWJjJyk7XG4gICAgICogLy8gPT4gWydhJywgJ2InLCAnYyddXG4gICAgICpcbiAgICAgKiBfLnRvQXJyYXkoMSk7XG4gICAgICogLy8gPT4gW11cbiAgICAgKlxuICAgICAqIF8udG9BcnJheShudWxsKTtcbiAgICAgKiAvLyA9PiBbXVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIHRvQXJyYXkodmFsdWUpIHtcbiAgICAgIGlmICghdmFsdWUpIHtcbiAgICAgICAgcmV0dXJuIFtdO1xuICAgICAgfVxuICAgICAgaWYgKGlzQXJyYXlMaWtlKHZhbHVlKSkge1xuICAgICAgICByZXR1cm4gaXNTdHJpbmcodmFsdWUpID8gc3RyaW5nVG9BcnJheSh2YWx1ZSkgOiBjb3B5QXJyYXkodmFsdWUpO1xuICAgICAgfVxuICAgICAgaWYgKHN5bUl0ZXJhdG9yICYmIHZhbHVlW3N5bUl0ZXJhdG9yXSkge1xuICAgICAgICByZXR1cm4gaXRlcmF0b3JUb0FycmF5KHZhbHVlW3N5bUl0ZXJhdG9yXSgpKTtcbiAgICAgIH1cbiAgICAgIHZhciB0YWcgPSBnZXRUYWcodmFsdWUpLFxuICAgICAgICAgIGZ1bmMgPSB0YWcgPT0gbWFwVGFnID8gbWFwVG9BcnJheSA6ICh0YWcgPT0gc2V0VGFnID8gc2V0VG9BcnJheSA6IHZhbHVlcyk7XG5cbiAgICAgIHJldHVybiBmdW5jKHZhbHVlKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDb252ZXJ0cyBgdmFsdWVgIHRvIGEgZmluaXRlIG51bWJlci5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjEyLjBcbiAgICAgKiBAY2F0ZWdvcnkgTGFuZ1xuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNvbnZlcnQuXG4gICAgICogQHJldHVybnMge251bWJlcn0gUmV0dXJucyB0aGUgY29udmVydGVkIG51bWJlci5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy50b0Zpbml0ZSgzLjIpO1xuICAgICAqIC8vID0+IDMuMlxuICAgICAqXG4gICAgICogXy50b0Zpbml0ZShOdW1iZXIuTUlOX1ZBTFVFKTtcbiAgICAgKiAvLyA9PiA1ZS0zMjRcbiAgICAgKlxuICAgICAqIF8udG9GaW5pdGUoSW5maW5pdHkpO1xuICAgICAqIC8vID0+IDEuNzk3NjkzMTM0ODYyMzE1N2UrMzA4XG4gICAgICpcbiAgICAgKiBfLnRvRmluaXRlKCczLjInKTtcbiAgICAgKiAvLyA9PiAzLjJcbiAgICAgKi9cbiAgICBmdW5jdGlvbiB0b0Zpbml0ZSh2YWx1ZSkge1xuICAgICAgaWYgKCF2YWx1ZSkge1xuICAgICAgICByZXR1cm4gdmFsdWUgPT09IDAgPyB2YWx1ZSA6IDA7XG4gICAgICB9XG4gICAgICB2YWx1ZSA9IHRvTnVtYmVyKHZhbHVlKTtcbiAgICAgIGlmICh2YWx1ZSA9PT0gSU5GSU5JVFkgfHwgdmFsdWUgPT09IC1JTkZJTklUWSkge1xuICAgICAgICB2YXIgc2lnbiA9ICh2YWx1ZSA8IDAgPyAtMSA6IDEpO1xuICAgICAgICByZXR1cm4gc2lnbiAqIE1BWF9JTlRFR0VSO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHZhbHVlID09PSB2YWx1ZSA/IHZhbHVlIDogMDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDb252ZXJ0cyBgdmFsdWVgIHRvIGFuIGludGVnZXIuXG4gICAgICpcbiAgICAgKiAqKk5vdGU6KiogVGhpcyBtZXRob2QgaXMgbG9vc2VseSBiYXNlZCBvblxuICAgICAqIFtgVG9JbnRlZ2VyYF0oaHR0cDovL3d3dy5lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzcuMC8jc2VjLXRvaW50ZWdlcikuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgTGFuZ1xuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNvbnZlcnQuXG4gICAgICogQHJldHVybnMge251bWJlcn0gUmV0dXJucyB0aGUgY29udmVydGVkIGludGVnZXIuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8udG9JbnRlZ2VyKDMuMik7XG4gICAgICogLy8gPT4gM1xuICAgICAqXG4gICAgICogXy50b0ludGVnZXIoTnVtYmVyLk1JTl9WQUxVRSk7XG4gICAgICogLy8gPT4gMFxuICAgICAqXG4gICAgICogXy50b0ludGVnZXIoSW5maW5pdHkpO1xuICAgICAqIC8vID0+IDEuNzk3NjkzMTM0ODYyMzE1N2UrMzA4XG4gICAgICpcbiAgICAgKiBfLnRvSW50ZWdlcignMy4yJyk7XG4gICAgICogLy8gPT4gM1xuICAgICAqL1xuICAgIGZ1bmN0aW9uIHRvSW50ZWdlcih2YWx1ZSkge1xuICAgICAgdmFyIHJlc3VsdCA9IHRvRmluaXRlKHZhbHVlKSxcbiAgICAgICAgICByZW1haW5kZXIgPSByZXN1bHQgJSAxO1xuXG4gICAgICByZXR1cm4gcmVzdWx0ID09PSByZXN1bHQgPyAocmVtYWluZGVyID8gcmVzdWx0IC0gcmVtYWluZGVyIDogcmVzdWx0KSA6IDA7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ29udmVydHMgYHZhbHVlYCB0byBhbiBpbnRlZ2VyIHN1aXRhYmxlIGZvciB1c2UgYXMgdGhlIGxlbmd0aCBvZiBhblxuICAgICAqIGFycmF5LWxpa2Ugb2JqZWN0LlxuICAgICAqXG4gICAgICogKipOb3RlOioqIFRoaXMgbWV0aG9kIGlzIGJhc2VkIG9uXG4gICAgICogW2BUb0xlbmd0aGBdKGh0dHA6Ly9lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzcuMC8jc2VjLXRvbGVuZ3RoKS5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjAuMFxuICAgICAqIEBjYXRlZ29yeSBMYW5nXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY29udmVydC5cbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBSZXR1cm5zIHRoZSBjb252ZXJ0ZWQgaW50ZWdlci5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy50b0xlbmd0aCgzLjIpO1xuICAgICAqIC8vID0+IDNcbiAgICAgKlxuICAgICAqIF8udG9MZW5ndGgoTnVtYmVyLk1JTl9WQUxVRSk7XG4gICAgICogLy8gPT4gMFxuICAgICAqXG4gICAgICogXy50b0xlbmd0aChJbmZpbml0eSk7XG4gICAgICogLy8gPT4gNDI5NDk2NzI5NVxuICAgICAqXG4gICAgICogXy50b0xlbmd0aCgnMy4yJyk7XG4gICAgICogLy8gPT4gM1xuICAgICAqL1xuICAgIGZ1bmN0aW9uIHRvTGVuZ3RoKHZhbHVlKSB7XG4gICAgICByZXR1cm4gdmFsdWUgPyBiYXNlQ2xhbXAodG9JbnRlZ2VyKHZhbHVlKSwgMCwgTUFYX0FSUkFZX0xFTkdUSCkgOiAwO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENvbnZlcnRzIGB2YWx1ZWAgdG8gYSBudW1iZXIuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgTGFuZ1xuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIHByb2Nlc3MuXG4gICAgICogQHJldHVybnMge251bWJlcn0gUmV0dXJucyB0aGUgbnVtYmVyLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLnRvTnVtYmVyKDMuMik7XG4gICAgICogLy8gPT4gMy4yXG4gICAgICpcbiAgICAgKiBfLnRvTnVtYmVyKE51bWJlci5NSU5fVkFMVUUpO1xuICAgICAqIC8vID0+IDVlLTMyNFxuICAgICAqXG4gICAgICogXy50b051bWJlcihJbmZpbml0eSk7XG4gICAgICogLy8gPT4gSW5maW5pdHlcbiAgICAgKlxuICAgICAqIF8udG9OdW1iZXIoJzMuMicpO1xuICAgICAqIC8vID0+IDMuMlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIHRvTnVtYmVyKHZhbHVlKSB7XG4gICAgICBpZiAodHlwZW9mIHZhbHVlID09ICdudW1iZXInKSB7XG4gICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICAgIH1cbiAgICAgIGlmIChpc1N5bWJvbCh2YWx1ZSkpIHtcbiAgICAgICAgcmV0dXJuIE5BTjtcbiAgICAgIH1cbiAgICAgIGlmIChpc09iamVjdCh2YWx1ZSkpIHtcbiAgICAgICAgdmFyIG90aGVyID0gdHlwZW9mIHZhbHVlLnZhbHVlT2YgPT0gJ2Z1bmN0aW9uJyA/IHZhbHVlLnZhbHVlT2YoKSA6IHZhbHVlO1xuICAgICAgICB2YWx1ZSA9IGlzT2JqZWN0KG90aGVyKSA/IChvdGhlciArICcnKSA6IG90aGVyO1xuICAgICAgfVxuICAgICAgaWYgKHR5cGVvZiB2YWx1ZSAhPSAnc3RyaW5nJykge1xuICAgICAgICByZXR1cm4gdmFsdWUgPT09IDAgPyB2YWx1ZSA6ICt2YWx1ZTtcbiAgICAgIH1cbiAgICAgIHZhbHVlID0gYmFzZVRyaW0odmFsdWUpO1xuICAgICAgdmFyIGlzQmluYXJ5ID0gcmVJc0JpbmFyeS50ZXN0KHZhbHVlKTtcbiAgICAgIHJldHVybiAoaXNCaW5hcnkgfHwgcmVJc09jdGFsLnRlc3QodmFsdWUpKVxuICAgICAgICA/IGZyZWVQYXJzZUludCh2YWx1ZS5zbGljZSgyKSwgaXNCaW5hcnkgPyAyIDogOClcbiAgICAgICAgOiAocmVJc0JhZEhleC50ZXN0KHZhbHVlKSA/IE5BTiA6ICt2YWx1ZSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ29udmVydHMgYHZhbHVlYCB0byBhIHBsYWluIG9iamVjdCBmbGF0dGVuaW5nIGluaGVyaXRlZCBlbnVtZXJhYmxlIHN0cmluZ1xuICAgICAqIGtleWVkIHByb3BlcnRpZXMgb2YgYHZhbHVlYCB0byBvd24gcHJvcGVydGllcyBvZiB0aGUgcGxhaW4gb2JqZWN0LlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDMuMC4wXG4gICAgICogQGNhdGVnb3J5IExhbmdcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjb252ZXJ0LlxuICAgICAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgdGhlIGNvbnZlcnRlZCBwbGFpbiBvYmplY3QuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIGZ1bmN0aW9uIEZvbygpIHtcbiAgICAgKiAgIHRoaXMuYiA9IDI7XG4gICAgICogfVxuICAgICAqXG4gICAgICogRm9vLnByb3RvdHlwZS5jID0gMztcbiAgICAgKlxuICAgICAqIF8uYXNzaWduKHsgJ2EnOiAxIH0sIG5ldyBGb28pO1xuICAgICAqIC8vID0+IHsgJ2EnOiAxLCAnYic6IDIgfVxuICAgICAqXG4gICAgICogXy5hc3NpZ24oeyAnYSc6IDEgfSwgXy50b1BsYWluT2JqZWN0KG5ldyBGb28pKTtcbiAgICAgKiAvLyA9PiB7ICdhJzogMSwgJ2InOiAyLCAnYyc6IDMgfVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIHRvUGxhaW5PYmplY3QodmFsdWUpIHtcbiAgICAgIHJldHVybiBjb3B5T2JqZWN0KHZhbHVlLCBrZXlzSW4odmFsdWUpKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDb252ZXJ0cyBgdmFsdWVgIHRvIGEgc2FmZSBpbnRlZ2VyLiBBIHNhZmUgaW50ZWdlciBjYW4gYmUgY29tcGFyZWQgYW5kXG4gICAgICogcmVwcmVzZW50ZWQgY29ycmVjdGx5LlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMC4wXG4gICAgICogQGNhdGVnb3J5IExhbmdcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjb252ZXJ0LlxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9IFJldHVybnMgdGhlIGNvbnZlcnRlZCBpbnRlZ2VyLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLnRvU2FmZUludGVnZXIoMy4yKTtcbiAgICAgKiAvLyA9PiAzXG4gICAgICpcbiAgICAgKiBfLnRvU2FmZUludGVnZXIoTnVtYmVyLk1JTl9WQUxVRSk7XG4gICAgICogLy8gPT4gMFxuICAgICAqXG4gICAgICogXy50b1NhZmVJbnRlZ2VyKEluZmluaXR5KTtcbiAgICAgKiAvLyA9PiA5MDA3MTk5MjU0NzQwOTkxXG4gICAgICpcbiAgICAgKiBfLnRvU2FmZUludGVnZXIoJzMuMicpO1xuICAgICAqIC8vID0+IDNcbiAgICAgKi9cbiAgICBmdW5jdGlvbiB0b1NhZmVJbnRlZ2VyKHZhbHVlKSB7XG4gICAgICByZXR1cm4gdmFsdWVcbiAgICAgICAgPyBiYXNlQ2xhbXAodG9JbnRlZ2VyKHZhbHVlKSwgLU1BWF9TQUZFX0lOVEVHRVIsIE1BWF9TQUZFX0lOVEVHRVIpXG4gICAgICAgIDogKHZhbHVlID09PSAwID8gdmFsdWUgOiAwKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDb252ZXJ0cyBgdmFsdWVgIHRvIGEgc3RyaW5nLiBBbiBlbXB0eSBzdHJpbmcgaXMgcmV0dXJuZWQgZm9yIGBudWxsYFxuICAgICAqIGFuZCBgdW5kZWZpbmVkYCB2YWx1ZXMuIFRoZSBzaWduIG9mIGAtMGAgaXMgcHJlc2VydmVkLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMC4wXG4gICAgICogQGNhdGVnb3J5IExhbmdcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjb252ZXJ0LlxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IFJldHVybnMgdGhlIGNvbnZlcnRlZCBzdHJpbmcuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8udG9TdHJpbmcobnVsbCk7XG4gICAgICogLy8gPT4gJydcbiAgICAgKlxuICAgICAqIF8udG9TdHJpbmcoLTApO1xuICAgICAqIC8vID0+ICctMCdcbiAgICAgKlxuICAgICAqIF8udG9TdHJpbmcoWzEsIDIsIDNdKTtcbiAgICAgKiAvLyA9PiAnMSwyLDMnXG4gICAgICovXG4gICAgZnVuY3Rpb24gdG9TdHJpbmcodmFsdWUpIHtcbiAgICAgIHJldHVybiB2YWx1ZSA9PSBudWxsID8gJycgOiBiYXNlVG9TdHJpbmcodmFsdWUpO1xuICAgIH1cblxuICAgIC8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi9cblxuICAgIC8qKlxuICAgICAqIEFzc2lnbnMgb3duIGVudW1lcmFibGUgc3RyaW5nIGtleWVkIHByb3BlcnRpZXMgb2Ygc291cmNlIG9iamVjdHMgdG8gdGhlXG4gICAgICogZGVzdGluYXRpb24gb2JqZWN0LiBTb3VyY2Ugb2JqZWN0cyBhcmUgYXBwbGllZCBmcm9tIGxlZnQgdG8gcmlnaHQuXG4gICAgICogU3Vic2VxdWVudCBzb3VyY2VzIG92ZXJ3cml0ZSBwcm9wZXJ0eSBhc3NpZ25tZW50cyBvZiBwcmV2aW91cyBzb3VyY2VzLlxuICAgICAqXG4gICAgICogKipOb3RlOioqIFRoaXMgbWV0aG9kIG11dGF0ZXMgYG9iamVjdGAgYW5kIGlzIGxvb3NlbHkgYmFzZWQgb25cbiAgICAgKiBbYE9iamVjdC5hc3NpZ25gXShodHRwczovL21kbi5pby9PYmplY3QvYXNzaWduKS5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAwLjEwLjBcbiAgICAgKiBAY2F0ZWdvcnkgT2JqZWN0XG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgZGVzdGluYXRpb24gb2JqZWN0LlxuICAgICAqIEBwYXJhbSB7Li4uT2JqZWN0fSBbc291cmNlc10gVGhlIHNvdXJjZSBvYmplY3RzLlxuICAgICAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgYG9iamVjdGAuXG4gICAgICogQHNlZSBfLmFzc2lnbkluXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIGZ1bmN0aW9uIEZvbygpIHtcbiAgICAgKiAgIHRoaXMuYSA9IDE7XG4gICAgICogfVxuICAgICAqXG4gICAgICogZnVuY3Rpb24gQmFyKCkge1xuICAgICAqICAgdGhpcy5jID0gMztcbiAgICAgKiB9XG4gICAgICpcbiAgICAgKiBGb28ucHJvdG90eXBlLmIgPSAyO1xuICAgICAqIEJhci5wcm90b3R5cGUuZCA9IDQ7XG4gICAgICpcbiAgICAgKiBfLmFzc2lnbih7ICdhJzogMCB9LCBuZXcgRm9vLCBuZXcgQmFyKTtcbiAgICAgKiAvLyA9PiB7ICdhJzogMSwgJ2MnOiAzIH1cbiAgICAgKi9cbiAgICB2YXIgYXNzaWduID0gY3JlYXRlQXNzaWduZXIoZnVuY3Rpb24ob2JqZWN0LCBzb3VyY2UpIHtcbiAgICAgIGlmIChpc1Byb3RvdHlwZShzb3VyY2UpIHx8IGlzQXJyYXlMaWtlKHNvdXJjZSkpIHtcbiAgICAgICAgY29weU9iamVjdChzb3VyY2UsIGtleXMoc291cmNlKSwgb2JqZWN0KTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgZm9yICh2YXIga2V5IGluIHNvdXJjZSkge1xuICAgICAgICBpZiAoaGFzT3duUHJvcGVydHkuY2FsbChzb3VyY2UsIGtleSkpIHtcbiAgICAgICAgICBhc3NpZ25WYWx1ZShvYmplY3QsIGtleSwgc291cmNlW2tleV0pO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIG1ldGhvZCBpcyBsaWtlIGBfLmFzc2lnbmAgZXhjZXB0IHRoYXQgaXQgaXRlcmF0ZXMgb3ZlciBvd24gYW5kXG4gICAgICogaW5oZXJpdGVkIHNvdXJjZSBwcm9wZXJ0aWVzLlxuICAgICAqXG4gICAgICogKipOb3RlOioqIFRoaXMgbWV0aG9kIG11dGF0ZXMgYG9iamVjdGAuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4wLjBcbiAgICAgKiBAYWxpYXMgZXh0ZW5kXG4gICAgICogQGNhdGVnb3J5IE9iamVjdFxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIGRlc3RpbmF0aW9uIG9iamVjdC5cbiAgICAgKiBAcGFyYW0gey4uLk9iamVjdH0gW3NvdXJjZXNdIFRoZSBzb3VyY2Ugb2JqZWN0cy5cbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIGBvYmplY3RgLlxuICAgICAqIEBzZWUgXy5hc3NpZ25cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogZnVuY3Rpb24gRm9vKCkge1xuICAgICAqICAgdGhpcy5hID0gMTtcbiAgICAgKiB9XG4gICAgICpcbiAgICAgKiBmdW5jdGlvbiBCYXIoKSB7XG4gICAgICogICB0aGlzLmMgPSAzO1xuICAgICAqIH1cbiAgICAgKlxuICAgICAqIEZvby5wcm90b3R5cGUuYiA9IDI7XG4gICAgICogQmFyLnByb3RvdHlwZS5kID0gNDtcbiAgICAgKlxuICAgICAqIF8uYXNzaWduSW4oeyAnYSc6IDAgfSwgbmV3IEZvbywgbmV3IEJhcik7XG4gICAgICogLy8gPT4geyAnYSc6IDEsICdiJzogMiwgJ2MnOiAzLCAnZCc6IDQgfVxuICAgICAqL1xuICAgIHZhciBhc3NpZ25JbiA9IGNyZWF0ZUFzc2lnbmVyKGZ1bmN0aW9uKG9iamVjdCwgc291cmNlKSB7XG4gICAgICBjb3B5T2JqZWN0KHNvdXJjZSwga2V5c0luKHNvdXJjZSksIG9iamVjdCk7XG4gICAgfSk7XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIG1ldGhvZCBpcyBsaWtlIGBfLmFzc2lnbkluYCBleGNlcHQgdGhhdCBpdCBhY2NlcHRzIGBjdXN0b21pemVyYFxuICAgICAqIHdoaWNoIGlzIGludm9rZWQgdG8gcHJvZHVjZSB0aGUgYXNzaWduZWQgdmFsdWVzLiBJZiBgY3VzdG9taXplcmAgcmV0dXJuc1xuICAgICAqIGB1bmRlZmluZWRgLCBhc3NpZ25tZW50IGlzIGhhbmRsZWQgYnkgdGhlIG1ldGhvZCBpbnN0ZWFkLiBUaGUgYGN1c3RvbWl6ZXJgXG4gICAgICogaXMgaW52b2tlZCB3aXRoIGZpdmUgYXJndW1lbnRzOiAob2JqVmFsdWUsIHNyY1ZhbHVlLCBrZXksIG9iamVjdCwgc291cmNlKS5cbiAgICAgKlxuICAgICAqICoqTm90ZToqKiBUaGlzIG1ldGhvZCBtdXRhdGVzIGBvYmplY3RgLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMC4wXG4gICAgICogQGFsaWFzIGV4dGVuZFdpdGhcbiAgICAgKiBAY2F0ZWdvcnkgT2JqZWN0XG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgZGVzdGluYXRpb24gb2JqZWN0LlxuICAgICAqIEBwYXJhbSB7Li4uT2JqZWN0fSBzb3VyY2VzIFRoZSBzb3VyY2Ugb2JqZWN0cy5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbY3VzdG9taXplcl0gVGhlIGZ1bmN0aW9uIHRvIGN1c3RvbWl6ZSBhc3NpZ25lZCB2YWx1ZXMuXG4gICAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyBgb2JqZWN0YC5cbiAgICAgKiBAc2VlIF8uYXNzaWduV2l0aFxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBmdW5jdGlvbiBjdXN0b21pemVyKG9ialZhbHVlLCBzcmNWYWx1ZSkge1xuICAgICAqICAgcmV0dXJuIF8uaXNVbmRlZmluZWQob2JqVmFsdWUpID8gc3JjVmFsdWUgOiBvYmpWYWx1ZTtcbiAgICAgKiB9XG4gICAgICpcbiAgICAgKiB2YXIgZGVmYXVsdHMgPSBfLnBhcnRpYWxSaWdodChfLmFzc2lnbkluV2l0aCwgY3VzdG9taXplcik7XG4gICAgICpcbiAgICAgKiBkZWZhdWx0cyh7ICdhJzogMSB9LCB7ICdiJzogMiB9LCB7ICdhJzogMyB9KTtcbiAgICAgKiAvLyA9PiB7ICdhJzogMSwgJ2InOiAyIH1cbiAgICAgKi9cbiAgICB2YXIgYXNzaWduSW5XaXRoID0gY3JlYXRlQXNzaWduZXIoZnVuY3Rpb24ob2JqZWN0LCBzb3VyY2UsIHNyY0luZGV4LCBjdXN0b21pemVyKSB7XG4gICAgICBjb3B5T2JqZWN0KHNvdXJjZSwga2V5c0luKHNvdXJjZSksIG9iamVjdCwgY3VzdG9taXplcik7XG4gICAgfSk7XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIG1ldGhvZCBpcyBsaWtlIGBfLmFzc2lnbmAgZXhjZXB0IHRoYXQgaXQgYWNjZXB0cyBgY3VzdG9taXplcmBcbiAgICAgKiB3aGljaCBpcyBpbnZva2VkIHRvIHByb2R1Y2UgdGhlIGFzc2lnbmVkIHZhbHVlcy4gSWYgYGN1c3RvbWl6ZXJgIHJldHVybnNcbiAgICAgKiBgdW5kZWZpbmVkYCwgYXNzaWdubWVudCBpcyBoYW5kbGVkIGJ5IHRoZSBtZXRob2QgaW5zdGVhZC4gVGhlIGBjdXN0b21pemVyYFxuICAgICAqIGlzIGludm9rZWQgd2l0aCBmaXZlIGFyZ3VtZW50czogKG9ialZhbHVlLCBzcmNWYWx1ZSwga2V5LCBvYmplY3QsIHNvdXJjZSkuXG4gICAgICpcbiAgICAgKiAqKk5vdGU6KiogVGhpcyBtZXRob2QgbXV0YXRlcyBgb2JqZWN0YC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjAuMFxuICAgICAqIEBjYXRlZ29yeSBPYmplY3RcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBkZXN0aW5hdGlvbiBvYmplY3QuXG4gICAgICogQHBhcmFtIHsuLi5PYmplY3R9IHNvdXJjZXMgVGhlIHNvdXJjZSBvYmplY3RzLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IFtjdXN0b21pemVyXSBUaGUgZnVuY3Rpb24gdG8gY3VzdG9taXplIGFzc2lnbmVkIHZhbHVlcy5cbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIGBvYmplY3RgLlxuICAgICAqIEBzZWUgXy5hc3NpZ25JbldpdGhcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogZnVuY3Rpb24gY3VzdG9taXplcihvYmpWYWx1ZSwgc3JjVmFsdWUpIHtcbiAgICAgKiAgIHJldHVybiBfLmlzVW5kZWZpbmVkKG9ialZhbHVlKSA/IHNyY1ZhbHVlIDogb2JqVmFsdWU7XG4gICAgICogfVxuICAgICAqXG4gICAgICogdmFyIGRlZmF1bHRzID0gXy5wYXJ0aWFsUmlnaHQoXy5hc3NpZ25XaXRoLCBjdXN0b21pemVyKTtcbiAgICAgKlxuICAgICAqIGRlZmF1bHRzKHsgJ2EnOiAxIH0sIHsgJ2InOiAyIH0sIHsgJ2EnOiAzIH0pO1xuICAgICAqIC8vID0+IHsgJ2EnOiAxLCAnYic6IDIgfVxuICAgICAqL1xuICAgIHZhciBhc3NpZ25XaXRoID0gY3JlYXRlQXNzaWduZXIoZnVuY3Rpb24ob2JqZWN0LCBzb3VyY2UsIHNyY0luZGV4LCBjdXN0b21pemVyKSB7XG4gICAgICBjb3B5T2JqZWN0KHNvdXJjZSwga2V5cyhzb3VyY2UpLCBvYmplY3QsIGN1c3RvbWl6ZXIpO1xuICAgIH0pO1xuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhbiBhcnJheSBvZiB2YWx1ZXMgY29ycmVzcG9uZGluZyB0byBgcGF0aHNgIG9mIGBvYmplY3RgLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDEuMC4wXG4gICAgICogQGNhdGVnb3J5IE9iamVjdFxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBpdGVyYXRlIG92ZXIuXG4gICAgICogQHBhcmFtIHsuLi4oc3RyaW5nfHN0cmluZ1tdKX0gW3BhdGhzXSBUaGUgcHJvcGVydHkgcGF0aHMgdG8gcGljay5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIHBpY2tlZCB2YWx1ZXMuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciBvYmplY3QgPSB7ICdhJzogW3sgJ2InOiB7ICdjJzogMyB9IH0sIDRdIH07XG4gICAgICpcbiAgICAgKiBfLmF0KG9iamVjdCwgWydhWzBdLmIuYycsICdhWzFdJ10pO1xuICAgICAqIC8vID0+IFszLCA0XVxuICAgICAqL1xuICAgIHZhciBhdCA9IGZsYXRSZXN0KGJhc2VBdCk7XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGFuIG9iamVjdCB0aGF0IGluaGVyaXRzIGZyb20gdGhlIGBwcm90b3R5cGVgIG9iamVjdC4gSWYgYVxuICAgICAqIGBwcm9wZXJ0aWVzYCBvYmplY3QgaXMgZ2l2ZW4sIGl0cyBvd24gZW51bWVyYWJsZSBzdHJpbmcga2V5ZWQgcHJvcGVydGllc1xuICAgICAqIGFyZSBhc3NpZ25lZCB0byB0aGUgY3JlYXRlZCBvYmplY3QuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMi4zLjBcbiAgICAgKiBAY2F0ZWdvcnkgT2JqZWN0XG4gICAgICogQHBhcmFtIHtPYmplY3R9IHByb3RvdHlwZSBUaGUgb2JqZWN0IHRvIGluaGVyaXQgZnJvbS5cbiAgICAgKiBAcGFyYW0ge09iamVjdH0gW3Byb3BlcnRpZXNdIFRoZSBwcm9wZXJ0aWVzIHRvIGFzc2lnbiB0byB0aGUgb2JqZWN0LlxuICAgICAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgdGhlIG5ldyBvYmplY3QuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIGZ1bmN0aW9uIFNoYXBlKCkge1xuICAgICAqICAgdGhpcy54ID0gMDtcbiAgICAgKiAgIHRoaXMueSA9IDA7XG4gICAgICogfVxuICAgICAqXG4gICAgICogZnVuY3Rpb24gQ2lyY2xlKCkge1xuICAgICAqICAgU2hhcGUuY2FsbCh0aGlzKTtcbiAgICAgKiB9XG4gICAgICpcbiAgICAgKiBDaXJjbGUucHJvdG90eXBlID0gXy5jcmVhdGUoU2hhcGUucHJvdG90eXBlLCB7XG4gICAgICogICAnY29uc3RydWN0b3InOiBDaXJjbGVcbiAgICAgKiB9KTtcbiAgICAgKlxuICAgICAqIHZhciBjaXJjbGUgPSBuZXcgQ2lyY2xlO1xuICAgICAqIGNpcmNsZSBpbnN0YW5jZW9mIENpcmNsZTtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICpcbiAgICAgKiBjaXJjbGUgaW5zdGFuY2VvZiBTaGFwZTtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICovXG4gICAgZnVuY3Rpb24gY3JlYXRlKHByb3RvdHlwZSwgcHJvcGVydGllcykge1xuICAgICAgdmFyIHJlc3VsdCA9IGJhc2VDcmVhdGUocHJvdG90eXBlKTtcbiAgICAgIHJldHVybiBwcm9wZXJ0aWVzID09IG51bGwgPyByZXN1bHQgOiBiYXNlQXNzaWduKHJlc3VsdCwgcHJvcGVydGllcyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQXNzaWducyBvd24gYW5kIGluaGVyaXRlZCBlbnVtZXJhYmxlIHN0cmluZyBrZXllZCBwcm9wZXJ0aWVzIG9mIHNvdXJjZVxuICAgICAqIG9iamVjdHMgdG8gdGhlIGRlc3RpbmF0aW9uIG9iamVjdCBmb3IgYWxsIGRlc3RpbmF0aW9uIHByb3BlcnRpZXMgdGhhdFxuICAgICAqIHJlc29sdmUgdG8gYHVuZGVmaW5lZGAuIFNvdXJjZSBvYmplY3RzIGFyZSBhcHBsaWVkIGZyb20gbGVmdCB0byByaWdodC5cbiAgICAgKiBPbmNlIGEgcHJvcGVydHkgaXMgc2V0LCBhZGRpdGlvbmFsIHZhbHVlcyBvZiB0aGUgc2FtZSBwcm9wZXJ0eSBhcmUgaWdub3JlZC5cbiAgICAgKlxuICAgICAqICoqTm90ZToqKiBUaGlzIG1ldGhvZCBtdXRhdGVzIGBvYmplY3RgLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBzaW5jZSAwLjEuMFxuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQGNhdGVnb3J5IE9iamVjdFxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIGRlc3RpbmF0aW9uIG9iamVjdC5cbiAgICAgKiBAcGFyYW0gey4uLk9iamVjdH0gW3NvdXJjZXNdIFRoZSBzb3VyY2Ugb2JqZWN0cy5cbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIGBvYmplY3RgLlxuICAgICAqIEBzZWUgXy5kZWZhdWx0c0RlZXBcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5kZWZhdWx0cyh7ICdhJzogMSB9LCB7ICdiJzogMiB9LCB7ICdhJzogMyB9KTtcbiAgICAgKiAvLyA9PiB7ICdhJzogMSwgJ2InOiAyIH1cbiAgICAgKi9cbiAgICB2YXIgZGVmYXVsdHMgPSBiYXNlUmVzdChmdW5jdGlvbihvYmplY3QsIHNvdXJjZXMpIHtcbiAgICAgIG9iamVjdCA9IE9iamVjdChvYmplY3QpO1xuXG4gICAgICB2YXIgaW5kZXggPSAtMTtcbiAgICAgIHZhciBsZW5ndGggPSBzb3VyY2VzLmxlbmd0aDtcbiAgICAgIHZhciBndWFyZCA9IGxlbmd0aCA+IDIgPyBzb3VyY2VzWzJdIDogdW5kZWZpbmVkO1xuXG4gICAgICBpZiAoZ3VhcmQgJiYgaXNJdGVyYXRlZUNhbGwoc291cmNlc1swXSwgc291cmNlc1sxXSwgZ3VhcmQpKSB7XG4gICAgICAgIGxlbmd0aCA9IDE7XG4gICAgICB9XG5cbiAgICAgIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XG4gICAgICAgIHZhciBzb3VyY2UgPSBzb3VyY2VzW2luZGV4XTtcbiAgICAgICAgdmFyIHByb3BzID0ga2V5c0luKHNvdXJjZSk7XG4gICAgICAgIHZhciBwcm9wc0luZGV4ID0gLTE7XG4gICAgICAgIHZhciBwcm9wc0xlbmd0aCA9IHByb3BzLmxlbmd0aDtcblxuICAgICAgICB3aGlsZSAoKytwcm9wc0luZGV4IDwgcHJvcHNMZW5ndGgpIHtcbiAgICAgICAgICB2YXIga2V5ID0gcHJvcHNbcHJvcHNJbmRleF07XG4gICAgICAgICAgdmFyIHZhbHVlID0gb2JqZWN0W2tleV07XG5cbiAgICAgICAgICBpZiAodmFsdWUgPT09IHVuZGVmaW5lZCB8fFxuICAgICAgICAgICAgICAoZXEodmFsdWUsIG9iamVjdFByb3RvW2tleV0pICYmICFoYXNPd25Qcm9wZXJ0eS5jYWxsKG9iamVjdCwga2V5KSkpIHtcbiAgICAgICAgICAgIG9iamVjdFtrZXldID0gc291cmNlW2tleV07XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBvYmplY3Q7XG4gICAgfSk7XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIG1ldGhvZCBpcyBsaWtlIGBfLmRlZmF1bHRzYCBleGNlcHQgdGhhdCBpdCByZWN1cnNpdmVseSBhc3NpZ25zXG4gICAgICogZGVmYXVsdCBwcm9wZXJ0aWVzLlxuICAgICAqXG4gICAgICogKipOb3RlOioqIFRoaXMgbWV0aG9kIG11dGF0ZXMgYG9iamVjdGAuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMy4xMC4wXG4gICAgICogQGNhdGVnb3J5IE9iamVjdFxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIGRlc3RpbmF0aW9uIG9iamVjdC5cbiAgICAgKiBAcGFyYW0gey4uLk9iamVjdH0gW3NvdXJjZXNdIFRoZSBzb3VyY2Ugb2JqZWN0cy5cbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIGBvYmplY3RgLlxuICAgICAqIEBzZWUgXy5kZWZhdWx0c1xuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLmRlZmF1bHRzRGVlcCh7ICdhJzogeyAnYic6IDIgfSB9LCB7ICdhJzogeyAnYic6IDEsICdjJzogMyB9IH0pO1xuICAgICAqIC8vID0+IHsgJ2EnOiB7ICdiJzogMiwgJ2MnOiAzIH0gfVxuICAgICAqL1xuICAgIHZhciBkZWZhdWx0c0RlZXAgPSBiYXNlUmVzdChmdW5jdGlvbihhcmdzKSB7XG4gICAgICBhcmdzLnB1c2godW5kZWZpbmVkLCBjdXN0b21EZWZhdWx0c01lcmdlKTtcbiAgICAgIHJldHVybiBhcHBseShtZXJnZVdpdGgsIHVuZGVmaW5lZCwgYXJncyk7XG4gICAgfSk7XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIG1ldGhvZCBpcyBsaWtlIGBfLmZpbmRgIGV4Y2VwdCB0aGF0IGl0IHJldHVybnMgdGhlIGtleSBvZiB0aGUgZmlyc3RcbiAgICAgKiBlbGVtZW50IGBwcmVkaWNhdGVgIHJldHVybnMgdHJ1dGh5IGZvciBpbnN0ZWFkIG9mIHRoZSBlbGVtZW50IGl0c2VsZi5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAxLjEuMFxuICAgICAqIEBjYXRlZ29yeSBPYmplY3RcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gaW5zcGVjdC5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbcHJlZGljYXRlPV8uaWRlbnRpdHldIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uXG4gICAgICogQHJldHVybnMge3N0cmluZ3x1bmRlZmluZWR9IFJldHVybnMgdGhlIGtleSBvZiB0aGUgbWF0Y2hlZCBlbGVtZW50LFxuICAgICAqICBlbHNlIGB1bmRlZmluZWRgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgdXNlcnMgPSB7XG4gICAgICogICAnYmFybmV5JzogIHsgJ2FnZSc6IDM2LCAnYWN0aXZlJzogdHJ1ZSB9LFxuICAgICAqICAgJ2ZyZWQnOiAgICB7ICdhZ2UnOiA0MCwgJ2FjdGl2ZSc6IGZhbHNlIH0sXG4gICAgICogICAncGViYmxlcyc6IHsgJ2FnZSc6IDEsICAnYWN0aXZlJzogdHJ1ZSB9XG4gICAgICogfTtcbiAgICAgKlxuICAgICAqIF8uZmluZEtleSh1c2VycywgZnVuY3Rpb24obykgeyByZXR1cm4gby5hZ2UgPCA0MDsgfSk7XG4gICAgICogLy8gPT4gJ2Jhcm5leScgKGl0ZXJhdGlvbiBvcmRlciBpcyBub3QgZ3VhcmFudGVlZClcbiAgICAgKlxuICAgICAqIC8vIFRoZSBgXy5tYXRjaGVzYCBpdGVyYXRlZSBzaG9ydGhhbmQuXG4gICAgICogXy5maW5kS2V5KHVzZXJzLCB7ICdhZ2UnOiAxLCAnYWN0aXZlJzogdHJ1ZSB9KTtcbiAgICAgKiAvLyA9PiAncGViYmxlcydcbiAgICAgKlxuICAgICAqIC8vIFRoZSBgXy5tYXRjaGVzUHJvcGVydHlgIGl0ZXJhdGVlIHNob3J0aGFuZC5cbiAgICAgKiBfLmZpbmRLZXkodXNlcnMsIFsnYWN0aXZlJywgZmFsc2VdKTtcbiAgICAgKiAvLyA9PiAnZnJlZCdcbiAgICAgKlxuICAgICAqIC8vIFRoZSBgXy5wcm9wZXJ0eWAgaXRlcmF0ZWUgc2hvcnRoYW5kLlxuICAgICAqIF8uZmluZEtleSh1c2VycywgJ2FjdGl2ZScpO1xuICAgICAqIC8vID0+ICdiYXJuZXknXG4gICAgICovXG4gICAgZnVuY3Rpb24gZmluZEtleShvYmplY3QsIHByZWRpY2F0ZSkge1xuICAgICAgcmV0dXJuIGJhc2VGaW5kS2V5KG9iamVjdCwgZ2V0SXRlcmF0ZWUocHJlZGljYXRlLCAzKSwgYmFzZUZvck93bik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgaXMgbGlrZSBgXy5maW5kS2V5YCBleGNlcHQgdGhhdCBpdCBpdGVyYXRlcyBvdmVyIGVsZW1lbnRzIG9mXG4gICAgICogYSBjb2xsZWN0aW9uIGluIHRoZSBvcHBvc2l0ZSBvcmRlci5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAyLjAuMFxuICAgICAqIEBjYXRlZ29yeSBPYmplY3RcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gaW5zcGVjdC5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbcHJlZGljYXRlPV8uaWRlbnRpdHldIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uXG4gICAgICogQHJldHVybnMge3N0cmluZ3x1bmRlZmluZWR9IFJldHVybnMgdGhlIGtleSBvZiB0aGUgbWF0Y2hlZCBlbGVtZW50LFxuICAgICAqICBlbHNlIGB1bmRlZmluZWRgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgdXNlcnMgPSB7XG4gICAgICogICAnYmFybmV5JzogIHsgJ2FnZSc6IDM2LCAnYWN0aXZlJzogdHJ1ZSB9LFxuICAgICAqICAgJ2ZyZWQnOiAgICB7ICdhZ2UnOiA0MCwgJ2FjdGl2ZSc6IGZhbHNlIH0sXG4gICAgICogICAncGViYmxlcyc6IHsgJ2FnZSc6IDEsICAnYWN0aXZlJzogdHJ1ZSB9XG4gICAgICogfTtcbiAgICAgKlxuICAgICAqIF8uZmluZExhc3RLZXkodXNlcnMsIGZ1bmN0aW9uKG8pIHsgcmV0dXJuIG8uYWdlIDwgNDA7IH0pO1xuICAgICAqIC8vID0+IHJldHVybnMgJ3BlYmJsZXMnIGFzc3VtaW5nIGBfLmZpbmRLZXlgIHJldHVybnMgJ2Jhcm5leSdcbiAgICAgKlxuICAgICAqIC8vIFRoZSBgXy5tYXRjaGVzYCBpdGVyYXRlZSBzaG9ydGhhbmQuXG4gICAgICogXy5maW5kTGFzdEtleSh1c2VycywgeyAnYWdlJzogMzYsICdhY3RpdmUnOiB0cnVlIH0pO1xuICAgICAqIC8vID0+ICdiYXJuZXknXG4gICAgICpcbiAgICAgKiAvLyBUaGUgYF8ubWF0Y2hlc1Byb3BlcnR5YCBpdGVyYXRlZSBzaG9ydGhhbmQuXG4gICAgICogXy5maW5kTGFzdEtleSh1c2VycywgWydhY3RpdmUnLCBmYWxzZV0pO1xuICAgICAqIC8vID0+ICdmcmVkJ1xuICAgICAqXG4gICAgICogLy8gVGhlIGBfLnByb3BlcnR5YCBpdGVyYXRlZSBzaG9ydGhhbmQuXG4gICAgICogXy5maW5kTGFzdEtleSh1c2VycywgJ2FjdGl2ZScpO1xuICAgICAqIC8vID0+ICdwZWJibGVzJ1xuICAgICAqL1xuICAgIGZ1bmN0aW9uIGZpbmRMYXN0S2V5KG9iamVjdCwgcHJlZGljYXRlKSB7XG4gICAgICByZXR1cm4gYmFzZUZpbmRLZXkob2JqZWN0LCBnZXRJdGVyYXRlZShwcmVkaWNhdGUsIDMpLCBiYXNlRm9yT3duUmlnaHQpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEl0ZXJhdGVzIG92ZXIgb3duIGFuZCBpbmhlcml0ZWQgZW51bWVyYWJsZSBzdHJpbmcga2V5ZWQgcHJvcGVydGllcyBvZiBhblxuICAgICAqIG9iamVjdCBhbmQgaW52b2tlcyBgaXRlcmF0ZWVgIGZvciBlYWNoIHByb3BlcnR5LiBUaGUgaXRlcmF0ZWUgaXMgaW52b2tlZFxuICAgICAqIHdpdGggdGhyZWUgYXJndW1lbnRzOiAodmFsdWUsIGtleSwgb2JqZWN0KS4gSXRlcmF0ZWUgZnVuY3Rpb25zIG1heSBleGl0XG4gICAgICogaXRlcmF0aW9uIGVhcmx5IGJ5IGV4cGxpY2l0bHkgcmV0dXJuaW5nIGBmYWxzZWAuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMC4zLjBcbiAgICAgKiBAY2F0ZWdvcnkgT2JqZWN0XG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIGl0ZXJhdGUgb3Zlci5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbaXRlcmF0ZWU9Xy5pZGVudGl0eV0gVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIGl0ZXJhdGlvbi5cbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIGBvYmplY3RgLlxuICAgICAqIEBzZWUgXy5mb3JJblJpZ2h0XG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIGZ1bmN0aW9uIEZvbygpIHtcbiAgICAgKiAgIHRoaXMuYSA9IDE7XG4gICAgICogICB0aGlzLmIgPSAyO1xuICAgICAqIH1cbiAgICAgKlxuICAgICAqIEZvby5wcm90b3R5cGUuYyA9IDM7XG4gICAgICpcbiAgICAgKiBfLmZvckluKG5ldyBGb28sIGZ1bmN0aW9uKHZhbHVlLCBrZXkpIHtcbiAgICAgKiAgIGNvbnNvbGUubG9nKGtleSk7XG4gICAgICogfSk7XG4gICAgICogLy8gPT4gTG9ncyAnYScsICdiJywgdGhlbiAnYycgKGl0ZXJhdGlvbiBvcmRlciBpcyBub3QgZ3VhcmFudGVlZCkuXG4gICAgICovXG4gICAgZnVuY3Rpb24gZm9ySW4ob2JqZWN0LCBpdGVyYXRlZSkge1xuICAgICAgcmV0dXJuIG9iamVjdCA9PSBudWxsXG4gICAgICAgID8gb2JqZWN0XG4gICAgICAgIDogYmFzZUZvcihvYmplY3QsIGdldEl0ZXJhdGVlKGl0ZXJhdGVlLCAzKSwga2V5c0luKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIG1ldGhvZCBpcyBsaWtlIGBfLmZvckluYCBleGNlcHQgdGhhdCBpdCBpdGVyYXRlcyBvdmVyIHByb3BlcnRpZXMgb2ZcbiAgICAgKiBgb2JqZWN0YCBpbiB0aGUgb3Bwb3NpdGUgb3JkZXIuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMi4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgT2JqZWN0XG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIGl0ZXJhdGUgb3Zlci5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbaXRlcmF0ZWU9Xy5pZGVudGl0eV0gVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIGl0ZXJhdGlvbi5cbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIGBvYmplY3RgLlxuICAgICAqIEBzZWUgXy5mb3JJblxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBmdW5jdGlvbiBGb28oKSB7XG4gICAgICogICB0aGlzLmEgPSAxO1xuICAgICAqICAgdGhpcy5iID0gMjtcbiAgICAgKiB9XG4gICAgICpcbiAgICAgKiBGb28ucHJvdG90eXBlLmMgPSAzO1xuICAgICAqXG4gICAgICogXy5mb3JJblJpZ2h0KG5ldyBGb28sIGZ1bmN0aW9uKHZhbHVlLCBrZXkpIHtcbiAgICAgKiAgIGNvbnNvbGUubG9nKGtleSk7XG4gICAgICogfSk7XG4gICAgICogLy8gPT4gTG9ncyAnYycsICdiJywgdGhlbiAnYScgYXNzdW1pbmcgYF8uZm9ySW5gIGxvZ3MgJ2EnLCAnYicsIHRoZW4gJ2MnLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGZvckluUmlnaHQob2JqZWN0LCBpdGVyYXRlZSkge1xuICAgICAgcmV0dXJuIG9iamVjdCA9PSBudWxsXG4gICAgICAgID8gb2JqZWN0XG4gICAgICAgIDogYmFzZUZvclJpZ2h0KG9iamVjdCwgZ2V0SXRlcmF0ZWUoaXRlcmF0ZWUsIDMpLCBrZXlzSW4pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEl0ZXJhdGVzIG92ZXIgb3duIGVudW1lcmFibGUgc3RyaW5nIGtleWVkIHByb3BlcnRpZXMgb2YgYW4gb2JqZWN0IGFuZFxuICAgICAqIGludm9rZXMgYGl0ZXJhdGVlYCBmb3IgZWFjaCBwcm9wZXJ0eS4gVGhlIGl0ZXJhdGVlIGlzIGludm9rZWQgd2l0aCB0aHJlZVxuICAgICAqIGFyZ3VtZW50czogKHZhbHVlLCBrZXksIG9iamVjdCkuIEl0ZXJhdGVlIGZ1bmN0aW9ucyBtYXkgZXhpdCBpdGVyYXRpb25cbiAgICAgKiBlYXJseSBieSBleHBsaWNpdGx5IHJldHVybmluZyBgZmFsc2VgLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDAuMy4wXG4gICAgICogQGNhdGVnb3J5IE9iamVjdFxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBpdGVyYXRlIG92ZXIuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW2l0ZXJhdGVlPV8uaWRlbnRpdHldIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uXG4gICAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyBgb2JqZWN0YC5cbiAgICAgKiBAc2VlIF8uZm9yT3duUmlnaHRcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogZnVuY3Rpb24gRm9vKCkge1xuICAgICAqICAgdGhpcy5hID0gMTtcbiAgICAgKiAgIHRoaXMuYiA9IDI7XG4gICAgICogfVxuICAgICAqXG4gICAgICogRm9vLnByb3RvdHlwZS5jID0gMztcbiAgICAgKlxuICAgICAqIF8uZm9yT3duKG5ldyBGb28sIGZ1bmN0aW9uKHZhbHVlLCBrZXkpIHtcbiAgICAgKiAgIGNvbnNvbGUubG9nKGtleSk7XG4gICAgICogfSk7XG4gICAgICogLy8gPT4gTG9ncyAnYScgdGhlbiAnYicgKGl0ZXJhdGlvbiBvcmRlciBpcyBub3QgZ3VhcmFudGVlZCkuXG4gICAgICovXG4gICAgZnVuY3Rpb24gZm9yT3duKG9iamVjdCwgaXRlcmF0ZWUpIHtcbiAgICAgIHJldHVybiBvYmplY3QgJiYgYmFzZUZvck93bihvYmplY3QsIGdldEl0ZXJhdGVlKGl0ZXJhdGVlLCAzKSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgaXMgbGlrZSBgXy5mb3JPd25gIGV4Y2VwdCB0aGF0IGl0IGl0ZXJhdGVzIG92ZXIgcHJvcGVydGllcyBvZlxuICAgICAqIGBvYmplY3RgIGluIHRoZSBvcHBvc2l0ZSBvcmRlci5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAyLjAuMFxuICAgICAqIEBjYXRlZ29yeSBPYmplY3RcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gaXRlcmF0ZSBvdmVyLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IFtpdGVyYXRlZT1fLmlkZW50aXR5XSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICAgICAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgYG9iamVjdGAuXG4gICAgICogQHNlZSBfLmZvck93blxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBmdW5jdGlvbiBGb28oKSB7XG4gICAgICogICB0aGlzLmEgPSAxO1xuICAgICAqICAgdGhpcy5iID0gMjtcbiAgICAgKiB9XG4gICAgICpcbiAgICAgKiBGb28ucHJvdG90eXBlLmMgPSAzO1xuICAgICAqXG4gICAgICogXy5mb3JPd25SaWdodChuZXcgRm9vLCBmdW5jdGlvbih2YWx1ZSwga2V5KSB7XG4gICAgICogICBjb25zb2xlLmxvZyhrZXkpO1xuICAgICAqIH0pO1xuICAgICAqIC8vID0+IExvZ3MgJ2InIHRoZW4gJ2EnIGFzc3VtaW5nIGBfLmZvck93bmAgbG9ncyAnYScgdGhlbiAnYicuXG4gICAgICovXG4gICAgZnVuY3Rpb24gZm9yT3duUmlnaHQob2JqZWN0LCBpdGVyYXRlZSkge1xuICAgICAgcmV0dXJuIG9iamVjdCAmJiBiYXNlRm9yT3duUmlnaHQob2JqZWN0LCBnZXRJdGVyYXRlZShpdGVyYXRlZSwgMykpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYW4gYXJyYXkgb2YgZnVuY3Rpb24gcHJvcGVydHkgbmFtZXMgZnJvbSBvd24gZW51bWVyYWJsZSBwcm9wZXJ0aWVzXG4gICAgICogb2YgYG9iamVjdGAuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQHNpbmNlIDAuMS4wXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAY2F0ZWdvcnkgT2JqZWN0XG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIGluc3BlY3QuXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBmdW5jdGlvbiBuYW1lcy5cbiAgICAgKiBAc2VlIF8uZnVuY3Rpb25zSW5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogZnVuY3Rpb24gRm9vKCkge1xuICAgICAqICAgdGhpcy5hID0gXy5jb25zdGFudCgnYScpO1xuICAgICAqICAgdGhpcy5iID0gXy5jb25zdGFudCgnYicpO1xuICAgICAqIH1cbiAgICAgKlxuICAgICAqIEZvby5wcm90b3R5cGUuYyA9IF8uY29uc3RhbnQoJ2MnKTtcbiAgICAgKlxuICAgICAqIF8uZnVuY3Rpb25zKG5ldyBGb28pO1xuICAgICAqIC8vID0+IFsnYScsICdiJ11cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBmdW5jdGlvbnMob2JqZWN0KSB7XG4gICAgICByZXR1cm4gb2JqZWN0ID09IG51bGwgPyBbXSA6IGJhc2VGdW5jdGlvbnMob2JqZWN0LCBrZXlzKG9iamVjdCkpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYW4gYXJyYXkgb2YgZnVuY3Rpb24gcHJvcGVydHkgbmFtZXMgZnJvbSBvd24gYW5kIGluaGVyaXRlZFxuICAgICAqIGVudW1lcmFibGUgcHJvcGVydGllcyBvZiBgb2JqZWN0YC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjAuMFxuICAgICAqIEBjYXRlZ29yeSBPYmplY3RcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gaW5zcGVjdC5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIGZ1bmN0aW9uIG5hbWVzLlxuICAgICAqIEBzZWUgXy5mdW5jdGlvbnNcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogZnVuY3Rpb24gRm9vKCkge1xuICAgICAqICAgdGhpcy5hID0gXy5jb25zdGFudCgnYScpO1xuICAgICAqICAgdGhpcy5iID0gXy5jb25zdGFudCgnYicpO1xuICAgICAqIH1cbiAgICAgKlxuICAgICAqIEZvby5wcm90b3R5cGUuYyA9IF8uY29uc3RhbnQoJ2MnKTtcbiAgICAgKlxuICAgICAqIF8uZnVuY3Rpb25zSW4obmV3IEZvbyk7XG4gICAgICogLy8gPT4gWydhJywgJ2InLCAnYyddXG4gICAgICovXG4gICAgZnVuY3Rpb24gZnVuY3Rpb25zSW4ob2JqZWN0KSB7XG4gICAgICByZXR1cm4gb2JqZWN0ID09IG51bGwgPyBbXSA6IGJhc2VGdW5jdGlvbnMob2JqZWN0LCBrZXlzSW4ob2JqZWN0KSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0cyB0aGUgdmFsdWUgYXQgYHBhdGhgIG9mIGBvYmplY3RgLiBJZiB0aGUgcmVzb2x2ZWQgdmFsdWUgaXNcbiAgICAgKiBgdW5kZWZpbmVkYCwgdGhlIGBkZWZhdWx0VmFsdWVgIGlzIHJldHVybmVkIGluIGl0cyBwbGFjZS5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAzLjcuMFxuICAgICAqIEBjYXRlZ29yeSBPYmplY3RcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gcXVlcnkuXG4gICAgICogQHBhcmFtIHtBcnJheXxzdHJpbmd9IHBhdGggVGhlIHBhdGggb2YgdGhlIHByb3BlcnR5IHRvIGdldC5cbiAgICAgKiBAcGFyYW0geyp9IFtkZWZhdWx0VmFsdWVdIFRoZSB2YWx1ZSByZXR1cm5lZCBmb3IgYHVuZGVmaW5lZGAgcmVzb2x2ZWQgdmFsdWVzLlxuICAgICAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSByZXNvbHZlZCB2YWx1ZS5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIG9iamVjdCA9IHsgJ2EnOiBbeyAnYic6IHsgJ2MnOiAzIH0gfV0gfTtcbiAgICAgKlxuICAgICAqIF8uZ2V0KG9iamVjdCwgJ2FbMF0uYi5jJyk7XG4gICAgICogLy8gPT4gM1xuICAgICAqXG4gICAgICogXy5nZXQob2JqZWN0LCBbJ2EnLCAnMCcsICdiJywgJ2MnXSk7XG4gICAgICogLy8gPT4gM1xuICAgICAqXG4gICAgICogXy5nZXQob2JqZWN0LCAnYS5iLmMnLCAnZGVmYXVsdCcpO1xuICAgICAqIC8vID0+ICdkZWZhdWx0J1xuICAgICAqL1xuICAgIGZ1bmN0aW9uIGdldChvYmplY3QsIHBhdGgsIGRlZmF1bHRWYWx1ZSkge1xuICAgICAgdmFyIHJlc3VsdCA9IG9iamVjdCA9PSBudWxsID8gdW5kZWZpbmVkIDogYmFzZUdldChvYmplY3QsIHBhdGgpO1xuICAgICAgcmV0dXJuIHJlc3VsdCA9PT0gdW5kZWZpbmVkID8gZGVmYXVsdFZhbHVlIDogcmVzdWx0O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENoZWNrcyBpZiBgcGF0aGAgaXMgYSBkaXJlY3QgcHJvcGVydHkgb2YgYG9iamVjdGAuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQHNpbmNlIDAuMS4wXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAY2F0ZWdvcnkgT2JqZWN0XG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIHF1ZXJ5LlxuICAgICAqIEBwYXJhbSB7QXJyYXl8c3RyaW5nfSBwYXRoIFRoZSBwYXRoIHRvIGNoZWNrLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgcGF0aGAgZXhpc3RzLCBlbHNlIGBmYWxzZWAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciBvYmplY3QgPSB7ICdhJzogeyAnYic6IDIgfSB9O1xuICAgICAqIHZhciBvdGhlciA9IF8uY3JlYXRlKHsgJ2EnOiBfLmNyZWF0ZSh7ICdiJzogMiB9KSB9KTtcbiAgICAgKlxuICAgICAqIF8uaGFzKG9iamVjdCwgJ2EnKTtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICpcbiAgICAgKiBfLmhhcyhvYmplY3QsICdhLmInKTtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICpcbiAgICAgKiBfLmhhcyhvYmplY3QsIFsnYScsICdiJ10pO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKlxuICAgICAqIF8uaGFzKG90aGVyLCAnYScpO1xuICAgICAqIC8vID0+IGZhbHNlXG4gICAgICovXG4gICAgZnVuY3Rpb24gaGFzKG9iamVjdCwgcGF0aCkge1xuICAgICAgcmV0dXJuIG9iamVjdCAhPSBudWxsICYmIGhhc1BhdGgob2JqZWN0LCBwYXRoLCBiYXNlSGFzKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDaGVja3MgaWYgYHBhdGhgIGlzIGEgZGlyZWN0IG9yIGluaGVyaXRlZCBwcm9wZXJ0eSBvZiBgb2JqZWN0YC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjAuMFxuICAgICAqIEBjYXRlZ29yeSBPYmplY3RcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gcXVlcnkuXG4gICAgICogQHBhcmFtIHtBcnJheXxzdHJpbmd9IHBhdGggVGhlIHBhdGggdG8gY2hlY2suXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGBwYXRoYCBleGlzdHMsIGVsc2UgYGZhbHNlYC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIG9iamVjdCA9IF8uY3JlYXRlKHsgJ2EnOiBfLmNyZWF0ZSh7ICdiJzogMiB9KSB9KTtcbiAgICAgKlxuICAgICAqIF8uaGFzSW4ob2JqZWN0LCAnYScpO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKlxuICAgICAqIF8uaGFzSW4ob2JqZWN0LCAnYS5iJyk7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqXG4gICAgICogXy5oYXNJbihvYmplY3QsIFsnYScsICdiJ10pO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKlxuICAgICAqIF8uaGFzSW4ob2JqZWN0LCAnYicpO1xuICAgICAqIC8vID0+IGZhbHNlXG4gICAgICovXG4gICAgZnVuY3Rpb24gaGFzSW4ob2JqZWN0LCBwYXRoKSB7XG4gICAgICByZXR1cm4gb2JqZWN0ICE9IG51bGwgJiYgaGFzUGF0aChvYmplY3QsIHBhdGgsIGJhc2VIYXNJbik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhbiBvYmplY3QgY29tcG9zZWQgb2YgdGhlIGludmVydGVkIGtleXMgYW5kIHZhbHVlcyBvZiBgb2JqZWN0YC5cbiAgICAgKiBJZiBgb2JqZWN0YCBjb250YWlucyBkdXBsaWNhdGUgdmFsdWVzLCBzdWJzZXF1ZW50IHZhbHVlcyBvdmVyd3JpdGVcbiAgICAgKiBwcm9wZXJ0eSBhc3NpZ25tZW50cyBvZiBwcmV2aW91cyB2YWx1ZXMuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMC43LjBcbiAgICAgKiBAY2F0ZWdvcnkgT2JqZWN0XG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIGludmVydC5cbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIHRoZSBuZXcgaW52ZXJ0ZWQgb2JqZWN0LlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgb2JqZWN0ID0geyAnYSc6IDEsICdiJzogMiwgJ2MnOiAxIH07XG4gICAgICpcbiAgICAgKiBfLmludmVydChvYmplY3QpO1xuICAgICAqIC8vID0+IHsgJzEnOiAnYycsICcyJzogJ2InIH1cbiAgICAgKi9cbiAgICB2YXIgaW52ZXJ0ID0gY3JlYXRlSW52ZXJ0ZXIoZnVuY3Rpb24ocmVzdWx0LCB2YWx1ZSwga2V5KSB7XG4gICAgICBpZiAodmFsdWUgIT0gbnVsbCAmJlxuICAgICAgICAgIHR5cGVvZiB2YWx1ZS50b1N0cmluZyAhPSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIHZhbHVlID0gbmF0aXZlT2JqZWN0VG9TdHJpbmcuY2FsbCh2YWx1ZSk7XG4gICAgICB9XG5cbiAgICAgIHJlc3VsdFt2YWx1ZV0gPSBrZXk7XG4gICAgfSwgY29uc3RhbnQoaWRlbnRpdHkpKTtcblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIGlzIGxpa2UgYF8uaW52ZXJ0YCBleGNlcHQgdGhhdCB0aGUgaW52ZXJ0ZWQgb2JqZWN0IGlzIGdlbmVyYXRlZFxuICAgICAqIGZyb20gdGhlIHJlc3VsdHMgb2YgcnVubmluZyBlYWNoIGVsZW1lbnQgb2YgYG9iamVjdGAgdGhydSBgaXRlcmF0ZWVgLiBUaGVcbiAgICAgKiBjb3JyZXNwb25kaW5nIGludmVydGVkIHZhbHVlIG9mIGVhY2ggaW52ZXJ0ZWQga2V5IGlzIGFuIGFycmF5IG9mIGtleXNcbiAgICAgKiByZXNwb25zaWJsZSBmb3IgZ2VuZXJhdGluZyB0aGUgaW52ZXJ0ZWQgdmFsdWUuIFRoZSBpdGVyYXRlZSBpcyBpbnZva2VkXG4gICAgICogd2l0aCBvbmUgYXJndW1lbnQ6ICh2YWx1ZSkuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4xLjBcbiAgICAgKiBAY2F0ZWdvcnkgT2JqZWN0XG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIGludmVydC5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbaXRlcmF0ZWU9Xy5pZGVudGl0eV0gVGhlIGl0ZXJhdGVlIGludm9rZWQgcGVyIGVsZW1lbnQuXG4gICAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyB0aGUgbmV3IGludmVydGVkIG9iamVjdC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIG9iamVjdCA9IHsgJ2EnOiAxLCAnYic6IDIsICdjJzogMSB9O1xuICAgICAqXG4gICAgICogXy5pbnZlcnRCeShvYmplY3QpO1xuICAgICAqIC8vID0+IHsgJzEnOiBbJ2EnLCAnYyddLCAnMic6IFsnYiddIH1cbiAgICAgKlxuICAgICAqIF8uaW52ZXJ0Qnkob2JqZWN0LCBmdW5jdGlvbih2YWx1ZSkge1xuICAgICAqICAgcmV0dXJuICdncm91cCcgKyB2YWx1ZTtcbiAgICAgKiB9KTtcbiAgICAgKiAvLyA9PiB7ICdncm91cDEnOiBbJ2EnLCAnYyddLCAnZ3JvdXAyJzogWydiJ10gfVxuICAgICAqL1xuICAgIHZhciBpbnZlcnRCeSA9IGNyZWF0ZUludmVydGVyKGZ1bmN0aW9uKHJlc3VsdCwgdmFsdWUsIGtleSkge1xuICAgICAgaWYgKHZhbHVlICE9IG51bGwgJiZcbiAgICAgICAgICB0eXBlb2YgdmFsdWUudG9TdHJpbmcgIT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICB2YWx1ZSA9IG5hdGl2ZU9iamVjdFRvU3RyaW5nLmNhbGwodmFsdWUpO1xuICAgICAgfVxuXG4gICAgICBpZiAoaGFzT3duUHJvcGVydHkuY2FsbChyZXN1bHQsIHZhbHVlKSkge1xuICAgICAgICByZXN1bHRbdmFsdWVdLnB1c2goa2V5KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJlc3VsdFt2YWx1ZV0gPSBba2V5XTtcbiAgICAgIH1cbiAgICB9LCBnZXRJdGVyYXRlZSk7XG5cbiAgICAvKipcbiAgICAgKiBJbnZva2VzIHRoZSBtZXRob2QgYXQgYHBhdGhgIG9mIGBvYmplY3RgLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMC4wXG4gICAgICogQGNhdGVnb3J5IE9iamVjdFxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBxdWVyeS5cbiAgICAgKiBAcGFyYW0ge0FycmF5fHN0cmluZ30gcGF0aCBUaGUgcGF0aCBvZiB0aGUgbWV0aG9kIHRvIGludm9rZS5cbiAgICAgKiBAcGFyYW0gey4uLip9IFthcmdzXSBUaGUgYXJndW1lbnRzIHRvIGludm9rZSB0aGUgbWV0aG9kIHdpdGguXG4gICAgICogQHJldHVybnMgeyp9IFJldHVybnMgdGhlIHJlc3VsdCBvZiB0aGUgaW52b2tlZCBtZXRob2QuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciBvYmplY3QgPSB7ICdhJzogW3sgJ2InOiB7ICdjJzogWzEsIDIsIDMsIDRdIH0gfV0gfTtcbiAgICAgKlxuICAgICAqIF8uaW52b2tlKG9iamVjdCwgJ2FbMF0uYi5jLnNsaWNlJywgMSwgMyk7XG4gICAgICogLy8gPT4gWzIsIDNdXG4gICAgICovXG4gICAgdmFyIGludm9rZSA9IGJhc2VSZXN0KGJhc2VJbnZva2UpO1xuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhbiBhcnJheSBvZiB0aGUgb3duIGVudW1lcmFibGUgcHJvcGVydHkgbmFtZXMgb2YgYG9iamVjdGAuXG4gICAgICpcbiAgICAgKiAqKk5vdGU6KiogTm9uLW9iamVjdCB2YWx1ZXMgYXJlIGNvZXJjZWQgdG8gb2JqZWN0cy4gU2VlIHRoZVxuICAgICAqIFtFUyBzcGVjXShodHRwOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi83LjAvI3NlYy1vYmplY3Qua2V5cylcbiAgICAgKiBmb3IgbW9yZSBkZXRhaWxzLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBzaW5jZSAwLjEuMFxuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQGNhdGVnb3J5IE9iamVjdFxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBxdWVyeS5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIGFycmF5IG9mIHByb3BlcnR5IG5hbWVzLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBmdW5jdGlvbiBGb28oKSB7XG4gICAgICogICB0aGlzLmEgPSAxO1xuICAgICAqICAgdGhpcy5iID0gMjtcbiAgICAgKiB9XG4gICAgICpcbiAgICAgKiBGb28ucHJvdG90eXBlLmMgPSAzO1xuICAgICAqXG4gICAgICogXy5rZXlzKG5ldyBGb28pO1xuICAgICAqIC8vID0+IFsnYScsICdiJ10gKGl0ZXJhdGlvbiBvcmRlciBpcyBub3QgZ3VhcmFudGVlZClcbiAgICAgKlxuICAgICAqIF8ua2V5cygnaGknKTtcbiAgICAgKiAvLyA9PiBbJzAnLCAnMSddXG4gICAgICovXG4gICAgZnVuY3Rpb24ga2V5cyhvYmplY3QpIHtcbiAgICAgIHJldHVybiBpc0FycmF5TGlrZShvYmplY3QpID8gYXJyYXlMaWtlS2V5cyhvYmplY3QpIDogYmFzZUtleXMob2JqZWN0KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGFuIGFycmF5IG9mIHRoZSBvd24gYW5kIGluaGVyaXRlZCBlbnVtZXJhYmxlIHByb3BlcnR5IG5hbWVzIG9mIGBvYmplY3RgLlxuICAgICAqXG4gICAgICogKipOb3RlOioqIE5vbi1vYmplY3QgdmFsdWVzIGFyZSBjb2VyY2VkIHRvIG9iamVjdHMuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMy4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgT2JqZWN0XG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIHF1ZXJ5LlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgYXJyYXkgb2YgcHJvcGVydHkgbmFtZXMuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIGZ1bmN0aW9uIEZvbygpIHtcbiAgICAgKiAgIHRoaXMuYSA9IDE7XG4gICAgICogICB0aGlzLmIgPSAyO1xuICAgICAqIH1cbiAgICAgKlxuICAgICAqIEZvby5wcm90b3R5cGUuYyA9IDM7XG4gICAgICpcbiAgICAgKiBfLmtleXNJbihuZXcgRm9vKTtcbiAgICAgKiAvLyA9PiBbJ2EnLCAnYicsICdjJ10gKGl0ZXJhdGlvbiBvcmRlciBpcyBub3QgZ3VhcmFudGVlZClcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBrZXlzSW4ob2JqZWN0KSB7XG4gICAgICByZXR1cm4gaXNBcnJheUxpa2Uob2JqZWN0KSA/IGFycmF5TGlrZUtleXMob2JqZWN0LCB0cnVlKSA6IGJhc2VLZXlzSW4ob2JqZWN0KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgb3Bwb3NpdGUgb2YgYF8ubWFwVmFsdWVzYDsgdGhpcyBtZXRob2QgY3JlYXRlcyBhbiBvYmplY3Qgd2l0aCB0aGVcbiAgICAgKiBzYW1lIHZhbHVlcyBhcyBgb2JqZWN0YCBhbmQga2V5cyBnZW5lcmF0ZWQgYnkgcnVubmluZyBlYWNoIG93biBlbnVtZXJhYmxlXG4gICAgICogc3RyaW5nIGtleWVkIHByb3BlcnR5IG9mIGBvYmplY3RgIHRocnUgYGl0ZXJhdGVlYC4gVGhlIGl0ZXJhdGVlIGlzIGludm9rZWRcbiAgICAgKiB3aXRoIHRocmVlIGFyZ3VtZW50czogKHZhbHVlLCBrZXksIG9iamVjdCkuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMy44LjBcbiAgICAgKiBAY2F0ZWdvcnkgT2JqZWN0XG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIGl0ZXJhdGUgb3Zlci5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbaXRlcmF0ZWU9Xy5pZGVudGl0eV0gVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIGl0ZXJhdGlvbi5cbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIHRoZSBuZXcgbWFwcGVkIG9iamVjdC5cbiAgICAgKiBAc2VlIF8ubWFwVmFsdWVzXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8ubWFwS2V5cyh7ICdhJzogMSwgJ2InOiAyIH0sIGZ1bmN0aW9uKHZhbHVlLCBrZXkpIHtcbiAgICAgKiAgIHJldHVybiBrZXkgKyB2YWx1ZTtcbiAgICAgKiB9KTtcbiAgICAgKiAvLyA9PiB7ICdhMSc6IDEsICdiMic6IDIgfVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIG1hcEtleXMob2JqZWN0LCBpdGVyYXRlZSkge1xuICAgICAgdmFyIHJlc3VsdCA9IHt9O1xuICAgICAgaXRlcmF0ZWUgPSBnZXRJdGVyYXRlZShpdGVyYXRlZSwgMyk7XG5cbiAgICAgIGJhc2VGb3JPd24ob2JqZWN0LCBmdW5jdGlvbih2YWx1ZSwga2V5LCBvYmplY3QpIHtcbiAgICAgICAgYmFzZUFzc2lnblZhbHVlKHJlc3VsdCwgaXRlcmF0ZWUodmFsdWUsIGtleSwgb2JqZWN0KSwgdmFsdWUpO1xuICAgICAgfSk7XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYW4gb2JqZWN0IHdpdGggdGhlIHNhbWUga2V5cyBhcyBgb2JqZWN0YCBhbmQgdmFsdWVzIGdlbmVyYXRlZFxuICAgICAqIGJ5IHJ1bm5pbmcgZWFjaCBvd24gZW51bWVyYWJsZSBzdHJpbmcga2V5ZWQgcHJvcGVydHkgb2YgYG9iamVjdGAgdGhydVxuICAgICAqIGBpdGVyYXRlZWAuIFRoZSBpdGVyYXRlZSBpcyBpbnZva2VkIHdpdGggdGhyZWUgYXJndW1lbnRzOlxuICAgICAqICh2YWx1ZSwga2V5LCBvYmplY3QpLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDIuNC4wXG4gICAgICogQGNhdGVnb3J5IE9iamVjdFxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBpdGVyYXRlIG92ZXIuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW2l0ZXJhdGVlPV8uaWRlbnRpdHldIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uXG4gICAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyB0aGUgbmV3IG1hcHBlZCBvYmplY3QuXG4gICAgICogQHNlZSBfLm1hcEtleXNcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIHVzZXJzID0ge1xuICAgICAqICAgJ2ZyZWQnOiAgICB7ICd1c2VyJzogJ2ZyZWQnLCAgICAnYWdlJzogNDAgfSxcbiAgICAgKiAgICdwZWJibGVzJzogeyAndXNlcic6ICdwZWJibGVzJywgJ2FnZSc6IDEgfVxuICAgICAqIH07XG4gICAgICpcbiAgICAgKiBfLm1hcFZhbHVlcyh1c2VycywgZnVuY3Rpb24obykgeyByZXR1cm4gby5hZ2U7IH0pO1xuICAgICAqIC8vID0+IHsgJ2ZyZWQnOiA0MCwgJ3BlYmJsZXMnOiAxIH0gKGl0ZXJhdGlvbiBvcmRlciBpcyBub3QgZ3VhcmFudGVlZClcbiAgICAgKlxuICAgICAqIC8vIFRoZSBgXy5wcm9wZXJ0eWAgaXRlcmF0ZWUgc2hvcnRoYW5kLlxuICAgICAqIF8ubWFwVmFsdWVzKHVzZXJzLCAnYWdlJyk7XG4gICAgICogLy8gPT4geyAnZnJlZCc6IDQwLCAncGViYmxlcyc6IDEgfSAoaXRlcmF0aW9uIG9yZGVyIGlzIG5vdCBndWFyYW50ZWVkKVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIG1hcFZhbHVlcyhvYmplY3QsIGl0ZXJhdGVlKSB7XG4gICAgICB2YXIgcmVzdWx0ID0ge307XG4gICAgICBpdGVyYXRlZSA9IGdldEl0ZXJhdGVlKGl0ZXJhdGVlLCAzKTtcblxuICAgICAgYmFzZUZvck93bihvYmplY3QsIGZ1bmN0aW9uKHZhbHVlLCBrZXksIG9iamVjdCkge1xuICAgICAgICBiYXNlQXNzaWduVmFsdWUocmVzdWx0LCBrZXksIGl0ZXJhdGVlKHZhbHVlLCBrZXksIG9iamVjdCkpO1xuICAgICAgfSk7XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIGlzIGxpa2UgYF8uYXNzaWduYCBleGNlcHQgdGhhdCBpdCByZWN1cnNpdmVseSBtZXJnZXMgb3duIGFuZFxuICAgICAqIGluaGVyaXRlZCBlbnVtZXJhYmxlIHN0cmluZyBrZXllZCBwcm9wZXJ0aWVzIG9mIHNvdXJjZSBvYmplY3RzIGludG8gdGhlXG4gICAgICogZGVzdGluYXRpb24gb2JqZWN0LiBTb3VyY2UgcHJvcGVydGllcyB0aGF0IHJlc29sdmUgdG8gYHVuZGVmaW5lZGAgYXJlXG4gICAgICogc2tpcHBlZCBpZiBhIGRlc3RpbmF0aW9uIHZhbHVlIGV4aXN0cy4gQXJyYXkgYW5kIHBsYWluIG9iamVjdCBwcm9wZXJ0aWVzXG4gICAgICogYXJlIG1lcmdlZCByZWN1cnNpdmVseS4gT3RoZXIgb2JqZWN0cyBhbmQgdmFsdWUgdHlwZXMgYXJlIG92ZXJyaWRkZW4gYnlcbiAgICAgKiBhc3NpZ25tZW50LiBTb3VyY2Ugb2JqZWN0cyBhcmUgYXBwbGllZCBmcm9tIGxlZnQgdG8gcmlnaHQuIFN1YnNlcXVlbnRcbiAgICAgKiBzb3VyY2VzIG92ZXJ3cml0ZSBwcm9wZXJ0eSBhc3NpZ25tZW50cyBvZiBwcmV2aW91cyBzb3VyY2VzLlxuICAgICAqXG4gICAgICogKipOb3RlOioqIFRoaXMgbWV0aG9kIG11dGF0ZXMgYG9iamVjdGAuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMC41LjBcbiAgICAgKiBAY2F0ZWdvcnkgT2JqZWN0XG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgZGVzdGluYXRpb24gb2JqZWN0LlxuICAgICAqIEBwYXJhbSB7Li4uT2JqZWN0fSBbc291cmNlc10gVGhlIHNvdXJjZSBvYmplY3RzLlxuICAgICAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgYG9iamVjdGAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciBvYmplY3QgPSB7XG4gICAgICogICAnYSc6IFt7ICdiJzogMiB9LCB7ICdkJzogNCB9XVxuICAgICAqIH07XG4gICAgICpcbiAgICAgKiB2YXIgb3RoZXIgPSB7XG4gICAgICogICAnYSc6IFt7ICdjJzogMyB9LCB7ICdlJzogNSB9XVxuICAgICAqIH07XG4gICAgICpcbiAgICAgKiBfLm1lcmdlKG9iamVjdCwgb3RoZXIpO1xuICAgICAqIC8vID0+IHsgJ2EnOiBbeyAnYic6IDIsICdjJzogMyB9LCB7ICdkJzogNCwgJ2UnOiA1IH1dIH1cbiAgICAgKi9cbiAgICB2YXIgbWVyZ2UgPSBjcmVhdGVBc3NpZ25lcihmdW5jdGlvbihvYmplY3QsIHNvdXJjZSwgc3JjSW5kZXgpIHtcbiAgICAgIGJhc2VNZXJnZShvYmplY3QsIHNvdXJjZSwgc3JjSW5kZXgpO1xuICAgIH0pO1xuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgaXMgbGlrZSBgXy5tZXJnZWAgZXhjZXB0IHRoYXQgaXQgYWNjZXB0cyBgY3VzdG9taXplcmAgd2hpY2hcbiAgICAgKiBpcyBpbnZva2VkIHRvIHByb2R1Y2UgdGhlIG1lcmdlZCB2YWx1ZXMgb2YgdGhlIGRlc3RpbmF0aW9uIGFuZCBzb3VyY2VcbiAgICAgKiBwcm9wZXJ0aWVzLiBJZiBgY3VzdG9taXplcmAgcmV0dXJucyBgdW5kZWZpbmVkYCwgbWVyZ2luZyBpcyBoYW5kbGVkIGJ5IHRoZVxuICAgICAqIG1ldGhvZCBpbnN0ZWFkLiBUaGUgYGN1c3RvbWl6ZXJgIGlzIGludm9rZWQgd2l0aCBzaXggYXJndW1lbnRzOlxuICAgICAqIChvYmpWYWx1ZSwgc3JjVmFsdWUsIGtleSwgb2JqZWN0LCBzb3VyY2UsIHN0YWNrKS5cbiAgICAgKlxuICAgICAqICoqTm90ZToqKiBUaGlzIG1ldGhvZCBtdXRhdGVzIGBvYmplY3RgLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMC4wXG4gICAgICogQGNhdGVnb3J5IE9iamVjdFxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIGRlc3RpbmF0aW9uIG9iamVjdC5cbiAgICAgKiBAcGFyYW0gey4uLk9iamVjdH0gc291cmNlcyBUaGUgc291cmNlIG9iamVjdHMuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gY3VzdG9taXplciBUaGUgZnVuY3Rpb24gdG8gY3VzdG9taXplIGFzc2lnbmVkIHZhbHVlcy5cbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIGBvYmplY3RgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBmdW5jdGlvbiBjdXN0b21pemVyKG9ialZhbHVlLCBzcmNWYWx1ZSkge1xuICAgICAqICAgaWYgKF8uaXNBcnJheShvYmpWYWx1ZSkpIHtcbiAgICAgKiAgICAgcmV0dXJuIG9ialZhbHVlLmNvbmNhdChzcmNWYWx1ZSk7XG4gICAgICogICB9XG4gICAgICogfVxuICAgICAqXG4gICAgICogdmFyIG9iamVjdCA9IHsgJ2EnOiBbMV0sICdiJzogWzJdIH07XG4gICAgICogdmFyIG90aGVyID0geyAnYSc6IFszXSwgJ2InOiBbNF0gfTtcbiAgICAgKlxuICAgICAqIF8ubWVyZ2VXaXRoKG9iamVjdCwgb3RoZXIsIGN1c3RvbWl6ZXIpO1xuICAgICAqIC8vID0+IHsgJ2EnOiBbMSwgM10sICdiJzogWzIsIDRdIH1cbiAgICAgKi9cbiAgICB2YXIgbWVyZ2VXaXRoID0gY3JlYXRlQXNzaWduZXIoZnVuY3Rpb24ob2JqZWN0LCBzb3VyY2UsIHNyY0luZGV4LCBjdXN0b21pemVyKSB7XG4gICAgICBiYXNlTWVyZ2Uob2JqZWN0LCBzb3VyY2UsIHNyY0luZGV4LCBjdXN0b21pemVyKTtcbiAgICB9KTtcblxuICAgIC8qKlxuICAgICAqIFRoZSBvcHBvc2l0ZSBvZiBgXy5waWNrYDsgdGhpcyBtZXRob2QgY3JlYXRlcyBhbiBvYmplY3QgY29tcG9zZWQgb2YgdGhlXG4gICAgICogb3duIGFuZCBpbmhlcml0ZWQgZW51bWVyYWJsZSBwcm9wZXJ0eSBwYXRocyBvZiBgb2JqZWN0YCB0aGF0IGFyZSBub3Qgb21pdHRlZC5cbiAgICAgKlxuICAgICAqICoqTm90ZToqKiBUaGlzIG1ldGhvZCBpcyBjb25zaWRlcmFibHkgc2xvd2VyIHRoYW4gYF8ucGlja2AuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQHNpbmNlIDAuMS4wXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAY2F0ZWdvcnkgT2JqZWN0XG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgc291cmNlIG9iamVjdC5cbiAgICAgKiBAcGFyYW0gey4uLihzdHJpbmd8c3RyaW5nW10pfSBbcGF0aHNdIFRoZSBwcm9wZXJ0eSBwYXRocyB0byBvbWl0LlxuICAgICAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgdGhlIG5ldyBvYmplY3QuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciBvYmplY3QgPSB7ICdhJzogMSwgJ2InOiAnMicsICdjJzogMyB9O1xuICAgICAqXG4gICAgICogXy5vbWl0KG9iamVjdCwgWydhJywgJ2MnXSk7XG4gICAgICogLy8gPT4geyAnYic6ICcyJyB9XG4gICAgICovXG4gICAgdmFyIG9taXQgPSBmbGF0UmVzdChmdW5jdGlvbihvYmplY3QsIHBhdGhzKSB7XG4gICAgICB2YXIgcmVzdWx0ID0ge307XG4gICAgICBpZiAob2JqZWN0ID09IG51bGwpIHtcbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgIH1cbiAgICAgIHZhciBpc0RlZXAgPSBmYWxzZTtcbiAgICAgIHBhdGhzID0gYXJyYXlNYXAocGF0aHMsIGZ1bmN0aW9uKHBhdGgpIHtcbiAgICAgICAgcGF0aCA9IGNhc3RQYXRoKHBhdGgsIG9iamVjdCk7XG4gICAgICAgIGlzRGVlcCB8fCAoaXNEZWVwID0gcGF0aC5sZW5ndGggPiAxKTtcbiAgICAgICAgcmV0dXJuIHBhdGg7XG4gICAgICB9KTtcbiAgICAgIGNvcHlPYmplY3Qob2JqZWN0LCBnZXRBbGxLZXlzSW4ob2JqZWN0KSwgcmVzdWx0KTtcbiAgICAgIGlmIChpc0RlZXApIHtcbiAgICAgICAgcmVzdWx0ID0gYmFzZUNsb25lKHJlc3VsdCwgQ0xPTkVfREVFUF9GTEFHIHwgQ0xPTkVfRkxBVF9GTEFHIHwgQ0xPTkVfU1lNQk9MU19GTEFHLCBjdXN0b21PbWl0Q2xvbmUpO1xuICAgICAgfVxuICAgICAgdmFyIGxlbmd0aCA9IHBhdGhzLmxlbmd0aDtcbiAgICAgIHdoaWxlIChsZW5ndGgtLSkge1xuICAgICAgICBiYXNlVW5zZXQocmVzdWx0LCBwYXRoc1tsZW5ndGhdKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfSk7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgb3Bwb3NpdGUgb2YgYF8ucGlja0J5YDsgdGhpcyBtZXRob2QgY3JlYXRlcyBhbiBvYmplY3QgY29tcG9zZWQgb2ZcbiAgICAgKiB0aGUgb3duIGFuZCBpbmhlcml0ZWQgZW51bWVyYWJsZSBzdHJpbmcga2V5ZWQgcHJvcGVydGllcyBvZiBgb2JqZWN0YCB0aGF0XG4gICAgICogYHByZWRpY2F0ZWAgZG9lc24ndCByZXR1cm4gdHJ1dGh5IGZvci4gVGhlIHByZWRpY2F0ZSBpcyBpbnZva2VkIHdpdGggdHdvXG4gICAgICogYXJndW1lbnRzOiAodmFsdWUsIGtleSkuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgT2JqZWN0XG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgc291cmNlIG9iamVjdC5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbcHJlZGljYXRlPV8uaWRlbnRpdHldIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBwcm9wZXJ0eS5cbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIHRoZSBuZXcgb2JqZWN0LlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgb2JqZWN0ID0geyAnYSc6IDEsICdiJzogJzInLCAnYyc6IDMgfTtcbiAgICAgKlxuICAgICAqIF8ub21pdEJ5KG9iamVjdCwgXy5pc051bWJlcik7XG4gICAgICogLy8gPT4geyAnYic6ICcyJyB9XG4gICAgICovXG4gICAgZnVuY3Rpb24gb21pdEJ5KG9iamVjdCwgcHJlZGljYXRlKSB7XG4gICAgICByZXR1cm4gcGlja0J5KG9iamVjdCwgbmVnYXRlKGdldEl0ZXJhdGVlKHByZWRpY2F0ZSkpKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGFuIG9iamVjdCBjb21wb3NlZCBvZiB0aGUgcGlja2VkIGBvYmplY3RgIHByb3BlcnRpZXMuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQHNpbmNlIDAuMS4wXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAY2F0ZWdvcnkgT2JqZWN0XG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgc291cmNlIG9iamVjdC5cbiAgICAgKiBAcGFyYW0gey4uLihzdHJpbmd8c3RyaW5nW10pfSBbcGF0aHNdIFRoZSBwcm9wZXJ0eSBwYXRocyB0byBwaWNrLlxuICAgICAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgdGhlIG5ldyBvYmplY3QuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciBvYmplY3QgPSB7ICdhJzogMSwgJ2InOiAnMicsICdjJzogMyB9O1xuICAgICAqXG4gICAgICogXy5waWNrKG9iamVjdCwgWydhJywgJ2MnXSk7XG4gICAgICogLy8gPT4geyAnYSc6IDEsICdjJzogMyB9XG4gICAgICovXG4gICAgdmFyIHBpY2sgPSBmbGF0UmVzdChmdW5jdGlvbihvYmplY3QsIHBhdGhzKSB7XG4gICAgICByZXR1cm4gb2JqZWN0ID09IG51bGwgPyB7fSA6IGJhc2VQaWNrKG9iamVjdCwgcGF0aHMpO1xuICAgIH0pO1xuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhbiBvYmplY3QgY29tcG9zZWQgb2YgdGhlIGBvYmplY3RgIHByb3BlcnRpZXMgYHByZWRpY2F0ZWAgcmV0dXJuc1xuICAgICAqIHRydXRoeSBmb3IuIFRoZSBwcmVkaWNhdGUgaXMgaW52b2tlZCB3aXRoIHR3byBhcmd1bWVudHM6ICh2YWx1ZSwga2V5KS5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjAuMFxuICAgICAqIEBjYXRlZ29yeSBPYmplY3RcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBzb3VyY2Ugb2JqZWN0LlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IFtwcmVkaWNhdGU9Xy5pZGVudGl0eV0gVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIHByb3BlcnR5LlxuICAgICAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgdGhlIG5ldyBvYmplY3QuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciBvYmplY3QgPSB7ICdhJzogMSwgJ2InOiAnMicsICdjJzogMyB9O1xuICAgICAqXG4gICAgICogXy5waWNrQnkob2JqZWN0LCBfLmlzTnVtYmVyKTtcbiAgICAgKiAvLyA9PiB7ICdhJzogMSwgJ2MnOiAzIH1cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBwaWNrQnkob2JqZWN0LCBwcmVkaWNhdGUpIHtcbiAgICAgIGlmIChvYmplY3QgPT0gbnVsbCkge1xuICAgICAgICByZXR1cm4ge307XG4gICAgICB9XG4gICAgICB2YXIgcHJvcHMgPSBhcnJheU1hcChnZXRBbGxLZXlzSW4ob2JqZWN0KSwgZnVuY3Rpb24ocHJvcCkge1xuICAgICAgICByZXR1cm4gW3Byb3BdO1xuICAgICAgfSk7XG4gICAgICBwcmVkaWNhdGUgPSBnZXRJdGVyYXRlZShwcmVkaWNhdGUpO1xuICAgICAgcmV0dXJuIGJhc2VQaWNrQnkob2JqZWN0LCBwcm9wcywgZnVuY3Rpb24odmFsdWUsIHBhdGgpIHtcbiAgICAgICAgcmV0dXJuIHByZWRpY2F0ZSh2YWx1ZSwgcGF0aFswXSk7XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIG1ldGhvZCBpcyBsaWtlIGBfLmdldGAgZXhjZXB0IHRoYXQgaWYgdGhlIHJlc29sdmVkIHZhbHVlIGlzIGFcbiAgICAgKiBmdW5jdGlvbiBpdCdzIGludm9rZWQgd2l0aCB0aGUgYHRoaXNgIGJpbmRpbmcgb2YgaXRzIHBhcmVudCBvYmplY3QgYW5kXG4gICAgICogaXRzIHJlc3VsdCBpcyByZXR1cm5lZC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAc2luY2UgMC4xLjBcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBjYXRlZ29yeSBPYmplY3RcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gcXVlcnkuXG4gICAgICogQHBhcmFtIHtBcnJheXxzdHJpbmd9IHBhdGggVGhlIHBhdGggb2YgdGhlIHByb3BlcnR5IHRvIHJlc29sdmUuXG4gICAgICogQHBhcmFtIHsqfSBbZGVmYXVsdFZhbHVlXSBUaGUgdmFsdWUgcmV0dXJuZWQgZm9yIGB1bmRlZmluZWRgIHJlc29sdmVkIHZhbHVlcy5cbiAgICAgKiBAcmV0dXJucyB7Kn0gUmV0dXJucyB0aGUgcmVzb2x2ZWQgdmFsdWUuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciBvYmplY3QgPSB7ICdhJzogW3sgJ2InOiB7ICdjMSc6IDMsICdjMic6IF8uY29uc3RhbnQoNCkgfSB9XSB9O1xuICAgICAqXG4gICAgICogXy5yZXN1bHQob2JqZWN0LCAnYVswXS5iLmMxJyk7XG4gICAgICogLy8gPT4gM1xuICAgICAqXG4gICAgICogXy5yZXN1bHQob2JqZWN0LCAnYVswXS5iLmMyJyk7XG4gICAgICogLy8gPT4gNFxuICAgICAqXG4gICAgICogXy5yZXN1bHQob2JqZWN0LCAnYVswXS5iLmMzJywgJ2RlZmF1bHQnKTtcbiAgICAgKiAvLyA9PiAnZGVmYXVsdCdcbiAgICAgKlxuICAgICAqIF8ucmVzdWx0KG9iamVjdCwgJ2FbMF0uYi5jMycsIF8uY29uc3RhbnQoJ2RlZmF1bHQnKSk7XG4gICAgICogLy8gPT4gJ2RlZmF1bHQnXG4gICAgICovXG4gICAgZnVuY3Rpb24gcmVzdWx0KG9iamVjdCwgcGF0aCwgZGVmYXVsdFZhbHVlKSB7XG4gICAgICBwYXRoID0gY2FzdFBhdGgocGF0aCwgb2JqZWN0KTtcblxuICAgICAgdmFyIGluZGV4ID0gLTEsXG4gICAgICAgICAgbGVuZ3RoID0gcGF0aC5sZW5ndGg7XG5cbiAgICAgIC8vIEVuc3VyZSB0aGUgbG9vcCBpcyBlbnRlcmVkIHdoZW4gcGF0aCBpcyBlbXB0eS5cbiAgICAgIGlmICghbGVuZ3RoKSB7XG4gICAgICAgIGxlbmd0aCA9IDE7XG4gICAgICAgIG9iamVjdCA9IHVuZGVmaW5lZDtcbiAgICAgIH1cbiAgICAgIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XG4gICAgICAgIHZhciB2YWx1ZSA9IG9iamVjdCA9PSBudWxsID8gdW5kZWZpbmVkIDogb2JqZWN0W3RvS2V5KHBhdGhbaW5kZXhdKV07XG4gICAgICAgIGlmICh2YWx1ZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgaW5kZXggPSBsZW5ndGg7XG4gICAgICAgICAgdmFsdWUgPSBkZWZhdWx0VmFsdWU7XG4gICAgICAgIH1cbiAgICAgICAgb2JqZWN0ID0gaXNGdW5jdGlvbih2YWx1ZSkgPyB2YWx1ZS5jYWxsKG9iamVjdCkgOiB2YWx1ZTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBvYmplY3Q7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2V0cyB0aGUgdmFsdWUgYXQgYHBhdGhgIG9mIGBvYmplY3RgLiBJZiBhIHBvcnRpb24gb2YgYHBhdGhgIGRvZXNuJ3QgZXhpc3QsXG4gICAgICogaXQncyBjcmVhdGVkLiBBcnJheXMgYXJlIGNyZWF0ZWQgZm9yIG1pc3NpbmcgaW5kZXggcHJvcGVydGllcyB3aGlsZSBvYmplY3RzXG4gICAgICogYXJlIGNyZWF0ZWQgZm9yIGFsbCBvdGhlciBtaXNzaW5nIHByb3BlcnRpZXMuIFVzZSBgXy5zZXRXaXRoYCB0byBjdXN0b21pemVcbiAgICAgKiBgcGF0aGAgY3JlYXRpb24uXG4gICAgICpcbiAgICAgKiAqKk5vdGU6KiogVGhpcyBtZXRob2QgbXV0YXRlcyBgb2JqZWN0YC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAzLjcuMFxuICAgICAqIEBjYXRlZ29yeSBPYmplY3RcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gbW9kaWZ5LlxuICAgICAqIEBwYXJhbSB7QXJyYXl8c3RyaW5nfSBwYXRoIFRoZSBwYXRoIG9mIHRoZSBwcm9wZXJ0eSB0byBzZXQuXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gc2V0LlxuICAgICAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgYG9iamVjdGAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciBvYmplY3QgPSB7ICdhJzogW3sgJ2InOiB7ICdjJzogMyB9IH1dIH07XG4gICAgICpcbiAgICAgKiBfLnNldChvYmplY3QsICdhWzBdLmIuYycsIDQpO1xuICAgICAqIGNvbnNvbGUubG9nKG9iamVjdC5hWzBdLmIuYyk7XG4gICAgICogLy8gPT4gNFxuICAgICAqXG4gICAgICogXy5zZXQob2JqZWN0LCBbJ3gnLCAnMCcsICd5JywgJ3onXSwgNSk7XG4gICAgICogY29uc29sZS5sb2cob2JqZWN0LnhbMF0ueS56KTtcbiAgICAgKiAvLyA9PiA1XG4gICAgICovXG4gICAgZnVuY3Rpb24gc2V0KG9iamVjdCwgcGF0aCwgdmFsdWUpIHtcbiAgICAgIHJldHVybiBvYmplY3QgPT0gbnVsbCA/IG9iamVjdCA6IGJhc2VTZXQob2JqZWN0LCBwYXRoLCB2YWx1ZSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgaXMgbGlrZSBgXy5zZXRgIGV4Y2VwdCB0aGF0IGl0IGFjY2VwdHMgYGN1c3RvbWl6ZXJgIHdoaWNoIGlzXG4gICAgICogaW52b2tlZCB0byBwcm9kdWNlIHRoZSBvYmplY3RzIG9mIGBwYXRoYC4gIElmIGBjdXN0b21pemVyYCByZXR1cm5zIGB1bmRlZmluZWRgXG4gICAgICogcGF0aCBjcmVhdGlvbiBpcyBoYW5kbGVkIGJ5IHRoZSBtZXRob2QgaW5zdGVhZC4gVGhlIGBjdXN0b21pemVyYCBpcyBpbnZva2VkXG4gICAgICogd2l0aCB0aHJlZSBhcmd1bWVudHM6IChuc1ZhbHVlLCBrZXksIG5zT2JqZWN0KS5cbiAgICAgKlxuICAgICAqICoqTm90ZToqKiBUaGlzIG1ldGhvZCBtdXRhdGVzIGBvYmplY3RgLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMC4wXG4gICAgICogQGNhdGVnb3J5IE9iamVjdFxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBtb2RpZnkuXG4gICAgICogQHBhcmFtIHtBcnJheXxzdHJpbmd9IHBhdGggVGhlIHBhdGggb2YgdGhlIHByb3BlcnR5IHRvIHNldC5cbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBzZXQuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW2N1c3RvbWl6ZXJdIFRoZSBmdW5jdGlvbiB0byBjdXN0b21pemUgYXNzaWduZWQgdmFsdWVzLlxuICAgICAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgYG9iamVjdGAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciBvYmplY3QgPSB7fTtcbiAgICAgKlxuICAgICAqIF8uc2V0V2l0aChvYmplY3QsICdbMF1bMV0nLCAnYScsIE9iamVjdCk7XG4gICAgICogLy8gPT4geyAnMCc6IHsgJzEnOiAnYScgfSB9XG4gICAgICovXG4gICAgZnVuY3Rpb24gc2V0V2l0aChvYmplY3QsIHBhdGgsIHZhbHVlLCBjdXN0b21pemVyKSB7XG4gICAgICBjdXN0b21pemVyID0gdHlwZW9mIGN1c3RvbWl6ZXIgPT0gJ2Z1bmN0aW9uJyA/IGN1c3RvbWl6ZXIgOiB1bmRlZmluZWQ7XG4gICAgICByZXR1cm4gb2JqZWN0ID09IG51bGwgPyBvYmplY3QgOiBiYXNlU2V0KG9iamVjdCwgcGF0aCwgdmFsdWUsIGN1c3RvbWl6ZXIpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYW4gYXJyYXkgb2Ygb3duIGVudW1lcmFibGUgc3RyaW5nIGtleWVkLXZhbHVlIHBhaXJzIGZvciBgb2JqZWN0YFxuICAgICAqIHdoaWNoIGNhbiBiZSBjb25zdW1lZCBieSBgXy5mcm9tUGFpcnNgLiBJZiBgb2JqZWN0YCBpcyBhIG1hcCBvciBzZXQsIGl0c1xuICAgICAqIGVudHJpZXMgYXJlIHJldHVybmVkLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMC4wXG4gICAgICogQGFsaWFzIGVudHJpZXNcbiAgICAgKiBAY2F0ZWdvcnkgT2JqZWN0XG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIHF1ZXJ5LlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUga2V5LXZhbHVlIHBhaXJzLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBmdW5jdGlvbiBGb28oKSB7XG4gICAgICogICB0aGlzLmEgPSAxO1xuICAgICAqICAgdGhpcy5iID0gMjtcbiAgICAgKiB9XG4gICAgICpcbiAgICAgKiBGb28ucHJvdG90eXBlLmMgPSAzO1xuICAgICAqXG4gICAgICogXy50b1BhaXJzKG5ldyBGb28pO1xuICAgICAqIC8vID0+IFtbJ2EnLCAxXSwgWydiJywgMl1dIChpdGVyYXRpb24gb3JkZXIgaXMgbm90IGd1YXJhbnRlZWQpXG4gICAgICovXG4gICAgdmFyIHRvUGFpcnMgPSBjcmVhdGVUb1BhaXJzKGtleXMpO1xuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhbiBhcnJheSBvZiBvd24gYW5kIGluaGVyaXRlZCBlbnVtZXJhYmxlIHN0cmluZyBrZXllZC12YWx1ZSBwYWlyc1xuICAgICAqIGZvciBgb2JqZWN0YCB3aGljaCBjYW4gYmUgY29uc3VtZWQgYnkgYF8uZnJvbVBhaXJzYC4gSWYgYG9iamVjdGAgaXMgYSBtYXBcbiAgICAgKiBvciBzZXQsIGl0cyBlbnRyaWVzIGFyZSByZXR1cm5lZC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjAuMFxuICAgICAqIEBhbGlhcyBlbnRyaWVzSW5cbiAgICAgKiBAY2F0ZWdvcnkgT2JqZWN0XG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIHF1ZXJ5LlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUga2V5LXZhbHVlIHBhaXJzLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBmdW5jdGlvbiBGb28oKSB7XG4gICAgICogICB0aGlzLmEgPSAxO1xuICAgICAqICAgdGhpcy5iID0gMjtcbiAgICAgKiB9XG4gICAgICpcbiAgICAgKiBGb28ucHJvdG90eXBlLmMgPSAzO1xuICAgICAqXG4gICAgICogXy50b1BhaXJzSW4obmV3IEZvbyk7XG4gICAgICogLy8gPT4gW1snYScsIDFdLCBbJ2InLCAyXSwgWydjJywgM11dIChpdGVyYXRpb24gb3JkZXIgaXMgbm90IGd1YXJhbnRlZWQpXG4gICAgICovXG4gICAgdmFyIHRvUGFpcnNJbiA9IGNyZWF0ZVRvUGFpcnMoa2V5c0luKTtcblxuICAgIC8qKlxuICAgICAqIEFuIGFsdGVybmF0aXZlIHRvIGBfLnJlZHVjZWA7IHRoaXMgbWV0aG9kIHRyYW5zZm9ybXMgYG9iamVjdGAgdG8gYSBuZXdcbiAgICAgKiBgYWNjdW11bGF0b3JgIG9iamVjdCB3aGljaCBpcyB0aGUgcmVzdWx0IG9mIHJ1bm5pbmcgZWFjaCBvZiBpdHMgb3duXG4gICAgICogZW51bWVyYWJsZSBzdHJpbmcga2V5ZWQgcHJvcGVydGllcyB0aHJ1IGBpdGVyYXRlZWAsIHdpdGggZWFjaCBpbnZvY2F0aW9uXG4gICAgICogcG90ZW50aWFsbHkgbXV0YXRpbmcgdGhlIGBhY2N1bXVsYXRvcmAgb2JqZWN0LiBJZiBgYWNjdW11bGF0b3JgIGlzIG5vdFxuICAgICAqIHByb3ZpZGVkLCBhIG5ldyBvYmplY3Qgd2l0aCB0aGUgc2FtZSBgW1tQcm90b3R5cGVdXWAgd2lsbCBiZSB1c2VkLiBUaGVcbiAgICAgKiBpdGVyYXRlZSBpcyBpbnZva2VkIHdpdGggZm91ciBhcmd1bWVudHM6IChhY2N1bXVsYXRvciwgdmFsdWUsIGtleSwgb2JqZWN0KS5cbiAgICAgKiBJdGVyYXRlZSBmdW5jdGlvbnMgbWF5IGV4aXQgaXRlcmF0aW9uIGVhcmx5IGJ5IGV4cGxpY2l0bHkgcmV0dXJuaW5nIGBmYWxzZWAuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMS4zLjBcbiAgICAgKiBAY2F0ZWdvcnkgT2JqZWN0XG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIGl0ZXJhdGUgb3Zlci5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbaXRlcmF0ZWU9Xy5pZGVudGl0eV0gVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIGl0ZXJhdGlvbi5cbiAgICAgKiBAcGFyYW0geyp9IFthY2N1bXVsYXRvcl0gVGhlIGN1c3RvbSBhY2N1bXVsYXRvciB2YWx1ZS5cbiAgICAgKiBAcmV0dXJucyB7Kn0gUmV0dXJucyB0aGUgYWNjdW11bGF0ZWQgdmFsdWUuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8udHJhbnNmb3JtKFsyLCAzLCA0XSwgZnVuY3Rpb24ocmVzdWx0LCBuKSB7XG4gICAgICogICByZXN1bHQucHVzaChuICo9IG4pO1xuICAgICAqICAgcmV0dXJuIG4gJSAyID09IDA7XG4gICAgICogfSwgW10pO1xuICAgICAqIC8vID0+IFs0LCA5XVxuICAgICAqXG4gICAgICogXy50cmFuc2Zvcm0oeyAnYSc6IDEsICdiJzogMiwgJ2MnOiAxIH0sIGZ1bmN0aW9uKHJlc3VsdCwgdmFsdWUsIGtleSkge1xuICAgICAqICAgKHJlc3VsdFt2YWx1ZV0gfHwgKHJlc3VsdFt2YWx1ZV0gPSBbXSkpLnB1c2goa2V5KTtcbiAgICAgKiB9LCB7fSk7XG4gICAgICogLy8gPT4geyAnMSc6IFsnYScsICdjJ10sICcyJzogWydiJ10gfVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIHRyYW5zZm9ybShvYmplY3QsIGl0ZXJhdGVlLCBhY2N1bXVsYXRvcikge1xuICAgICAgdmFyIGlzQXJyID0gaXNBcnJheShvYmplY3QpLFxuICAgICAgICAgIGlzQXJyTGlrZSA9IGlzQXJyIHx8IGlzQnVmZmVyKG9iamVjdCkgfHwgaXNUeXBlZEFycmF5KG9iamVjdCk7XG5cbiAgICAgIGl0ZXJhdGVlID0gZ2V0SXRlcmF0ZWUoaXRlcmF0ZWUsIDQpO1xuICAgICAgaWYgKGFjY3VtdWxhdG9yID09IG51bGwpIHtcbiAgICAgICAgdmFyIEN0b3IgPSBvYmplY3QgJiYgb2JqZWN0LmNvbnN0cnVjdG9yO1xuICAgICAgICBpZiAoaXNBcnJMaWtlKSB7XG4gICAgICAgICAgYWNjdW11bGF0b3IgPSBpc0FyciA/IG5ldyBDdG9yIDogW107XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoaXNPYmplY3Qob2JqZWN0KSkge1xuICAgICAgICAgIGFjY3VtdWxhdG9yID0gaXNGdW5jdGlvbihDdG9yKSA/IGJhc2VDcmVhdGUoZ2V0UHJvdG90eXBlKG9iamVjdCkpIDoge307XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgYWNjdW11bGF0b3IgPSB7fTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgKGlzQXJyTGlrZSA/IGFycmF5RWFjaCA6IGJhc2VGb3JPd24pKG9iamVjdCwgZnVuY3Rpb24odmFsdWUsIGluZGV4LCBvYmplY3QpIHtcbiAgICAgICAgcmV0dXJuIGl0ZXJhdGVlKGFjY3VtdWxhdG9yLCB2YWx1ZSwgaW5kZXgsIG9iamVjdCk7XG4gICAgICB9KTtcbiAgICAgIHJldHVybiBhY2N1bXVsYXRvcjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZW1vdmVzIHRoZSBwcm9wZXJ0eSBhdCBgcGF0aGAgb2YgYG9iamVjdGAuXG4gICAgICpcbiAgICAgKiAqKk5vdGU6KiogVGhpcyBtZXRob2QgbXV0YXRlcyBgb2JqZWN0YC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjAuMFxuICAgICAqIEBjYXRlZ29yeSBPYmplY3RcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gbW9kaWZ5LlxuICAgICAqIEBwYXJhbSB7QXJyYXl8c3RyaW5nfSBwYXRoIFRoZSBwYXRoIG9mIHRoZSBwcm9wZXJ0eSB0byB1bnNldC5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgdGhlIHByb3BlcnR5IGlzIGRlbGV0ZWQsIGVsc2UgYGZhbHNlYC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIG9iamVjdCA9IHsgJ2EnOiBbeyAnYic6IHsgJ2MnOiA3IH0gfV0gfTtcbiAgICAgKiBfLnVuc2V0KG9iamVjdCwgJ2FbMF0uYi5jJyk7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqXG4gICAgICogY29uc29sZS5sb2cob2JqZWN0KTtcbiAgICAgKiAvLyA9PiB7ICdhJzogW3sgJ2InOiB7fSB9XSB9O1xuICAgICAqXG4gICAgICogXy51bnNldChvYmplY3QsIFsnYScsICcwJywgJ2InLCAnYyddKTtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICpcbiAgICAgKiBjb25zb2xlLmxvZyhvYmplY3QpO1xuICAgICAqIC8vID0+IHsgJ2EnOiBbeyAnYic6IHt9IH1dIH07XG4gICAgICovXG4gICAgZnVuY3Rpb24gdW5zZXQob2JqZWN0LCBwYXRoKSB7XG4gICAgICByZXR1cm4gb2JqZWN0ID09IG51bGwgPyB0cnVlIDogYmFzZVVuc2V0KG9iamVjdCwgcGF0aCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgaXMgbGlrZSBgXy5zZXRgIGV4Y2VwdCB0aGF0IGFjY2VwdHMgYHVwZGF0ZXJgIHRvIHByb2R1Y2UgdGhlXG4gICAgICogdmFsdWUgdG8gc2V0LiBVc2UgYF8udXBkYXRlV2l0aGAgdG8gY3VzdG9taXplIGBwYXRoYCBjcmVhdGlvbi4gVGhlIGB1cGRhdGVyYFxuICAgICAqIGlzIGludm9rZWQgd2l0aCBvbmUgYXJndW1lbnQ6ICh2YWx1ZSkuXG4gICAgICpcbiAgICAgKiAqKk5vdGU6KiogVGhpcyBtZXRob2QgbXV0YXRlcyBgb2JqZWN0YC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjYuMFxuICAgICAqIEBjYXRlZ29yeSBPYmplY3RcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gbW9kaWZ5LlxuICAgICAqIEBwYXJhbSB7QXJyYXl8c3RyaW5nfSBwYXRoIFRoZSBwYXRoIG9mIHRoZSBwcm9wZXJ0eSB0byBzZXQuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gdXBkYXRlciBUaGUgZnVuY3Rpb24gdG8gcHJvZHVjZSB0aGUgdXBkYXRlZCB2YWx1ZS5cbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIGBvYmplY3RgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgb2JqZWN0ID0geyAnYSc6IFt7ICdiJzogeyAnYyc6IDMgfSB9XSB9O1xuICAgICAqXG4gICAgICogXy51cGRhdGUob2JqZWN0LCAnYVswXS5iLmMnLCBmdW5jdGlvbihuKSB7IHJldHVybiBuICogbjsgfSk7XG4gICAgICogY29uc29sZS5sb2cob2JqZWN0LmFbMF0uYi5jKTtcbiAgICAgKiAvLyA9PiA5XG4gICAgICpcbiAgICAgKiBfLnVwZGF0ZShvYmplY3QsICd4WzBdLnkueicsIGZ1bmN0aW9uKG4pIHsgcmV0dXJuIG4gPyBuICsgMSA6IDA7IH0pO1xuICAgICAqIGNvbnNvbGUubG9nKG9iamVjdC54WzBdLnkueik7XG4gICAgICogLy8gPT4gMFxuICAgICAqL1xuICAgIGZ1bmN0aW9uIHVwZGF0ZShvYmplY3QsIHBhdGgsIHVwZGF0ZXIpIHtcbiAgICAgIHJldHVybiBvYmplY3QgPT0gbnVsbCA/IG9iamVjdCA6IGJhc2VVcGRhdGUob2JqZWN0LCBwYXRoLCBjYXN0RnVuY3Rpb24odXBkYXRlcikpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIGlzIGxpa2UgYF8udXBkYXRlYCBleGNlcHQgdGhhdCBpdCBhY2NlcHRzIGBjdXN0b21pemVyYCB3aGljaCBpc1xuICAgICAqIGludm9rZWQgdG8gcHJvZHVjZSB0aGUgb2JqZWN0cyBvZiBgcGF0aGAuICBJZiBgY3VzdG9taXplcmAgcmV0dXJucyBgdW5kZWZpbmVkYFxuICAgICAqIHBhdGggY3JlYXRpb24gaXMgaGFuZGxlZCBieSB0aGUgbWV0aG9kIGluc3RlYWQuIFRoZSBgY3VzdG9taXplcmAgaXMgaW52b2tlZFxuICAgICAqIHdpdGggdGhyZWUgYXJndW1lbnRzOiAobnNWYWx1ZSwga2V5LCBuc09iamVjdCkuXG4gICAgICpcbiAgICAgKiAqKk5vdGU6KiogVGhpcyBtZXRob2QgbXV0YXRlcyBgb2JqZWN0YC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjYuMFxuICAgICAqIEBjYXRlZ29yeSBPYmplY3RcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gbW9kaWZ5LlxuICAgICAqIEBwYXJhbSB7QXJyYXl8c3RyaW5nfSBwYXRoIFRoZSBwYXRoIG9mIHRoZSBwcm9wZXJ0eSB0byBzZXQuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gdXBkYXRlciBUaGUgZnVuY3Rpb24gdG8gcHJvZHVjZSB0aGUgdXBkYXRlZCB2YWx1ZS5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbY3VzdG9taXplcl0gVGhlIGZ1bmN0aW9uIHRvIGN1c3RvbWl6ZSBhc3NpZ25lZCB2YWx1ZXMuXG4gICAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyBgb2JqZWN0YC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIG9iamVjdCA9IHt9O1xuICAgICAqXG4gICAgICogXy51cGRhdGVXaXRoKG9iamVjdCwgJ1swXVsxXScsIF8uY29uc3RhbnQoJ2EnKSwgT2JqZWN0KTtcbiAgICAgKiAvLyA9PiB7ICcwJzogeyAnMSc6ICdhJyB9IH1cbiAgICAgKi9cbiAgICBmdW5jdGlvbiB1cGRhdGVXaXRoKG9iamVjdCwgcGF0aCwgdXBkYXRlciwgY3VzdG9taXplcikge1xuICAgICAgY3VzdG9taXplciA9IHR5cGVvZiBjdXN0b21pemVyID09ICdmdW5jdGlvbicgPyBjdXN0b21pemVyIDogdW5kZWZpbmVkO1xuICAgICAgcmV0dXJuIG9iamVjdCA9PSBudWxsID8gb2JqZWN0IDogYmFzZVVwZGF0ZShvYmplY3QsIHBhdGgsIGNhc3RGdW5jdGlvbih1cGRhdGVyKSwgY3VzdG9taXplcik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhbiBhcnJheSBvZiB0aGUgb3duIGVudW1lcmFibGUgc3RyaW5nIGtleWVkIHByb3BlcnR5IHZhbHVlcyBvZiBgb2JqZWN0YC5cbiAgICAgKlxuICAgICAqICoqTm90ZToqKiBOb24tb2JqZWN0IHZhbHVlcyBhcmUgY29lcmNlZCB0byBvYmplY3RzLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBzaW5jZSAwLjEuMFxuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQGNhdGVnb3J5IE9iamVjdFxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBxdWVyeS5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIGFycmF5IG9mIHByb3BlcnR5IHZhbHVlcy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogZnVuY3Rpb24gRm9vKCkge1xuICAgICAqICAgdGhpcy5hID0gMTtcbiAgICAgKiAgIHRoaXMuYiA9IDI7XG4gICAgICogfVxuICAgICAqXG4gICAgICogRm9vLnByb3RvdHlwZS5jID0gMztcbiAgICAgKlxuICAgICAqIF8udmFsdWVzKG5ldyBGb28pO1xuICAgICAqIC8vID0+IFsxLCAyXSAoaXRlcmF0aW9uIG9yZGVyIGlzIG5vdCBndWFyYW50ZWVkKVxuICAgICAqXG4gICAgICogXy52YWx1ZXMoJ2hpJyk7XG4gICAgICogLy8gPT4gWydoJywgJ2knXVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIHZhbHVlcyhvYmplY3QpIHtcbiAgICAgIHJldHVybiBvYmplY3QgPT0gbnVsbCA/IFtdIDogYmFzZVZhbHVlcyhvYmplY3QsIGtleXMob2JqZWN0KSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhbiBhcnJheSBvZiB0aGUgb3duIGFuZCBpbmhlcml0ZWQgZW51bWVyYWJsZSBzdHJpbmcga2V5ZWQgcHJvcGVydHlcbiAgICAgKiB2YWx1ZXMgb2YgYG9iamVjdGAuXG4gICAgICpcbiAgICAgKiAqKk5vdGU6KiogTm9uLW9iamVjdCB2YWx1ZXMgYXJlIGNvZXJjZWQgdG8gb2JqZWN0cy5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAzLjAuMFxuICAgICAqIEBjYXRlZ29yeSBPYmplY3RcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gcXVlcnkuXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBhcnJheSBvZiBwcm9wZXJ0eSB2YWx1ZXMuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIGZ1bmN0aW9uIEZvbygpIHtcbiAgICAgKiAgIHRoaXMuYSA9IDE7XG4gICAgICogICB0aGlzLmIgPSAyO1xuICAgICAqIH1cbiAgICAgKlxuICAgICAqIEZvby5wcm90b3R5cGUuYyA9IDM7XG4gICAgICpcbiAgICAgKiBfLnZhbHVlc0luKG5ldyBGb28pO1xuICAgICAqIC8vID0+IFsxLCAyLCAzXSAoaXRlcmF0aW9uIG9yZGVyIGlzIG5vdCBndWFyYW50ZWVkKVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIHZhbHVlc0luKG9iamVjdCkge1xuICAgICAgcmV0dXJuIG9iamVjdCA9PSBudWxsID8gW10gOiBiYXNlVmFsdWVzKG9iamVjdCwga2V5c0luKG9iamVjdCkpO1xuICAgIH1cblxuICAgIC8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi9cblxuICAgIC8qKlxuICAgICAqIENsYW1wcyBgbnVtYmVyYCB3aXRoaW4gdGhlIGluY2x1c2l2ZSBgbG93ZXJgIGFuZCBgdXBwZXJgIGJvdW5kcy5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjAuMFxuICAgICAqIEBjYXRlZ29yeSBOdW1iZXJcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gbnVtYmVyIFRoZSBudW1iZXIgdG8gY2xhbXAuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtsb3dlcl0gVGhlIGxvd2VyIGJvdW5kLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSB1cHBlciBUaGUgdXBwZXIgYm91bmQuXG4gICAgICogQHJldHVybnMge251bWJlcn0gUmV0dXJucyB0aGUgY2xhbXBlZCBudW1iZXIuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uY2xhbXAoLTEwLCAtNSwgNSk7XG4gICAgICogLy8gPT4gLTVcbiAgICAgKlxuICAgICAqIF8uY2xhbXAoMTAsIC01LCA1KTtcbiAgICAgKiAvLyA9PiA1XG4gICAgICovXG4gICAgZnVuY3Rpb24gY2xhbXAobnVtYmVyLCBsb3dlciwgdXBwZXIpIHtcbiAgICAgIGlmICh1cHBlciA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHVwcGVyID0gbG93ZXI7XG4gICAgICAgIGxvd2VyID0gdW5kZWZpbmVkO1xuICAgICAgfVxuICAgICAgaWYgKHVwcGVyICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgdXBwZXIgPSB0b051bWJlcih1cHBlcik7XG4gICAgICAgIHVwcGVyID0gdXBwZXIgPT09IHVwcGVyID8gdXBwZXIgOiAwO1xuICAgICAgfVxuICAgICAgaWYgKGxvd2VyICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgbG93ZXIgPSB0b051bWJlcihsb3dlcik7XG4gICAgICAgIGxvd2VyID0gbG93ZXIgPT09IGxvd2VyID8gbG93ZXIgOiAwO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGJhc2VDbGFtcCh0b051bWJlcihudW1iZXIpLCBsb3dlciwgdXBwZXIpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENoZWNrcyBpZiBgbmAgaXMgYmV0d2VlbiBgc3RhcnRgIGFuZCB1cCB0bywgYnV0IG5vdCBpbmNsdWRpbmcsIGBlbmRgLiBJZlxuICAgICAqIGBlbmRgIGlzIG5vdCBzcGVjaWZpZWQsIGl0J3Mgc2V0IHRvIGBzdGFydGAgd2l0aCBgc3RhcnRgIHRoZW4gc2V0IHRvIGAwYC5cbiAgICAgKiBJZiBgc3RhcnRgIGlzIGdyZWF0ZXIgdGhhbiBgZW5kYCB0aGUgcGFyYW1zIGFyZSBzd2FwcGVkIHRvIHN1cHBvcnRcbiAgICAgKiBuZWdhdGl2ZSByYW5nZXMuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMy4zLjBcbiAgICAgKiBAY2F0ZWdvcnkgTnVtYmVyXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IG51bWJlciBUaGUgbnVtYmVyIHRvIGNoZWNrLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbc3RhcnQ9MF0gVGhlIHN0YXJ0IG9mIHRoZSByYW5nZS5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gZW5kIFRoZSBlbmQgb2YgdGhlIHJhbmdlLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgbnVtYmVyYCBpcyBpbiB0aGUgcmFuZ2UsIGVsc2UgYGZhbHNlYC5cbiAgICAgKiBAc2VlIF8ucmFuZ2UsIF8ucmFuZ2VSaWdodFxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLmluUmFuZ2UoMywgMiwgNCk7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqXG4gICAgICogXy5pblJhbmdlKDQsIDgpO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKlxuICAgICAqIF8uaW5SYW5nZSg0LCAyKTtcbiAgICAgKiAvLyA9PiBmYWxzZVxuICAgICAqXG4gICAgICogXy5pblJhbmdlKDIsIDIpO1xuICAgICAqIC8vID0+IGZhbHNlXG4gICAgICpcbiAgICAgKiBfLmluUmFuZ2UoMS4yLCAyKTtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICpcbiAgICAgKiBfLmluUmFuZ2UoNS4yLCA0KTtcbiAgICAgKiAvLyA9PiBmYWxzZVxuICAgICAqXG4gICAgICogXy5pblJhbmdlKC0zLCAtMiwgLTYpO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBpblJhbmdlKG51bWJlciwgc3RhcnQsIGVuZCkge1xuICAgICAgc3RhcnQgPSB0b0Zpbml0ZShzdGFydCk7XG4gICAgICBpZiAoZW5kID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgZW5kID0gc3RhcnQ7XG4gICAgICAgIHN0YXJ0ID0gMDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGVuZCA9IHRvRmluaXRlKGVuZCk7XG4gICAgICB9XG4gICAgICBudW1iZXIgPSB0b051bWJlcihudW1iZXIpO1xuICAgICAgcmV0dXJuIGJhc2VJblJhbmdlKG51bWJlciwgc3RhcnQsIGVuZCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUHJvZHVjZXMgYSByYW5kb20gbnVtYmVyIGJldHdlZW4gdGhlIGluY2x1c2l2ZSBgbG93ZXJgIGFuZCBgdXBwZXJgIGJvdW5kcy5cbiAgICAgKiBJZiBvbmx5IG9uZSBhcmd1bWVudCBpcyBwcm92aWRlZCBhIG51bWJlciBiZXR3ZWVuIGAwYCBhbmQgdGhlIGdpdmVuIG51bWJlclxuICAgICAqIGlzIHJldHVybmVkLiBJZiBgZmxvYXRpbmdgIGlzIGB0cnVlYCwgb3IgZWl0aGVyIGBsb3dlcmAgb3IgYHVwcGVyYCBhcmVcbiAgICAgKiBmbG9hdHMsIGEgZmxvYXRpbmctcG9pbnQgbnVtYmVyIGlzIHJldHVybmVkIGluc3RlYWQgb2YgYW4gaW50ZWdlci5cbiAgICAgKlxuICAgICAqICoqTm90ZToqKiBKYXZhU2NyaXB0IGZvbGxvd3MgdGhlIElFRUUtNzU0IHN0YW5kYXJkIGZvciByZXNvbHZpbmdcbiAgICAgKiBmbG9hdGluZy1wb2ludCB2YWx1ZXMgd2hpY2ggY2FuIHByb2R1Y2UgdW5leHBlY3RlZCByZXN1bHRzLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDAuNy4wXG4gICAgICogQGNhdGVnb3J5IE51bWJlclxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbbG93ZXI9MF0gVGhlIGxvd2VyIGJvdW5kLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbdXBwZXI9MV0gVGhlIHVwcGVyIGJvdW5kLlxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbn0gW2Zsb2F0aW5nXSBTcGVjaWZ5IHJldHVybmluZyBhIGZsb2F0aW5nLXBvaW50IG51bWJlci5cbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBSZXR1cm5zIHRoZSByYW5kb20gbnVtYmVyLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLnJhbmRvbSgwLCA1KTtcbiAgICAgKiAvLyA9PiBhbiBpbnRlZ2VyIGJldHdlZW4gMCBhbmQgNVxuICAgICAqXG4gICAgICogXy5yYW5kb20oNSk7XG4gICAgICogLy8gPT4gYWxzbyBhbiBpbnRlZ2VyIGJldHdlZW4gMCBhbmQgNVxuICAgICAqXG4gICAgICogXy5yYW5kb20oNSwgdHJ1ZSk7XG4gICAgICogLy8gPT4gYSBmbG9hdGluZy1wb2ludCBudW1iZXIgYmV0d2VlbiAwIGFuZCA1XG4gICAgICpcbiAgICAgKiBfLnJhbmRvbSgxLjIsIDUuMik7XG4gICAgICogLy8gPT4gYSBmbG9hdGluZy1wb2ludCBudW1iZXIgYmV0d2VlbiAxLjIgYW5kIDUuMlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIHJhbmRvbShsb3dlciwgdXBwZXIsIGZsb2F0aW5nKSB7XG4gICAgICBpZiAoZmxvYXRpbmcgJiYgdHlwZW9mIGZsb2F0aW5nICE9ICdib29sZWFuJyAmJiBpc0l0ZXJhdGVlQ2FsbChsb3dlciwgdXBwZXIsIGZsb2F0aW5nKSkge1xuICAgICAgICB1cHBlciA9IGZsb2F0aW5nID0gdW5kZWZpbmVkO1xuICAgICAgfVxuICAgICAgaWYgKGZsb2F0aW5nID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgaWYgKHR5cGVvZiB1cHBlciA9PSAnYm9vbGVhbicpIHtcbiAgICAgICAgICBmbG9hdGluZyA9IHVwcGVyO1xuICAgICAgICAgIHVwcGVyID0gdW5kZWZpbmVkO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKHR5cGVvZiBsb3dlciA9PSAnYm9vbGVhbicpIHtcbiAgICAgICAgICBmbG9hdGluZyA9IGxvd2VyO1xuICAgICAgICAgIGxvd2VyID0gdW5kZWZpbmVkO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAobG93ZXIgPT09IHVuZGVmaW5lZCAmJiB1cHBlciA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGxvd2VyID0gMDtcbiAgICAgICAgdXBwZXIgPSAxO1xuICAgICAgfVxuICAgICAgZWxzZSB7XG4gICAgICAgIGxvd2VyID0gdG9GaW5pdGUobG93ZXIpO1xuICAgICAgICBpZiAodXBwZXIgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIHVwcGVyID0gbG93ZXI7XG4gICAgICAgICAgbG93ZXIgPSAwO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHVwcGVyID0gdG9GaW5pdGUodXBwZXIpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAobG93ZXIgPiB1cHBlcikge1xuICAgICAgICB2YXIgdGVtcCA9IGxvd2VyO1xuICAgICAgICBsb3dlciA9IHVwcGVyO1xuICAgICAgICB1cHBlciA9IHRlbXA7XG4gICAgICB9XG4gICAgICBpZiAoZmxvYXRpbmcgfHwgbG93ZXIgJSAxIHx8IHVwcGVyICUgMSkge1xuICAgICAgICB2YXIgcmFuZCA9IG5hdGl2ZVJhbmRvbSgpO1xuICAgICAgICByZXR1cm4gbmF0aXZlTWluKGxvd2VyICsgKHJhbmQgKiAodXBwZXIgLSBsb3dlciArIGZyZWVQYXJzZUZsb2F0KCcxZS0nICsgKChyYW5kICsgJycpLmxlbmd0aCAtIDEpKSkpLCB1cHBlcik7XG4gICAgICB9XG4gICAgICByZXR1cm4gYmFzZVJhbmRvbShsb3dlciwgdXBwZXIpO1xuICAgIH1cblxuICAgIC8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi9cblxuICAgIC8qKlxuICAgICAqIENvbnZlcnRzIGBzdHJpbmdgIHRvIFtjYW1lbCBjYXNlXShodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9DYW1lbENhc2UpLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDMuMC4wXG4gICAgICogQGNhdGVnb3J5IFN0cmluZ1xuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBbc3RyaW5nPScnXSBUaGUgc3RyaW5nIHRvIGNvbnZlcnQuXG4gICAgICogQHJldHVybnMge3N0cmluZ30gUmV0dXJucyB0aGUgY2FtZWwgY2FzZWQgc3RyaW5nLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLmNhbWVsQ2FzZSgnRm9vIEJhcicpO1xuICAgICAqIC8vID0+ICdmb29CYXInXG4gICAgICpcbiAgICAgKiBfLmNhbWVsQ2FzZSgnLS1mb28tYmFyLS0nKTtcbiAgICAgKiAvLyA9PiAnZm9vQmFyJ1xuICAgICAqXG4gICAgICogXy5jYW1lbENhc2UoJ19fRk9PX0JBUl9fJyk7XG4gICAgICogLy8gPT4gJ2Zvb0JhcidcbiAgICAgKi9cbiAgICB2YXIgY2FtZWxDYXNlID0gY3JlYXRlQ29tcG91bmRlcihmdW5jdGlvbihyZXN1bHQsIHdvcmQsIGluZGV4KSB7XG4gICAgICB3b3JkID0gd29yZC50b0xvd2VyQ2FzZSgpO1xuICAgICAgcmV0dXJuIHJlc3VsdCArIChpbmRleCA/IGNhcGl0YWxpemUod29yZCkgOiB3b3JkKTtcbiAgICB9KTtcblxuICAgIC8qKlxuICAgICAqIENvbnZlcnRzIHRoZSBmaXJzdCBjaGFyYWN0ZXIgb2YgYHN0cmluZ2AgdG8gdXBwZXIgY2FzZSBhbmQgdGhlIHJlbWFpbmluZ1xuICAgICAqIHRvIGxvd2VyIGNhc2UuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMy4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgU3RyaW5nXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IFtzdHJpbmc9JyddIFRoZSBzdHJpbmcgdG8gY2FwaXRhbGl6ZS5cbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfSBSZXR1cm5zIHRoZSBjYXBpdGFsaXplZCBzdHJpbmcuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uY2FwaXRhbGl6ZSgnRlJFRCcpO1xuICAgICAqIC8vID0+ICdGcmVkJ1xuICAgICAqL1xuICAgIGZ1bmN0aW9uIGNhcGl0YWxpemUoc3RyaW5nKSB7XG4gICAgICByZXR1cm4gdXBwZXJGaXJzdCh0b1N0cmluZyhzdHJpbmcpLnRvTG93ZXJDYXNlKCkpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIERlYnVycnMgYHN0cmluZ2AgYnkgY29udmVydGluZ1xuICAgICAqIFtMYXRpbi0xIFN1cHBsZW1lbnRdKGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL0xhdGluLTFfU3VwcGxlbWVudF8oVW5pY29kZV9ibG9jaykjQ2hhcmFjdGVyX3RhYmxlKVxuICAgICAqIGFuZCBbTGF0aW4gRXh0ZW5kZWQtQV0oaHR0cHM6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvTGF0aW5fRXh0ZW5kZWQtQSlcbiAgICAgKiBsZXR0ZXJzIHRvIGJhc2ljIExhdGluIGxldHRlcnMgYW5kIHJlbW92aW5nXG4gICAgICogW2NvbWJpbmluZyBkaWFjcml0aWNhbCBtYXJrc10oaHR0cHM6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvQ29tYmluaW5nX0RpYWNyaXRpY2FsX01hcmtzKS5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAzLjAuMFxuICAgICAqIEBjYXRlZ29yeSBTdHJpbmdcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gW3N0cmluZz0nJ10gVGhlIHN0cmluZyB0byBkZWJ1cnIuXG4gICAgICogQHJldHVybnMge3N0cmluZ30gUmV0dXJucyB0aGUgZGVidXJyZWQgc3RyaW5nLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLmRlYnVycignZMOpasOgIHZ1Jyk7XG4gICAgICogLy8gPT4gJ2RlamEgdnUnXG4gICAgICovXG4gICAgZnVuY3Rpb24gZGVidXJyKHN0cmluZykge1xuICAgICAgc3RyaW5nID0gdG9TdHJpbmcoc3RyaW5nKTtcbiAgICAgIHJldHVybiBzdHJpbmcgJiYgc3RyaW5nLnJlcGxhY2UocmVMYXRpbiwgZGVidXJyTGV0dGVyKS5yZXBsYWNlKHJlQ29tYm9NYXJrLCAnJyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2hlY2tzIGlmIGBzdHJpbmdgIGVuZHMgd2l0aCB0aGUgZ2l2ZW4gdGFyZ2V0IHN0cmluZy5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAzLjAuMFxuICAgICAqIEBjYXRlZ29yeSBTdHJpbmdcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gW3N0cmluZz0nJ10gVGhlIHN0cmluZyB0byBpbnNwZWN0LlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBbdGFyZ2V0XSBUaGUgc3RyaW5nIHRvIHNlYXJjaCBmb3IuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtwb3NpdGlvbj1zdHJpbmcubGVuZ3RoXSBUaGUgcG9zaXRpb24gdG8gc2VhcmNoIHVwIHRvLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgc3RyaW5nYCBlbmRzIHdpdGggYHRhcmdldGAsXG4gICAgICogIGVsc2UgYGZhbHNlYC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5lbmRzV2l0aCgnYWJjJywgJ2MnKTtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICpcbiAgICAgKiBfLmVuZHNXaXRoKCdhYmMnLCAnYicpO1xuICAgICAqIC8vID0+IGZhbHNlXG4gICAgICpcbiAgICAgKiBfLmVuZHNXaXRoKCdhYmMnLCAnYicsIDIpO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBlbmRzV2l0aChzdHJpbmcsIHRhcmdldCwgcG9zaXRpb24pIHtcbiAgICAgIHN0cmluZyA9IHRvU3RyaW5nKHN0cmluZyk7XG4gICAgICB0YXJnZXQgPSBiYXNlVG9TdHJpbmcodGFyZ2V0KTtcblxuICAgICAgdmFyIGxlbmd0aCA9IHN0cmluZy5sZW5ndGg7XG4gICAgICBwb3NpdGlvbiA9IHBvc2l0aW9uID09PSB1bmRlZmluZWRcbiAgICAgICAgPyBsZW5ndGhcbiAgICAgICAgOiBiYXNlQ2xhbXAodG9JbnRlZ2VyKHBvc2l0aW9uKSwgMCwgbGVuZ3RoKTtcblxuICAgICAgdmFyIGVuZCA9IHBvc2l0aW9uO1xuICAgICAgcG9zaXRpb24gLT0gdGFyZ2V0Lmxlbmd0aDtcbiAgICAgIHJldHVybiBwb3NpdGlvbiA+PSAwICYmIHN0cmluZy5zbGljZShwb3NpdGlvbiwgZW5kKSA9PSB0YXJnZXQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ29udmVydHMgdGhlIGNoYXJhY3RlcnMgXCImXCIsIFwiPFwiLCBcIj5cIiwgJ1wiJywgYW5kIFwiJ1wiIGluIGBzdHJpbmdgIHRvIHRoZWlyXG4gICAgICogY29ycmVzcG9uZGluZyBIVE1MIGVudGl0aWVzLlxuICAgICAqXG4gICAgICogKipOb3RlOioqIE5vIG90aGVyIGNoYXJhY3RlcnMgYXJlIGVzY2FwZWQuIFRvIGVzY2FwZSBhZGRpdGlvbmFsXG4gICAgICogY2hhcmFjdGVycyB1c2UgYSB0aGlyZC1wYXJ0eSBsaWJyYXJ5IGxpa2UgW19oZV9dKGh0dHBzOi8vbXRocy5iZS9oZSkuXG4gICAgICpcbiAgICAgKiBUaG91Z2ggdGhlIFwiPlwiIGNoYXJhY3RlciBpcyBlc2NhcGVkIGZvciBzeW1tZXRyeSwgY2hhcmFjdGVycyBsaWtlXG4gICAgICogXCI+XCIgYW5kIFwiL1wiIGRvbid0IG5lZWQgZXNjYXBpbmcgaW4gSFRNTCBhbmQgaGF2ZSBubyBzcGVjaWFsIG1lYW5pbmdcbiAgICAgKiB1bmxlc3MgdGhleSdyZSBwYXJ0IG9mIGEgdGFnIG9yIHVucXVvdGVkIGF0dHJpYnV0ZSB2YWx1ZS4gU2VlXG4gICAgICogW01hdGhpYXMgQnluZW5zJ3MgYXJ0aWNsZV0oaHR0cHM6Ly9tYXRoaWFzYnluZW5zLmJlL25vdGVzL2FtYmlndW91cy1hbXBlcnNhbmRzKVxuICAgICAqICh1bmRlciBcInNlbWktcmVsYXRlZCBmdW4gZmFjdFwiKSBmb3IgbW9yZSBkZXRhaWxzLlxuICAgICAqXG4gICAgICogV2hlbiB3b3JraW5nIHdpdGggSFRNTCB5b3Ugc2hvdWxkIGFsd2F5c1xuICAgICAqIFtxdW90ZSBhdHRyaWJ1dGUgdmFsdWVzXShodHRwOi8vd29ua28uY29tL3Bvc3QvaHRtbC1lc2NhcGluZykgdG8gcmVkdWNlXG4gICAgICogWFNTIHZlY3RvcnMuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQHNpbmNlIDAuMS4wXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAY2F0ZWdvcnkgU3RyaW5nXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IFtzdHJpbmc9JyddIFRoZSBzdHJpbmcgdG8gZXNjYXBlLlxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IFJldHVybnMgdGhlIGVzY2FwZWQgc3RyaW5nLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLmVzY2FwZSgnZnJlZCwgYmFybmV5LCAmIHBlYmJsZXMnKTtcbiAgICAgKiAvLyA9PiAnZnJlZCwgYmFybmV5LCAmYW1wOyBwZWJibGVzJ1xuICAgICAqL1xuICAgIGZ1bmN0aW9uIGVzY2FwZShzdHJpbmcpIHtcbiAgICAgIHN0cmluZyA9IHRvU3RyaW5nKHN0cmluZyk7XG4gICAgICByZXR1cm4gKHN0cmluZyAmJiByZUhhc1VuZXNjYXBlZEh0bWwudGVzdChzdHJpbmcpKVxuICAgICAgICA/IHN0cmluZy5yZXBsYWNlKHJlVW5lc2NhcGVkSHRtbCwgZXNjYXBlSHRtbENoYXIpXG4gICAgICAgIDogc3RyaW5nO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEVzY2FwZXMgdGhlIGBSZWdFeHBgIHNwZWNpYWwgY2hhcmFjdGVycyBcIl5cIiwgXCIkXCIsIFwiXFxcIiwgXCIuXCIsIFwiKlwiLCBcIitcIixcbiAgICAgKiBcIj9cIiwgXCIoXCIsIFwiKVwiLCBcIltcIiwgXCJdXCIsIFwie1wiLCBcIn1cIiwgYW5kIFwifFwiIGluIGBzdHJpbmdgLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDMuMC4wXG4gICAgICogQGNhdGVnb3J5IFN0cmluZ1xuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBbc3RyaW5nPScnXSBUaGUgc3RyaW5nIHRvIGVzY2FwZS5cbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfSBSZXR1cm5zIHRoZSBlc2NhcGVkIHN0cmluZy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5lc2NhcGVSZWdFeHAoJ1tsb2Rhc2hdKGh0dHBzOi8vbG9kYXNoLmNvbS8pJyk7XG4gICAgICogLy8gPT4gJ1xcW2xvZGFzaFxcXVxcKGh0dHBzOi8vbG9kYXNoXFwuY29tL1xcKSdcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBlc2NhcGVSZWdFeHAoc3RyaW5nKSB7XG4gICAgICBzdHJpbmcgPSB0b1N0cmluZyhzdHJpbmcpO1xuICAgICAgcmV0dXJuIChzdHJpbmcgJiYgcmVIYXNSZWdFeHBDaGFyLnRlc3Qoc3RyaW5nKSlcbiAgICAgICAgPyBzdHJpbmcucmVwbGFjZShyZVJlZ0V4cENoYXIsICdcXFxcJCYnKVxuICAgICAgICA6IHN0cmluZztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDb252ZXJ0cyBgc3RyaW5nYCB0b1xuICAgICAqIFtrZWJhYiBjYXNlXShodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9MZXR0ZXJfY2FzZSNTcGVjaWFsX2Nhc2Vfc3R5bGVzKS5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAzLjAuMFxuICAgICAqIEBjYXRlZ29yeSBTdHJpbmdcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gW3N0cmluZz0nJ10gVGhlIHN0cmluZyB0byBjb252ZXJ0LlxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IFJldHVybnMgdGhlIGtlYmFiIGNhc2VkIHN0cmluZy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5rZWJhYkNhc2UoJ0ZvbyBCYXInKTtcbiAgICAgKiAvLyA9PiAnZm9vLWJhcidcbiAgICAgKlxuICAgICAqIF8ua2ViYWJDYXNlKCdmb29CYXInKTtcbiAgICAgKiAvLyA9PiAnZm9vLWJhcidcbiAgICAgKlxuICAgICAqIF8ua2ViYWJDYXNlKCdfX0ZPT19CQVJfXycpO1xuICAgICAqIC8vID0+ICdmb28tYmFyJ1xuICAgICAqL1xuICAgIHZhciBrZWJhYkNhc2UgPSBjcmVhdGVDb21wb3VuZGVyKGZ1bmN0aW9uKHJlc3VsdCwgd29yZCwgaW5kZXgpIHtcbiAgICAgIHJldHVybiByZXN1bHQgKyAoaW5kZXggPyAnLScgOiAnJykgKyB3b3JkLnRvTG93ZXJDYXNlKCk7XG4gICAgfSk7XG5cbiAgICAvKipcbiAgICAgKiBDb252ZXJ0cyBgc3RyaW5nYCwgYXMgc3BhY2Ugc2VwYXJhdGVkIHdvcmRzLCB0byBsb3dlciBjYXNlLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMC4wXG4gICAgICogQGNhdGVnb3J5IFN0cmluZ1xuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBbc3RyaW5nPScnXSBUaGUgc3RyaW5nIHRvIGNvbnZlcnQuXG4gICAgICogQHJldHVybnMge3N0cmluZ30gUmV0dXJucyB0aGUgbG93ZXIgY2FzZWQgc3RyaW5nLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLmxvd2VyQ2FzZSgnLS1Gb28tQmFyLS0nKTtcbiAgICAgKiAvLyA9PiAnZm9vIGJhcidcbiAgICAgKlxuICAgICAqIF8ubG93ZXJDYXNlKCdmb29CYXInKTtcbiAgICAgKiAvLyA9PiAnZm9vIGJhcidcbiAgICAgKlxuICAgICAqIF8ubG93ZXJDYXNlKCdfX0ZPT19CQVJfXycpO1xuICAgICAqIC8vID0+ICdmb28gYmFyJ1xuICAgICAqL1xuICAgIHZhciBsb3dlckNhc2UgPSBjcmVhdGVDb21wb3VuZGVyKGZ1bmN0aW9uKHJlc3VsdCwgd29yZCwgaW5kZXgpIHtcbiAgICAgIHJldHVybiByZXN1bHQgKyAoaW5kZXggPyAnICcgOiAnJykgKyB3b3JkLnRvTG93ZXJDYXNlKCk7XG4gICAgfSk7XG5cbiAgICAvKipcbiAgICAgKiBDb252ZXJ0cyB0aGUgZmlyc3QgY2hhcmFjdGVyIG9mIGBzdHJpbmdgIHRvIGxvd2VyIGNhc2UuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgU3RyaW5nXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IFtzdHJpbmc9JyddIFRoZSBzdHJpbmcgdG8gY29udmVydC5cbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfSBSZXR1cm5zIHRoZSBjb252ZXJ0ZWQgc3RyaW5nLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLmxvd2VyRmlyc3QoJ0ZyZWQnKTtcbiAgICAgKiAvLyA9PiAnZnJlZCdcbiAgICAgKlxuICAgICAqIF8ubG93ZXJGaXJzdCgnRlJFRCcpO1xuICAgICAqIC8vID0+ICdmUkVEJ1xuICAgICAqL1xuICAgIHZhciBsb3dlckZpcnN0ID0gY3JlYXRlQ2FzZUZpcnN0KCd0b0xvd2VyQ2FzZScpO1xuXG4gICAgLyoqXG4gICAgICogUGFkcyBgc3RyaW5nYCBvbiB0aGUgbGVmdCBhbmQgcmlnaHQgc2lkZXMgaWYgaXQncyBzaG9ydGVyIHRoYW4gYGxlbmd0aGAuXG4gICAgICogUGFkZGluZyBjaGFyYWN0ZXJzIGFyZSB0cnVuY2F0ZWQgaWYgdGhleSBjYW4ndCBiZSBldmVubHkgZGl2aWRlZCBieSBgbGVuZ3RoYC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAzLjAuMFxuICAgICAqIEBjYXRlZ29yeSBTdHJpbmdcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gW3N0cmluZz0nJ10gVGhlIHN0cmluZyB0byBwYWQuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtsZW5ndGg9MF0gVGhlIHBhZGRpbmcgbGVuZ3RoLlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBbY2hhcnM9JyAnXSBUaGUgc3RyaW5nIHVzZWQgYXMgcGFkZGluZy5cbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfSBSZXR1cm5zIHRoZSBwYWRkZWQgc3RyaW5nLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLnBhZCgnYWJjJywgOCk7XG4gICAgICogLy8gPT4gJyAgYWJjICAgJ1xuICAgICAqXG4gICAgICogXy5wYWQoJ2FiYycsIDgsICdfLScpO1xuICAgICAqIC8vID0+ICdfLWFiY18tXydcbiAgICAgKlxuICAgICAqIF8ucGFkKCdhYmMnLCAzKTtcbiAgICAgKiAvLyA9PiAnYWJjJ1xuICAgICAqL1xuICAgIGZ1bmN0aW9uIHBhZChzdHJpbmcsIGxlbmd0aCwgY2hhcnMpIHtcbiAgICAgIHN0cmluZyA9IHRvU3RyaW5nKHN0cmluZyk7XG4gICAgICBsZW5ndGggPSB0b0ludGVnZXIobGVuZ3RoKTtcblxuICAgICAgdmFyIHN0ckxlbmd0aCA9IGxlbmd0aCA/IHN0cmluZ1NpemUoc3RyaW5nKSA6IDA7XG4gICAgICBpZiAoIWxlbmd0aCB8fCBzdHJMZW5ndGggPj0gbGVuZ3RoKSB7XG4gICAgICAgIHJldHVybiBzdHJpbmc7XG4gICAgICB9XG4gICAgICB2YXIgbWlkID0gKGxlbmd0aCAtIHN0ckxlbmd0aCkgLyAyO1xuICAgICAgcmV0dXJuIChcbiAgICAgICAgY3JlYXRlUGFkZGluZyhuYXRpdmVGbG9vcihtaWQpLCBjaGFycykgK1xuICAgICAgICBzdHJpbmcgK1xuICAgICAgICBjcmVhdGVQYWRkaW5nKG5hdGl2ZUNlaWwobWlkKSwgY2hhcnMpXG4gICAgICApO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFBhZHMgYHN0cmluZ2Agb24gdGhlIHJpZ2h0IHNpZGUgaWYgaXQncyBzaG9ydGVyIHRoYW4gYGxlbmd0aGAuIFBhZGRpbmdcbiAgICAgKiBjaGFyYWN0ZXJzIGFyZSB0cnVuY2F0ZWQgaWYgdGhleSBleGNlZWQgYGxlbmd0aGAuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgU3RyaW5nXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IFtzdHJpbmc9JyddIFRoZSBzdHJpbmcgdG8gcGFkLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbbGVuZ3RoPTBdIFRoZSBwYWRkaW5nIGxlbmd0aC5cbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gW2NoYXJzPScgJ10gVGhlIHN0cmluZyB1c2VkIGFzIHBhZGRpbmcuXG4gICAgICogQHJldHVybnMge3N0cmluZ30gUmV0dXJucyB0aGUgcGFkZGVkIHN0cmluZy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5wYWRFbmQoJ2FiYycsIDYpO1xuICAgICAqIC8vID0+ICdhYmMgICAnXG4gICAgICpcbiAgICAgKiBfLnBhZEVuZCgnYWJjJywgNiwgJ18tJyk7XG4gICAgICogLy8gPT4gJ2FiY18tXydcbiAgICAgKlxuICAgICAqIF8ucGFkRW5kKCdhYmMnLCAzKTtcbiAgICAgKiAvLyA9PiAnYWJjJ1xuICAgICAqL1xuICAgIGZ1bmN0aW9uIHBhZEVuZChzdHJpbmcsIGxlbmd0aCwgY2hhcnMpIHtcbiAgICAgIHN0cmluZyA9IHRvU3RyaW5nKHN0cmluZyk7XG4gICAgICBsZW5ndGggPSB0b0ludGVnZXIobGVuZ3RoKTtcblxuICAgICAgdmFyIHN0ckxlbmd0aCA9IGxlbmd0aCA/IHN0cmluZ1NpemUoc3RyaW5nKSA6IDA7XG4gICAgICByZXR1cm4gKGxlbmd0aCAmJiBzdHJMZW5ndGggPCBsZW5ndGgpXG4gICAgICAgID8gKHN0cmluZyArIGNyZWF0ZVBhZGRpbmcobGVuZ3RoIC0gc3RyTGVuZ3RoLCBjaGFycykpXG4gICAgICAgIDogc3RyaW5nO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFBhZHMgYHN0cmluZ2Agb24gdGhlIGxlZnQgc2lkZSBpZiBpdCdzIHNob3J0ZXIgdGhhbiBgbGVuZ3RoYC4gUGFkZGluZ1xuICAgICAqIGNoYXJhY3RlcnMgYXJlIHRydW5jYXRlZCBpZiB0aGV5IGV4Y2VlZCBgbGVuZ3RoYC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjAuMFxuICAgICAqIEBjYXRlZ29yeSBTdHJpbmdcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gW3N0cmluZz0nJ10gVGhlIHN0cmluZyB0byBwYWQuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtsZW5ndGg9MF0gVGhlIHBhZGRpbmcgbGVuZ3RoLlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBbY2hhcnM9JyAnXSBUaGUgc3RyaW5nIHVzZWQgYXMgcGFkZGluZy5cbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfSBSZXR1cm5zIHRoZSBwYWRkZWQgc3RyaW5nLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLnBhZFN0YXJ0KCdhYmMnLCA2KTtcbiAgICAgKiAvLyA9PiAnICAgYWJjJ1xuICAgICAqXG4gICAgICogXy5wYWRTdGFydCgnYWJjJywgNiwgJ18tJyk7XG4gICAgICogLy8gPT4gJ18tX2FiYydcbiAgICAgKlxuICAgICAqIF8ucGFkU3RhcnQoJ2FiYycsIDMpO1xuICAgICAqIC8vID0+ICdhYmMnXG4gICAgICovXG4gICAgZnVuY3Rpb24gcGFkU3RhcnQoc3RyaW5nLCBsZW5ndGgsIGNoYXJzKSB7XG4gICAgICBzdHJpbmcgPSB0b1N0cmluZyhzdHJpbmcpO1xuICAgICAgbGVuZ3RoID0gdG9JbnRlZ2VyKGxlbmd0aCk7XG5cbiAgICAgIHZhciBzdHJMZW5ndGggPSBsZW5ndGggPyBzdHJpbmdTaXplKHN0cmluZykgOiAwO1xuICAgICAgcmV0dXJuIChsZW5ndGggJiYgc3RyTGVuZ3RoIDwgbGVuZ3RoKVxuICAgICAgICA/IChjcmVhdGVQYWRkaW5nKGxlbmd0aCAtIHN0ckxlbmd0aCwgY2hhcnMpICsgc3RyaW5nKVxuICAgICAgICA6IHN0cmluZztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDb252ZXJ0cyBgc3RyaW5nYCB0byBhbiBpbnRlZ2VyIG9mIHRoZSBzcGVjaWZpZWQgcmFkaXguIElmIGByYWRpeGAgaXNcbiAgICAgKiBgdW5kZWZpbmVkYCBvciBgMGAsIGEgYHJhZGl4YCBvZiBgMTBgIGlzIHVzZWQgdW5sZXNzIGB2YWx1ZWAgaXMgYVxuICAgICAqIGhleGFkZWNpbWFsLCBpbiB3aGljaCBjYXNlIGEgYHJhZGl4YCBvZiBgMTZgIGlzIHVzZWQuXG4gICAgICpcbiAgICAgKiAqKk5vdGU6KiogVGhpcyBtZXRob2QgYWxpZ25zIHdpdGggdGhlXG4gICAgICogW0VTNSBpbXBsZW1lbnRhdGlvbl0oaHR0cHM6Ly9lczUuZ2l0aHViLmlvLyN4MTUuMS4yLjIpIG9mIGBwYXJzZUludGAuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMS4xLjBcbiAgICAgKiBAY2F0ZWdvcnkgU3RyaW5nXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IHN0cmluZyBUaGUgc3RyaW5nIHRvIGNvbnZlcnQuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtyYWRpeD0xMF0gVGhlIHJhZGl4IHRvIGludGVycHJldCBgdmFsdWVgIGJ5LlxuICAgICAqIEBwYXJhbS0ge09iamVjdH0gW2d1YXJkXSBFbmFibGVzIHVzZSBhcyBhbiBpdGVyYXRlZSBmb3IgbWV0aG9kcyBsaWtlIGBfLm1hcGAuXG4gICAgICogQHJldHVybnMge251bWJlcn0gUmV0dXJucyB0aGUgY29udmVydGVkIGludGVnZXIuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8ucGFyc2VJbnQoJzA4Jyk7XG4gICAgICogLy8gPT4gOFxuICAgICAqXG4gICAgICogXy5tYXAoWyc2JywgJzA4JywgJzEwJ10sIF8ucGFyc2VJbnQpO1xuICAgICAqIC8vID0+IFs2LCA4LCAxMF1cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBwYXJzZUludChzdHJpbmcsIHJhZGl4LCBndWFyZCkge1xuICAgICAgaWYgKGd1YXJkIHx8IHJhZGl4ID09IG51bGwpIHtcbiAgICAgICAgcmFkaXggPSAwO1xuICAgICAgfSBlbHNlIGlmIChyYWRpeCkge1xuICAgICAgICByYWRpeCA9ICtyYWRpeDtcbiAgICAgIH1cbiAgICAgIHJldHVybiBuYXRpdmVQYXJzZUludCh0b1N0cmluZyhzdHJpbmcpLnJlcGxhY2UocmVUcmltU3RhcnQsICcnKSwgcmFkaXggfHwgMCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmVwZWF0cyB0aGUgZ2l2ZW4gc3RyaW5nIGBuYCB0aW1lcy5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAzLjAuMFxuICAgICAqIEBjYXRlZ29yeSBTdHJpbmdcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gW3N0cmluZz0nJ10gVGhlIHN0cmluZyB0byByZXBlYXQuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtuPTFdIFRoZSBudW1iZXIgb2YgdGltZXMgdG8gcmVwZWF0IHRoZSBzdHJpbmcuXG4gICAgICogQHBhcmFtLSB7T2JqZWN0fSBbZ3VhcmRdIEVuYWJsZXMgdXNlIGFzIGFuIGl0ZXJhdGVlIGZvciBtZXRob2RzIGxpa2UgYF8ubWFwYC5cbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfSBSZXR1cm5zIHRoZSByZXBlYXRlZCBzdHJpbmcuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8ucmVwZWF0KCcqJywgMyk7XG4gICAgICogLy8gPT4gJyoqKidcbiAgICAgKlxuICAgICAqIF8ucmVwZWF0KCdhYmMnLCAyKTtcbiAgICAgKiAvLyA9PiAnYWJjYWJjJ1xuICAgICAqXG4gICAgICogXy5yZXBlYXQoJ2FiYycsIDApO1xuICAgICAqIC8vID0+ICcnXG4gICAgICovXG4gICAgZnVuY3Rpb24gcmVwZWF0KHN0cmluZywgbiwgZ3VhcmQpIHtcbiAgICAgIGlmICgoZ3VhcmQgPyBpc0l0ZXJhdGVlQ2FsbChzdHJpbmcsIG4sIGd1YXJkKSA6IG4gPT09IHVuZGVmaW5lZCkpIHtcbiAgICAgICAgbiA9IDE7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBuID0gdG9JbnRlZ2VyKG4pO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGJhc2VSZXBlYXQodG9TdHJpbmcoc3RyaW5nKSwgbik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmVwbGFjZXMgbWF0Y2hlcyBmb3IgYHBhdHRlcm5gIGluIGBzdHJpbmdgIHdpdGggYHJlcGxhY2VtZW50YC5cbiAgICAgKlxuICAgICAqICoqTm90ZToqKiBUaGlzIG1ldGhvZCBpcyBiYXNlZCBvblxuICAgICAqIFtgU3RyaW5nI3JlcGxhY2VgXShodHRwczovL21kbi5pby9TdHJpbmcvcmVwbGFjZSkuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgU3RyaW5nXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IFtzdHJpbmc9JyddIFRoZSBzdHJpbmcgdG8gbW9kaWZ5LlxuICAgICAqIEBwYXJhbSB7UmVnRXhwfHN0cmluZ30gcGF0dGVybiBUaGUgcGF0dGVybiB0byByZXBsYWNlLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb258c3RyaW5nfSByZXBsYWNlbWVudCBUaGUgbWF0Y2ggcmVwbGFjZW1lbnQuXG4gICAgICogQHJldHVybnMge3N0cmluZ30gUmV0dXJucyB0aGUgbW9kaWZpZWQgc3RyaW5nLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLnJlcGxhY2UoJ0hpIEZyZWQnLCAnRnJlZCcsICdCYXJuZXknKTtcbiAgICAgKiAvLyA9PiAnSGkgQmFybmV5J1xuICAgICAqL1xuICAgIGZ1bmN0aW9uIHJlcGxhY2UoKSB7XG4gICAgICB2YXIgYXJncyA9IGFyZ3VtZW50cyxcbiAgICAgICAgICBzdHJpbmcgPSB0b1N0cmluZyhhcmdzWzBdKTtcblxuICAgICAgcmV0dXJuIGFyZ3MubGVuZ3RoIDwgMyA/IHN0cmluZyA6IHN0cmluZy5yZXBsYWNlKGFyZ3NbMV0sIGFyZ3NbMl0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENvbnZlcnRzIGBzdHJpbmdgIHRvXG4gICAgICogW3NuYWtlIGNhc2VdKGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL1NuYWtlX2Nhc2UpLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDMuMC4wXG4gICAgICogQGNhdGVnb3J5IFN0cmluZ1xuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBbc3RyaW5nPScnXSBUaGUgc3RyaW5nIHRvIGNvbnZlcnQuXG4gICAgICogQHJldHVybnMge3N0cmluZ30gUmV0dXJucyB0aGUgc25ha2UgY2FzZWQgc3RyaW5nLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLnNuYWtlQ2FzZSgnRm9vIEJhcicpO1xuICAgICAqIC8vID0+ICdmb29fYmFyJ1xuICAgICAqXG4gICAgICogXy5zbmFrZUNhc2UoJ2Zvb0JhcicpO1xuICAgICAqIC8vID0+ICdmb29fYmFyJ1xuICAgICAqXG4gICAgICogXy5zbmFrZUNhc2UoJy0tRk9PLUJBUi0tJyk7XG4gICAgICogLy8gPT4gJ2Zvb19iYXInXG4gICAgICovXG4gICAgdmFyIHNuYWtlQ2FzZSA9IGNyZWF0ZUNvbXBvdW5kZXIoZnVuY3Rpb24ocmVzdWx0LCB3b3JkLCBpbmRleCkge1xuICAgICAgcmV0dXJuIHJlc3VsdCArIChpbmRleCA/ICdfJyA6ICcnKSArIHdvcmQudG9Mb3dlckNhc2UoKTtcbiAgICB9KTtcblxuICAgIC8qKlxuICAgICAqIFNwbGl0cyBgc3RyaW5nYCBieSBgc2VwYXJhdG9yYC5cbiAgICAgKlxuICAgICAqICoqTm90ZToqKiBUaGlzIG1ldGhvZCBpcyBiYXNlZCBvblxuICAgICAqIFtgU3RyaW5nI3NwbGl0YF0oaHR0cHM6Ly9tZG4uaW8vU3RyaW5nL3NwbGl0KS5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjAuMFxuICAgICAqIEBjYXRlZ29yeSBTdHJpbmdcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gW3N0cmluZz0nJ10gVGhlIHN0cmluZyB0byBzcGxpdC5cbiAgICAgKiBAcGFyYW0ge1JlZ0V4cHxzdHJpbmd9IHNlcGFyYXRvciBUaGUgc2VwYXJhdG9yIHBhdHRlcm4gdG8gc3BsaXQgYnkuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtsaW1pdF0gVGhlIGxlbmd0aCB0byB0cnVuY2F0ZSByZXN1bHRzIHRvLlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgc3RyaW5nIHNlZ21lbnRzLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLnNwbGl0KCdhLWItYycsICctJywgMik7XG4gICAgICogLy8gPT4gWydhJywgJ2InXVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIHNwbGl0KHN0cmluZywgc2VwYXJhdG9yLCBsaW1pdCkge1xuICAgICAgaWYgKGxpbWl0ICYmIHR5cGVvZiBsaW1pdCAhPSAnbnVtYmVyJyAmJiBpc0l0ZXJhdGVlQ2FsbChzdHJpbmcsIHNlcGFyYXRvciwgbGltaXQpKSB7XG4gICAgICAgIHNlcGFyYXRvciA9IGxpbWl0ID0gdW5kZWZpbmVkO1xuICAgICAgfVxuICAgICAgbGltaXQgPSBsaW1pdCA9PT0gdW5kZWZpbmVkID8gTUFYX0FSUkFZX0xFTkdUSCA6IGxpbWl0ID4+PiAwO1xuICAgICAgaWYgKCFsaW1pdCkge1xuICAgICAgICByZXR1cm4gW107XG4gICAgICB9XG4gICAgICBzdHJpbmcgPSB0b1N0cmluZyhzdHJpbmcpO1xuICAgICAgaWYgKHN0cmluZyAmJiAoXG4gICAgICAgICAgICB0eXBlb2Ygc2VwYXJhdG9yID09ICdzdHJpbmcnIHx8XG4gICAgICAgICAgICAoc2VwYXJhdG9yICE9IG51bGwgJiYgIWlzUmVnRXhwKHNlcGFyYXRvcikpXG4gICAgICAgICAgKSkge1xuICAgICAgICBzZXBhcmF0b3IgPSBiYXNlVG9TdHJpbmcoc2VwYXJhdG9yKTtcbiAgICAgICAgaWYgKCFzZXBhcmF0b3IgJiYgaGFzVW5pY29kZShzdHJpbmcpKSB7XG4gICAgICAgICAgcmV0dXJuIGNhc3RTbGljZShzdHJpbmdUb0FycmF5KHN0cmluZyksIDAsIGxpbWl0KTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIHN0cmluZy5zcGxpdChzZXBhcmF0b3IsIGxpbWl0KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDb252ZXJ0cyBgc3RyaW5nYCB0b1xuICAgICAqIFtzdGFydCBjYXNlXShodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9MZXR0ZXJfY2FzZSNTdHlsaXN0aWNfb3Jfc3BlY2lhbGlzZWRfdXNhZ2UpLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDMuMS4wXG4gICAgICogQGNhdGVnb3J5IFN0cmluZ1xuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBbc3RyaW5nPScnXSBUaGUgc3RyaW5nIHRvIGNvbnZlcnQuXG4gICAgICogQHJldHVybnMge3N0cmluZ30gUmV0dXJucyB0aGUgc3RhcnQgY2FzZWQgc3RyaW5nLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLnN0YXJ0Q2FzZSgnLS1mb28tYmFyLS0nKTtcbiAgICAgKiAvLyA9PiAnRm9vIEJhcidcbiAgICAgKlxuICAgICAqIF8uc3RhcnRDYXNlKCdmb29CYXInKTtcbiAgICAgKiAvLyA9PiAnRm9vIEJhcidcbiAgICAgKlxuICAgICAqIF8uc3RhcnRDYXNlKCdfX0ZPT19CQVJfXycpO1xuICAgICAqIC8vID0+ICdGT08gQkFSJ1xuICAgICAqL1xuICAgIHZhciBzdGFydENhc2UgPSBjcmVhdGVDb21wb3VuZGVyKGZ1bmN0aW9uKHJlc3VsdCwgd29yZCwgaW5kZXgpIHtcbiAgICAgIHJldHVybiByZXN1bHQgKyAoaW5kZXggPyAnICcgOiAnJykgKyB1cHBlckZpcnN0KHdvcmQpO1xuICAgIH0pO1xuXG4gICAgLyoqXG4gICAgICogQ2hlY2tzIGlmIGBzdHJpbmdgIHN0YXJ0cyB3aXRoIHRoZSBnaXZlbiB0YXJnZXQgc3RyaW5nLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDMuMC4wXG4gICAgICogQGNhdGVnb3J5IFN0cmluZ1xuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBbc3RyaW5nPScnXSBUaGUgc3RyaW5nIHRvIGluc3BlY3QuXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IFt0YXJnZXRdIFRoZSBzdHJpbmcgdG8gc2VhcmNoIGZvci5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW3Bvc2l0aW9uPTBdIFRoZSBwb3NpdGlvbiB0byBzZWFyY2ggZnJvbS5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHN0cmluZ2Agc3RhcnRzIHdpdGggYHRhcmdldGAsXG4gICAgICogIGVsc2UgYGZhbHNlYC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5zdGFydHNXaXRoKCdhYmMnLCAnYScpO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKlxuICAgICAqIF8uc3RhcnRzV2l0aCgnYWJjJywgJ2InKTtcbiAgICAgKiAvLyA9PiBmYWxzZVxuICAgICAqXG4gICAgICogXy5zdGFydHNXaXRoKCdhYmMnLCAnYicsIDEpO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBzdGFydHNXaXRoKHN0cmluZywgdGFyZ2V0LCBwb3NpdGlvbikge1xuICAgICAgc3RyaW5nID0gdG9TdHJpbmcoc3RyaW5nKTtcbiAgICAgIHBvc2l0aW9uID0gcG9zaXRpb24gPT0gbnVsbFxuICAgICAgICA/IDBcbiAgICAgICAgOiBiYXNlQ2xhbXAodG9JbnRlZ2VyKHBvc2l0aW9uKSwgMCwgc3RyaW5nLmxlbmd0aCk7XG5cbiAgICAgIHRhcmdldCA9IGJhc2VUb1N0cmluZyh0YXJnZXQpO1xuICAgICAgcmV0dXJuIHN0cmluZy5zbGljZShwb3NpdGlvbiwgcG9zaXRpb24gKyB0YXJnZXQubGVuZ3RoKSA9PSB0YXJnZXQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIGNvbXBpbGVkIHRlbXBsYXRlIGZ1bmN0aW9uIHRoYXQgY2FuIGludGVycG9sYXRlIGRhdGEgcHJvcGVydGllc1xuICAgICAqIGluIFwiaW50ZXJwb2xhdGVcIiBkZWxpbWl0ZXJzLCBIVE1MLWVzY2FwZSBpbnRlcnBvbGF0ZWQgZGF0YSBwcm9wZXJ0aWVzIGluXG4gICAgICogXCJlc2NhcGVcIiBkZWxpbWl0ZXJzLCBhbmQgZXhlY3V0ZSBKYXZhU2NyaXB0IGluIFwiZXZhbHVhdGVcIiBkZWxpbWl0ZXJzLiBEYXRhXG4gICAgICogcHJvcGVydGllcyBtYXkgYmUgYWNjZXNzZWQgYXMgZnJlZSB2YXJpYWJsZXMgaW4gdGhlIHRlbXBsYXRlLiBJZiBhIHNldHRpbmdcbiAgICAgKiBvYmplY3QgaXMgZ2l2ZW4sIGl0IHRha2VzIHByZWNlZGVuY2Ugb3ZlciBgXy50ZW1wbGF0ZVNldHRpbmdzYCB2YWx1ZXMuXG4gICAgICpcbiAgICAgKiAqKk5vdGU6KiogSW4gdGhlIGRldmVsb3BtZW50IGJ1aWxkIGBfLnRlbXBsYXRlYCB1dGlsaXplc1xuICAgICAqIFtzb3VyY2VVUkxzXShodHRwOi8vd3d3Lmh0bWw1cm9ja3MuY29tL2VuL3R1dG9yaWFscy9kZXZlbG9wZXJ0b29scy9zb3VyY2VtYXBzLyN0b2Mtc291cmNldXJsKVxuICAgICAqIGZvciBlYXNpZXIgZGVidWdnaW5nLlxuICAgICAqXG4gICAgICogRm9yIG1vcmUgaW5mb3JtYXRpb24gb24gcHJlY29tcGlsaW5nIHRlbXBsYXRlcyBzZWVcbiAgICAgKiBbbG9kYXNoJ3MgY3VzdG9tIGJ1aWxkcyBkb2N1bWVudGF0aW9uXShodHRwczovL2xvZGFzaC5jb20vY3VzdG9tLWJ1aWxkcykuXG4gICAgICpcbiAgICAgKiBGb3IgbW9yZSBpbmZvcm1hdGlvbiBvbiBDaHJvbWUgZXh0ZW5zaW9uIHNhbmRib3hlcyBzZWVcbiAgICAgKiBbQ2hyb21lJ3MgZXh0ZW5zaW9ucyBkb2N1bWVudGF0aW9uXShodHRwczovL2RldmVsb3Blci5jaHJvbWUuY29tL2V4dGVuc2lvbnMvc2FuZGJveGluZ0V2YWwpLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBzaW5jZSAwLjEuMFxuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQGNhdGVnb3J5IFN0cmluZ1xuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBbc3RyaW5nPScnXSBUaGUgdGVtcGxhdGUgc3RyaW5nLlxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBbb3B0aW9ucz17fV0gVGhlIG9wdGlvbnMgb2JqZWN0LlxuICAgICAqIEBwYXJhbSB7UmVnRXhwfSBbb3B0aW9ucy5lc2NhcGU9Xy50ZW1wbGF0ZVNldHRpbmdzLmVzY2FwZV1cbiAgICAgKiAgVGhlIEhUTUwgXCJlc2NhcGVcIiBkZWxpbWl0ZXIuXG4gICAgICogQHBhcmFtIHtSZWdFeHB9IFtvcHRpb25zLmV2YWx1YXRlPV8udGVtcGxhdGVTZXR0aW5ncy5ldmFsdWF0ZV1cbiAgICAgKiAgVGhlIFwiZXZhbHVhdGVcIiBkZWxpbWl0ZXIuXG4gICAgICogQHBhcmFtIHtPYmplY3R9IFtvcHRpb25zLmltcG9ydHM9Xy50ZW1wbGF0ZVNldHRpbmdzLmltcG9ydHNdXG4gICAgICogIEFuIG9iamVjdCB0byBpbXBvcnQgaW50byB0aGUgdGVtcGxhdGUgYXMgZnJlZSB2YXJpYWJsZXMuXG4gICAgICogQHBhcmFtIHtSZWdFeHB9IFtvcHRpb25zLmludGVycG9sYXRlPV8udGVtcGxhdGVTZXR0aW5ncy5pbnRlcnBvbGF0ZV1cbiAgICAgKiAgVGhlIFwiaW50ZXJwb2xhdGVcIiBkZWxpbWl0ZXIuXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IFtvcHRpb25zLnNvdXJjZVVSTD0nbG9kYXNoLnRlbXBsYXRlU291cmNlc1tuXSddXG4gICAgICogIFRoZSBzb3VyY2VVUkwgb2YgdGhlIGNvbXBpbGVkIHRlbXBsYXRlLlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBbb3B0aW9ucy52YXJpYWJsZT0nb2JqJ11cbiAgICAgKiAgVGhlIGRhdGEgb2JqZWN0IHZhcmlhYmxlIG5hbWUuXG4gICAgICogQHBhcmFtLSB7T2JqZWN0fSBbZ3VhcmRdIEVuYWJsZXMgdXNlIGFzIGFuIGl0ZXJhdGVlIGZvciBtZXRob2RzIGxpa2UgYF8ubWFwYC5cbiAgICAgKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIGNvbXBpbGVkIHRlbXBsYXRlIGZ1bmN0aW9uLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiAvLyBVc2UgdGhlIFwiaW50ZXJwb2xhdGVcIiBkZWxpbWl0ZXIgdG8gY3JlYXRlIGEgY29tcGlsZWQgdGVtcGxhdGUuXG4gICAgICogdmFyIGNvbXBpbGVkID0gXy50ZW1wbGF0ZSgnaGVsbG8gPCU9IHVzZXIgJT4hJyk7XG4gICAgICogY29tcGlsZWQoeyAndXNlcic6ICdmcmVkJyB9KTtcbiAgICAgKiAvLyA9PiAnaGVsbG8gZnJlZCEnXG4gICAgICpcbiAgICAgKiAvLyBVc2UgdGhlIEhUTUwgXCJlc2NhcGVcIiBkZWxpbWl0ZXIgdG8gZXNjYXBlIGRhdGEgcHJvcGVydHkgdmFsdWVzLlxuICAgICAqIHZhciBjb21waWxlZCA9IF8udGVtcGxhdGUoJzxiPjwlLSB2YWx1ZSAlPjwvYj4nKTtcbiAgICAgKiBjb21waWxlZCh7ICd2YWx1ZSc6ICc8c2NyaXB0PicgfSk7XG4gICAgICogLy8gPT4gJzxiPiZsdDtzY3JpcHQmZ3Q7PC9iPidcbiAgICAgKlxuICAgICAqIC8vIFVzZSB0aGUgXCJldmFsdWF0ZVwiIGRlbGltaXRlciB0byBleGVjdXRlIEphdmFTY3JpcHQgYW5kIGdlbmVyYXRlIEhUTUwuXG4gICAgICogdmFyIGNvbXBpbGVkID0gXy50ZW1wbGF0ZSgnPCUgXy5mb3JFYWNoKHVzZXJzLCBmdW5jdGlvbih1c2VyKSB7ICU+PGxpPjwlLSB1c2VyICU+PC9saT48JSB9KTsgJT4nKTtcbiAgICAgKiBjb21waWxlZCh7ICd1c2Vycyc6IFsnZnJlZCcsICdiYXJuZXknXSB9KTtcbiAgICAgKiAvLyA9PiAnPGxpPmZyZWQ8L2xpPjxsaT5iYXJuZXk8L2xpPidcbiAgICAgKlxuICAgICAqIC8vIFVzZSB0aGUgaW50ZXJuYWwgYHByaW50YCBmdW5jdGlvbiBpbiBcImV2YWx1YXRlXCIgZGVsaW1pdGVycy5cbiAgICAgKiB2YXIgY29tcGlsZWQgPSBfLnRlbXBsYXRlKCc8JSBwcmludChcImhlbGxvIFwiICsgdXNlcik7ICU+IScpO1xuICAgICAqIGNvbXBpbGVkKHsgJ3VzZXInOiAnYmFybmV5JyB9KTtcbiAgICAgKiAvLyA9PiAnaGVsbG8gYmFybmV5ISdcbiAgICAgKlxuICAgICAqIC8vIFVzZSB0aGUgRVMgdGVtcGxhdGUgbGl0ZXJhbCBkZWxpbWl0ZXIgYXMgYW4gXCJpbnRlcnBvbGF0ZVwiIGRlbGltaXRlci5cbiAgICAgKiAvLyBEaXNhYmxlIHN1cHBvcnQgYnkgcmVwbGFjaW5nIHRoZSBcImludGVycG9sYXRlXCIgZGVsaW1pdGVyLlxuICAgICAqIHZhciBjb21waWxlZCA9IF8udGVtcGxhdGUoJ2hlbGxvICR7IHVzZXIgfSEnKTtcbiAgICAgKiBjb21waWxlZCh7ICd1c2VyJzogJ3BlYmJsZXMnIH0pO1xuICAgICAqIC8vID0+ICdoZWxsbyBwZWJibGVzISdcbiAgICAgKlxuICAgICAqIC8vIFVzZSBiYWNrc2xhc2hlcyB0byB0cmVhdCBkZWxpbWl0ZXJzIGFzIHBsYWluIHRleHQuXG4gICAgICogdmFyIGNvbXBpbGVkID0gXy50ZW1wbGF0ZSgnPCU9IFwiXFxcXDwlLSB2YWx1ZSAlXFxcXD5cIiAlPicpO1xuICAgICAqIGNvbXBpbGVkKHsgJ3ZhbHVlJzogJ2lnbm9yZWQnIH0pO1xuICAgICAqIC8vID0+ICc8JS0gdmFsdWUgJT4nXG4gICAgICpcbiAgICAgKiAvLyBVc2UgdGhlIGBpbXBvcnRzYCBvcHRpb24gdG8gaW1wb3J0IGBqUXVlcnlgIGFzIGBqcWAuXG4gICAgICogdmFyIHRleHQgPSAnPCUganEuZWFjaCh1c2VycywgZnVuY3Rpb24odXNlcikgeyAlPjxsaT48JS0gdXNlciAlPjwvbGk+PCUgfSk7ICU+JztcbiAgICAgKiB2YXIgY29tcGlsZWQgPSBfLnRlbXBsYXRlKHRleHQsIHsgJ2ltcG9ydHMnOiB7ICdqcSc6IGpRdWVyeSB9IH0pO1xuICAgICAqIGNvbXBpbGVkKHsgJ3VzZXJzJzogWydmcmVkJywgJ2Jhcm5leSddIH0pO1xuICAgICAqIC8vID0+ICc8bGk+ZnJlZDwvbGk+PGxpPmJhcm5leTwvbGk+J1xuICAgICAqXG4gICAgICogLy8gVXNlIHRoZSBgc291cmNlVVJMYCBvcHRpb24gdG8gc3BlY2lmeSBhIGN1c3RvbSBzb3VyY2VVUkwgZm9yIHRoZSB0ZW1wbGF0ZS5cbiAgICAgKiB2YXIgY29tcGlsZWQgPSBfLnRlbXBsYXRlKCdoZWxsbyA8JT0gdXNlciAlPiEnLCB7ICdzb3VyY2VVUkwnOiAnL2Jhc2ljL2dyZWV0aW5nLmpzdCcgfSk7XG4gICAgICogY29tcGlsZWQoZGF0YSk7XG4gICAgICogLy8gPT4gRmluZCB0aGUgc291cmNlIG9mIFwiZ3JlZXRpbmcuanN0XCIgdW5kZXIgdGhlIFNvdXJjZXMgdGFiIG9yIFJlc291cmNlcyBwYW5lbCBvZiB0aGUgd2ViIGluc3BlY3Rvci5cbiAgICAgKlxuICAgICAqIC8vIFVzZSB0aGUgYHZhcmlhYmxlYCBvcHRpb24gdG8gZW5zdXJlIGEgd2l0aC1zdGF0ZW1lbnQgaXNuJ3QgdXNlZCBpbiB0aGUgY29tcGlsZWQgdGVtcGxhdGUuXG4gICAgICogdmFyIGNvbXBpbGVkID0gXy50ZW1wbGF0ZSgnaGkgPCU9IGRhdGEudXNlciAlPiEnLCB7ICd2YXJpYWJsZSc6ICdkYXRhJyB9KTtcbiAgICAgKiBjb21waWxlZC5zb3VyY2U7XG4gICAgICogLy8gPT4gZnVuY3Rpb24oZGF0YSkge1xuICAgICAqIC8vICAgdmFyIF9fdCwgX19wID0gJyc7XG4gICAgICogLy8gICBfX3AgKz0gJ2hpICcgKyAoKF9fdCA9ICggZGF0YS51c2VyICkpID09IG51bGwgPyAnJyA6IF9fdCkgKyAnISc7XG4gICAgICogLy8gICByZXR1cm4gX19wO1xuICAgICAqIC8vIH1cbiAgICAgKlxuICAgICAqIC8vIFVzZSBjdXN0b20gdGVtcGxhdGUgZGVsaW1pdGVycy5cbiAgICAgKiBfLnRlbXBsYXRlU2V0dGluZ3MuaW50ZXJwb2xhdGUgPSAve3soW1xcc1xcU10rPyl9fS9nO1xuICAgICAqIHZhciBjb21waWxlZCA9IF8udGVtcGxhdGUoJ2hlbGxvIHt7IHVzZXIgfX0hJyk7XG4gICAgICogY29tcGlsZWQoeyAndXNlcic6ICdtdXN0YWNoZScgfSk7XG4gICAgICogLy8gPT4gJ2hlbGxvIG11c3RhY2hlISdcbiAgICAgKlxuICAgICAqIC8vIFVzZSB0aGUgYHNvdXJjZWAgcHJvcGVydHkgdG8gaW5saW5lIGNvbXBpbGVkIHRlbXBsYXRlcyBmb3IgbWVhbmluZ2Z1bFxuICAgICAqIC8vIGxpbmUgbnVtYmVycyBpbiBlcnJvciBtZXNzYWdlcyBhbmQgc3RhY2sgdHJhY2VzLlxuICAgICAqIGZzLndyaXRlRmlsZVN5bmMocGF0aC5qb2luKHByb2Nlc3MuY3dkKCksICdqc3QuanMnKSwgJ1xcXG4gICAgICogICB2YXIgSlNUID0ge1xcXG4gICAgICogICAgIFwibWFpblwiOiAnICsgXy50ZW1wbGF0ZShtYWluVGV4dCkuc291cmNlICsgJ1xcXG4gICAgICogICB9O1xcXG4gICAgICogJyk7XG4gICAgICovXG4gICAgZnVuY3Rpb24gdGVtcGxhdGUoc3RyaW5nLCBvcHRpb25zLCBndWFyZCkge1xuICAgICAgLy8gQmFzZWQgb24gSm9obiBSZXNpZydzIGB0bXBsYCBpbXBsZW1lbnRhdGlvblxuICAgICAgLy8gKGh0dHA6Ly9lam9obi5vcmcvYmxvZy9qYXZhc2NyaXB0LW1pY3JvLXRlbXBsYXRpbmcvKVxuICAgICAgLy8gYW5kIExhdXJhIERva3Rvcm92YSdzIGRvVC5qcyAoaHR0cHM6Ly9naXRodWIuY29tL29sYWRvL2RvVCkuXG4gICAgICB2YXIgc2V0dGluZ3MgPSBsb2Rhc2gudGVtcGxhdGVTZXR0aW5ncztcblxuICAgICAgaWYgKGd1YXJkICYmIGlzSXRlcmF0ZWVDYWxsKHN0cmluZywgb3B0aW9ucywgZ3VhcmQpKSB7XG4gICAgICAgIG9wdGlvbnMgPSB1bmRlZmluZWQ7XG4gICAgICB9XG4gICAgICBzdHJpbmcgPSB0b1N0cmluZyhzdHJpbmcpO1xuICAgICAgb3B0aW9ucyA9IGFzc2lnbkluV2l0aCh7fSwgb3B0aW9ucywgc2V0dGluZ3MsIGN1c3RvbURlZmF1bHRzQXNzaWduSW4pO1xuXG4gICAgICB2YXIgaW1wb3J0cyA9IGFzc2lnbkluV2l0aCh7fSwgb3B0aW9ucy5pbXBvcnRzLCBzZXR0aW5ncy5pbXBvcnRzLCBjdXN0b21EZWZhdWx0c0Fzc2lnbkluKSxcbiAgICAgICAgICBpbXBvcnRzS2V5cyA9IGtleXMoaW1wb3J0cyksXG4gICAgICAgICAgaW1wb3J0c1ZhbHVlcyA9IGJhc2VWYWx1ZXMoaW1wb3J0cywgaW1wb3J0c0tleXMpO1xuXG4gICAgICB2YXIgaXNFc2NhcGluZyxcbiAgICAgICAgICBpc0V2YWx1YXRpbmcsXG4gICAgICAgICAgaW5kZXggPSAwLFxuICAgICAgICAgIGludGVycG9sYXRlID0gb3B0aW9ucy5pbnRlcnBvbGF0ZSB8fCByZU5vTWF0Y2gsXG4gICAgICAgICAgc291cmNlID0gXCJfX3AgKz0gJ1wiO1xuXG4gICAgICAvLyBDb21waWxlIHRoZSByZWdleHAgdG8gbWF0Y2ggZWFjaCBkZWxpbWl0ZXIuXG4gICAgICB2YXIgcmVEZWxpbWl0ZXJzID0gUmVnRXhwKFxuICAgICAgICAob3B0aW9ucy5lc2NhcGUgfHwgcmVOb01hdGNoKS5zb3VyY2UgKyAnfCcgK1xuICAgICAgICBpbnRlcnBvbGF0ZS5zb3VyY2UgKyAnfCcgK1xuICAgICAgICAoaW50ZXJwb2xhdGUgPT09IHJlSW50ZXJwb2xhdGUgPyByZUVzVGVtcGxhdGUgOiByZU5vTWF0Y2gpLnNvdXJjZSArICd8JyArXG4gICAgICAgIChvcHRpb25zLmV2YWx1YXRlIHx8IHJlTm9NYXRjaCkuc291cmNlICsgJ3wkJ1xuICAgICAgLCAnZycpO1xuXG4gICAgICAvLyBVc2UgYSBzb3VyY2VVUkwgZm9yIGVhc2llciBkZWJ1Z2dpbmcuXG4gICAgICAvLyBUaGUgc291cmNlVVJMIGdldHMgaW5qZWN0ZWQgaW50byB0aGUgc291cmNlIHRoYXQncyBldmFsLWVkLCBzbyBiZSBjYXJlZnVsXG4gICAgICAvLyB0byBub3JtYWxpemUgYWxsIGtpbmRzIG9mIHdoaXRlc3BhY2UsIHNvIGUuZy4gbmV3bGluZXMgKGFuZCB1bmljb2RlIHZlcnNpb25zIG9mIGl0KSBjYW4ndCBzbmVhayBpblxuICAgICAgLy8gYW5kIGVzY2FwZSB0aGUgY29tbWVudCwgdGh1cyBpbmplY3RpbmcgY29kZSB0aGF0IGdldHMgZXZhbGVkLlxuICAgICAgdmFyIHNvdXJjZVVSTCA9ICcvLyMgc291cmNlVVJMPScgK1xuICAgICAgICAoaGFzT3duUHJvcGVydHkuY2FsbChvcHRpb25zLCAnc291cmNlVVJMJylcbiAgICAgICAgICA/IChvcHRpb25zLnNvdXJjZVVSTCArICcnKS5yZXBsYWNlKC9cXHMvZywgJyAnKVxuICAgICAgICAgIDogKCdsb2Rhc2gudGVtcGxhdGVTb3VyY2VzWycgKyAoKyt0ZW1wbGF0ZUNvdW50ZXIpICsgJ10nKVxuICAgICAgICApICsgJ1xcbic7XG5cbiAgICAgIHN0cmluZy5yZXBsYWNlKHJlRGVsaW1pdGVycywgZnVuY3Rpb24obWF0Y2gsIGVzY2FwZVZhbHVlLCBpbnRlcnBvbGF0ZVZhbHVlLCBlc1RlbXBsYXRlVmFsdWUsIGV2YWx1YXRlVmFsdWUsIG9mZnNldCkge1xuICAgICAgICBpbnRlcnBvbGF0ZVZhbHVlIHx8IChpbnRlcnBvbGF0ZVZhbHVlID0gZXNUZW1wbGF0ZVZhbHVlKTtcblxuICAgICAgICAvLyBFc2NhcGUgY2hhcmFjdGVycyB0aGF0IGNhbid0IGJlIGluY2x1ZGVkIGluIHN0cmluZyBsaXRlcmFscy5cbiAgICAgICAgc291cmNlICs9IHN0cmluZy5zbGljZShpbmRleCwgb2Zmc2V0KS5yZXBsYWNlKHJlVW5lc2NhcGVkU3RyaW5nLCBlc2NhcGVTdHJpbmdDaGFyKTtcblxuICAgICAgICAvLyBSZXBsYWNlIGRlbGltaXRlcnMgd2l0aCBzbmlwcGV0cy5cbiAgICAgICAgaWYgKGVzY2FwZVZhbHVlKSB7XG4gICAgICAgICAgaXNFc2NhcGluZyA9IHRydWU7XG4gICAgICAgICAgc291cmNlICs9IFwiJyArXFxuX19lKFwiICsgZXNjYXBlVmFsdWUgKyBcIikgK1xcbidcIjtcbiAgICAgICAgfVxuICAgICAgICBpZiAoZXZhbHVhdGVWYWx1ZSkge1xuICAgICAgICAgIGlzRXZhbHVhdGluZyA9IHRydWU7XG4gICAgICAgICAgc291cmNlICs9IFwiJztcXG5cIiArIGV2YWx1YXRlVmFsdWUgKyBcIjtcXG5fX3AgKz0gJ1wiO1xuICAgICAgICB9XG4gICAgICAgIGlmIChpbnRlcnBvbGF0ZVZhbHVlKSB7XG4gICAgICAgICAgc291cmNlICs9IFwiJyArXFxuKChfX3QgPSAoXCIgKyBpbnRlcnBvbGF0ZVZhbHVlICsgXCIpKSA9PSBudWxsID8gJycgOiBfX3QpICtcXG4nXCI7XG4gICAgICAgIH1cbiAgICAgICAgaW5kZXggPSBvZmZzZXQgKyBtYXRjaC5sZW5ndGg7XG5cbiAgICAgICAgLy8gVGhlIEpTIGVuZ2luZSBlbWJlZGRlZCBpbiBBZG9iZSBwcm9kdWN0cyBuZWVkcyBgbWF0Y2hgIHJldHVybmVkIGluXG4gICAgICAgIC8vIG9yZGVyIHRvIHByb2R1Y2UgdGhlIGNvcnJlY3QgYG9mZnNldGAgdmFsdWUuXG4gICAgICAgIHJldHVybiBtYXRjaDtcbiAgICAgIH0pO1xuXG4gICAgICBzb3VyY2UgKz0gXCInO1xcblwiO1xuXG4gICAgICAvLyBJZiBgdmFyaWFibGVgIGlzIG5vdCBzcGVjaWZpZWQgd3JhcCBhIHdpdGgtc3RhdGVtZW50IGFyb3VuZCB0aGUgZ2VuZXJhdGVkXG4gICAgICAvLyBjb2RlIHRvIGFkZCB0aGUgZGF0YSBvYmplY3QgdG8gdGhlIHRvcCBvZiB0aGUgc2NvcGUgY2hhaW4uXG4gICAgICB2YXIgdmFyaWFibGUgPSBoYXNPd25Qcm9wZXJ0eS5jYWxsKG9wdGlvbnMsICd2YXJpYWJsZScpICYmIG9wdGlvbnMudmFyaWFibGU7XG4gICAgICBpZiAoIXZhcmlhYmxlKSB7XG4gICAgICAgIHNvdXJjZSA9ICd3aXRoIChvYmopIHtcXG4nICsgc291cmNlICsgJ1xcbn1cXG4nO1xuICAgICAgfVxuICAgICAgLy8gVGhyb3cgYW4gZXJyb3IgaWYgYSBmb3JiaWRkZW4gY2hhcmFjdGVyIHdhcyBmb3VuZCBpbiBgdmFyaWFibGVgLCB0byBwcmV2ZW50XG4gICAgICAvLyBwb3RlbnRpYWwgY29tbWFuZCBpbmplY3Rpb24gYXR0YWNrcy5cbiAgICAgIGVsc2UgaWYgKHJlRm9yYmlkZGVuSWRlbnRpZmllckNoYXJzLnRlc3QodmFyaWFibGUpKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihJTlZBTElEX1RFTVBMX1ZBUl9FUlJPUl9URVhUKTtcbiAgICAgIH1cblxuICAgICAgLy8gQ2xlYW51cCBjb2RlIGJ5IHN0cmlwcGluZyBlbXB0eSBzdHJpbmdzLlxuICAgICAgc291cmNlID0gKGlzRXZhbHVhdGluZyA/IHNvdXJjZS5yZXBsYWNlKHJlRW1wdHlTdHJpbmdMZWFkaW5nLCAnJykgOiBzb3VyY2UpXG4gICAgICAgIC5yZXBsYWNlKHJlRW1wdHlTdHJpbmdNaWRkbGUsICckMScpXG4gICAgICAgIC5yZXBsYWNlKHJlRW1wdHlTdHJpbmdUcmFpbGluZywgJyQxOycpO1xuXG4gICAgICAvLyBGcmFtZSBjb2RlIGFzIHRoZSBmdW5jdGlvbiBib2R5LlxuICAgICAgc291cmNlID0gJ2Z1bmN0aW9uKCcgKyAodmFyaWFibGUgfHwgJ29iaicpICsgJykge1xcbicgK1xuICAgICAgICAodmFyaWFibGVcbiAgICAgICAgICA/ICcnXG4gICAgICAgICAgOiAnb2JqIHx8IChvYmogPSB7fSk7XFxuJ1xuICAgICAgICApICtcbiAgICAgICAgXCJ2YXIgX190LCBfX3AgPSAnJ1wiICtcbiAgICAgICAgKGlzRXNjYXBpbmdcbiAgICAgICAgICAgPyAnLCBfX2UgPSBfLmVzY2FwZSdcbiAgICAgICAgICAgOiAnJ1xuICAgICAgICApICtcbiAgICAgICAgKGlzRXZhbHVhdGluZ1xuICAgICAgICAgID8gJywgX19qID0gQXJyYXkucHJvdG90eXBlLmpvaW47XFxuJyArXG4gICAgICAgICAgICBcImZ1bmN0aW9uIHByaW50KCkgeyBfX3AgKz0gX19qLmNhbGwoYXJndW1lbnRzLCAnJykgfVxcblwiXG4gICAgICAgICAgOiAnO1xcbidcbiAgICAgICAgKSArXG4gICAgICAgIHNvdXJjZSArXG4gICAgICAgICdyZXR1cm4gX19wXFxufSc7XG5cbiAgICAgIHZhciByZXN1bHQgPSBhdHRlbXB0KGZ1bmN0aW9uKCkge1xuICAgICAgICByZXR1cm4gRnVuY3Rpb24oaW1wb3J0c0tleXMsIHNvdXJjZVVSTCArICdyZXR1cm4gJyArIHNvdXJjZSlcbiAgICAgICAgICAuYXBwbHkodW5kZWZpbmVkLCBpbXBvcnRzVmFsdWVzKTtcbiAgICAgIH0pO1xuXG4gICAgICAvLyBQcm92aWRlIHRoZSBjb21waWxlZCBmdW5jdGlvbidzIHNvdXJjZSBieSBpdHMgYHRvU3RyaW5nYCBtZXRob2Qgb3JcbiAgICAgIC8vIHRoZSBgc291cmNlYCBwcm9wZXJ0eSBhcyBhIGNvbnZlbmllbmNlIGZvciBpbmxpbmluZyBjb21waWxlZCB0ZW1wbGF0ZXMuXG4gICAgICByZXN1bHQuc291cmNlID0gc291cmNlO1xuICAgICAgaWYgKGlzRXJyb3IocmVzdWx0KSkge1xuICAgICAgICB0aHJvdyByZXN1bHQ7XG4gICAgICB9XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENvbnZlcnRzIGBzdHJpbmdgLCBhcyBhIHdob2xlLCB0byBsb3dlciBjYXNlIGp1c3QgbGlrZVxuICAgICAqIFtTdHJpbmcjdG9Mb3dlckNhc2VdKGh0dHBzOi8vbWRuLmlvL3RvTG93ZXJDYXNlKS5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjAuMFxuICAgICAqIEBjYXRlZ29yeSBTdHJpbmdcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gW3N0cmluZz0nJ10gVGhlIHN0cmluZyB0byBjb252ZXJ0LlxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IFJldHVybnMgdGhlIGxvd2VyIGNhc2VkIHN0cmluZy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy50b0xvd2VyKCctLUZvby1CYXItLScpO1xuICAgICAqIC8vID0+ICctLWZvby1iYXItLSdcbiAgICAgKlxuICAgICAqIF8udG9Mb3dlcignZm9vQmFyJyk7XG4gICAgICogLy8gPT4gJ2Zvb2JhcidcbiAgICAgKlxuICAgICAqIF8udG9Mb3dlcignX19GT09fQkFSX18nKTtcbiAgICAgKiAvLyA9PiAnX19mb29fYmFyX18nXG4gICAgICovXG4gICAgZnVuY3Rpb24gdG9Mb3dlcih2YWx1ZSkge1xuICAgICAgcmV0dXJuIHRvU3RyaW5nKHZhbHVlKS50b0xvd2VyQ2FzZSgpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENvbnZlcnRzIGBzdHJpbmdgLCBhcyBhIHdob2xlLCB0byB1cHBlciBjYXNlIGp1c3QgbGlrZVxuICAgICAqIFtTdHJpbmcjdG9VcHBlckNhc2VdKGh0dHBzOi8vbWRuLmlvL3RvVXBwZXJDYXNlKS5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjAuMFxuICAgICAqIEBjYXRlZ29yeSBTdHJpbmdcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gW3N0cmluZz0nJ10gVGhlIHN0cmluZyB0byBjb252ZXJ0LlxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IFJldHVybnMgdGhlIHVwcGVyIGNhc2VkIHN0cmluZy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy50b1VwcGVyKCctLWZvby1iYXItLScpO1xuICAgICAqIC8vID0+ICctLUZPTy1CQVItLSdcbiAgICAgKlxuICAgICAqIF8udG9VcHBlcignZm9vQmFyJyk7XG4gICAgICogLy8gPT4gJ0ZPT0JBUidcbiAgICAgKlxuICAgICAqIF8udG9VcHBlcignX19mb29fYmFyX18nKTtcbiAgICAgKiAvLyA9PiAnX19GT09fQkFSX18nXG4gICAgICovXG4gICAgZnVuY3Rpb24gdG9VcHBlcih2YWx1ZSkge1xuICAgICAgcmV0dXJuIHRvU3RyaW5nKHZhbHVlKS50b1VwcGVyQ2FzZSgpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJlbW92ZXMgbGVhZGluZyBhbmQgdHJhaWxpbmcgd2hpdGVzcGFjZSBvciBzcGVjaWZpZWQgY2hhcmFjdGVycyBmcm9tIGBzdHJpbmdgLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDMuMC4wXG4gICAgICogQGNhdGVnb3J5IFN0cmluZ1xuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBbc3RyaW5nPScnXSBUaGUgc3RyaW5nIHRvIHRyaW0uXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IFtjaGFycz13aGl0ZXNwYWNlXSBUaGUgY2hhcmFjdGVycyB0byB0cmltLlxuICAgICAqIEBwYXJhbS0ge09iamVjdH0gW2d1YXJkXSBFbmFibGVzIHVzZSBhcyBhbiBpdGVyYXRlZSBmb3IgbWV0aG9kcyBsaWtlIGBfLm1hcGAuXG4gICAgICogQHJldHVybnMge3N0cmluZ30gUmV0dXJucyB0aGUgdHJpbW1lZCBzdHJpbmcuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8udHJpbSgnICBhYmMgICcpO1xuICAgICAqIC8vID0+ICdhYmMnXG4gICAgICpcbiAgICAgKiBfLnRyaW0oJy1fLWFiYy1fLScsICdfLScpO1xuICAgICAqIC8vID0+ICdhYmMnXG4gICAgICpcbiAgICAgKiBfLm1hcChbJyAgZm9vICAnLCAnICBiYXIgICddLCBfLnRyaW0pO1xuICAgICAqIC8vID0+IFsnZm9vJywgJ2JhciddXG4gICAgICovXG4gICAgZnVuY3Rpb24gdHJpbShzdHJpbmcsIGNoYXJzLCBndWFyZCkge1xuICAgICAgc3RyaW5nID0gdG9TdHJpbmcoc3RyaW5nKTtcbiAgICAgIGlmIChzdHJpbmcgJiYgKGd1YXJkIHx8IGNoYXJzID09PSB1bmRlZmluZWQpKSB7XG4gICAgICAgIHJldHVybiBiYXNlVHJpbShzdHJpbmcpO1xuICAgICAgfVxuICAgICAgaWYgKCFzdHJpbmcgfHwgIShjaGFycyA9IGJhc2VUb1N0cmluZyhjaGFycykpKSB7XG4gICAgICAgIHJldHVybiBzdHJpbmc7XG4gICAgICB9XG4gICAgICB2YXIgc3RyU3ltYm9scyA9IHN0cmluZ1RvQXJyYXkoc3RyaW5nKSxcbiAgICAgICAgICBjaHJTeW1ib2xzID0gc3RyaW5nVG9BcnJheShjaGFycyksXG4gICAgICAgICAgc3RhcnQgPSBjaGFyc1N0YXJ0SW5kZXgoc3RyU3ltYm9scywgY2hyU3ltYm9scyksXG4gICAgICAgICAgZW5kID0gY2hhcnNFbmRJbmRleChzdHJTeW1ib2xzLCBjaHJTeW1ib2xzKSArIDE7XG5cbiAgICAgIHJldHVybiBjYXN0U2xpY2Uoc3RyU3ltYm9scywgc3RhcnQsIGVuZCkuam9pbignJyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmVtb3ZlcyB0cmFpbGluZyB3aGl0ZXNwYWNlIG9yIHNwZWNpZmllZCBjaGFyYWN0ZXJzIGZyb20gYHN0cmluZ2AuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgU3RyaW5nXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IFtzdHJpbmc9JyddIFRoZSBzdHJpbmcgdG8gdHJpbS5cbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gW2NoYXJzPXdoaXRlc3BhY2VdIFRoZSBjaGFyYWN0ZXJzIHRvIHRyaW0uXG4gICAgICogQHBhcmFtLSB7T2JqZWN0fSBbZ3VhcmRdIEVuYWJsZXMgdXNlIGFzIGFuIGl0ZXJhdGVlIGZvciBtZXRob2RzIGxpa2UgYF8ubWFwYC5cbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfSBSZXR1cm5zIHRoZSB0cmltbWVkIHN0cmluZy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy50cmltRW5kKCcgIGFiYyAgJyk7XG4gICAgICogLy8gPT4gJyAgYWJjJ1xuICAgICAqXG4gICAgICogXy50cmltRW5kKCctXy1hYmMtXy0nLCAnXy0nKTtcbiAgICAgKiAvLyA9PiAnLV8tYWJjJ1xuICAgICAqL1xuICAgIGZ1bmN0aW9uIHRyaW1FbmQoc3RyaW5nLCBjaGFycywgZ3VhcmQpIHtcbiAgICAgIHN0cmluZyA9IHRvU3RyaW5nKHN0cmluZyk7XG4gICAgICBpZiAoc3RyaW5nICYmIChndWFyZCB8fCBjaGFycyA9PT0gdW5kZWZpbmVkKSkge1xuICAgICAgICByZXR1cm4gc3RyaW5nLnNsaWNlKDAsIHRyaW1tZWRFbmRJbmRleChzdHJpbmcpICsgMSk7XG4gICAgICB9XG4gICAgICBpZiAoIXN0cmluZyB8fCAhKGNoYXJzID0gYmFzZVRvU3RyaW5nKGNoYXJzKSkpIHtcbiAgICAgICAgcmV0dXJuIHN0cmluZztcbiAgICAgIH1cbiAgICAgIHZhciBzdHJTeW1ib2xzID0gc3RyaW5nVG9BcnJheShzdHJpbmcpLFxuICAgICAgICAgIGVuZCA9IGNoYXJzRW5kSW5kZXgoc3RyU3ltYm9scywgc3RyaW5nVG9BcnJheShjaGFycykpICsgMTtcblxuICAgICAgcmV0dXJuIGNhc3RTbGljZShzdHJTeW1ib2xzLCAwLCBlbmQpLmpvaW4oJycpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJlbW92ZXMgbGVhZGluZyB3aGl0ZXNwYWNlIG9yIHNwZWNpZmllZCBjaGFyYWN0ZXJzIGZyb20gYHN0cmluZ2AuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgU3RyaW5nXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IFtzdHJpbmc9JyddIFRoZSBzdHJpbmcgdG8gdHJpbS5cbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gW2NoYXJzPXdoaXRlc3BhY2VdIFRoZSBjaGFyYWN0ZXJzIHRvIHRyaW0uXG4gICAgICogQHBhcmFtLSB7T2JqZWN0fSBbZ3VhcmRdIEVuYWJsZXMgdXNlIGFzIGFuIGl0ZXJhdGVlIGZvciBtZXRob2RzIGxpa2UgYF8ubWFwYC5cbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfSBSZXR1cm5zIHRoZSB0cmltbWVkIHN0cmluZy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy50cmltU3RhcnQoJyAgYWJjICAnKTtcbiAgICAgKiAvLyA9PiAnYWJjICAnXG4gICAgICpcbiAgICAgKiBfLnRyaW1TdGFydCgnLV8tYWJjLV8tJywgJ18tJyk7XG4gICAgICogLy8gPT4gJ2FiYy1fLSdcbiAgICAgKi9cbiAgICBmdW5jdGlvbiB0cmltU3RhcnQoc3RyaW5nLCBjaGFycywgZ3VhcmQpIHtcbiAgICAgIHN0cmluZyA9IHRvU3RyaW5nKHN0cmluZyk7XG4gICAgICBpZiAoc3RyaW5nICYmIChndWFyZCB8fCBjaGFycyA9PT0gdW5kZWZpbmVkKSkge1xuICAgICAgICByZXR1cm4gc3RyaW5nLnJlcGxhY2UocmVUcmltU3RhcnQsICcnKTtcbiAgICAgIH1cbiAgICAgIGlmICghc3RyaW5nIHx8ICEoY2hhcnMgPSBiYXNlVG9TdHJpbmcoY2hhcnMpKSkge1xuICAgICAgICByZXR1cm4gc3RyaW5nO1xuICAgICAgfVxuICAgICAgdmFyIHN0clN5bWJvbHMgPSBzdHJpbmdUb0FycmF5KHN0cmluZyksXG4gICAgICAgICAgc3RhcnQgPSBjaGFyc1N0YXJ0SW5kZXgoc3RyU3ltYm9scywgc3RyaW5nVG9BcnJheShjaGFycykpO1xuXG4gICAgICByZXR1cm4gY2FzdFNsaWNlKHN0clN5bWJvbHMsIHN0YXJ0KS5qb2luKCcnKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUcnVuY2F0ZXMgYHN0cmluZ2AgaWYgaXQncyBsb25nZXIgdGhhbiB0aGUgZ2l2ZW4gbWF4aW11bSBzdHJpbmcgbGVuZ3RoLlxuICAgICAqIFRoZSBsYXN0IGNoYXJhY3RlcnMgb2YgdGhlIHRydW5jYXRlZCBzdHJpbmcgYXJlIHJlcGxhY2VkIHdpdGggdGhlIG9taXNzaW9uXG4gICAgICogc3RyaW5nIHdoaWNoIGRlZmF1bHRzIHRvIFwiLi4uXCIuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgU3RyaW5nXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IFtzdHJpbmc9JyddIFRoZSBzdHJpbmcgdG8gdHJ1bmNhdGUuXG4gICAgICogQHBhcmFtIHtPYmplY3R9IFtvcHRpb25zPXt9XSBUaGUgb3B0aW9ucyBvYmplY3QuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtvcHRpb25zLmxlbmd0aD0zMF0gVGhlIG1heGltdW0gc3RyaW5nIGxlbmd0aC5cbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gW29wdGlvbnMub21pc3Npb249Jy4uLiddIFRoZSBzdHJpbmcgdG8gaW5kaWNhdGUgdGV4dCBpcyBvbWl0dGVkLlxuICAgICAqIEBwYXJhbSB7UmVnRXhwfHN0cmluZ30gW29wdGlvbnMuc2VwYXJhdG9yXSBUaGUgc2VwYXJhdG9yIHBhdHRlcm4gdG8gdHJ1bmNhdGUgdG8uXG4gICAgICogQHJldHVybnMge3N0cmluZ30gUmV0dXJucyB0aGUgdHJ1bmNhdGVkIHN0cmluZy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy50cnVuY2F0ZSgnaGktZGlkZGx5LWhvIHRoZXJlLCBuZWlnaGJvcmlubycpO1xuICAgICAqIC8vID0+ICdoaS1kaWRkbHktaG8gdGhlcmUsIG5laWdoYm8uLi4nXG4gICAgICpcbiAgICAgKiBfLnRydW5jYXRlKCdoaS1kaWRkbHktaG8gdGhlcmUsIG5laWdoYm9yaW5vJywge1xuICAgICAqICAgJ2xlbmd0aCc6IDI0LFxuICAgICAqICAgJ3NlcGFyYXRvcic6ICcgJ1xuICAgICAqIH0pO1xuICAgICAqIC8vID0+ICdoaS1kaWRkbHktaG8gdGhlcmUsLi4uJ1xuICAgICAqXG4gICAgICogXy50cnVuY2F0ZSgnaGktZGlkZGx5LWhvIHRoZXJlLCBuZWlnaGJvcmlubycsIHtcbiAgICAgKiAgICdsZW5ndGgnOiAyNCxcbiAgICAgKiAgICdzZXBhcmF0b3InOiAvLD8gKy9cbiAgICAgKiB9KTtcbiAgICAgKiAvLyA9PiAnaGktZGlkZGx5LWhvIHRoZXJlLi4uJ1xuICAgICAqXG4gICAgICogXy50cnVuY2F0ZSgnaGktZGlkZGx5LWhvIHRoZXJlLCBuZWlnaGJvcmlubycsIHtcbiAgICAgKiAgICdvbWlzc2lvbic6ICcgWy4uLl0nXG4gICAgICogfSk7XG4gICAgICogLy8gPT4gJ2hpLWRpZGRseS1obyB0aGVyZSwgbmVpZyBbLi4uXSdcbiAgICAgKi9cbiAgICBmdW5jdGlvbiB0cnVuY2F0ZShzdHJpbmcsIG9wdGlvbnMpIHtcbiAgICAgIHZhciBsZW5ndGggPSBERUZBVUxUX1RSVU5DX0xFTkdUSCxcbiAgICAgICAgICBvbWlzc2lvbiA9IERFRkFVTFRfVFJVTkNfT01JU1NJT047XG5cbiAgICAgIGlmIChpc09iamVjdChvcHRpb25zKSkge1xuICAgICAgICB2YXIgc2VwYXJhdG9yID0gJ3NlcGFyYXRvcicgaW4gb3B0aW9ucyA/IG9wdGlvbnMuc2VwYXJhdG9yIDogc2VwYXJhdG9yO1xuICAgICAgICBsZW5ndGggPSAnbGVuZ3RoJyBpbiBvcHRpb25zID8gdG9JbnRlZ2VyKG9wdGlvbnMubGVuZ3RoKSA6IGxlbmd0aDtcbiAgICAgICAgb21pc3Npb24gPSAnb21pc3Npb24nIGluIG9wdGlvbnMgPyBiYXNlVG9TdHJpbmcob3B0aW9ucy5vbWlzc2lvbikgOiBvbWlzc2lvbjtcbiAgICAgIH1cbiAgICAgIHN0cmluZyA9IHRvU3RyaW5nKHN0cmluZyk7XG5cbiAgICAgIHZhciBzdHJMZW5ndGggPSBzdHJpbmcubGVuZ3RoO1xuICAgICAgaWYgKGhhc1VuaWNvZGUoc3RyaW5nKSkge1xuICAgICAgICB2YXIgc3RyU3ltYm9scyA9IHN0cmluZ1RvQXJyYXkoc3RyaW5nKTtcbiAgICAgICAgc3RyTGVuZ3RoID0gc3RyU3ltYm9scy5sZW5ndGg7XG4gICAgICB9XG4gICAgICBpZiAobGVuZ3RoID49IHN0ckxlbmd0aCkge1xuICAgICAgICByZXR1cm4gc3RyaW5nO1xuICAgICAgfVxuICAgICAgdmFyIGVuZCA9IGxlbmd0aCAtIHN0cmluZ1NpemUob21pc3Npb24pO1xuICAgICAgaWYgKGVuZCA8IDEpIHtcbiAgICAgICAgcmV0dXJuIG9taXNzaW9uO1xuICAgICAgfVxuICAgICAgdmFyIHJlc3VsdCA9IHN0clN5bWJvbHNcbiAgICAgICAgPyBjYXN0U2xpY2Uoc3RyU3ltYm9scywgMCwgZW5kKS5qb2luKCcnKVxuICAgICAgICA6IHN0cmluZy5zbGljZSgwLCBlbmQpO1xuXG4gICAgICBpZiAoc2VwYXJhdG9yID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgcmV0dXJuIHJlc3VsdCArIG9taXNzaW9uO1xuICAgICAgfVxuICAgICAgaWYgKHN0clN5bWJvbHMpIHtcbiAgICAgICAgZW5kICs9IChyZXN1bHQubGVuZ3RoIC0gZW5kKTtcbiAgICAgIH1cbiAgICAgIGlmIChpc1JlZ0V4cChzZXBhcmF0b3IpKSB7XG4gICAgICAgIGlmIChzdHJpbmcuc2xpY2UoZW5kKS5zZWFyY2goc2VwYXJhdG9yKSkge1xuICAgICAgICAgIHZhciBtYXRjaCxcbiAgICAgICAgICAgICAgc3Vic3RyaW5nID0gcmVzdWx0O1xuXG4gICAgICAgICAgaWYgKCFzZXBhcmF0b3IuZ2xvYmFsKSB7XG4gICAgICAgICAgICBzZXBhcmF0b3IgPSBSZWdFeHAoc2VwYXJhdG9yLnNvdXJjZSwgdG9TdHJpbmcocmVGbGFncy5leGVjKHNlcGFyYXRvcikpICsgJ2cnKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgc2VwYXJhdG9yLmxhc3RJbmRleCA9IDA7XG4gICAgICAgICAgd2hpbGUgKChtYXRjaCA9IHNlcGFyYXRvci5leGVjKHN1YnN0cmluZykpKSB7XG4gICAgICAgICAgICB2YXIgbmV3RW5kID0gbWF0Y2guaW5kZXg7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJlc3VsdCA9IHJlc3VsdC5zbGljZSgwLCBuZXdFbmQgPT09IHVuZGVmaW5lZCA/IGVuZCA6IG5ld0VuZCk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSBpZiAoc3RyaW5nLmluZGV4T2YoYmFzZVRvU3RyaW5nKHNlcGFyYXRvciksIGVuZCkgIT0gZW5kKSB7XG4gICAgICAgIHZhciBpbmRleCA9IHJlc3VsdC5sYXN0SW5kZXhPZihzZXBhcmF0b3IpO1xuICAgICAgICBpZiAoaW5kZXggPiAtMSkge1xuICAgICAgICAgIHJlc3VsdCA9IHJlc3VsdC5zbGljZSgwLCBpbmRleCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiByZXN1bHQgKyBvbWlzc2lvbjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgaW52ZXJzZSBvZiBgXy5lc2NhcGVgOyB0aGlzIG1ldGhvZCBjb252ZXJ0cyB0aGUgSFRNTCBlbnRpdGllc1xuICAgICAqIGAmYW1wO2AsIGAmbHQ7YCwgYCZndDtgLCBgJnF1b3Q7YCwgYW5kIGAmIzM5O2AgaW4gYHN0cmluZ2AgdG9cbiAgICAgKiB0aGVpciBjb3JyZXNwb25kaW5nIGNoYXJhY3RlcnMuXG4gICAgICpcbiAgICAgKiAqKk5vdGU6KiogTm8gb3RoZXIgSFRNTCBlbnRpdGllcyBhcmUgdW5lc2NhcGVkLiBUbyB1bmVzY2FwZSBhZGRpdGlvbmFsXG4gICAgICogSFRNTCBlbnRpdGllcyB1c2UgYSB0aGlyZC1wYXJ0eSBsaWJyYXJ5IGxpa2UgW19oZV9dKGh0dHBzOi8vbXRocy5iZS9oZSkuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMC42LjBcbiAgICAgKiBAY2F0ZWdvcnkgU3RyaW5nXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IFtzdHJpbmc9JyddIFRoZSBzdHJpbmcgdG8gdW5lc2NhcGUuXG4gICAgICogQHJldHVybnMge3N0cmluZ30gUmV0dXJucyB0aGUgdW5lc2NhcGVkIHN0cmluZy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy51bmVzY2FwZSgnZnJlZCwgYmFybmV5LCAmYW1wOyBwZWJibGVzJyk7XG4gICAgICogLy8gPT4gJ2ZyZWQsIGJhcm5leSwgJiBwZWJibGVzJ1xuICAgICAqL1xuICAgIGZ1bmN0aW9uIHVuZXNjYXBlKHN0cmluZykge1xuICAgICAgc3RyaW5nID0gdG9TdHJpbmcoc3RyaW5nKTtcbiAgICAgIHJldHVybiAoc3RyaW5nICYmIHJlSGFzRXNjYXBlZEh0bWwudGVzdChzdHJpbmcpKVxuICAgICAgICA/IHN0cmluZy5yZXBsYWNlKHJlRXNjYXBlZEh0bWwsIHVuZXNjYXBlSHRtbENoYXIpXG4gICAgICAgIDogc3RyaW5nO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENvbnZlcnRzIGBzdHJpbmdgLCBhcyBzcGFjZSBzZXBhcmF0ZWQgd29yZHMsIHRvIHVwcGVyIGNhc2UuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgU3RyaW5nXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IFtzdHJpbmc9JyddIFRoZSBzdHJpbmcgdG8gY29udmVydC5cbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfSBSZXR1cm5zIHRoZSB1cHBlciBjYXNlZCBzdHJpbmcuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8udXBwZXJDYXNlKCctLWZvby1iYXInKTtcbiAgICAgKiAvLyA9PiAnRk9PIEJBUidcbiAgICAgKlxuICAgICAqIF8udXBwZXJDYXNlKCdmb29CYXInKTtcbiAgICAgKiAvLyA9PiAnRk9PIEJBUidcbiAgICAgKlxuICAgICAqIF8udXBwZXJDYXNlKCdfX2Zvb19iYXJfXycpO1xuICAgICAqIC8vID0+ICdGT08gQkFSJ1xuICAgICAqL1xuICAgIHZhciB1cHBlckNhc2UgPSBjcmVhdGVDb21wb3VuZGVyKGZ1bmN0aW9uKHJlc3VsdCwgd29yZCwgaW5kZXgpIHtcbiAgICAgIHJldHVybiByZXN1bHQgKyAoaW5kZXggPyAnICcgOiAnJykgKyB3b3JkLnRvVXBwZXJDYXNlKCk7XG4gICAgfSk7XG5cbiAgICAvKipcbiAgICAgKiBDb252ZXJ0cyB0aGUgZmlyc3QgY2hhcmFjdGVyIG9mIGBzdHJpbmdgIHRvIHVwcGVyIGNhc2UuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgU3RyaW5nXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IFtzdHJpbmc9JyddIFRoZSBzdHJpbmcgdG8gY29udmVydC5cbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfSBSZXR1cm5zIHRoZSBjb252ZXJ0ZWQgc3RyaW5nLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLnVwcGVyRmlyc3QoJ2ZyZWQnKTtcbiAgICAgKiAvLyA9PiAnRnJlZCdcbiAgICAgKlxuICAgICAqIF8udXBwZXJGaXJzdCgnRlJFRCcpO1xuICAgICAqIC8vID0+ICdGUkVEJ1xuICAgICAqL1xuICAgIHZhciB1cHBlckZpcnN0ID0gY3JlYXRlQ2FzZUZpcnN0KCd0b1VwcGVyQ2FzZScpO1xuXG4gICAgLyoqXG4gICAgICogU3BsaXRzIGBzdHJpbmdgIGludG8gYW4gYXJyYXkgb2YgaXRzIHdvcmRzLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDMuMC4wXG4gICAgICogQGNhdGVnb3J5IFN0cmluZ1xuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBbc3RyaW5nPScnXSBUaGUgc3RyaW5nIHRvIGluc3BlY3QuXG4gICAgICogQHBhcmFtIHtSZWdFeHB8c3RyaW5nfSBbcGF0dGVybl0gVGhlIHBhdHRlcm4gdG8gbWF0Y2ggd29yZHMuXG4gICAgICogQHBhcmFtLSB7T2JqZWN0fSBbZ3VhcmRdIEVuYWJsZXMgdXNlIGFzIGFuIGl0ZXJhdGVlIGZvciBtZXRob2RzIGxpa2UgYF8ubWFwYC5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIHdvcmRzIG9mIGBzdHJpbmdgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLndvcmRzKCdmcmVkLCBiYXJuZXksICYgcGViYmxlcycpO1xuICAgICAqIC8vID0+IFsnZnJlZCcsICdiYXJuZXknLCAncGViYmxlcyddXG4gICAgICpcbiAgICAgKiBfLndvcmRzKCdmcmVkLCBiYXJuZXksICYgcGViYmxlcycsIC9bXiwgXSsvZyk7XG4gICAgICogLy8gPT4gWydmcmVkJywgJ2Jhcm5leScsICcmJywgJ3BlYmJsZXMnXVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIHdvcmRzKHN0cmluZywgcGF0dGVybiwgZ3VhcmQpIHtcbiAgICAgIHN0cmluZyA9IHRvU3RyaW5nKHN0cmluZyk7XG4gICAgICBwYXR0ZXJuID0gZ3VhcmQgPyB1bmRlZmluZWQgOiBwYXR0ZXJuO1xuXG4gICAgICBpZiAocGF0dGVybiA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHJldHVybiBoYXNVbmljb2RlV29yZChzdHJpbmcpID8gdW5pY29kZVdvcmRzKHN0cmluZykgOiBhc2NpaVdvcmRzKHN0cmluZyk7XG4gICAgICB9XG4gICAgICByZXR1cm4gc3RyaW5nLm1hdGNoKHBhdHRlcm4pIHx8IFtdO1xuICAgIH1cblxuICAgIC8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi9cblxuICAgIC8qKlxuICAgICAqIEF0dGVtcHRzIHRvIGludm9rZSBgZnVuY2AsIHJldHVybmluZyBlaXRoZXIgdGhlIHJlc3VsdCBvciB0aGUgY2F1Z2h0IGVycm9yXG4gICAgICogb2JqZWN0LiBBbnkgYWRkaXRpb25hbCBhcmd1bWVudHMgYXJlIHByb3ZpZGVkIHRvIGBmdW5jYCB3aGVuIGl0J3MgaW52b2tlZC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAzLjAuMFxuICAgICAqIEBjYXRlZ29yeSBVdGlsXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gZnVuYyBUaGUgZnVuY3Rpb24gdG8gYXR0ZW1wdC5cbiAgICAgKiBAcGFyYW0gey4uLip9IFthcmdzXSBUaGUgYXJndW1lbnRzIHRvIGludm9rZSBgZnVuY2Agd2l0aC5cbiAgICAgKiBAcmV0dXJucyB7Kn0gUmV0dXJucyB0aGUgYGZ1bmNgIHJlc3VsdCBvciBlcnJvciBvYmplY3QuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIC8vIEF2b2lkIHRocm93aW5nIGVycm9ycyBmb3IgaW52YWxpZCBzZWxlY3RvcnMuXG4gICAgICogdmFyIGVsZW1lbnRzID0gXy5hdHRlbXB0KGZ1bmN0aW9uKHNlbGVjdG9yKSB7XG4gICAgICogICByZXR1cm4gZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbChzZWxlY3Rvcik7XG4gICAgICogfSwgJz5fPicpO1xuICAgICAqXG4gICAgICogaWYgKF8uaXNFcnJvcihlbGVtZW50cykpIHtcbiAgICAgKiAgIGVsZW1lbnRzID0gW107XG4gICAgICogfVxuICAgICAqL1xuICAgIHZhciBhdHRlbXB0ID0gYmFzZVJlc3QoZnVuY3Rpb24oZnVuYywgYXJncykge1xuICAgICAgdHJ5IHtcbiAgICAgICAgcmV0dXJuIGFwcGx5KGZ1bmMsIHVuZGVmaW5lZCwgYXJncyk7XG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIHJldHVybiBpc0Vycm9yKGUpID8gZSA6IG5ldyBFcnJvcihlKTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIC8qKlxuICAgICAqIEJpbmRzIG1ldGhvZHMgb2YgYW4gb2JqZWN0IHRvIHRoZSBvYmplY3QgaXRzZWxmLCBvdmVyd3JpdGluZyB0aGUgZXhpc3RpbmdcbiAgICAgKiBtZXRob2QuXG4gICAgICpcbiAgICAgKiAqKk5vdGU6KiogVGhpcyBtZXRob2QgZG9lc24ndCBzZXQgdGhlIFwibGVuZ3RoXCIgcHJvcGVydHkgb2YgYm91bmQgZnVuY3Rpb25zLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBzaW5jZSAwLjEuMFxuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQGNhdGVnb3J5IFV0aWxcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gYmluZCBhbmQgYXNzaWduIHRoZSBib3VuZCBtZXRob2RzIHRvLlxuICAgICAqIEBwYXJhbSB7Li4uKHN0cmluZ3xzdHJpbmdbXSl9IG1ldGhvZE5hbWVzIFRoZSBvYmplY3QgbWV0aG9kIG5hbWVzIHRvIGJpbmQuXG4gICAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyBgb2JqZWN0YC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIHZpZXcgPSB7XG4gICAgICogICAnbGFiZWwnOiAnZG9jcycsXG4gICAgICogICAnY2xpY2snOiBmdW5jdGlvbigpIHtcbiAgICAgKiAgICAgY29uc29sZS5sb2coJ2NsaWNrZWQgJyArIHRoaXMubGFiZWwpO1xuICAgICAqICAgfVxuICAgICAqIH07XG4gICAgICpcbiAgICAgKiBfLmJpbmRBbGwodmlldywgWydjbGljayddKTtcbiAgICAgKiBqUXVlcnkoZWxlbWVudCkub24oJ2NsaWNrJywgdmlldy5jbGljayk7XG4gICAgICogLy8gPT4gTG9ncyAnY2xpY2tlZCBkb2NzJyB3aGVuIGNsaWNrZWQuXG4gICAgICovXG4gICAgdmFyIGJpbmRBbGwgPSBmbGF0UmVzdChmdW5jdGlvbihvYmplY3QsIG1ldGhvZE5hbWVzKSB7XG4gICAgICBhcnJheUVhY2gobWV0aG9kTmFtZXMsIGZ1bmN0aW9uKGtleSkge1xuICAgICAgICBrZXkgPSB0b0tleShrZXkpO1xuICAgICAgICBiYXNlQXNzaWduVmFsdWUob2JqZWN0LCBrZXksIGJpbmQob2JqZWN0W2tleV0sIG9iamVjdCkpO1xuICAgICAgfSk7XG4gICAgICByZXR1cm4gb2JqZWN0O1xuICAgIH0pO1xuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIGZ1bmN0aW9uIHRoYXQgaXRlcmF0ZXMgb3ZlciBgcGFpcnNgIGFuZCBpbnZva2VzIHRoZSBjb3JyZXNwb25kaW5nXG4gICAgICogZnVuY3Rpb24gb2YgdGhlIGZpcnN0IHByZWRpY2F0ZSB0byByZXR1cm4gdHJ1dGh5LiBUaGUgcHJlZGljYXRlLWZ1bmN0aW9uXG4gICAgICogcGFpcnMgYXJlIGludm9rZWQgd2l0aCB0aGUgYHRoaXNgIGJpbmRpbmcgYW5kIGFyZ3VtZW50cyBvZiB0aGUgY3JlYXRlZFxuICAgICAqIGZ1bmN0aW9uLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMC4wXG4gICAgICogQGNhdGVnb3J5IFV0aWxcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBwYWlycyBUaGUgcHJlZGljYXRlLWZ1bmN0aW9uIHBhaXJzLlxuICAgICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IGNvbXBvc2l0ZSBmdW5jdGlvbi5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIGZ1bmMgPSBfLmNvbmQoW1xuICAgICAqICAgW18ubWF0Y2hlcyh7ICdhJzogMSB9KSwgICAgICAgICAgIF8uY29uc3RhbnQoJ21hdGNoZXMgQScpXSxcbiAgICAgKiAgIFtfLmNvbmZvcm1zKHsgJ2InOiBfLmlzTnVtYmVyIH0pLCBfLmNvbnN0YW50KCdtYXRjaGVzIEInKV0sXG4gICAgICogICBbXy5zdHViVHJ1ZSwgICAgICAgICAgICAgICAgICAgICAgXy5jb25zdGFudCgnbm8gbWF0Y2gnKV1cbiAgICAgKiBdKTtcbiAgICAgKlxuICAgICAqIGZ1bmMoeyAnYSc6IDEsICdiJzogMiB9KTtcbiAgICAgKiAvLyA9PiAnbWF0Y2hlcyBBJ1xuICAgICAqXG4gICAgICogZnVuYyh7ICdhJzogMCwgJ2InOiAxIH0pO1xuICAgICAqIC8vID0+ICdtYXRjaGVzIEInXG4gICAgICpcbiAgICAgKiBmdW5jKHsgJ2EnOiAnMScsICdiJzogJzInIH0pO1xuICAgICAqIC8vID0+ICdubyBtYXRjaCdcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBjb25kKHBhaXJzKSB7XG4gICAgICB2YXIgbGVuZ3RoID0gcGFpcnMgPT0gbnVsbCA/IDAgOiBwYWlycy5sZW5ndGgsXG4gICAgICAgICAgdG9JdGVyYXRlZSA9IGdldEl0ZXJhdGVlKCk7XG5cbiAgICAgIHBhaXJzID0gIWxlbmd0aCA/IFtdIDogYXJyYXlNYXAocGFpcnMsIGZ1bmN0aW9uKHBhaXIpIHtcbiAgICAgICAgaWYgKHR5cGVvZiBwYWlyWzFdICE9ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKEZVTkNfRVJST1JfVEVYVCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIFt0b0l0ZXJhdGVlKHBhaXJbMF0pLCBwYWlyWzFdXTtcbiAgICAgIH0pO1xuXG4gICAgICByZXR1cm4gYmFzZVJlc3QoZnVuY3Rpb24oYXJncykge1xuICAgICAgICB2YXIgaW5kZXggPSAtMTtcbiAgICAgICAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHtcbiAgICAgICAgICB2YXIgcGFpciA9IHBhaXJzW2luZGV4XTtcbiAgICAgICAgICBpZiAoYXBwbHkocGFpclswXSwgdGhpcywgYXJncykpIHtcbiAgICAgICAgICAgIHJldHVybiBhcHBseShwYWlyWzFdLCB0aGlzLCBhcmdzKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBmdW5jdGlvbiB0aGF0IGludm9rZXMgdGhlIHByZWRpY2F0ZSBwcm9wZXJ0aWVzIG9mIGBzb3VyY2VgIHdpdGhcbiAgICAgKiB0aGUgY29ycmVzcG9uZGluZyBwcm9wZXJ0eSB2YWx1ZXMgb2YgYSBnaXZlbiBvYmplY3QsIHJldHVybmluZyBgdHJ1ZWAgaWZcbiAgICAgKiBhbGwgcHJlZGljYXRlcyByZXR1cm4gdHJ1dGh5LCBlbHNlIGBmYWxzZWAuXG4gICAgICpcbiAgICAgKiAqKk5vdGU6KiogVGhlIGNyZWF0ZWQgZnVuY3Rpb24gaXMgZXF1aXZhbGVudCB0byBgXy5jb25mb3Jtc1RvYCB3aXRoXG4gICAgICogYHNvdXJjZWAgcGFydGlhbGx5IGFwcGxpZWQuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgVXRpbFxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBzb3VyY2UgVGhlIG9iamVjdCBvZiBwcm9wZXJ0eSBwcmVkaWNhdGVzIHRvIGNvbmZvcm0gdG8uXG4gICAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgc3BlYyBmdW5jdGlvbi5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIG9iamVjdHMgPSBbXG4gICAgICogICB7ICdhJzogMiwgJ2InOiAxIH0sXG4gICAgICogICB7ICdhJzogMSwgJ2InOiAyIH1cbiAgICAgKiBdO1xuICAgICAqXG4gICAgICogXy5maWx0ZXIob2JqZWN0cywgXy5jb25mb3Jtcyh7ICdiJzogZnVuY3Rpb24obikgeyByZXR1cm4gbiA+IDE7IH0gfSkpO1xuICAgICAqIC8vID0+IFt7ICdhJzogMSwgJ2InOiAyIH1dXG4gICAgICovXG4gICAgZnVuY3Rpb24gY29uZm9ybXMoc291cmNlKSB7XG4gICAgICByZXR1cm4gYmFzZUNvbmZvcm1zKGJhc2VDbG9uZShzb3VyY2UsIENMT05FX0RFRVBfRkxBRykpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBmdW5jdGlvbiB0aGF0IHJldHVybnMgYHZhbHVlYC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAyLjQuMFxuICAgICAqIEBjYXRlZ29yeSBVdGlsXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gcmV0dXJuIGZyb20gdGhlIG5ldyBmdW5jdGlvbi5cbiAgICAgKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBjb25zdGFudCBmdW5jdGlvbi5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIG9iamVjdHMgPSBfLnRpbWVzKDIsIF8uY29uc3RhbnQoeyAnYSc6IDEgfSkpO1xuICAgICAqXG4gICAgICogY29uc29sZS5sb2cob2JqZWN0cyk7XG4gICAgICogLy8gPT4gW3sgJ2EnOiAxIH0sIHsgJ2EnOiAxIH1dXG4gICAgICpcbiAgICAgKiBjb25zb2xlLmxvZyhvYmplY3RzWzBdID09PSBvYmplY3RzWzFdKTtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICovXG4gICAgZnVuY3Rpb24gY29uc3RhbnQodmFsdWUpIHtcbiAgICAgIHJldHVybiBmdW5jdGlvbigpIHtcbiAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgICAgfTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDaGVja3MgYHZhbHVlYCB0byBkZXRlcm1pbmUgd2hldGhlciBhIGRlZmF1bHQgdmFsdWUgc2hvdWxkIGJlIHJldHVybmVkIGluXG4gICAgICogaXRzIHBsYWNlLiBUaGUgYGRlZmF1bHRWYWx1ZWAgaXMgcmV0dXJuZWQgaWYgYHZhbHVlYCBpcyBgTmFOYCwgYG51bGxgLFxuICAgICAqIG9yIGB1bmRlZmluZWRgLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMTQuMFxuICAgICAqIEBjYXRlZ29yeSBVdGlsXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gICAgICogQHBhcmFtIHsqfSBkZWZhdWx0VmFsdWUgVGhlIGRlZmF1bHQgdmFsdWUuXG4gICAgICogQHJldHVybnMgeyp9IFJldHVybnMgdGhlIHJlc29sdmVkIHZhbHVlLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLmRlZmF1bHRUbygxLCAxMCk7XG4gICAgICogLy8gPT4gMVxuICAgICAqXG4gICAgICogXy5kZWZhdWx0VG8odW5kZWZpbmVkLCAxMCk7XG4gICAgICogLy8gPT4gMTBcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBkZWZhdWx0VG8odmFsdWUsIGRlZmF1bHRWYWx1ZSkge1xuICAgICAgcmV0dXJuICh2YWx1ZSA9PSBudWxsIHx8IHZhbHVlICE9PSB2YWx1ZSkgPyBkZWZhdWx0VmFsdWUgOiB2YWx1ZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgZnVuY3Rpb24gdGhhdCByZXR1cm5zIHRoZSByZXN1bHQgb2YgaW52b2tpbmcgdGhlIGdpdmVuIGZ1bmN0aW9uc1xuICAgICAqIHdpdGggdGhlIGB0aGlzYCBiaW5kaW5nIG9mIHRoZSBjcmVhdGVkIGZ1bmN0aW9uLCB3aGVyZSBlYWNoIHN1Y2Nlc3NpdmVcbiAgICAgKiBpbnZvY2F0aW9uIGlzIHN1cHBsaWVkIHRoZSByZXR1cm4gdmFsdWUgb2YgdGhlIHByZXZpb3VzLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDMuMC4wXG4gICAgICogQGNhdGVnb3J5IFV0aWxcbiAgICAgKiBAcGFyYW0gey4uLihGdW5jdGlvbnxGdW5jdGlvbltdKX0gW2Z1bmNzXSBUaGUgZnVuY3Rpb25zIHRvIGludm9rZS5cbiAgICAgKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBjb21wb3NpdGUgZnVuY3Rpb24uXG4gICAgICogQHNlZSBfLmZsb3dSaWdodFxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBmdW5jdGlvbiBzcXVhcmUobikge1xuICAgICAqICAgcmV0dXJuIG4gKiBuO1xuICAgICAqIH1cbiAgICAgKlxuICAgICAqIHZhciBhZGRTcXVhcmUgPSBfLmZsb3coW18uYWRkLCBzcXVhcmVdKTtcbiAgICAgKiBhZGRTcXVhcmUoMSwgMik7XG4gICAgICogLy8gPT4gOVxuICAgICAqL1xuICAgIHZhciBmbG93ID0gY3JlYXRlRmxvdygpO1xuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgaXMgbGlrZSBgXy5mbG93YCBleGNlcHQgdGhhdCBpdCBjcmVhdGVzIGEgZnVuY3Rpb24gdGhhdFxuICAgICAqIGludm9rZXMgdGhlIGdpdmVuIGZ1bmN0aW9ucyBmcm9tIHJpZ2h0IHRvIGxlZnQuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQHNpbmNlIDMuMC4wXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAY2F0ZWdvcnkgVXRpbFxuICAgICAqIEBwYXJhbSB7Li4uKEZ1bmN0aW9ufEZ1bmN0aW9uW10pfSBbZnVuY3NdIFRoZSBmdW5jdGlvbnMgdG8gaW52b2tlLlxuICAgICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IGNvbXBvc2l0ZSBmdW5jdGlvbi5cbiAgICAgKiBAc2VlIF8uZmxvd1xuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBmdW5jdGlvbiBzcXVhcmUobikge1xuICAgICAqICAgcmV0dXJuIG4gKiBuO1xuICAgICAqIH1cbiAgICAgKlxuICAgICAqIHZhciBhZGRTcXVhcmUgPSBfLmZsb3dSaWdodChbc3F1YXJlLCBfLmFkZF0pO1xuICAgICAqIGFkZFNxdWFyZSgxLCAyKTtcbiAgICAgKiAvLyA9PiA5XG4gICAgICovXG4gICAgdmFyIGZsb3dSaWdodCA9IGNyZWF0ZUZsb3codHJ1ZSk7XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIG1ldGhvZCByZXR1cm5zIHRoZSBmaXJzdCBhcmd1bWVudCBpdCByZWNlaXZlcy5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAc2luY2UgMC4xLjBcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBjYXRlZ29yeSBVdGlsXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBBbnkgdmFsdWUuXG4gICAgICogQHJldHVybnMgeyp9IFJldHVybnMgYHZhbHVlYC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIG9iamVjdCA9IHsgJ2EnOiAxIH07XG4gICAgICpcbiAgICAgKiBjb25zb2xlLmxvZyhfLmlkZW50aXR5KG9iamVjdCkgPT09IG9iamVjdCk7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGlkZW50aXR5KHZhbHVlKSB7XG4gICAgICByZXR1cm4gdmFsdWU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIGZ1bmN0aW9uIHRoYXQgaW52b2tlcyBgZnVuY2Agd2l0aCB0aGUgYXJndW1lbnRzIG9mIHRoZSBjcmVhdGVkXG4gICAgICogZnVuY3Rpb24uIElmIGBmdW5jYCBpcyBhIHByb3BlcnR5IG5hbWUsIHRoZSBjcmVhdGVkIGZ1bmN0aW9uIHJldHVybnMgdGhlXG4gICAgICogcHJvcGVydHkgdmFsdWUgZm9yIGEgZ2l2ZW4gZWxlbWVudC4gSWYgYGZ1bmNgIGlzIGFuIGFycmF5IG9yIG9iamVjdCwgdGhlXG4gICAgICogY3JlYXRlZCBmdW5jdGlvbiByZXR1cm5zIGB0cnVlYCBmb3IgZWxlbWVudHMgdGhhdCBjb250YWluIHRoZSBlcXVpdmFsZW50XG4gICAgICogc291cmNlIHByb3BlcnRpZXMsIG90aGVyd2lzZSBpdCByZXR1cm5zIGBmYWxzZWAuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQHNpbmNlIDQuMC4wXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAY2F0ZWdvcnkgVXRpbFxuICAgICAqIEBwYXJhbSB7Kn0gW2Z1bmM9Xy5pZGVudGl0eV0gVGhlIHZhbHVlIHRvIGNvbnZlcnQgdG8gYSBjYWxsYmFjay5cbiAgICAgKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIGNhbGxiYWNrLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgdXNlcnMgPSBbXG4gICAgICogICB7ICd1c2VyJzogJ2Jhcm5leScsICdhZ2UnOiAzNiwgJ2FjdGl2ZSc6IHRydWUgfSxcbiAgICAgKiAgIHsgJ3VzZXInOiAnZnJlZCcsICAgJ2FnZSc6IDQwLCAnYWN0aXZlJzogZmFsc2UgfVxuICAgICAqIF07XG4gICAgICpcbiAgICAgKiAvLyBUaGUgYF8ubWF0Y2hlc2AgaXRlcmF0ZWUgc2hvcnRoYW5kLlxuICAgICAqIF8uZmlsdGVyKHVzZXJzLCBfLml0ZXJhdGVlKHsgJ3VzZXInOiAnYmFybmV5JywgJ2FjdGl2ZSc6IHRydWUgfSkpO1xuICAgICAqIC8vID0+IFt7ICd1c2VyJzogJ2Jhcm5leScsICdhZ2UnOiAzNiwgJ2FjdGl2ZSc6IHRydWUgfV1cbiAgICAgKlxuICAgICAqIC8vIFRoZSBgXy5tYXRjaGVzUHJvcGVydHlgIGl0ZXJhdGVlIHNob3J0aGFuZC5cbiAgICAgKiBfLmZpbHRlcih1c2VycywgXy5pdGVyYXRlZShbJ3VzZXInLCAnZnJlZCddKSk7XG4gICAgICogLy8gPT4gW3sgJ3VzZXInOiAnZnJlZCcsICdhZ2UnOiA0MCB9XVxuICAgICAqXG4gICAgICogLy8gVGhlIGBfLnByb3BlcnR5YCBpdGVyYXRlZSBzaG9ydGhhbmQuXG4gICAgICogXy5tYXAodXNlcnMsIF8uaXRlcmF0ZWUoJ3VzZXInKSk7XG4gICAgICogLy8gPT4gWydiYXJuZXknLCAnZnJlZCddXG4gICAgICpcbiAgICAgKiAvLyBDcmVhdGUgY3VzdG9tIGl0ZXJhdGVlIHNob3J0aGFuZHMuXG4gICAgICogXy5pdGVyYXRlZSA9IF8ud3JhcChfLml0ZXJhdGVlLCBmdW5jdGlvbihpdGVyYXRlZSwgZnVuYykge1xuICAgICAqICAgcmV0dXJuICFfLmlzUmVnRXhwKGZ1bmMpID8gaXRlcmF0ZWUoZnVuYykgOiBmdW5jdGlvbihzdHJpbmcpIHtcbiAgICAgKiAgICAgcmV0dXJuIGZ1bmMudGVzdChzdHJpbmcpO1xuICAgICAqICAgfTtcbiAgICAgKiB9KTtcbiAgICAgKlxuICAgICAqIF8uZmlsdGVyKFsnYWJjJywgJ2RlZiddLCAvZWYvKTtcbiAgICAgKiAvLyA9PiBbJ2RlZiddXG4gICAgICovXG4gICAgZnVuY3Rpb24gaXRlcmF0ZWUoZnVuYykge1xuICAgICAgcmV0dXJuIGJhc2VJdGVyYXRlZSh0eXBlb2YgZnVuYyA9PSAnZnVuY3Rpb24nID8gZnVuYyA6IGJhc2VDbG9uZShmdW5jLCBDTE9ORV9ERUVQX0ZMQUcpKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgZnVuY3Rpb24gdGhhdCBwZXJmb3JtcyBhIHBhcnRpYWwgZGVlcCBjb21wYXJpc29uIGJldHdlZW4gYSBnaXZlblxuICAgICAqIG9iamVjdCBhbmQgYHNvdXJjZWAsIHJldHVybmluZyBgdHJ1ZWAgaWYgdGhlIGdpdmVuIG9iamVjdCBoYXMgZXF1aXZhbGVudFxuICAgICAqIHByb3BlcnR5IHZhbHVlcywgZWxzZSBgZmFsc2VgLlxuICAgICAqXG4gICAgICogKipOb3RlOioqIFRoZSBjcmVhdGVkIGZ1bmN0aW9uIGlzIGVxdWl2YWxlbnQgdG8gYF8uaXNNYXRjaGAgd2l0aCBgc291cmNlYFxuICAgICAqIHBhcnRpYWxseSBhcHBsaWVkLlxuICAgICAqXG4gICAgICogUGFydGlhbCBjb21wYXJpc29ucyB3aWxsIG1hdGNoIGVtcHR5IGFycmF5IGFuZCBlbXB0eSBvYmplY3QgYHNvdXJjZWBcbiAgICAgKiB2YWx1ZXMgYWdhaW5zdCBhbnkgYXJyYXkgb3Igb2JqZWN0IHZhbHVlLCByZXNwZWN0aXZlbHkuIFNlZSBgXy5pc0VxdWFsYFxuICAgICAqIGZvciBhIGxpc3Qgb2Ygc3VwcG9ydGVkIHZhbHVlIGNvbXBhcmlzb25zLlxuICAgICAqXG4gICAgICogKipOb3RlOioqIE11bHRpcGxlIHZhbHVlcyBjYW4gYmUgY2hlY2tlZCBieSBjb21iaW5pbmcgc2V2ZXJhbCBtYXRjaGVyc1xuICAgICAqIHVzaW5nIGBfLm92ZXJTb21lYFxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDMuMC4wXG4gICAgICogQGNhdGVnb3J5IFV0aWxcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gc291cmNlIFRoZSBvYmplY3Qgb2YgcHJvcGVydHkgdmFsdWVzIHRvIG1hdGNoLlxuICAgICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IHNwZWMgZnVuY3Rpb24uXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciBvYmplY3RzID0gW1xuICAgICAqICAgeyAnYSc6IDEsICdiJzogMiwgJ2MnOiAzIH0sXG4gICAgICogICB7ICdhJzogNCwgJ2InOiA1LCAnYyc6IDYgfVxuICAgICAqIF07XG4gICAgICpcbiAgICAgKiBfLmZpbHRlcihvYmplY3RzLCBfLm1hdGNoZXMoeyAnYSc6IDQsICdjJzogNiB9KSk7XG4gICAgICogLy8gPT4gW3sgJ2EnOiA0LCAnYic6IDUsICdjJzogNiB9XVxuICAgICAqXG4gICAgICogLy8gQ2hlY2tpbmcgZm9yIHNldmVyYWwgcG9zc2libGUgdmFsdWVzXG4gICAgICogXy5maWx0ZXIob2JqZWN0cywgXy5vdmVyU29tZShbXy5tYXRjaGVzKHsgJ2EnOiAxIH0pLCBfLm1hdGNoZXMoeyAnYSc6IDQgfSldKSk7XG4gICAgICogLy8gPT4gW3sgJ2EnOiAxLCAnYic6IDIsICdjJzogMyB9LCB7ICdhJzogNCwgJ2InOiA1LCAnYyc6IDYgfV1cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBtYXRjaGVzKHNvdXJjZSkge1xuICAgICAgcmV0dXJuIGJhc2VNYXRjaGVzKGJhc2VDbG9uZShzb3VyY2UsIENMT05FX0RFRVBfRkxBRykpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBmdW5jdGlvbiB0aGF0IHBlcmZvcm1zIGEgcGFydGlhbCBkZWVwIGNvbXBhcmlzb24gYmV0d2VlbiB0aGVcbiAgICAgKiB2YWx1ZSBhdCBgcGF0aGAgb2YgYSBnaXZlbiBvYmplY3QgdG8gYHNyY1ZhbHVlYCwgcmV0dXJuaW5nIGB0cnVlYCBpZiB0aGVcbiAgICAgKiBvYmplY3QgdmFsdWUgaXMgZXF1aXZhbGVudCwgZWxzZSBgZmFsc2VgLlxuICAgICAqXG4gICAgICogKipOb3RlOioqIFBhcnRpYWwgY29tcGFyaXNvbnMgd2lsbCBtYXRjaCBlbXB0eSBhcnJheSBhbmQgZW1wdHkgb2JqZWN0XG4gICAgICogYHNyY1ZhbHVlYCB2YWx1ZXMgYWdhaW5zdCBhbnkgYXJyYXkgb3Igb2JqZWN0IHZhbHVlLCByZXNwZWN0aXZlbHkuIFNlZVxuICAgICAqIGBfLmlzRXF1YWxgIGZvciBhIGxpc3Qgb2Ygc3VwcG9ydGVkIHZhbHVlIGNvbXBhcmlzb25zLlxuICAgICAqXG4gICAgICogKipOb3RlOioqIE11bHRpcGxlIHZhbHVlcyBjYW4gYmUgY2hlY2tlZCBieSBjb21iaW5pbmcgc2V2ZXJhbCBtYXRjaGVyc1xuICAgICAqIHVzaW5nIGBfLm92ZXJTb21lYFxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDMuMi4wXG4gICAgICogQGNhdGVnb3J5IFV0aWxcbiAgICAgKiBAcGFyYW0ge0FycmF5fHN0cmluZ30gcGF0aCBUaGUgcGF0aCBvZiB0aGUgcHJvcGVydHkgdG8gZ2V0LlxuICAgICAqIEBwYXJhbSB7Kn0gc3JjVmFsdWUgVGhlIHZhbHVlIHRvIG1hdGNoLlxuICAgICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IHNwZWMgZnVuY3Rpb24uXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciBvYmplY3RzID0gW1xuICAgICAqICAgeyAnYSc6IDEsICdiJzogMiwgJ2MnOiAzIH0sXG4gICAgICogICB7ICdhJzogNCwgJ2InOiA1LCAnYyc6IDYgfVxuICAgICAqIF07XG4gICAgICpcbiAgICAgKiBfLmZpbmQob2JqZWN0cywgXy5tYXRjaGVzUHJvcGVydHkoJ2EnLCA0KSk7XG4gICAgICogLy8gPT4geyAnYSc6IDQsICdiJzogNSwgJ2MnOiA2IH1cbiAgICAgKlxuICAgICAqIC8vIENoZWNraW5nIGZvciBzZXZlcmFsIHBvc3NpYmxlIHZhbHVlc1xuICAgICAqIF8uZmlsdGVyKG9iamVjdHMsIF8ub3ZlclNvbWUoW18ubWF0Y2hlc1Byb3BlcnR5KCdhJywgMSksIF8ubWF0Y2hlc1Byb3BlcnR5KCdhJywgNCldKSk7XG4gICAgICogLy8gPT4gW3sgJ2EnOiAxLCAnYic6IDIsICdjJzogMyB9LCB7ICdhJzogNCwgJ2InOiA1LCAnYyc6IDYgfV1cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBtYXRjaGVzUHJvcGVydHkocGF0aCwgc3JjVmFsdWUpIHtcbiAgICAgIHJldHVybiBiYXNlTWF0Y2hlc1Byb3BlcnR5KHBhdGgsIGJhc2VDbG9uZShzcmNWYWx1ZSwgQ0xPTkVfREVFUF9GTEFHKSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIGZ1bmN0aW9uIHRoYXQgaW52b2tlcyB0aGUgbWV0aG9kIGF0IGBwYXRoYCBvZiBhIGdpdmVuIG9iamVjdC5cbiAgICAgKiBBbnkgYWRkaXRpb25hbCBhcmd1bWVudHMgYXJlIHByb3ZpZGVkIHRvIHRoZSBpbnZva2VkIG1ldGhvZC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAzLjcuMFxuICAgICAqIEBjYXRlZ29yeSBVdGlsXG4gICAgICogQHBhcmFtIHtBcnJheXxzdHJpbmd9IHBhdGggVGhlIHBhdGggb2YgdGhlIG1ldGhvZCB0byBpbnZva2UuXG4gICAgICogQHBhcmFtIHsuLi4qfSBbYXJnc10gVGhlIGFyZ3VtZW50cyB0byBpbnZva2UgdGhlIG1ldGhvZCB3aXRoLlxuICAgICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IGludm9rZXIgZnVuY3Rpb24uXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciBvYmplY3RzID0gW1xuICAgICAqICAgeyAnYSc6IHsgJ2InOiBfLmNvbnN0YW50KDIpIH0gfSxcbiAgICAgKiAgIHsgJ2EnOiB7ICdiJzogXy5jb25zdGFudCgxKSB9IH1cbiAgICAgKiBdO1xuICAgICAqXG4gICAgICogXy5tYXAob2JqZWN0cywgXy5tZXRob2QoJ2EuYicpKTtcbiAgICAgKiAvLyA9PiBbMiwgMV1cbiAgICAgKlxuICAgICAqIF8ubWFwKG9iamVjdHMsIF8ubWV0aG9kKFsnYScsICdiJ10pKTtcbiAgICAgKiAvLyA9PiBbMiwgMV1cbiAgICAgKi9cbiAgICB2YXIgbWV0aG9kID0gYmFzZVJlc3QoZnVuY3Rpb24ocGF0aCwgYXJncykge1xuICAgICAgcmV0dXJuIGZ1bmN0aW9uKG9iamVjdCkge1xuICAgICAgICByZXR1cm4gYmFzZUludm9rZShvYmplY3QsIHBhdGgsIGFyZ3MpO1xuICAgICAgfTtcbiAgICB9KTtcblxuICAgIC8qKlxuICAgICAqIFRoZSBvcHBvc2l0ZSBvZiBgXy5tZXRob2RgOyB0aGlzIG1ldGhvZCBjcmVhdGVzIGEgZnVuY3Rpb24gdGhhdCBpbnZva2VzXG4gICAgICogdGhlIG1ldGhvZCBhdCBhIGdpdmVuIHBhdGggb2YgYG9iamVjdGAuIEFueSBhZGRpdGlvbmFsIGFyZ3VtZW50cyBhcmVcbiAgICAgKiBwcm92aWRlZCB0byB0aGUgaW52b2tlZCBtZXRob2QuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMy43LjBcbiAgICAgKiBAY2F0ZWdvcnkgVXRpbFxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBxdWVyeS5cbiAgICAgKiBAcGFyYW0gey4uLip9IFthcmdzXSBUaGUgYXJndW1lbnRzIHRvIGludm9rZSB0aGUgbWV0aG9kIHdpdGguXG4gICAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgaW52b2tlciBmdW5jdGlvbi5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIGFycmF5ID0gXy50aW1lcygzLCBfLmNvbnN0YW50KSxcbiAgICAgKiAgICAgb2JqZWN0ID0geyAnYSc6IGFycmF5LCAnYic6IGFycmF5LCAnYyc6IGFycmF5IH07XG4gICAgICpcbiAgICAgKiBfLm1hcChbJ2FbMl0nLCAnY1swXSddLCBfLm1ldGhvZE9mKG9iamVjdCkpO1xuICAgICAqIC8vID0+IFsyLCAwXVxuICAgICAqXG4gICAgICogXy5tYXAoW1snYScsICcyJ10sIFsnYycsICcwJ11dLCBfLm1ldGhvZE9mKG9iamVjdCkpO1xuICAgICAqIC8vID0+IFsyLCAwXVxuICAgICAqL1xuICAgIHZhciBtZXRob2RPZiA9IGJhc2VSZXN0KGZ1bmN0aW9uKG9iamVjdCwgYXJncykge1xuICAgICAgcmV0dXJuIGZ1bmN0aW9uKHBhdGgpIHtcbiAgICAgICAgcmV0dXJuIGJhc2VJbnZva2Uob2JqZWN0LCBwYXRoLCBhcmdzKTtcbiAgICAgIH07XG4gICAgfSk7XG5cbiAgICAvKipcbiAgICAgKiBBZGRzIGFsbCBvd24gZW51bWVyYWJsZSBzdHJpbmcga2V5ZWQgZnVuY3Rpb24gcHJvcGVydGllcyBvZiBhIHNvdXJjZVxuICAgICAqIG9iamVjdCB0byB0aGUgZGVzdGluYXRpb24gb2JqZWN0LiBJZiBgb2JqZWN0YCBpcyBhIGZ1bmN0aW9uLCB0aGVuIG1ldGhvZHNcbiAgICAgKiBhcmUgYWRkZWQgdG8gaXRzIHByb3RvdHlwZSBhcyB3ZWxsLlxuICAgICAqXG4gICAgICogKipOb3RlOioqIFVzZSBgXy5ydW5JbkNvbnRleHRgIHRvIGNyZWF0ZSBhIHByaXN0aW5lIGBsb2Rhc2hgIGZ1bmN0aW9uIHRvXG4gICAgICogYXZvaWQgY29uZmxpY3RzIGNhdXNlZCBieSBtb2RpZnlpbmcgdGhlIG9yaWdpbmFsLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBzaW5jZSAwLjEuMFxuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQGNhdGVnb3J5IFV0aWxcbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufE9iamVjdH0gW29iamVjdD1sb2Rhc2hdIFRoZSBkZXN0aW5hdGlvbiBvYmplY3QuXG4gICAgICogQHBhcmFtIHtPYmplY3R9IHNvdXJjZSBUaGUgb2JqZWN0IG9mIGZ1bmN0aW9ucyB0byBhZGQuXG4gICAgICogQHBhcmFtIHtPYmplY3R9IFtvcHRpb25zPXt9XSBUaGUgb3B0aW9ucyBvYmplY3QuXG4gICAgICogQHBhcmFtIHtib29sZWFufSBbb3B0aW9ucy5jaGFpbj10cnVlXSBTcGVjaWZ5IHdoZXRoZXIgbWl4aW5zIGFyZSBjaGFpbmFibGUuXG4gICAgICogQHJldHVybnMge0Z1bmN0aW9ufE9iamVjdH0gUmV0dXJucyBgb2JqZWN0YC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogZnVuY3Rpb24gdm93ZWxzKHN0cmluZykge1xuICAgICAqICAgcmV0dXJuIF8uZmlsdGVyKHN0cmluZywgZnVuY3Rpb24odikge1xuICAgICAqICAgICByZXR1cm4gL1thZWlvdV0vaS50ZXN0KHYpO1xuICAgICAqICAgfSk7XG4gICAgICogfVxuICAgICAqXG4gICAgICogXy5taXhpbih7ICd2b3dlbHMnOiB2b3dlbHMgfSk7XG4gICAgICogXy52b3dlbHMoJ2ZyZWQnKTtcbiAgICAgKiAvLyA9PiBbJ2UnXVxuICAgICAqXG4gICAgICogXygnZnJlZCcpLnZvd2VscygpLnZhbHVlKCk7XG4gICAgICogLy8gPT4gWydlJ11cbiAgICAgKlxuICAgICAqIF8ubWl4aW4oeyAndm93ZWxzJzogdm93ZWxzIH0sIHsgJ2NoYWluJzogZmFsc2UgfSk7XG4gICAgICogXygnZnJlZCcpLnZvd2VscygpO1xuICAgICAqIC8vID0+IFsnZSddXG4gICAgICovXG4gICAgZnVuY3Rpb24gbWl4aW4ob2JqZWN0LCBzb3VyY2UsIG9wdGlvbnMpIHtcbiAgICAgIHZhciBwcm9wcyA9IGtleXMoc291cmNlKSxcbiAgICAgICAgICBtZXRob2ROYW1lcyA9IGJhc2VGdW5jdGlvbnMoc291cmNlLCBwcm9wcyk7XG5cbiAgICAgIGlmIChvcHRpb25zID09IG51bGwgJiZcbiAgICAgICAgICAhKGlzT2JqZWN0KHNvdXJjZSkgJiYgKG1ldGhvZE5hbWVzLmxlbmd0aCB8fCAhcHJvcHMubGVuZ3RoKSkpIHtcbiAgICAgICAgb3B0aW9ucyA9IHNvdXJjZTtcbiAgICAgICAgc291cmNlID0gb2JqZWN0O1xuICAgICAgICBvYmplY3QgPSB0aGlzO1xuICAgICAgICBtZXRob2ROYW1lcyA9IGJhc2VGdW5jdGlvbnMoc291cmNlLCBrZXlzKHNvdXJjZSkpO1xuICAgICAgfVxuICAgICAgdmFyIGNoYWluID0gIShpc09iamVjdChvcHRpb25zKSAmJiAnY2hhaW4nIGluIG9wdGlvbnMpIHx8ICEhb3B0aW9ucy5jaGFpbixcbiAgICAgICAgICBpc0Z1bmMgPSBpc0Z1bmN0aW9uKG9iamVjdCk7XG5cbiAgICAgIGFycmF5RWFjaChtZXRob2ROYW1lcywgZnVuY3Rpb24obWV0aG9kTmFtZSkge1xuICAgICAgICB2YXIgZnVuYyA9IHNvdXJjZVttZXRob2ROYW1lXTtcbiAgICAgICAgb2JqZWN0W21ldGhvZE5hbWVdID0gZnVuYztcbiAgICAgICAgaWYgKGlzRnVuYykge1xuICAgICAgICAgIG9iamVjdC5wcm90b3R5cGVbbWV0aG9kTmFtZV0gPSBmdW5jdGlvbigpIHtcbiAgICAgICAgICAgIHZhciBjaGFpbkFsbCA9IHRoaXMuX19jaGFpbl9fO1xuICAgICAgICAgICAgaWYgKGNoYWluIHx8IGNoYWluQWxsKSB7XG4gICAgICAgICAgICAgIHZhciByZXN1bHQgPSBvYmplY3QodGhpcy5fX3dyYXBwZWRfXyksXG4gICAgICAgICAgICAgICAgICBhY3Rpb25zID0gcmVzdWx0Ll9fYWN0aW9uc19fID0gY29weUFycmF5KHRoaXMuX19hY3Rpb25zX18pO1xuXG4gICAgICAgICAgICAgIGFjdGlvbnMucHVzaCh7ICdmdW5jJzogZnVuYywgJ2FyZ3MnOiBhcmd1bWVudHMsICd0aGlzQXJnJzogb2JqZWN0IH0pO1xuICAgICAgICAgICAgICByZXN1bHQuX19jaGFpbl9fID0gY2hhaW5BbGw7XG4gICAgICAgICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gZnVuYy5hcHBseShvYmplY3QsIGFycmF5UHVzaChbdGhpcy52YWx1ZSgpXSwgYXJndW1lbnRzKSk7XG4gICAgICAgICAgfTtcbiAgICAgICAgfVxuICAgICAgfSk7XG5cbiAgICAgIHJldHVybiBvYmplY3Q7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmV2ZXJ0cyB0aGUgYF9gIHZhcmlhYmxlIHRvIGl0cyBwcmV2aW91cyB2YWx1ZSBhbmQgcmV0dXJucyBhIHJlZmVyZW5jZSB0b1xuICAgICAqIHRoZSBgbG9kYXNoYCBmdW5jdGlvbi5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAc2luY2UgMC4xLjBcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBjYXRlZ29yeSBVdGlsXG4gICAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBgbG9kYXNoYCBmdW5jdGlvbi5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIGxvZGFzaCA9IF8ubm9Db25mbGljdCgpO1xuICAgICAqL1xuICAgIGZ1bmN0aW9uIG5vQ29uZmxpY3QoKSB7XG4gICAgICBpZiAocm9vdC5fID09PSB0aGlzKSB7XG4gICAgICAgIHJvb3QuXyA9IG9sZERhc2g7XG4gICAgICB9XG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIG1ldGhvZCByZXR1cm5zIGB1bmRlZmluZWRgLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDIuMy4wXG4gICAgICogQGNhdGVnb3J5IFV0aWxcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy50aW1lcygyLCBfLm5vb3ApO1xuICAgICAqIC8vID0+IFt1bmRlZmluZWQsIHVuZGVmaW5lZF1cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBub29wKCkge1xuICAgICAgLy8gTm8gb3BlcmF0aW9uIHBlcmZvcm1lZC5cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgZnVuY3Rpb24gdGhhdCBnZXRzIHRoZSBhcmd1bWVudCBhdCBpbmRleCBgbmAuIElmIGBuYCBpcyBuZWdhdGl2ZSxcbiAgICAgKiB0aGUgbnRoIGFyZ3VtZW50IGZyb20gdGhlIGVuZCBpcyByZXR1cm5lZC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjAuMFxuICAgICAqIEBjYXRlZ29yeSBVdGlsXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtuPTBdIFRoZSBpbmRleCBvZiB0aGUgYXJndW1lbnQgdG8gcmV0dXJuLlxuICAgICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IHBhc3MtdGhydSBmdW5jdGlvbi5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIGZ1bmMgPSBfLm50aEFyZygxKTtcbiAgICAgKiBmdW5jKCdhJywgJ2InLCAnYycsICdkJyk7XG4gICAgICogLy8gPT4gJ2InXG4gICAgICpcbiAgICAgKiB2YXIgZnVuYyA9IF8ubnRoQXJnKC0yKTtcbiAgICAgKiBmdW5jKCdhJywgJ2InLCAnYycsICdkJyk7XG4gICAgICogLy8gPT4gJ2MnXG4gICAgICovXG4gICAgZnVuY3Rpb24gbnRoQXJnKG4pIHtcbiAgICAgIG4gPSB0b0ludGVnZXIobik7XG4gICAgICByZXR1cm4gYmFzZVJlc3QoZnVuY3Rpb24oYXJncykge1xuICAgICAgICByZXR1cm4gYmFzZU50aChhcmdzLCBuKTtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBmdW5jdGlvbiB0aGF0IGludm9rZXMgYGl0ZXJhdGVlc2Agd2l0aCB0aGUgYXJndW1lbnRzIGl0IHJlY2VpdmVzXG4gICAgICogYW5kIHJldHVybnMgdGhlaXIgcmVzdWx0cy5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjAuMFxuICAgICAqIEBjYXRlZ29yeSBVdGlsXG4gICAgICogQHBhcmFtIHsuLi4oRnVuY3Rpb258RnVuY3Rpb25bXSl9IFtpdGVyYXRlZXM9W18uaWRlbnRpdHldXVxuICAgICAqICBUaGUgaXRlcmF0ZWVzIHRvIGludm9rZS5cbiAgICAgKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBmdW5jdGlvbi5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIGZ1bmMgPSBfLm92ZXIoW01hdGgubWF4LCBNYXRoLm1pbl0pO1xuICAgICAqXG4gICAgICogZnVuYygxLCAyLCAzLCA0KTtcbiAgICAgKiAvLyA9PiBbNCwgMV1cbiAgICAgKi9cbiAgICB2YXIgb3ZlciA9IGNyZWF0ZU92ZXIoYXJyYXlNYXApO1xuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIGZ1bmN0aW9uIHRoYXQgY2hlY2tzIGlmICoqYWxsKiogb2YgdGhlIGBwcmVkaWNhdGVzYCByZXR1cm5cbiAgICAgKiB0cnV0aHkgd2hlbiBpbnZva2VkIHdpdGggdGhlIGFyZ3VtZW50cyBpdCByZWNlaXZlcy5cbiAgICAgKlxuICAgICAqIEZvbGxvd2luZyBzaG9ydGhhbmRzIGFyZSBwb3NzaWJsZSBmb3IgcHJvdmlkaW5nIHByZWRpY2F0ZXMuXG4gICAgICogUGFzcyBhbiBgT2JqZWN0YCBhbmQgaXQgd2lsbCBiZSB1c2VkIGFzIGFuIHBhcmFtZXRlciBmb3IgYF8ubWF0Y2hlc2AgdG8gY3JlYXRlIHRoZSBwcmVkaWNhdGUuXG4gICAgICogUGFzcyBhbiBgQXJyYXlgIG9mIHBhcmFtZXRlcnMgZm9yIGBfLm1hdGNoZXNQcm9wZXJ0eWAgYW5kIHRoZSBwcmVkaWNhdGUgd2lsbCBiZSBjcmVhdGVkIHVzaW5nIHRoZW0uXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgVXRpbFxuICAgICAqIEBwYXJhbSB7Li4uKEZ1bmN0aW9ufEZ1bmN0aW9uW10pfSBbcHJlZGljYXRlcz1bXy5pZGVudGl0eV1dXG4gICAgICogIFRoZSBwcmVkaWNhdGVzIHRvIGNoZWNrLlxuICAgICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IGZ1bmN0aW9uLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgZnVuYyA9IF8ub3ZlckV2ZXJ5KFtCb29sZWFuLCBpc0Zpbml0ZV0pO1xuICAgICAqXG4gICAgICogZnVuYygnMScpO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKlxuICAgICAqIGZ1bmMobnVsbCk7XG4gICAgICogLy8gPT4gZmFsc2VcbiAgICAgKlxuICAgICAqIGZ1bmMoTmFOKTtcbiAgICAgKiAvLyA9PiBmYWxzZVxuICAgICAqL1xuICAgIHZhciBvdmVyRXZlcnkgPSBjcmVhdGVPdmVyKGFycmF5RXZlcnkpO1xuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIGZ1bmN0aW9uIHRoYXQgY2hlY2tzIGlmICoqYW55Kiogb2YgdGhlIGBwcmVkaWNhdGVzYCByZXR1cm5cbiAgICAgKiB0cnV0aHkgd2hlbiBpbnZva2VkIHdpdGggdGhlIGFyZ3VtZW50cyBpdCByZWNlaXZlcy5cbiAgICAgKlxuICAgICAqIEZvbGxvd2luZyBzaG9ydGhhbmRzIGFyZSBwb3NzaWJsZSBmb3IgcHJvdmlkaW5nIHByZWRpY2F0ZXMuXG4gICAgICogUGFzcyBhbiBgT2JqZWN0YCBhbmQgaXQgd2lsbCBiZSB1c2VkIGFzIGFuIHBhcmFtZXRlciBmb3IgYF8ubWF0Y2hlc2AgdG8gY3JlYXRlIHRoZSBwcmVkaWNhdGUuXG4gICAgICogUGFzcyBhbiBgQXJyYXlgIG9mIHBhcmFtZXRlcnMgZm9yIGBfLm1hdGNoZXNQcm9wZXJ0eWAgYW5kIHRoZSBwcmVkaWNhdGUgd2lsbCBiZSBjcmVhdGVkIHVzaW5nIHRoZW0uXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgVXRpbFxuICAgICAqIEBwYXJhbSB7Li4uKEZ1bmN0aW9ufEZ1bmN0aW9uW10pfSBbcHJlZGljYXRlcz1bXy5pZGVudGl0eV1dXG4gICAgICogIFRoZSBwcmVkaWNhdGVzIHRvIGNoZWNrLlxuICAgICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IGZ1bmN0aW9uLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgZnVuYyA9IF8ub3ZlclNvbWUoW0Jvb2xlYW4sIGlzRmluaXRlXSk7XG4gICAgICpcbiAgICAgKiBmdW5jKCcxJyk7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqXG4gICAgICogZnVuYyhudWxsKTtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICpcbiAgICAgKiBmdW5jKE5hTik7XG4gICAgICogLy8gPT4gZmFsc2VcbiAgICAgKlxuICAgICAqIHZhciBtYXRjaGVzRnVuYyA9IF8ub3ZlclNvbWUoW3sgJ2EnOiAxIH0sIHsgJ2EnOiAyIH1dKVxuICAgICAqIHZhciBtYXRjaGVzUHJvcGVydHlGdW5jID0gXy5vdmVyU29tZShbWydhJywgMV0sIFsnYScsIDJdXSlcbiAgICAgKi9cbiAgICB2YXIgb3ZlclNvbWUgPSBjcmVhdGVPdmVyKGFycmF5U29tZSk7XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgZnVuY3Rpb24gdGhhdCByZXR1cm5zIHRoZSB2YWx1ZSBhdCBgcGF0aGAgb2YgYSBnaXZlbiBvYmplY3QuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMi40LjBcbiAgICAgKiBAY2F0ZWdvcnkgVXRpbFxuICAgICAqIEBwYXJhbSB7QXJyYXl8c3RyaW5nfSBwYXRoIFRoZSBwYXRoIG9mIHRoZSBwcm9wZXJ0eSB0byBnZXQuXG4gICAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgYWNjZXNzb3IgZnVuY3Rpb24uXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciBvYmplY3RzID0gW1xuICAgICAqICAgeyAnYSc6IHsgJ2InOiAyIH0gfSxcbiAgICAgKiAgIHsgJ2EnOiB7ICdiJzogMSB9IH1cbiAgICAgKiBdO1xuICAgICAqXG4gICAgICogXy5tYXAob2JqZWN0cywgXy5wcm9wZXJ0eSgnYS5iJykpO1xuICAgICAqIC8vID0+IFsyLCAxXVxuICAgICAqXG4gICAgICogXy5tYXAoXy5zb3J0Qnkob2JqZWN0cywgXy5wcm9wZXJ0eShbJ2EnLCAnYiddKSksICdhLmInKTtcbiAgICAgKiAvLyA9PiBbMSwgMl1cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBwcm9wZXJ0eShwYXRoKSB7XG4gICAgICByZXR1cm4gaXNLZXkocGF0aCkgPyBiYXNlUHJvcGVydHkodG9LZXkocGF0aCkpIDogYmFzZVByb3BlcnR5RGVlcChwYXRoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgb3Bwb3NpdGUgb2YgYF8ucHJvcGVydHlgOyB0aGlzIG1ldGhvZCBjcmVhdGVzIGEgZnVuY3Rpb24gdGhhdCByZXR1cm5zXG4gICAgICogdGhlIHZhbHVlIGF0IGEgZ2l2ZW4gcGF0aCBvZiBgb2JqZWN0YC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAzLjAuMFxuICAgICAqIEBjYXRlZ29yeSBVdGlsXG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIHF1ZXJ5LlxuICAgICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IGFjY2Vzc29yIGZ1bmN0aW9uLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgYXJyYXkgPSBbMCwgMSwgMl0sXG4gICAgICogICAgIG9iamVjdCA9IHsgJ2EnOiBhcnJheSwgJ2InOiBhcnJheSwgJ2MnOiBhcnJheSB9O1xuICAgICAqXG4gICAgICogXy5tYXAoWydhWzJdJywgJ2NbMF0nXSwgXy5wcm9wZXJ0eU9mKG9iamVjdCkpO1xuICAgICAqIC8vID0+IFsyLCAwXVxuICAgICAqXG4gICAgICogXy5tYXAoW1snYScsICcyJ10sIFsnYycsICcwJ11dLCBfLnByb3BlcnR5T2Yob2JqZWN0KSk7XG4gICAgICogLy8gPT4gWzIsIDBdXG4gICAgICovXG4gICAgZnVuY3Rpb24gcHJvcGVydHlPZihvYmplY3QpIHtcbiAgICAgIHJldHVybiBmdW5jdGlvbihwYXRoKSB7XG4gICAgICAgIHJldHVybiBvYmplY3QgPT0gbnVsbCA/IHVuZGVmaW5lZCA6IGJhc2VHZXQob2JqZWN0LCBwYXRoKTtcbiAgICAgIH07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhbiBhcnJheSBvZiBudW1iZXJzIChwb3NpdGl2ZSBhbmQvb3IgbmVnYXRpdmUpIHByb2dyZXNzaW5nIGZyb21cbiAgICAgKiBgc3RhcnRgIHVwIHRvLCBidXQgbm90IGluY2x1ZGluZywgYGVuZGAuIEEgc3RlcCBvZiBgLTFgIGlzIHVzZWQgaWYgYSBuZWdhdGl2ZVxuICAgICAqIGBzdGFydGAgaXMgc3BlY2lmaWVkIHdpdGhvdXQgYW4gYGVuZGAgb3IgYHN0ZXBgLiBJZiBgZW5kYCBpcyBub3Qgc3BlY2lmaWVkLFxuICAgICAqIGl0J3Mgc2V0IHRvIGBzdGFydGAgd2l0aCBgc3RhcnRgIHRoZW4gc2V0IHRvIGAwYC5cbiAgICAgKlxuICAgICAqICoqTm90ZToqKiBKYXZhU2NyaXB0IGZvbGxvd3MgdGhlIElFRUUtNzU0IHN0YW5kYXJkIGZvciByZXNvbHZpbmdcbiAgICAgKiBmbG9hdGluZy1wb2ludCB2YWx1ZXMgd2hpY2ggY2FuIHByb2R1Y2UgdW5leHBlY3RlZCByZXN1bHRzLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBzaW5jZSAwLjEuMFxuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQGNhdGVnb3J5IFV0aWxcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW3N0YXJ0PTBdIFRoZSBzdGFydCBvZiB0aGUgcmFuZ2UuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IGVuZCBUaGUgZW5kIG9mIHRoZSByYW5nZS5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW3N0ZXA9MV0gVGhlIHZhbHVlIHRvIGluY3JlbWVudCBvciBkZWNyZW1lbnQgYnkuXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSByYW5nZSBvZiBudW1iZXJzLlxuICAgICAqIEBzZWUgXy5pblJhbmdlLCBfLnJhbmdlUmlnaHRcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5yYW5nZSg0KTtcbiAgICAgKiAvLyA9PiBbMCwgMSwgMiwgM11cbiAgICAgKlxuICAgICAqIF8ucmFuZ2UoLTQpO1xuICAgICAqIC8vID0+IFswLCAtMSwgLTIsIC0zXVxuICAgICAqXG4gICAgICogXy5yYW5nZSgxLCA1KTtcbiAgICAgKiAvLyA9PiBbMSwgMiwgMywgNF1cbiAgICAgKlxuICAgICAqIF8ucmFuZ2UoMCwgMjAsIDUpO1xuICAgICAqIC8vID0+IFswLCA1LCAxMCwgMTVdXG4gICAgICpcbiAgICAgKiBfLnJhbmdlKDAsIC00LCAtMSk7XG4gICAgICogLy8gPT4gWzAsIC0xLCAtMiwgLTNdXG4gICAgICpcbiAgICAgKiBfLnJhbmdlKDEsIDQsIDApO1xuICAgICAqIC8vID0+IFsxLCAxLCAxXVxuICAgICAqXG4gICAgICogXy5yYW5nZSgwKTtcbiAgICAgKiAvLyA9PiBbXVxuICAgICAqL1xuICAgIHZhciByYW5nZSA9IGNyZWF0ZVJhbmdlKCk7XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIG1ldGhvZCBpcyBsaWtlIGBfLnJhbmdlYCBleGNlcHQgdGhhdCBpdCBwb3B1bGF0ZXMgdmFsdWVzIGluXG4gICAgICogZGVzY2VuZGluZyBvcmRlci5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjAuMFxuICAgICAqIEBjYXRlZ29yeSBVdGlsXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtzdGFydD0wXSBUaGUgc3RhcnQgb2YgdGhlIHJhbmdlLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBlbmQgVGhlIGVuZCBvZiB0aGUgcmFuZ2UuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtzdGVwPTFdIFRoZSB2YWx1ZSB0byBpbmNyZW1lbnQgb3IgZGVjcmVtZW50IGJ5LlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgcmFuZ2Ugb2YgbnVtYmVycy5cbiAgICAgKiBAc2VlIF8uaW5SYW5nZSwgXy5yYW5nZVxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLnJhbmdlUmlnaHQoNCk7XG4gICAgICogLy8gPT4gWzMsIDIsIDEsIDBdXG4gICAgICpcbiAgICAgKiBfLnJhbmdlUmlnaHQoLTQpO1xuICAgICAqIC8vID0+IFstMywgLTIsIC0xLCAwXVxuICAgICAqXG4gICAgICogXy5yYW5nZVJpZ2h0KDEsIDUpO1xuICAgICAqIC8vID0+IFs0LCAzLCAyLCAxXVxuICAgICAqXG4gICAgICogXy5yYW5nZVJpZ2h0KDAsIDIwLCA1KTtcbiAgICAgKiAvLyA9PiBbMTUsIDEwLCA1LCAwXVxuICAgICAqXG4gICAgICogXy5yYW5nZVJpZ2h0KDAsIC00LCAtMSk7XG4gICAgICogLy8gPT4gWy0zLCAtMiwgLTEsIDBdXG4gICAgICpcbiAgICAgKiBfLnJhbmdlUmlnaHQoMSwgNCwgMCk7XG4gICAgICogLy8gPT4gWzEsIDEsIDFdXG4gICAgICpcbiAgICAgKiBfLnJhbmdlUmlnaHQoMCk7XG4gICAgICogLy8gPT4gW11cbiAgICAgKi9cbiAgICB2YXIgcmFuZ2VSaWdodCA9IGNyZWF0ZVJhbmdlKHRydWUpO1xuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgcmV0dXJucyBhIG5ldyBlbXB0eSBhcnJheS5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjEzLjBcbiAgICAgKiBAY2F0ZWdvcnkgVXRpbFxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IGVtcHR5IGFycmF5LlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgYXJyYXlzID0gXy50aW1lcygyLCBfLnN0dWJBcnJheSk7XG4gICAgICpcbiAgICAgKiBjb25zb2xlLmxvZyhhcnJheXMpO1xuICAgICAqIC8vID0+IFtbXSwgW11dXG4gICAgICpcbiAgICAgKiBjb25zb2xlLmxvZyhhcnJheXNbMF0gPT09IGFycmF5c1sxXSk7XG4gICAgICogLy8gPT4gZmFsc2VcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBzdHViQXJyYXkoKSB7XG4gICAgICByZXR1cm4gW107XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgcmV0dXJucyBgZmFsc2VgLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMTMuMFxuICAgICAqIEBjYXRlZ29yeSBVdGlsXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYGZhbHNlYC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy50aW1lcygyLCBfLnN0dWJGYWxzZSk7XG4gICAgICogLy8gPT4gW2ZhbHNlLCBmYWxzZV1cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBzdHViRmFsc2UoKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgcmV0dXJucyBhIG5ldyBlbXB0eSBvYmplY3QuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4xMy4wXG4gICAgICogQGNhdGVnb3J5IFV0aWxcbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIHRoZSBuZXcgZW1wdHkgb2JqZWN0LlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgb2JqZWN0cyA9IF8udGltZXMoMiwgXy5zdHViT2JqZWN0KTtcbiAgICAgKlxuICAgICAqIGNvbnNvbGUubG9nKG9iamVjdHMpO1xuICAgICAqIC8vID0+IFt7fSwge31dXG4gICAgICpcbiAgICAgKiBjb25zb2xlLmxvZyhvYmplY3RzWzBdID09PSBvYmplY3RzWzFdKTtcbiAgICAgKiAvLyA9PiBmYWxzZVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIHN0dWJPYmplY3QoKSB7XG4gICAgICByZXR1cm4ge307XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgcmV0dXJucyBhbiBlbXB0eSBzdHJpbmcuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4xMy4wXG4gICAgICogQGNhdGVnb3J5IFV0aWxcbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfSBSZXR1cm5zIHRoZSBlbXB0eSBzdHJpbmcuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8udGltZXMoMiwgXy5zdHViU3RyaW5nKTtcbiAgICAgKiAvLyA9PiBbJycsICcnXVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIHN0dWJTdHJpbmcoKSB7XG4gICAgICByZXR1cm4gJyc7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgcmV0dXJucyBgdHJ1ZWAuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4xMy4wXG4gICAgICogQGNhdGVnb3J5IFV0aWxcbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8udGltZXMoMiwgXy5zdHViVHJ1ZSk7XG4gICAgICogLy8gPT4gW3RydWUsIHRydWVdXG4gICAgICovXG4gICAgZnVuY3Rpb24gc3R1YlRydWUoKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBJbnZva2VzIHRoZSBpdGVyYXRlZSBgbmAgdGltZXMsIHJldHVybmluZyBhbiBhcnJheSBvZiB0aGUgcmVzdWx0cyBvZlxuICAgICAqIGVhY2ggaW52b2NhdGlvbi4gVGhlIGl0ZXJhdGVlIGlzIGludm9rZWQgd2l0aCBvbmUgYXJndW1lbnQ7IChpbmRleCkuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQHNpbmNlIDAuMS4wXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAY2F0ZWdvcnkgVXRpbFxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBuIFRoZSBudW1iZXIgb2YgdGltZXMgdG8gaW52b2tlIGBpdGVyYXRlZWAuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW2l0ZXJhdGVlPV8uaWRlbnRpdHldIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBhcnJheSBvZiByZXN1bHRzLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLnRpbWVzKDMsIFN0cmluZyk7XG4gICAgICogLy8gPT4gWycwJywgJzEnLCAnMiddXG4gICAgICpcbiAgICAgKiAgXy50aW1lcyg0LCBfLmNvbnN0YW50KDApKTtcbiAgICAgKiAvLyA9PiBbMCwgMCwgMCwgMF1cbiAgICAgKi9cbiAgICBmdW5jdGlvbiB0aW1lcyhuLCBpdGVyYXRlZSkge1xuICAgICAgbiA9IHRvSW50ZWdlcihuKTtcbiAgICAgIGlmIChuIDwgMSB8fCBuID4gTUFYX1NBRkVfSU5URUdFUikge1xuICAgICAgICByZXR1cm4gW107XG4gICAgICB9XG4gICAgICB2YXIgaW5kZXggPSBNQVhfQVJSQVlfTEVOR1RILFxuICAgICAgICAgIGxlbmd0aCA9IG5hdGl2ZU1pbihuLCBNQVhfQVJSQVlfTEVOR1RIKTtcblxuICAgICAgaXRlcmF0ZWUgPSBnZXRJdGVyYXRlZShpdGVyYXRlZSk7XG4gICAgICBuIC09IE1BWF9BUlJBWV9MRU5HVEg7XG5cbiAgICAgIHZhciByZXN1bHQgPSBiYXNlVGltZXMobGVuZ3RoLCBpdGVyYXRlZSk7XG4gICAgICB3aGlsZSAoKytpbmRleCA8IG4pIHtcbiAgICAgICAgaXRlcmF0ZWUoaW5kZXgpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDb252ZXJ0cyBgdmFsdWVgIHRvIGEgcHJvcGVydHkgcGF0aCBhcnJheS5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjAuMFxuICAgICAqIEBjYXRlZ29yeSBVdGlsXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY29udmVydC5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIG5ldyBwcm9wZXJ0eSBwYXRoIGFycmF5LlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLnRvUGF0aCgnYS5iLmMnKTtcbiAgICAgKiAvLyA9PiBbJ2EnLCAnYicsICdjJ11cbiAgICAgKlxuICAgICAqIF8udG9QYXRoKCdhWzBdLmIuYycpO1xuICAgICAqIC8vID0+IFsnYScsICcwJywgJ2InLCAnYyddXG4gICAgICovXG4gICAgZnVuY3Rpb24gdG9QYXRoKHZhbHVlKSB7XG4gICAgICBpZiAoaXNBcnJheSh2YWx1ZSkpIHtcbiAgICAgICAgcmV0dXJuIGFycmF5TWFwKHZhbHVlLCB0b0tleSk7XG4gICAgICB9XG4gICAgICByZXR1cm4gaXNTeW1ib2wodmFsdWUpID8gW3ZhbHVlXSA6IGNvcHlBcnJheShzdHJpbmdUb1BhdGgodG9TdHJpbmcodmFsdWUpKSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2VuZXJhdGVzIGEgdW5pcXVlIElELiBJZiBgcHJlZml4YCBpcyBnaXZlbiwgdGhlIElEIGlzIGFwcGVuZGVkIHRvIGl0LlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBzaW5jZSAwLjEuMFxuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQGNhdGVnb3J5IFV0aWxcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gW3ByZWZpeD0nJ10gVGhlIHZhbHVlIHRvIHByZWZpeCB0aGUgSUQgd2l0aC5cbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfSBSZXR1cm5zIHRoZSB1bmlxdWUgSUQuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8udW5pcXVlSWQoJ2NvbnRhY3RfJyk7XG4gICAgICogLy8gPT4gJ2NvbnRhY3RfMTA0J1xuICAgICAqXG4gICAgICogXy51bmlxdWVJZCgpO1xuICAgICAqIC8vID0+ICcxMDUnXG4gICAgICovXG4gICAgZnVuY3Rpb24gdW5pcXVlSWQocHJlZml4KSB7XG4gICAgICB2YXIgaWQgPSArK2lkQ291bnRlcjtcbiAgICAgIHJldHVybiB0b1N0cmluZyhwcmVmaXgpICsgaWQ7XG4gICAgfVxuXG4gICAgLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuXG4gICAgLyoqXG4gICAgICogQWRkcyB0d28gbnVtYmVycy5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAzLjQuMFxuICAgICAqIEBjYXRlZ29yeSBNYXRoXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IGF1Z2VuZCBUaGUgZmlyc3QgbnVtYmVyIGluIGFuIGFkZGl0aW9uLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBhZGRlbmQgVGhlIHNlY29uZCBudW1iZXIgaW4gYW4gYWRkaXRpb24uXG4gICAgICogQHJldHVybnMge251bWJlcn0gUmV0dXJucyB0aGUgdG90YWwuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uYWRkKDYsIDQpO1xuICAgICAqIC8vID0+IDEwXG4gICAgICovXG4gICAgdmFyIGFkZCA9IGNyZWF0ZU1hdGhPcGVyYXRpb24oZnVuY3Rpb24oYXVnZW5kLCBhZGRlbmQpIHtcbiAgICAgIHJldHVybiBhdWdlbmQgKyBhZGRlbmQ7XG4gICAgfSwgMCk7XG5cbiAgICAvKipcbiAgICAgKiBDb21wdXRlcyBgbnVtYmVyYCByb3VuZGVkIHVwIHRvIGBwcmVjaXNpb25gLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDMuMTAuMFxuICAgICAqIEBjYXRlZ29yeSBNYXRoXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IG51bWJlciBUaGUgbnVtYmVyIHRvIHJvdW5kIHVwLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbcHJlY2lzaW9uPTBdIFRoZSBwcmVjaXNpb24gdG8gcm91bmQgdXAgdG8uXG4gICAgICogQHJldHVybnMge251bWJlcn0gUmV0dXJucyB0aGUgcm91bmRlZCB1cCBudW1iZXIuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uY2VpbCg0LjAwNik7XG4gICAgICogLy8gPT4gNVxuICAgICAqXG4gICAgICogXy5jZWlsKDYuMDA0LCAyKTtcbiAgICAgKiAvLyA9PiA2LjAxXG4gICAgICpcbiAgICAgKiBfLmNlaWwoNjA0MCwgLTIpO1xuICAgICAqIC8vID0+IDYxMDBcbiAgICAgKi9cbiAgICB2YXIgY2VpbCA9IGNyZWF0ZVJvdW5kKCdjZWlsJyk7XG5cbiAgICAvKipcbiAgICAgKiBEaXZpZGUgdHdvIG51bWJlcnMuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC43LjBcbiAgICAgKiBAY2F0ZWdvcnkgTWF0aFxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBkaXZpZGVuZCBUaGUgZmlyc3QgbnVtYmVyIGluIGEgZGl2aXNpb24uXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IGRpdmlzb3IgVGhlIHNlY29uZCBudW1iZXIgaW4gYSBkaXZpc2lvbi5cbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBSZXR1cm5zIHRoZSBxdW90aWVudC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5kaXZpZGUoNiwgNCk7XG4gICAgICogLy8gPT4gMS41XG4gICAgICovXG4gICAgdmFyIGRpdmlkZSA9IGNyZWF0ZU1hdGhPcGVyYXRpb24oZnVuY3Rpb24oZGl2aWRlbmQsIGRpdmlzb3IpIHtcbiAgICAgIHJldHVybiBkaXZpZGVuZCAvIGRpdmlzb3I7XG4gICAgfSwgMSk7XG5cbiAgICAvKipcbiAgICAgKiBDb21wdXRlcyBgbnVtYmVyYCByb3VuZGVkIGRvd24gdG8gYHByZWNpc2lvbmAuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMy4xMC4wXG4gICAgICogQGNhdGVnb3J5IE1hdGhcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gbnVtYmVyIFRoZSBudW1iZXIgdG8gcm91bmQgZG93bi5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW3ByZWNpc2lvbj0wXSBUaGUgcHJlY2lzaW9uIHRvIHJvdW5kIGRvd24gdG8uXG4gICAgICogQHJldHVybnMge251bWJlcn0gUmV0dXJucyB0aGUgcm91bmRlZCBkb3duIG51bWJlci5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5mbG9vcig0LjAwNik7XG4gICAgICogLy8gPT4gNFxuICAgICAqXG4gICAgICogXy5mbG9vcigwLjA0NiwgMik7XG4gICAgICogLy8gPT4gMC4wNFxuICAgICAqXG4gICAgICogXy5mbG9vcig0MDYwLCAtMik7XG4gICAgICogLy8gPT4gNDAwMFxuICAgICAqL1xuICAgIHZhciBmbG9vciA9IGNyZWF0ZVJvdW5kKCdmbG9vcicpO1xuXG4gICAgLyoqXG4gICAgICogQ29tcHV0ZXMgdGhlIG1heGltdW0gdmFsdWUgb2YgYGFycmF5YC4gSWYgYGFycmF5YCBpcyBlbXB0eSBvciBmYWxzZXksXG4gICAgICogYHVuZGVmaW5lZGAgaXMgcmV0dXJuZWQuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQHNpbmNlIDAuMS4wXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAY2F0ZWdvcnkgTWF0aFxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBpdGVyYXRlIG92ZXIuXG4gICAgICogQHJldHVybnMgeyp9IFJldHVybnMgdGhlIG1heGltdW0gdmFsdWUuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8ubWF4KFs0LCAyLCA4LCA2XSk7XG4gICAgICogLy8gPT4gOFxuICAgICAqXG4gICAgICogXy5tYXgoW10pO1xuICAgICAqIC8vID0+IHVuZGVmaW5lZFxuICAgICAqL1xuICAgIGZ1bmN0aW9uIG1heChhcnJheSkge1xuICAgICAgcmV0dXJuIChhcnJheSAmJiBhcnJheS5sZW5ndGgpXG4gICAgICAgID8gYmFzZUV4dHJlbXVtKGFycmF5LCBpZGVudGl0eSwgYmFzZUd0KVxuICAgICAgICA6IHVuZGVmaW5lZDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIG1ldGhvZCBpcyBsaWtlIGBfLm1heGAgZXhjZXB0IHRoYXQgaXQgYWNjZXB0cyBgaXRlcmF0ZWVgIHdoaWNoIGlzXG4gICAgICogaW52b2tlZCBmb3IgZWFjaCBlbGVtZW50IGluIGBhcnJheWAgdG8gZ2VuZXJhdGUgdGhlIGNyaXRlcmlvbiBieSB3aGljaFxuICAgICAqIHRoZSB2YWx1ZSBpcyByYW5rZWQuIFRoZSBpdGVyYXRlZSBpcyBpbnZva2VkIHdpdGggb25lIGFyZ3VtZW50OiAodmFsdWUpLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMC4wXG4gICAgICogQGNhdGVnb3J5IE1hdGhcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gaXRlcmF0ZSBvdmVyLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IFtpdGVyYXRlZT1fLmlkZW50aXR5XSBUaGUgaXRlcmF0ZWUgaW52b2tlZCBwZXIgZWxlbWVudC5cbiAgICAgKiBAcmV0dXJucyB7Kn0gUmV0dXJucyB0aGUgbWF4aW11bSB2YWx1ZS5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIG9iamVjdHMgPSBbeyAnbic6IDEgfSwgeyAnbic6IDIgfV07XG4gICAgICpcbiAgICAgKiBfLm1heEJ5KG9iamVjdHMsIGZ1bmN0aW9uKG8pIHsgcmV0dXJuIG8ubjsgfSk7XG4gICAgICogLy8gPT4geyAnbic6IDIgfVxuICAgICAqXG4gICAgICogLy8gVGhlIGBfLnByb3BlcnR5YCBpdGVyYXRlZSBzaG9ydGhhbmQuXG4gICAgICogXy5tYXhCeShvYmplY3RzLCAnbicpO1xuICAgICAqIC8vID0+IHsgJ24nOiAyIH1cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBtYXhCeShhcnJheSwgaXRlcmF0ZWUpIHtcbiAgICAgIHJldHVybiAoYXJyYXkgJiYgYXJyYXkubGVuZ3RoKVxuICAgICAgICA/IGJhc2VFeHRyZW11bShhcnJheSwgZ2V0SXRlcmF0ZWUoaXRlcmF0ZWUsIDIpLCBiYXNlR3QpXG4gICAgICAgIDogdW5kZWZpbmVkO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENvbXB1dGVzIHRoZSBtZWFuIG9mIHRoZSB2YWx1ZXMgaW4gYGFycmF5YC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjAuMFxuICAgICAqIEBjYXRlZ29yeSBNYXRoXG4gICAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIGl0ZXJhdGUgb3Zlci5cbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBSZXR1cm5zIHRoZSBtZWFuLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLm1lYW4oWzQsIDIsIDgsIDZdKTtcbiAgICAgKiAvLyA9PiA1XG4gICAgICovXG4gICAgZnVuY3Rpb24gbWVhbihhcnJheSkge1xuICAgICAgcmV0dXJuIGJhc2VNZWFuKGFycmF5LCBpZGVudGl0eSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgaXMgbGlrZSBgXy5tZWFuYCBleGNlcHQgdGhhdCBpdCBhY2NlcHRzIGBpdGVyYXRlZWAgd2hpY2ggaXNcbiAgICAgKiBpbnZva2VkIGZvciBlYWNoIGVsZW1lbnQgaW4gYGFycmF5YCB0byBnZW5lcmF0ZSB0aGUgdmFsdWUgdG8gYmUgYXZlcmFnZWQuXG4gICAgICogVGhlIGl0ZXJhdGVlIGlzIGludm9rZWQgd2l0aCBvbmUgYXJndW1lbnQ6ICh2YWx1ZSkuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC43LjBcbiAgICAgKiBAY2F0ZWdvcnkgTWF0aFxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBpdGVyYXRlIG92ZXIuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW2l0ZXJhdGVlPV8uaWRlbnRpdHldIFRoZSBpdGVyYXRlZSBpbnZva2VkIHBlciBlbGVtZW50LlxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9IFJldHVybnMgdGhlIG1lYW4uXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciBvYmplY3RzID0gW3sgJ24nOiA0IH0sIHsgJ24nOiAyIH0sIHsgJ24nOiA4IH0sIHsgJ24nOiA2IH1dO1xuICAgICAqXG4gICAgICogXy5tZWFuQnkob2JqZWN0cywgZnVuY3Rpb24obykgeyByZXR1cm4gby5uOyB9KTtcbiAgICAgKiAvLyA9PiA1XG4gICAgICpcbiAgICAgKiAvLyBUaGUgYF8ucHJvcGVydHlgIGl0ZXJhdGVlIHNob3J0aGFuZC5cbiAgICAgKiBfLm1lYW5CeShvYmplY3RzLCAnbicpO1xuICAgICAqIC8vID0+IDVcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBtZWFuQnkoYXJyYXksIGl0ZXJhdGVlKSB7XG4gICAgICByZXR1cm4gYmFzZU1lYW4oYXJyYXksIGdldEl0ZXJhdGVlKGl0ZXJhdGVlLCAyKSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ29tcHV0ZXMgdGhlIG1pbmltdW0gdmFsdWUgb2YgYGFycmF5YC4gSWYgYGFycmF5YCBpcyBlbXB0eSBvciBmYWxzZXksXG4gICAgICogYHVuZGVmaW5lZGAgaXMgcmV0dXJuZWQuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQHNpbmNlIDAuMS4wXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAY2F0ZWdvcnkgTWF0aFxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBpdGVyYXRlIG92ZXIuXG4gICAgICogQHJldHVybnMgeyp9IFJldHVybnMgdGhlIG1pbmltdW0gdmFsdWUuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8ubWluKFs0LCAyLCA4LCA2XSk7XG4gICAgICogLy8gPT4gMlxuICAgICAqXG4gICAgICogXy5taW4oW10pO1xuICAgICAqIC8vID0+IHVuZGVmaW5lZFxuICAgICAqL1xuICAgIGZ1bmN0aW9uIG1pbihhcnJheSkge1xuICAgICAgcmV0dXJuIChhcnJheSAmJiBhcnJheS5sZW5ndGgpXG4gICAgICAgID8gYmFzZUV4dHJlbXVtKGFycmF5LCBpZGVudGl0eSwgYmFzZUx0KVxuICAgICAgICA6IHVuZGVmaW5lZDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIG1ldGhvZCBpcyBsaWtlIGBfLm1pbmAgZXhjZXB0IHRoYXQgaXQgYWNjZXB0cyBgaXRlcmF0ZWVgIHdoaWNoIGlzXG4gICAgICogaW52b2tlZCBmb3IgZWFjaCBlbGVtZW50IGluIGBhcnJheWAgdG8gZ2VuZXJhdGUgdGhlIGNyaXRlcmlvbiBieSB3aGljaFxuICAgICAqIHRoZSB2YWx1ZSBpcyByYW5rZWQuIFRoZSBpdGVyYXRlZSBpcyBpbnZva2VkIHdpdGggb25lIGFyZ3VtZW50OiAodmFsdWUpLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMC4wXG4gICAgICogQGNhdGVnb3J5IE1hdGhcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gaXRlcmF0ZSBvdmVyLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IFtpdGVyYXRlZT1fLmlkZW50aXR5XSBUaGUgaXRlcmF0ZWUgaW52b2tlZCBwZXIgZWxlbWVudC5cbiAgICAgKiBAcmV0dXJucyB7Kn0gUmV0dXJucyB0aGUgbWluaW11bSB2YWx1ZS5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIG9iamVjdHMgPSBbeyAnbic6IDEgfSwgeyAnbic6IDIgfV07XG4gICAgICpcbiAgICAgKiBfLm1pbkJ5KG9iamVjdHMsIGZ1bmN0aW9uKG8pIHsgcmV0dXJuIG8ubjsgfSk7XG4gICAgICogLy8gPT4geyAnbic6IDEgfVxuICAgICAqXG4gICAgICogLy8gVGhlIGBfLnByb3BlcnR5YCBpdGVyYXRlZSBzaG9ydGhhbmQuXG4gICAgICogXy5taW5CeShvYmplY3RzLCAnbicpO1xuICAgICAqIC8vID0+IHsgJ24nOiAxIH1cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBtaW5CeShhcnJheSwgaXRlcmF0ZWUpIHtcbiAgICAgIHJldHVybiAoYXJyYXkgJiYgYXJyYXkubGVuZ3RoKVxuICAgICAgICA/IGJhc2VFeHRyZW11bShhcnJheSwgZ2V0SXRlcmF0ZWUoaXRlcmF0ZWUsIDIpLCBiYXNlTHQpXG4gICAgICAgIDogdW5kZWZpbmVkO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIE11bHRpcGx5IHR3byBudW1iZXJzLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuNy4wXG4gICAgICogQGNhdGVnb3J5IE1hdGhcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gbXVsdGlwbGllciBUaGUgZmlyc3QgbnVtYmVyIGluIGEgbXVsdGlwbGljYXRpb24uXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IG11bHRpcGxpY2FuZCBUaGUgc2Vjb25kIG51bWJlciBpbiBhIG11bHRpcGxpY2F0aW9uLlxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9IFJldHVybnMgdGhlIHByb2R1Y3QuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8ubXVsdGlwbHkoNiwgNCk7XG4gICAgICogLy8gPT4gMjRcbiAgICAgKi9cbiAgICB2YXIgbXVsdGlwbHkgPSBjcmVhdGVNYXRoT3BlcmF0aW9uKGZ1bmN0aW9uKG11bHRpcGxpZXIsIG11bHRpcGxpY2FuZCkge1xuICAgICAgcmV0dXJuIG11bHRpcGxpZXIgKiBtdWx0aXBsaWNhbmQ7XG4gICAgfSwgMSk7XG5cbiAgICAvKipcbiAgICAgKiBDb21wdXRlcyBgbnVtYmVyYCByb3VuZGVkIHRvIGBwcmVjaXNpb25gLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDMuMTAuMFxuICAgICAqIEBjYXRlZ29yeSBNYXRoXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IG51bWJlciBUaGUgbnVtYmVyIHRvIHJvdW5kLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbcHJlY2lzaW9uPTBdIFRoZSBwcmVjaXNpb24gdG8gcm91bmQgdG8uXG4gICAgICogQHJldHVybnMge251bWJlcn0gUmV0dXJucyB0aGUgcm91bmRlZCBudW1iZXIuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8ucm91bmQoNC4wMDYpO1xuICAgICAqIC8vID0+IDRcbiAgICAgKlxuICAgICAqIF8ucm91bmQoNC4wMDYsIDIpO1xuICAgICAqIC8vID0+IDQuMDFcbiAgICAgKlxuICAgICAqIF8ucm91bmQoNDA2MCwgLTIpO1xuICAgICAqIC8vID0+IDQxMDBcbiAgICAgKi9cbiAgICB2YXIgcm91bmQgPSBjcmVhdGVSb3VuZCgncm91bmQnKTtcblxuICAgIC8qKlxuICAgICAqIFN1YnRyYWN0IHR3byBudW1iZXJzLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMC4wXG4gICAgICogQGNhdGVnb3J5IE1hdGhcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gbWludWVuZCBUaGUgZmlyc3QgbnVtYmVyIGluIGEgc3VidHJhY3Rpb24uXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHN1YnRyYWhlbmQgVGhlIHNlY29uZCBudW1iZXIgaW4gYSBzdWJ0cmFjdGlvbi5cbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBSZXR1cm5zIHRoZSBkaWZmZXJlbmNlLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLnN1YnRyYWN0KDYsIDQpO1xuICAgICAqIC8vID0+IDJcbiAgICAgKi9cbiAgICB2YXIgc3VidHJhY3QgPSBjcmVhdGVNYXRoT3BlcmF0aW9uKGZ1bmN0aW9uKG1pbnVlbmQsIHN1YnRyYWhlbmQpIHtcbiAgICAgIHJldHVybiBtaW51ZW5kIC0gc3VidHJhaGVuZDtcbiAgICB9LCAwKTtcblxuICAgIC8qKlxuICAgICAqIENvbXB1dGVzIHRoZSBzdW0gb2YgdGhlIHZhbHVlcyBpbiBgYXJyYXlgLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDMuNC4wXG4gICAgICogQGNhdGVnb3J5IE1hdGhcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gaXRlcmF0ZSBvdmVyLlxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9IFJldHVybnMgdGhlIHN1bS5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5zdW0oWzQsIDIsIDgsIDZdKTtcbiAgICAgKiAvLyA9PiAyMFxuICAgICAqL1xuICAgIGZ1bmN0aW9uIHN1bShhcnJheSkge1xuICAgICAgcmV0dXJuIChhcnJheSAmJiBhcnJheS5sZW5ndGgpXG4gICAgICAgID8gYmFzZVN1bShhcnJheSwgaWRlbnRpdHkpXG4gICAgICAgIDogMDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIG1ldGhvZCBpcyBsaWtlIGBfLnN1bWAgZXhjZXB0IHRoYXQgaXQgYWNjZXB0cyBgaXRlcmF0ZWVgIHdoaWNoIGlzXG4gICAgICogaW52b2tlZCBmb3IgZWFjaCBlbGVtZW50IGluIGBhcnJheWAgdG8gZ2VuZXJhdGUgdGhlIHZhbHVlIHRvIGJlIHN1bW1lZC5cbiAgICAgKiBUaGUgaXRlcmF0ZWUgaXMgaW52b2tlZCB3aXRoIG9uZSBhcmd1bWVudDogKHZhbHVlKS5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjAuMFxuICAgICAqIEBjYXRlZ29yeSBNYXRoXG4gICAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIGl0ZXJhdGUgb3Zlci5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbaXRlcmF0ZWU9Xy5pZGVudGl0eV0gVGhlIGl0ZXJhdGVlIGludm9rZWQgcGVyIGVsZW1lbnQuXG4gICAgICogQHJldHVybnMge251bWJlcn0gUmV0dXJucyB0aGUgc3VtLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgb2JqZWN0cyA9IFt7ICduJzogNCB9LCB7ICduJzogMiB9LCB7ICduJzogOCB9LCB7ICduJzogNiB9XTtcbiAgICAgKlxuICAgICAqIF8uc3VtQnkob2JqZWN0cywgZnVuY3Rpb24obykgeyByZXR1cm4gby5uOyB9KTtcbiAgICAgKiAvLyA9PiAyMFxuICAgICAqXG4gICAgICogLy8gVGhlIGBfLnByb3BlcnR5YCBpdGVyYXRlZSBzaG9ydGhhbmQuXG4gICAgICogXy5zdW1CeShvYmplY3RzLCAnbicpO1xuICAgICAqIC8vID0+IDIwXG4gICAgICovXG4gICAgZnVuY3Rpb24gc3VtQnkoYXJyYXksIGl0ZXJhdGVlKSB7XG4gICAgICByZXR1cm4gKGFycmF5ICYmIGFycmF5Lmxlbmd0aClcbiAgICAgICAgPyBiYXNlU3VtKGFycmF5LCBnZXRJdGVyYXRlZShpdGVyYXRlZSwgMikpXG4gICAgICAgIDogMDtcbiAgICB9XG5cbiAgICAvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovXG5cbiAgICAvLyBBZGQgbWV0aG9kcyB0aGF0IHJldHVybiB3cmFwcGVkIHZhbHVlcyBpbiBjaGFpbiBzZXF1ZW5jZXMuXG4gICAgbG9kYXNoLmFmdGVyID0gYWZ0ZXI7XG4gICAgbG9kYXNoLmFyeSA9IGFyeTtcbiAgICBsb2Rhc2guYXNzaWduID0gYXNzaWduO1xuICAgIGxvZGFzaC5hc3NpZ25JbiA9IGFzc2lnbkluO1xuICAgIGxvZGFzaC5hc3NpZ25JbldpdGggPSBhc3NpZ25JbldpdGg7XG4gICAgbG9kYXNoLmFzc2lnbldpdGggPSBhc3NpZ25XaXRoO1xuICAgIGxvZGFzaC5hdCA9IGF0O1xuICAgIGxvZGFzaC5iZWZvcmUgPSBiZWZvcmU7XG4gICAgbG9kYXNoLmJpbmQgPSBiaW5kO1xuICAgIGxvZGFzaC5iaW5kQWxsID0gYmluZEFsbDtcbiAgICBsb2Rhc2guYmluZEtleSA9IGJpbmRLZXk7XG4gICAgbG9kYXNoLmNhc3RBcnJheSA9IGNhc3RBcnJheTtcbiAgICBsb2Rhc2guY2hhaW4gPSBjaGFpbjtcbiAgICBsb2Rhc2guY2h1bmsgPSBjaHVuaztcbiAgICBsb2Rhc2guY29tcGFjdCA9IGNvbXBhY3Q7XG4gICAgbG9kYXNoLmNvbmNhdCA9IGNvbmNhdDtcbiAgICBsb2Rhc2guY29uZCA9IGNvbmQ7XG4gICAgbG9kYXNoLmNvbmZvcm1zID0gY29uZm9ybXM7XG4gICAgbG9kYXNoLmNvbnN0YW50ID0gY29uc3RhbnQ7XG4gICAgbG9kYXNoLmNvdW50QnkgPSBjb3VudEJ5O1xuICAgIGxvZGFzaC5jcmVhdGUgPSBjcmVhdGU7XG4gICAgbG9kYXNoLmN1cnJ5ID0gY3Vycnk7XG4gICAgbG9kYXNoLmN1cnJ5UmlnaHQgPSBjdXJyeVJpZ2h0O1xuICAgIGxvZGFzaC5kZWJvdW5jZSA9IGRlYm91bmNlO1xuICAgIGxvZGFzaC5kZWZhdWx0cyA9IGRlZmF1bHRzO1xuICAgIGxvZGFzaC5kZWZhdWx0c0RlZXAgPSBkZWZhdWx0c0RlZXA7XG4gICAgbG9kYXNoLmRlZmVyID0gZGVmZXI7XG4gICAgbG9kYXNoLmRlbGF5ID0gZGVsYXk7XG4gICAgbG9kYXNoLmRpZmZlcmVuY2UgPSBkaWZmZXJlbmNlO1xuICAgIGxvZGFzaC5kaWZmZXJlbmNlQnkgPSBkaWZmZXJlbmNlQnk7XG4gICAgbG9kYXNoLmRpZmZlcmVuY2VXaXRoID0gZGlmZmVyZW5jZVdpdGg7XG4gICAgbG9kYXNoLmRyb3AgPSBkcm9wO1xuICAgIGxvZGFzaC5kcm9wUmlnaHQgPSBkcm9wUmlnaHQ7XG4gICAgbG9kYXNoLmRyb3BSaWdodFdoaWxlID0gZHJvcFJpZ2h0V2hpbGU7XG4gICAgbG9kYXNoLmRyb3BXaGlsZSA9IGRyb3BXaGlsZTtcbiAgICBsb2Rhc2guZmlsbCA9IGZpbGw7XG4gICAgbG9kYXNoLmZpbHRlciA9IGZpbHRlcjtcbiAgICBsb2Rhc2guZmxhdE1hcCA9IGZsYXRNYXA7XG4gICAgbG9kYXNoLmZsYXRNYXBEZWVwID0gZmxhdE1hcERlZXA7XG4gICAgbG9kYXNoLmZsYXRNYXBEZXB0aCA9IGZsYXRNYXBEZXB0aDtcbiAgICBsb2Rhc2guZmxhdHRlbiA9IGZsYXR0ZW47XG4gICAgbG9kYXNoLmZsYXR0ZW5EZWVwID0gZmxhdHRlbkRlZXA7XG4gICAgbG9kYXNoLmZsYXR0ZW5EZXB0aCA9IGZsYXR0ZW5EZXB0aDtcbiAgICBsb2Rhc2guZmxpcCA9IGZsaXA7XG4gICAgbG9kYXNoLmZsb3cgPSBmbG93O1xuICAgIGxvZGFzaC5mbG93UmlnaHQgPSBmbG93UmlnaHQ7XG4gICAgbG9kYXNoLmZyb21QYWlycyA9IGZyb21QYWlycztcbiAgICBsb2Rhc2guZnVuY3Rpb25zID0gZnVuY3Rpb25zO1xuICAgIGxvZGFzaC5mdW5jdGlvbnNJbiA9IGZ1bmN0aW9uc0luO1xuICAgIGxvZGFzaC5ncm91cEJ5ID0gZ3JvdXBCeTtcbiAgICBsb2Rhc2guaW5pdGlhbCA9IGluaXRpYWw7XG4gICAgbG9kYXNoLmludGVyc2VjdGlvbiA9IGludGVyc2VjdGlvbjtcbiAgICBsb2Rhc2guaW50ZXJzZWN0aW9uQnkgPSBpbnRlcnNlY3Rpb25CeTtcbiAgICBsb2Rhc2guaW50ZXJzZWN0aW9uV2l0aCA9IGludGVyc2VjdGlvbldpdGg7XG4gICAgbG9kYXNoLmludmVydCA9IGludmVydDtcbiAgICBsb2Rhc2guaW52ZXJ0QnkgPSBpbnZlcnRCeTtcbiAgICBsb2Rhc2guaW52b2tlTWFwID0gaW52b2tlTWFwO1xuICAgIGxvZGFzaC5pdGVyYXRlZSA9IGl0ZXJhdGVlO1xuICAgIGxvZGFzaC5rZXlCeSA9IGtleUJ5O1xuICAgIGxvZGFzaC5rZXlzID0ga2V5cztcbiAgICBsb2Rhc2gua2V5c0luID0ga2V5c0luO1xuICAgIGxvZGFzaC5tYXAgPSBtYXA7XG4gICAgbG9kYXNoLm1hcEtleXMgPSBtYXBLZXlzO1xuICAgIGxvZGFzaC5tYXBWYWx1ZXMgPSBtYXBWYWx1ZXM7XG4gICAgbG9kYXNoLm1hdGNoZXMgPSBtYXRjaGVzO1xuICAgIGxvZGFzaC5tYXRjaGVzUHJvcGVydHkgPSBtYXRjaGVzUHJvcGVydHk7XG4gICAgbG9kYXNoLm1lbW9pemUgPSBtZW1vaXplO1xuICAgIGxvZGFzaC5tZXJnZSA9IG1lcmdlO1xuICAgIGxvZGFzaC5tZXJnZVdpdGggPSBtZXJnZVdpdGg7XG4gICAgbG9kYXNoLm1ldGhvZCA9IG1ldGhvZDtcbiAgICBsb2Rhc2gubWV0aG9kT2YgPSBtZXRob2RPZjtcbiAgICBsb2Rhc2gubWl4aW4gPSBtaXhpbjtcbiAgICBsb2Rhc2gubmVnYXRlID0gbmVnYXRlO1xuICAgIGxvZGFzaC5udGhBcmcgPSBudGhBcmc7XG4gICAgbG9kYXNoLm9taXQgPSBvbWl0O1xuICAgIGxvZGFzaC5vbWl0QnkgPSBvbWl0Qnk7XG4gICAgbG9kYXNoLm9uY2UgPSBvbmNlO1xuICAgIGxvZGFzaC5vcmRlckJ5ID0gb3JkZXJCeTtcbiAgICBsb2Rhc2gub3ZlciA9IG92ZXI7XG4gICAgbG9kYXNoLm92ZXJBcmdzID0gb3ZlckFyZ3M7XG4gICAgbG9kYXNoLm92ZXJFdmVyeSA9IG92ZXJFdmVyeTtcbiAgICBsb2Rhc2gub3ZlclNvbWUgPSBvdmVyU29tZTtcbiAgICBsb2Rhc2gucGFydGlhbCA9IHBhcnRpYWw7XG4gICAgbG9kYXNoLnBhcnRpYWxSaWdodCA9IHBhcnRpYWxSaWdodDtcbiAgICBsb2Rhc2gucGFydGl0aW9uID0gcGFydGl0aW9uO1xuICAgIGxvZGFzaC5waWNrID0gcGljaztcbiAgICBsb2Rhc2gucGlja0J5ID0gcGlja0J5O1xuICAgIGxvZGFzaC5wcm9wZXJ0eSA9IHByb3BlcnR5O1xuICAgIGxvZGFzaC5wcm9wZXJ0eU9mID0gcHJvcGVydHlPZjtcbiAgICBsb2Rhc2gucHVsbCA9IHB1bGw7XG4gICAgbG9kYXNoLnB1bGxBbGwgPSBwdWxsQWxsO1xuICAgIGxvZGFzaC5wdWxsQWxsQnkgPSBwdWxsQWxsQnk7XG4gICAgbG9kYXNoLnB1bGxBbGxXaXRoID0gcHVsbEFsbFdpdGg7XG4gICAgbG9kYXNoLnB1bGxBdCA9IHB1bGxBdDtcbiAgICBsb2Rhc2gucmFuZ2UgPSByYW5nZTtcbiAgICBsb2Rhc2gucmFuZ2VSaWdodCA9IHJhbmdlUmlnaHQ7XG4gICAgbG9kYXNoLnJlYXJnID0gcmVhcmc7XG4gICAgbG9kYXNoLnJlamVjdCA9IHJlamVjdDtcbiAgICBsb2Rhc2gucmVtb3ZlID0gcmVtb3ZlO1xuICAgIGxvZGFzaC5yZXN0ID0gcmVzdDtcbiAgICBsb2Rhc2gucmV2ZXJzZSA9IHJldmVyc2U7XG4gICAgbG9kYXNoLnNhbXBsZVNpemUgPSBzYW1wbGVTaXplO1xuICAgIGxvZGFzaC5zZXQgPSBzZXQ7XG4gICAgbG9kYXNoLnNldFdpdGggPSBzZXRXaXRoO1xuICAgIGxvZGFzaC5zaHVmZmxlID0gc2h1ZmZsZTtcbiAgICBsb2Rhc2guc2xpY2UgPSBzbGljZTtcbiAgICBsb2Rhc2guc29ydEJ5ID0gc29ydEJ5O1xuICAgIGxvZGFzaC5zb3J0ZWRVbmlxID0gc29ydGVkVW5pcTtcbiAgICBsb2Rhc2guc29ydGVkVW5pcUJ5ID0gc29ydGVkVW5pcUJ5O1xuICAgIGxvZGFzaC5zcGxpdCA9IHNwbGl0O1xuICAgIGxvZGFzaC5zcHJlYWQgPSBzcHJlYWQ7XG4gICAgbG9kYXNoLnRhaWwgPSB0YWlsO1xuICAgIGxvZGFzaC50YWtlID0gdGFrZTtcbiAgICBsb2Rhc2gudGFrZVJpZ2h0ID0gdGFrZVJpZ2h0O1xuICAgIGxvZGFzaC50YWtlUmlnaHRXaGlsZSA9IHRha2VSaWdodFdoaWxlO1xuICAgIGxvZGFzaC50YWtlV2hpbGUgPSB0YWtlV2hpbGU7XG4gICAgbG9kYXNoLnRhcCA9IHRhcDtcbiAgICBsb2Rhc2gudGhyb3R0bGUgPSB0aHJvdHRsZTtcbiAgICBsb2Rhc2gudGhydSA9IHRocnU7XG4gICAgbG9kYXNoLnRvQXJyYXkgPSB0b0FycmF5O1xuICAgIGxvZGFzaC50b1BhaXJzID0gdG9QYWlycztcbiAgICBsb2Rhc2gudG9QYWlyc0luID0gdG9QYWlyc0luO1xuICAgIGxvZGFzaC50b1BhdGggPSB0b1BhdGg7XG4gICAgbG9kYXNoLnRvUGxhaW5PYmplY3QgPSB0b1BsYWluT2JqZWN0O1xuICAgIGxvZGFzaC50cmFuc2Zvcm0gPSB0cmFuc2Zvcm07XG4gICAgbG9kYXNoLnVuYXJ5ID0gdW5hcnk7XG4gICAgbG9kYXNoLnVuaW9uID0gdW5pb247XG4gICAgbG9kYXNoLnVuaW9uQnkgPSB1bmlvbkJ5O1xuICAgIGxvZGFzaC51bmlvbldpdGggPSB1bmlvbldpdGg7XG4gICAgbG9kYXNoLnVuaXEgPSB1bmlxO1xuICAgIGxvZGFzaC51bmlxQnkgPSB1bmlxQnk7XG4gICAgbG9kYXNoLnVuaXFXaXRoID0gdW5pcVdpdGg7XG4gICAgbG9kYXNoLnVuc2V0ID0gdW5zZXQ7XG4gICAgbG9kYXNoLnVuemlwID0gdW56aXA7XG4gICAgbG9kYXNoLnVuemlwV2l0aCA9IHVuemlwV2l0aDtcbiAgICBsb2Rhc2gudXBkYXRlID0gdXBkYXRlO1xuICAgIGxvZGFzaC51cGRhdGVXaXRoID0gdXBkYXRlV2l0aDtcbiAgICBsb2Rhc2gudmFsdWVzID0gdmFsdWVzO1xuICAgIGxvZGFzaC52YWx1ZXNJbiA9IHZhbHVlc0luO1xuICAgIGxvZGFzaC53aXRob3V0ID0gd2l0aG91dDtcbiAgICBsb2Rhc2gud29yZHMgPSB3b3JkcztcbiAgICBsb2Rhc2gud3JhcCA9IHdyYXA7XG4gICAgbG9kYXNoLnhvciA9IHhvcjtcbiAgICBsb2Rhc2gueG9yQnkgPSB4b3JCeTtcbiAgICBsb2Rhc2gueG9yV2l0aCA9IHhvcldpdGg7XG4gICAgbG9kYXNoLnppcCA9IHppcDtcbiAgICBsb2Rhc2guemlwT2JqZWN0ID0gemlwT2JqZWN0O1xuICAgIGxvZGFzaC56aXBPYmplY3REZWVwID0gemlwT2JqZWN0RGVlcDtcbiAgICBsb2Rhc2guemlwV2l0aCA9IHppcFdpdGg7XG5cbiAgICAvLyBBZGQgYWxpYXNlcy5cbiAgICBsb2Rhc2guZW50cmllcyA9IHRvUGFpcnM7XG4gICAgbG9kYXNoLmVudHJpZXNJbiA9IHRvUGFpcnNJbjtcbiAgICBsb2Rhc2guZXh0ZW5kID0gYXNzaWduSW47XG4gICAgbG9kYXNoLmV4dGVuZFdpdGggPSBhc3NpZ25JbldpdGg7XG5cbiAgICAvLyBBZGQgbWV0aG9kcyB0byBgbG9kYXNoLnByb3RvdHlwZWAuXG4gICAgbWl4aW4obG9kYXNoLCBsb2Rhc2gpO1xuXG4gICAgLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuXG4gICAgLy8gQWRkIG1ldGhvZHMgdGhhdCByZXR1cm4gdW53cmFwcGVkIHZhbHVlcyBpbiBjaGFpbiBzZXF1ZW5jZXMuXG4gICAgbG9kYXNoLmFkZCA9IGFkZDtcbiAgICBsb2Rhc2guYXR0ZW1wdCA9IGF0dGVtcHQ7XG4gICAgbG9kYXNoLmNhbWVsQ2FzZSA9IGNhbWVsQ2FzZTtcbiAgICBsb2Rhc2guY2FwaXRhbGl6ZSA9IGNhcGl0YWxpemU7XG4gICAgbG9kYXNoLmNlaWwgPSBjZWlsO1xuICAgIGxvZGFzaC5jbGFtcCA9IGNsYW1wO1xuICAgIGxvZGFzaC5jbG9uZSA9IGNsb25lO1xuICAgIGxvZGFzaC5jbG9uZURlZXAgPSBjbG9uZURlZXA7XG4gICAgbG9kYXNoLmNsb25lRGVlcFdpdGggPSBjbG9uZURlZXBXaXRoO1xuICAgIGxvZGFzaC5jbG9uZVdpdGggPSBjbG9uZVdpdGg7XG4gICAgbG9kYXNoLmNvbmZvcm1zVG8gPSBjb25mb3Jtc1RvO1xuICAgIGxvZGFzaC5kZWJ1cnIgPSBkZWJ1cnI7XG4gICAgbG9kYXNoLmRlZmF1bHRUbyA9IGRlZmF1bHRUbztcbiAgICBsb2Rhc2guZGl2aWRlID0gZGl2aWRlO1xuICAgIGxvZGFzaC5lbmRzV2l0aCA9IGVuZHNXaXRoO1xuICAgIGxvZGFzaC5lcSA9IGVxO1xuICAgIGxvZGFzaC5lc2NhcGUgPSBlc2NhcGU7XG4gICAgbG9kYXNoLmVzY2FwZVJlZ0V4cCA9IGVzY2FwZVJlZ0V4cDtcbiAgICBsb2Rhc2guZXZlcnkgPSBldmVyeTtcbiAgICBsb2Rhc2guZmluZCA9IGZpbmQ7XG4gICAgbG9kYXNoLmZpbmRJbmRleCA9IGZpbmRJbmRleDtcbiAgICBsb2Rhc2guZmluZEtleSA9IGZpbmRLZXk7XG4gICAgbG9kYXNoLmZpbmRMYXN0ID0gZmluZExhc3Q7XG4gICAgbG9kYXNoLmZpbmRMYXN0SW5kZXggPSBmaW5kTGFzdEluZGV4O1xuICAgIGxvZGFzaC5maW5kTGFzdEtleSA9IGZpbmRMYXN0S2V5O1xuICAgIGxvZGFzaC5mbG9vciA9IGZsb29yO1xuICAgIGxvZGFzaC5mb3JFYWNoID0gZm9yRWFjaDtcbiAgICBsb2Rhc2guZm9yRWFjaFJpZ2h0ID0gZm9yRWFjaFJpZ2h0O1xuICAgIGxvZGFzaC5mb3JJbiA9IGZvckluO1xuICAgIGxvZGFzaC5mb3JJblJpZ2h0ID0gZm9ySW5SaWdodDtcbiAgICBsb2Rhc2guZm9yT3duID0gZm9yT3duO1xuICAgIGxvZGFzaC5mb3JPd25SaWdodCA9IGZvck93blJpZ2h0O1xuICAgIGxvZGFzaC5nZXQgPSBnZXQ7XG4gICAgbG9kYXNoLmd0ID0gZ3Q7XG4gICAgbG9kYXNoLmd0ZSA9IGd0ZTtcbiAgICBsb2Rhc2guaGFzID0gaGFzO1xuICAgIGxvZGFzaC5oYXNJbiA9IGhhc0luO1xuICAgIGxvZGFzaC5oZWFkID0gaGVhZDtcbiAgICBsb2Rhc2guaWRlbnRpdHkgPSBpZGVudGl0eTtcbiAgICBsb2Rhc2guaW5jbHVkZXMgPSBpbmNsdWRlcztcbiAgICBsb2Rhc2guaW5kZXhPZiA9IGluZGV4T2Y7XG4gICAgbG9kYXNoLmluUmFuZ2UgPSBpblJhbmdlO1xuICAgIGxvZGFzaC5pbnZva2UgPSBpbnZva2U7XG4gICAgbG9kYXNoLmlzQXJndW1lbnRzID0gaXNBcmd1bWVudHM7XG4gICAgbG9kYXNoLmlzQXJyYXkgPSBpc0FycmF5O1xuICAgIGxvZGFzaC5pc0FycmF5QnVmZmVyID0gaXNBcnJheUJ1ZmZlcjtcbiAgICBsb2Rhc2guaXNBcnJheUxpa2UgPSBpc0FycmF5TGlrZTtcbiAgICBsb2Rhc2guaXNBcnJheUxpa2VPYmplY3QgPSBpc0FycmF5TGlrZU9iamVjdDtcbiAgICBsb2Rhc2guaXNCb29sZWFuID0gaXNCb29sZWFuO1xuICAgIGxvZGFzaC5pc0J1ZmZlciA9IGlzQnVmZmVyO1xuICAgIGxvZGFzaC5pc0RhdGUgPSBpc0RhdGU7XG4gICAgbG9kYXNoLmlzRWxlbWVudCA9IGlzRWxlbWVudDtcbiAgICBsb2Rhc2guaXNFbXB0eSA9IGlzRW1wdHk7XG4gICAgbG9kYXNoLmlzRXF1YWwgPSBpc0VxdWFsO1xuICAgIGxvZGFzaC5pc0VxdWFsV2l0aCA9IGlzRXF1YWxXaXRoO1xuICAgIGxvZGFzaC5pc0Vycm9yID0gaXNFcnJvcjtcbiAgICBsb2Rhc2guaXNGaW5pdGUgPSBpc0Zpbml0ZTtcbiAgICBsb2Rhc2guaXNGdW5jdGlvbiA9IGlzRnVuY3Rpb247XG4gICAgbG9kYXNoLmlzSW50ZWdlciA9IGlzSW50ZWdlcjtcbiAgICBsb2Rhc2guaXNMZW5ndGggPSBpc0xlbmd0aDtcbiAgICBsb2Rhc2guaXNNYXAgPSBpc01hcDtcbiAgICBsb2Rhc2guaXNNYXRjaCA9IGlzTWF0Y2g7XG4gICAgbG9kYXNoLmlzTWF0Y2hXaXRoID0gaXNNYXRjaFdpdGg7XG4gICAgbG9kYXNoLmlzTmFOID0gaXNOYU47XG4gICAgbG9kYXNoLmlzTmF0aXZlID0gaXNOYXRpdmU7XG4gICAgbG9kYXNoLmlzTmlsID0gaXNOaWw7XG4gICAgbG9kYXNoLmlzTnVsbCA9IGlzTnVsbDtcbiAgICBsb2Rhc2guaXNOdW1iZXIgPSBpc051bWJlcjtcbiAgICBsb2Rhc2guaXNPYmplY3QgPSBpc09iamVjdDtcbiAgICBsb2Rhc2guaXNPYmplY3RMaWtlID0gaXNPYmplY3RMaWtlO1xuICAgIGxvZGFzaC5pc1BsYWluT2JqZWN0ID0gaXNQbGFpbk9iamVjdDtcbiAgICBsb2Rhc2guaXNSZWdFeHAgPSBpc1JlZ0V4cDtcbiAgICBsb2Rhc2guaXNTYWZlSW50ZWdlciA9IGlzU2FmZUludGVnZXI7XG4gICAgbG9kYXNoLmlzU2V0ID0gaXNTZXQ7XG4gICAgbG9kYXNoLmlzU3RyaW5nID0gaXNTdHJpbmc7XG4gICAgbG9kYXNoLmlzU3ltYm9sID0gaXNTeW1ib2w7XG4gICAgbG9kYXNoLmlzVHlwZWRBcnJheSA9IGlzVHlwZWRBcnJheTtcbiAgICBsb2Rhc2guaXNVbmRlZmluZWQgPSBpc1VuZGVmaW5lZDtcbiAgICBsb2Rhc2guaXNXZWFrTWFwID0gaXNXZWFrTWFwO1xuICAgIGxvZGFzaC5pc1dlYWtTZXQgPSBpc1dlYWtTZXQ7XG4gICAgbG9kYXNoLmpvaW4gPSBqb2luO1xuICAgIGxvZGFzaC5rZWJhYkNhc2UgPSBrZWJhYkNhc2U7XG4gICAgbG9kYXNoLmxhc3QgPSBsYXN0O1xuICAgIGxvZGFzaC5sYXN0SW5kZXhPZiA9IGxhc3RJbmRleE9mO1xuICAgIGxvZGFzaC5sb3dlckNhc2UgPSBsb3dlckNhc2U7XG4gICAgbG9kYXNoLmxvd2VyRmlyc3QgPSBsb3dlckZpcnN0O1xuICAgIGxvZGFzaC5sdCA9IGx0O1xuICAgIGxvZGFzaC5sdGUgPSBsdGU7XG4gICAgbG9kYXNoLm1heCA9IG1heDtcbiAgICBsb2Rhc2gubWF4QnkgPSBtYXhCeTtcbiAgICBsb2Rhc2gubWVhbiA9IG1lYW47XG4gICAgbG9kYXNoLm1lYW5CeSA9IG1lYW5CeTtcbiAgICBsb2Rhc2gubWluID0gbWluO1xuICAgIGxvZGFzaC5taW5CeSA9IG1pbkJ5O1xuICAgIGxvZGFzaC5zdHViQXJyYXkgPSBzdHViQXJyYXk7XG4gICAgbG9kYXNoLnN0dWJGYWxzZSA9IHN0dWJGYWxzZTtcbiAgICBsb2Rhc2guc3R1Yk9iamVjdCA9IHN0dWJPYmplY3Q7XG4gICAgbG9kYXNoLnN0dWJTdHJpbmcgPSBzdHViU3RyaW5nO1xuICAgIGxvZGFzaC5zdHViVHJ1ZSA9IHN0dWJUcnVlO1xuICAgIGxvZGFzaC5tdWx0aXBseSA9IG11bHRpcGx5O1xuICAgIGxvZGFzaC5udGggPSBudGg7XG4gICAgbG9kYXNoLm5vQ29uZmxpY3QgPSBub0NvbmZsaWN0O1xuICAgIGxvZGFzaC5ub29wID0gbm9vcDtcbiAgICBsb2Rhc2gubm93ID0gbm93O1xuICAgIGxvZGFzaC5wYWQgPSBwYWQ7XG4gICAgbG9kYXNoLnBhZEVuZCA9IHBhZEVuZDtcbiAgICBsb2Rhc2gucGFkU3RhcnQgPSBwYWRTdGFydDtcbiAgICBsb2Rhc2gucGFyc2VJbnQgPSBwYXJzZUludDtcbiAgICBsb2Rhc2gucmFuZG9tID0gcmFuZG9tO1xuICAgIGxvZGFzaC5yZWR1Y2UgPSByZWR1Y2U7XG4gICAgbG9kYXNoLnJlZHVjZVJpZ2h0ID0gcmVkdWNlUmlnaHQ7XG4gICAgbG9kYXNoLnJlcGVhdCA9IHJlcGVhdDtcbiAgICBsb2Rhc2gucmVwbGFjZSA9IHJlcGxhY2U7XG4gICAgbG9kYXNoLnJlc3VsdCA9IHJlc3VsdDtcbiAgICBsb2Rhc2gucm91bmQgPSByb3VuZDtcbiAgICBsb2Rhc2gucnVuSW5Db250ZXh0ID0gcnVuSW5Db250ZXh0O1xuICAgIGxvZGFzaC5zYW1wbGUgPSBzYW1wbGU7XG4gICAgbG9kYXNoLnNpemUgPSBzaXplO1xuICAgIGxvZGFzaC5zbmFrZUNhc2UgPSBzbmFrZUNhc2U7XG4gICAgbG9kYXNoLnNvbWUgPSBzb21lO1xuICAgIGxvZGFzaC5zb3J0ZWRJbmRleCA9IHNvcnRlZEluZGV4O1xuICAgIGxvZGFzaC5zb3J0ZWRJbmRleEJ5ID0gc29ydGVkSW5kZXhCeTtcbiAgICBsb2Rhc2guc29ydGVkSW5kZXhPZiA9IHNvcnRlZEluZGV4T2Y7XG4gICAgbG9kYXNoLnNvcnRlZExhc3RJbmRleCA9IHNvcnRlZExhc3RJbmRleDtcbiAgICBsb2Rhc2guc29ydGVkTGFzdEluZGV4QnkgPSBzb3J0ZWRMYXN0SW5kZXhCeTtcbiAgICBsb2Rhc2guc29ydGVkTGFzdEluZGV4T2YgPSBzb3J0ZWRMYXN0SW5kZXhPZjtcbiAgICBsb2Rhc2guc3RhcnRDYXNlID0gc3RhcnRDYXNlO1xuICAgIGxvZGFzaC5zdGFydHNXaXRoID0gc3RhcnRzV2l0aDtcbiAgICBsb2Rhc2guc3VidHJhY3QgPSBzdWJ0cmFjdDtcbiAgICBsb2Rhc2guc3VtID0gc3VtO1xuICAgIGxvZGFzaC5zdW1CeSA9IHN1bUJ5O1xuICAgIGxvZGFzaC50ZW1wbGF0ZSA9IHRlbXBsYXRlO1xuICAgIGxvZGFzaC50aW1lcyA9IHRpbWVzO1xuICAgIGxvZGFzaC50b0Zpbml0ZSA9IHRvRmluaXRlO1xuICAgIGxvZGFzaC50b0ludGVnZXIgPSB0b0ludGVnZXI7XG4gICAgbG9kYXNoLnRvTGVuZ3RoID0gdG9MZW5ndGg7XG4gICAgbG9kYXNoLnRvTG93ZXIgPSB0b0xvd2VyO1xuICAgIGxvZGFzaC50b051bWJlciA9IHRvTnVtYmVyO1xuICAgIGxvZGFzaC50b1NhZmVJbnRlZ2VyID0gdG9TYWZlSW50ZWdlcjtcbiAgICBsb2Rhc2gudG9TdHJpbmcgPSB0b1N0cmluZztcbiAgICBsb2Rhc2gudG9VcHBlciA9IHRvVXBwZXI7XG4gICAgbG9kYXNoLnRyaW0gPSB0cmltO1xuICAgIGxvZGFzaC50cmltRW5kID0gdHJpbUVuZDtcbiAgICBsb2Rhc2gudHJpbVN0YXJ0ID0gdHJpbVN0YXJ0O1xuICAgIGxvZGFzaC50cnVuY2F0ZSA9IHRydW5jYXRlO1xuICAgIGxvZGFzaC51bmVzY2FwZSA9IHVuZXNjYXBlO1xuICAgIGxvZGFzaC51bmlxdWVJZCA9IHVuaXF1ZUlkO1xuICAgIGxvZGFzaC51cHBlckNhc2UgPSB1cHBlckNhc2U7XG4gICAgbG9kYXNoLnVwcGVyRmlyc3QgPSB1cHBlckZpcnN0O1xuXG4gICAgLy8gQWRkIGFsaWFzZXMuXG4gICAgbG9kYXNoLmVhY2ggPSBmb3JFYWNoO1xuICAgIGxvZGFzaC5lYWNoUmlnaHQgPSBmb3JFYWNoUmlnaHQ7XG4gICAgbG9kYXNoLmZpcnN0ID0gaGVhZDtcblxuICAgIG1peGluKGxvZGFzaCwgKGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIHNvdXJjZSA9IHt9O1xuICAgICAgYmFzZUZvck93bihsb2Rhc2gsIGZ1bmN0aW9uKGZ1bmMsIG1ldGhvZE5hbWUpIHtcbiAgICAgICAgaWYgKCFoYXNPd25Qcm9wZXJ0eS5jYWxsKGxvZGFzaC5wcm90b3R5cGUsIG1ldGhvZE5hbWUpKSB7XG4gICAgICAgICAgc291cmNlW21ldGhvZE5hbWVdID0gZnVuYztcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgICByZXR1cm4gc291cmNlO1xuICAgIH0oKSksIHsgJ2NoYWluJzogZmFsc2UgfSk7XG5cbiAgICAvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovXG5cbiAgICAvKipcbiAgICAgKiBUaGUgc2VtYW50aWMgdmVyc2lvbiBudW1iZXIuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAdHlwZSB7c3RyaW5nfVxuICAgICAqL1xuICAgIGxvZGFzaC5WRVJTSU9OID0gVkVSU0lPTjtcblxuICAgIC8vIEFzc2lnbiBkZWZhdWx0IHBsYWNlaG9sZGVycy5cbiAgICBhcnJheUVhY2goWydiaW5kJywgJ2JpbmRLZXknLCAnY3VycnknLCAnY3VycnlSaWdodCcsICdwYXJ0aWFsJywgJ3BhcnRpYWxSaWdodCddLCBmdW5jdGlvbihtZXRob2ROYW1lKSB7XG4gICAgICBsb2Rhc2hbbWV0aG9kTmFtZV0ucGxhY2Vob2xkZXIgPSBsb2Rhc2g7XG4gICAgfSk7XG5cbiAgICAvLyBBZGQgYExhenlXcmFwcGVyYCBtZXRob2RzIGZvciBgXy5kcm9wYCBhbmQgYF8udGFrZWAgdmFyaWFudHMuXG4gICAgYXJyYXlFYWNoKFsnZHJvcCcsICd0YWtlJ10sIGZ1bmN0aW9uKG1ldGhvZE5hbWUsIGluZGV4KSB7XG4gICAgICBMYXp5V3JhcHBlci5wcm90b3R5cGVbbWV0aG9kTmFtZV0gPSBmdW5jdGlvbihuKSB7XG4gICAgICAgIG4gPSBuID09PSB1bmRlZmluZWQgPyAxIDogbmF0aXZlTWF4KHRvSW50ZWdlcihuKSwgMCk7XG5cbiAgICAgICAgdmFyIHJlc3VsdCA9ICh0aGlzLl9fZmlsdGVyZWRfXyAmJiAhaW5kZXgpXG4gICAgICAgICAgPyBuZXcgTGF6eVdyYXBwZXIodGhpcylcbiAgICAgICAgICA6IHRoaXMuY2xvbmUoKTtcblxuICAgICAgICBpZiAocmVzdWx0Ll9fZmlsdGVyZWRfXykge1xuICAgICAgICAgIHJlc3VsdC5fX3Rha2VDb3VudF9fID0gbmF0aXZlTWluKG4sIHJlc3VsdC5fX3Rha2VDb3VudF9fKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXN1bHQuX192aWV3c19fLnB1c2goe1xuICAgICAgICAgICAgJ3NpemUnOiBuYXRpdmVNaW4obiwgTUFYX0FSUkFZX0xFTkdUSCksXG4gICAgICAgICAgICAndHlwZSc6IG1ldGhvZE5hbWUgKyAocmVzdWx0Ll9fZGlyX18gPCAwID8gJ1JpZ2h0JyA6ICcnKVxuICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICB9O1xuXG4gICAgICBMYXp5V3JhcHBlci5wcm90b3R5cGVbbWV0aG9kTmFtZSArICdSaWdodCddID0gZnVuY3Rpb24obikge1xuICAgICAgICByZXR1cm4gdGhpcy5yZXZlcnNlKClbbWV0aG9kTmFtZV0obikucmV2ZXJzZSgpO1xuICAgICAgfTtcbiAgICB9KTtcblxuICAgIC8vIEFkZCBgTGF6eVdyYXBwZXJgIG1ldGhvZHMgdGhhdCBhY2NlcHQgYW4gYGl0ZXJhdGVlYCB2YWx1ZS5cbiAgICBhcnJheUVhY2goWydmaWx0ZXInLCAnbWFwJywgJ3Rha2VXaGlsZSddLCBmdW5jdGlvbihtZXRob2ROYW1lLCBpbmRleCkge1xuICAgICAgdmFyIHR5cGUgPSBpbmRleCArIDEsXG4gICAgICAgICAgaXNGaWx0ZXIgPSB0eXBlID09IExBWllfRklMVEVSX0ZMQUcgfHwgdHlwZSA9PSBMQVpZX1dISUxFX0ZMQUc7XG5cbiAgICAgIExhenlXcmFwcGVyLnByb3RvdHlwZVttZXRob2ROYW1lXSA9IGZ1bmN0aW9uKGl0ZXJhdGVlKSB7XG4gICAgICAgIHZhciByZXN1bHQgPSB0aGlzLmNsb25lKCk7XG4gICAgICAgIHJlc3VsdC5fX2l0ZXJhdGVlc19fLnB1c2goe1xuICAgICAgICAgICdpdGVyYXRlZSc6IGdldEl0ZXJhdGVlKGl0ZXJhdGVlLCAzKSxcbiAgICAgICAgICAndHlwZSc6IHR5cGVcbiAgICAgICAgfSk7XG4gICAgICAgIHJlc3VsdC5fX2ZpbHRlcmVkX18gPSByZXN1bHQuX19maWx0ZXJlZF9fIHx8IGlzRmlsdGVyO1xuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgfTtcbiAgICB9KTtcblxuICAgIC8vIEFkZCBgTGF6eVdyYXBwZXJgIG1ldGhvZHMgZm9yIGBfLmhlYWRgIGFuZCBgXy5sYXN0YC5cbiAgICBhcnJheUVhY2goWydoZWFkJywgJ2xhc3QnXSwgZnVuY3Rpb24obWV0aG9kTmFtZSwgaW5kZXgpIHtcbiAgICAgIHZhciB0YWtlTmFtZSA9ICd0YWtlJyArIChpbmRleCA/ICdSaWdodCcgOiAnJyk7XG5cbiAgICAgIExhenlXcmFwcGVyLnByb3RvdHlwZVttZXRob2ROYW1lXSA9IGZ1bmN0aW9uKCkge1xuICAgICAgICByZXR1cm4gdGhpc1t0YWtlTmFtZV0oMSkudmFsdWUoKVswXTtcbiAgICAgIH07XG4gICAgfSk7XG5cbiAgICAvLyBBZGQgYExhenlXcmFwcGVyYCBtZXRob2RzIGZvciBgXy5pbml0aWFsYCBhbmQgYF8udGFpbGAuXG4gICAgYXJyYXlFYWNoKFsnaW5pdGlhbCcsICd0YWlsJ10sIGZ1bmN0aW9uKG1ldGhvZE5hbWUsIGluZGV4KSB7XG4gICAgICB2YXIgZHJvcE5hbWUgPSAnZHJvcCcgKyAoaW5kZXggPyAnJyA6ICdSaWdodCcpO1xuXG4gICAgICBMYXp5V3JhcHBlci5wcm90b3R5cGVbbWV0aG9kTmFtZV0gPSBmdW5jdGlvbigpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX19maWx0ZXJlZF9fID8gbmV3IExhenlXcmFwcGVyKHRoaXMpIDogdGhpc1tkcm9wTmFtZV0oMSk7XG4gICAgICB9O1xuICAgIH0pO1xuXG4gICAgTGF6eVdyYXBwZXIucHJvdG90eXBlLmNvbXBhY3QgPSBmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiB0aGlzLmZpbHRlcihpZGVudGl0eSk7XG4gICAgfTtcblxuICAgIExhenlXcmFwcGVyLnByb3RvdHlwZS5maW5kID0gZnVuY3Rpb24ocHJlZGljYXRlKSB7XG4gICAgICByZXR1cm4gdGhpcy5maWx0ZXIocHJlZGljYXRlKS5oZWFkKCk7XG4gICAgfTtcblxuICAgIExhenlXcmFwcGVyLnByb3RvdHlwZS5maW5kTGFzdCA9IGZ1bmN0aW9uKHByZWRpY2F0ZSkge1xuICAgICAgcmV0dXJuIHRoaXMucmV2ZXJzZSgpLmZpbmQocHJlZGljYXRlKTtcbiAgICB9O1xuXG4gICAgTGF6eVdyYXBwZXIucHJvdG90eXBlLmludm9rZU1hcCA9IGJhc2VSZXN0KGZ1bmN0aW9uKHBhdGgsIGFyZ3MpIHtcbiAgICAgIGlmICh0eXBlb2YgcGF0aCA9PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIHJldHVybiBuZXcgTGF6eVdyYXBwZXIodGhpcyk7XG4gICAgICB9XG4gICAgICByZXR1cm4gdGhpcy5tYXAoZnVuY3Rpb24odmFsdWUpIHtcbiAgICAgICAgcmV0dXJuIGJhc2VJbnZva2UodmFsdWUsIHBhdGgsIGFyZ3MpO1xuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBMYXp5V3JhcHBlci5wcm90b3R5cGUucmVqZWN0ID0gZnVuY3Rpb24ocHJlZGljYXRlKSB7XG4gICAgICByZXR1cm4gdGhpcy5maWx0ZXIobmVnYXRlKGdldEl0ZXJhdGVlKHByZWRpY2F0ZSkpKTtcbiAgICB9O1xuXG4gICAgTGF6eVdyYXBwZXIucHJvdG90eXBlLnNsaWNlID0gZnVuY3Rpb24oc3RhcnQsIGVuZCkge1xuICAgICAgc3RhcnQgPSB0b0ludGVnZXIoc3RhcnQpO1xuXG4gICAgICB2YXIgcmVzdWx0ID0gdGhpcztcbiAgICAgIGlmIChyZXN1bHQuX19maWx0ZXJlZF9fICYmIChzdGFydCA+IDAgfHwgZW5kIDwgMCkpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBMYXp5V3JhcHBlcihyZXN1bHQpO1xuICAgICAgfVxuICAgICAgaWYgKHN0YXJ0IDwgMCkge1xuICAgICAgICByZXN1bHQgPSByZXN1bHQudGFrZVJpZ2h0KC1zdGFydCk7XG4gICAgICB9IGVsc2UgaWYgKHN0YXJ0KSB7XG4gICAgICAgIHJlc3VsdCA9IHJlc3VsdC5kcm9wKHN0YXJ0KTtcbiAgICAgIH1cbiAgICAgIGlmIChlbmQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICBlbmQgPSB0b0ludGVnZXIoZW5kKTtcbiAgICAgICAgcmVzdWx0ID0gZW5kIDwgMCA/IHJlc3VsdC5kcm9wUmlnaHQoLWVuZCkgOiByZXN1bHQudGFrZShlbmQgLSBzdGFydCk7XG4gICAgICB9XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH07XG5cbiAgICBMYXp5V3JhcHBlci5wcm90b3R5cGUudGFrZVJpZ2h0V2hpbGUgPSBmdW5jdGlvbihwcmVkaWNhdGUpIHtcbiAgICAgIHJldHVybiB0aGlzLnJldmVyc2UoKS50YWtlV2hpbGUocHJlZGljYXRlKS5yZXZlcnNlKCk7XG4gICAgfTtcblxuICAgIExhenlXcmFwcGVyLnByb3RvdHlwZS50b0FycmF5ID0gZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gdGhpcy50YWtlKE1BWF9BUlJBWV9MRU5HVEgpO1xuICAgIH07XG5cbiAgICAvLyBBZGQgYExhenlXcmFwcGVyYCBtZXRob2RzIHRvIGBsb2Rhc2gucHJvdG90eXBlYC5cbiAgICBiYXNlRm9yT3duKExhenlXcmFwcGVyLnByb3RvdHlwZSwgZnVuY3Rpb24oZnVuYywgbWV0aG9kTmFtZSkge1xuICAgICAgdmFyIGNoZWNrSXRlcmF0ZWUgPSAvXig/OmZpbHRlcnxmaW5kfG1hcHxyZWplY3QpfFdoaWxlJC8udGVzdChtZXRob2ROYW1lKSxcbiAgICAgICAgICBpc1Rha2VyID0gL14oPzpoZWFkfGxhc3QpJC8udGVzdChtZXRob2ROYW1lKSxcbiAgICAgICAgICBsb2Rhc2hGdW5jID0gbG9kYXNoW2lzVGFrZXIgPyAoJ3Rha2UnICsgKG1ldGhvZE5hbWUgPT0gJ2xhc3QnID8gJ1JpZ2h0JyA6ICcnKSkgOiBtZXRob2ROYW1lXSxcbiAgICAgICAgICByZXRVbndyYXBwZWQgPSBpc1Rha2VyIHx8IC9eZmluZC8udGVzdChtZXRob2ROYW1lKTtcblxuICAgICAgaWYgKCFsb2Rhc2hGdW5jKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGxvZGFzaC5wcm90b3R5cGVbbWV0aG9kTmFtZV0gPSBmdW5jdGlvbigpIHtcbiAgICAgICAgdmFyIHZhbHVlID0gdGhpcy5fX3dyYXBwZWRfXyxcbiAgICAgICAgICAgIGFyZ3MgPSBpc1Rha2VyID8gWzFdIDogYXJndW1lbnRzLFxuICAgICAgICAgICAgaXNMYXp5ID0gdmFsdWUgaW5zdGFuY2VvZiBMYXp5V3JhcHBlcixcbiAgICAgICAgICAgIGl0ZXJhdGVlID0gYXJnc1swXSxcbiAgICAgICAgICAgIHVzZUxhenkgPSBpc0xhenkgfHwgaXNBcnJheSh2YWx1ZSk7XG5cbiAgICAgICAgdmFyIGludGVyY2VwdG9yID0gZnVuY3Rpb24odmFsdWUpIHtcbiAgICAgICAgICB2YXIgcmVzdWx0ID0gbG9kYXNoRnVuYy5hcHBseShsb2Rhc2gsIGFycmF5UHVzaChbdmFsdWVdLCBhcmdzKSk7XG4gICAgICAgICAgcmV0dXJuIChpc1Rha2VyICYmIGNoYWluQWxsKSA/IHJlc3VsdFswXSA6IHJlc3VsdDtcbiAgICAgICAgfTtcblxuICAgICAgICBpZiAodXNlTGF6eSAmJiBjaGVja0l0ZXJhdGVlICYmIHR5cGVvZiBpdGVyYXRlZSA9PSAnZnVuY3Rpb24nICYmIGl0ZXJhdGVlLmxlbmd0aCAhPSAxKSB7XG4gICAgICAgICAgLy8gQXZvaWQgbGF6eSB1c2UgaWYgdGhlIGl0ZXJhdGVlIGhhcyBhIFwibGVuZ3RoXCIgdmFsdWUgb3RoZXIgdGhhbiBgMWAuXG4gICAgICAgICAgaXNMYXp5ID0gdXNlTGF6eSA9IGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIHZhciBjaGFpbkFsbCA9IHRoaXMuX19jaGFpbl9fLFxuICAgICAgICAgICAgaXNIeWJyaWQgPSAhIXRoaXMuX19hY3Rpb25zX18ubGVuZ3RoLFxuICAgICAgICAgICAgaXNVbndyYXBwZWQgPSByZXRVbndyYXBwZWQgJiYgIWNoYWluQWxsLFxuICAgICAgICAgICAgb25seUxhenkgPSBpc0xhenkgJiYgIWlzSHlicmlkO1xuXG4gICAgICAgIGlmICghcmV0VW53cmFwcGVkICYmIHVzZUxhenkpIHtcbiAgICAgICAgICB2YWx1ZSA9IG9ubHlMYXp5ID8gdmFsdWUgOiBuZXcgTGF6eVdyYXBwZXIodGhpcyk7XG4gICAgICAgICAgdmFyIHJlc3VsdCA9IGZ1bmMuYXBwbHkodmFsdWUsIGFyZ3MpO1xuICAgICAgICAgIHJlc3VsdC5fX2FjdGlvbnNfXy5wdXNoKHsgJ2Z1bmMnOiB0aHJ1LCAnYXJncyc6IFtpbnRlcmNlcHRvcl0sICd0aGlzQXJnJzogdW5kZWZpbmVkIH0pO1xuICAgICAgICAgIHJldHVybiBuZXcgTG9kYXNoV3JhcHBlcihyZXN1bHQsIGNoYWluQWxsKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoaXNVbndyYXBwZWQgJiYgb25seUxhenkpIHtcbiAgICAgICAgICByZXR1cm4gZnVuYy5hcHBseSh0aGlzLCBhcmdzKTtcbiAgICAgICAgfVxuICAgICAgICByZXN1bHQgPSB0aGlzLnRocnUoaW50ZXJjZXB0b3IpO1xuICAgICAgICByZXR1cm4gaXNVbndyYXBwZWQgPyAoaXNUYWtlciA/IHJlc3VsdC52YWx1ZSgpWzBdIDogcmVzdWx0LnZhbHVlKCkpIDogcmVzdWx0O1xuICAgICAgfTtcbiAgICB9KTtcblxuICAgIC8vIEFkZCBgQXJyYXlgIG1ldGhvZHMgdG8gYGxvZGFzaC5wcm90b3R5cGVgLlxuICAgIGFycmF5RWFjaChbJ3BvcCcsICdwdXNoJywgJ3NoaWZ0JywgJ3NvcnQnLCAnc3BsaWNlJywgJ3Vuc2hpZnQnXSwgZnVuY3Rpb24obWV0aG9kTmFtZSkge1xuICAgICAgdmFyIGZ1bmMgPSBhcnJheVByb3RvW21ldGhvZE5hbWVdLFxuICAgICAgICAgIGNoYWluTmFtZSA9IC9eKD86cHVzaHxzb3J0fHVuc2hpZnQpJC8udGVzdChtZXRob2ROYW1lKSA/ICd0YXAnIDogJ3RocnUnLFxuICAgICAgICAgIHJldFVud3JhcHBlZCA9IC9eKD86cG9wfHNoaWZ0KSQvLnRlc3QobWV0aG9kTmFtZSk7XG5cbiAgICAgIGxvZGFzaC5wcm90b3R5cGVbbWV0aG9kTmFtZV0gPSBmdW5jdGlvbigpIHtcbiAgICAgICAgdmFyIGFyZ3MgPSBhcmd1bWVudHM7XG4gICAgICAgIGlmIChyZXRVbndyYXBwZWQgJiYgIXRoaXMuX19jaGFpbl9fKSB7XG4gICAgICAgICAgdmFyIHZhbHVlID0gdGhpcy52YWx1ZSgpO1xuICAgICAgICAgIHJldHVybiBmdW5jLmFwcGx5KGlzQXJyYXkodmFsdWUpID8gdmFsdWUgOiBbXSwgYXJncyk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXNbY2hhaW5OYW1lXShmdW5jdGlvbih2YWx1ZSkge1xuICAgICAgICAgIHJldHVybiBmdW5jLmFwcGx5KGlzQXJyYXkodmFsdWUpID8gdmFsdWUgOiBbXSwgYXJncyk7XG4gICAgICAgIH0pO1xuICAgICAgfTtcbiAgICB9KTtcblxuICAgIC8vIE1hcCBtaW5pZmllZCBtZXRob2QgbmFtZXMgdG8gdGhlaXIgcmVhbCBuYW1lcy5cbiAgICBiYXNlRm9yT3duKExhenlXcmFwcGVyLnByb3RvdHlwZSwgZnVuY3Rpb24oZnVuYywgbWV0aG9kTmFtZSkge1xuICAgICAgdmFyIGxvZGFzaEZ1bmMgPSBsb2Rhc2hbbWV0aG9kTmFtZV07XG4gICAgICBpZiAobG9kYXNoRnVuYykge1xuICAgICAgICB2YXIga2V5ID0gbG9kYXNoRnVuYy5uYW1lICsgJyc7XG4gICAgICAgIGlmICghaGFzT3duUHJvcGVydHkuY2FsbChyZWFsTmFtZXMsIGtleSkpIHtcbiAgICAgICAgICByZWFsTmFtZXNba2V5XSA9IFtdO1xuICAgICAgICB9XG4gICAgICAgIHJlYWxOYW1lc1trZXldLnB1c2goeyAnbmFtZSc6IG1ldGhvZE5hbWUsICdmdW5jJzogbG9kYXNoRnVuYyB9KTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIHJlYWxOYW1lc1tjcmVhdGVIeWJyaWQodW5kZWZpbmVkLCBXUkFQX0JJTkRfS0VZX0ZMQUcpLm5hbWVdID0gW3tcbiAgICAgICduYW1lJzogJ3dyYXBwZXInLFxuICAgICAgJ2Z1bmMnOiB1bmRlZmluZWRcbiAgICB9XTtcblxuICAgIC8vIEFkZCBtZXRob2RzIHRvIGBMYXp5V3JhcHBlcmAuXG4gICAgTGF6eVdyYXBwZXIucHJvdG90eXBlLmNsb25lID0gbGF6eUNsb25lO1xuICAgIExhenlXcmFwcGVyLnByb3RvdHlwZS5yZXZlcnNlID0gbGF6eVJldmVyc2U7XG4gICAgTGF6eVdyYXBwZXIucHJvdG90eXBlLnZhbHVlID0gbGF6eVZhbHVlO1xuXG4gICAgLy8gQWRkIGNoYWluIHNlcXVlbmNlIG1ldGhvZHMgdG8gdGhlIGBsb2Rhc2hgIHdyYXBwZXIuXG4gICAgbG9kYXNoLnByb3RvdHlwZS5hdCA9IHdyYXBwZXJBdDtcbiAgICBsb2Rhc2gucHJvdG90eXBlLmNoYWluID0gd3JhcHBlckNoYWluO1xuICAgIGxvZGFzaC5wcm90b3R5cGUuY29tbWl0ID0gd3JhcHBlckNvbW1pdDtcbiAgICBsb2Rhc2gucHJvdG90eXBlLm5leHQgPSB3cmFwcGVyTmV4dDtcbiAgICBsb2Rhc2gucHJvdG90eXBlLnBsYW50ID0gd3JhcHBlclBsYW50O1xuICAgIGxvZGFzaC5wcm90b3R5cGUucmV2ZXJzZSA9IHdyYXBwZXJSZXZlcnNlO1xuICAgIGxvZGFzaC5wcm90b3R5cGUudG9KU09OID0gbG9kYXNoLnByb3RvdHlwZS52YWx1ZU9mID0gbG9kYXNoLnByb3RvdHlwZS52YWx1ZSA9IHdyYXBwZXJWYWx1ZTtcblxuICAgIC8vIEFkZCBsYXp5IGFsaWFzZXMuXG4gICAgbG9kYXNoLnByb3RvdHlwZS5maXJzdCA9IGxvZGFzaC5wcm90b3R5cGUuaGVhZDtcblxuICAgIGlmIChzeW1JdGVyYXRvcikge1xuICAgICAgbG9kYXNoLnByb3RvdHlwZVtzeW1JdGVyYXRvcl0gPSB3cmFwcGVyVG9JdGVyYXRvcjtcbiAgICB9XG4gICAgcmV0dXJuIGxvZGFzaDtcbiAgfSk7XG5cbiAgLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovXG5cbiAgLy8gRXhwb3J0IGxvZGFzaC5cbiAgdmFyIF8gPSBydW5JbkNvbnRleHQoKTtcblxuICAvLyBTb21lIEFNRCBidWlsZCBvcHRpbWl6ZXJzLCBsaWtlIHIuanMsIGNoZWNrIGZvciBjb25kaXRpb24gcGF0dGVybnMgbGlrZTpcbiAgaWYgKHR5cGVvZiBkZWZpbmUgPT0gJ2Z1bmN0aW9uJyAmJiB0eXBlb2YgZGVmaW5lLmFtZCA9PSAnb2JqZWN0JyAmJiBkZWZpbmUuYW1kKSB7XG4gICAgLy8gRXhwb3NlIExvZGFzaCBvbiB0aGUgZ2xvYmFsIG9iamVjdCB0byBwcmV2ZW50IGVycm9ycyB3aGVuIExvZGFzaCBpc1xuICAgIC8vIGxvYWRlZCBieSBhIHNjcmlwdCB0YWcgaW4gdGhlIHByZXNlbmNlIG9mIGFuIEFNRCBsb2FkZXIuXG4gICAgLy8gU2VlIGh0dHA6Ly9yZXF1aXJlanMub3JnL2RvY3MvZXJyb3JzLmh0bWwjbWlzbWF0Y2ggZm9yIG1vcmUgZGV0YWlscy5cbiAgICAvLyBVc2UgYF8ubm9Db25mbGljdGAgdG8gcmVtb3ZlIExvZGFzaCBmcm9tIHRoZSBnbG9iYWwgb2JqZWN0LlxuICAgIHJvb3QuXyA9IF87XG5cbiAgICAvLyBEZWZpbmUgYXMgYW4gYW5vbnltb3VzIG1vZHVsZSBzbywgdGhyb3VnaCBwYXRoIG1hcHBpbmcsIGl0IGNhbiBiZVxuICAgIC8vIHJlZmVyZW5jZWQgYXMgdGhlIFwidW5kZXJzY29yZVwiIG1vZHVsZS5cbiAgICBkZWZpbmUoZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gXztcbiAgICB9KTtcbiAgfVxuICAvLyBDaGVjayBmb3IgYGV4cG9ydHNgIGFmdGVyIGBkZWZpbmVgIGluIGNhc2UgYSBidWlsZCBvcHRpbWl6ZXIgYWRkcyBpdC5cbiAgZWxzZSBpZiAoZnJlZU1vZHVsZSkge1xuICAgIC8vIEV4cG9ydCBmb3IgTm9kZS5qcy5cbiAgICAoZnJlZU1vZHVsZS5leHBvcnRzID0gXykuXyA9IF87XG4gICAgLy8gRXhwb3J0IGZvciBDb21tb25KUyBzdXBwb3J0LlxuICAgIGZyZWVFeHBvcnRzLl8gPSBfO1xuICB9XG4gIGVsc2Uge1xuICAgIC8vIEV4cG9ydCB0byB0aGUgZ2xvYmFsIG9iamVjdC5cbiAgICByb290Ll8gPSBfO1xuICB9XG59LmNhbGwodGhpcykpO1xuIiwiaW1wb3J0IHsgT3V0bGluZSwgUmF3T3V0bGluZSB9IGZyb20gJy4vb3V0bGluZSc7XG5pbXBvcnQgeyBDdXJzb3IgfSBmcm9tICcuL2N1cnNvcic7XG5pbXBvcnQga2V5Ym9hcmRKUyBmcm9tICdrZXlib2FyZGpzJztcbmltcG9ydCAqIGFzIHJhd091dGxpbmUgZnJvbSAnLi90ZXN0LWRhdGEuanNvbic7XG5cbmxldCBvdXRsaW5lRGF0YSA9IHJhd091dGxpbmU7XG5pZihsb2NhbFN0b3JhZ2UuZ2V0SXRlbSgnYWN0aXZlT3V0bGluZScpKSB7XG4gIGNvbnN0IG91dGxpbmVJZCA9IGxvY2FsU3RvcmFnZS5nZXRJdGVtKCdhY3RpdmVPdXRsaW5lJyk7XG4gIG91dGxpbmVEYXRhID0gSlNPTi5wYXJzZShsb2NhbFN0b3JhZ2UuZ2V0SXRlbShvdXRsaW5lSWQpKTtcbn1cblxuY29uc3Qgc3RhdGUgPSBuZXcgTWFwPHN0cmluZywgYW55PigpO1xuY29uc3Qgb3V0bGluZSA9IG5ldyBPdXRsaW5lKG91dGxpbmVEYXRhIGFzIHVua25vd24gYXMgUmF3T3V0bGluZSk7XG5vdXRsaW5lcigpLmlubmVySFRNTCA9IG91dGxpbmUucmVuZGVyKCk7XG5cbmNvbnN0IGN1cnNvciA9IG5ldyBDdXJzb3IoKTtcbi8vIHBsYWNlIHRoZSBjdXJzb3IgYXQgdGhlIHRvcCFcbmN1cnNvci5zZXQoJy5ub2RlJyk7XG5cbmZ1bmN0aW9uIG91dGxpbmVyKCkge1xuICByZXR1cm4gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI291dGxpbmVyJyk7XG59XG5cbi8vIG1vdmUgZG93blxua2V5Ym9hcmRKUy53aXRoQ29udGV4dCgnbmF2aWdhdGlvbicsICgpID0+IHtcbiAga2V5Ym9hcmRKUy5iaW5kKCdqJywgZSA9PiB7XG4gICAgLy8gbW92ZSBjdXJzb3IgZG93blxuICAgIC8vIGlmIHNoaWZ0IGtleSBpcyBoZWxkLCBzd2FwIHRoZSBub2RlIHdpdGggaXRzIG5leHQgc2libGluZ1xuICAgIGNvbnN0IHNpYmxpbmcgPSBjdXJzb3IuZ2V0KCkubmV4dEVsZW1lbnRTaWJsaW5nO1xuXG4gICAgaWYoc2libGluZykge1xuICAgICAgaWYoZS5zaGlmdEtleSkge1xuICAgICAgICAvLyBzd2FwIHRoaXMgbm9kZSB3aXRoIGl0cyBwcmV2aW91cyBzaWJsaW5nXG4gICAgICAgIGNvbnN0IHJlcyA9IG91dGxpbmUuc3dhcE5vZGVXaXRoTmV4dFNpYmxpbmcoY3Vyc29yLmdldElkT2ZOb2RlKCkpO1xuICAgICAgICBjb25zdCBodG1sID0gb3V0bGluZS5yZW5kZXJOb2RlKHJlcy5wYXJlbnROb2RlKTtcblxuICAgICAgICBpZihyZXMucGFyZW50Tm9kZS5pZCA9PT0gJzAwMDAwMCcpIHtcbiAgICAgICAgICBjdXJzb3IuZ2V0KCkucGFyZW50RWxlbWVudC5pbm5lckhUTUwgPSBodG1sO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgIGN1cnNvci5nZXQoKS5wYXJlbnRFbGVtZW50Lm91dGVySFRNTCA9IGh0bWw7XG4gICAgICAgIH1cblxuICAgICAgICBjdXJzb3Iuc2V0KGAjaWQtJHtyZXMudGFyZ2V0Tm9kZS5pZH1gKTtcbiAgICAgICAgc2F2ZSgpO1xuICAgICAgfVxuICAgICAgZWxzZSB7XG4gICAgICAgIGN1cnNvci5zZXQoYCNpZC0ke3NpYmxpbmcuZ2V0QXR0cmlidXRlKCdkYXRhLWlkJyl9YCk7XG4gICAgICB9XG4gICAgfVxuICB9KTtcblxuICBrZXlib2FyZEpTLmJpbmQoJ2snLCBlID0+IHtcbiAgICAvLyBtb3ZlIGN1cnNvciB1cFxuICAgIC8vIGlmIHNoaWZ0IGtleSBpcyBoZWxkLCBzd2FwIHRoZSBub2RlIHdpdGggaXRzIHByZXZpb3VzIHNpYmxpbmdcbiAgICBjb25zdCBzaWJsaW5nID0gY3Vyc29yLmdldCgpLnByZXZpb3VzRWxlbWVudFNpYmxpbmc7XG5cbiAgICBpZihzaWJsaW5nICYmICFzaWJsaW5nLmNsYXNzTGlzdC5jb250YWlucygnbm9kZUNvbnRlbnQnKSkge1xuICAgICAgaWYoZS5zaGlmdEtleSkge1xuICAgICAgICAvLyBzd2FwIHRoaXMgbm9kZSB3aXRoIGl0cyBwcmV2aW91cyBzaWJsaW5nXG4gICAgICAgIGNvbnN0IHJlcyA9IG91dGxpbmUuc3dhcE5vZGVXaXRoUHJldmlvdXNTaWJsaW5nKGN1cnNvci5nZXRJZE9mTm9kZSgpKTtcbiAgICAgICAgLy8gcmUtcmVuZGVyIHRoZSBwYXJlbnQgbm9kZSBhbmQgZGlzcGxheSB0aGF0IVxuICAgICAgICBjb25zdCBodG1sID0gb3V0bGluZS5yZW5kZXJOb2RlKHJlcy5wYXJlbnROb2RlKTtcblxuICAgICAgICBpZihyZXMucGFyZW50Tm9kZS5pZCA9PT0gJzAwMDAwMCcpIHtcbiAgICAgICAgICBjdXJzb3IuZ2V0KCkucGFyZW50RWxlbWVudC5pbm5lckhUTUwgPSBodG1sO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgIGN1cnNvci5nZXQoKS5wYXJlbnRFbGVtZW50Lm91dGVySFRNTCA9IGh0bWw7XG4gICAgICAgIH1cblxuICAgICAgICBjdXJzb3Iuc2V0KGAjaWQtJHtyZXMudGFyZ2V0Tm9kZS5pZH1gKTtcbiAgICAgICAgc2F2ZSgpO1xuICAgICAgfVxuICAgICAgZWxzZSB7XG4gICAgICAgIGN1cnNvci5zZXQoYCNpZC0ke3NpYmxpbmcuZ2V0QXR0cmlidXRlKCdkYXRhLWlkJyl9YCk7XG4gICAgICB9XG4gICAgfVxuICB9KTtcblxuICBrZXlib2FyZEpTLmJpbmQoJ2wnLCBlID0+IHtcbiAgICAvLyBpZiB0aGUgbm9kZSBpcyBjb2xsYXBzZWQsIHdlIGNhbid0IGdvIGludG8gaXRzIGNoaWxkcmVuXG4gICAgaWYoY3Vyc29yLmlzTm9kZUNvbGxhcHNlZCgpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGlmKGUuc2hpZnRLZXkpIHtcbiAgICAgIGNvbnN0IHJlcyA9IG91dGxpbmUubG93ZXJOb2RlVG9DaGlsZChjdXJzb3IuZ2V0SWRPZk5vZGUoKSk7XG4gICAgICBjb25zdCBodG1sID0gb3V0bGluZS5yZW5kZXJOb2RlKHJlcy5vbGRQYXJlbnROb2RlKTtcblxuICAgICAgaWYocmVzLm9sZFBhcmVudE5vZGUuaWQgPT09ICcwMDAwMDAnKSB7XG4gICAgICAgIGN1cnNvci5nZXQoKS5wYXJlbnRFbGVtZW50LmlubmVySFRNTCA9IGh0bWw7XG4gICAgICB9XG4gICAgICBlbHNlIHtcbiAgICAgICAgY3Vyc29yLmdldCgpLnBhcmVudEVsZW1lbnQub3V0ZXJIVE1MID0gaHRtbDtcbiAgICAgIH1cbiAgICAgIGN1cnNvci5zZXQoYCNpZC0ke3Jlcy50YXJnZXROb2RlLmlkfWApO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgIGNvbnN0IGNoaWxkcmVuID0gY3Vyc29yLmdldCgpLnF1ZXJ5U2VsZWN0b3IoJy5ub2RlJyk7XG4gICAgICBpZihjaGlsZHJlbikge1xuICAgICAgICBjdXJzb3Iuc2V0KGAjaWQtJHtjaGlsZHJlbi5nZXRBdHRyaWJ1dGUoJ2RhdGEtaWQnKX1gKTtcbiAgICAgIH1cbiAgICB9XG4gIH0pO1xuXG4gIGtleWJvYXJkSlMuYmluZCgnaCcsIGUgPT4ge1xuICAgIGNvbnN0IHBhcmVudCA9IGN1cnNvci5nZXQoKS5wYXJlbnRFbGVtZW50O1xuICAgIGlmKHBhcmVudCAmJiBwYXJlbnQuY2xhc3NMaXN0LmNvbnRhaW5zKCdub2RlJykpIHtcbiAgICAgIGlmKGUuc2hpZnRLZXkpIHtcbiAgICAgICAgaWYob3V0bGluZS5kYXRhLnRyZWUuY2hpbGRyZW4ubWFwKG4gPT4gbi5pZCkuaW5jbHVkZXMoY3Vyc29yLmdldElkT2ZOb2RlKCkpKSB7XG4gICAgICAgICAgLy8gaWYgdGhpcyBpcyBhIHRvcCBsZXZlbCBpdGVtLCB3ZSBjYW4ndCBlbGV2YXRlIGFueSBmdXJ0aGVyXG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHJlcyA9IG91dGxpbmUubGlmdE5vZGVUb1BhcmVudChjdXJzb3IuZ2V0SWRPZk5vZGUoKSk7XG5cbiAgICAgICAgY29uc3QgaHRtbCA9IG91dGxpbmUucmVuZGVyTm9kZShyZXMucGFyZW50Tm9kZSk7XG5cbiAgICAgICAgaWYocmVzLnBhcmVudE5vZGUuaWQgPT09ICcwMDAwMDAnKSB7XG4gICAgICAgICAgY3Vyc29yLmdldCgpLnBhcmVudEVsZW1lbnQucGFyZW50RWxlbWVudC5pbm5lckhUTUwgPSBodG1sO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgIGN1cnNvci5nZXQoKS5wYXJlbnRFbGVtZW50LnBhcmVudEVsZW1lbnQub3V0ZXJIVE1MID0gaHRtbDtcbiAgICAgICAgfVxuXG4gICAgICAgIGN1cnNvci5zZXQoYCNpZC0ke3Jlcy50YXJnZXROb2RlLmlkfWApO1xuICAgICAgICBzYXZlKCk7XG4gICAgICB9XG4gICAgICBlbHNlIHtcbiAgICAgICAgY3Vyc29yLnNldChgI2lkLSR7cGFyZW50LmdldEF0dHJpYnV0ZSgnZGF0YS1pZCcpfWApO1xuICAgICAgfVxuICAgIH1cbiAgfSk7XG5cbiAga2V5Ym9hcmRKUy5iaW5kKCd6JywgZSA9PiB7XG4gICAgLy8gdG9nZ2xlIGNvbGxhcHNlXG4gICAgaWYoY3Vyc29yLmlzTm9kZUV4cGFuZGVkKCkpIHtcbiAgICAgIGN1cnNvci5jb2xsYXBzZSgpO1xuICAgICAgb3V0bGluZS5mb2xkKGN1cnNvci5nZXRJZE9mTm9kZSgpKTtcbiAgICB9XG4gICAgZWxzZSBpZihjdXJzb3IuaXNOb2RlQ29sbGFwc2VkKCkpIHtcbiAgICAgIGN1cnNvci5leHBhbmQoKTtcbiAgICAgIG91dGxpbmUudW5mb2xkKGN1cnNvci5nZXRJZE9mTm9kZSgpKTtcbiAgICB9XG4gICAgc2F2ZSgpO1xuICB9KTtcblxuICBrZXlib2FyZEpTLmJpbmQoJ2knLCBlID0+IHtcbiAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgLy8gc3dpdGNoIHRvIGVkaXRpbmcgbW9kZVxuICAgIGN1cnNvci5nZXQoKS5jbGFzc0xpc3QuYWRkKCdoaWRkZW4tY3Vyc29yJyk7XG4gICAgY29uc3QgY29udGVudE5vZGUgPSBjdXJzb3IuZ2V0KCkucXVlcnlTZWxlY3RvcignLm5vZGVDb250ZW50JykgYXMgSFRNTEVsZW1lbnQ7XG5cbiAgICAvLyBzd2FwIHRoZSBjb250ZW50IHRvIHRoZSBkZWZhdWx0IVxuICAgIGNvbnRlbnROb2RlLmlubmVySFRNTCA9IG91dGxpbmUuZGF0YS5jb250ZW50Tm9kZXNbY3Vyc29yLmdldElkT2ZOb2RlKCldLmNvbnRlbnQ7XG4gICAgY29udGVudE5vZGUuY29udGVudEVkaXRhYmxlID0gXCJ0cnVlXCI7XG4gICAgY29udGVudE5vZGUuZm9jdXMoKTtcbiAgICBrZXlib2FyZEpTLnNldENvbnRleHQoJ2VkaXRpbmcnKTtcbiAgfSk7XG5cbiAga2V5Ym9hcmRKUy5iaW5kKCd0YWInLCBlID0+IHtcbiAgICBlLnByZXZlbnREZWZhdWx0KCk7XG5cbiAgICBjb25zdCByZXMgPSBvdXRsaW5lLmNyZWF0ZUNoaWxkTm9kZShjdXJzb3IuZ2V0SWRPZk5vZGUoKSk7XG4gICAgY29uc3QgaHRtbCA9IG91dGxpbmUucmVuZGVyTm9kZShyZXMucGFyZW50Tm9kZSk7XG5cbiAgICBjdXJzb3IuZ2V0KCkub3V0ZXJIVE1MID0gaHRtbDtcblxuICAgIGN1cnNvci5zZXQoYCNpZC0ke3Jlcy5ub2RlLmlkfWApO1xuICAgIHNhdmUoKTtcbiAgfSk7XG4gIFxuICBrZXlib2FyZEpTLmJpbmQoJ2VudGVyJywgZSA9PiB7XG4gICAgLy8gY3JlYXRlIGEgbmV3IG5vZGUgYXMgYSBzaWJsaW5nIG9mIHRoZSBzZWxlY3RlZCBub2RlXG4gICAgaWYoZS5zaGlmdEtleSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgZS5wcmV2ZW50UmVwZWF0KCk7XG5cbiAgICBjb25zdCByZXMgPSBvdXRsaW5lLmNyZWF0ZVNpYmxpbmdOb2RlKGN1cnNvci5nZXRJZE9mTm9kZSgpKTtcblxuICAgIGNvbnN0IGh0bWwgPSBvdXRsaW5lLnJlbmRlck5vZGUocmVzLnBhcmVudE5vZGUpO1xuICAgIGlmKHJlcy5wYXJlbnROb2RlLmlkID09PSAnMDAwMDAwJykge1xuICAgICAgY3Vyc29yLmdldCgpLnBhcmVudEVsZW1lbnQuaW5uZXJIVE1MID0gaHRtbDtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICBjdXJzb3IuZ2V0KCkucGFyZW50RWxlbWVudC5vdXRlckhUTUwgPSBodG1sO1xuICAgIH1cblxuICAgIGN1cnNvci5zZXQoYCNpZC0ke3Jlcy5ub2RlLmlkfWApO1xuICAgIHNhdmUoKTtcbiAgfSk7XG5cbiAga2V5Ym9hcmRKUy5iaW5kKCdkJywgZSA9PiB7XG4gICAgLy8gZGVsZXRpbmcgYSBub2RlIHJlcXVpcmVzIGQgKyBzaGlmdFxuICAgIGlmKCFlLnNoaWZ0S2V5KSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgcmVzID0gb3V0bGluZS5yZW1vdmVOb2RlKGN1cnNvci5nZXRJZE9mTm9kZSgpKTtcbiAgICBjb25zdCBodG1sID0gb3V0bGluZS5yZW5kZXJOb2RlKHJlcy5wYXJlbnROb2RlKTtcbiAgICAvLyB0aGUgcHJldmlvdXMgc2libGluZyFcbiAgICBjb25zdCBwcmV2U2libGluZyA9IGN1cnNvci5nZXQoKS5wcmV2aW91c0VsZW1lbnRTaWJsaW5nO1xuICAgIGNvbnN0IG5leHRTaWJsaW5nID0gY3Vyc29yLmdldCgpLm5leHRFbGVtZW50U2libGluZztcbiAgICBpZihyZXMucGFyZW50Tm9kZS5pZCA9PT0gJzAwMDAwMCcpIHtcbiAgICAgIGN1cnNvci5nZXQoKS5wYXJlbnRFbGVtZW50LmlubmVySFRNTCA9IGh0bWw7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgY3Vyc29yLmdldCgpLnBhcmVudEVsZW1lbnQub3V0ZXJIVE1MID0gaHRtbDtcbiAgICB9XG5cbiAgICBpZihwcmV2U2libGluZy5nZXRBdHRyaWJ1dGUoJ2RhdGEtaWQnKSkge1xuICAgICAgY3Vyc29yLnNldChgI2lkLSR7cHJldlNpYmxpbmcuZ2V0QXR0cmlidXRlKCdkYXRhLWlkJyl9YCk7XG4gICAgfVxuICAgIGVsc2UgaWYobmV4dFNpYmxpbmcuZ2V0QXR0cmlidXRlKCdkYXRhLWlkJykpIHtcbiAgICAgIGN1cnNvci5zZXQoYCNpZC0ke25leHRTaWJsaW5nLmdldEF0dHJpYnV0ZSgnZGF0YS1pZCcpfWApO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgIGNvbnNvbGUubG9nKHJlcy5wYXJlbnROb2RlLmlkKTtcbiAgICAgIGN1cnNvci5zZXQoYCNpZC0ke3Jlcy5wYXJlbnROb2RlLmlkfWApO1xuICAgIH1cblxuICAgIHNhdmUoKTtcbiAgfSk7XG59KTtcblxua2V5Ym9hcmRKUy53aXRoQ29udGV4dCgnZWRpdGluZycsICgpID0+IHtcbiAga2V5Ym9hcmRKUy5iaW5kKFsnZXNjJywgJ2VudGVyJ10sIGUgPT4ge1xuICAgIGN1cnNvci5nZXQoKS5jbGFzc0xpc3QucmVtb3ZlKCdoaWRkZW4tY3Vyc29yJyk7XG5cbiAgICBjb25zdCBjb250ZW50Tm9kZSA9IGN1cnNvci5nZXQoKS5xdWVyeVNlbGVjdG9yKCcubm9kZUNvbnRlbnQnKSBhcyBIVE1MRWxlbWVudDtcblxuICAgIGNvbnRlbnROb2RlLmNvbnRlbnRFZGl0YWJsZSA9IFwiZmFsc2VcIjtcbiAgICBjb250ZW50Tm9kZS5ibHVyKCk7XG4gICAga2V5Ym9hcmRKUy5zZXRDb250ZXh0KCduYXZpZ2F0aW9uJyk7XG5cbiAgICBvdXRsaW5lLnVwZGF0ZUNvbnRlbnQoY3Vyc29yLmdldElkT2ZOb2RlKCksIGNvbnRlbnROb2RlLmlubmVySFRNTC50cmltKCkpO1xuICAgIC8vIHJlLXJlbmRlciB0aGlzIG5vZGUhXG4gICAgY29udGVudE5vZGUuaW5uZXJIVE1MID0gb3V0bGluZS5yZW5kZXJDb250ZW50KGN1cnNvci5nZXRJZE9mTm9kZSgpKTtcbiAgICBzYXZlKCk7XG4gIH0pO1xufSk7XG5cbmtleWJvYXJkSlMuc2V0Q29udGV4dCgnbmF2aWdhdGlvbicpO1xuXG5mdW5jdGlvbiBzYXZlSW1tZWRpYXRlKCkge1xuICBsb2NhbFN0b3JhZ2Uuc2V0SXRlbShvdXRsaW5lLmRhdGEuaWQsIEpTT04uc3RyaW5naWZ5KG91dGxpbmUuZGF0YSkpO1xuICBsb2NhbFN0b3JhZ2Uuc2V0SXRlbSgnYWN0aXZlT3V0bGluZScsIG91dGxpbmUuZGF0YS5pZCk7XG4gIGNvbnNvbGUubG9nKCdzYXZlZC4uLicsIG91dGxpbmUuZGF0YSk7XG4gIHN0YXRlLmRlbGV0ZSgnc2F2ZVRpbWVvdXQnKTtcbn1cblxuZnVuY3Rpb24gc2F2ZSgpIHtcbiAgaWYoIXN0YXRlLmhhcygnc2F2ZVRpbWVvdXQnKSkge1xuICAgIHN0YXRlLnNldCgnc2F2ZVRpbWVvdXQnLCBzZXRUaW1lb3V0KHNhdmVJbW1lZGlhdGUsIDIwMDApKTtcbiAgfVxufVxuXG5cbnNhdmUoKTtcbiIsImV4cG9ydCBjbGFzcyBDdXJzb3Ige1xuICBjb25zdHJ1Y3RvcigpIHtcblxuICB9XG5cbiAgZ2V0KCkge1xuICAgIHJldHVybiBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcuY3Vyc29yJyk7XG4gIH1cblxuICBnZXRJZE9mTm9kZSgpOiBzdHJpbmcge1xuICAgIHJldHVybiB0aGlzLmdldCgpLmdldEF0dHJpYnV0ZSgnZGF0YS1pZCcpO1xuICB9XG5cbiAgdW5zZXQoKSB7XG4gICAgY29uc3QgZWwgPSB0aGlzLmdldCgpO1xuICAgIGlmKGVsKSB7XG4gICAgICBlbC5jbGFzc0xpc3QucmVtb3ZlKCdjdXJzb3InKTtcbiAgICB9XG4gIH1cblxuICBzZXQoZWxlbWVudElkOiBzdHJpbmcpIHtcbiAgICB0aGlzLnVuc2V0KCk7XG4gICAgY29uc3QgZWwgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKGVsZW1lbnRJZCk7XG5cbiAgICBpZihlbCkge1xuICAgICAgZWwuY2xhc3NMaXN0LmFkZCgnY3Vyc29yJyk7XG4gICAgICBpZighdGhpcy5pc1Zpc2libGUoZWxlbWVudElkKSkge1xuICAgICAgICBlbC5zY3JvbGxJbnRvVmlldyh0cnVlKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBjb2xsYXBzZSgpIHtcbiAgICB0aGlzLmdldCgpLmNsYXNzTGlzdC5yZW1vdmUoJ2V4cGFuZGVkJyk7XG4gICAgdGhpcy5nZXQoKS5jbGFzc0xpc3QuYWRkKCdjb2xsYXBzZWQnKTtcbiAgfVxuXG4gIGV4cGFuZCgpIHtcbiAgICB0aGlzLmdldCgpLmNsYXNzTGlzdC5yZW1vdmUoJ2NvbGxhcHNlZCcpO1xuICAgIHRoaXMuZ2V0KCkuY2xhc3NMaXN0LmFkZCgnZXhwYW5kZWQnKTtcbiAgfVxuXG4gIGlzTm9kZUNvbGxhcHNlZCgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5nZXQoKS5jbGFzc0xpc3QuY29udGFpbnMoJ2NvbGxhcHNlZCcpO1xuICB9XG4gIFxuICBpc05vZGVFeHBhbmRlZCgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5nZXQoKS5jbGFzc0xpc3QuY29udGFpbnMoJ2V4cGFuZGVkJyk7XG4gIH1cblxuICBpc1Zpc2libGUoZWxlbWVudElkOiBzdHJpbmcpIHtcbiAgICBjb25zdCBlbCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoZWxlbWVudElkKSBhcyBIVE1MRWxlbWVudDtcbiAgICB2YXIgcmVjdCA9IGVsLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICAgIHJldHVybiAoXG4gICAgICAgIHJlY3QudG9wID49IDAgJiZcbiAgICAgICAgcmVjdC5sZWZ0ID49IDAgJiZcbiAgICAgICAgcmVjdC5ib3R0b20gPD0gKHdpbmRvdy5pbm5lckhlaWdodCB8fCBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuY2xpZW50SGVpZ2h0KSAmJiAgICAgXG4gICAgICAgIHJlY3QucmlnaHQgPD0gKHdpbmRvdy5pbm5lcldpZHRoIHx8IGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5jbGllbnRXaWR0aClcbiAgICApO1xuICB9XG59XG4iLCJpbXBvcnQgKiBhcyBfIGZyb20gJ2xvZGFzaCc7XG5pbXBvcnQgeyB2NCBhcyB1dWlkIH0gZnJvbSAndXVpZCc7XG5pbXBvcnQgeyBtYXJrZWQgfSBmcm9tICdtYXJrZWQnO1xuXG5leHBvcnQgaW50ZXJmYWNlIFJhd091dGxpbmUge1xuICBpZDogc3RyaW5nO1xuICBjcmVhdGVkOiBudW1iZXI7XG4gIG5hbWU6IHN0cmluZztcbiAgdHJlZTogT3V0bGluZVRyZWU7XG4gIGNvbnRlbnROb2RlczogUmVjb3JkPHN0cmluZywgT3V0bGluZU5vZGU+XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgT3V0bGluZVRyZWUge1xuICBpZDogc3RyaW5nO1xuICBjaGlsZHJlbjogT3V0bGluZVRyZWVbXVxuICBjb2xsYXBzZWQ6IGJvb2xlYW47XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgT3V0bGluZU5vZGUge1xuICBpZDogc3RyaW5nO1xuICBjcmVhdGVkOiBudW1iZXI7XG4gIHR5cGU6ICd0ZXh0JyxcbiAgY29udGVudDogc3RyaW5nLFxufTtcblxuZXhwb3J0IGNsYXNzIE91dGxpbmUge1xuICBkYXRhOiBSYXdPdXRsaW5lO1xuXG4gIGNvbnN0cnVjdG9yKG91dGxpbmVEYXRhOiBSYXdPdXRsaW5lKSB7XG4gICAgdGhpcy5kYXRhID0gb3V0bGluZURhdGE7XG4gIH1cblxuICBmaW5kTm9kZUluVHJlZShyb290OiBPdXRsaW5lVHJlZSwgaWQ6IHN0cmluZywgYWN0aW9uOiAoaXRlbTogT3V0bGluZVRyZWUsIHBhcmVudDogT3V0bGluZVRyZWUpID0+IHZvaWQsIHJ1blN0YXRlOiBib29sZWFuID0gZmFsc2UpIHtcbiAgICBsZXQgcnVuID0gcnVuU3RhdGU7XG4gICAgaWYocnVuKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIF8uZWFjaChyb290LmNoaWxkcmVuLCAoY2hpbGROb2RlLCBpZHgpID0+IHtcbiAgICAgIGlmKGNoaWxkTm9kZS5pZCA9PT0gaWQpIHtcbiAgICAgICAgYWN0aW9uKGNoaWxkTm9kZSwgcm9vdCk7XG4gICAgICAgIHJ1biA9IHRydWU7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICAgIGVsc2UgaWYoY2hpbGROb2RlLmNoaWxkcmVuKSB7XG4gICAgICAgIHRoaXMuZmluZE5vZGVJblRyZWUoY2hpbGROb2RlLCBpZCwgYWN0aW9uLCBydW4pO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgZm9sZChub2RlSWQ6IHN0cmluZykge1xuICAgIHRoaXMuZmluZE5vZGVJblRyZWUodGhpcy5kYXRhLnRyZWUsIG5vZGVJZCwgaXRlbSA9PiB7XG4gICAgICBpdGVtLmNvbGxhcHNlZCA9IHRydWU7XG4gICAgfSk7XG4gIH1cblxuICB1bmZvbGQobm9kZUlkOiBzdHJpbmcpIHtcbiAgICB0aGlzLmZpbmROb2RlSW5UcmVlKHRoaXMuZGF0YS50cmVlLCBub2RlSWQsIGl0ZW0gPT4ge1xuICAgICAgaXRlbS5jb2xsYXBzZWQgPSB0cnVlO1xuICAgIH0pO1xuICB9XG5cbiAgZmxhdHRlbk91dGxpbmVUcmVlQ2hpbGRyZW4odHJlZTogT3V0bGluZVRyZWUpOiBzdHJpbmdbXSB7XG4gICAgcmV0dXJuIHRyZWUuY2hpbGRyZW4ubWFwKG5vZGUgPT4gbm9kZS5pZCk7XG4gIH1cblxuICBsaWZ0Tm9kZVRvUGFyZW50KG5vZGVJZDogc3RyaW5nKSB7XG4gICAgbGV0IHJ1biA9IGZhbHNlO1xuICAgIGxldCB0YXJnZXROb2RlOiBPdXRsaW5lVHJlZSwgcGFyZW50Tm9kZTogT3V0bGluZVRyZWU7XG4gICAgdGhpcy5maW5kTm9kZUluVHJlZSh0aGlzLmRhdGEudHJlZSwgbm9kZUlkLCAodE5vZGUsIHBOb2RlKSA9PiB7XG4gICAgICB0YXJnZXROb2RlID0gdE5vZGU7XG4gICAgICB0aGlzLmZpbmROb2RlSW5UcmVlKHRoaXMuZGF0YS50cmVlLCBwTm9kZS5pZCwgKG9yaWdpbmFsUGFyZW50Tm9kZSwgbmV3UGFyZW50Tm9kZSkgPT4geztcbiAgICAgICAgICBpZihydW4pIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICB9XG4gICAgICAgICAgcGFyZW50Tm9kZSA9IG5ld1BhcmVudE5vZGU7XG4gICAgICAgICAgcnVuID0gdHJ1ZTtcblxuICAgICAgICAgIGNvbnN0IGZsYXRJZCA9IG5ld1BhcmVudE5vZGUuY2hpbGRyZW4ubWFwKG4gPT4gbi5pZCk7XG5cbiAgICAgICAgICBjb25zdCBvcmlnaW5hbE5vZGVQb3NpdGlvbiA9IG9yaWdpbmFsUGFyZW50Tm9kZS5jaGlsZHJlbi5tYXAobiA9PiBuLmlkKS5pbmRleE9mKHRhcmdldE5vZGUuaWQpO1xuICAgICAgICAgIGNvbnN0IG5ld05vZGVQb3NpdGlvbiA9IGZsYXRJZC5pbmRleE9mKG9yaWdpbmFsUGFyZW50Tm9kZS5pZCk7XG5cbiAgICAgICAgICBvcmlnaW5hbFBhcmVudE5vZGUuY2hpbGRyZW4uc3BsaWNlKG9yaWdpbmFsTm9kZVBvc2l0aW9uLCAxKTtcblxuICAgICAgICAgIG5ld1BhcmVudE5vZGUuY2hpbGRyZW4uc3BsaWNlKG5ld05vZGVQb3NpdGlvbiArIDEsIDAsIHRhcmdldE5vZGUpO1xuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICByZXR1cm4ge1xuICAgICAgdGFyZ2V0Tm9kZSxcbiAgICAgIHBhcmVudE5vZGVcbiAgICB9XG4gIH1cbiAgXG4gIGxvd2VyTm9kZVRvQ2hpbGQobm9kZUlkOiBzdHJpbmcpIHtcbiAgICBsZXQgcnVuID0gZmFsc2U7XG4gICAgLy8gZmluZCB0aGUgcHJldmlvdXMgc2libGluZ1xuICAgIC8vIG1ha2UgdGhpcyBub2RlIGEgY2hpbGQgb2YgdGhlIHNpYmxpbmcgbm9kZVxuICAgIGxldCB0YXJnZXROb2RlOiBPdXRsaW5lVHJlZSwgbmV3UGFyZW50Tm9kZTogT3V0bGluZVRyZWUsIG9sZFBhcmVudE5vZGU6IE91dGxpbmVUcmVlO1xuICAgIHRoaXMuZmluZE5vZGVJblRyZWUodGhpcy5kYXRhLnRyZWUsIG5vZGVJZCwgKHROb2RlLCBwTm9kZSkgPT4ge1xuICAgICAgaWYocnVuKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIHJ1biAgPSB0cnVlO1xuICAgICAgdGFyZ2V0Tm9kZSA9IHROb2RlO1xuICAgICAgXG4gICAgICBsZXQgaWRMaXN0ID0gcE5vZGUuY2hpbGRyZW4ubWFwKG4gPT4gbi5pZCk7XG4gICAgICAvLyB0aGVyZSBhcmUgbm8gb3RoZXIgc2libGluZ3Mgc28gd2UgY2FuJ3QgZG8gYW55dGhpbmdcbiAgICAgIGlmKGlkTGlzdC5sZW5ndGggPT09IDEpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBwb3NpdGlvbiA9IGlkTGlzdC5pbmRleE9mKHRhcmdldE5vZGUuaWQpO1xuICAgICAgY29uc3QgcHJldlNpYmxpbmdQb3NpdGlvbiA9IHBvc2l0aW9uIC0gMTtcblxuICAgICAgcE5vZGUuY2hpbGRyZW5bcHJldlNpYmxpbmdQb3NpdGlvbl0uY2hpbGRyZW4uc3BsaWNlKDAsIDAsIHRhcmdldE5vZGUpO1xuICAgICAgcE5vZGUuY2hpbGRyZW4uc3BsaWNlKHBvc2l0aW9uLCAxKTtcblxuICAgICAgbmV3UGFyZW50Tm9kZSA9IHBOb2RlLmNoaWxkcmVuW3ByZXZTaWJsaW5nUG9zaXRpb25dO1xuICAgICAgb2xkUGFyZW50Tm9kZSA9IHBOb2RlO1xuICAgIH0pO1xuICAgIHJldHVybiB7XG4gICAgICB0YXJnZXROb2RlLFxuICAgICAgbmV3UGFyZW50Tm9kZSxcbiAgICAgIG9sZFBhcmVudE5vZGVcbiAgICB9XG4gIH1cblxuICBzd2FwTm9kZVdpdGhOZXh0U2libGluZyhub2RlSWQ6IHN0cmluZykge1xuICAgIGxldCB0YXJnZXROb2RlOiBPdXRsaW5lVHJlZSwgcGFyZW50Tm9kZTogT3V0bGluZVRyZWU7XG4gICAgdGhpcy5maW5kTm9kZUluVHJlZSh0aGlzLmRhdGEudHJlZSwgbm9kZUlkLCAodE5vZGUsIHBOb2RlKSA9PiB7XG4gICAgICAgIHRhcmdldE5vZGUgPSB0Tm9kZTtcbiAgICAgICAgcGFyZW50Tm9kZSA9IHBOb2RlO1xuICAgICAgICBjb25zdCBmbGF0SWQgPSBwYXJlbnROb2RlLmNoaWxkcmVuLm1hcChuID0+IG4uaWQpO1xuICAgICAgICBjb25zdCBub2RlUG9zaXRpb24gPSBmbGF0SWQuaW5kZXhPZih0YXJnZXROb2RlLmlkKTtcblxuICAgICAgICBpZihub2RlUG9zaXRpb24gPT09IChmbGF0SWQubGVuZ3RoIC0gMSkpIHtcbiAgICAgICAgICAvLyB0aGlzIGlzIHRoZSBsYXN0IG5vZGUgaW4gdGhlIGxpc3QsIHRoZXJlJ3Mgbm90aGluZyB0byBzd2FwXG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gcmVtb3ZlIHRoZSBub2RlIGZyb20gdGhpcyBwb2ludCwgYW5kIHB1c2ggaXQgb25lIGxhdGVyXG4gICAgICAgIHBhcmVudE5vZGUuY2hpbGRyZW4uc3BsaWNlKG5vZGVQb3NpdGlvbiwgMSk7XG4gICAgICAgIHBhcmVudE5vZGUuY2hpbGRyZW4uc3BsaWNlKG5vZGVQb3NpdGlvbiArIDEsIDAsIHRhcmdldE5vZGUpO1xuICAgIH0pO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIHRhcmdldE5vZGUsXG4gICAgICBwYXJlbnROb2RlXG4gICAgfVxuICB9XG5cbiAgc3dhcE5vZGVXaXRoUHJldmlvdXNTaWJsaW5nKG5vZGVJZDogc3RyaW5nKSB7XG4gICAgbGV0IHRhcmdldE5vZGU6IE91dGxpbmVUcmVlLCBwYXJlbnROb2RlOiBPdXRsaW5lVHJlZTtcbiAgICB0aGlzLmZpbmROb2RlSW5UcmVlKHRoaXMuZGF0YS50cmVlLCBub2RlSWQsICh0Tm9kZSwgcE5vZGUpID0+IHtcbiAgICAgICAgdGFyZ2V0Tm9kZSA9IHROb2RlO1xuICAgICAgICBwYXJlbnROb2RlID0gcE5vZGU7XG4gICAgICAgIGNvbnN0IGZsYXRJZCA9IHBhcmVudE5vZGUuY2hpbGRyZW4ubWFwKG4gPT4gbi5pZCk7XG4gICAgICAgIGNvbnN0IG5vZGVQb3NpdGlvbiA9IGZsYXRJZC5pbmRleE9mKHRhcmdldE5vZGUuaWQpO1xuXG4gICAgICAgIGlmKG5vZGVQb3NpdGlvbiA9PT0gMCkge1xuICAgICAgICAgIC8vIHRoaXMgaXMgdGhlIGZpcnN0IG5vZGUgaW4gdGhlIGxpc3QsIHRoZXJlJ3Mgbm90aGluZyB0byBzd2FwXG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gcmVtb3ZlIHRoZSBub2RlIGZyb20gdGhpcyBwb2ludCwgYW5kIHB1c2ggaXQgb25lIGxhdGVyXG4gICAgICAgIHBhcmVudE5vZGUuY2hpbGRyZW4uc3BsaWNlKG5vZGVQb3NpdGlvbiwgMSk7XG4gICAgICAgIHBhcmVudE5vZGUuY2hpbGRyZW4uc3BsaWNlKG5vZGVQb3NpdGlvbiAtIDEsIDAsIHRhcmdldE5vZGUpO1xuICAgIH0pO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIHRhcmdldE5vZGUsXG4gICAgICBwYXJlbnROb2RlXG4gICAgfVxuICB9XG5cbiAgY3JlYXRlU2libGluZ05vZGUodGFyZ2V0Tm9kZTogc3RyaW5nLCBub2RlRGF0YT86IE91dGxpbmVOb2RlKSB7XG4gICAgY29uc3Qgb3V0bGluZU5vZGU6IE91dGxpbmVOb2RlID0gbm9kZURhdGEgfHwge1xuICAgICAgaWQ6IHV1aWQoKSxcbiAgICAgIGNyZWF0ZWQ6IERhdGUubm93KCksXG4gICAgICB0eXBlOiAndGV4dCcsXG4gICAgICBjb250ZW50OiAnLS0tJ1xuICAgIH07XG5cbiAgICB0aGlzLmRhdGEuY29udGVudE5vZGVzW291dGxpbmVOb2RlLmlkXSA9IG91dGxpbmVOb2RlO1xuXG4gICAgbGV0IHBhcmVudE5vZGU6IE91dGxpbmVUcmVlO1xuXG4gICAgdGhpcy5maW5kTm9kZUluVHJlZSh0aGlzLmRhdGEudHJlZSwgdGFyZ2V0Tm9kZSwgKG5vZGUsIHBhcmVudCkgPT4ge1xuICAgICAgY29uc3QgcG9zaXRpb24gPSBwYXJlbnQuY2hpbGRyZW4ubWFwKG4gPT4gbi5pZCkuaW5kZXhPZih0YXJnZXROb2RlKTtcbiAgICAgIHBhcmVudC5jaGlsZHJlbi5zcGxpY2UocG9zaXRpb24gKyAxLCAwLCB7XG4gICAgICAgIGlkOiBvdXRsaW5lTm9kZS5pZCxcbiAgICAgICAgY29sbGFwc2VkOiBmYWxzZSxcbiAgICAgICAgY2hpbGRyZW46IFtdXG4gICAgICB9KTtcblxuICAgICAgcGFyZW50Tm9kZSA9IHBhcmVudDtcbiAgICB9KTtcblxuICAgIHJldHVybiB7XG4gICAgICBub2RlOiBvdXRsaW5lTm9kZSxcbiAgICAgIHBhcmVudE5vZGVcbiAgICB9XG4gIH1cblxuICBjcmVhdGVDaGlsZE5vZGUoY3VycmVudE5vZGU6IHN0cmluZywgbm9kZUlkPzogc3RyaW5nKSB7XG4gICAgY29uc3Qgbm9kZTogT3V0bGluZU5vZGUgPSBub2RlSWQgPyB0aGlzLmRhdGEuY29udGVudE5vZGVzW25vZGVJZF0gOlxuICAgIHtcbiAgICAgIGlkOiB1dWlkKCksXG4gICAgICBjcmVhdGVkOiBEYXRlLm5vdygpLFxuICAgICAgdHlwZTogJ3RleHQnLFxuICAgICAgY29udGVudDogJy0tLSdcbiAgICB9O1xuXG4gICAgaWYoIW5vZGVJZCkge1xuICAgICAgdGhpcy5kYXRhLmNvbnRlbnROb2Rlc1tub2RlLmlkXSA9IG5vZGU7XG4gICAgfVxuXG4gICAgbGV0IHBhcmVudE5vZGU6IE91dGxpbmVUcmVlO1xuXG4gICAgdGhpcy5maW5kTm9kZUluVHJlZSh0aGlzLmRhdGEudHJlZSwgY3VycmVudE5vZGUsIChmb3VuZE5vZGUsIHBhcmVudCkgPT4ge1xuICAgICAgZm91bmROb2RlLmNoaWxkcmVuLnVuc2hpZnQoe1xuICAgICAgICBpZDogbm9kZS5pZCxcbiAgICAgICAgY2hpbGRyZW46IFtdLFxuICAgICAgICBjb2xsYXBzZWQ6IGZhbHNlXG4gICAgICB9KTtcblxuICAgICAgcGFyZW50Tm9kZSA9IGZvdW5kTm9kZTtcbiAgICB9KTtcblxuICAgIHJldHVybiB7XG4gICAgICBub2RlLFxuICAgICAgcGFyZW50Tm9kZVxuICAgIH1cbiAgfVxuXG4gIHJlbW92ZU5vZGUobm9kZUlkOiBzdHJpbmcpIHtcbiAgICBsZXQgcnVuID0gZmFsc2U7XG4gICAgbGV0IHJlbW92ZWROb2RlOiBPdXRsaW5lVHJlZSwgcGFyZW50Tm9kZTogT3V0bGluZVRyZWU7XG4gICAgdGhpcy5maW5kTm9kZUluVHJlZSh0aGlzLmRhdGEudHJlZSwgbm9kZUlkLCAodE5vZGUsIHBOb2RlKSA9PiB7XG4gICAgICBpZihydW4pIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgcnVuID0gdHJ1ZTtcbiAgICAgIHJlbW92ZWROb2RlID0gdE5vZGU7XG4gICAgICBwYXJlbnROb2RlID0gcE5vZGU7XG5cbiAgICAgIGxldCBwb3NpdGlvbiA9IHBhcmVudE5vZGUuY2hpbGRyZW4ubWFwKG4gPT4gbi5pZCkuaW5kZXhPZih0Tm9kZS5pZCk7XG5cbiAgICAgIHBhcmVudE5vZGUuY2hpbGRyZW4uc3BsaWNlKHBvc2l0aW9uLCAxKTtcbiAgICB9KTtcblxuICAgIHJldHVybiB7XG4gICAgICByZW1vdmVkTm9kZSxcbiAgICAgIHBhcmVudE5vZGVcbiAgICB9XG4gIH1cblxuICB1cGRhdGVDb250ZW50KGlkOiBzdHJpbmcsIGNvbnRlbnQ6IHN0cmluZykge1xuICAgIGlmKCF0aGlzLmRhdGEuY29udGVudE5vZGVzW2lkXSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIG5vZGUnKTtcbiAgICB9XG5cbiAgICB0aGlzLmRhdGEuY29udGVudE5vZGVzW2lkXS5jb250ZW50ID0gY29udGVudDtcbiAgfVxuXG4gIHJlbmRlckNvbnRlbnQobm9kZUlkOiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIGxldCBub2RlID0gdGhpcy5kYXRhLmNvbnRlbnROb2Rlc1tub2RlSWRdO1xuICAgIGxldCBjb250ZW50OiBzdHJpbmc7XG4gICAgc3dpdGNoKG5vZGUudHlwZSkge1xuICAgICAgY2FzZSAndGV4dCc6XG4gICAgICAgIGNvbnRlbnQgPSBtYXJrZWQucGFyc2Uobm9kZS5jb250ZW50KTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBkZWZhdWx0OiBcbiAgICAgICAgY29udGVudCA9IG5vZGUuY29udGVudDtcbiAgICAgICAgYnJlYWs7XG4gICAgfVxuXG4gICAgcmV0dXJuIGNvbnRlbnQ7XG4gIH1cblxuICByZW5kZXJOb2RlKG5vZGU6IE91dGxpbmVUcmVlKTogc3RyaW5nIHtcbiAgICBpZihub2RlLmlkID09PSAnMDAwMDAwJykge1xuICAgICAgcmV0dXJuIHRoaXMucmVuZGVyKCk7XG4gICAgfVxuICAgIGNvbnN0IGNvbGxhcHNlID0gbm9kZS5jb2xsYXBzZWQgPyAnY29sbGFwc2VkJzogJ2V4cGFuZGVkJztcbiAgICBjb25zdCBjb250ZW50OiBPdXRsaW5lTm9kZSA9IHRoaXMuZGF0YS5jb250ZW50Tm9kZXNbbm9kZS5pZF0gfHwge1xuICAgICAgaWQ6IG5vZGUuaWQsXG4gICAgICBjcmVhdGVkOiBEYXRlLm5vdygpLFxuICAgICAgdHlwZTogJ3RleHQnLFxuICAgICAgY29udGVudDogJydcbiAgICB9O1xuXG4gICAgbGV0IGh0bWwgPSBgPGRpdiBjbGFzcz1cIm5vZGUgJHtjb2xsYXBzZX1cIiBkYXRhLWlkPVwiJHtub2RlLmlkfVwiIGlkPVwiaWQtJHtub2RlLmlkfVwiPlxuICAgIDxkaXYgY2xhc3M9XCJub2RlQ29udGVudFwiIGRhdGEtdHlwZT1cIiR7Y29udGVudC50eXBlfVwiPlxuICAgICAgJHt0aGlzLnJlbmRlckNvbnRlbnQobm9kZS5pZCl9XG4gICAgPC9kaXY+XG4gICAgJHtub2RlLmNoaWxkcmVuLmxlbmd0aCA/IF8ubWFwKG5vZGUuY2hpbGRyZW4sIHRoaXMucmVuZGVyTm9kZS5iaW5kKHRoaXMpKS5qb2luKFwiXFxuXCIpIDogJyd9XG4gICAgPC9kaXY+YFxuXG4gICAgcmV0dXJuIGh0bWw7XG4gIH1cblxuICByZW5kZXIoKSB7XG4gICAgLypcbiAgICAgKiByZW5kZXIgc3RhcnRzIGF0IHRoZSByb290IG5vZGUgYW5kIG9ubHkgcmVuZGVycyBpdHMgY2hpbGRyZW4uIFRoZSByb290IFxuICAgICAqIG5vZGUgb25seSBleGlzdHMgYXMgYSBjb250YWluZXIgYXJvdW5kIHRoZSByZXN0IHRvIGVuc3VyZSBhIHN0YW5kYXJkIGZvcm1hdFxuICAgICAqIGZvciB0aGUgdHJlZVxuICAgICAqL1xuICAgIHJldHVybiBfLm1hcCh0aGlzLmRhdGEudHJlZS5jaGlsZHJlbiwgdGhpcy5yZW5kZXJOb2RlLmJpbmQodGhpcykpLmpvaW4oXCJcXG5cIik7XG4gIH1cbn1cbiIsIlwidXNlIHN0cmljdFwiO1xuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHtcbiAgdmFsdWU6IHRydWVcbn0pO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiTklMXCIsIHtcbiAgZW51bWVyYWJsZTogdHJ1ZSxcbiAgZ2V0OiBmdW5jdGlvbiBnZXQoKSB7XG4gICAgcmV0dXJuIF9uaWwuZGVmYXVsdDtcbiAgfVxufSk7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJwYXJzZVwiLCB7XG4gIGVudW1lcmFibGU6IHRydWUsXG4gIGdldDogZnVuY3Rpb24gZ2V0KCkge1xuICAgIHJldHVybiBfcGFyc2UuZGVmYXVsdDtcbiAgfVxufSk7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJzdHJpbmdpZnlcIiwge1xuICBlbnVtZXJhYmxlOiB0cnVlLFxuICBnZXQ6IGZ1bmN0aW9uIGdldCgpIHtcbiAgICByZXR1cm4gX3N0cmluZ2lmeS5kZWZhdWx0O1xuICB9XG59KTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcInYxXCIsIHtcbiAgZW51bWVyYWJsZTogdHJ1ZSxcbiAgZ2V0OiBmdW5jdGlvbiBnZXQoKSB7XG4gICAgcmV0dXJuIF92LmRlZmF1bHQ7XG4gIH1cbn0pO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwidjNcIiwge1xuICBlbnVtZXJhYmxlOiB0cnVlLFxuICBnZXQ6IGZ1bmN0aW9uIGdldCgpIHtcbiAgICByZXR1cm4gX3YyLmRlZmF1bHQ7XG4gIH1cbn0pO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwidjRcIiwge1xuICBlbnVtZXJhYmxlOiB0cnVlLFxuICBnZXQ6IGZ1bmN0aW9uIGdldCgpIHtcbiAgICByZXR1cm4gX3YzLmRlZmF1bHQ7XG4gIH1cbn0pO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwidjVcIiwge1xuICBlbnVtZXJhYmxlOiB0cnVlLFxuICBnZXQ6IGZ1bmN0aW9uIGdldCgpIHtcbiAgICByZXR1cm4gX3Y0LmRlZmF1bHQ7XG4gIH1cbn0pO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwidmFsaWRhdGVcIiwge1xuICBlbnVtZXJhYmxlOiB0cnVlLFxuICBnZXQ6IGZ1bmN0aW9uIGdldCgpIHtcbiAgICByZXR1cm4gX3ZhbGlkYXRlLmRlZmF1bHQ7XG4gIH1cbn0pO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwidmVyc2lvblwiLCB7XG4gIGVudW1lcmFibGU6IHRydWUsXG4gIGdldDogZnVuY3Rpb24gZ2V0KCkge1xuICAgIHJldHVybiBfdmVyc2lvbi5kZWZhdWx0O1xuICB9XG59KTtcblxudmFyIF92ID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChyZXF1aXJlKFwiLi92MS5qc1wiKSk7XG5cbnZhciBfdjIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KHJlcXVpcmUoXCIuL3YzLmpzXCIpKTtcblxudmFyIF92MyA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQocmVxdWlyZShcIi4vdjQuanNcIikpO1xuXG52YXIgX3Y0ID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChyZXF1aXJlKFwiLi92NS5qc1wiKSk7XG5cbnZhciBfbmlsID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChyZXF1aXJlKFwiLi9uaWwuanNcIikpO1xuXG52YXIgX3ZlcnNpb24gPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KHJlcXVpcmUoXCIuL3ZlcnNpb24uanNcIikpO1xuXG52YXIgX3ZhbGlkYXRlID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChyZXF1aXJlKFwiLi92YWxpZGF0ZS5qc1wiKSk7XG5cbnZhciBfc3RyaW5naWZ5ID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChyZXF1aXJlKFwiLi9zdHJpbmdpZnkuanNcIikpO1xuXG52YXIgX3BhcnNlID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChyZXF1aXJlKFwiLi9wYXJzZS5qc1wiKSk7XG5cbmZ1bmN0aW9uIF9pbnRlcm9wUmVxdWlyZURlZmF1bHQob2JqKSB7IHJldHVybiBvYmogJiYgb2JqLl9fZXNNb2R1bGUgPyBvYmogOiB7IGRlZmF1bHQ6IG9iaiB9OyB9IiwiXCJ1c2Ugc3RyaWN0XCI7XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwge1xuICB2YWx1ZTogdHJ1ZVxufSk7XG5leHBvcnRzLmRlZmF1bHQgPSB2b2lkIDA7XG5cbi8qXG4gKiBCcm93c2VyLWNvbXBhdGlibGUgSmF2YVNjcmlwdCBNRDVcbiAqXG4gKiBNb2RpZmljYXRpb24gb2YgSmF2YVNjcmlwdCBNRDVcbiAqIGh0dHBzOi8vZ2l0aHViLmNvbS9ibHVlaW1wL0phdmFTY3JpcHQtTUQ1XG4gKlxuICogQ29weXJpZ2h0IDIwMTEsIFNlYmFzdGlhbiBUc2NoYW5cbiAqIGh0dHBzOi8vYmx1ZWltcC5uZXRcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIGxpY2Vuc2U6XG4gKiBodHRwczovL29wZW5zb3VyY2Uub3JnL2xpY2Vuc2VzL01JVFxuICpcbiAqIEJhc2VkIG9uXG4gKiBBIEphdmFTY3JpcHQgaW1wbGVtZW50YXRpb24gb2YgdGhlIFJTQSBEYXRhIFNlY3VyaXR5LCBJbmMuIE1ENSBNZXNzYWdlXG4gKiBEaWdlc3QgQWxnb3JpdGhtLCBhcyBkZWZpbmVkIGluIFJGQyAxMzIxLlxuICogVmVyc2lvbiAyLjIgQ29weXJpZ2h0IChDKSBQYXVsIEpvaG5zdG9uIDE5OTkgLSAyMDA5XG4gKiBPdGhlciBjb250cmlidXRvcnM6IEdyZWcgSG9sdCwgQW5kcmV3IEtlcGVydCwgWWRuYXIsIExvc3RpbmV0XG4gKiBEaXN0cmlidXRlZCB1bmRlciB0aGUgQlNEIExpY2Vuc2VcbiAqIFNlZSBodHRwOi8vcGFqaG9tZS5vcmcudWsvY3J5cHQvbWQ1IGZvciBtb3JlIGluZm8uXG4gKi9cbmZ1bmN0aW9uIG1kNShieXRlcykge1xuICBpZiAodHlwZW9mIGJ5dGVzID09PSAnc3RyaW5nJykge1xuICAgIGNvbnN0IG1zZyA9IHVuZXNjYXBlKGVuY29kZVVSSUNvbXBvbmVudChieXRlcykpOyAvLyBVVEY4IGVzY2FwZVxuXG4gICAgYnl0ZXMgPSBuZXcgVWludDhBcnJheShtc2cubGVuZ3RoKTtcblxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbXNnLmxlbmd0aDsgKytpKSB7XG4gICAgICBieXRlc1tpXSA9IG1zZy5jaGFyQ29kZUF0KGkpO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBtZDVUb0hleEVuY29kZWRBcnJheSh3b3Jkc1RvTWQ1KGJ5dGVzVG9Xb3JkcyhieXRlcyksIGJ5dGVzLmxlbmd0aCAqIDgpKTtcbn1cbi8qXG4gKiBDb252ZXJ0IGFuIGFycmF5IG9mIGxpdHRsZS1lbmRpYW4gd29yZHMgdG8gYW4gYXJyYXkgb2YgYnl0ZXNcbiAqL1xuXG5cbmZ1bmN0aW9uIG1kNVRvSGV4RW5jb2RlZEFycmF5KGlucHV0KSB7XG4gIGNvbnN0IG91dHB1dCA9IFtdO1xuICBjb25zdCBsZW5ndGgzMiA9IGlucHV0Lmxlbmd0aCAqIDMyO1xuICBjb25zdCBoZXhUYWIgPSAnMDEyMzQ1Njc4OWFiY2RlZic7XG5cbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBsZW5ndGgzMjsgaSArPSA4KSB7XG4gICAgY29uc3QgeCA9IGlucHV0W2kgPj4gNV0gPj4+IGkgJSAzMiAmIDB4ZmY7XG4gICAgY29uc3QgaGV4ID0gcGFyc2VJbnQoaGV4VGFiLmNoYXJBdCh4ID4+PiA0ICYgMHgwZikgKyBoZXhUYWIuY2hhckF0KHggJiAweDBmKSwgMTYpO1xuICAgIG91dHB1dC5wdXNoKGhleCk7XG4gIH1cblxuICByZXR1cm4gb3V0cHV0O1xufVxuLyoqXG4gKiBDYWxjdWxhdGUgb3V0cHV0IGxlbmd0aCB3aXRoIHBhZGRpbmcgYW5kIGJpdCBsZW5ndGhcbiAqL1xuXG5cbmZ1bmN0aW9uIGdldE91dHB1dExlbmd0aChpbnB1dExlbmd0aDgpIHtcbiAgcmV0dXJuIChpbnB1dExlbmd0aDggKyA2NCA+Pj4gOSA8PCA0KSArIDE0ICsgMTtcbn1cbi8qXG4gKiBDYWxjdWxhdGUgdGhlIE1ENSBvZiBhbiBhcnJheSBvZiBsaXR0bGUtZW5kaWFuIHdvcmRzLCBhbmQgYSBiaXQgbGVuZ3RoLlxuICovXG5cblxuZnVuY3Rpb24gd29yZHNUb01kNSh4LCBsZW4pIHtcbiAgLyogYXBwZW5kIHBhZGRpbmcgKi9cbiAgeFtsZW4gPj4gNV0gfD0gMHg4MCA8PCBsZW4gJSAzMjtcbiAgeFtnZXRPdXRwdXRMZW5ndGgobGVuKSAtIDFdID0gbGVuO1xuICBsZXQgYSA9IDE3MzI1ODQxOTM7XG4gIGxldCBiID0gLTI3MTczMzg3OTtcbiAgbGV0IGMgPSAtMTczMjU4NDE5NDtcbiAgbGV0IGQgPSAyNzE3MzM4Nzg7XG5cbiAgZm9yIChsZXQgaSA9IDA7IGkgPCB4Lmxlbmd0aDsgaSArPSAxNikge1xuICAgIGNvbnN0IG9sZGEgPSBhO1xuICAgIGNvbnN0IG9sZGIgPSBiO1xuICAgIGNvbnN0IG9sZGMgPSBjO1xuICAgIGNvbnN0IG9sZGQgPSBkO1xuICAgIGEgPSBtZDVmZihhLCBiLCBjLCBkLCB4W2ldLCA3LCAtNjgwODc2OTM2KTtcbiAgICBkID0gbWQ1ZmYoZCwgYSwgYiwgYywgeFtpICsgMV0sIDEyLCAtMzg5NTY0NTg2KTtcbiAgICBjID0gbWQ1ZmYoYywgZCwgYSwgYiwgeFtpICsgMl0sIDE3LCA2MDYxMDU4MTkpO1xuICAgIGIgPSBtZDVmZihiLCBjLCBkLCBhLCB4W2kgKyAzXSwgMjIsIC0xMDQ0NTI1MzMwKTtcbiAgICBhID0gbWQ1ZmYoYSwgYiwgYywgZCwgeFtpICsgNF0sIDcsIC0xNzY0MTg4OTcpO1xuICAgIGQgPSBtZDVmZihkLCBhLCBiLCBjLCB4W2kgKyA1XSwgMTIsIDEyMDAwODA0MjYpO1xuICAgIGMgPSBtZDVmZihjLCBkLCBhLCBiLCB4W2kgKyA2XSwgMTcsIC0xNDczMjMxMzQxKTtcbiAgICBiID0gbWQ1ZmYoYiwgYywgZCwgYSwgeFtpICsgN10sIDIyLCAtNDU3MDU5ODMpO1xuICAgIGEgPSBtZDVmZihhLCBiLCBjLCBkLCB4W2kgKyA4XSwgNywgMTc3MDAzNTQxNik7XG4gICAgZCA9IG1kNWZmKGQsIGEsIGIsIGMsIHhbaSArIDldLCAxMiwgLTE5NTg0MTQ0MTcpO1xuICAgIGMgPSBtZDVmZihjLCBkLCBhLCBiLCB4W2kgKyAxMF0sIDE3LCAtNDIwNjMpO1xuICAgIGIgPSBtZDVmZihiLCBjLCBkLCBhLCB4W2kgKyAxMV0sIDIyLCAtMTk5MDQwNDE2Mik7XG4gICAgYSA9IG1kNWZmKGEsIGIsIGMsIGQsIHhbaSArIDEyXSwgNywgMTgwNDYwMzY4Mik7XG4gICAgZCA9IG1kNWZmKGQsIGEsIGIsIGMsIHhbaSArIDEzXSwgMTIsIC00MDM0MTEwMSk7XG4gICAgYyA9IG1kNWZmKGMsIGQsIGEsIGIsIHhbaSArIDE0XSwgMTcsIC0xNTAyMDAyMjkwKTtcbiAgICBiID0gbWQ1ZmYoYiwgYywgZCwgYSwgeFtpICsgMTVdLCAyMiwgMTIzNjUzNTMyOSk7XG4gICAgYSA9IG1kNWdnKGEsIGIsIGMsIGQsIHhbaSArIDFdLCA1LCAtMTY1Nzk2NTEwKTtcbiAgICBkID0gbWQ1Z2coZCwgYSwgYiwgYywgeFtpICsgNl0sIDksIC0xMDY5NTAxNjMyKTtcbiAgICBjID0gbWQ1Z2coYywgZCwgYSwgYiwgeFtpICsgMTFdLCAxNCwgNjQzNzE3NzEzKTtcbiAgICBiID0gbWQ1Z2coYiwgYywgZCwgYSwgeFtpXSwgMjAsIC0zNzM4OTczMDIpO1xuICAgIGEgPSBtZDVnZyhhLCBiLCBjLCBkLCB4W2kgKyA1XSwgNSwgLTcwMTU1ODY5MSk7XG4gICAgZCA9IG1kNWdnKGQsIGEsIGIsIGMsIHhbaSArIDEwXSwgOSwgMzgwMTYwODMpO1xuICAgIGMgPSBtZDVnZyhjLCBkLCBhLCBiLCB4W2kgKyAxNV0sIDE0LCAtNjYwNDc4MzM1KTtcbiAgICBiID0gbWQ1Z2coYiwgYywgZCwgYSwgeFtpICsgNF0sIDIwLCAtNDA1NTM3ODQ4KTtcbiAgICBhID0gbWQ1Z2coYSwgYiwgYywgZCwgeFtpICsgOV0sIDUsIDU2ODQ0NjQzOCk7XG4gICAgZCA9IG1kNWdnKGQsIGEsIGIsIGMsIHhbaSArIDE0XSwgOSwgLTEwMTk4MDM2OTApO1xuICAgIGMgPSBtZDVnZyhjLCBkLCBhLCBiLCB4W2kgKyAzXSwgMTQsIC0xODczNjM5NjEpO1xuICAgIGIgPSBtZDVnZyhiLCBjLCBkLCBhLCB4W2kgKyA4XSwgMjAsIDExNjM1MzE1MDEpO1xuICAgIGEgPSBtZDVnZyhhLCBiLCBjLCBkLCB4W2kgKyAxM10sIDUsIC0xNDQ0NjgxNDY3KTtcbiAgICBkID0gbWQ1Z2coZCwgYSwgYiwgYywgeFtpICsgMl0sIDksIC01MTQwMzc4NCk7XG4gICAgYyA9IG1kNWdnKGMsIGQsIGEsIGIsIHhbaSArIDddLCAxNCwgMTczNTMyODQ3Myk7XG4gICAgYiA9IG1kNWdnKGIsIGMsIGQsIGEsIHhbaSArIDEyXSwgMjAsIC0xOTI2NjA3NzM0KTtcbiAgICBhID0gbWQ1aGgoYSwgYiwgYywgZCwgeFtpICsgNV0sIDQsIC0zNzg1NTgpO1xuICAgIGQgPSBtZDVoaChkLCBhLCBiLCBjLCB4W2kgKyA4XSwgMTEsIC0yMDIyNTc0NDYzKTtcbiAgICBjID0gbWQ1aGgoYywgZCwgYSwgYiwgeFtpICsgMTFdLCAxNiwgMTgzOTAzMDU2Mik7XG4gICAgYiA9IG1kNWhoKGIsIGMsIGQsIGEsIHhbaSArIDE0XSwgMjMsIC0zNTMwOTU1Nik7XG4gICAgYSA9IG1kNWhoKGEsIGIsIGMsIGQsIHhbaSArIDFdLCA0LCAtMTUzMDk5MjA2MCk7XG4gICAgZCA9IG1kNWhoKGQsIGEsIGIsIGMsIHhbaSArIDRdLCAxMSwgMTI3Mjg5MzM1Myk7XG4gICAgYyA9IG1kNWhoKGMsIGQsIGEsIGIsIHhbaSArIDddLCAxNiwgLTE1NTQ5NzYzMik7XG4gICAgYiA9IG1kNWhoKGIsIGMsIGQsIGEsIHhbaSArIDEwXSwgMjMsIC0xMDk0NzMwNjQwKTtcbiAgICBhID0gbWQ1aGgoYSwgYiwgYywgZCwgeFtpICsgMTNdLCA0LCA2ODEyNzkxNzQpO1xuICAgIGQgPSBtZDVoaChkLCBhLCBiLCBjLCB4W2ldLCAxMSwgLTM1ODUzNzIyMik7XG4gICAgYyA9IG1kNWhoKGMsIGQsIGEsIGIsIHhbaSArIDNdLCAxNiwgLTcyMjUyMTk3OSk7XG4gICAgYiA9IG1kNWhoKGIsIGMsIGQsIGEsIHhbaSArIDZdLCAyMywgNzYwMjkxODkpO1xuICAgIGEgPSBtZDVoaChhLCBiLCBjLCBkLCB4W2kgKyA5XSwgNCwgLTY0MDM2NDQ4Nyk7XG4gICAgZCA9IG1kNWhoKGQsIGEsIGIsIGMsIHhbaSArIDEyXSwgMTEsIC00MjE4MTU4MzUpO1xuICAgIGMgPSBtZDVoaChjLCBkLCBhLCBiLCB4W2kgKyAxNV0sIDE2LCA1MzA3NDI1MjApO1xuICAgIGIgPSBtZDVoaChiLCBjLCBkLCBhLCB4W2kgKyAyXSwgMjMsIC05OTUzMzg2NTEpO1xuICAgIGEgPSBtZDVpaShhLCBiLCBjLCBkLCB4W2ldLCA2LCAtMTk4NjMwODQ0KTtcbiAgICBkID0gbWQ1aWkoZCwgYSwgYiwgYywgeFtpICsgN10sIDEwLCAxMTI2ODkxNDE1KTtcbiAgICBjID0gbWQ1aWkoYywgZCwgYSwgYiwgeFtpICsgMTRdLCAxNSwgLTE0MTYzNTQ5MDUpO1xuICAgIGIgPSBtZDVpaShiLCBjLCBkLCBhLCB4W2kgKyA1XSwgMjEsIC01NzQzNDA1NSk7XG4gICAgYSA9IG1kNWlpKGEsIGIsIGMsIGQsIHhbaSArIDEyXSwgNiwgMTcwMDQ4NTU3MSk7XG4gICAgZCA9IG1kNWlpKGQsIGEsIGIsIGMsIHhbaSArIDNdLCAxMCwgLTE4OTQ5ODY2MDYpO1xuICAgIGMgPSBtZDVpaShjLCBkLCBhLCBiLCB4W2kgKyAxMF0sIDE1LCAtMTA1MTUyMyk7XG4gICAgYiA9IG1kNWlpKGIsIGMsIGQsIGEsIHhbaSArIDFdLCAyMSwgLTIwNTQ5MjI3OTkpO1xuICAgIGEgPSBtZDVpaShhLCBiLCBjLCBkLCB4W2kgKyA4XSwgNiwgMTg3MzMxMzM1OSk7XG4gICAgZCA9IG1kNWlpKGQsIGEsIGIsIGMsIHhbaSArIDE1XSwgMTAsIC0zMDYxMTc0NCk7XG4gICAgYyA9IG1kNWlpKGMsIGQsIGEsIGIsIHhbaSArIDZdLCAxNSwgLTE1NjAxOTgzODApO1xuICAgIGIgPSBtZDVpaShiLCBjLCBkLCBhLCB4W2kgKyAxM10sIDIxLCAxMzA5MTUxNjQ5KTtcbiAgICBhID0gbWQ1aWkoYSwgYiwgYywgZCwgeFtpICsgNF0sIDYsIC0xNDU1MjMwNzApO1xuICAgIGQgPSBtZDVpaShkLCBhLCBiLCBjLCB4W2kgKyAxMV0sIDEwLCAtMTEyMDIxMDM3OSk7XG4gICAgYyA9IG1kNWlpKGMsIGQsIGEsIGIsIHhbaSArIDJdLCAxNSwgNzE4Nzg3MjU5KTtcbiAgICBiID0gbWQ1aWkoYiwgYywgZCwgYSwgeFtpICsgOV0sIDIxLCAtMzQzNDg1NTUxKTtcbiAgICBhID0gc2FmZUFkZChhLCBvbGRhKTtcbiAgICBiID0gc2FmZUFkZChiLCBvbGRiKTtcbiAgICBjID0gc2FmZUFkZChjLCBvbGRjKTtcbiAgICBkID0gc2FmZUFkZChkLCBvbGRkKTtcbiAgfVxuXG4gIHJldHVybiBbYSwgYiwgYywgZF07XG59XG4vKlxuICogQ29udmVydCBhbiBhcnJheSBieXRlcyB0byBhbiBhcnJheSBvZiBsaXR0bGUtZW5kaWFuIHdvcmRzXG4gKiBDaGFyYWN0ZXJzID4yNTUgaGF2ZSB0aGVpciBoaWdoLWJ5dGUgc2lsZW50bHkgaWdub3JlZC5cbiAqL1xuXG5cbmZ1bmN0aW9uIGJ5dGVzVG9Xb3JkcyhpbnB1dCkge1xuICBpZiAoaW5wdXQubGVuZ3RoID09PSAwKSB7XG4gICAgcmV0dXJuIFtdO1xuICB9XG5cbiAgY29uc3QgbGVuZ3RoOCA9IGlucHV0Lmxlbmd0aCAqIDg7XG4gIGNvbnN0IG91dHB1dCA9IG5ldyBVaW50MzJBcnJheShnZXRPdXRwdXRMZW5ndGgobGVuZ3RoOCkpO1xuXG4gIGZvciAobGV0IGkgPSAwOyBpIDwgbGVuZ3RoODsgaSArPSA4KSB7XG4gICAgb3V0cHV0W2kgPj4gNV0gfD0gKGlucHV0W2kgLyA4XSAmIDB4ZmYpIDw8IGkgJSAzMjtcbiAgfVxuXG4gIHJldHVybiBvdXRwdXQ7XG59XG4vKlxuICogQWRkIGludGVnZXJzLCB3cmFwcGluZyBhdCAyXjMyLiBUaGlzIHVzZXMgMTYtYml0IG9wZXJhdGlvbnMgaW50ZXJuYWxseVxuICogdG8gd29yayBhcm91bmQgYnVncyBpbiBzb21lIEpTIGludGVycHJldGVycy5cbiAqL1xuXG5cbmZ1bmN0aW9uIHNhZmVBZGQoeCwgeSkge1xuICBjb25zdCBsc3cgPSAoeCAmIDB4ZmZmZikgKyAoeSAmIDB4ZmZmZik7XG4gIGNvbnN0IG1zdyA9ICh4ID4+IDE2KSArICh5ID4+IDE2KSArIChsc3cgPj4gMTYpO1xuICByZXR1cm4gbXN3IDw8IDE2IHwgbHN3ICYgMHhmZmZmO1xufVxuLypcbiAqIEJpdHdpc2Ugcm90YXRlIGEgMzItYml0IG51bWJlciB0byB0aGUgbGVmdC5cbiAqL1xuXG5cbmZ1bmN0aW9uIGJpdFJvdGF0ZUxlZnQobnVtLCBjbnQpIHtcbiAgcmV0dXJuIG51bSA8PCBjbnQgfCBudW0gPj4+IDMyIC0gY250O1xufVxuLypcbiAqIFRoZXNlIGZ1bmN0aW9ucyBpbXBsZW1lbnQgdGhlIGZvdXIgYmFzaWMgb3BlcmF0aW9ucyB0aGUgYWxnb3JpdGhtIHVzZXMuXG4gKi9cblxuXG5mdW5jdGlvbiBtZDVjbW4ocSwgYSwgYiwgeCwgcywgdCkge1xuICByZXR1cm4gc2FmZUFkZChiaXRSb3RhdGVMZWZ0KHNhZmVBZGQoc2FmZUFkZChhLCBxKSwgc2FmZUFkZCh4LCB0KSksIHMpLCBiKTtcbn1cblxuZnVuY3Rpb24gbWQ1ZmYoYSwgYiwgYywgZCwgeCwgcywgdCkge1xuICByZXR1cm4gbWQ1Y21uKGIgJiBjIHwgfmIgJiBkLCBhLCBiLCB4LCBzLCB0KTtcbn1cblxuZnVuY3Rpb24gbWQ1Z2coYSwgYiwgYywgZCwgeCwgcywgdCkge1xuICByZXR1cm4gbWQ1Y21uKGIgJiBkIHwgYyAmIH5kLCBhLCBiLCB4LCBzLCB0KTtcbn1cblxuZnVuY3Rpb24gbWQ1aGgoYSwgYiwgYywgZCwgeCwgcywgdCkge1xuICByZXR1cm4gbWQ1Y21uKGIgXiBjIF4gZCwgYSwgYiwgeCwgcywgdCk7XG59XG5cbmZ1bmN0aW9uIG1kNWlpKGEsIGIsIGMsIGQsIHgsIHMsIHQpIHtcbiAgcmV0dXJuIG1kNWNtbihjIF4gKGIgfCB+ZCksIGEsIGIsIHgsIHMsIHQpO1xufVxuXG52YXIgX2RlZmF1bHQgPSBtZDU7XG5leHBvcnRzLmRlZmF1bHQgPSBfZGVmYXVsdDsiLCJcInVzZSBzdHJpY3RcIjtcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7XG4gIHZhbHVlOiB0cnVlXG59KTtcbmV4cG9ydHMuZGVmYXVsdCA9IHZvaWQgMDtcbmNvbnN0IHJhbmRvbVVVSUQgPSB0eXBlb2YgY3J5cHRvICE9PSAndW5kZWZpbmVkJyAmJiBjcnlwdG8ucmFuZG9tVVVJRCAmJiBjcnlwdG8ucmFuZG9tVVVJRC5iaW5kKGNyeXB0byk7XG52YXIgX2RlZmF1bHQgPSB7XG4gIHJhbmRvbVVVSURcbn07XG5leHBvcnRzLmRlZmF1bHQgPSBfZGVmYXVsdDsiLCJcInVzZSBzdHJpY3RcIjtcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7XG4gIHZhbHVlOiB0cnVlXG59KTtcbmV4cG9ydHMuZGVmYXVsdCA9IHZvaWQgMDtcbnZhciBfZGVmYXVsdCA9ICcwMDAwMDAwMC0wMDAwLTAwMDAtMDAwMC0wMDAwMDAwMDAwMDAnO1xuZXhwb3J0cy5kZWZhdWx0ID0gX2RlZmF1bHQ7IiwiXCJ1c2Ugc3RyaWN0XCI7XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwge1xuICB2YWx1ZTogdHJ1ZVxufSk7XG5leHBvcnRzLmRlZmF1bHQgPSB2b2lkIDA7XG5cbnZhciBfdmFsaWRhdGUgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KHJlcXVpcmUoXCIuL3ZhbGlkYXRlLmpzXCIpKTtcblxuZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChvYmopIHsgcmV0dXJuIG9iaiAmJiBvYmouX19lc01vZHVsZSA/IG9iaiA6IHsgZGVmYXVsdDogb2JqIH07IH1cblxuZnVuY3Rpb24gcGFyc2UodXVpZCkge1xuICBpZiAoISgwLCBfdmFsaWRhdGUuZGVmYXVsdCkodXVpZCkpIHtcbiAgICB0aHJvdyBUeXBlRXJyb3IoJ0ludmFsaWQgVVVJRCcpO1xuICB9XG5cbiAgbGV0IHY7XG4gIGNvbnN0IGFyciA9IG5ldyBVaW50OEFycmF5KDE2KTsgLy8gUGFyc2UgIyMjIyMjIyMtLi4uLi0uLi4uLS4uLi4tLi4uLi4uLi4uLi4uXG5cbiAgYXJyWzBdID0gKHYgPSBwYXJzZUludCh1dWlkLnNsaWNlKDAsIDgpLCAxNikpID4+PiAyNDtcbiAgYXJyWzFdID0gdiA+Pj4gMTYgJiAweGZmO1xuICBhcnJbMl0gPSB2ID4+PiA4ICYgMHhmZjtcbiAgYXJyWzNdID0gdiAmIDB4ZmY7IC8vIFBhcnNlIC4uLi4uLi4uLSMjIyMtLi4uLi0uLi4uLS4uLi4uLi4uLi4uLlxuXG4gIGFycls0XSA9ICh2ID0gcGFyc2VJbnQodXVpZC5zbGljZSg5LCAxMyksIDE2KSkgPj4+IDg7XG4gIGFycls1XSA9IHYgJiAweGZmOyAvLyBQYXJzZSAuLi4uLi4uLi0uLi4uLSMjIyMtLi4uLi0uLi4uLi4uLi4uLi5cblxuICBhcnJbNl0gPSAodiA9IHBhcnNlSW50KHV1aWQuc2xpY2UoMTQsIDE4KSwgMTYpKSA+Pj4gODtcbiAgYXJyWzddID0gdiAmIDB4ZmY7IC8vIFBhcnNlIC4uLi4uLi4uLS4uLi4tLi4uLi0jIyMjLS4uLi4uLi4uLi4uLlxuXG4gIGFycls4XSA9ICh2ID0gcGFyc2VJbnQodXVpZC5zbGljZSgxOSwgMjMpLCAxNikpID4+PiA4O1xuICBhcnJbOV0gPSB2ICYgMHhmZjsgLy8gUGFyc2UgLi4uLi4uLi4tLi4uLi0uLi4uLS4uLi4tIyMjIyMjIyMjIyMjXG4gIC8vIChVc2UgXCIvXCIgdG8gYXZvaWQgMzItYml0IHRydW5jYXRpb24gd2hlbiBiaXQtc2hpZnRpbmcgaGlnaC1vcmRlciBieXRlcylcblxuICBhcnJbMTBdID0gKHYgPSBwYXJzZUludCh1dWlkLnNsaWNlKDI0LCAzNiksIDE2KSkgLyAweDEwMDAwMDAwMDAwICYgMHhmZjtcbiAgYXJyWzExXSA9IHYgLyAweDEwMDAwMDAwMCAmIDB4ZmY7XG4gIGFyclsxMl0gPSB2ID4+PiAyNCAmIDB4ZmY7XG4gIGFyclsxM10gPSB2ID4+PiAxNiAmIDB4ZmY7XG4gIGFyclsxNF0gPSB2ID4+PiA4ICYgMHhmZjtcbiAgYXJyWzE1XSA9IHYgJiAweGZmO1xuICByZXR1cm4gYXJyO1xufVxuXG52YXIgX2RlZmF1bHQgPSBwYXJzZTtcbmV4cG9ydHMuZGVmYXVsdCA9IF9kZWZhdWx0OyIsIlwidXNlIHN0cmljdFwiO1xuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHtcbiAgdmFsdWU6IHRydWVcbn0pO1xuZXhwb3J0cy5kZWZhdWx0ID0gdm9pZCAwO1xudmFyIF9kZWZhdWx0ID0gL14oPzpbMC05YS1mXXs4fS1bMC05YS1mXXs0fS1bMS01XVswLTlhLWZdezN9LVs4OWFiXVswLTlhLWZdezN9LVswLTlhLWZdezEyfXwwMDAwMDAwMC0wMDAwLTAwMDAtMDAwMC0wMDAwMDAwMDAwMDApJC9pO1xuZXhwb3J0cy5kZWZhdWx0ID0gX2RlZmF1bHQ7IiwiXCJ1c2Ugc3RyaWN0XCI7XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwge1xuICB2YWx1ZTogdHJ1ZVxufSk7XG5leHBvcnRzLmRlZmF1bHQgPSBybmc7XG4vLyBVbmlxdWUgSUQgY3JlYXRpb24gcmVxdWlyZXMgYSBoaWdoIHF1YWxpdHkgcmFuZG9tICMgZ2VuZXJhdG9yLiBJbiB0aGUgYnJvd3NlciB3ZSB0aGVyZWZvcmVcbi8vIHJlcXVpcmUgdGhlIGNyeXB0byBBUEkgYW5kIGRvIG5vdCBzdXBwb3J0IGJ1aWx0LWluIGZhbGxiYWNrIHRvIGxvd2VyIHF1YWxpdHkgcmFuZG9tIG51bWJlclxuLy8gZ2VuZXJhdG9ycyAobGlrZSBNYXRoLnJhbmRvbSgpKS5cbmxldCBnZXRSYW5kb21WYWx1ZXM7XG5jb25zdCBybmRzOCA9IG5ldyBVaW50OEFycmF5KDE2KTtcblxuZnVuY3Rpb24gcm5nKCkge1xuICAvLyBsYXp5IGxvYWQgc28gdGhhdCBlbnZpcm9ubWVudHMgdGhhdCBuZWVkIHRvIHBvbHlmaWxsIGhhdmUgYSBjaGFuY2UgdG8gZG8gc29cbiAgaWYgKCFnZXRSYW5kb21WYWx1ZXMpIHtcbiAgICAvLyBnZXRSYW5kb21WYWx1ZXMgbmVlZHMgdG8gYmUgaW52b2tlZCBpbiBhIGNvbnRleHQgd2hlcmUgXCJ0aGlzXCIgaXMgYSBDcnlwdG8gaW1wbGVtZW50YXRpb24uXG4gICAgZ2V0UmFuZG9tVmFsdWVzID0gdHlwZW9mIGNyeXB0byAhPT0gJ3VuZGVmaW5lZCcgJiYgY3J5cHRvLmdldFJhbmRvbVZhbHVlcyAmJiBjcnlwdG8uZ2V0UmFuZG9tVmFsdWVzLmJpbmQoY3J5cHRvKTtcblxuICAgIGlmICghZ2V0UmFuZG9tVmFsdWVzKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2NyeXB0by5nZXRSYW5kb21WYWx1ZXMoKSBub3Qgc3VwcG9ydGVkLiBTZWUgaHR0cHM6Ly9naXRodWIuY29tL3V1aWRqcy91dWlkI2dldHJhbmRvbXZhbHVlcy1ub3Qtc3VwcG9ydGVkJyk7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIGdldFJhbmRvbVZhbHVlcyhybmRzOCk7XG59IiwiXCJ1c2Ugc3RyaWN0XCI7XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwge1xuICB2YWx1ZTogdHJ1ZVxufSk7XG5leHBvcnRzLmRlZmF1bHQgPSB2b2lkIDA7XG5cbi8vIEFkYXB0ZWQgZnJvbSBDaHJpcyBWZW5lc3MnIFNIQTEgY29kZSBhdFxuLy8gaHR0cDovL3d3dy5tb3ZhYmxlLXR5cGUuY28udWsvc2NyaXB0cy9zaGExLmh0bWxcbmZ1bmN0aW9uIGYocywgeCwgeSwgeikge1xuICBzd2l0Y2ggKHMpIHtcbiAgICBjYXNlIDA6XG4gICAgICByZXR1cm4geCAmIHkgXiB+eCAmIHo7XG5cbiAgICBjYXNlIDE6XG4gICAgICByZXR1cm4geCBeIHkgXiB6O1xuXG4gICAgY2FzZSAyOlxuICAgICAgcmV0dXJuIHggJiB5IF4geCAmIHogXiB5ICYgejtcblxuICAgIGNhc2UgMzpcbiAgICAgIHJldHVybiB4IF4geSBeIHo7XG4gIH1cbn1cblxuZnVuY3Rpb24gUk9UTCh4LCBuKSB7XG4gIHJldHVybiB4IDw8IG4gfCB4ID4+PiAzMiAtIG47XG59XG5cbmZ1bmN0aW9uIHNoYTEoYnl0ZXMpIHtcbiAgY29uc3QgSyA9IFsweDVhODI3OTk5LCAweDZlZDllYmExLCAweDhmMWJiY2RjLCAweGNhNjJjMWQ2XTtcbiAgY29uc3QgSCA9IFsweDY3NDUyMzAxLCAweGVmY2RhYjg5LCAweDk4YmFkY2ZlLCAweDEwMzI1NDc2LCAweGMzZDJlMWYwXTtcblxuICBpZiAodHlwZW9mIGJ5dGVzID09PSAnc3RyaW5nJykge1xuICAgIGNvbnN0IG1zZyA9IHVuZXNjYXBlKGVuY29kZVVSSUNvbXBvbmVudChieXRlcykpOyAvLyBVVEY4IGVzY2FwZVxuXG4gICAgYnl0ZXMgPSBbXTtcblxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbXNnLmxlbmd0aDsgKytpKSB7XG4gICAgICBieXRlcy5wdXNoKG1zZy5jaGFyQ29kZUF0KGkpKTtcbiAgICB9XG4gIH0gZWxzZSBpZiAoIUFycmF5LmlzQXJyYXkoYnl0ZXMpKSB7XG4gICAgLy8gQ29udmVydCBBcnJheS1saWtlIHRvIEFycmF5XG4gICAgYnl0ZXMgPSBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChieXRlcyk7XG4gIH1cblxuICBieXRlcy5wdXNoKDB4ODApO1xuICBjb25zdCBsID0gYnl0ZXMubGVuZ3RoIC8gNCArIDI7XG4gIGNvbnN0IE4gPSBNYXRoLmNlaWwobCAvIDE2KTtcbiAgY29uc3QgTSA9IG5ldyBBcnJheShOKTtcblxuICBmb3IgKGxldCBpID0gMDsgaSA8IE47ICsraSkge1xuICAgIGNvbnN0IGFyciA9IG5ldyBVaW50MzJBcnJheSgxNik7XG5cbiAgICBmb3IgKGxldCBqID0gMDsgaiA8IDE2OyArK2opIHtcbiAgICAgIGFycltqXSA9IGJ5dGVzW2kgKiA2NCArIGogKiA0XSA8PCAyNCB8IGJ5dGVzW2kgKiA2NCArIGogKiA0ICsgMV0gPDwgMTYgfCBieXRlc1tpICogNjQgKyBqICogNCArIDJdIDw8IDggfCBieXRlc1tpICogNjQgKyBqICogNCArIDNdO1xuICAgIH1cblxuICAgIE1baV0gPSBhcnI7XG4gIH1cblxuICBNW04gLSAxXVsxNF0gPSAoYnl0ZXMubGVuZ3RoIC0gMSkgKiA4IC8gTWF0aC5wb3coMiwgMzIpO1xuICBNW04gLSAxXVsxNF0gPSBNYXRoLmZsb29yKE1bTiAtIDFdWzE0XSk7XG4gIE1bTiAtIDFdWzE1XSA9IChieXRlcy5sZW5ndGggLSAxKSAqIDggJiAweGZmZmZmZmZmO1xuXG4gIGZvciAobGV0IGkgPSAwOyBpIDwgTjsgKytpKSB7XG4gICAgY29uc3QgVyA9IG5ldyBVaW50MzJBcnJheSg4MCk7XG5cbiAgICBmb3IgKGxldCB0ID0gMDsgdCA8IDE2OyArK3QpIHtcbiAgICAgIFdbdF0gPSBNW2ldW3RdO1xuICAgIH1cblxuICAgIGZvciAobGV0IHQgPSAxNjsgdCA8IDgwOyArK3QpIHtcbiAgICAgIFdbdF0gPSBST1RMKFdbdCAtIDNdIF4gV1t0IC0gOF0gXiBXW3QgLSAxNF0gXiBXW3QgLSAxNl0sIDEpO1xuICAgIH1cblxuICAgIGxldCBhID0gSFswXTtcbiAgICBsZXQgYiA9IEhbMV07XG4gICAgbGV0IGMgPSBIWzJdO1xuICAgIGxldCBkID0gSFszXTtcbiAgICBsZXQgZSA9IEhbNF07XG5cbiAgICBmb3IgKGxldCB0ID0gMDsgdCA8IDgwOyArK3QpIHtcbiAgICAgIGNvbnN0IHMgPSBNYXRoLmZsb29yKHQgLyAyMCk7XG4gICAgICBjb25zdCBUID0gUk9UTChhLCA1KSArIGYocywgYiwgYywgZCkgKyBlICsgS1tzXSArIFdbdF0gPj4+IDA7XG4gICAgICBlID0gZDtcbiAgICAgIGQgPSBjO1xuICAgICAgYyA9IFJPVEwoYiwgMzApID4+PiAwO1xuICAgICAgYiA9IGE7XG4gICAgICBhID0gVDtcbiAgICB9XG5cbiAgICBIWzBdID0gSFswXSArIGEgPj4+IDA7XG4gICAgSFsxXSA9IEhbMV0gKyBiID4+PiAwO1xuICAgIEhbMl0gPSBIWzJdICsgYyA+Pj4gMDtcbiAgICBIWzNdID0gSFszXSArIGQgPj4+IDA7XG4gICAgSFs0XSA9IEhbNF0gKyBlID4+PiAwO1xuICB9XG5cbiAgcmV0dXJuIFtIWzBdID4+IDI0ICYgMHhmZiwgSFswXSA+PiAxNiAmIDB4ZmYsIEhbMF0gPj4gOCAmIDB4ZmYsIEhbMF0gJiAweGZmLCBIWzFdID4+IDI0ICYgMHhmZiwgSFsxXSA+PiAxNiAmIDB4ZmYsIEhbMV0gPj4gOCAmIDB4ZmYsIEhbMV0gJiAweGZmLCBIWzJdID4+IDI0ICYgMHhmZiwgSFsyXSA+PiAxNiAmIDB4ZmYsIEhbMl0gPj4gOCAmIDB4ZmYsIEhbMl0gJiAweGZmLCBIWzNdID4+IDI0ICYgMHhmZiwgSFszXSA+PiAxNiAmIDB4ZmYsIEhbM10gPj4gOCAmIDB4ZmYsIEhbM10gJiAweGZmLCBIWzRdID4+IDI0ICYgMHhmZiwgSFs0XSA+PiAxNiAmIDB4ZmYsIEhbNF0gPj4gOCAmIDB4ZmYsIEhbNF0gJiAweGZmXTtcbn1cblxudmFyIF9kZWZhdWx0ID0gc2hhMTtcbmV4cG9ydHMuZGVmYXVsdCA9IF9kZWZhdWx0OyIsIlwidXNlIHN0cmljdFwiO1xuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHtcbiAgdmFsdWU6IHRydWVcbn0pO1xuZXhwb3J0cy5kZWZhdWx0ID0gdm9pZCAwO1xuZXhwb3J0cy51bnNhZmVTdHJpbmdpZnkgPSB1bnNhZmVTdHJpbmdpZnk7XG5cbnZhciBfdmFsaWRhdGUgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KHJlcXVpcmUoXCIuL3ZhbGlkYXRlLmpzXCIpKTtcblxuZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChvYmopIHsgcmV0dXJuIG9iaiAmJiBvYmouX19lc01vZHVsZSA/IG9iaiA6IHsgZGVmYXVsdDogb2JqIH07IH1cblxuLyoqXG4gKiBDb252ZXJ0IGFycmF5IG9mIDE2IGJ5dGUgdmFsdWVzIHRvIFVVSUQgc3RyaW5nIGZvcm1hdCBvZiB0aGUgZm9ybTpcbiAqIFhYWFhYWFhYLVhYWFgtWFhYWC1YWFhYLVhYWFhYWFhYWFhYWFxuICovXG5jb25zdCBieXRlVG9IZXggPSBbXTtcblxuZm9yIChsZXQgaSA9IDA7IGkgPCAyNTY7ICsraSkge1xuICBieXRlVG9IZXgucHVzaCgoaSArIDB4MTAwKS50b1N0cmluZygxNikuc2xpY2UoMSkpO1xufVxuXG5mdW5jdGlvbiB1bnNhZmVTdHJpbmdpZnkoYXJyLCBvZmZzZXQgPSAwKSB7XG4gIC8vIE5vdGU6IEJlIGNhcmVmdWwgZWRpdGluZyB0aGlzIGNvZGUhICBJdCdzIGJlZW4gdHVuZWQgZm9yIHBlcmZvcm1hbmNlXG4gIC8vIGFuZCB3b3JrcyBpbiB3YXlzIHlvdSBtYXkgbm90IGV4cGVjdC4gU2VlIGh0dHBzOi8vZ2l0aHViLmNvbS91dWlkanMvdXVpZC9wdWxsLzQzNFxuICByZXR1cm4gKGJ5dGVUb0hleFthcnJbb2Zmc2V0ICsgMF1dICsgYnl0ZVRvSGV4W2FycltvZmZzZXQgKyAxXV0gKyBieXRlVG9IZXhbYXJyW29mZnNldCArIDJdXSArIGJ5dGVUb0hleFthcnJbb2Zmc2V0ICsgM11dICsgJy0nICsgYnl0ZVRvSGV4W2FycltvZmZzZXQgKyA0XV0gKyBieXRlVG9IZXhbYXJyW29mZnNldCArIDVdXSArICctJyArIGJ5dGVUb0hleFthcnJbb2Zmc2V0ICsgNl1dICsgYnl0ZVRvSGV4W2FycltvZmZzZXQgKyA3XV0gKyAnLScgKyBieXRlVG9IZXhbYXJyW29mZnNldCArIDhdXSArIGJ5dGVUb0hleFthcnJbb2Zmc2V0ICsgOV1dICsgJy0nICsgYnl0ZVRvSGV4W2FycltvZmZzZXQgKyAxMF1dICsgYnl0ZVRvSGV4W2FycltvZmZzZXQgKyAxMV1dICsgYnl0ZVRvSGV4W2FycltvZmZzZXQgKyAxMl1dICsgYnl0ZVRvSGV4W2FycltvZmZzZXQgKyAxM11dICsgYnl0ZVRvSGV4W2FycltvZmZzZXQgKyAxNF1dICsgYnl0ZVRvSGV4W2FycltvZmZzZXQgKyAxNV1dKS50b0xvd2VyQ2FzZSgpO1xufVxuXG5mdW5jdGlvbiBzdHJpbmdpZnkoYXJyLCBvZmZzZXQgPSAwKSB7XG4gIGNvbnN0IHV1aWQgPSB1bnNhZmVTdHJpbmdpZnkoYXJyLCBvZmZzZXQpOyAvLyBDb25zaXN0ZW5jeSBjaGVjayBmb3IgdmFsaWQgVVVJRC4gIElmIHRoaXMgdGhyb3dzLCBpdCdzIGxpa2VseSBkdWUgdG8gb25lXG4gIC8vIG9mIHRoZSBmb2xsb3dpbmc6XG4gIC8vIC0gT25lIG9yIG1vcmUgaW5wdXQgYXJyYXkgdmFsdWVzIGRvbid0IG1hcCB0byBhIGhleCBvY3RldCAobGVhZGluZyB0b1xuICAvLyBcInVuZGVmaW5lZFwiIGluIHRoZSB1dWlkKVxuICAvLyAtIEludmFsaWQgaW5wdXQgdmFsdWVzIGZvciB0aGUgUkZDIGB2ZXJzaW9uYCBvciBgdmFyaWFudGAgZmllbGRzXG5cbiAgaWYgKCEoMCwgX3ZhbGlkYXRlLmRlZmF1bHQpKHV1aWQpKSB7XG4gICAgdGhyb3cgVHlwZUVycm9yKCdTdHJpbmdpZmllZCBVVUlEIGlzIGludmFsaWQnKTtcbiAgfVxuXG4gIHJldHVybiB1dWlkO1xufVxuXG52YXIgX2RlZmF1bHQgPSBzdHJpbmdpZnk7XG5leHBvcnRzLmRlZmF1bHQgPSBfZGVmYXVsdDsiLCJcInVzZSBzdHJpY3RcIjtcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7XG4gIHZhbHVlOiB0cnVlXG59KTtcbmV4cG9ydHMuZGVmYXVsdCA9IHZvaWQgMDtcblxudmFyIF9ybmcgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KHJlcXVpcmUoXCIuL3JuZy5qc1wiKSk7XG5cbnZhciBfc3RyaW5naWZ5ID0gcmVxdWlyZShcIi4vc3RyaW5naWZ5LmpzXCIpO1xuXG5mdW5jdGlvbiBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KG9iaikgeyByZXR1cm4gb2JqICYmIG9iai5fX2VzTW9kdWxlID8gb2JqIDogeyBkZWZhdWx0OiBvYmogfTsgfVxuXG4vLyAqKmB2MSgpYCAtIEdlbmVyYXRlIHRpbWUtYmFzZWQgVVVJRCoqXG4vL1xuLy8gSW5zcGlyZWQgYnkgaHR0cHM6Ly9naXRodWIuY29tL0xpb3NLL1VVSUQuanNcbi8vIGFuZCBodHRwOi8vZG9jcy5weXRob24ub3JnL2xpYnJhcnkvdXVpZC5odG1sXG5sZXQgX25vZGVJZDtcblxubGV0IF9jbG9ja3NlcTsgLy8gUHJldmlvdXMgdXVpZCBjcmVhdGlvbiB0aW1lXG5cblxubGV0IF9sYXN0TVNlY3MgPSAwO1xubGV0IF9sYXN0TlNlY3MgPSAwOyAvLyBTZWUgaHR0cHM6Ly9naXRodWIuY29tL3V1aWRqcy91dWlkIGZvciBBUEkgZGV0YWlsc1xuXG5mdW5jdGlvbiB2MShvcHRpb25zLCBidWYsIG9mZnNldCkge1xuICBsZXQgaSA9IGJ1ZiAmJiBvZmZzZXQgfHwgMDtcbiAgY29uc3QgYiA9IGJ1ZiB8fCBuZXcgQXJyYXkoMTYpO1xuICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fTtcbiAgbGV0IG5vZGUgPSBvcHRpb25zLm5vZGUgfHwgX25vZGVJZDtcbiAgbGV0IGNsb2Nrc2VxID0gb3B0aW9ucy5jbG9ja3NlcSAhPT0gdW5kZWZpbmVkID8gb3B0aW9ucy5jbG9ja3NlcSA6IF9jbG9ja3NlcTsgLy8gbm9kZSBhbmQgY2xvY2tzZXEgbmVlZCB0byBiZSBpbml0aWFsaXplZCB0byByYW5kb20gdmFsdWVzIGlmIHRoZXkncmUgbm90XG4gIC8vIHNwZWNpZmllZC4gIFdlIGRvIHRoaXMgbGF6aWx5IHRvIG1pbmltaXplIGlzc3VlcyByZWxhdGVkIHRvIGluc3VmZmljaWVudFxuICAvLyBzeXN0ZW0gZW50cm9weS4gIFNlZSAjMTg5XG5cbiAgaWYgKG5vZGUgPT0gbnVsbCB8fCBjbG9ja3NlcSA9PSBudWxsKSB7XG4gICAgY29uc3Qgc2VlZEJ5dGVzID0gb3B0aW9ucy5yYW5kb20gfHwgKG9wdGlvbnMucm5nIHx8IF9ybmcuZGVmYXVsdCkoKTtcblxuICAgIGlmIChub2RlID09IG51bGwpIHtcbiAgICAgIC8vIFBlciA0LjUsIGNyZWF0ZSBhbmQgNDgtYml0IG5vZGUgaWQsICg0NyByYW5kb20gYml0cyArIG11bHRpY2FzdCBiaXQgPSAxKVxuICAgICAgbm9kZSA9IF9ub2RlSWQgPSBbc2VlZEJ5dGVzWzBdIHwgMHgwMSwgc2VlZEJ5dGVzWzFdLCBzZWVkQnl0ZXNbMl0sIHNlZWRCeXRlc1szXSwgc2VlZEJ5dGVzWzRdLCBzZWVkQnl0ZXNbNV1dO1xuICAgIH1cblxuICAgIGlmIChjbG9ja3NlcSA9PSBudWxsKSB7XG4gICAgICAvLyBQZXIgNC4yLjIsIHJhbmRvbWl6ZSAoMTQgYml0KSBjbG9ja3NlcVxuICAgICAgY2xvY2tzZXEgPSBfY2xvY2tzZXEgPSAoc2VlZEJ5dGVzWzZdIDw8IDggfCBzZWVkQnl0ZXNbN10pICYgMHgzZmZmO1xuICAgIH1cbiAgfSAvLyBVVUlEIHRpbWVzdGFtcHMgYXJlIDEwMCBuYW5vLXNlY29uZCB1bml0cyBzaW5jZSB0aGUgR3JlZ29yaWFuIGVwb2NoLFxuICAvLyAoMTU4Mi0xMC0xNSAwMDowMCkuICBKU051bWJlcnMgYXJlbid0IHByZWNpc2UgZW5vdWdoIGZvciB0aGlzLCBzb1xuICAvLyB0aW1lIGlzIGhhbmRsZWQgaW50ZXJuYWxseSBhcyAnbXNlY3MnIChpbnRlZ2VyIG1pbGxpc2Vjb25kcykgYW5kICduc2VjcydcbiAgLy8gKDEwMC1uYW5vc2Vjb25kcyBvZmZzZXQgZnJvbSBtc2Vjcykgc2luY2UgdW5peCBlcG9jaCwgMTk3MC0wMS0wMSAwMDowMC5cblxuXG4gIGxldCBtc2VjcyA9IG9wdGlvbnMubXNlY3MgIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMubXNlY3MgOiBEYXRlLm5vdygpOyAvLyBQZXIgNC4yLjEuMiwgdXNlIGNvdW50IG9mIHV1aWQncyBnZW5lcmF0ZWQgZHVyaW5nIHRoZSBjdXJyZW50IGNsb2NrXG4gIC8vIGN5Y2xlIHRvIHNpbXVsYXRlIGhpZ2hlciByZXNvbHV0aW9uIGNsb2NrXG5cbiAgbGV0IG5zZWNzID0gb3B0aW9ucy5uc2VjcyAhPT0gdW5kZWZpbmVkID8gb3B0aW9ucy5uc2VjcyA6IF9sYXN0TlNlY3MgKyAxOyAvLyBUaW1lIHNpbmNlIGxhc3QgdXVpZCBjcmVhdGlvbiAoaW4gbXNlY3MpXG5cbiAgY29uc3QgZHQgPSBtc2VjcyAtIF9sYXN0TVNlY3MgKyAobnNlY3MgLSBfbGFzdE5TZWNzKSAvIDEwMDAwOyAvLyBQZXIgNC4yLjEuMiwgQnVtcCBjbG9ja3NlcSBvbiBjbG9jayByZWdyZXNzaW9uXG5cbiAgaWYgKGR0IDwgMCAmJiBvcHRpb25zLmNsb2Nrc2VxID09PSB1bmRlZmluZWQpIHtcbiAgICBjbG9ja3NlcSA9IGNsb2Nrc2VxICsgMSAmIDB4M2ZmZjtcbiAgfSAvLyBSZXNldCBuc2VjcyBpZiBjbG9jayByZWdyZXNzZXMgKG5ldyBjbG9ja3NlcSkgb3Igd2UndmUgbW92ZWQgb250byBhIG5ld1xuICAvLyB0aW1lIGludGVydmFsXG5cblxuICBpZiAoKGR0IDwgMCB8fCBtc2VjcyA+IF9sYXN0TVNlY3MpICYmIG9wdGlvbnMubnNlY3MgPT09IHVuZGVmaW5lZCkge1xuICAgIG5zZWNzID0gMDtcbiAgfSAvLyBQZXIgNC4yLjEuMiBUaHJvdyBlcnJvciBpZiB0b28gbWFueSB1dWlkcyBhcmUgcmVxdWVzdGVkXG5cblxuICBpZiAobnNlY3MgPj0gMTAwMDApIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXCJ1dWlkLnYxKCk6IENhbid0IGNyZWF0ZSBtb3JlIHRoYW4gMTBNIHV1aWRzL3NlY1wiKTtcbiAgfVxuXG4gIF9sYXN0TVNlY3MgPSBtc2VjcztcbiAgX2xhc3ROU2VjcyA9IG5zZWNzO1xuICBfY2xvY2tzZXEgPSBjbG9ja3NlcTsgLy8gUGVyIDQuMS40IC0gQ29udmVydCBmcm9tIHVuaXggZXBvY2ggdG8gR3JlZ29yaWFuIGVwb2NoXG5cbiAgbXNlY3MgKz0gMTIyMTkyOTI4MDAwMDA7IC8vIGB0aW1lX2xvd2BcblxuICBjb25zdCB0bCA9ICgobXNlY3MgJiAweGZmZmZmZmYpICogMTAwMDAgKyBuc2VjcykgJSAweDEwMDAwMDAwMDtcbiAgYltpKytdID0gdGwgPj4+IDI0ICYgMHhmZjtcbiAgYltpKytdID0gdGwgPj4+IDE2ICYgMHhmZjtcbiAgYltpKytdID0gdGwgPj4+IDggJiAweGZmO1xuICBiW2krK10gPSB0bCAmIDB4ZmY7IC8vIGB0aW1lX21pZGBcblxuICBjb25zdCB0bWggPSBtc2VjcyAvIDB4MTAwMDAwMDAwICogMTAwMDAgJiAweGZmZmZmZmY7XG4gIGJbaSsrXSA9IHRtaCA+Pj4gOCAmIDB4ZmY7XG4gIGJbaSsrXSA9IHRtaCAmIDB4ZmY7IC8vIGB0aW1lX2hpZ2hfYW5kX3ZlcnNpb25gXG5cbiAgYltpKytdID0gdG1oID4+PiAyNCAmIDB4ZiB8IDB4MTA7IC8vIGluY2x1ZGUgdmVyc2lvblxuXG4gIGJbaSsrXSA9IHRtaCA+Pj4gMTYgJiAweGZmOyAvLyBgY2xvY2tfc2VxX2hpX2FuZF9yZXNlcnZlZGAgKFBlciA0LjIuMiAtIGluY2x1ZGUgdmFyaWFudClcblxuICBiW2krK10gPSBjbG9ja3NlcSA+Pj4gOCB8IDB4ODA7IC8vIGBjbG9ja19zZXFfbG93YFxuXG4gIGJbaSsrXSA9IGNsb2Nrc2VxICYgMHhmZjsgLy8gYG5vZGVgXG5cbiAgZm9yIChsZXQgbiA9IDA7IG4gPCA2OyArK24pIHtcbiAgICBiW2kgKyBuXSA9IG5vZGVbbl07XG4gIH1cblxuICByZXR1cm4gYnVmIHx8ICgwLCBfc3RyaW5naWZ5LnVuc2FmZVN0cmluZ2lmeSkoYik7XG59XG5cbnZhciBfZGVmYXVsdCA9IHYxO1xuZXhwb3J0cy5kZWZhdWx0ID0gX2RlZmF1bHQ7IiwiXCJ1c2Ugc3RyaWN0XCI7XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwge1xuICB2YWx1ZTogdHJ1ZVxufSk7XG5leHBvcnRzLmRlZmF1bHQgPSB2b2lkIDA7XG5cbnZhciBfdiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQocmVxdWlyZShcIi4vdjM1LmpzXCIpKTtcblxudmFyIF9tZCA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQocmVxdWlyZShcIi4vbWQ1LmpzXCIpKTtcblxuZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChvYmopIHsgcmV0dXJuIG9iaiAmJiBvYmouX19lc01vZHVsZSA/IG9iaiA6IHsgZGVmYXVsdDogb2JqIH07IH1cblxuY29uc3QgdjMgPSAoMCwgX3YuZGVmYXVsdCkoJ3YzJywgMHgzMCwgX21kLmRlZmF1bHQpO1xudmFyIF9kZWZhdWx0ID0gdjM7XG5leHBvcnRzLmRlZmF1bHQgPSBfZGVmYXVsdDsiLCJcInVzZSBzdHJpY3RcIjtcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7XG4gIHZhbHVlOiB0cnVlXG59KTtcbmV4cG9ydHMuVVJMID0gZXhwb3J0cy5ETlMgPSB2b2lkIDA7XG5leHBvcnRzLmRlZmF1bHQgPSB2MzU7XG5cbnZhciBfc3RyaW5naWZ5ID0gcmVxdWlyZShcIi4vc3RyaW5naWZ5LmpzXCIpO1xuXG52YXIgX3BhcnNlID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChyZXF1aXJlKFwiLi9wYXJzZS5qc1wiKSk7XG5cbmZ1bmN0aW9uIF9pbnRlcm9wUmVxdWlyZURlZmF1bHQob2JqKSB7IHJldHVybiBvYmogJiYgb2JqLl9fZXNNb2R1bGUgPyBvYmogOiB7IGRlZmF1bHQ6IG9iaiB9OyB9XG5cbmZ1bmN0aW9uIHN0cmluZ1RvQnl0ZXMoc3RyKSB7XG4gIHN0ciA9IHVuZXNjYXBlKGVuY29kZVVSSUNvbXBvbmVudChzdHIpKTsgLy8gVVRGOCBlc2NhcGVcblxuICBjb25zdCBieXRlcyA9IFtdO1xuXG4gIGZvciAobGV0IGkgPSAwOyBpIDwgc3RyLmxlbmd0aDsgKytpKSB7XG4gICAgYnl0ZXMucHVzaChzdHIuY2hhckNvZGVBdChpKSk7XG4gIH1cblxuICByZXR1cm4gYnl0ZXM7XG59XG5cbmNvbnN0IEROUyA9ICc2YmE3YjgxMC05ZGFkLTExZDEtODBiNC0wMGMwNGZkNDMwYzgnO1xuZXhwb3J0cy5ETlMgPSBETlM7XG5jb25zdCBVUkwgPSAnNmJhN2I4MTEtOWRhZC0xMWQxLTgwYjQtMDBjMDRmZDQzMGM4JztcbmV4cG9ydHMuVVJMID0gVVJMO1xuXG5mdW5jdGlvbiB2MzUobmFtZSwgdmVyc2lvbiwgaGFzaGZ1bmMpIHtcbiAgZnVuY3Rpb24gZ2VuZXJhdGVVVUlEKHZhbHVlLCBuYW1lc3BhY2UsIGJ1Ziwgb2Zmc2V0KSB7XG4gICAgdmFyIF9uYW1lc3BhY2U7XG5cbiAgICBpZiAodHlwZW9mIHZhbHVlID09PSAnc3RyaW5nJykge1xuICAgICAgdmFsdWUgPSBzdHJpbmdUb0J5dGVzKHZhbHVlKTtcbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIG5hbWVzcGFjZSA9PT0gJ3N0cmluZycpIHtcbiAgICAgIG5hbWVzcGFjZSA9ICgwLCBfcGFyc2UuZGVmYXVsdCkobmFtZXNwYWNlKTtcbiAgICB9XG5cbiAgICBpZiAoKChfbmFtZXNwYWNlID0gbmFtZXNwYWNlKSA9PT0gbnVsbCB8fCBfbmFtZXNwYWNlID09PSB2b2lkIDAgPyB2b2lkIDAgOiBfbmFtZXNwYWNlLmxlbmd0aCkgIT09IDE2KSB7XG4gICAgICB0aHJvdyBUeXBlRXJyb3IoJ05hbWVzcGFjZSBtdXN0IGJlIGFycmF5LWxpa2UgKDE2IGl0ZXJhYmxlIGludGVnZXIgdmFsdWVzLCAwLTI1NSknKTtcbiAgICB9IC8vIENvbXB1dGUgaGFzaCBvZiBuYW1lc3BhY2UgYW5kIHZhbHVlLCBQZXIgNC4zXG4gICAgLy8gRnV0dXJlOiBVc2Ugc3ByZWFkIHN5bnRheCB3aGVuIHN1cHBvcnRlZCBvbiBhbGwgcGxhdGZvcm1zLCBlLmcuIGBieXRlcyA9XG4gICAgLy8gaGFzaGZ1bmMoWy4uLm5hbWVzcGFjZSwgLi4uIHZhbHVlXSlgXG5cblxuICAgIGxldCBieXRlcyA9IG5ldyBVaW50OEFycmF5KDE2ICsgdmFsdWUubGVuZ3RoKTtcbiAgICBieXRlcy5zZXQobmFtZXNwYWNlKTtcbiAgICBieXRlcy5zZXQodmFsdWUsIG5hbWVzcGFjZS5sZW5ndGgpO1xuICAgIGJ5dGVzID0gaGFzaGZ1bmMoYnl0ZXMpO1xuICAgIGJ5dGVzWzZdID0gYnl0ZXNbNl0gJiAweDBmIHwgdmVyc2lvbjtcbiAgICBieXRlc1s4XSA9IGJ5dGVzWzhdICYgMHgzZiB8IDB4ODA7XG5cbiAgICBpZiAoYnVmKSB7XG4gICAgICBvZmZzZXQgPSBvZmZzZXQgfHwgMDtcblxuICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCAxNjsgKytpKSB7XG4gICAgICAgIGJ1ZltvZmZzZXQgKyBpXSA9IGJ5dGVzW2ldO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gYnVmO1xuICAgIH1cblxuICAgIHJldHVybiAoMCwgX3N0cmluZ2lmeS51bnNhZmVTdHJpbmdpZnkpKGJ5dGVzKTtcbiAgfSAvLyBGdW5jdGlvbiNuYW1lIGlzIG5vdCBzZXR0YWJsZSBvbiBzb21lIHBsYXRmb3JtcyAoIzI3MClcblxuXG4gIHRyeSB7XG4gICAgZ2VuZXJhdGVVVUlELm5hbWUgPSBuYW1lOyAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tZW1wdHlcbiAgfSBjYXRjaCAoZXJyKSB7fSAvLyBGb3IgQ29tbW9uSlMgZGVmYXVsdCBleHBvcnQgc3VwcG9ydFxuXG5cbiAgZ2VuZXJhdGVVVUlELkROUyA9IEROUztcbiAgZ2VuZXJhdGVVVUlELlVSTCA9IFVSTDtcbiAgcmV0dXJuIGdlbmVyYXRlVVVJRDtcbn0iLCJcInVzZSBzdHJpY3RcIjtcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7XG4gIHZhbHVlOiB0cnVlXG59KTtcbmV4cG9ydHMuZGVmYXVsdCA9IHZvaWQgMDtcblxudmFyIF9uYXRpdmUgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KHJlcXVpcmUoXCIuL25hdGl2ZS5qc1wiKSk7XG5cbnZhciBfcm5nID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChyZXF1aXJlKFwiLi9ybmcuanNcIikpO1xuXG52YXIgX3N0cmluZ2lmeSA9IHJlcXVpcmUoXCIuL3N0cmluZ2lmeS5qc1wiKTtcblxuZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChvYmopIHsgcmV0dXJuIG9iaiAmJiBvYmouX19lc01vZHVsZSA/IG9iaiA6IHsgZGVmYXVsdDogb2JqIH07IH1cblxuZnVuY3Rpb24gdjQob3B0aW9ucywgYnVmLCBvZmZzZXQpIHtcbiAgaWYgKF9uYXRpdmUuZGVmYXVsdC5yYW5kb21VVUlEICYmICFidWYgJiYgIW9wdGlvbnMpIHtcbiAgICByZXR1cm4gX25hdGl2ZS5kZWZhdWx0LnJhbmRvbVVVSUQoKTtcbiAgfVxuXG4gIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9O1xuXG4gIGNvbnN0IHJuZHMgPSBvcHRpb25zLnJhbmRvbSB8fCAob3B0aW9ucy5ybmcgfHwgX3JuZy5kZWZhdWx0KSgpOyAvLyBQZXIgNC40LCBzZXQgYml0cyBmb3IgdmVyc2lvbiBhbmQgYGNsb2NrX3NlcV9oaV9hbmRfcmVzZXJ2ZWRgXG5cblxuICBybmRzWzZdID0gcm5kc1s2XSAmIDB4MGYgfCAweDQwO1xuICBybmRzWzhdID0gcm5kc1s4XSAmIDB4M2YgfCAweDgwOyAvLyBDb3B5IGJ5dGVzIHRvIGJ1ZmZlciwgaWYgcHJvdmlkZWRcblxuICBpZiAoYnVmKSB7XG4gICAgb2Zmc2V0ID0gb2Zmc2V0IHx8IDA7XG5cbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IDE2OyArK2kpIHtcbiAgICAgIGJ1ZltvZmZzZXQgKyBpXSA9IHJuZHNbaV07XG4gICAgfVxuXG4gICAgcmV0dXJuIGJ1ZjtcbiAgfVxuXG4gIHJldHVybiAoMCwgX3N0cmluZ2lmeS51bnNhZmVTdHJpbmdpZnkpKHJuZHMpO1xufVxuXG52YXIgX2RlZmF1bHQgPSB2NDtcbmV4cG9ydHMuZGVmYXVsdCA9IF9kZWZhdWx0OyIsIlwidXNlIHN0cmljdFwiO1xuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHtcbiAgdmFsdWU6IHRydWVcbn0pO1xuZXhwb3J0cy5kZWZhdWx0ID0gdm9pZCAwO1xuXG52YXIgX3YgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KHJlcXVpcmUoXCIuL3YzNS5qc1wiKSk7XG5cbnZhciBfc2hhID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChyZXF1aXJlKFwiLi9zaGExLmpzXCIpKTtcblxuZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChvYmopIHsgcmV0dXJuIG9iaiAmJiBvYmouX19lc01vZHVsZSA/IG9iaiA6IHsgZGVmYXVsdDogb2JqIH07IH1cblxuY29uc3QgdjUgPSAoMCwgX3YuZGVmYXVsdCkoJ3Y1JywgMHg1MCwgX3NoYS5kZWZhdWx0KTtcbnZhciBfZGVmYXVsdCA9IHY1O1xuZXhwb3J0cy5kZWZhdWx0ID0gX2RlZmF1bHQ7IiwiXCJ1c2Ugc3RyaWN0XCI7XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwge1xuICB2YWx1ZTogdHJ1ZVxufSk7XG5leHBvcnRzLmRlZmF1bHQgPSB2b2lkIDA7XG5cbnZhciBfcmVnZXggPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KHJlcXVpcmUoXCIuL3JlZ2V4LmpzXCIpKTtcblxuZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChvYmopIHsgcmV0dXJuIG9iaiAmJiBvYmouX19lc01vZHVsZSA/IG9iaiA6IHsgZGVmYXVsdDogb2JqIH07IH1cblxuZnVuY3Rpb24gdmFsaWRhdGUodXVpZCkge1xuICByZXR1cm4gdHlwZW9mIHV1aWQgPT09ICdzdHJpbmcnICYmIF9yZWdleC5kZWZhdWx0LnRlc3QodXVpZCk7XG59XG5cbnZhciBfZGVmYXVsdCA9IHZhbGlkYXRlO1xuZXhwb3J0cy5kZWZhdWx0ID0gX2RlZmF1bHQ7IiwiXCJ1c2Ugc3RyaWN0XCI7XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwge1xuICB2YWx1ZTogdHJ1ZVxufSk7XG5leHBvcnRzLmRlZmF1bHQgPSB2b2lkIDA7XG5cbnZhciBfdmFsaWRhdGUgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KHJlcXVpcmUoXCIuL3ZhbGlkYXRlLmpzXCIpKTtcblxuZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChvYmopIHsgcmV0dXJuIG9iaiAmJiBvYmouX19lc01vZHVsZSA/IG9iaiA6IHsgZGVmYXVsdDogb2JqIH07IH1cblxuZnVuY3Rpb24gdmVyc2lvbih1dWlkKSB7XG4gIGlmICghKDAsIF92YWxpZGF0ZS5kZWZhdWx0KSh1dWlkKSkge1xuICAgIHRocm93IFR5cGVFcnJvcignSW52YWxpZCBVVUlEJyk7XG4gIH1cblxuICByZXR1cm4gcGFyc2VJbnQodXVpZC5zbGljZSgxNCwgMTUpLCAxNik7XG59XG5cbnZhciBfZGVmYXVsdCA9IHZlcnNpb247XG5leHBvcnRzLmRlZmF1bHQgPSBfZGVmYXVsdDsiLCIvKipcbiAqIG1hcmtlZCB2NC4yLjEyIC0gYSBtYXJrZG93biBwYXJzZXJcbiAqIENvcHlyaWdodCAoYykgMjAxMS0yMDIzLCBDaHJpc3RvcGhlciBKZWZmcmV5LiAoTUlUIExpY2Vuc2VkKVxuICogaHR0cHM6Ly9naXRodWIuY29tL21hcmtlZGpzL21hcmtlZFxuICovXG5cbi8qKlxuICogRE8gTk9UIEVESVQgVEhJUyBGSUxFXG4gKiBUaGUgY29kZSBpbiB0aGlzIGZpbGUgaXMgZ2VuZXJhdGVkIGZyb20gZmlsZXMgaW4gLi9zcmMvXG4gKi9cblxuJ3VzZSBzdHJpY3QnO1xuXG5mdW5jdGlvbiBfZGVmaW5lUHJvcGVydGllcyh0YXJnZXQsIHByb3BzKSB7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgcHJvcHMubGVuZ3RoOyBpKyspIHtcbiAgICB2YXIgZGVzY3JpcHRvciA9IHByb3BzW2ldO1xuICAgIGRlc2NyaXB0b3IuZW51bWVyYWJsZSA9IGRlc2NyaXB0b3IuZW51bWVyYWJsZSB8fCBmYWxzZTtcbiAgICBkZXNjcmlwdG9yLmNvbmZpZ3VyYWJsZSA9IHRydWU7XG4gICAgaWYgKFwidmFsdWVcIiBpbiBkZXNjcmlwdG9yKSBkZXNjcmlwdG9yLndyaXRhYmxlID0gdHJ1ZTtcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkodGFyZ2V0LCBfdG9Qcm9wZXJ0eUtleShkZXNjcmlwdG9yLmtleSksIGRlc2NyaXB0b3IpO1xuICB9XG59XG5mdW5jdGlvbiBfY3JlYXRlQ2xhc3MoQ29uc3RydWN0b3IsIHByb3RvUHJvcHMsIHN0YXRpY1Byb3BzKSB7XG4gIGlmIChwcm90b1Byb3BzKSBfZGVmaW5lUHJvcGVydGllcyhDb25zdHJ1Y3Rvci5wcm90b3R5cGUsIHByb3RvUHJvcHMpO1xuICBpZiAoc3RhdGljUHJvcHMpIF9kZWZpbmVQcm9wZXJ0aWVzKENvbnN0cnVjdG9yLCBzdGF0aWNQcm9wcyk7XG4gIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShDb25zdHJ1Y3RvciwgXCJwcm90b3R5cGVcIiwge1xuICAgIHdyaXRhYmxlOiBmYWxzZVxuICB9KTtcbiAgcmV0dXJuIENvbnN0cnVjdG9yO1xufVxuZnVuY3Rpb24gX3Vuc3VwcG9ydGVkSXRlcmFibGVUb0FycmF5KG8sIG1pbkxlbikge1xuICBpZiAoIW8pIHJldHVybjtcbiAgaWYgKHR5cGVvZiBvID09PSBcInN0cmluZ1wiKSByZXR1cm4gX2FycmF5TGlrZVRvQXJyYXkobywgbWluTGVuKTtcbiAgdmFyIG4gPSBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwobykuc2xpY2UoOCwgLTEpO1xuICBpZiAobiA9PT0gXCJPYmplY3RcIiAmJiBvLmNvbnN0cnVjdG9yKSBuID0gby5jb25zdHJ1Y3Rvci5uYW1lO1xuICBpZiAobiA9PT0gXCJNYXBcIiB8fCBuID09PSBcIlNldFwiKSByZXR1cm4gQXJyYXkuZnJvbShvKTtcbiAgaWYgKG4gPT09IFwiQXJndW1lbnRzXCIgfHwgL14oPzpVaXxJKW50KD86OHwxNnwzMikoPzpDbGFtcGVkKT9BcnJheSQvLnRlc3QobikpIHJldHVybiBfYXJyYXlMaWtlVG9BcnJheShvLCBtaW5MZW4pO1xufVxuZnVuY3Rpb24gX2FycmF5TGlrZVRvQXJyYXkoYXJyLCBsZW4pIHtcbiAgaWYgKGxlbiA9PSBudWxsIHx8IGxlbiA+IGFyci5sZW5ndGgpIGxlbiA9IGFyci5sZW5ndGg7XG4gIGZvciAodmFyIGkgPSAwLCBhcnIyID0gbmV3IEFycmF5KGxlbik7IGkgPCBsZW47IGkrKykgYXJyMltpXSA9IGFycltpXTtcbiAgcmV0dXJuIGFycjI7XG59XG5mdW5jdGlvbiBfY3JlYXRlRm9yT2ZJdGVyYXRvckhlbHBlckxvb3NlKG8sIGFsbG93QXJyYXlMaWtlKSB7XG4gIHZhciBpdCA9IHR5cGVvZiBTeW1ib2wgIT09IFwidW5kZWZpbmVkXCIgJiYgb1tTeW1ib2wuaXRlcmF0b3JdIHx8IG9bXCJAQGl0ZXJhdG9yXCJdO1xuICBpZiAoaXQpIHJldHVybiAoaXQgPSBpdC5jYWxsKG8pKS5uZXh0LmJpbmQoaXQpO1xuICBpZiAoQXJyYXkuaXNBcnJheShvKSB8fCAoaXQgPSBfdW5zdXBwb3J0ZWRJdGVyYWJsZVRvQXJyYXkobykpIHx8IGFsbG93QXJyYXlMaWtlICYmIG8gJiYgdHlwZW9mIG8ubGVuZ3RoID09PSBcIm51bWJlclwiKSB7XG4gICAgaWYgKGl0KSBvID0gaXQ7XG4gICAgdmFyIGkgPSAwO1xuICAgIHJldHVybiBmdW5jdGlvbiAoKSB7XG4gICAgICBpZiAoaSA+PSBvLmxlbmd0aCkgcmV0dXJuIHtcbiAgICAgICAgZG9uZTogdHJ1ZVxuICAgICAgfTtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIGRvbmU6IGZhbHNlLFxuICAgICAgICB2YWx1ZTogb1tpKytdXG4gICAgICB9O1xuICAgIH07XG4gIH1cbiAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkludmFsaWQgYXR0ZW1wdCB0byBpdGVyYXRlIG5vbi1pdGVyYWJsZSBpbnN0YW5jZS5cXG5JbiBvcmRlciB0byBiZSBpdGVyYWJsZSwgbm9uLWFycmF5IG9iamVjdHMgbXVzdCBoYXZlIGEgW1N5bWJvbC5pdGVyYXRvcl0oKSBtZXRob2QuXCIpO1xufVxuZnVuY3Rpb24gX3RvUHJpbWl0aXZlKGlucHV0LCBoaW50KSB7XG4gIGlmICh0eXBlb2YgaW5wdXQgIT09IFwib2JqZWN0XCIgfHwgaW5wdXQgPT09IG51bGwpIHJldHVybiBpbnB1dDtcbiAgdmFyIHByaW0gPSBpbnB1dFtTeW1ib2wudG9QcmltaXRpdmVdO1xuICBpZiAocHJpbSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgdmFyIHJlcyA9IHByaW0uY2FsbChpbnB1dCwgaGludCB8fCBcImRlZmF1bHRcIik7XG4gICAgaWYgKHR5cGVvZiByZXMgIT09IFwib2JqZWN0XCIpIHJldHVybiByZXM7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkBAdG9QcmltaXRpdmUgbXVzdCByZXR1cm4gYSBwcmltaXRpdmUgdmFsdWUuXCIpO1xuICB9XG4gIHJldHVybiAoaGludCA9PT0gXCJzdHJpbmdcIiA/IFN0cmluZyA6IE51bWJlcikoaW5wdXQpO1xufVxuZnVuY3Rpb24gX3RvUHJvcGVydHlLZXkoYXJnKSB7XG4gIHZhciBrZXkgPSBfdG9QcmltaXRpdmUoYXJnLCBcInN0cmluZ1wiKTtcbiAgcmV0dXJuIHR5cGVvZiBrZXkgPT09IFwic3ltYm9sXCIgPyBrZXkgOiBTdHJpbmcoa2V5KTtcbn1cblxuZnVuY3Rpb24gZ2V0RGVmYXVsdHMoKSB7XG4gIHJldHVybiB7XG4gICAgYXN5bmM6IGZhbHNlLFxuICAgIGJhc2VVcmw6IG51bGwsXG4gICAgYnJlYWtzOiBmYWxzZSxcbiAgICBleHRlbnNpb25zOiBudWxsLFxuICAgIGdmbTogdHJ1ZSxcbiAgICBoZWFkZXJJZHM6IHRydWUsXG4gICAgaGVhZGVyUHJlZml4OiAnJyxcbiAgICBoaWdobGlnaHQ6IG51bGwsXG4gICAgbGFuZ1ByZWZpeDogJ2xhbmd1YWdlLScsXG4gICAgbWFuZ2xlOiB0cnVlLFxuICAgIHBlZGFudGljOiBmYWxzZSxcbiAgICByZW5kZXJlcjogbnVsbCxcbiAgICBzYW5pdGl6ZTogZmFsc2UsXG4gICAgc2FuaXRpemVyOiBudWxsLFxuICAgIHNpbGVudDogZmFsc2UsXG4gICAgc21hcnR5cGFudHM6IGZhbHNlLFxuICAgIHRva2VuaXplcjogbnVsbCxcbiAgICB3YWxrVG9rZW5zOiBudWxsLFxuICAgIHhodG1sOiBmYWxzZVxuICB9O1xufVxuZXhwb3J0cy5kZWZhdWx0cyA9IGdldERlZmF1bHRzKCk7XG5mdW5jdGlvbiBjaGFuZ2VEZWZhdWx0cyhuZXdEZWZhdWx0cykge1xuICBleHBvcnRzLmRlZmF1bHRzID0gbmV3RGVmYXVsdHM7XG59XG5cbi8qKlxuICogSGVscGVyc1xuICovXG52YXIgZXNjYXBlVGVzdCA9IC9bJjw+XCInXS87XG52YXIgZXNjYXBlUmVwbGFjZSA9IG5ldyBSZWdFeHAoZXNjYXBlVGVzdC5zb3VyY2UsICdnJyk7XG52YXIgZXNjYXBlVGVzdE5vRW5jb2RlID0gL1s8PlwiJ118Jig/ISgjXFxkezEsN318I1tYeF1bYS1mQS1GMC05XXsxLDZ9fFxcdyspOykvO1xudmFyIGVzY2FwZVJlcGxhY2VOb0VuY29kZSA9IG5ldyBSZWdFeHAoZXNjYXBlVGVzdE5vRW5jb2RlLnNvdXJjZSwgJ2cnKTtcbnZhciBlc2NhcGVSZXBsYWNlbWVudHMgPSB7XG4gICcmJzogJyZhbXA7JyxcbiAgJzwnOiAnJmx0OycsXG4gICc+JzogJyZndDsnLFxuICAnXCInOiAnJnF1b3Q7JyxcbiAgXCInXCI6ICcmIzM5Oydcbn07XG52YXIgZ2V0RXNjYXBlUmVwbGFjZW1lbnQgPSBmdW5jdGlvbiBnZXRFc2NhcGVSZXBsYWNlbWVudChjaCkge1xuICByZXR1cm4gZXNjYXBlUmVwbGFjZW1lbnRzW2NoXTtcbn07XG5mdW5jdGlvbiBlc2NhcGUoaHRtbCwgZW5jb2RlKSB7XG4gIGlmIChlbmNvZGUpIHtcbiAgICBpZiAoZXNjYXBlVGVzdC50ZXN0KGh0bWwpKSB7XG4gICAgICByZXR1cm4gaHRtbC5yZXBsYWNlKGVzY2FwZVJlcGxhY2UsIGdldEVzY2FwZVJlcGxhY2VtZW50KTtcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgaWYgKGVzY2FwZVRlc3ROb0VuY29kZS50ZXN0KGh0bWwpKSB7XG4gICAgICByZXR1cm4gaHRtbC5yZXBsYWNlKGVzY2FwZVJlcGxhY2VOb0VuY29kZSwgZ2V0RXNjYXBlUmVwbGFjZW1lbnQpO1xuICAgIH1cbiAgfVxuICByZXR1cm4gaHRtbDtcbn1cbnZhciB1bmVzY2FwZVRlc3QgPSAvJigjKD86XFxkKyl8KD86I3hbMC05QS1GYS1mXSspfCg/OlxcdyspKTs/L2lnO1xuXG4vKipcbiAqIEBwYXJhbSB7c3RyaW5nfSBodG1sXG4gKi9cbmZ1bmN0aW9uIHVuZXNjYXBlKGh0bWwpIHtcbiAgLy8gZXhwbGljaXRseSBtYXRjaCBkZWNpbWFsLCBoZXgsIGFuZCBuYW1lZCBIVE1MIGVudGl0aWVzXG4gIHJldHVybiBodG1sLnJlcGxhY2UodW5lc2NhcGVUZXN0LCBmdW5jdGlvbiAoXywgbikge1xuICAgIG4gPSBuLnRvTG93ZXJDYXNlKCk7XG4gICAgaWYgKG4gPT09ICdjb2xvbicpIHJldHVybiAnOic7XG4gICAgaWYgKG4uY2hhckF0KDApID09PSAnIycpIHtcbiAgICAgIHJldHVybiBuLmNoYXJBdCgxKSA9PT0gJ3gnID8gU3RyaW5nLmZyb21DaGFyQ29kZShwYXJzZUludChuLnN1YnN0cmluZygyKSwgMTYpKSA6IFN0cmluZy5mcm9tQ2hhckNvZGUoK24uc3Vic3RyaW5nKDEpKTtcbiAgICB9XG4gICAgcmV0dXJuICcnO1xuICB9KTtcbn1cbnZhciBjYXJldCA9IC8oXnxbXlxcW10pXFxeL2c7XG5cbi8qKlxuICogQHBhcmFtIHtzdHJpbmcgfCBSZWdFeHB9IHJlZ2V4XG4gKiBAcGFyYW0ge3N0cmluZ30gb3B0XG4gKi9cbmZ1bmN0aW9uIGVkaXQocmVnZXgsIG9wdCkge1xuICByZWdleCA9IHR5cGVvZiByZWdleCA9PT0gJ3N0cmluZycgPyByZWdleCA6IHJlZ2V4LnNvdXJjZTtcbiAgb3B0ID0gb3B0IHx8ICcnO1xuICB2YXIgb2JqID0ge1xuICAgIHJlcGxhY2U6IGZ1bmN0aW9uIHJlcGxhY2UobmFtZSwgdmFsKSB7XG4gICAgICB2YWwgPSB2YWwuc291cmNlIHx8IHZhbDtcbiAgICAgIHZhbCA9IHZhbC5yZXBsYWNlKGNhcmV0LCAnJDEnKTtcbiAgICAgIHJlZ2V4ID0gcmVnZXgucmVwbGFjZShuYW1lLCB2YWwpO1xuICAgICAgcmV0dXJuIG9iajtcbiAgICB9LFxuICAgIGdldFJlZ2V4OiBmdW5jdGlvbiBnZXRSZWdleCgpIHtcbiAgICAgIHJldHVybiBuZXcgUmVnRXhwKHJlZ2V4LCBvcHQpO1xuICAgIH1cbiAgfTtcbiAgcmV0dXJuIG9iajtcbn1cbnZhciBub25Xb3JkQW5kQ29sb25UZXN0ID0gL1teXFx3Ol0vZztcbnZhciBvcmlnaW5JbmRlcGVuZGVudFVybCA9IC9eJHxeW2Etel1bYS16MC05Ky4tXSo6fF5bPyNdL2k7XG5cbi8qKlxuICogQHBhcmFtIHtib29sZWFufSBzYW5pdGl6ZVxuICogQHBhcmFtIHtzdHJpbmd9IGJhc2VcbiAqIEBwYXJhbSB7c3RyaW5nfSBocmVmXG4gKi9cbmZ1bmN0aW9uIGNsZWFuVXJsKHNhbml0aXplLCBiYXNlLCBocmVmKSB7XG4gIGlmIChzYW5pdGl6ZSkge1xuICAgIHZhciBwcm90O1xuICAgIHRyeSB7XG4gICAgICBwcm90ID0gZGVjb2RlVVJJQ29tcG9uZW50KHVuZXNjYXBlKGhyZWYpKS5yZXBsYWNlKG5vbldvcmRBbmRDb2xvblRlc3QsICcnKS50b0xvd2VyQ2FzZSgpO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgICBpZiAocHJvdC5pbmRleE9mKCdqYXZhc2NyaXB0OicpID09PSAwIHx8IHByb3QuaW5kZXhPZigndmJzY3JpcHQ6JykgPT09IDAgfHwgcHJvdC5pbmRleE9mKCdkYXRhOicpID09PSAwKSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gIH1cbiAgaWYgKGJhc2UgJiYgIW9yaWdpbkluZGVwZW5kZW50VXJsLnRlc3QoaHJlZikpIHtcbiAgICBocmVmID0gcmVzb2x2ZVVybChiYXNlLCBocmVmKTtcbiAgfVxuICB0cnkge1xuICAgIGhyZWYgPSBlbmNvZGVVUkkoaHJlZikucmVwbGFjZSgvJTI1L2csICclJyk7XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuICByZXR1cm4gaHJlZjtcbn1cbnZhciBiYXNlVXJscyA9IHt9O1xudmFyIGp1c3REb21haW4gPSAvXlteOl0rOlxcLypbXi9dKiQvO1xudmFyIHByb3RvY29sID0gL14oW146XSs6KVtcXHNcXFNdKiQvO1xudmFyIGRvbWFpbiA9IC9eKFteOl0rOlxcLypbXi9dKilbXFxzXFxTXSokLztcblxuLyoqXG4gKiBAcGFyYW0ge3N0cmluZ30gYmFzZVxuICogQHBhcmFtIHtzdHJpbmd9IGhyZWZcbiAqL1xuZnVuY3Rpb24gcmVzb2x2ZVVybChiYXNlLCBocmVmKSB7XG4gIGlmICghYmFzZVVybHNbJyAnICsgYmFzZV0pIHtcbiAgICAvLyB3ZSBjYW4gaWdub3JlIGV2ZXJ5dGhpbmcgaW4gYmFzZSBhZnRlciB0aGUgbGFzdCBzbGFzaCBvZiBpdHMgcGF0aCBjb21wb25lbnQsXG4gICAgLy8gYnV0IHdlIG1pZ2h0IG5lZWQgdG8gYWRkIF90aGF0X1xuICAgIC8vIGh0dHBzOi8vdG9vbHMuaWV0Zi5vcmcvaHRtbC9yZmMzOTg2I3NlY3Rpb24tM1xuICAgIGlmIChqdXN0RG9tYWluLnRlc3QoYmFzZSkpIHtcbiAgICAgIGJhc2VVcmxzWycgJyArIGJhc2VdID0gYmFzZSArICcvJztcbiAgICB9IGVsc2Uge1xuICAgICAgYmFzZVVybHNbJyAnICsgYmFzZV0gPSBydHJpbShiYXNlLCAnLycsIHRydWUpO1xuICAgIH1cbiAgfVxuICBiYXNlID0gYmFzZVVybHNbJyAnICsgYmFzZV07XG4gIHZhciByZWxhdGl2ZUJhc2UgPSBiYXNlLmluZGV4T2YoJzonKSA9PT0gLTE7XG4gIGlmIChocmVmLnN1YnN0cmluZygwLCAyKSA9PT0gJy8vJykge1xuICAgIGlmIChyZWxhdGl2ZUJhc2UpIHtcbiAgICAgIHJldHVybiBocmVmO1xuICAgIH1cbiAgICByZXR1cm4gYmFzZS5yZXBsYWNlKHByb3RvY29sLCAnJDEnKSArIGhyZWY7XG4gIH0gZWxzZSBpZiAoaHJlZi5jaGFyQXQoMCkgPT09ICcvJykge1xuICAgIGlmIChyZWxhdGl2ZUJhc2UpIHtcbiAgICAgIHJldHVybiBocmVmO1xuICAgIH1cbiAgICByZXR1cm4gYmFzZS5yZXBsYWNlKGRvbWFpbiwgJyQxJykgKyBocmVmO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiBiYXNlICsgaHJlZjtcbiAgfVxufVxudmFyIG5vb3BUZXN0ID0ge1xuICBleGVjOiBmdW5jdGlvbiBub29wVGVzdCgpIHt9XG59O1xuZnVuY3Rpb24gbWVyZ2Uob2JqKSB7XG4gIHZhciBpID0gMSxcbiAgICB0YXJnZXQsXG4gICAga2V5O1xuICBmb3IgKDsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKykge1xuICAgIHRhcmdldCA9IGFyZ3VtZW50c1tpXTtcbiAgICBmb3IgKGtleSBpbiB0YXJnZXQpIHtcbiAgICAgIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwodGFyZ2V0LCBrZXkpKSB7XG4gICAgICAgIG9ialtrZXldID0gdGFyZ2V0W2tleV07XG4gICAgICB9XG4gICAgfVxuICB9XG4gIHJldHVybiBvYmo7XG59XG5mdW5jdGlvbiBzcGxpdENlbGxzKHRhYmxlUm93LCBjb3VudCkge1xuICAvLyBlbnN1cmUgdGhhdCBldmVyeSBjZWxsLWRlbGltaXRpbmcgcGlwZSBoYXMgYSBzcGFjZVxuICAvLyBiZWZvcmUgaXQgdG8gZGlzdGluZ3Vpc2ggaXQgZnJvbSBhbiBlc2NhcGVkIHBpcGVcbiAgdmFyIHJvdyA9IHRhYmxlUm93LnJlcGxhY2UoL1xcfC9nLCBmdW5jdGlvbiAobWF0Y2gsIG9mZnNldCwgc3RyKSB7XG4gICAgICB2YXIgZXNjYXBlZCA9IGZhbHNlLFxuICAgICAgICBjdXJyID0gb2Zmc2V0O1xuICAgICAgd2hpbGUgKC0tY3VyciA+PSAwICYmIHN0cltjdXJyXSA9PT0gJ1xcXFwnKSB7XG4gICAgICAgIGVzY2FwZWQgPSAhZXNjYXBlZDtcbiAgICAgIH1cbiAgICAgIGlmIChlc2NhcGVkKSB7XG4gICAgICAgIC8vIG9kZCBudW1iZXIgb2Ygc2xhc2hlcyBtZWFucyB8IGlzIGVzY2FwZWRcbiAgICAgICAgLy8gc28gd2UgbGVhdmUgaXQgYWxvbmVcbiAgICAgICAgcmV0dXJuICd8JztcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIGFkZCBzcGFjZSBiZWZvcmUgdW5lc2NhcGVkIHxcbiAgICAgICAgcmV0dXJuICcgfCc7XG4gICAgICB9XG4gICAgfSksXG4gICAgY2VsbHMgPSByb3cuc3BsaXQoLyBcXHwvKTtcbiAgdmFyIGkgPSAwO1xuXG4gIC8vIEZpcnN0L2xhc3QgY2VsbCBpbiBhIHJvdyBjYW5ub3QgYmUgZW1wdHkgaWYgaXQgaGFzIG5vIGxlYWRpbmcvdHJhaWxpbmcgcGlwZVxuICBpZiAoIWNlbGxzWzBdLnRyaW0oKSkge1xuICAgIGNlbGxzLnNoaWZ0KCk7XG4gIH1cbiAgaWYgKGNlbGxzLmxlbmd0aCA+IDAgJiYgIWNlbGxzW2NlbGxzLmxlbmd0aCAtIDFdLnRyaW0oKSkge1xuICAgIGNlbGxzLnBvcCgpO1xuICB9XG4gIGlmIChjZWxscy5sZW5ndGggPiBjb3VudCkge1xuICAgIGNlbGxzLnNwbGljZShjb3VudCk7XG4gIH0gZWxzZSB7XG4gICAgd2hpbGUgKGNlbGxzLmxlbmd0aCA8IGNvdW50KSB7XG4gICAgICBjZWxscy5wdXNoKCcnKTtcbiAgICB9XG4gIH1cbiAgZm9yICg7IGkgPCBjZWxscy5sZW5ndGg7IGkrKykge1xuICAgIC8vIGxlYWRpbmcgb3IgdHJhaWxpbmcgd2hpdGVzcGFjZSBpcyBpZ25vcmVkIHBlciB0aGUgZ2ZtIHNwZWNcbiAgICBjZWxsc1tpXSA9IGNlbGxzW2ldLnRyaW0oKS5yZXBsYWNlKC9cXFxcXFx8L2csICd8Jyk7XG4gIH1cbiAgcmV0dXJuIGNlbGxzO1xufVxuXG4vKipcbiAqIFJlbW92ZSB0cmFpbGluZyAnYydzLiBFcXVpdmFsZW50IHRvIHN0ci5yZXBsYWNlKC9jKiQvLCAnJykuXG4gKiAvYyokLyBpcyB2dWxuZXJhYmxlIHRvIFJFRE9TLlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBzdHJcbiAqIEBwYXJhbSB7c3RyaW5nfSBjXG4gKiBAcGFyYW0ge2Jvb2xlYW59IGludmVydCBSZW1vdmUgc3VmZml4IG9mIG5vbi1jIGNoYXJzIGluc3RlYWQuIERlZmF1bHQgZmFsc2V5LlxuICovXG5mdW5jdGlvbiBydHJpbShzdHIsIGMsIGludmVydCkge1xuICB2YXIgbCA9IHN0ci5sZW5ndGg7XG4gIGlmIChsID09PSAwKSB7XG4gICAgcmV0dXJuICcnO1xuICB9XG5cbiAgLy8gTGVuZ3RoIG9mIHN1ZmZpeCBtYXRjaGluZyB0aGUgaW52ZXJ0IGNvbmRpdGlvbi5cbiAgdmFyIHN1ZmZMZW4gPSAwO1xuXG4gIC8vIFN0ZXAgbGVmdCB1bnRpbCB3ZSBmYWlsIHRvIG1hdGNoIHRoZSBpbnZlcnQgY29uZGl0aW9uLlxuICB3aGlsZSAoc3VmZkxlbiA8IGwpIHtcbiAgICB2YXIgY3VyckNoYXIgPSBzdHIuY2hhckF0KGwgLSBzdWZmTGVuIC0gMSk7XG4gICAgaWYgKGN1cnJDaGFyID09PSBjICYmICFpbnZlcnQpIHtcbiAgICAgIHN1ZmZMZW4rKztcbiAgICB9IGVsc2UgaWYgKGN1cnJDaGFyICE9PSBjICYmIGludmVydCkge1xuICAgICAgc3VmZkxlbisrO1xuICAgIH0gZWxzZSB7XG4gICAgICBicmVhaztcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHN0ci5zbGljZSgwLCBsIC0gc3VmZkxlbik7XG59XG5mdW5jdGlvbiBmaW5kQ2xvc2luZ0JyYWNrZXQoc3RyLCBiKSB7XG4gIGlmIChzdHIuaW5kZXhPZihiWzFdKSA9PT0gLTEpIHtcbiAgICByZXR1cm4gLTE7XG4gIH1cbiAgdmFyIGwgPSBzdHIubGVuZ3RoO1xuICB2YXIgbGV2ZWwgPSAwLFxuICAgIGkgPSAwO1xuICBmb3IgKDsgaSA8IGw7IGkrKykge1xuICAgIGlmIChzdHJbaV0gPT09ICdcXFxcJykge1xuICAgICAgaSsrO1xuICAgIH0gZWxzZSBpZiAoc3RyW2ldID09PSBiWzBdKSB7XG4gICAgICBsZXZlbCsrO1xuICAgIH0gZWxzZSBpZiAoc3RyW2ldID09PSBiWzFdKSB7XG4gICAgICBsZXZlbC0tO1xuICAgICAgaWYgKGxldmVsIDwgMCkge1xuICAgICAgICByZXR1cm4gaTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgcmV0dXJuIC0xO1xufVxuZnVuY3Rpb24gY2hlY2tTYW5pdGl6ZURlcHJlY2F0aW9uKG9wdCkge1xuICBpZiAob3B0ICYmIG9wdC5zYW5pdGl6ZSAmJiAhb3B0LnNpbGVudCkge1xuICAgIGNvbnNvbGUud2FybignbWFya2VkKCk6IHNhbml0aXplIGFuZCBzYW5pdGl6ZXIgcGFyYW1ldGVycyBhcmUgZGVwcmVjYXRlZCBzaW5jZSB2ZXJzaW9uIDAuNy4wLCBzaG91bGQgbm90IGJlIHVzZWQgYW5kIHdpbGwgYmUgcmVtb3ZlZCBpbiB0aGUgZnV0dXJlLiBSZWFkIG1vcmUgaGVyZTogaHR0cHM6Ly9tYXJrZWQuanMub3JnLyMvVVNJTkdfQURWQU5DRUQubWQjb3B0aW9ucycpO1xuICB9XG59XG5cbi8vIGNvcGllZCBmcm9tIGh0dHBzOi8vc3RhY2tvdmVyZmxvdy5jb20vYS81NDUwMTEzLzgwNjc3N1xuLyoqXG4gKiBAcGFyYW0ge3N0cmluZ30gcGF0dGVyblxuICogQHBhcmFtIHtudW1iZXJ9IGNvdW50XG4gKi9cbmZ1bmN0aW9uIHJlcGVhdFN0cmluZyhwYXR0ZXJuLCBjb3VudCkge1xuICBpZiAoY291bnQgPCAxKSB7XG4gICAgcmV0dXJuICcnO1xuICB9XG4gIHZhciByZXN1bHQgPSAnJztcbiAgd2hpbGUgKGNvdW50ID4gMSkge1xuICAgIGlmIChjb3VudCAmIDEpIHtcbiAgICAgIHJlc3VsdCArPSBwYXR0ZXJuO1xuICAgIH1cbiAgICBjb3VudCA+Pj0gMTtcbiAgICBwYXR0ZXJuICs9IHBhdHRlcm47XG4gIH1cbiAgcmV0dXJuIHJlc3VsdCArIHBhdHRlcm47XG59XG5cbmZ1bmN0aW9uIG91dHB1dExpbmsoY2FwLCBsaW5rLCByYXcsIGxleGVyKSB7XG4gIHZhciBocmVmID0gbGluay5ocmVmO1xuICB2YXIgdGl0bGUgPSBsaW5rLnRpdGxlID8gZXNjYXBlKGxpbmsudGl0bGUpIDogbnVsbDtcbiAgdmFyIHRleHQgPSBjYXBbMV0ucmVwbGFjZSgvXFxcXChbXFxbXFxdXSkvZywgJyQxJyk7XG4gIGlmIChjYXBbMF0uY2hhckF0KDApICE9PSAnIScpIHtcbiAgICBsZXhlci5zdGF0ZS5pbkxpbmsgPSB0cnVlO1xuICAgIHZhciB0b2tlbiA9IHtcbiAgICAgIHR5cGU6ICdsaW5rJyxcbiAgICAgIHJhdzogcmF3LFxuICAgICAgaHJlZjogaHJlZixcbiAgICAgIHRpdGxlOiB0aXRsZSxcbiAgICAgIHRleHQ6IHRleHQsXG4gICAgICB0b2tlbnM6IGxleGVyLmlubGluZVRva2Vucyh0ZXh0KVxuICAgIH07XG4gICAgbGV4ZXIuc3RhdGUuaW5MaW5rID0gZmFsc2U7XG4gICAgcmV0dXJuIHRva2VuO1xuICB9XG4gIHJldHVybiB7XG4gICAgdHlwZTogJ2ltYWdlJyxcbiAgICByYXc6IHJhdyxcbiAgICBocmVmOiBocmVmLFxuICAgIHRpdGxlOiB0aXRsZSxcbiAgICB0ZXh0OiBlc2NhcGUodGV4dClcbiAgfTtcbn1cbmZ1bmN0aW9uIGluZGVudENvZGVDb21wZW5zYXRpb24ocmF3LCB0ZXh0KSB7XG4gIHZhciBtYXRjaEluZGVudFRvQ29kZSA9IHJhdy5tYXRjaCgvXihcXHMrKSg/OmBgYCkvKTtcbiAgaWYgKG1hdGNoSW5kZW50VG9Db2RlID09PSBudWxsKSB7XG4gICAgcmV0dXJuIHRleHQ7XG4gIH1cbiAgdmFyIGluZGVudFRvQ29kZSA9IG1hdGNoSW5kZW50VG9Db2RlWzFdO1xuICByZXR1cm4gdGV4dC5zcGxpdCgnXFxuJykubWFwKGZ1bmN0aW9uIChub2RlKSB7XG4gICAgdmFyIG1hdGNoSW5kZW50SW5Ob2RlID0gbm9kZS5tYXRjaCgvXlxccysvKTtcbiAgICBpZiAobWF0Y2hJbmRlbnRJbk5vZGUgPT09IG51bGwpIHtcbiAgICAgIHJldHVybiBub2RlO1xuICAgIH1cbiAgICB2YXIgaW5kZW50SW5Ob2RlID0gbWF0Y2hJbmRlbnRJbk5vZGVbMF07XG4gICAgaWYgKGluZGVudEluTm9kZS5sZW5ndGggPj0gaW5kZW50VG9Db2RlLmxlbmd0aCkge1xuICAgICAgcmV0dXJuIG5vZGUuc2xpY2UoaW5kZW50VG9Db2RlLmxlbmd0aCk7XG4gICAgfVxuICAgIHJldHVybiBub2RlO1xuICB9KS5qb2luKCdcXG4nKTtcbn1cblxuLyoqXG4gKiBUb2tlbml6ZXJcbiAqL1xudmFyIFRva2VuaXplciA9IC8qI19fUFVSRV9fKi9mdW5jdGlvbiAoKSB7XG4gIGZ1bmN0aW9uIFRva2VuaXplcihvcHRpb25zKSB7XG4gICAgdGhpcy5vcHRpb25zID0gb3B0aW9ucyB8fCBleHBvcnRzLmRlZmF1bHRzO1xuICB9XG4gIHZhciBfcHJvdG8gPSBUb2tlbml6ZXIucHJvdG90eXBlO1xuICBfcHJvdG8uc3BhY2UgPSBmdW5jdGlvbiBzcGFjZShzcmMpIHtcbiAgICB2YXIgY2FwID0gdGhpcy5ydWxlcy5ibG9jay5uZXdsaW5lLmV4ZWMoc3JjKTtcbiAgICBpZiAoY2FwICYmIGNhcFswXS5sZW5ndGggPiAwKSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICB0eXBlOiAnc3BhY2UnLFxuICAgICAgICByYXc6IGNhcFswXVxuICAgICAgfTtcbiAgICB9XG4gIH07XG4gIF9wcm90by5jb2RlID0gZnVuY3Rpb24gY29kZShzcmMpIHtcbiAgICB2YXIgY2FwID0gdGhpcy5ydWxlcy5ibG9jay5jb2RlLmV4ZWMoc3JjKTtcbiAgICBpZiAoY2FwKSB7XG4gICAgICB2YXIgdGV4dCA9IGNhcFswXS5yZXBsYWNlKC9eIHsxLDR9L2dtLCAnJyk7XG4gICAgICByZXR1cm4ge1xuICAgICAgICB0eXBlOiAnY29kZScsXG4gICAgICAgIHJhdzogY2FwWzBdLFxuICAgICAgICBjb2RlQmxvY2tTdHlsZTogJ2luZGVudGVkJyxcbiAgICAgICAgdGV4dDogIXRoaXMub3B0aW9ucy5wZWRhbnRpYyA/IHJ0cmltKHRleHQsICdcXG4nKSA6IHRleHRcbiAgICAgIH07XG4gICAgfVxuICB9O1xuICBfcHJvdG8uZmVuY2VzID0gZnVuY3Rpb24gZmVuY2VzKHNyYykge1xuICAgIHZhciBjYXAgPSB0aGlzLnJ1bGVzLmJsb2NrLmZlbmNlcy5leGVjKHNyYyk7XG4gICAgaWYgKGNhcCkge1xuICAgICAgdmFyIHJhdyA9IGNhcFswXTtcbiAgICAgIHZhciB0ZXh0ID0gaW5kZW50Q29kZUNvbXBlbnNhdGlvbihyYXcsIGNhcFszXSB8fCAnJyk7XG4gICAgICByZXR1cm4ge1xuICAgICAgICB0eXBlOiAnY29kZScsXG4gICAgICAgIHJhdzogcmF3LFxuICAgICAgICBsYW5nOiBjYXBbMl0gPyBjYXBbMl0udHJpbSgpLnJlcGxhY2UodGhpcy5ydWxlcy5pbmxpbmUuX2VzY2FwZXMsICckMScpIDogY2FwWzJdLFxuICAgICAgICB0ZXh0OiB0ZXh0XG4gICAgICB9O1xuICAgIH1cbiAgfTtcbiAgX3Byb3RvLmhlYWRpbmcgPSBmdW5jdGlvbiBoZWFkaW5nKHNyYykge1xuICAgIHZhciBjYXAgPSB0aGlzLnJ1bGVzLmJsb2NrLmhlYWRpbmcuZXhlYyhzcmMpO1xuICAgIGlmIChjYXApIHtcbiAgICAgIHZhciB0ZXh0ID0gY2FwWzJdLnRyaW0oKTtcblxuICAgICAgLy8gcmVtb3ZlIHRyYWlsaW5nICNzXG4gICAgICBpZiAoLyMkLy50ZXN0KHRleHQpKSB7XG4gICAgICAgIHZhciB0cmltbWVkID0gcnRyaW0odGV4dCwgJyMnKTtcbiAgICAgICAgaWYgKHRoaXMub3B0aW9ucy5wZWRhbnRpYykge1xuICAgICAgICAgIHRleHQgPSB0cmltbWVkLnRyaW0oKTtcbiAgICAgICAgfSBlbHNlIGlmICghdHJpbW1lZCB8fCAvICQvLnRlc3QodHJpbW1lZCkpIHtcbiAgICAgICAgICAvLyBDb21tb25NYXJrIHJlcXVpcmVzIHNwYWNlIGJlZm9yZSB0cmFpbGluZyAjc1xuICAgICAgICAgIHRleHQgPSB0cmltbWVkLnRyaW0oKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgdHlwZTogJ2hlYWRpbmcnLFxuICAgICAgICByYXc6IGNhcFswXSxcbiAgICAgICAgZGVwdGg6IGNhcFsxXS5sZW5ndGgsXG4gICAgICAgIHRleHQ6IHRleHQsXG4gICAgICAgIHRva2VuczogdGhpcy5sZXhlci5pbmxpbmUodGV4dClcbiAgICAgIH07XG4gICAgfVxuICB9O1xuICBfcHJvdG8uaHIgPSBmdW5jdGlvbiBocihzcmMpIHtcbiAgICB2YXIgY2FwID0gdGhpcy5ydWxlcy5ibG9jay5oci5leGVjKHNyYyk7XG4gICAgaWYgKGNhcCkge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgdHlwZTogJ2hyJyxcbiAgICAgICAgcmF3OiBjYXBbMF1cbiAgICAgIH07XG4gICAgfVxuICB9O1xuICBfcHJvdG8uYmxvY2txdW90ZSA9IGZ1bmN0aW9uIGJsb2NrcXVvdGUoc3JjKSB7XG4gICAgdmFyIGNhcCA9IHRoaXMucnVsZXMuYmxvY2suYmxvY2txdW90ZS5leGVjKHNyYyk7XG4gICAgaWYgKGNhcCkge1xuICAgICAgdmFyIHRleHQgPSBjYXBbMF0ucmVwbGFjZSgvXiAqPlsgXFx0XT8vZ20sICcnKTtcbiAgICAgIHZhciB0b3AgPSB0aGlzLmxleGVyLnN0YXRlLnRvcDtcbiAgICAgIHRoaXMubGV4ZXIuc3RhdGUudG9wID0gdHJ1ZTtcbiAgICAgIHZhciB0b2tlbnMgPSB0aGlzLmxleGVyLmJsb2NrVG9rZW5zKHRleHQpO1xuICAgICAgdGhpcy5sZXhlci5zdGF0ZS50b3AgPSB0b3A7XG4gICAgICByZXR1cm4ge1xuICAgICAgICB0eXBlOiAnYmxvY2txdW90ZScsXG4gICAgICAgIHJhdzogY2FwWzBdLFxuICAgICAgICB0b2tlbnM6IHRva2VucyxcbiAgICAgICAgdGV4dDogdGV4dFxuICAgICAgfTtcbiAgICB9XG4gIH07XG4gIF9wcm90by5saXN0ID0gZnVuY3Rpb24gbGlzdChzcmMpIHtcbiAgICB2YXIgY2FwID0gdGhpcy5ydWxlcy5ibG9jay5saXN0LmV4ZWMoc3JjKTtcbiAgICBpZiAoY2FwKSB7XG4gICAgICB2YXIgcmF3LCBpc3Rhc2ssIGlzY2hlY2tlZCwgaW5kZW50LCBpLCBibGFua0xpbmUsIGVuZHNXaXRoQmxhbmtMaW5lLCBsaW5lLCBuZXh0TGluZSwgcmF3TGluZSwgaXRlbUNvbnRlbnRzLCBlbmRFYXJseTtcbiAgICAgIHZhciBidWxsID0gY2FwWzFdLnRyaW0oKTtcbiAgICAgIHZhciBpc29yZGVyZWQgPSBidWxsLmxlbmd0aCA+IDE7XG4gICAgICB2YXIgbGlzdCA9IHtcbiAgICAgICAgdHlwZTogJ2xpc3QnLFxuICAgICAgICByYXc6ICcnLFxuICAgICAgICBvcmRlcmVkOiBpc29yZGVyZWQsXG4gICAgICAgIHN0YXJ0OiBpc29yZGVyZWQgPyArYnVsbC5zbGljZSgwLCAtMSkgOiAnJyxcbiAgICAgICAgbG9vc2U6IGZhbHNlLFxuICAgICAgICBpdGVtczogW11cbiAgICAgIH07XG4gICAgICBidWxsID0gaXNvcmRlcmVkID8gXCJcXFxcZHsxLDl9XFxcXFwiICsgYnVsbC5zbGljZSgtMSkgOiBcIlxcXFxcIiArIGJ1bGw7XG4gICAgICBpZiAodGhpcy5vcHRpb25zLnBlZGFudGljKSB7XG4gICAgICAgIGJ1bGwgPSBpc29yZGVyZWQgPyBidWxsIDogJ1sqKy1dJztcbiAgICAgIH1cblxuICAgICAgLy8gR2V0IG5leHQgbGlzdCBpdGVtXG4gICAgICB2YXIgaXRlbVJlZ2V4ID0gbmV3IFJlZ0V4cChcIl4oIHswLDN9XCIgKyBidWxsICsgXCIpKCg/OltcXHQgXVteXFxcXG5dKik/KD86XFxcXG58JCkpXCIpO1xuXG4gICAgICAvLyBDaGVjayBpZiBjdXJyZW50IGJ1bGxldCBwb2ludCBjYW4gc3RhcnQgYSBuZXcgTGlzdCBJdGVtXG4gICAgICB3aGlsZSAoc3JjKSB7XG4gICAgICAgIGVuZEVhcmx5ID0gZmFsc2U7XG4gICAgICAgIGlmICghKGNhcCA9IGl0ZW1SZWdleC5leGVjKHNyYykpKSB7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMucnVsZXMuYmxvY2suaHIudGVzdChzcmMpKSB7XG4gICAgICAgICAgLy8gRW5kIGxpc3QgaWYgYnVsbGV0IHdhcyBhY3R1YWxseSBIUiAocG9zc2libHkgbW92ZSBpbnRvIGl0ZW1SZWdleD8pXG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgICAgcmF3ID0gY2FwWzBdO1xuICAgICAgICBzcmMgPSBzcmMuc3Vic3RyaW5nKHJhdy5sZW5ndGgpO1xuICAgICAgICBsaW5lID0gY2FwWzJdLnNwbGl0KCdcXG4nLCAxKVswXS5yZXBsYWNlKC9eXFx0Ky8sIGZ1bmN0aW9uICh0KSB7XG4gICAgICAgICAgcmV0dXJuICcgJy5yZXBlYXQoMyAqIHQubGVuZ3RoKTtcbiAgICAgICAgfSk7XG4gICAgICAgIG5leHRMaW5lID0gc3JjLnNwbGl0KCdcXG4nLCAxKVswXTtcbiAgICAgICAgaWYgKHRoaXMub3B0aW9ucy5wZWRhbnRpYykge1xuICAgICAgICAgIGluZGVudCA9IDI7XG4gICAgICAgICAgaXRlbUNvbnRlbnRzID0gbGluZS50cmltTGVmdCgpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGluZGVudCA9IGNhcFsyXS5zZWFyY2goL1teIF0vKTsgLy8gRmluZCBmaXJzdCBub24tc3BhY2UgY2hhclxuICAgICAgICAgIGluZGVudCA9IGluZGVudCA+IDQgPyAxIDogaW5kZW50OyAvLyBUcmVhdCBpbmRlbnRlZCBjb2RlIGJsb2NrcyAoPiA0IHNwYWNlcykgYXMgaGF2aW5nIG9ubHkgMSBpbmRlbnRcbiAgICAgICAgICBpdGVtQ29udGVudHMgPSBsaW5lLnNsaWNlKGluZGVudCk7XG4gICAgICAgICAgaW5kZW50ICs9IGNhcFsxXS5sZW5ndGg7XG4gICAgICAgIH1cbiAgICAgICAgYmxhbmtMaW5lID0gZmFsc2U7XG4gICAgICAgIGlmICghbGluZSAmJiAvXiAqJC8udGVzdChuZXh0TGluZSkpIHtcbiAgICAgICAgICAvLyBJdGVtcyBiZWdpbiB3aXRoIGF0IG1vc3Qgb25lIGJsYW5rIGxpbmVcbiAgICAgICAgICByYXcgKz0gbmV4dExpbmUgKyAnXFxuJztcbiAgICAgICAgICBzcmMgPSBzcmMuc3Vic3RyaW5nKG5leHRMaW5lLmxlbmd0aCArIDEpO1xuICAgICAgICAgIGVuZEVhcmx5ID0gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoIWVuZEVhcmx5KSB7XG4gICAgICAgICAgdmFyIG5leHRCdWxsZXRSZWdleCA9IG5ldyBSZWdFeHAoXCJeIHswLFwiICsgTWF0aC5taW4oMywgaW5kZW50IC0gMSkgKyBcIn0oPzpbKistXXxcXFxcZHsxLDl9Wy4pXSkoKD86WyBcXHRdW15cXFxcbl0qKT8oPzpcXFxcbnwkKSlcIik7XG4gICAgICAgICAgdmFyIGhyUmVnZXggPSBuZXcgUmVnRXhwKFwiXiB7MCxcIiArIE1hdGgubWluKDMsIGluZGVudCAtIDEpICsgXCJ9KCg/Oi0gKil7Myx9fCg/Ol8gKil7Myx9fCg/OlxcXFwqICopezMsfSkoPzpcXFxcbit8JClcIik7XG4gICAgICAgICAgdmFyIGZlbmNlc0JlZ2luUmVnZXggPSBuZXcgUmVnRXhwKFwiXiB7MCxcIiArIE1hdGgubWluKDMsIGluZGVudCAtIDEpICsgXCJ9KD86YGBgfH5+filcIik7XG4gICAgICAgICAgdmFyIGhlYWRpbmdCZWdpblJlZ2V4ID0gbmV3IFJlZ0V4cChcIl4gezAsXCIgKyBNYXRoLm1pbigzLCBpbmRlbnQgLSAxKSArIFwifSNcIik7XG5cbiAgICAgICAgICAvLyBDaGVjayBpZiBmb2xsb3dpbmcgbGluZXMgc2hvdWxkIGJlIGluY2x1ZGVkIGluIExpc3QgSXRlbVxuICAgICAgICAgIHdoaWxlIChzcmMpIHtcbiAgICAgICAgICAgIHJhd0xpbmUgPSBzcmMuc3BsaXQoJ1xcbicsIDEpWzBdO1xuICAgICAgICAgICAgbmV4dExpbmUgPSByYXdMaW5lO1xuXG4gICAgICAgICAgICAvLyBSZS1hbGlnbiB0byBmb2xsb3cgY29tbW9ubWFyayBuZXN0aW5nIHJ1bGVzXG4gICAgICAgICAgICBpZiAodGhpcy5vcHRpb25zLnBlZGFudGljKSB7XG4gICAgICAgICAgICAgIG5leHRMaW5lID0gbmV4dExpbmUucmVwbGFjZSgvXiB7MSw0fSg/PSggezR9KSpbXiBdKS9nLCAnICAnKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gRW5kIGxpc3QgaXRlbSBpZiBmb3VuZCBjb2RlIGZlbmNlc1xuICAgICAgICAgICAgaWYgKGZlbmNlc0JlZ2luUmVnZXgudGVzdChuZXh0TGluZSkpIHtcbiAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIEVuZCBsaXN0IGl0ZW0gaWYgZm91bmQgc3RhcnQgb2YgbmV3IGhlYWRpbmdcbiAgICAgICAgICAgIGlmIChoZWFkaW5nQmVnaW5SZWdleC50ZXN0KG5leHRMaW5lKSkge1xuICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gRW5kIGxpc3QgaXRlbSBpZiBmb3VuZCBzdGFydCBvZiBuZXcgYnVsbGV0XG4gICAgICAgICAgICBpZiAobmV4dEJ1bGxldFJlZ2V4LnRlc3QobmV4dExpbmUpKSB7XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBIb3Jpem9udGFsIHJ1bGUgZm91bmRcbiAgICAgICAgICAgIGlmIChoclJlZ2V4LnRlc3Qoc3JjKSkge1xuICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChuZXh0TGluZS5zZWFyY2goL1teIF0vKSA+PSBpbmRlbnQgfHwgIW5leHRMaW5lLnRyaW0oKSkge1xuICAgICAgICAgICAgICAvLyBEZWRlbnQgaWYgcG9zc2libGVcbiAgICAgICAgICAgICAgaXRlbUNvbnRlbnRzICs9ICdcXG4nICsgbmV4dExpbmUuc2xpY2UoaW5kZW50KTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIC8vIG5vdCBlbm91Z2ggaW5kZW50YXRpb25cbiAgICAgICAgICAgICAgaWYgKGJsYW5rTGluZSkge1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgLy8gcGFyYWdyYXBoIGNvbnRpbnVhdGlvbiB1bmxlc3MgbGFzdCBsaW5lIHdhcyBhIGRpZmZlcmVudCBibG9jayBsZXZlbCBlbGVtZW50XG4gICAgICAgICAgICAgIGlmIChsaW5lLnNlYXJjaCgvW14gXS8pID49IDQpIHtcbiAgICAgICAgICAgICAgICAvLyBpbmRlbnRlZCBjb2RlIGJsb2NrXG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgaWYgKGZlbmNlc0JlZ2luUmVnZXgudGVzdChsaW5lKSkge1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIGlmIChoZWFkaW5nQmVnaW5SZWdleC50ZXN0KGxpbmUpKSB7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgaWYgKGhyUmVnZXgudGVzdChsaW5lKSkge1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIGl0ZW1Db250ZW50cyArPSAnXFxuJyArIG5leHRMaW5lO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKCFibGFua0xpbmUgJiYgIW5leHRMaW5lLnRyaW0oKSkge1xuICAgICAgICAgICAgICAvLyBDaGVjayBpZiBjdXJyZW50IGxpbmUgaXMgYmxhbmtcbiAgICAgICAgICAgICAgYmxhbmtMaW5lID0gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJhdyArPSByYXdMaW5lICsgJ1xcbic7XG4gICAgICAgICAgICBzcmMgPSBzcmMuc3Vic3RyaW5nKHJhd0xpbmUubGVuZ3RoICsgMSk7XG4gICAgICAgICAgICBsaW5lID0gbmV4dExpbmUuc2xpY2UoaW5kZW50KTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCFsaXN0Lmxvb3NlKSB7XG4gICAgICAgICAgLy8gSWYgdGhlIHByZXZpb3VzIGl0ZW0gZW5kZWQgd2l0aCBhIGJsYW5rIGxpbmUsIHRoZSBsaXN0IGlzIGxvb3NlXG4gICAgICAgICAgaWYgKGVuZHNXaXRoQmxhbmtMaW5lKSB7XG4gICAgICAgICAgICBsaXN0Lmxvb3NlID0gdHJ1ZTtcbiAgICAgICAgICB9IGVsc2UgaWYgKC9cXG4gKlxcbiAqJC8udGVzdChyYXcpKSB7XG4gICAgICAgICAgICBlbmRzV2l0aEJsYW5rTGluZSA9IHRydWU7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gQ2hlY2sgZm9yIHRhc2sgbGlzdCBpdGVtc1xuICAgICAgICBpZiAodGhpcy5vcHRpb25zLmdmbSkge1xuICAgICAgICAgIGlzdGFzayA9IC9eXFxbWyB4WF1cXF0gLy5leGVjKGl0ZW1Db250ZW50cyk7XG4gICAgICAgICAgaWYgKGlzdGFzaykge1xuICAgICAgICAgICAgaXNjaGVja2VkID0gaXN0YXNrWzBdICE9PSAnWyBdICc7XG4gICAgICAgICAgICBpdGVtQ29udGVudHMgPSBpdGVtQ29udGVudHMucmVwbGFjZSgvXlxcW1sgeFhdXFxdICsvLCAnJyk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGxpc3QuaXRlbXMucHVzaCh7XG4gICAgICAgICAgdHlwZTogJ2xpc3RfaXRlbScsXG4gICAgICAgICAgcmF3OiByYXcsXG4gICAgICAgICAgdGFzazogISFpc3Rhc2ssXG4gICAgICAgICAgY2hlY2tlZDogaXNjaGVja2VkLFxuICAgICAgICAgIGxvb3NlOiBmYWxzZSxcbiAgICAgICAgICB0ZXh0OiBpdGVtQ29udGVudHNcbiAgICAgICAgfSk7XG4gICAgICAgIGxpc3QucmF3ICs9IHJhdztcbiAgICAgIH1cblxuICAgICAgLy8gRG8gbm90IGNvbnN1bWUgbmV3bGluZXMgYXQgZW5kIG9mIGZpbmFsIGl0ZW0uIEFsdGVybmF0aXZlbHksIG1ha2UgaXRlbVJlZ2V4ICpzdGFydCogd2l0aCBhbnkgbmV3bGluZXMgdG8gc2ltcGxpZnkvc3BlZWQgdXAgZW5kc1dpdGhCbGFua0xpbmUgbG9naWNcbiAgICAgIGxpc3QuaXRlbXNbbGlzdC5pdGVtcy5sZW5ndGggLSAxXS5yYXcgPSByYXcudHJpbVJpZ2h0KCk7XG4gICAgICBsaXN0Lml0ZW1zW2xpc3QuaXRlbXMubGVuZ3RoIC0gMV0udGV4dCA9IGl0ZW1Db250ZW50cy50cmltUmlnaHQoKTtcbiAgICAgIGxpc3QucmF3ID0gbGlzdC5yYXcudHJpbVJpZ2h0KCk7XG4gICAgICB2YXIgbCA9IGxpc3QuaXRlbXMubGVuZ3RoO1xuXG4gICAgICAvLyBJdGVtIGNoaWxkIHRva2VucyBoYW5kbGVkIGhlcmUgYXQgZW5kIGJlY2F1c2Ugd2UgbmVlZGVkIHRvIGhhdmUgdGhlIGZpbmFsIGl0ZW0gdG8gdHJpbSBpdCBmaXJzdFxuICAgICAgZm9yIChpID0gMDsgaSA8IGw7IGkrKykge1xuICAgICAgICB0aGlzLmxleGVyLnN0YXRlLnRvcCA9IGZhbHNlO1xuICAgICAgICBsaXN0Lml0ZW1zW2ldLnRva2VucyA9IHRoaXMubGV4ZXIuYmxvY2tUb2tlbnMobGlzdC5pdGVtc1tpXS50ZXh0LCBbXSk7XG4gICAgICAgIGlmICghbGlzdC5sb29zZSkge1xuICAgICAgICAgIC8vIENoZWNrIGlmIGxpc3Qgc2hvdWxkIGJlIGxvb3NlXG4gICAgICAgICAgdmFyIHNwYWNlcnMgPSBsaXN0Lml0ZW1zW2ldLnRva2Vucy5maWx0ZXIoZnVuY3Rpb24gKHQpIHtcbiAgICAgICAgICAgIHJldHVybiB0LnR5cGUgPT09ICdzcGFjZSc7XG4gICAgICAgICAgfSk7XG4gICAgICAgICAgdmFyIGhhc011bHRpcGxlTGluZUJyZWFrcyA9IHNwYWNlcnMubGVuZ3RoID4gMCAmJiBzcGFjZXJzLnNvbWUoZnVuY3Rpb24gKHQpIHtcbiAgICAgICAgICAgIHJldHVybiAvXFxuLipcXG4vLnRlc3QodC5yYXcpO1xuICAgICAgICAgIH0pO1xuICAgICAgICAgIGxpc3QubG9vc2UgPSBoYXNNdWx0aXBsZUxpbmVCcmVha3M7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgLy8gU2V0IGFsbCBpdGVtcyB0byBsb29zZSBpZiBsaXN0IGlzIGxvb3NlXG4gICAgICBpZiAobGlzdC5sb29zZSkge1xuICAgICAgICBmb3IgKGkgPSAwOyBpIDwgbDsgaSsrKSB7XG4gICAgICAgICAgbGlzdC5pdGVtc1tpXS5sb29zZSA9IHRydWU7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiBsaXN0O1xuICAgIH1cbiAgfTtcbiAgX3Byb3RvLmh0bWwgPSBmdW5jdGlvbiBodG1sKHNyYykge1xuICAgIHZhciBjYXAgPSB0aGlzLnJ1bGVzLmJsb2NrLmh0bWwuZXhlYyhzcmMpO1xuICAgIGlmIChjYXApIHtcbiAgICAgIHZhciB0b2tlbiA9IHtcbiAgICAgICAgdHlwZTogJ2h0bWwnLFxuICAgICAgICByYXc6IGNhcFswXSxcbiAgICAgICAgcHJlOiAhdGhpcy5vcHRpb25zLnNhbml0aXplciAmJiAoY2FwWzFdID09PSAncHJlJyB8fCBjYXBbMV0gPT09ICdzY3JpcHQnIHx8IGNhcFsxXSA9PT0gJ3N0eWxlJyksXG4gICAgICAgIHRleHQ6IGNhcFswXVxuICAgICAgfTtcbiAgICAgIGlmICh0aGlzLm9wdGlvbnMuc2FuaXRpemUpIHtcbiAgICAgICAgdmFyIHRleHQgPSB0aGlzLm9wdGlvbnMuc2FuaXRpemVyID8gdGhpcy5vcHRpb25zLnNhbml0aXplcihjYXBbMF0pIDogZXNjYXBlKGNhcFswXSk7XG4gICAgICAgIHRva2VuLnR5cGUgPSAncGFyYWdyYXBoJztcbiAgICAgICAgdG9rZW4udGV4dCA9IHRleHQ7XG4gICAgICAgIHRva2VuLnRva2VucyA9IHRoaXMubGV4ZXIuaW5saW5lKHRleHQpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHRva2VuO1xuICAgIH1cbiAgfTtcbiAgX3Byb3RvLmRlZiA9IGZ1bmN0aW9uIGRlZihzcmMpIHtcbiAgICB2YXIgY2FwID0gdGhpcy5ydWxlcy5ibG9jay5kZWYuZXhlYyhzcmMpO1xuICAgIGlmIChjYXApIHtcbiAgICAgIHZhciB0YWcgPSBjYXBbMV0udG9Mb3dlckNhc2UoKS5yZXBsYWNlKC9cXHMrL2csICcgJyk7XG4gICAgICB2YXIgaHJlZiA9IGNhcFsyXSA/IGNhcFsyXS5yZXBsYWNlKC9ePCguKik+JC8sICckMScpLnJlcGxhY2UodGhpcy5ydWxlcy5pbmxpbmUuX2VzY2FwZXMsICckMScpIDogJyc7XG4gICAgICB2YXIgdGl0bGUgPSBjYXBbM10gPyBjYXBbM10uc3Vic3RyaW5nKDEsIGNhcFszXS5sZW5ndGggLSAxKS5yZXBsYWNlKHRoaXMucnVsZXMuaW5saW5lLl9lc2NhcGVzLCAnJDEnKSA6IGNhcFszXTtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHR5cGU6ICdkZWYnLFxuICAgICAgICB0YWc6IHRhZyxcbiAgICAgICAgcmF3OiBjYXBbMF0sXG4gICAgICAgIGhyZWY6IGhyZWYsXG4gICAgICAgIHRpdGxlOiB0aXRsZVxuICAgICAgfTtcbiAgICB9XG4gIH07XG4gIF9wcm90by50YWJsZSA9IGZ1bmN0aW9uIHRhYmxlKHNyYykge1xuICAgIHZhciBjYXAgPSB0aGlzLnJ1bGVzLmJsb2NrLnRhYmxlLmV4ZWMoc3JjKTtcbiAgICBpZiAoY2FwKSB7XG4gICAgICB2YXIgaXRlbSA9IHtcbiAgICAgICAgdHlwZTogJ3RhYmxlJyxcbiAgICAgICAgaGVhZGVyOiBzcGxpdENlbGxzKGNhcFsxXSkubWFwKGZ1bmN0aW9uIChjKSB7XG4gICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHRleHQ6IGNcbiAgICAgICAgICB9O1xuICAgICAgICB9KSxcbiAgICAgICAgYWxpZ246IGNhcFsyXS5yZXBsYWNlKC9eICp8XFx8ICokL2csICcnKS5zcGxpdCgvICpcXHwgKi8pLFxuICAgICAgICByb3dzOiBjYXBbM10gJiYgY2FwWzNdLnRyaW0oKSA/IGNhcFszXS5yZXBsYWNlKC9cXG5bIFxcdF0qJC8sICcnKS5zcGxpdCgnXFxuJykgOiBbXVxuICAgICAgfTtcbiAgICAgIGlmIChpdGVtLmhlYWRlci5sZW5ndGggPT09IGl0ZW0uYWxpZ24ubGVuZ3RoKSB7XG4gICAgICAgIGl0ZW0ucmF3ID0gY2FwWzBdO1xuICAgICAgICB2YXIgbCA9IGl0ZW0uYWxpZ24ubGVuZ3RoO1xuICAgICAgICB2YXIgaSwgaiwgaywgcm93O1xuICAgICAgICBmb3IgKGkgPSAwOyBpIDwgbDsgaSsrKSB7XG4gICAgICAgICAgaWYgKC9eICotKzogKiQvLnRlc3QoaXRlbS5hbGlnbltpXSkpIHtcbiAgICAgICAgICAgIGl0ZW0uYWxpZ25baV0gPSAncmlnaHQnO1xuICAgICAgICAgIH0gZWxzZSBpZiAoL14gKjotKzogKiQvLnRlc3QoaXRlbS5hbGlnbltpXSkpIHtcbiAgICAgICAgICAgIGl0ZW0uYWxpZ25baV0gPSAnY2VudGVyJztcbiAgICAgICAgICB9IGVsc2UgaWYgKC9eICo6LSsgKiQvLnRlc3QoaXRlbS5hbGlnbltpXSkpIHtcbiAgICAgICAgICAgIGl0ZW0uYWxpZ25baV0gPSAnbGVmdCc7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGl0ZW0uYWxpZ25baV0gPSBudWxsO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBsID0gaXRlbS5yb3dzLmxlbmd0aDtcbiAgICAgICAgZm9yIChpID0gMDsgaSA8IGw7IGkrKykge1xuICAgICAgICAgIGl0ZW0ucm93c1tpXSA9IHNwbGl0Q2VsbHMoaXRlbS5yb3dzW2ldLCBpdGVtLmhlYWRlci5sZW5ndGgpLm1hcChmdW5jdGlvbiAoYykge1xuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgdGV4dDogY1xuICAgICAgICAgICAgfTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIHBhcnNlIGNoaWxkIHRva2VucyBpbnNpZGUgaGVhZGVycyBhbmQgY2VsbHNcblxuICAgICAgICAvLyBoZWFkZXIgY2hpbGQgdG9rZW5zXG4gICAgICAgIGwgPSBpdGVtLmhlYWRlci5sZW5ndGg7XG4gICAgICAgIGZvciAoaiA9IDA7IGogPCBsOyBqKyspIHtcbiAgICAgICAgICBpdGVtLmhlYWRlcltqXS50b2tlbnMgPSB0aGlzLmxleGVyLmlubGluZShpdGVtLmhlYWRlcltqXS50ZXh0KTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIGNlbGwgY2hpbGQgdG9rZW5zXG4gICAgICAgIGwgPSBpdGVtLnJvd3MubGVuZ3RoO1xuICAgICAgICBmb3IgKGogPSAwOyBqIDwgbDsgaisrKSB7XG4gICAgICAgICAgcm93ID0gaXRlbS5yb3dzW2pdO1xuICAgICAgICAgIGZvciAoayA9IDA7IGsgPCByb3cubGVuZ3RoOyBrKyspIHtcbiAgICAgICAgICAgIHJvd1trXS50b2tlbnMgPSB0aGlzLmxleGVyLmlubGluZShyb3dba10udGV4dCk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBpdGVtO1xuICAgICAgfVxuICAgIH1cbiAgfTtcbiAgX3Byb3RvLmxoZWFkaW5nID0gZnVuY3Rpb24gbGhlYWRpbmcoc3JjKSB7XG4gICAgdmFyIGNhcCA9IHRoaXMucnVsZXMuYmxvY2subGhlYWRpbmcuZXhlYyhzcmMpO1xuICAgIGlmIChjYXApIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHR5cGU6ICdoZWFkaW5nJyxcbiAgICAgICAgcmF3OiBjYXBbMF0sXG4gICAgICAgIGRlcHRoOiBjYXBbMl0uY2hhckF0KDApID09PSAnPScgPyAxIDogMixcbiAgICAgICAgdGV4dDogY2FwWzFdLFxuICAgICAgICB0b2tlbnM6IHRoaXMubGV4ZXIuaW5saW5lKGNhcFsxXSlcbiAgICAgIH07XG4gICAgfVxuICB9O1xuICBfcHJvdG8ucGFyYWdyYXBoID0gZnVuY3Rpb24gcGFyYWdyYXBoKHNyYykge1xuICAgIHZhciBjYXAgPSB0aGlzLnJ1bGVzLmJsb2NrLnBhcmFncmFwaC5leGVjKHNyYyk7XG4gICAgaWYgKGNhcCkge1xuICAgICAgdmFyIHRleHQgPSBjYXBbMV0uY2hhckF0KGNhcFsxXS5sZW5ndGggLSAxKSA9PT0gJ1xcbicgPyBjYXBbMV0uc2xpY2UoMCwgLTEpIDogY2FwWzFdO1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgdHlwZTogJ3BhcmFncmFwaCcsXG4gICAgICAgIHJhdzogY2FwWzBdLFxuICAgICAgICB0ZXh0OiB0ZXh0LFxuICAgICAgICB0b2tlbnM6IHRoaXMubGV4ZXIuaW5saW5lKHRleHQpXG4gICAgICB9O1xuICAgIH1cbiAgfTtcbiAgX3Byb3RvLnRleHQgPSBmdW5jdGlvbiB0ZXh0KHNyYykge1xuICAgIHZhciBjYXAgPSB0aGlzLnJ1bGVzLmJsb2NrLnRleHQuZXhlYyhzcmMpO1xuICAgIGlmIChjYXApIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHR5cGU6ICd0ZXh0JyxcbiAgICAgICAgcmF3OiBjYXBbMF0sXG4gICAgICAgIHRleHQ6IGNhcFswXSxcbiAgICAgICAgdG9rZW5zOiB0aGlzLmxleGVyLmlubGluZShjYXBbMF0pXG4gICAgICB9O1xuICAgIH1cbiAgfTtcbiAgX3Byb3RvLmVzY2FwZSA9IGZ1bmN0aW9uIGVzY2FwZSQxKHNyYykge1xuICAgIHZhciBjYXAgPSB0aGlzLnJ1bGVzLmlubGluZS5lc2NhcGUuZXhlYyhzcmMpO1xuICAgIGlmIChjYXApIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHR5cGU6ICdlc2NhcGUnLFxuICAgICAgICByYXc6IGNhcFswXSxcbiAgICAgICAgdGV4dDogZXNjYXBlKGNhcFsxXSlcbiAgICAgIH07XG4gICAgfVxuICB9O1xuICBfcHJvdG8udGFnID0gZnVuY3Rpb24gdGFnKHNyYykge1xuICAgIHZhciBjYXAgPSB0aGlzLnJ1bGVzLmlubGluZS50YWcuZXhlYyhzcmMpO1xuICAgIGlmIChjYXApIHtcbiAgICAgIGlmICghdGhpcy5sZXhlci5zdGF0ZS5pbkxpbmsgJiYgL148YSAvaS50ZXN0KGNhcFswXSkpIHtcbiAgICAgICAgdGhpcy5sZXhlci5zdGF0ZS5pbkxpbmsgPSB0cnVlO1xuICAgICAgfSBlbHNlIGlmICh0aGlzLmxleGVyLnN0YXRlLmluTGluayAmJiAvXjxcXC9hPi9pLnRlc3QoY2FwWzBdKSkge1xuICAgICAgICB0aGlzLmxleGVyLnN0YXRlLmluTGluayA9IGZhbHNlO1xuICAgICAgfVxuICAgICAgaWYgKCF0aGlzLmxleGVyLnN0YXRlLmluUmF3QmxvY2sgJiYgL148KHByZXxjb2RlfGtiZHxzY3JpcHQpKFxcc3w+KS9pLnRlc3QoY2FwWzBdKSkge1xuICAgICAgICB0aGlzLmxleGVyLnN0YXRlLmluUmF3QmxvY2sgPSB0cnVlO1xuICAgICAgfSBlbHNlIGlmICh0aGlzLmxleGVyLnN0YXRlLmluUmF3QmxvY2sgJiYgL148XFwvKHByZXxjb2RlfGtiZHxzY3JpcHQpKFxcc3w+KS9pLnRlc3QoY2FwWzBdKSkge1xuICAgICAgICB0aGlzLmxleGVyLnN0YXRlLmluUmF3QmxvY2sgPSBmYWxzZTtcbiAgICAgIH1cbiAgICAgIHJldHVybiB7XG4gICAgICAgIHR5cGU6IHRoaXMub3B0aW9ucy5zYW5pdGl6ZSA/ICd0ZXh0JyA6ICdodG1sJyxcbiAgICAgICAgcmF3OiBjYXBbMF0sXG4gICAgICAgIGluTGluazogdGhpcy5sZXhlci5zdGF0ZS5pbkxpbmssXG4gICAgICAgIGluUmF3QmxvY2s6IHRoaXMubGV4ZXIuc3RhdGUuaW5SYXdCbG9jayxcbiAgICAgICAgdGV4dDogdGhpcy5vcHRpb25zLnNhbml0aXplID8gdGhpcy5vcHRpb25zLnNhbml0aXplciA/IHRoaXMub3B0aW9ucy5zYW5pdGl6ZXIoY2FwWzBdKSA6IGVzY2FwZShjYXBbMF0pIDogY2FwWzBdXG4gICAgICB9O1xuICAgIH1cbiAgfTtcbiAgX3Byb3RvLmxpbmsgPSBmdW5jdGlvbiBsaW5rKHNyYykge1xuICAgIHZhciBjYXAgPSB0aGlzLnJ1bGVzLmlubGluZS5saW5rLmV4ZWMoc3JjKTtcbiAgICBpZiAoY2FwKSB7XG4gICAgICB2YXIgdHJpbW1lZFVybCA9IGNhcFsyXS50cmltKCk7XG4gICAgICBpZiAoIXRoaXMub3B0aW9ucy5wZWRhbnRpYyAmJiAvXjwvLnRlc3QodHJpbW1lZFVybCkpIHtcbiAgICAgICAgLy8gY29tbW9ubWFyayByZXF1aXJlcyBtYXRjaGluZyBhbmdsZSBicmFja2V0c1xuICAgICAgICBpZiAoIS8+JC8udGVzdCh0cmltbWVkVXJsKSkge1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIGVuZGluZyBhbmdsZSBicmFja2V0IGNhbm5vdCBiZSBlc2NhcGVkXG4gICAgICAgIHZhciBydHJpbVNsYXNoID0gcnRyaW0odHJpbW1lZFVybC5zbGljZSgwLCAtMSksICdcXFxcJyk7XG4gICAgICAgIGlmICgodHJpbW1lZFVybC5sZW5ndGggLSBydHJpbVNsYXNoLmxlbmd0aCkgJSAyID09PSAwKSB7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBmaW5kIGNsb3NpbmcgcGFyZW50aGVzaXNcbiAgICAgICAgdmFyIGxhc3RQYXJlbkluZGV4ID0gZmluZENsb3NpbmdCcmFja2V0KGNhcFsyXSwgJygpJyk7XG4gICAgICAgIGlmIChsYXN0UGFyZW5JbmRleCA+IC0xKSB7XG4gICAgICAgICAgdmFyIHN0YXJ0ID0gY2FwWzBdLmluZGV4T2YoJyEnKSA9PT0gMCA/IDUgOiA0O1xuICAgICAgICAgIHZhciBsaW5rTGVuID0gc3RhcnQgKyBjYXBbMV0ubGVuZ3RoICsgbGFzdFBhcmVuSW5kZXg7XG4gICAgICAgICAgY2FwWzJdID0gY2FwWzJdLnN1YnN0cmluZygwLCBsYXN0UGFyZW5JbmRleCk7XG4gICAgICAgICAgY2FwWzBdID0gY2FwWzBdLnN1YnN0cmluZygwLCBsaW5rTGVuKS50cmltKCk7XG4gICAgICAgICAgY2FwWzNdID0gJyc7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHZhciBocmVmID0gY2FwWzJdO1xuICAgICAgdmFyIHRpdGxlID0gJyc7XG4gICAgICBpZiAodGhpcy5vcHRpb25zLnBlZGFudGljKSB7XG4gICAgICAgIC8vIHNwbGl0IHBlZGFudGljIGhyZWYgYW5kIHRpdGxlXG4gICAgICAgIHZhciBsaW5rID0gL14oW14nXCJdKlteXFxzXSlcXHMrKFsnXCJdKSguKilcXDIvLmV4ZWMoaHJlZik7XG4gICAgICAgIGlmIChsaW5rKSB7XG4gICAgICAgICAgaHJlZiA9IGxpbmtbMV07XG4gICAgICAgICAgdGl0bGUgPSBsaW5rWzNdO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aXRsZSA9IGNhcFszXSA/IGNhcFszXS5zbGljZSgxLCAtMSkgOiAnJztcbiAgICAgIH1cbiAgICAgIGhyZWYgPSBocmVmLnRyaW0oKTtcbiAgICAgIGlmICgvXjwvLnRlc3QoaHJlZikpIHtcbiAgICAgICAgaWYgKHRoaXMub3B0aW9ucy5wZWRhbnRpYyAmJiAhLz4kLy50ZXN0KHRyaW1tZWRVcmwpKSB7XG4gICAgICAgICAgLy8gcGVkYW50aWMgYWxsb3dzIHN0YXJ0aW5nIGFuZ2xlIGJyYWNrZXQgd2l0aG91dCBlbmRpbmcgYW5nbGUgYnJhY2tldFxuICAgICAgICAgIGhyZWYgPSBocmVmLnNsaWNlKDEpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGhyZWYgPSBocmVmLnNsaWNlKDEsIC0xKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIG91dHB1dExpbmsoY2FwLCB7XG4gICAgICAgIGhyZWY6IGhyZWYgPyBocmVmLnJlcGxhY2UodGhpcy5ydWxlcy5pbmxpbmUuX2VzY2FwZXMsICckMScpIDogaHJlZixcbiAgICAgICAgdGl0bGU6IHRpdGxlID8gdGl0bGUucmVwbGFjZSh0aGlzLnJ1bGVzLmlubGluZS5fZXNjYXBlcywgJyQxJykgOiB0aXRsZVxuICAgICAgfSwgY2FwWzBdLCB0aGlzLmxleGVyKTtcbiAgICB9XG4gIH07XG4gIF9wcm90by5yZWZsaW5rID0gZnVuY3Rpb24gcmVmbGluayhzcmMsIGxpbmtzKSB7XG4gICAgdmFyIGNhcDtcbiAgICBpZiAoKGNhcCA9IHRoaXMucnVsZXMuaW5saW5lLnJlZmxpbmsuZXhlYyhzcmMpKSB8fCAoY2FwID0gdGhpcy5ydWxlcy5pbmxpbmUubm9saW5rLmV4ZWMoc3JjKSkpIHtcbiAgICAgIHZhciBsaW5rID0gKGNhcFsyXSB8fCBjYXBbMV0pLnJlcGxhY2UoL1xccysvZywgJyAnKTtcbiAgICAgIGxpbmsgPSBsaW5rc1tsaW5rLnRvTG93ZXJDYXNlKCldO1xuICAgICAgaWYgKCFsaW5rKSB7XG4gICAgICAgIHZhciB0ZXh0ID0gY2FwWzBdLmNoYXJBdCgwKTtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICB0eXBlOiAndGV4dCcsXG4gICAgICAgICAgcmF3OiB0ZXh0LFxuICAgICAgICAgIHRleHQ6IHRleHRcbiAgICAgICAgfTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBvdXRwdXRMaW5rKGNhcCwgbGluaywgY2FwWzBdLCB0aGlzLmxleGVyKTtcbiAgICB9XG4gIH07XG4gIF9wcm90by5lbVN0cm9uZyA9IGZ1bmN0aW9uIGVtU3Ryb25nKHNyYywgbWFza2VkU3JjLCBwcmV2Q2hhcikge1xuICAgIGlmIChwcmV2Q2hhciA9PT0gdm9pZCAwKSB7XG4gICAgICBwcmV2Q2hhciA9ICcnO1xuICAgIH1cbiAgICB2YXIgbWF0Y2ggPSB0aGlzLnJ1bGVzLmlubGluZS5lbVN0cm9uZy5sRGVsaW0uZXhlYyhzcmMpO1xuICAgIGlmICghbWF0Y2gpIHJldHVybjtcblxuICAgIC8vIF8gY2FuJ3QgYmUgYmV0d2VlbiB0d28gYWxwaGFudW1lcmljcy4gXFxwe0x9XFxwe059IGluY2x1ZGVzIG5vbi1lbmdsaXNoIGFscGhhYmV0L251bWJlcnMgYXMgd2VsbFxuICAgIGlmIChtYXRjaFszXSAmJiBwcmV2Q2hhci5tYXRjaCgvKD86WzAtOUEtWmEtelxceEFBXFx4QjJcXHhCM1xceEI1XFx4QjlcXHhCQVxceEJDLVxceEJFXFx4QzAtXFx4RDZcXHhEOC1cXHhGNlxceEY4LVxcdTAyQzFcXHUwMkM2LVxcdTAyRDFcXHUwMkUwLVxcdTAyRTRcXHUwMkVDXFx1MDJFRVxcdTAzNzAtXFx1MDM3NFxcdTAzNzZcXHUwMzc3XFx1MDM3QS1cXHUwMzdEXFx1MDM3RlxcdTAzODZcXHUwMzg4LVxcdTAzOEFcXHUwMzhDXFx1MDM4RS1cXHUwM0ExXFx1MDNBMy1cXHUwM0Y1XFx1MDNGNy1cXHUwNDgxXFx1MDQ4QS1cXHUwNTJGXFx1MDUzMS1cXHUwNTU2XFx1MDU1OVxcdTA1NjAtXFx1MDU4OFxcdTA1RDAtXFx1MDVFQVxcdTA1RUYtXFx1MDVGMlxcdTA2MjAtXFx1MDY0QVxcdTA2NjAtXFx1MDY2OVxcdTA2NkVcXHUwNjZGXFx1MDY3MS1cXHUwNkQzXFx1MDZENVxcdTA2RTVcXHUwNkU2XFx1MDZFRS1cXHUwNkZDXFx1MDZGRlxcdTA3MTBcXHUwNzEyLVxcdTA3MkZcXHUwNzRELVxcdTA3QTVcXHUwN0IxXFx1MDdDMC1cXHUwN0VBXFx1MDdGNFxcdTA3RjVcXHUwN0ZBXFx1MDgwMC1cXHUwODE1XFx1MDgxQVxcdTA4MjRcXHUwODI4XFx1MDg0MC1cXHUwODU4XFx1MDg2MC1cXHUwODZBXFx1MDg3MC1cXHUwODg3XFx1MDg4OS1cXHUwODhFXFx1MDhBMC1cXHUwOEM5XFx1MDkwNC1cXHUwOTM5XFx1MDkzRFxcdTA5NTBcXHUwOTU4LVxcdTA5NjFcXHUwOTY2LVxcdTA5NkZcXHUwOTcxLVxcdTA5ODBcXHUwOTg1LVxcdTA5OENcXHUwOThGXFx1MDk5MFxcdTA5OTMtXFx1MDlBOFxcdTA5QUEtXFx1MDlCMFxcdTA5QjJcXHUwOUI2LVxcdTA5QjlcXHUwOUJEXFx1MDlDRVxcdTA5RENcXHUwOUREXFx1MDlERi1cXHUwOUUxXFx1MDlFNi1cXHUwOUYxXFx1MDlGNC1cXHUwOUY5XFx1MDlGQ1xcdTBBMDUtXFx1MEEwQVxcdTBBMEZcXHUwQTEwXFx1MEExMy1cXHUwQTI4XFx1MEEyQS1cXHUwQTMwXFx1MEEzMlxcdTBBMzNcXHUwQTM1XFx1MEEzNlxcdTBBMzhcXHUwQTM5XFx1MEE1OS1cXHUwQTVDXFx1MEE1RVxcdTBBNjYtXFx1MEE2RlxcdTBBNzItXFx1MEE3NFxcdTBBODUtXFx1MEE4RFxcdTBBOEYtXFx1MEE5MVxcdTBBOTMtXFx1MEFBOFxcdTBBQUEtXFx1MEFCMFxcdTBBQjJcXHUwQUIzXFx1MEFCNS1cXHUwQUI5XFx1MEFCRFxcdTBBRDBcXHUwQUUwXFx1MEFFMVxcdTBBRTYtXFx1MEFFRlxcdTBBRjlcXHUwQjA1LVxcdTBCMENcXHUwQjBGXFx1MEIxMFxcdTBCMTMtXFx1MEIyOFxcdTBCMkEtXFx1MEIzMFxcdTBCMzJcXHUwQjMzXFx1MEIzNS1cXHUwQjM5XFx1MEIzRFxcdTBCNUNcXHUwQjVEXFx1MEI1Ri1cXHUwQjYxXFx1MEI2Ni1cXHUwQjZGXFx1MEI3MS1cXHUwQjc3XFx1MEI4M1xcdTBCODUtXFx1MEI4QVxcdTBCOEUtXFx1MEI5MFxcdTBCOTItXFx1MEI5NVxcdTBCOTlcXHUwQjlBXFx1MEI5Q1xcdTBCOUVcXHUwQjlGXFx1MEJBM1xcdTBCQTRcXHUwQkE4LVxcdTBCQUFcXHUwQkFFLVxcdTBCQjlcXHUwQkQwXFx1MEJFNi1cXHUwQkYyXFx1MEMwNS1cXHUwQzBDXFx1MEMwRS1cXHUwQzEwXFx1MEMxMi1cXHUwQzI4XFx1MEMyQS1cXHUwQzM5XFx1MEMzRFxcdTBDNTgtXFx1MEM1QVxcdTBDNURcXHUwQzYwXFx1MEM2MVxcdTBDNjYtXFx1MEM2RlxcdTBDNzgtXFx1MEM3RVxcdTBDODBcXHUwQzg1LVxcdTBDOENcXHUwQzhFLVxcdTBDOTBcXHUwQzkyLVxcdTBDQThcXHUwQ0FBLVxcdTBDQjNcXHUwQ0I1LVxcdTBDQjlcXHUwQ0JEXFx1MENERFxcdTBDREVcXHUwQ0UwXFx1MENFMVxcdTBDRTYtXFx1MENFRlxcdTBDRjFcXHUwQ0YyXFx1MEQwNC1cXHUwRDBDXFx1MEQwRS1cXHUwRDEwXFx1MEQxMi1cXHUwRDNBXFx1MEQzRFxcdTBENEVcXHUwRDU0LVxcdTBENTZcXHUwRDU4LVxcdTBENjFcXHUwRDY2LVxcdTBENzhcXHUwRDdBLVxcdTBEN0ZcXHUwRDg1LVxcdTBEOTZcXHUwRDlBLVxcdTBEQjFcXHUwREIzLVxcdTBEQkJcXHUwREJEXFx1MERDMC1cXHUwREM2XFx1MERFNi1cXHUwREVGXFx1MEUwMS1cXHUwRTMwXFx1MEUzMlxcdTBFMzNcXHUwRTQwLVxcdTBFNDZcXHUwRTUwLVxcdTBFNTlcXHUwRTgxXFx1MEU4MlxcdTBFODRcXHUwRTg2LVxcdTBFOEFcXHUwRThDLVxcdTBFQTNcXHUwRUE1XFx1MEVBNy1cXHUwRUIwXFx1MEVCMlxcdTBFQjNcXHUwRUJEXFx1MEVDMC1cXHUwRUM0XFx1MEVDNlxcdTBFRDAtXFx1MEVEOVxcdTBFREMtXFx1MEVERlxcdTBGMDBcXHUwRjIwLVxcdTBGMzNcXHUwRjQwLVxcdTBGNDdcXHUwRjQ5LVxcdTBGNkNcXHUwRjg4LVxcdTBGOENcXHUxMDAwLVxcdTEwMkFcXHUxMDNGLVxcdTEwNDlcXHUxMDUwLVxcdTEwNTVcXHUxMDVBLVxcdTEwNURcXHUxMDYxXFx1MTA2NVxcdTEwNjZcXHUxMDZFLVxcdTEwNzBcXHUxMDc1LVxcdTEwODFcXHUxMDhFXFx1MTA5MC1cXHUxMDk5XFx1MTBBMC1cXHUxMEM1XFx1MTBDN1xcdTEwQ0RcXHUxMEQwLVxcdTEwRkFcXHUxMEZDLVxcdTEyNDhcXHUxMjRBLVxcdTEyNERcXHUxMjUwLVxcdTEyNTZcXHUxMjU4XFx1MTI1QS1cXHUxMjVEXFx1MTI2MC1cXHUxMjg4XFx1MTI4QS1cXHUxMjhEXFx1MTI5MC1cXHUxMkIwXFx1MTJCMi1cXHUxMkI1XFx1MTJCOC1cXHUxMkJFXFx1MTJDMFxcdTEyQzItXFx1MTJDNVxcdTEyQzgtXFx1MTJENlxcdTEyRDgtXFx1MTMxMFxcdTEzMTItXFx1MTMxNVxcdTEzMTgtXFx1MTM1QVxcdTEzNjktXFx1MTM3Q1xcdTEzODAtXFx1MTM4RlxcdTEzQTAtXFx1MTNGNVxcdTEzRjgtXFx1MTNGRFxcdTE0MDEtXFx1MTY2Q1xcdTE2NkYtXFx1MTY3RlxcdTE2ODEtXFx1MTY5QVxcdTE2QTAtXFx1MTZFQVxcdTE2RUUtXFx1MTZGOFxcdTE3MDAtXFx1MTcxMVxcdTE3MUYtXFx1MTczMVxcdTE3NDAtXFx1MTc1MVxcdTE3NjAtXFx1MTc2Q1xcdTE3NkUtXFx1MTc3MFxcdTE3ODAtXFx1MTdCM1xcdTE3RDdcXHUxN0RDXFx1MTdFMC1cXHUxN0U5XFx1MTdGMC1cXHUxN0Y5XFx1MTgxMC1cXHUxODE5XFx1MTgyMC1cXHUxODc4XFx1MTg4MC1cXHUxODg0XFx1MTg4Ny1cXHUxOEE4XFx1MThBQVxcdTE4QjAtXFx1MThGNVxcdTE5MDAtXFx1MTkxRVxcdTE5NDYtXFx1MTk2RFxcdTE5NzAtXFx1MTk3NFxcdTE5ODAtXFx1MTlBQlxcdTE5QjAtXFx1MTlDOVxcdTE5RDAtXFx1MTlEQVxcdTFBMDAtXFx1MUExNlxcdTFBMjAtXFx1MUE1NFxcdTFBODAtXFx1MUE4OVxcdTFBOTAtXFx1MUE5OVxcdTFBQTdcXHUxQjA1LVxcdTFCMzNcXHUxQjQ1LVxcdTFCNENcXHUxQjUwLVxcdTFCNTlcXHUxQjgzLVxcdTFCQTBcXHUxQkFFLVxcdTFCRTVcXHUxQzAwLVxcdTFDMjNcXHUxQzQwLVxcdTFDNDlcXHUxQzRELVxcdTFDN0RcXHUxQzgwLVxcdTFDODhcXHUxQzkwLVxcdTFDQkFcXHUxQ0JELVxcdTFDQkZcXHUxQ0U5LVxcdTFDRUNcXHUxQ0VFLVxcdTFDRjNcXHUxQ0Y1XFx1MUNGNlxcdTFDRkFcXHUxRDAwLVxcdTFEQkZcXHUxRTAwLVxcdTFGMTVcXHUxRjE4LVxcdTFGMURcXHUxRjIwLVxcdTFGNDVcXHUxRjQ4LVxcdTFGNERcXHUxRjUwLVxcdTFGNTdcXHUxRjU5XFx1MUY1QlxcdTFGNURcXHUxRjVGLVxcdTFGN0RcXHUxRjgwLVxcdTFGQjRcXHUxRkI2LVxcdTFGQkNcXHUxRkJFXFx1MUZDMi1cXHUxRkM0XFx1MUZDNi1cXHUxRkNDXFx1MUZEMC1cXHUxRkQzXFx1MUZENi1cXHUxRkRCXFx1MUZFMC1cXHUxRkVDXFx1MUZGMi1cXHUxRkY0XFx1MUZGNi1cXHUxRkZDXFx1MjA3MFxcdTIwNzFcXHUyMDc0LVxcdTIwNzlcXHUyMDdGLVxcdTIwODlcXHUyMDkwLVxcdTIwOUNcXHUyMTAyXFx1MjEwN1xcdTIxMEEtXFx1MjExM1xcdTIxMTVcXHUyMTE5LVxcdTIxMURcXHUyMTI0XFx1MjEyNlxcdTIxMjhcXHUyMTJBLVxcdTIxMkRcXHUyMTJGLVxcdTIxMzlcXHUyMTNDLVxcdTIxM0ZcXHUyMTQ1LVxcdTIxNDlcXHUyMTRFXFx1MjE1MC1cXHUyMTg5XFx1MjQ2MC1cXHUyNDlCXFx1MjRFQS1cXHUyNEZGXFx1Mjc3Ni1cXHUyNzkzXFx1MkMwMC1cXHUyQ0U0XFx1MkNFQi1cXHUyQ0VFXFx1MkNGMlxcdTJDRjNcXHUyQ0ZEXFx1MkQwMC1cXHUyRDI1XFx1MkQyN1xcdTJEMkRcXHUyRDMwLVxcdTJENjdcXHUyRDZGXFx1MkQ4MC1cXHUyRDk2XFx1MkRBMC1cXHUyREE2XFx1MkRBOC1cXHUyREFFXFx1MkRCMC1cXHUyREI2XFx1MkRCOC1cXHUyREJFXFx1MkRDMC1cXHUyREM2XFx1MkRDOC1cXHUyRENFXFx1MkREMC1cXHUyREQ2XFx1MkREOC1cXHUyRERFXFx1MkUyRlxcdTMwMDUtXFx1MzAwN1xcdTMwMjEtXFx1MzAyOVxcdTMwMzEtXFx1MzAzNVxcdTMwMzgtXFx1MzAzQ1xcdTMwNDEtXFx1MzA5NlxcdTMwOUQtXFx1MzA5RlxcdTMwQTEtXFx1MzBGQVxcdTMwRkMtXFx1MzBGRlxcdTMxMDUtXFx1MzEyRlxcdTMxMzEtXFx1MzE4RVxcdTMxOTItXFx1MzE5NVxcdTMxQTAtXFx1MzFCRlxcdTMxRjAtXFx1MzFGRlxcdTMyMjAtXFx1MzIyOVxcdTMyNDgtXFx1MzI0RlxcdTMyNTEtXFx1MzI1RlxcdTMyODAtXFx1MzI4OVxcdTMyQjEtXFx1MzJCRlxcdTM0MDAtXFx1NERCRlxcdTRFMDAtXFx1QTQ4Q1xcdUE0RDAtXFx1QTRGRFxcdUE1MDAtXFx1QTYwQ1xcdUE2MTAtXFx1QTYyQlxcdUE2NDAtXFx1QTY2RVxcdUE2N0YtXFx1QTY5RFxcdUE2QTAtXFx1QTZFRlxcdUE3MTctXFx1QTcxRlxcdUE3MjItXFx1QTc4OFxcdUE3OEItXFx1QTdDQVxcdUE3RDBcXHVBN0QxXFx1QTdEM1xcdUE3RDUtXFx1QTdEOVxcdUE3RjItXFx1QTgwMVxcdUE4MDMtXFx1QTgwNVxcdUE4MDctXFx1QTgwQVxcdUE4MEMtXFx1QTgyMlxcdUE4MzAtXFx1QTgzNVxcdUE4NDAtXFx1QTg3M1xcdUE4ODItXFx1QThCM1xcdUE4RDAtXFx1QThEOVxcdUE4RjItXFx1QThGN1xcdUE4RkJcXHVBOEZEXFx1QThGRVxcdUE5MDAtXFx1QTkyNVxcdUE5MzAtXFx1QTk0NlxcdUE5NjAtXFx1QTk3Q1xcdUE5ODQtXFx1QTlCMlxcdUE5Q0YtXFx1QTlEOVxcdUE5RTAtXFx1QTlFNFxcdUE5RTYtXFx1QTlGRVxcdUFBMDAtXFx1QUEyOFxcdUFBNDAtXFx1QUE0MlxcdUFBNDQtXFx1QUE0QlxcdUFBNTAtXFx1QUE1OVxcdUFBNjAtXFx1QUE3NlxcdUFBN0FcXHVBQTdFLVxcdUFBQUZcXHVBQUIxXFx1QUFCNVxcdUFBQjZcXHVBQUI5LVxcdUFBQkRcXHVBQUMwXFx1QUFDMlxcdUFBREItXFx1QUFERFxcdUFBRTAtXFx1QUFFQVxcdUFBRjItXFx1QUFGNFxcdUFCMDEtXFx1QUIwNlxcdUFCMDktXFx1QUIwRVxcdUFCMTEtXFx1QUIxNlxcdUFCMjAtXFx1QUIyNlxcdUFCMjgtXFx1QUIyRVxcdUFCMzAtXFx1QUI1QVxcdUFCNUMtXFx1QUI2OVxcdUFCNzAtXFx1QUJFMlxcdUFCRjAtXFx1QUJGOVxcdUFDMDAtXFx1RDdBM1xcdUQ3QjAtXFx1RDdDNlxcdUQ3Q0ItXFx1RDdGQlxcdUY5MDAtXFx1RkE2RFxcdUZBNzAtXFx1RkFEOVxcdUZCMDAtXFx1RkIwNlxcdUZCMTMtXFx1RkIxN1xcdUZCMURcXHVGQjFGLVxcdUZCMjhcXHVGQjJBLVxcdUZCMzZcXHVGQjM4LVxcdUZCM0NcXHVGQjNFXFx1RkI0MFxcdUZCNDFcXHVGQjQzXFx1RkI0NFxcdUZCNDYtXFx1RkJCMVxcdUZCRDMtXFx1RkQzRFxcdUZENTAtXFx1RkQ4RlxcdUZEOTItXFx1RkRDN1xcdUZERjAtXFx1RkRGQlxcdUZFNzAtXFx1RkU3NFxcdUZFNzYtXFx1RkVGQ1xcdUZGMTAtXFx1RkYxOVxcdUZGMjEtXFx1RkYzQVxcdUZGNDEtXFx1RkY1QVxcdUZGNjYtXFx1RkZCRVxcdUZGQzItXFx1RkZDN1xcdUZGQ0EtXFx1RkZDRlxcdUZGRDItXFx1RkZEN1xcdUZGREEtXFx1RkZEQ118XFx1RDgwMFtcXHVEQzAwLVxcdURDMEJcXHVEQzBELVxcdURDMjZcXHVEQzI4LVxcdURDM0FcXHVEQzNDXFx1REMzRFxcdURDM0YtXFx1REM0RFxcdURDNTAtXFx1REM1RFxcdURDODAtXFx1RENGQVxcdUREMDctXFx1REQzM1xcdURENDAtXFx1REQ3OFxcdUREOEFcXHVERDhCXFx1REU4MC1cXHVERTlDXFx1REVBMC1cXHVERUQwXFx1REVFMS1cXHVERUZCXFx1REYwMC1cXHVERjIzXFx1REYyRC1cXHVERjRBXFx1REY1MC1cXHVERjc1XFx1REY4MC1cXHVERjlEXFx1REZBMC1cXHVERkMzXFx1REZDOC1cXHVERkNGXFx1REZEMS1cXHVERkQ1XXxcXHVEODAxW1xcdURDMDAtXFx1REM5RFxcdURDQTAtXFx1RENBOVxcdURDQjAtXFx1RENEM1xcdURDRDgtXFx1RENGQlxcdUREMDAtXFx1REQyN1xcdUREMzAtXFx1REQ2M1xcdURENzAtXFx1REQ3QVxcdUREN0MtXFx1REQ4QVxcdUREOEMtXFx1REQ5MlxcdUREOTRcXHVERDk1XFx1REQ5Ny1cXHVEREExXFx1RERBMy1cXHVEREIxXFx1RERCMy1cXHVEREI5XFx1RERCQlxcdUREQkNcXHVERTAwLVxcdURGMzZcXHVERjQwLVxcdURGNTVcXHVERjYwLVxcdURGNjdcXHVERjgwLVxcdURGODVcXHVERjg3LVxcdURGQjBcXHVERkIyLVxcdURGQkFdfFxcdUQ4MDJbXFx1REMwMC1cXHVEQzA1XFx1REMwOFxcdURDMEEtXFx1REMzNVxcdURDMzdcXHVEQzM4XFx1REMzQ1xcdURDM0YtXFx1REM1NVxcdURDNTgtXFx1REM3NlxcdURDNzktXFx1REM5RVxcdURDQTctXFx1RENBRlxcdURDRTAtXFx1RENGMlxcdURDRjRcXHVEQ0Y1XFx1RENGQi1cXHVERDFCXFx1REQyMC1cXHVERDM5XFx1REQ4MC1cXHVEREI3XFx1RERCQy1cXHVERENGXFx1REREMi1cXHVERTAwXFx1REUxMC1cXHVERTEzXFx1REUxNS1cXHVERTE3XFx1REUxOS1cXHVERTM1XFx1REU0MC1cXHVERTQ4XFx1REU2MC1cXHVERTdFXFx1REU4MC1cXHVERTlGXFx1REVDMC1cXHVERUM3XFx1REVDOS1cXHVERUU0XFx1REVFQi1cXHVERUVGXFx1REYwMC1cXHVERjM1XFx1REY0MC1cXHVERjU1XFx1REY1OC1cXHVERjcyXFx1REY3OC1cXHVERjkxXFx1REZBOS1cXHVERkFGXXxcXHVEODAzW1xcdURDMDAtXFx1REM0OFxcdURDODAtXFx1RENCMlxcdURDQzAtXFx1RENGMlxcdURDRkEtXFx1REQyM1xcdUREMzAtXFx1REQzOVxcdURFNjAtXFx1REU3RVxcdURFODAtXFx1REVBOVxcdURFQjBcXHVERUIxXFx1REYwMC1cXHVERjI3XFx1REYzMC1cXHVERjQ1XFx1REY1MS1cXHVERjU0XFx1REY3MC1cXHVERjgxXFx1REZCMC1cXHVERkNCXFx1REZFMC1cXHVERkY2XXxcXHVEODA0W1xcdURDMDMtXFx1REMzN1xcdURDNTItXFx1REM2RlxcdURDNzFcXHVEQzcyXFx1REM3NVxcdURDODMtXFx1RENBRlxcdURDRDAtXFx1RENFOFxcdURDRjAtXFx1RENGOVxcdUREMDMtXFx1REQyNlxcdUREMzYtXFx1REQzRlxcdURENDRcXHVERDQ3XFx1REQ1MC1cXHVERDcyXFx1REQ3NlxcdUREODMtXFx1RERCMlxcdUREQzEtXFx1RERDNFxcdURERDAtXFx1REREQVxcdURERENcXHVEREUxLVxcdURERjRcXHVERTAwLVxcdURFMTFcXHVERTEzLVxcdURFMkJcXHVERTgwLVxcdURFODZcXHVERTg4XFx1REU4QS1cXHVERThEXFx1REU4Ri1cXHVERTlEXFx1REU5Ri1cXHVERUE4XFx1REVCMC1cXHVERURFXFx1REVGMC1cXHVERUY5XFx1REYwNS1cXHVERjBDXFx1REYwRlxcdURGMTBcXHVERjEzLVxcdURGMjhcXHVERjJBLVxcdURGMzBcXHVERjMyXFx1REYzM1xcdURGMzUtXFx1REYzOVxcdURGM0RcXHVERjUwXFx1REY1RC1cXHVERjYxXXxcXHVEODA1W1xcdURDMDAtXFx1REMzNFxcdURDNDctXFx1REM0QVxcdURDNTAtXFx1REM1OVxcdURDNUYtXFx1REM2MVxcdURDODAtXFx1RENBRlxcdURDQzRcXHVEQ0M1XFx1RENDN1xcdURDRDAtXFx1RENEOVxcdUREODAtXFx1RERBRVxcdURERDgtXFx1REREQlxcdURFMDAtXFx1REUyRlxcdURFNDRcXHVERTUwLVxcdURFNTlcXHVERTgwLVxcdURFQUFcXHVERUI4XFx1REVDMC1cXHVERUM5XFx1REYwMC1cXHVERjFBXFx1REYzMC1cXHVERjNCXFx1REY0MC1cXHVERjQ2XXxcXHVEODA2W1xcdURDMDAtXFx1REMyQlxcdURDQTAtXFx1RENGMlxcdURDRkYtXFx1REQwNlxcdUREMDlcXHVERDBDLVxcdUREMTNcXHVERDE1XFx1REQxNlxcdUREMTgtXFx1REQyRlxcdUREM0ZcXHVERDQxXFx1REQ1MC1cXHVERDU5XFx1RERBMC1cXHVEREE3XFx1RERBQS1cXHVEREQwXFx1RERFMVxcdURERTNcXHVERTAwXFx1REUwQi1cXHVERTMyXFx1REUzQVxcdURFNTBcXHVERTVDLVxcdURFODlcXHVERTlEXFx1REVCMC1cXHVERUY4XXxcXHVEODA3W1xcdURDMDAtXFx1REMwOFxcdURDMEEtXFx1REMyRVxcdURDNDBcXHVEQzUwLVxcdURDNkNcXHVEQzcyLVxcdURDOEZcXHVERDAwLVxcdUREMDZcXHVERDA4XFx1REQwOVxcdUREMEItXFx1REQzMFxcdURENDZcXHVERDUwLVxcdURENTlcXHVERDYwLVxcdURENjVcXHVERDY3XFx1REQ2OFxcdURENkEtXFx1REQ4OVxcdUREOThcXHVEREEwLVxcdUREQTlcXHVERUUwLVxcdURFRjJcXHVERkIwXFx1REZDMC1cXHVERkQ0XXxcXHVEODA4W1xcdURDMDAtXFx1REY5OV18XFx1RDgwOVtcXHVEQzAwLVxcdURDNkVcXHVEQzgwLVxcdURENDNdfFxcdUQ4MEJbXFx1REY5MC1cXHVERkYwXXxbXFx1RDgwQ1xcdUQ4MUMtXFx1RDgyMFxcdUQ4MjJcXHVEODQwLVxcdUQ4NjhcXHVEODZBLVxcdUQ4NkNcXHVEODZGLVxcdUQ4NzJcXHVEODc0LVxcdUQ4NzlcXHVEODgwLVxcdUQ4ODNdW1xcdURDMDAtXFx1REZGRl18XFx1RDgwRFtcXHVEQzAwLVxcdURDMkVdfFxcdUQ4MTFbXFx1REMwMC1cXHVERTQ2XXxcXHVEODFBW1xcdURDMDAtXFx1REUzOFxcdURFNDAtXFx1REU1RVxcdURFNjAtXFx1REU2OVxcdURFNzAtXFx1REVCRVxcdURFQzAtXFx1REVDOVxcdURFRDAtXFx1REVFRFxcdURGMDAtXFx1REYyRlxcdURGNDAtXFx1REY0M1xcdURGNTAtXFx1REY1OVxcdURGNUItXFx1REY2MVxcdURGNjMtXFx1REY3N1xcdURGN0QtXFx1REY4Rl18XFx1RDgxQltcXHVERTQwLVxcdURFOTZcXHVERjAwLVxcdURGNEFcXHVERjUwXFx1REY5My1cXHVERjlGXFx1REZFMFxcdURGRTFcXHVERkUzXXxcXHVEODIxW1xcdURDMDAtXFx1REZGN118XFx1RDgyM1tcXHVEQzAwLVxcdURDRDVcXHVERDAwLVxcdUREMDhdfFxcdUQ4MkJbXFx1REZGMC1cXHVERkYzXFx1REZGNS1cXHVERkZCXFx1REZGRFxcdURGRkVdfFxcdUQ4MkNbXFx1REMwMC1cXHVERDIyXFx1REQ1MC1cXHVERDUyXFx1REQ2NC1cXHVERDY3XFx1REQ3MC1cXHVERUZCXXxcXHVEODJGW1xcdURDMDAtXFx1REM2QVxcdURDNzAtXFx1REM3Q1xcdURDODAtXFx1REM4OFxcdURDOTAtXFx1REM5OV18XFx1RDgzNFtcXHVERUUwLVxcdURFRjNcXHVERjYwLVxcdURGNzhdfFxcdUQ4MzVbXFx1REMwMC1cXHVEQzU0XFx1REM1Ni1cXHVEQzlDXFx1REM5RVxcdURDOUZcXHVEQ0EyXFx1RENBNVxcdURDQTZcXHVEQ0E5LVxcdURDQUNcXHVEQ0FFLVxcdURDQjlcXHVEQ0JCXFx1RENCRC1cXHVEQ0MzXFx1RENDNS1cXHVERDA1XFx1REQwNy1cXHVERDBBXFx1REQwRC1cXHVERDE0XFx1REQxNi1cXHVERDFDXFx1REQxRS1cXHVERDM5XFx1REQzQi1cXHVERDNFXFx1REQ0MC1cXHVERDQ0XFx1REQ0NlxcdURENEEtXFx1REQ1MFxcdURENTItXFx1REVBNVxcdURFQTgtXFx1REVDMFxcdURFQzItXFx1REVEQVxcdURFREMtXFx1REVGQVxcdURFRkMtXFx1REYxNFxcdURGMTYtXFx1REYzNFxcdURGMzYtXFx1REY0RVxcdURGNTAtXFx1REY2RVxcdURGNzAtXFx1REY4OFxcdURGOEEtXFx1REZBOFxcdURGQUEtXFx1REZDMlxcdURGQzQtXFx1REZDQlxcdURGQ0UtXFx1REZGRl18XFx1RDgzN1tcXHVERjAwLVxcdURGMUVdfFxcdUQ4MzhbXFx1REQwMC1cXHVERDJDXFx1REQzNy1cXHVERDNEXFx1REQ0MC1cXHVERDQ5XFx1REQ0RVxcdURFOTAtXFx1REVBRFxcdURFQzAtXFx1REVFQlxcdURFRjAtXFx1REVGOV18XFx1RDgzOVtcXHVERkUwLVxcdURGRTZcXHVERkU4LVxcdURGRUJcXHVERkVEXFx1REZFRVxcdURGRjAtXFx1REZGRV18XFx1RDgzQVtcXHVEQzAwLVxcdURDQzRcXHVEQ0M3LVxcdURDQ0ZcXHVERDAwLVxcdURENDNcXHVERDRCXFx1REQ1MC1cXHVERDU5XXxcXHVEODNCW1xcdURDNzEtXFx1RENBQlxcdURDQUQtXFx1RENBRlxcdURDQjEtXFx1RENCNFxcdUREMDEtXFx1REQyRFxcdUREMkYtXFx1REQzRFxcdURFMDAtXFx1REUwM1xcdURFMDUtXFx1REUxRlxcdURFMjFcXHVERTIyXFx1REUyNFxcdURFMjdcXHVERTI5LVxcdURFMzJcXHVERTM0LVxcdURFMzdcXHVERTM5XFx1REUzQlxcdURFNDJcXHVERTQ3XFx1REU0OVxcdURFNEJcXHVERTRELVxcdURFNEZcXHVERTUxXFx1REU1MlxcdURFNTRcXHVERTU3XFx1REU1OVxcdURFNUJcXHVERTVEXFx1REU1RlxcdURFNjFcXHVERTYyXFx1REU2NFxcdURFNjctXFx1REU2QVxcdURFNkMtXFx1REU3MlxcdURFNzQtXFx1REU3N1xcdURFNzktXFx1REU3Q1xcdURFN0VcXHVERTgwLVxcdURFODlcXHVERThCLVxcdURFOUJcXHVERUExLVxcdURFQTNcXHVERUE1LVxcdURFQTlcXHVERUFCLVxcdURFQkJdfFxcdUQ4M0NbXFx1REQwMC1cXHVERDBDXXxcXHVEODNFW1xcdURGRjAtXFx1REZGOV18XFx1RDg2OVtcXHVEQzAwLVxcdURFREZcXHVERjAwLVxcdURGRkZdfFxcdUQ4NkRbXFx1REMwMC1cXHVERjM4XFx1REY0MC1cXHVERkZGXXxcXHVEODZFW1xcdURDMDAtXFx1REMxRFxcdURDMjAtXFx1REZGRl18XFx1RDg3M1tcXHVEQzAwLVxcdURFQTFcXHVERUIwLVxcdURGRkZdfFxcdUQ4N0FbXFx1REMwMC1cXHVERkUwXXxcXHVEODdFW1xcdURDMDAtXFx1REUxRF18XFx1RDg4NFtcXHVEQzAwLVxcdURGNEFdKS8pKSByZXR1cm47XG4gICAgdmFyIG5leHRDaGFyID0gbWF0Y2hbMV0gfHwgbWF0Y2hbMl0gfHwgJyc7XG4gICAgaWYgKCFuZXh0Q2hhciB8fCBuZXh0Q2hhciAmJiAocHJldkNoYXIgPT09ICcnIHx8IHRoaXMucnVsZXMuaW5saW5lLnB1bmN0dWF0aW9uLmV4ZWMocHJldkNoYXIpKSkge1xuICAgICAgdmFyIGxMZW5ndGggPSBtYXRjaFswXS5sZW5ndGggLSAxO1xuICAgICAgdmFyIHJEZWxpbSxcbiAgICAgICAgckxlbmd0aCxcbiAgICAgICAgZGVsaW1Ub3RhbCA9IGxMZW5ndGgsXG4gICAgICAgIG1pZERlbGltVG90YWwgPSAwO1xuICAgICAgdmFyIGVuZFJlZyA9IG1hdGNoWzBdWzBdID09PSAnKicgPyB0aGlzLnJ1bGVzLmlubGluZS5lbVN0cm9uZy5yRGVsaW1Bc3QgOiB0aGlzLnJ1bGVzLmlubGluZS5lbVN0cm9uZy5yRGVsaW1VbmQ7XG4gICAgICBlbmRSZWcubGFzdEluZGV4ID0gMDtcblxuICAgICAgLy8gQ2xpcCBtYXNrZWRTcmMgdG8gc2FtZSBzZWN0aW9uIG9mIHN0cmluZyBhcyBzcmMgKG1vdmUgdG8gbGV4ZXI/KVxuICAgICAgbWFza2VkU3JjID0gbWFza2VkU3JjLnNsaWNlKC0xICogc3JjLmxlbmd0aCArIGxMZW5ndGgpO1xuICAgICAgd2hpbGUgKChtYXRjaCA9IGVuZFJlZy5leGVjKG1hc2tlZFNyYykpICE9IG51bGwpIHtcbiAgICAgICAgckRlbGltID0gbWF0Y2hbMV0gfHwgbWF0Y2hbMl0gfHwgbWF0Y2hbM10gfHwgbWF0Y2hbNF0gfHwgbWF0Y2hbNV0gfHwgbWF0Y2hbNl07XG4gICAgICAgIGlmICghckRlbGltKSBjb250aW51ZTsgLy8gc2tpcCBzaW5nbGUgKiBpbiBfX2FiYyphYmNfX1xuXG4gICAgICAgIHJMZW5ndGggPSByRGVsaW0ubGVuZ3RoO1xuICAgICAgICBpZiAobWF0Y2hbM10gfHwgbWF0Y2hbNF0pIHtcbiAgICAgICAgICAvLyBmb3VuZCBhbm90aGVyIExlZnQgRGVsaW1cbiAgICAgICAgICBkZWxpbVRvdGFsICs9IHJMZW5ndGg7XG4gICAgICAgICAgY29udGludWU7XG4gICAgICAgIH0gZWxzZSBpZiAobWF0Y2hbNV0gfHwgbWF0Y2hbNl0pIHtcbiAgICAgICAgICAvLyBlaXRoZXIgTGVmdCBvciBSaWdodCBEZWxpbVxuICAgICAgICAgIGlmIChsTGVuZ3RoICUgMyAmJiAhKChsTGVuZ3RoICsgckxlbmd0aCkgJSAzKSkge1xuICAgICAgICAgICAgbWlkRGVsaW1Ub3RhbCArPSByTGVuZ3RoO1xuICAgICAgICAgICAgY29udGludWU7IC8vIENvbW1vbk1hcmsgRW1waGFzaXMgUnVsZXMgOS0xMFxuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGRlbGltVG90YWwgLT0gckxlbmd0aDtcbiAgICAgICAgaWYgKGRlbGltVG90YWwgPiAwKSBjb250aW51ZTsgLy8gSGF2ZW4ndCBmb3VuZCBlbm91Z2ggY2xvc2luZyBkZWxpbWl0ZXJzXG5cbiAgICAgICAgLy8gUmVtb3ZlIGV4dHJhIGNoYXJhY3RlcnMuICphKioqIC0+ICphKlxuICAgICAgICByTGVuZ3RoID0gTWF0aC5taW4ockxlbmd0aCwgckxlbmd0aCArIGRlbGltVG90YWwgKyBtaWREZWxpbVRvdGFsKTtcbiAgICAgICAgdmFyIHJhdyA9IHNyYy5zbGljZSgwLCBsTGVuZ3RoICsgbWF0Y2guaW5kZXggKyAobWF0Y2hbMF0ubGVuZ3RoIC0gckRlbGltLmxlbmd0aCkgKyByTGVuZ3RoKTtcblxuICAgICAgICAvLyBDcmVhdGUgYGVtYCBpZiBzbWFsbGVzdCBkZWxpbWl0ZXIgaGFzIG9kZCBjaGFyIGNvdW50LiAqYSoqKlxuICAgICAgICBpZiAoTWF0aC5taW4obExlbmd0aCwgckxlbmd0aCkgJSAyKSB7XG4gICAgICAgICAgdmFyIF90ZXh0ID0gcmF3LnNsaWNlKDEsIC0xKTtcbiAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgdHlwZTogJ2VtJyxcbiAgICAgICAgICAgIHJhdzogcmF3LFxuICAgICAgICAgICAgdGV4dDogX3RleHQsXG4gICAgICAgICAgICB0b2tlbnM6IHRoaXMubGV4ZXIuaW5saW5lVG9rZW5zKF90ZXh0KVxuICAgICAgICAgIH07XG4gICAgICAgIH1cblxuICAgICAgICAvLyBDcmVhdGUgJ3N0cm9uZycgaWYgc21hbGxlc3QgZGVsaW1pdGVyIGhhcyBldmVuIGNoYXIgY291bnQuICoqYSoqKlxuICAgICAgICB2YXIgdGV4dCA9IHJhdy5zbGljZSgyLCAtMik7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgdHlwZTogJ3N0cm9uZycsXG4gICAgICAgICAgcmF3OiByYXcsXG4gICAgICAgICAgdGV4dDogdGV4dCxcbiAgICAgICAgICB0b2tlbnM6IHRoaXMubGV4ZXIuaW5saW5lVG9rZW5zKHRleHQpXG4gICAgICAgIH07XG4gICAgICB9XG4gICAgfVxuICB9O1xuICBfcHJvdG8uY29kZXNwYW4gPSBmdW5jdGlvbiBjb2Rlc3BhbihzcmMpIHtcbiAgICB2YXIgY2FwID0gdGhpcy5ydWxlcy5pbmxpbmUuY29kZS5leGVjKHNyYyk7XG4gICAgaWYgKGNhcCkge1xuICAgICAgdmFyIHRleHQgPSBjYXBbMl0ucmVwbGFjZSgvXFxuL2csICcgJyk7XG4gICAgICB2YXIgaGFzTm9uU3BhY2VDaGFycyA9IC9bXiBdLy50ZXN0KHRleHQpO1xuICAgICAgdmFyIGhhc1NwYWNlQ2hhcnNPbkJvdGhFbmRzID0gL14gLy50ZXN0KHRleHQpICYmIC8gJC8udGVzdCh0ZXh0KTtcbiAgICAgIGlmIChoYXNOb25TcGFjZUNoYXJzICYmIGhhc1NwYWNlQ2hhcnNPbkJvdGhFbmRzKSB7XG4gICAgICAgIHRleHQgPSB0ZXh0LnN1YnN0cmluZygxLCB0ZXh0Lmxlbmd0aCAtIDEpO1xuICAgICAgfVxuICAgICAgdGV4dCA9IGVzY2FwZSh0ZXh0LCB0cnVlKTtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHR5cGU6ICdjb2Rlc3BhbicsXG4gICAgICAgIHJhdzogY2FwWzBdLFxuICAgICAgICB0ZXh0OiB0ZXh0XG4gICAgICB9O1xuICAgIH1cbiAgfTtcbiAgX3Byb3RvLmJyID0gZnVuY3Rpb24gYnIoc3JjKSB7XG4gICAgdmFyIGNhcCA9IHRoaXMucnVsZXMuaW5saW5lLmJyLmV4ZWMoc3JjKTtcbiAgICBpZiAoY2FwKSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICB0eXBlOiAnYnInLFxuICAgICAgICByYXc6IGNhcFswXVxuICAgICAgfTtcbiAgICB9XG4gIH07XG4gIF9wcm90by5kZWwgPSBmdW5jdGlvbiBkZWwoc3JjKSB7XG4gICAgdmFyIGNhcCA9IHRoaXMucnVsZXMuaW5saW5lLmRlbC5leGVjKHNyYyk7XG4gICAgaWYgKGNhcCkge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgdHlwZTogJ2RlbCcsXG4gICAgICAgIHJhdzogY2FwWzBdLFxuICAgICAgICB0ZXh0OiBjYXBbMl0sXG4gICAgICAgIHRva2VuczogdGhpcy5sZXhlci5pbmxpbmVUb2tlbnMoY2FwWzJdKVxuICAgICAgfTtcbiAgICB9XG4gIH07XG4gIF9wcm90by5hdXRvbGluayA9IGZ1bmN0aW9uIGF1dG9saW5rKHNyYywgbWFuZ2xlKSB7XG4gICAgdmFyIGNhcCA9IHRoaXMucnVsZXMuaW5saW5lLmF1dG9saW5rLmV4ZWMoc3JjKTtcbiAgICBpZiAoY2FwKSB7XG4gICAgICB2YXIgdGV4dCwgaHJlZjtcbiAgICAgIGlmIChjYXBbMl0gPT09ICdAJykge1xuICAgICAgICB0ZXh0ID0gZXNjYXBlKHRoaXMub3B0aW9ucy5tYW5nbGUgPyBtYW5nbGUoY2FwWzFdKSA6IGNhcFsxXSk7XG4gICAgICAgIGhyZWYgPSAnbWFpbHRvOicgKyB0ZXh0O1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGV4dCA9IGVzY2FwZShjYXBbMV0pO1xuICAgICAgICBocmVmID0gdGV4dDtcbiAgICAgIH1cbiAgICAgIHJldHVybiB7XG4gICAgICAgIHR5cGU6ICdsaW5rJyxcbiAgICAgICAgcmF3OiBjYXBbMF0sXG4gICAgICAgIHRleHQ6IHRleHQsXG4gICAgICAgIGhyZWY6IGhyZWYsXG4gICAgICAgIHRva2VuczogW3tcbiAgICAgICAgICB0eXBlOiAndGV4dCcsXG4gICAgICAgICAgcmF3OiB0ZXh0LFxuICAgICAgICAgIHRleHQ6IHRleHRcbiAgICAgICAgfV1cbiAgICAgIH07XG4gICAgfVxuICB9O1xuICBfcHJvdG8udXJsID0gZnVuY3Rpb24gdXJsKHNyYywgbWFuZ2xlKSB7XG4gICAgdmFyIGNhcDtcbiAgICBpZiAoY2FwID0gdGhpcy5ydWxlcy5pbmxpbmUudXJsLmV4ZWMoc3JjKSkge1xuICAgICAgdmFyIHRleHQsIGhyZWY7XG4gICAgICBpZiAoY2FwWzJdID09PSAnQCcpIHtcbiAgICAgICAgdGV4dCA9IGVzY2FwZSh0aGlzLm9wdGlvbnMubWFuZ2xlID8gbWFuZ2xlKGNhcFswXSkgOiBjYXBbMF0pO1xuICAgICAgICBocmVmID0gJ21haWx0bzonICsgdGV4dDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIGRvIGV4dGVuZGVkIGF1dG9saW5rIHBhdGggdmFsaWRhdGlvblxuICAgICAgICB2YXIgcHJldkNhcFplcm87XG4gICAgICAgIGRvIHtcbiAgICAgICAgICBwcmV2Q2FwWmVybyA9IGNhcFswXTtcbiAgICAgICAgICBjYXBbMF0gPSB0aGlzLnJ1bGVzLmlubGluZS5fYmFja3BlZGFsLmV4ZWMoY2FwWzBdKVswXTtcbiAgICAgICAgfSB3aGlsZSAocHJldkNhcFplcm8gIT09IGNhcFswXSk7XG4gICAgICAgIHRleHQgPSBlc2NhcGUoY2FwWzBdKTtcbiAgICAgICAgaWYgKGNhcFsxXSA9PT0gJ3d3dy4nKSB7XG4gICAgICAgICAgaHJlZiA9ICdodHRwOi8vJyArIGNhcFswXTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBocmVmID0gY2FwWzBdO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4ge1xuICAgICAgICB0eXBlOiAnbGluaycsXG4gICAgICAgIHJhdzogY2FwWzBdLFxuICAgICAgICB0ZXh0OiB0ZXh0LFxuICAgICAgICBocmVmOiBocmVmLFxuICAgICAgICB0b2tlbnM6IFt7XG4gICAgICAgICAgdHlwZTogJ3RleHQnLFxuICAgICAgICAgIHJhdzogdGV4dCxcbiAgICAgICAgICB0ZXh0OiB0ZXh0XG4gICAgICAgIH1dXG4gICAgICB9O1xuICAgIH1cbiAgfTtcbiAgX3Byb3RvLmlubGluZVRleHQgPSBmdW5jdGlvbiBpbmxpbmVUZXh0KHNyYywgc21hcnR5cGFudHMpIHtcbiAgICB2YXIgY2FwID0gdGhpcy5ydWxlcy5pbmxpbmUudGV4dC5leGVjKHNyYyk7XG4gICAgaWYgKGNhcCkge1xuICAgICAgdmFyIHRleHQ7XG4gICAgICBpZiAodGhpcy5sZXhlci5zdGF0ZS5pblJhd0Jsb2NrKSB7XG4gICAgICAgIHRleHQgPSB0aGlzLm9wdGlvbnMuc2FuaXRpemUgPyB0aGlzLm9wdGlvbnMuc2FuaXRpemVyID8gdGhpcy5vcHRpb25zLnNhbml0aXplcihjYXBbMF0pIDogZXNjYXBlKGNhcFswXSkgOiBjYXBbMF07XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0ZXh0ID0gZXNjYXBlKHRoaXMub3B0aW9ucy5zbWFydHlwYW50cyA/IHNtYXJ0eXBhbnRzKGNhcFswXSkgOiBjYXBbMF0pO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgdHlwZTogJ3RleHQnLFxuICAgICAgICByYXc6IGNhcFswXSxcbiAgICAgICAgdGV4dDogdGV4dFxuICAgICAgfTtcbiAgICB9XG4gIH07XG4gIHJldHVybiBUb2tlbml6ZXI7XG59KCk7XG5cbi8qKlxuICogQmxvY2stTGV2ZWwgR3JhbW1hclxuICovXG52YXIgYmxvY2sgPSB7XG4gIG5ld2xpbmU6IC9eKD86ICooPzpcXG58JCkpKy8sXG4gIGNvZGU6IC9eKCB7NH1bXlxcbl0rKD86XFxuKD86ICooPzpcXG58JCkpKik/KSsvLFxuICBmZW5jZXM6IC9eIHswLDN9KGB7Myx9KD89W15gXFxuXSpcXG4pfH57Myx9KShbXlxcbl0qKVxcbig/OnwoW1xcc1xcU10qPylcXG4pKD86IHswLDN9XFwxW35gXSogKig/PVxcbnwkKXwkKS8sXG4gIGhyOiAvXiB7MCwzfSgoPzotW1xcdCBdKil7Myx9fCg/Ol9bIFxcdF0qKXszLH18KD86XFwqWyBcXHRdKil7Myx9KSg/Olxcbit8JCkvLFxuICBoZWFkaW5nOiAvXiB7MCwzfSgjezEsNn0pKD89XFxzfCQpKC4qKSg/Olxcbit8JCkvLFxuICBibG9ja3F1b3RlOiAvXiggezAsM30+ID8ocGFyYWdyYXBofFteXFxuXSopKD86XFxufCQpKSsvLFxuICBsaXN0OiAvXiggezAsM31idWxsKShbIFxcdF1bXlxcbl0rPyk/KD86XFxufCQpLyxcbiAgaHRtbDogJ14gezAsM30oPzonIC8vIG9wdGlvbmFsIGluZGVudGF0aW9uXG4gICsgJzwoc2NyaXB0fHByZXxzdHlsZXx0ZXh0YXJlYSlbXFxcXHM+XVtcXFxcc1xcXFxTXSo/KD86PC9cXFxcMT5bXlxcXFxuXSpcXFxcbit8JCknIC8vICgxKVxuICArICd8Y29tbWVudFteXFxcXG5dKihcXFxcbit8JCknIC8vICgyKVxuICArICd8PFxcXFw/W1xcXFxzXFxcXFNdKj8oPzpcXFxcPz5cXFxcbip8JCknIC8vICgzKVxuICArICd8PCFbQS1aXVtcXFxcc1xcXFxTXSo/KD86PlxcXFxuKnwkKScgLy8gKDQpXG4gICsgJ3w8IVxcXFxbQ0RBVEFcXFxcW1tcXFxcc1xcXFxTXSo/KD86XFxcXF1cXFxcXT5cXFxcbip8JCknIC8vICg1KVxuICArICd8PC8/KHRhZykoPzogK3xcXFxcbnwvPz4pW1xcXFxzXFxcXFNdKj8oPzooPzpcXFxcbiAqKStcXFxcbnwkKScgLy8gKDYpXG4gICsgJ3w8KD8hc2NyaXB0fHByZXxzdHlsZXx0ZXh0YXJlYSkoW2Etel1bXFxcXHctXSopKD86YXR0cmlidXRlKSo/ICovPz4oPz1bIFxcXFx0XSooPzpcXFxcbnwkKSlbXFxcXHNcXFxcU10qPyg/Oig/OlxcXFxuICopK1xcXFxufCQpJyAvLyAoNykgb3BlbiB0YWdcbiAgKyAnfDwvKD8hc2NyaXB0fHByZXxzdHlsZXx0ZXh0YXJlYSlbYS16XVtcXFxcdy1dKlxcXFxzKj4oPz1bIFxcXFx0XSooPzpcXFxcbnwkKSlbXFxcXHNcXFxcU10qPyg/Oig/OlxcXFxuICopK1xcXFxufCQpJyAvLyAoNykgY2xvc2luZyB0YWdcbiAgKyAnKScsXG4gIGRlZjogL14gezAsM31cXFsobGFiZWwpXFxdOiAqKD86XFxuICopPyhbXjxcXHNdW15cXHNdKnw8Lio/PikoPzooPzogKyg/OlxcbiAqKT98ICpcXG4gKikodGl0bGUpKT8gKig/Olxcbit8JCkvLFxuICB0YWJsZTogbm9vcFRlc3QsXG4gIGxoZWFkaW5nOiAvXigoPzoufFxcbig/IVxcbikpKz8pXFxuIHswLDN9KD0rfC0rKSAqKD86XFxuK3wkKS8sXG4gIC8vIHJlZ2V4IHRlbXBsYXRlLCBwbGFjZWhvbGRlcnMgd2lsbCBiZSByZXBsYWNlZCBhY2NvcmRpbmcgdG8gZGlmZmVyZW50IHBhcmFncmFwaFxuICAvLyBpbnRlcnJ1cHRpb24gcnVsZXMgb2YgY29tbW9ubWFyayBhbmQgdGhlIG9yaWdpbmFsIG1hcmtkb3duIHNwZWM6XG4gIF9wYXJhZ3JhcGg6IC9eKFteXFxuXSsoPzpcXG4oPyFocnxoZWFkaW5nfGxoZWFkaW5nfGJsb2NrcXVvdGV8ZmVuY2VzfGxpc3R8aHRtbHx0YWJsZXwgK1xcbilbXlxcbl0rKSopLyxcbiAgdGV4dDogL15bXlxcbl0rL1xufTtcbmJsb2NrLl9sYWJlbCA9IC8oPyFcXHMqXFxdKSg/OlxcXFwufFteXFxbXFxdXFxcXF0pKy87XG5ibG9jay5fdGl0bGUgPSAvKD86XCIoPzpcXFxcXCI/fFteXCJcXFxcXSkqXCJ8J1teJ1xcbl0qKD86XFxuW14nXFxuXSspKlxcbj8nfFxcKFteKCldKlxcKSkvO1xuYmxvY2suZGVmID0gZWRpdChibG9jay5kZWYpLnJlcGxhY2UoJ2xhYmVsJywgYmxvY2suX2xhYmVsKS5yZXBsYWNlKCd0aXRsZScsIGJsb2NrLl90aXRsZSkuZ2V0UmVnZXgoKTtcbmJsb2NrLmJ1bGxldCA9IC8oPzpbKistXXxcXGR7MSw5fVsuKV0pLztcbmJsb2NrLmxpc3RJdGVtU3RhcnQgPSBlZGl0KC9eKCAqKShidWxsKSAqLykucmVwbGFjZSgnYnVsbCcsIGJsb2NrLmJ1bGxldCkuZ2V0UmVnZXgoKTtcbmJsb2NrLmxpc3QgPSBlZGl0KGJsb2NrLmxpc3QpLnJlcGxhY2UoL2J1bGwvZywgYmxvY2suYnVsbGV0KS5yZXBsYWNlKCdocicsICdcXFxcbisoPz1cXFxcMT8oPzooPzotICopezMsfXwoPzpfICopezMsfXwoPzpcXFxcKiAqKXszLH0pKD86XFxcXG4rfCQpKScpLnJlcGxhY2UoJ2RlZicsICdcXFxcbisoPz0nICsgYmxvY2suZGVmLnNvdXJjZSArICcpJykuZ2V0UmVnZXgoKTtcbmJsb2NrLl90YWcgPSAnYWRkcmVzc3xhcnRpY2xlfGFzaWRlfGJhc2V8YmFzZWZvbnR8YmxvY2txdW90ZXxib2R5fGNhcHRpb24nICsgJ3xjZW50ZXJ8Y29sfGNvbGdyb3VwfGRkfGRldGFpbHN8ZGlhbG9nfGRpcnxkaXZ8ZGx8ZHR8ZmllbGRzZXR8ZmlnY2FwdGlvbicgKyAnfGZpZ3VyZXxmb290ZXJ8Zm9ybXxmcmFtZXxmcmFtZXNldHxoWzEtNl18aGVhZHxoZWFkZXJ8aHJ8aHRtbHxpZnJhbWUnICsgJ3xsZWdlbmR8bGl8bGlua3xtYWlufG1lbnV8bWVudWl0ZW18bWV0YXxuYXZ8bm9mcmFtZXN8b2x8b3B0Z3JvdXB8b3B0aW9uJyArICd8cHxwYXJhbXxzZWN0aW9ufHNvdXJjZXxzdW1tYXJ5fHRhYmxlfHRib2R5fHRkfHRmb290fHRofHRoZWFkfHRpdGxlfHRyJyArICd8dHJhY2t8dWwnO1xuYmxvY2suX2NvbW1lbnQgPSAvPCEtLSg/IS0/PilbXFxzXFxTXSo/KD86LS0+fCQpLztcbmJsb2NrLmh0bWwgPSBlZGl0KGJsb2NrLmh0bWwsICdpJykucmVwbGFjZSgnY29tbWVudCcsIGJsb2NrLl9jb21tZW50KS5yZXBsYWNlKCd0YWcnLCBibG9jay5fdGFnKS5yZXBsYWNlKCdhdHRyaWJ1dGUnLCAvICtbYS16QS1aOl9dW1xcdy46LV0qKD86ICo9ICpcIlteXCJcXG5dKlwifCAqPSAqJ1teJ1xcbl0qJ3wgKj0gKlteXFxzXCInPTw+YF0rKT8vKS5nZXRSZWdleCgpO1xuYmxvY2sucGFyYWdyYXBoID0gZWRpdChibG9jay5fcGFyYWdyYXBoKS5yZXBsYWNlKCdocicsIGJsb2NrLmhyKS5yZXBsYWNlKCdoZWFkaW5nJywgJyB7MCwzfSN7MSw2fSAnKS5yZXBsYWNlKCd8bGhlYWRpbmcnLCAnJykgLy8gc2V0ZXggaGVhZGluZ3MgZG9uJ3QgaW50ZXJydXB0IGNvbW1vbm1hcmsgcGFyYWdyYXBoc1xuLnJlcGxhY2UoJ3x0YWJsZScsICcnKS5yZXBsYWNlKCdibG9ja3F1b3RlJywgJyB7MCwzfT4nKS5yZXBsYWNlKCdmZW5jZXMnLCAnIHswLDN9KD86YHszLH0oPz1bXmBcXFxcbl0qXFxcXG4pfH57Myx9KVteXFxcXG5dKlxcXFxuJykucmVwbGFjZSgnbGlzdCcsICcgezAsM30oPzpbKistXXwxWy4pXSkgJykgLy8gb25seSBsaXN0cyBzdGFydGluZyBmcm9tIDEgY2FuIGludGVycnVwdFxuLnJlcGxhY2UoJ2h0bWwnLCAnPC8/KD86dGFnKSg/OiArfFxcXFxufC8/Pil8PCg/OnNjcmlwdHxwcmV8c3R5bGV8dGV4dGFyZWF8IS0tKScpLnJlcGxhY2UoJ3RhZycsIGJsb2NrLl90YWcpIC8vIHBhcnMgY2FuIGJlIGludGVycnVwdGVkIGJ5IHR5cGUgKDYpIGh0bWwgYmxvY2tzXG4uZ2V0UmVnZXgoKTtcbmJsb2NrLmJsb2NrcXVvdGUgPSBlZGl0KGJsb2NrLmJsb2NrcXVvdGUpLnJlcGxhY2UoJ3BhcmFncmFwaCcsIGJsb2NrLnBhcmFncmFwaCkuZ2V0UmVnZXgoKTtcblxuLyoqXG4gKiBOb3JtYWwgQmxvY2sgR3JhbW1hclxuICovXG5cbmJsb2NrLm5vcm1hbCA9IG1lcmdlKHt9LCBibG9jayk7XG5cbi8qKlxuICogR0ZNIEJsb2NrIEdyYW1tYXJcbiAqL1xuXG5ibG9jay5nZm0gPSBtZXJnZSh7fSwgYmxvY2subm9ybWFsLCB7XG4gIHRhYmxlOiAnXiAqKFteXFxcXG4gXS4qXFxcXHwuKilcXFxcbicgLy8gSGVhZGVyXG4gICsgJyB7MCwzfSg/OlxcXFx8ICopPyg6Py0rOj8gKig/OlxcXFx8ICo6Py0rOj8gKikqKSg/OlxcXFx8ICopPycgLy8gQWxpZ25cbiAgKyAnKD86XFxcXG4oKD86KD8hICpcXFxcbnxocnxoZWFkaW5nfGJsb2NrcXVvdGV8Y29kZXxmZW5jZXN8bGlzdHxodG1sKS4qKD86XFxcXG58JCkpKilcXFxcbip8JCknIC8vIENlbGxzXG59KTtcblxuYmxvY2suZ2ZtLnRhYmxlID0gZWRpdChibG9jay5nZm0udGFibGUpLnJlcGxhY2UoJ2hyJywgYmxvY2suaHIpLnJlcGxhY2UoJ2hlYWRpbmcnLCAnIHswLDN9I3sxLDZ9ICcpLnJlcGxhY2UoJ2Jsb2NrcXVvdGUnLCAnIHswLDN9PicpLnJlcGxhY2UoJ2NvZGUnLCAnIHs0fVteXFxcXG5dJykucmVwbGFjZSgnZmVuY2VzJywgJyB7MCwzfSg/OmB7Myx9KD89W15gXFxcXG5dKlxcXFxuKXx+ezMsfSlbXlxcXFxuXSpcXFxcbicpLnJlcGxhY2UoJ2xpc3QnLCAnIHswLDN9KD86WyorLV18MVsuKV0pICcpIC8vIG9ubHkgbGlzdHMgc3RhcnRpbmcgZnJvbSAxIGNhbiBpbnRlcnJ1cHRcbi5yZXBsYWNlKCdodG1sJywgJzwvPyg/OnRhZykoPzogK3xcXFxcbnwvPz4pfDwoPzpzY3JpcHR8cHJlfHN0eWxlfHRleHRhcmVhfCEtLSknKS5yZXBsYWNlKCd0YWcnLCBibG9jay5fdGFnKSAvLyB0YWJsZXMgY2FuIGJlIGludGVycnVwdGVkIGJ5IHR5cGUgKDYpIGh0bWwgYmxvY2tzXG4uZ2V0UmVnZXgoKTtcbmJsb2NrLmdmbS5wYXJhZ3JhcGggPSBlZGl0KGJsb2NrLl9wYXJhZ3JhcGgpLnJlcGxhY2UoJ2hyJywgYmxvY2suaHIpLnJlcGxhY2UoJ2hlYWRpbmcnLCAnIHswLDN9I3sxLDZ9ICcpLnJlcGxhY2UoJ3xsaGVhZGluZycsICcnKSAvLyBzZXRleCBoZWFkaW5ncyBkb24ndCBpbnRlcnJ1cHQgY29tbW9ubWFyayBwYXJhZ3JhcGhzXG4ucmVwbGFjZSgndGFibGUnLCBibG9jay5nZm0udGFibGUpIC8vIGludGVycnVwdCBwYXJhZ3JhcGhzIHdpdGggdGFibGVcbi5yZXBsYWNlKCdibG9ja3F1b3RlJywgJyB7MCwzfT4nKS5yZXBsYWNlKCdmZW5jZXMnLCAnIHswLDN9KD86YHszLH0oPz1bXmBcXFxcbl0qXFxcXG4pfH57Myx9KVteXFxcXG5dKlxcXFxuJykucmVwbGFjZSgnbGlzdCcsICcgezAsM30oPzpbKistXXwxWy4pXSkgJykgLy8gb25seSBsaXN0cyBzdGFydGluZyBmcm9tIDEgY2FuIGludGVycnVwdFxuLnJlcGxhY2UoJ2h0bWwnLCAnPC8/KD86dGFnKSg/OiArfFxcXFxufC8/Pil8PCg/OnNjcmlwdHxwcmV8c3R5bGV8dGV4dGFyZWF8IS0tKScpLnJlcGxhY2UoJ3RhZycsIGJsb2NrLl90YWcpIC8vIHBhcnMgY2FuIGJlIGludGVycnVwdGVkIGJ5IHR5cGUgKDYpIGh0bWwgYmxvY2tzXG4uZ2V0UmVnZXgoKTtcbi8qKlxuICogUGVkYW50aWMgZ3JhbW1hciAob3JpZ2luYWwgSm9obiBHcnViZXIncyBsb29zZSBtYXJrZG93biBzcGVjaWZpY2F0aW9uKVxuICovXG5cbmJsb2NrLnBlZGFudGljID0gbWVyZ2Uoe30sIGJsb2NrLm5vcm1hbCwge1xuICBodG1sOiBlZGl0KCdeICooPzpjb21tZW50ICooPzpcXFxcbnxcXFxccyokKScgKyAnfDwodGFnKVtcXFxcc1xcXFxTXSs/PC9cXFxcMT4gKig/OlxcXFxuezIsfXxcXFxccyokKScgLy8gY2xvc2VkIHRhZ1xuICArICd8PHRhZyg/OlwiW15cIl0qXCJ8XFwnW15cXCddKlxcJ3xcXFxcc1teXFwnXCIvPlxcXFxzXSopKj8vPz4gKig/OlxcXFxuezIsfXxcXFxccyokKSknKS5yZXBsYWNlKCdjb21tZW50JywgYmxvY2suX2NvbW1lbnQpLnJlcGxhY2UoL3RhZy9nLCAnKD8hKD86JyArICdhfGVtfHN0cm9uZ3xzbWFsbHxzfGNpdGV8cXxkZm58YWJicnxkYXRhfHRpbWV8Y29kZXx2YXJ8c2FtcHxrYmR8c3ViJyArICd8c3VwfGl8Ynx1fG1hcmt8cnVieXxydHxycHxiZGl8YmRvfHNwYW58YnJ8d2JyfGluc3xkZWx8aW1nKScgKyAnXFxcXGIpXFxcXHcrKD8hOnxbXlxcXFx3XFxcXHNAXSpAKVxcXFxiJykuZ2V0UmVnZXgoKSxcbiAgZGVmOiAvXiAqXFxbKFteXFxdXSspXFxdOiAqPD8oW15cXHM+XSspPj8oPzogKyhbXCIoXVteXFxuXStbXCIpXSkpPyAqKD86XFxuK3wkKS8sXG4gIGhlYWRpbmc6IC9eKCN7MSw2fSkoLiopKD86XFxuK3wkKS8sXG4gIGZlbmNlczogbm9vcFRlc3QsXG4gIC8vIGZlbmNlcyBub3Qgc3VwcG9ydGVkXG4gIGxoZWFkaW5nOiAvXiguKz8pXFxuIHswLDN9KD0rfC0rKSAqKD86XFxuK3wkKS8sXG4gIHBhcmFncmFwaDogZWRpdChibG9jay5ub3JtYWwuX3BhcmFncmFwaCkucmVwbGFjZSgnaHInLCBibG9jay5ocikucmVwbGFjZSgnaGVhZGluZycsICcgKiN7MSw2fSAqW15cXG5dJykucmVwbGFjZSgnbGhlYWRpbmcnLCBibG9jay5saGVhZGluZykucmVwbGFjZSgnYmxvY2txdW90ZScsICcgezAsM30+JykucmVwbGFjZSgnfGZlbmNlcycsICcnKS5yZXBsYWNlKCd8bGlzdCcsICcnKS5yZXBsYWNlKCd8aHRtbCcsICcnKS5nZXRSZWdleCgpXG59KTtcblxuLyoqXG4gKiBJbmxpbmUtTGV2ZWwgR3JhbW1hclxuICovXG52YXIgaW5saW5lID0ge1xuICBlc2NhcGU6IC9eXFxcXChbIVwiIyQlJicoKSorLFxcLS4vOjs8PT4/QFxcW1xcXVxcXFxeX2B7fH1+XSkvLFxuICBhdXRvbGluazogL148KHNjaGVtZTpbXlxcc1xceDAwLVxceDFmPD5dKnxlbWFpbCk+LyxcbiAgdXJsOiBub29wVGVzdCxcbiAgdGFnOiAnXmNvbW1lbnQnICsgJ3xePC9bYS16QS1aXVtcXFxcdzotXSpcXFxccyo+JyAvLyBzZWxmLWNsb3NpbmcgdGFnXG4gICsgJ3xePFthLXpBLVpdW1xcXFx3LV0qKD86YXR0cmlidXRlKSo/XFxcXHMqLz8+JyAvLyBvcGVuIHRhZ1xuICArICd8XjxcXFxcP1tcXFxcc1xcXFxTXSo/XFxcXD8+JyAvLyBwcm9jZXNzaW5nIGluc3RydWN0aW9uLCBlLmcuIDw/cGhwID8+XG4gICsgJ3xePCFbYS16QS1aXStcXFxcc1tcXFxcc1xcXFxTXSo/PicgLy8gZGVjbGFyYXRpb24sIGUuZy4gPCFET0NUWVBFIGh0bWw+XG4gICsgJ3xePCFcXFxcW0NEQVRBXFxcXFtbXFxcXHNcXFxcU10qP1xcXFxdXFxcXF0+JyxcbiAgLy8gQ0RBVEEgc2VjdGlvblxuICBsaW5rOiAvXiE/XFxbKGxhYmVsKVxcXVxcKFxccyooaHJlZikoPzpcXHMrKHRpdGxlKSk/XFxzKlxcKS8sXG4gIHJlZmxpbms6IC9eIT9cXFsobGFiZWwpXFxdXFxbKHJlZilcXF0vLFxuICBub2xpbms6IC9eIT9cXFsocmVmKVxcXSg/OlxcW1xcXSk/LyxcbiAgcmVmbGlua1NlYXJjaDogJ3JlZmxpbmt8bm9saW5rKD8hXFxcXCgpJyxcbiAgZW1TdHJvbmc6IHtcbiAgICBsRGVsaW06IC9eKD86XFwqKyg/OihbcHVuY3RfXSl8W15cXHMqXSkpfF5fKyg/OihbcHVuY3QqXSl8KFteXFxzX10pKS8sXG4gICAgLy8gICAgICAgICgxKSBhbmQgKDIpIGNhbiBvbmx5IGJlIGEgUmlnaHQgRGVsaW1pdGVyLiAoMykgYW5kICg0KSBjYW4gb25seSBiZSBMZWZ0LiAgKDUpIGFuZCAoNikgY2FuIGJlIGVpdGhlciBMZWZ0IG9yIFJpZ2h0LlxuICAgIC8vICAgICAgICAgICgpIFNraXAgb3JwaGFuIGluc2lkZSBzdHJvbmcgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICgpIENvbnN1bWUgdG8gZGVsaW0gICAgICgxKSAjKioqICAgICAgICAgICAgICAgICgyKSBhKioqIywgYSoqKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKDMpICMqKiphLCAqKiphICAgICAgICAgICAgICAgICAoNCkgKioqIyAgICAgICAgICAgICAgKDUpICMqKiojICAgICAgICAgICAgICAgICAoNikgYSoqKmFcbiAgICByRGVsaW1Bc3Q6IC9eKD86W15fKlxcXFxdfFxcXFwuKSo/XFxfXFxfKD86W15fKlxcXFxdfFxcXFwuKSo/XFwqKD86W15fKlxcXFxdfFxcXFwuKSo/KD89XFxfXFxfKXwoPzpbXipcXFxcXXxcXFxcLikrKD89W14qXSl8W3B1bmN0X10oXFwqKykoPz1bXFxzXXwkKXwoPzpbXnB1bmN0Kl9cXHNcXFxcXXxcXFxcLikoXFwqKykoPz1bcHVuY3RfXFxzXXwkKXxbcHVuY3RfXFxzXShcXCorKSg/PVtecHVuY3QqX1xcc10pfFtcXHNdKFxcKispKD89W3B1bmN0X10pfFtwdW5jdF9dKFxcKispKD89W3B1bmN0X10pfCg/OltecHVuY3QqX1xcc1xcXFxdfFxcXFwuKShcXCorKSg/PVtecHVuY3QqX1xcc10pLyxcbiAgICByRGVsaW1VbmQ6IC9eKD86W15fKlxcXFxdfFxcXFwuKSo/XFwqXFwqKD86W15fKlxcXFxdfFxcXFwuKSo/XFxfKD86W15fKlxcXFxdfFxcXFwuKSo/KD89XFwqXFwqKXwoPzpbXl9cXFxcXXxcXFxcLikrKD89W15fXSl8W3B1bmN0Kl0oXFxfKykoPz1bXFxzXXwkKXwoPzpbXnB1bmN0Kl9cXHNcXFxcXXxcXFxcLikoXFxfKykoPz1bcHVuY3QqXFxzXXwkKXxbcHVuY3QqXFxzXShcXF8rKSg/PVtecHVuY3QqX1xcc10pfFtcXHNdKFxcXyspKD89W3B1bmN0Kl0pfFtwdW5jdCpdKFxcXyspKD89W3B1bmN0Kl0pLyAvLyBeLSBOb3QgYWxsb3dlZCBmb3IgX1xuICB9LFxuXG4gIGNvZGU6IC9eKGArKShbXmBdfFteYF1bXFxzXFxTXSo/W15gXSlcXDEoPyFgKS8sXG4gIGJyOiAvXiggezIsfXxcXFxcKVxcbig/IVxccyokKS8sXG4gIGRlbDogbm9vcFRlc3QsXG4gIHRleHQ6IC9eKGArfFteYF0pKD86KD89IHsyLH1cXG4pfFtcXHNcXFNdKj8oPzooPz1bXFxcXDwhXFxbYCpfXXxcXGJffCQpfFteIF0oPz0gezIsfVxcbikpKS8sXG4gIHB1bmN0dWF0aW9uOiAvXihbXFxzcHVuY3R1YXRpb25dKS9cbn07XG5cbi8vIGxpc3Qgb2YgcHVuY3R1YXRpb24gbWFya3MgZnJvbSBDb21tb25NYXJrIHNwZWNcbi8vIHdpdGhvdXQgKiBhbmQgXyB0byBoYW5kbGUgdGhlIGRpZmZlcmVudCBlbXBoYXNpcyBtYXJrZXJzICogYW5kIF9cbmlubGluZS5fcHVuY3R1YXRpb24gPSAnIVwiIyQlJlxcJygpK1xcXFwtLiwvOjs8PT4/QFxcXFxbXFxcXF1gXnt8fX4nO1xuaW5saW5lLnB1bmN0dWF0aW9uID0gZWRpdChpbmxpbmUucHVuY3R1YXRpb24pLnJlcGxhY2UoL3B1bmN0dWF0aW9uL2csIGlubGluZS5fcHVuY3R1YXRpb24pLmdldFJlZ2V4KCk7XG5cbi8vIHNlcXVlbmNlcyBlbSBzaG91bGQgc2tpcCBvdmVyIFt0aXRsZV0obGluayksIGBjb2RlYCwgPGh0bWw+XG5pbmxpbmUuYmxvY2tTa2lwID0gL1xcW1teXFxdXSo/XFxdXFwoW15cXCldKj9cXCl8YFteYF0qP2B8PFtePl0qPz4vZztcbi8vIGxvb2tiZWhpbmQgaXMgbm90IGF2YWlsYWJsZSBvbiBTYWZhcmkgYXMgb2YgdmVyc2lvbiAxNlxuLy8gaW5saW5lLmVzY2FwZWRFbVN0ID0gLyg/PD0oPzpefFteXFxcXCkoPzpcXFxcW15dKSopXFxcXFsqX10vZztcbmlubGluZS5lc2NhcGVkRW1TdCA9IC8oPzpefFteXFxcXF0pKD86XFxcXFxcXFwpKlxcXFxbKl9dL2c7XG5pbmxpbmUuX2NvbW1lbnQgPSBlZGl0KGJsb2NrLl9jb21tZW50KS5yZXBsYWNlKCcoPzotLT58JCknLCAnLS0+JykuZ2V0UmVnZXgoKTtcbmlubGluZS5lbVN0cm9uZy5sRGVsaW0gPSBlZGl0KGlubGluZS5lbVN0cm9uZy5sRGVsaW0pLnJlcGxhY2UoL3B1bmN0L2csIGlubGluZS5fcHVuY3R1YXRpb24pLmdldFJlZ2V4KCk7XG5pbmxpbmUuZW1TdHJvbmcuckRlbGltQXN0ID0gZWRpdChpbmxpbmUuZW1TdHJvbmcuckRlbGltQXN0LCAnZycpLnJlcGxhY2UoL3B1bmN0L2csIGlubGluZS5fcHVuY3R1YXRpb24pLmdldFJlZ2V4KCk7XG5pbmxpbmUuZW1TdHJvbmcuckRlbGltVW5kID0gZWRpdChpbmxpbmUuZW1TdHJvbmcuckRlbGltVW5kLCAnZycpLnJlcGxhY2UoL3B1bmN0L2csIGlubGluZS5fcHVuY3R1YXRpb24pLmdldFJlZ2V4KCk7XG5pbmxpbmUuX2VzY2FwZXMgPSAvXFxcXChbIVwiIyQlJicoKSorLFxcLS4vOjs8PT4/QFxcW1xcXVxcXFxeX2B7fH1+XSkvZztcbmlubGluZS5fc2NoZW1lID0gL1thLXpBLVpdW2EtekEtWjAtOSsuLV17MSwzMX0vO1xuaW5saW5lLl9lbWFpbCA9IC9bYS16QS1aMC05LiEjJCUmJyorLz0/Xl9ge3x9fi1dKyhAKVthLXpBLVowLTldKD86W2EtekEtWjAtOS1dezAsNjF9W2EtekEtWjAtOV0pPyg/OlxcLlthLXpBLVowLTldKD86W2EtekEtWjAtOS1dezAsNjF9W2EtekEtWjAtOV0pPykrKD8hWy1fXSkvO1xuaW5saW5lLmF1dG9saW5rID0gZWRpdChpbmxpbmUuYXV0b2xpbmspLnJlcGxhY2UoJ3NjaGVtZScsIGlubGluZS5fc2NoZW1lKS5yZXBsYWNlKCdlbWFpbCcsIGlubGluZS5fZW1haWwpLmdldFJlZ2V4KCk7XG5pbmxpbmUuX2F0dHJpYnV0ZSA9IC9cXHMrW2EtekEtWjpfXVtcXHcuOi1dKig/Olxccyo9XFxzKlwiW15cIl0qXCJ8XFxzKj1cXHMqJ1teJ10qJ3xcXHMqPVxccypbXlxcc1wiJz08PmBdKyk/LztcbmlubGluZS50YWcgPSBlZGl0KGlubGluZS50YWcpLnJlcGxhY2UoJ2NvbW1lbnQnLCBpbmxpbmUuX2NvbW1lbnQpLnJlcGxhY2UoJ2F0dHJpYnV0ZScsIGlubGluZS5fYXR0cmlidXRlKS5nZXRSZWdleCgpO1xuaW5saW5lLl9sYWJlbCA9IC8oPzpcXFsoPzpcXFxcLnxbXlxcW1xcXVxcXFxdKSpcXF18XFxcXC58YFteYF0qYHxbXlxcW1xcXVxcXFxgXSkqPy87XG5pbmxpbmUuX2hyZWYgPSAvPCg/OlxcXFwufFteXFxuPD5cXFxcXSkrPnxbXlxcc1xceDAwLVxceDFmXSovO1xuaW5saW5lLl90aXRsZSA9IC9cIig/OlxcXFxcIj98W15cIlxcXFxdKSpcInwnKD86XFxcXCc/fFteJ1xcXFxdKSonfFxcKCg/OlxcXFxcXCk/fFteKVxcXFxdKSpcXCkvO1xuaW5saW5lLmxpbmsgPSBlZGl0KGlubGluZS5saW5rKS5yZXBsYWNlKCdsYWJlbCcsIGlubGluZS5fbGFiZWwpLnJlcGxhY2UoJ2hyZWYnLCBpbmxpbmUuX2hyZWYpLnJlcGxhY2UoJ3RpdGxlJywgaW5saW5lLl90aXRsZSkuZ2V0UmVnZXgoKTtcbmlubGluZS5yZWZsaW5rID0gZWRpdChpbmxpbmUucmVmbGluaykucmVwbGFjZSgnbGFiZWwnLCBpbmxpbmUuX2xhYmVsKS5yZXBsYWNlKCdyZWYnLCBibG9jay5fbGFiZWwpLmdldFJlZ2V4KCk7XG5pbmxpbmUubm9saW5rID0gZWRpdChpbmxpbmUubm9saW5rKS5yZXBsYWNlKCdyZWYnLCBibG9jay5fbGFiZWwpLmdldFJlZ2V4KCk7XG5pbmxpbmUucmVmbGlua1NlYXJjaCA9IGVkaXQoaW5saW5lLnJlZmxpbmtTZWFyY2gsICdnJykucmVwbGFjZSgncmVmbGluaycsIGlubGluZS5yZWZsaW5rKS5yZXBsYWNlKCdub2xpbmsnLCBpbmxpbmUubm9saW5rKS5nZXRSZWdleCgpO1xuXG4vKipcbiAqIE5vcm1hbCBJbmxpbmUgR3JhbW1hclxuICovXG5cbmlubGluZS5ub3JtYWwgPSBtZXJnZSh7fSwgaW5saW5lKTtcblxuLyoqXG4gKiBQZWRhbnRpYyBJbmxpbmUgR3JhbW1hclxuICovXG5cbmlubGluZS5wZWRhbnRpYyA9IG1lcmdlKHt9LCBpbmxpbmUubm9ybWFsLCB7XG4gIHN0cm9uZzoge1xuICAgIHN0YXJ0OiAvXl9ffFxcKlxcKi8sXG4gICAgbWlkZGxlOiAvXl9fKD89XFxTKShbXFxzXFxTXSo/XFxTKV9fKD8hXyl8XlxcKlxcKig/PVxcUykoW1xcc1xcU10qP1xcUylcXCpcXCooPyFcXCopLyxcbiAgICBlbmRBc3Q6IC9cXCpcXCooPyFcXCopL2csXG4gICAgZW5kVW5kOiAvX18oPyFfKS9nXG4gIH0sXG4gIGVtOiB7XG4gICAgc3RhcnQ6IC9eX3xcXCovLFxuICAgIG1pZGRsZTogL14oKVxcKig/PVxcUykoW1xcc1xcU10qP1xcUylcXCooPyFcXCopfF5fKD89XFxTKShbXFxzXFxTXSo/XFxTKV8oPyFfKS8sXG4gICAgZW5kQXN0OiAvXFwqKD8hXFwqKS9nLFxuICAgIGVuZFVuZDogL18oPyFfKS9nXG4gIH0sXG4gIGxpbms6IGVkaXQoL14hP1xcWyhsYWJlbClcXF1cXCgoLio/KVxcKS8pLnJlcGxhY2UoJ2xhYmVsJywgaW5saW5lLl9sYWJlbCkuZ2V0UmVnZXgoKSxcbiAgcmVmbGluazogZWRpdCgvXiE/XFxbKGxhYmVsKVxcXVxccypcXFsoW15cXF1dKilcXF0vKS5yZXBsYWNlKCdsYWJlbCcsIGlubGluZS5fbGFiZWwpLmdldFJlZ2V4KClcbn0pO1xuXG4vKipcbiAqIEdGTSBJbmxpbmUgR3JhbW1hclxuICovXG5cbmlubGluZS5nZm0gPSBtZXJnZSh7fSwgaW5saW5lLm5vcm1hbCwge1xuICBlc2NhcGU6IGVkaXQoaW5saW5lLmVzY2FwZSkucmVwbGFjZSgnXSknLCAnfnxdKScpLmdldFJlZ2V4KCksXG4gIF9leHRlbmRlZF9lbWFpbDogL1tBLVphLXowLTkuXystXSsoQClbYS16QS1aMC05LV9dKyg/OlxcLlthLXpBLVowLTktX10qW2EtekEtWjAtOV0pKyg/IVstX10pLyxcbiAgdXJsOiAvXigoPzpmdHB8aHR0cHM/KTpcXC9cXC98d3d3XFwuKSg/OlthLXpBLVowLTlcXC1dK1xcLj8pK1teXFxzPF0qfF5lbWFpbC8sXG4gIF9iYWNrcGVkYWw6IC8oPzpbXj8hLiw6OypfJ1wifigpJl0rfFxcKFteKV0qXFwpfCYoPyFbYS16QS1aMC05XSs7JCl8Wz8hLiw6OypfJ1wifildKyg/ISQpKSsvLFxuICBkZWw6IC9eKH5+PykoPz1bXlxcc35dKShbXFxzXFxTXSo/W15cXHN+XSlcXDEoPz1bXn5dfCQpLyxcbiAgdGV4dDogL14oW2B+XSt8W15gfl0pKD86KD89IHsyLH1cXG4pfCg/PVthLXpBLVowLTkuISMkJSYnKitcXC89P19ge1xcfH1+LV0rQCl8W1xcc1xcU10qPyg/Oig/PVtcXFxcPCFcXFtgKn5fXXxcXGJffGh0dHBzPzpcXC9cXC98ZnRwOlxcL1xcL3x3d3dcXC58JCl8W14gXSg/PSB7Mix9XFxuKXxbXmEtekEtWjAtOS4hIyQlJicqK1xcLz0/X2B7XFx8fX4tXSg/PVthLXpBLVowLTkuISMkJSYnKitcXC89P19ge1xcfH1+LV0rQCkpKS9cbn0pO1xuaW5saW5lLmdmbS51cmwgPSBlZGl0KGlubGluZS5nZm0udXJsLCAnaScpLnJlcGxhY2UoJ2VtYWlsJywgaW5saW5lLmdmbS5fZXh0ZW5kZWRfZW1haWwpLmdldFJlZ2V4KCk7XG4vKipcbiAqIEdGTSArIExpbmUgQnJlYWtzIElubGluZSBHcmFtbWFyXG4gKi9cblxuaW5saW5lLmJyZWFrcyA9IG1lcmdlKHt9LCBpbmxpbmUuZ2ZtLCB7XG4gIGJyOiBlZGl0KGlubGluZS5icikucmVwbGFjZSgnezIsfScsICcqJykuZ2V0UmVnZXgoKSxcbiAgdGV4dDogZWRpdChpbmxpbmUuZ2ZtLnRleHQpLnJlcGxhY2UoJ1xcXFxiXycsICdcXFxcYl98IHsyLH1cXFxcbicpLnJlcGxhY2UoL1xcezIsXFx9L2csICcqJykuZ2V0UmVnZXgoKVxufSk7XG5cbi8qKlxuICogc21hcnR5cGFudHMgdGV4dCByZXBsYWNlbWVudFxuICogQHBhcmFtIHtzdHJpbmd9IHRleHRcbiAqL1xuZnVuY3Rpb24gc21hcnR5cGFudHModGV4dCkge1xuICByZXR1cm4gdGV4dFxuICAvLyBlbS1kYXNoZXNcbiAgLnJlcGxhY2UoLy0tLS9nLCBcIlxcdTIwMTRcIilcbiAgLy8gZW4tZGFzaGVzXG4gIC5yZXBsYWNlKC8tLS9nLCBcIlxcdTIwMTNcIilcbiAgLy8gb3BlbmluZyBzaW5nbGVzXG4gIC5yZXBsYWNlKC8oXnxbLVxcdTIwMTQvKFxcW3tcIlxcc10pJy9nLCBcIiQxXFx1MjAxOFwiKVxuICAvLyBjbG9zaW5nIHNpbmdsZXMgJiBhcG9zdHJvcGhlc1xuICAucmVwbGFjZSgvJy9nLCBcIlxcdTIwMTlcIilcbiAgLy8gb3BlbmluZyBkb3VibGVzXG4gIC5yZXBsYWNlKC8oXnxbLVxcdTIwMTQvKFxcW3tcXHUyMDE4XFxzXSlcIi9nLCBcIiQxXFx1MjAxQ1wiKVxuICAvLyBjbG9zaW5nIGRvdWJsZXNcbiAgLnJlcGxhY2UoL1wiL2csIFwiXFx1MjAxRFwiKVxuICAvLyBlbGxpcHNlc1xuICAucmVwbGFjZSgvXFwuezN9L2csIFwiXFx1MjAyNlwiKTtcbn1cblxuLyoqXG4gKiBtYW5nbGUgZW1haWwgYWRkcmVzc2VzXG4gKiBAcGFyYW0ge3N0cmluZ30gdGV4dFxuICovXG5mdW5jdGlvbiBtYW5nbGUodGV4dCkge1xuICB2YXIgb3V0ID0gJycsXG4gICAgaSxcbiAgICBjaDtcbiAgdmFyIGwgPSB0ZXh0Lmxlbmd0aDtcbiAgZm9yIChpID0gMDsgaSA8IGw7IGkrKykge1xuICAgIGNoID0gdGV4dC5jaGFyQ29kZUF0KGkpO1xuICAgIGlmIChNYXRoLnJhbmRvbSgpID4gMC41KSB7XG4gICAgICBjaCA9ICd4JyArIGNoLnRvU3RyaW5nKDE2KTtcbiAgICB9XG4gICAgb3V0ICs9ICcmIycgKyBjaCArICc7JztcbiAgfVxuICByZXR1cm4gb3V0O1xufVxuXG4vKipcbiAqIEJsb2NrIExleGVyXG4gKi9cbnZhciBMZXhlciA9IC8qI19fUFVSRV9fKi9mdW5jdGlvbiAoKSB7XG4gIGZ1bmN0aW9uIExleGVyKG9wdGlvbnMpIHtcbiAgICB0aGlzLnRva2VucyA9IFtdO1xuICAgIHRoaXMudG9rZW5zLmxpbmtzID0gT2JqZWN0LmNyZWF0ZShudWxsKTtcbiAgICB0aGlzLm9wdGlvbnMgPSBvcHRpb25zIHx8IGV4cG9ydHMuZGVmYXVsdHM7XG4gICAgdGhpcy5vcHRpb25zLnRva2VuaXplciA9IHRoaXMub3B0aW9ucy50b2tlbml6ZXIgfHwgbmV3IFRva2VuaXplcigpO1xuICAgIHRoaXMudG9rZW5pemVyID0gdGhpcy5vcHRpb25zLnRva2VuaXplcjtcbiAgICB0aGlzLnRva2VuaXplci5vcHRpb25zID0gdGhpcy5vcHRpb25zO1xuICAgIHRoaXMudG9rZW5pemVyLmxleGVyID0gdGhpcztcbiAgICB0aGlzLmlubGluZVF1ZXVlID0gW107XG4gICAgdGhpcy5zdGF0ZSA9IHtcbiAgICAgIGluTGluazogZmFsc2UsXG4gICAgICBpblJhd0Jsb2NrOiBmYWxzZSxcbiAgICAgIHRvcDogdHJ1ZVxuICAgIH07XG4gICAgdmFyIHJ1bGVzID0ge1xuICAgICAgYmxvY2s6IGJsb2NrLm5vcm1hbCxcbiAgICAgIGlubGluZTogaW5saW5lLm5vcm1hbFxuICAgIH07XG4gICAgaWYgKHRoaXMub3B0aW9ucy5wZWRhbnRpYykge1xuICAgICAgcnVsZXMuYmxvY2sgPSBibG9jay5wZWRhbnRpYztcbiAgICAgIHJ1bGVzLmlubGluZSA9IGlubGluZS5wZWRhbnRpYztcbiAgICB9IGVsc2UgaWYgKHRoaXMub3B0aW9ucy5nZm0pIHtcbiAgICAgIHJ1bGVzLmJsb2NrID0gYmxvY2suZ2ZtO1xuICAgICAgaWYgKHRoaXMub3B0aW9ucy5icmVha3MpIHtcbiAgICAgICAgcnVsZXMuaW5saW5lID0gaW5saW5lLmJyZWFrcztcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJ1bGVzLmlubGluZSA9IGlubGluZS5nZm07XG4gICAgICB9XG4gICAgfVxuICAgIHRoaXMudG9rZW5pemVyLnJ1bGVzID0gcnVsZXM7XG4gIH1cblxuICAvKipcbiAgICogRXhwb3NlIFJ1bGVzXG4gICAqL1xuICAvKipcbiAgICogU3RhdGljIExleCBNZXRob2RcbiAgICovXG4gIExleGVyLmxleCA9IGZ1bmN0aW9uIGxleChzcmMsIG9wdGlvbnMpIHtcbiAgICB2YXIgbGV4ZXIgPSBuZXcgTGV4ZXIob3B0aW9ucyk7XG4gICAgcmV0dXJuIGxleGVyLmxleChzcmMpO1xuICB9XG5cbiAgLyoqXG4gICAqIFN0YXRpYyBMZXggSW5saW5lIE1ldGhvZFxuICAgKi87XG4gIExleGVyLmxleElubGluZSA9IGZ1bmN0aW9uIGxleElubGluZShzcmMsIG9wdGlvbnMpIHtcbiAgICB2YXIgbGV4ZXIgPSBuZXcgTGV4ZXIob3B0aW9ucyk7XG4gICAgcmV0dXJuIGxleGVyLmlubGluZVRva2VucyhzcmMpO1xuICB9XG5cbiAgLyoqXG4gICAqIFByZXByb2Nlc3NpbmdcbiAgICovO1xuICB2YXIgX3Byb3RvID0gTGV4ZXIucHJvdG90eXBlO1xuICBfcHJvdG8ubGV4ID0gZnVuY3Rpb24gbGV4KHNyYykge1xuICAgIHNyYyA9IHNyYy5yZXBsYWNlKC9cXHJcXG58XFxyL2csICdcXG4nKTtcbiAgICB0aGlzLmJsb2NrVG9rZW5zKHNyYywgdGhpcy50b2tlbnMpO1xuICAgIHZhciBuZXh0O1xuICAgIHdoaWxlIChuZXh0ID0gdGhpcy5pbmxpbmVRdWV1ZS5zaGlmdCgpKSB7XG4gICAgICB0aGlzLmlubGluZVRva2VucyhuZXh0LnNyYywgbmV4dC50b2tlbnMpO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy50b2tlbnM7XG4gIH1cblxuICAvKipcbiAgICogTGV4aW5nXG4gICAqLztcbiAgX3Byb3RvLmJsb2NrVG9rZW5zID0gZnVuY3Rpb24gYmxvY2tUb2tlbnMoc3JjLCB0b2tlbnMpIHtcbiAgICB2YXIgX3RoaXMgPSB0aGlzO1xuICAgIGlmICh0b2tlbnMgPT09IHZvaWQgMCkge1xuICAgICAgdG9rZW5zID0gW107XG4gICAgfVxuICAgIGlmICh0aGlzLm9wdGlvbnMucGVkYW50aWMpIHtcbiAgICAgIHNyYyA9IHNyYy5yZXBsYWNlKC9cXHQvZywgJyAgICAnKS5yZXBsYWNlKC9eICskL2dtLCAnJyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHNyYyA9IHNyYy5yZXBsYWNlKC9eKCAqKShcXHQrKS9nbSwgZnVuY3Rpb24gKF8sIGxlYWRpbmcsIHRhYnMpIHtcbiAgICAgICAgcmV0dXJuIGxlYWRpbmcgKyAnICAgICcucmVwZWF0KHRhYnMubGVuZ3RoKTtcbiAgICAgIH0pO1xuICAgIH1cbiAgICB2YXIgdG9rZW4sIGxhc3RUb2tlbiwgY3V0U3JjLCBsYXN0UGFyYWdyYXBoQ2xpcHBlZDtcbiAgICB3aGlsZSAoc3JjKSB7XG4gICAgICBpZiAodGhpcy5vcHRpb25zLmV4dGVuc2lvbnMgJiYgdGhpcy5vcHRpb25zLmV4dGVuc2lvbnMuYmxvY2sgJiYgdGhpcy5vcHRpb25zLmV4dGVuc2lvbnMuYmxvY2suc29tZShmdW5jdGlvbiAoZXh0VG9rZW5pemVyKSB7XG4gICAgICAgIGlmICh0b2tlbiA9IGV4dFRva2VuaXplci5jYWxsKHtcbiAgICAgICAgICBsZXhlcjogX3RoaXNcbiAgICAgICAgfSwgc3JjLCB0b2tlbnMpKSB7XG4gICAgICAgICAgc3JjID0gc3JjLnN1YnN0cmluZyh0b2tlbi5yYXcubGVuZ3RoKTtcbiAgICAgICAgICB0b2tlbnMucHVzaCh0b2tlbik7XG4gICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfSkpIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIC8vIG5ld2xpbmVcbiAgICAgIGlmICh0b2tlbiA9IHRoaXMudG9rZW5pemVyLnNwYWNlKHNyYykpIHtcbiAgICAgICAgc3JjID0gc3JjLnN1YnN0cmluZyh0b2tlbi5yYXcubGVuZ3RoKTtcbiAgICAgICAgaWYgKHRva2VuLnJhdy5sZW5ndGggPT09IDEgJiYgdG9rZW5zLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAvLyBpZiB0aGVyZSdzIGEgc2luZ2xlIFxcbiBhcyBhIHNwYWNlciwgaXQncyB0ZXJtaW5hdGluZyB0aGUgbGFzdCBsaW5lLFxuICAgICAgICAgIC8vIHNvIG1vdmUgaXQgdGhlcmUgc28gdGhhdCB3ZSBkb24ndCBnZXQgdW5lY2Vzc2FyeSBwYXJhZ3JhcGggdGFnc1xuICAgICAgICAgIHRva2Vuc1t0b2tlbnMubGVuZ3RoIC0gMV0ucmF3ICs9ICdcXG4nO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRva2Vucy5wdXNoKHRva2VuKTtcbiAgICAgICAgfVxuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgLy8gY29kZVxuICAgICAgaWYgKHRva2VuID0gdGhpcy50b2tlbml6ZXIuY29kZShzcmMpKSB7XG4gICAgICAgIHNyYyA9IHNyYy5zdWJzdHJpbmcodG9rZW4ucmF3Lmxlbmd0aCk7XG4gICAgICAgIGxhc3RUb2tlbiA9IHRva2Vuc1t0b2tlbnMubGVuZ3RoIC0gMV07XG4gICAgICAgIC8vIEFuIGluZGVudGVkIGNvZGUgYmxvY2sgY2Fubm90IGludGVycnVwdCBhIHBhcmFncmFwaC5cbiAgICAgICAgaWYgKGxhc3RUb2tlbiAmJiAobGFzdFRva2VuLnR5cGUgPT09ICdwYXJhZ3JhcGgnIHx8IGxhc3RUb2tlbi50eXBlID09PSAndGV4dCcpKSB7XG4gICAgICAgICAgbGFzdFRva2VuLnJhdyArPSAnXFxuJyArIHRva2VuLnJhdztcbiAgICAgICAgICBsYXN0VG9rZW4udGV4dCArPSAnXFxuJyArIHRva2VuLnRleHQ7XG4gICAgICAgICAgdGhpcy5pbmxpbmVRdWV1ZVt0aGlzLmlubGluZVF1ZXVlLmxlbmd0aCAtIDFdLnNyYyA9IGxhc3RUb2tlbi50ZXh0O1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRva2Vucy5wdXNoKHRva2VuKTtcbiAgICAgICAgfVxuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgLy8gZmVuY2VzXG4gICAgICBpZiAodG9rZW4gPSB0aGlzLnRva2VuaXplci5mZW5jZXMoc3JjKSkge1xuICAgICAgICBzcmMgPSBzcmMuc3Vic3RyaW5nKHRva2VuLnJhdy5sZW5ndGgpO1xuICAgICAgICB0b2tlbnMucHVzaCh0b2tlbik7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICAvLyBoZWFkaW5nXG4gICAgICBpZiAodG9rZW4gPSB0aGlzLnRva2VuaXplci5oZWFkaW5nKHNyYykpIHtcbiAgICAgICAgc3JjID0gc3JjLnN1YnN0cmluZyh0b2tlbi5yYXcubGVuZ3RoKTtcbiAgICAgICAgdG9rZW5zLnB1c2godG9rZW4pO1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgLy8gaHJcbiAgICAgIGlmICh0b2tlbiA9IHRoaXMudG9rZW5pemVyLmhyKHNyYykpIHtcbiAgICAgICAgc3JjID0gc3JjLnN1YnN0cmluZyh0b2tlbi5yYXcubGVuZ3RoKTtcbiAgICAgICAgdG9rZW5zLnB1c2godG9rZW4pO1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgLy8gYmxvY2txdW90ZVxuICAgICAgaWYgKHRva2VuID0gdGhpcy50b2tlbml6ZXIuYmxvY2txdW90ZShzcmMpKSB7XG4gICAgICAgIHNyYyA9IHNyYy5zdWJzdHJpbmcodG9rZW4ucmF3Lmxlbmd0aCk7XG4gICAgICAgIHRva2Vucy5wdXNoKHRva2VuKTtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIC8vIGxpc3RcbiAgICAgIGlmICh0b2tlbiA9IHRoaXMudG9rZW5pemVyLmxpc3Qoc3JjKSkge1xuICAgICAgICBzcmMgPSBzcmMuc3Vic3RyaW5nKHRva2VuLnJhdy5sZW5ndGgpO1xuICAgICAgICB0b2tlbnMucHVzaCh0b2tlbik7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICAvLyBodG1sXG4gICAgICBpZiAodG9rZW4gPSB0aGlzLnRva2VuaXplci5odG1sKHNyYykpIHtcbiAgICAgICAgc3JjID0gc3JjLnN1YnN0cmluZyh0b2tlbi5yYXcubGVuZ3RoKTtcbiAgICAgICAgdG9rZW5zLnB1c2godG9rZW4pO1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgLy8gZGVmXG4gICAgICBpZiAodG9rZW4gPSB0aGlzLnRva2VuaXplci5kZWYoc3JjKSkge1xuICAgICAgICBzcmMgPSBzcmMuc3Vic3RyaW5nKHRva2VuLnJhdy5sZW5ndGgpO1xuICAgICAgICBsYXN0VG9rZW4gPSB0b2tlbnNbdG9rZW5zLmxlbmd0aCAtIDFdO1xuICAgICAgICBpZiAobGFzdFRva2VuICYmIChsYXN0VG9rZW4udHlwZSA9PT0gJ3BhcmFncmFwaCcgfHwgbGFzdFRva2VuLnR5cGUgPT09ICd0ZXh0JykpIHtcbiAgICAgICAgICBsYXN0VG9rZW4ucmF3ICs9ICdcXG4nICsgdG9rZW4ucmF3O1xuICAgICAgICAgIGxhc3RUb2tlbi50ZXh0ICs9ICdcXG4nICsgdG9rZW4ucmF3O1xuICAgICAgICAgIHRoaXMuaW5saW5lUXVldWVbdGhpcy5pbmxpbmVRdWV1ZS5sZW5ndGggLSAxXS5zcmMgPSBsYXN0VG9rZW4udGV4dDtcbiAgICAgICAgfSBlbHNlIGlmICghdGhpcy50b2tlbnMubGlua3NbdG9rZW4udGFnXSkge1xuICAgICAgICAgIHRoaXMudG9rZW5zLmxpbmtzW3Rva2VuLnRhZ10gPSB7XG4gICAgICAgICAgICBocmVmOiB0b2tlbi5ocmVmLFxuICAgICAgICAgICAgdGl0bGU6IHRva2VuLnRpdGxlXG4gICAgICAgICAgfTtcbiAgICAgICAgfVxuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgLy8gdGFibGUgKGdmbSlcbiAgICAgIGlmICh0b2tlbiA9IHRoaXMudG9rZW5pemVyLnRhYmxlKHNyYykpIHtcbiAgICAgICAgc3JjID0gc3JjLnN1YnN0cmluZyh0b2tlbi5yYXcubGVuZ3RoKTtcbiAgICAgICAgdG9rZW5zLnB1c2godG9rZW4pO1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgLy8gbGhlYWRpbmdcbiAgICAgIGlmICh0b2tlbiA9IHRoaXMudG9rZW5pemVyLmxoZWFkaW5nKHNyYykpIHtcbiAgICAgICAgc3JjID0gc3JjLnN1YnN0cmluZyh0b2tlbi5yYXcubGVuZ3RoKTtcbiAgICAgICAgdG9rZW5zLnB1c2godG9rZW4pO1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgLy8gdG9wLWxldmVsIHBhcmFncmFwaFxuICAgICAgLy8gcHJldmVudCBwYXJhZ3JhcGggY29uc3VtaW5nIGV4dGVuc2lvbnMgYnkgY2xpcHBpbmcgJ3NyYycgdG8gZXh0ZW5zaW9uIHN0YXJ0XG4gICAgICBjdXRTcmMgPSBzcmM7XG4gICAgICBpZiAodGhpcy5vcHRpb25zLmV4dGVuc2lvbnMgJiYgdGhpcy5vcHRpb25zLmV4dGVuc2lvbnMuc3RhcnRCbG9jaykge1xuICAgICAgICAoZnVuY3Rpb24gKCkge1xuICAgICAgICAgIHZhciBzdGFydEluZGV4ID0gSW5maW5pdHk7XG4gICAgICAgICAgdmFyIHRlbXBTcmMgPSBzcmMuc2xpY2UoMSk7XG4gICAgICAgICAgdmFyIHRlbXBTdGFydCA9IHZvaWQgMDtcbiAgICAgICAgICBfdGhpcy5vcHRpb25zLmV4dGVuc2lvbnMuc3RhcnRCbG9jay5mb3JFYWNoKGZ1bmN0aW9uIChnZXRTdGFydEluZGV4KSB7XG4gICAgICAgICAgICB0ZW1wU3RhcnQgPSBnZXRTdGFydEluZGV4LmNhbGwoe1xuICAgICAgICAgICAgICBsZXhlcjogdGhpc1xuICAgICAgICAgICAgfSwgdGVtcFNyYyk7XG4gICAgICAgICAgICBpZiAodHlwZW9mIHRlbXBTdGFydCA9PT0gJ251bWJlcicgJiYgdGVtcFN0YXJ0ID49IDApIHtcbiAgICAgICAgICAgICAgc3RhcnRJbmRleCA9IE1hdGgubWluKHN0YXJ0SW5kZXgsIHRlbXBTdGFydCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSk7XG4gICAgICAgICAgaWYgKHN0YXJ0SW5kZXggPCBJbmZpbml0eSAmJiBzdGFydEluZGV4ID49IDApIHtcbiAgICAgICAgICAgIGN1dFNyYyA9IHNyYy5zdWJzdHJpbmcoMCwgc3RhcnRJbmRleCArIDEpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSkoKTtcbiAgICAgIH1cbiAgICAgIGlmICh0aGlzLnN0YXRlLnRvcCAmJiAodG9rZW4gPSB0aGlzLnRva2VuaXplci5wYXJhZ3JhcGgoY3V0U3JjKSkpIHtcbiAgICAgICAgbGFzdFRva2VuID0gdG9rZW5zW3Rva2Vucy5sZW5ndGggLSAxXTtcbiAgICAgICAgaWYgKGxhc3RQYXJhZ3JhcGhDbGlwcGVkICYmIGxhc3RUb2tlbi50eXBlID09PSAncGFyYWdyYXBoJykge1xuICAgICAgICAgIGxhc3RUb2tlbi5yYXcgKz0gJ1xcbicgKyB0b2tlbi5yYXc7XG4gICAgICAgICAgbGFzdFRva2VuLnRleHQgKz0gJ1xcbicgKyB0b2tlbi50ZXh0O1xuICAgICAgICAgIHRoaXMuaW5saW5lUXVldWUucG9wKCk7XG4gICAgICAgICAgdGhpcy5pbmxpbmVRdWV1ZVt0aGlzLmlubGluZVF1ZXVlLmxlbmd0aCAtIDFdLnNyYyA9IGxhc3RUb2tlbi50ZXh0O1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRva2Vucy5wdXNoKHRva2VuKTtcbiAgICAgICAgfVxuICAgICAgICBsYXN0UGFyYWdyYXBoQ2xpcHBlZCA9IGN1dFNyYy5sZW5ndGggIT09IHNyYy5sZW5ndGg7XG4gICAgICAgIHNyYyA9IHNyYy5zdWJzdHJpbmcodG9rZW4ucmF3Lmxlbmd0aCk7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICAvLyB0ZXh0XG4gICAgICBpZiAodG9rZW4gPSB0aGlzLnRva2VuaXplci50ZXh0KHNyYykpIHtcbiAgICAgICAgc3JjID0gc3JjLnN1YnN0cmluZyh0b2tlbi5yYXcubGVuZ3RoKTtcbiAgICAgICAgbGFzdFRva2VuID0gdG9rZW5zW3Rva2Vucy5sZW5ndGggLSAxXTtcbiAgICAgICAgaWYgKGxhc3RUb2tlbiAmJiBsYXN0VG9rZW4udHlwZSA9PT0gJ3RleHQnKSB7XG4gICAgICAgICAgbGFzdFRva2VuLnJhdyArPSAnXFxuJyArIHRva2VuLnJhdztcbiAgICAgICAgICBsYXN0VG9rZW4udGV4dCArPSAnXFxuJyArIHRva2VuLnRleHQ7XG4gICAgICAgICAgdGhpcy5pbmxpbmVRdWV1ZS5wb3AoKTtcbiAgICAgICAgICB0aGlzLmlubGluZVF1ZXVlW3RoaXMuaW5saW5lUXVldWUubGVuZ3RoIC0gMV0uc3JjID0gbGFzdFRva2VuLnRleHQ7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdG9rZW5zLnB1c2godG9rZW4pO1xuICAgICAgICB9XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuICAgICAgaWYgKHNyYykge1xuICAgICAgICB2YXIgZXJyTXNnID0gJ0luZmluaXRlIGxvb3Agb24gYnl0ZTogJyArIHNyYy5jaGFyQ29kZUF0KDApO1xuICAgICAgICBpZiAodGhpcy5vcHRpb25zLnNpbGVudCkge1xuICAgICAgICAgIGNvbnNvbGUuZXJyb3IoZXJyTXNnKTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoZXJyTXNnKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICB0aGlzLnN0YXRlLnRvcCA9IHRydWU7XG4gICAgcmV0dXJuIHRva2VucztcbiAgfTtcbiAgX3Byb3RvLmlubGluZSA9IGZ1bmN0aW9uIGlubGluZShzcmMsIHRva2Vucykge1xuICAgIGlmICh0b2tlbnMgPT09IHZvaWQgMCkge1xuICAgICAgdG9rZW5zID0gW107XG4gICAgfVxuICAgIHRoaXMuaW5saW5lUXVldWUucHVzaCh7XG4gICAgICBzcmM6IHNyYyxcbiAgICAgIHRva2VuczogdG9rZW5zXG4gICAgfSk7XG4gICAgcmV0dXJuIHRva2VucztcbiAgfVxuXG4gIC8qKlxuICAgKiBMZXhpbmcvQ29tcGlsaW5nXG4gICAqLztcbiAgX3Byb3RvLmlubGluZVRva2VucyA9IGZ1bmN0aW9uIGlubGluZVRva2VucyhzcmMsIHRva2Vucykge1xuICAgIHZhciBfdGhpczIgPSB0aGlzO1xuICAgIGlmICh0b2tlbnMgPT09IHZvaWQgMCkge1xuICAgICAgdG9rZW5zID0gW107XG4gICAgfVxuICAgIHZhciB0b2tlbiwgbGFzdFRva2VuLCBjdXRTcmM7XG5cbiAgICAvLyBTdHJpbmcgd2l0aCBsaW5rcyBtYXNrZWQgdG8gYXZvaWQgaW50ZXJmZXJlbmNlIHdpdGggZW0gYW5kIHN0cm9uZ1xuICAgIHZhciBtYXNrZWRTcmMgPSBzcmM7XG4gICAgdmFyIG1hdGNoO1xuICAgIHZhciBrZWVwUHJldkNoYXIsIHByZXZDaGFyO1xuXG4gICAgLy8gTWFzayBvdXQgcmVmbGlua3NcbiAgICBpZiAodGhpcy50b2tlbnMubGlua3MpIHtcbiAgICAgIHZhciBsaW5rcyA9IE9iamVjdC5rZXlzKHRoaXMudG9rZW5zLmxpbmtzKTtcbiAgICAgIGlmIChsaW5rcy5sZW5ndGggPiAwKSB7XG4gICAgICAgIHdoaWxlICgobWF0Y2ggPSB0aGlzLnRva2VuaXplci5ydWxlcy5pbmxpbmUucmVmbGlua1NlYXJjaC5leGVjKG1hc2tlZFNyYykpICE9IG51bGwpIHtcbiAgICAgICAgICBpZiAobGlua3MuaW5jbHVkZXMobWF0Y2hbMF0uc2xpY2UobWF0Y2hbMF0ubGFzdEluZGV4T2YoJ1snKSArIDEsIC0xKSkpIHtcbiAgICAgICAgICAgIG1hc2tlZFNyYyA9IG1hc2tlZFNyYy5zbGljZSgwLCBtYXRjaC5pbmRleCkgKyAnWycgKyByZXBlYXRTdHJpbmcoJ2EnLCBtYXRjaFswXS5sZW5ndGggLSAyKSArICddJyArIG1hc2tlZFNyYy5zbGljZSh0aGlzLnRva2VuaXplci5ydWxlcy5pbmxpbmUucmVmbGlua1NlYXJjaC5sYXN0SW5kZXgpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICAvLyBNYXNrIG91dCBvdGhlciBibG9ja3NcbiAgICB3aGlsZSAoKG1hdGNoID0gdGhpcy50b2tlbml6ZXIucnVsZXMuaW5saW5lLmJsb2NrU2tpcC5leGVjKG1hc2tlZFNyYykpICE9IG51bGwpIHtcbiAgICAgIG1hc2tlZFNyYyA9IG1hc2tlZFNyYy5zbGljZSgwLCBtYXRjaC5pbmRleCkgKyAnWycgKyByZXBlYXRTdHJpbmcoJ2EnLCBtYXRjaFswXS5sZW5ndGggLSAyKSArICddJyArIG1hc2tlZFNyYy5zbGljZSh0aGlzLnRva2VuaXplci5ydWxlcy5pbmxpbmUuYmxvY2tTa2lwLmxhc3RJbmRleCk7XG4gICAgfVxuXG4gICAgLy8gTWFzayBvdXQgZXNjYXBlZCBlbSAmIHN0cm9uZyBkZWxpbWl0ZXJzXG4gICAgd2hpbGUgKChtYXRjaCA9IHRoaXMudG9rZW5pemVyLnJ1bGVzLmlubGluZS5lc2NhcGVkRW1TdC5leGVjKG1hc2tlZFNyYykpICE9IG51bGwpIHtcbiAgICAgIG1hc2tlZFNyYyA9IG1hc2tlZFNyYy5zbGljZSgwLCBtYXRjaC5pbmRleCArIG1hdGNoWzBdLmxlbmd0aCAtIDIpICsgJysrJyArIG1hc2tlZFNyYy5zbGljZSh0aGlzLnRva2VuaXplci5ydWxlcy5pbmxpbmUuZXNjYXBlZEVtU3QubGFzdEluZGV4KTtcbiAgICAgIHRoaXMudG9rZW5pemVyLnJ1bGVzLmlubGluZS5lc2NhcGVkRW1TdC5sYXN0SW5kZXgtLTtcbiAgICB9XG4gICAgd2hpbGUgKHNyYykge1xuICAgICAgaWYgKCFrZWVwUHJldkNoYXIpIHtcbiAgICAgICAgcHJldkNoYXIgPSAnJztcbiAgICAgIH1cbiAgICAgIGtlZXBQcmV2Q2hhciA9IGZhbHNlO1xuXG4gICAgICAvLyBleHRlbnNpb25zXG4gICAgICBpZiAodGhpcy5vcHRpb25zLmV4dGVuc2lvbnMgJiYgdGhpcy5vcHRpb25zLmV4dGVuc2lvbnMuaW5saW5lICYmIHRoaXMub3B0aW9ucy5leHRlbnNpb25zLmlubGluZS5zb21lKGZ1bmN0aW9uIChleHRUb2tlbml6ZXIpIHtcbiAgICAgICAgaWYgKHRva2VuID0gZXh0VG9rZW5pemVyLmNhbGwoe1xuICAgICAgICAgIGxleGVyOiBfdGhpczJcbiAgICAgICAgfSwgc3JjLCB0b2tlbnMpKSB7XG4gICAgICAgICAgc3JjID0gc3JjLnN1YnN0cmluZyh0b2tlbi5yYXcubGVuZ3RoKTtcbiAgICAgICAgICB0b2tlbnMucHVzaCh0b2tlbik7XG4gICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfSkpIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIC8vIGVzY2FwZVxuICAgICAgaWYgKHRva2VuID0gdGhpcy50b2tlbml6ZXIuZXNjYXBlKHNyYykpIHtcbiAgICAgICAgc3JjID0gc3JjLnN1YnN0cmluZyh0b2tlbi5yYXcubGVuZ3RoKTtcbiAgICAgICAgdG9rZW5zLnB1c2godG9rZW4pO1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgLy8gdGFnXG4gICAgICBpZiAodG9rZW4gPSB0aGlzLnRva2VuaXplci50YWcoc3JjKSkge1xuICAgICAgICBzcmMgPSBzcmMuc3Vic3RyaW5nKHRva2VuLnJhdy5sZW5ndGgpO1xuICAgICAgICBsYXN0VG9rZW4gPSB0b2tlbnNbdG9rZW5zLmxlbmd0aCAtIDFdO1xuICAgICAgICBpZiAobGFzdFRva2VuICYmIHRva2VuLnR5cGUgPT09ICd0ZXh0JyAmJiBsYXN0VG9rZW4udHlwZSA9PT0gJ3RleHQnKSB7XG4gICAgICAgICAgbGFzdFRva2VuLnJhdyArPSB0b2tlbi5yYXc7XG4gICAgICAgICAgbGFzdFRva2VuLnRleHQgKz0gdG9rZW4udGV4dDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0b2tlbnMucHVzaCh0b2tlbik7XG4gICAgICAgIH1cbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIC8vIGxpbmtcbiAgICAgIGlmICh0b2tlbiA9IHRoaXMudG9rZW5pemVyLmxpbmsoc3JjKSkge1xuICAgICAgICBzcmMgPSBzcmMuc3Vic3RyaW5nKHRva2VuLnJhdy5sZW5ndGgpO1xuICAgICAgICB0b2tlbnMucHVzaCh0b2tlbik7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICAvLyByZWZsaW5rLCBub2xpbmtcbiAgICAgIGlmICh0b2tlbiA9IHRoaXMudG9rZW5pemVyLnJlZmxpbmsoc3JjLCB0aGlzLnRva2Vucy5saW5rcykpIHtcbiAgICAgICAgc3JjID0gc3JjLnN1YnN0cmluZyh0b2tlbi5yYXcubGVuZ3RoKTtcbiAgICAgICAgbGFzdFRva2VuID0gdG9rZW5zW3Rva2Vucy5sZW5ndGggLSAxXTtcbiAgICAgICAgaWYgKGxhc3RUb2tlbiAmJiB0b2tlbi50eXBlID09PSAndGV4dCcgJiYgbGFzdFRva2VuLnR5cGUgPT09ICd0ZXh0Jykge1xuICAgICAgICAgIGxhc3RUb2tlbi5yYXcgKz0gdG9rZW4ucmF3O1xuICAgICAgICAgIGxhc3RUb2tlbi50ZXh0ICs9IHRva2VuLnRleHQ7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdG9rZW5zLnB1c2godG9rZW4pO1xuICAgICAgICB9XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICAvLyBlbSAmIHN0cm9uZ1xuICAgICAgaWYgKHRva2VuID0gdGhpcy50b2tlbml6ZXIuZW1TdHJvbmcoc3JjLCBtYXNrZWRTcmMsIHByZXZDaGFyKSkge1xuICAgICAgICBzcmMgPSBzcmMuc3Vic3RyaW5nKHRva2VuLnJhdy5sZW5ndGgpO1xuICAgICAgICB0b2tlbnMucHVzaCh0b2tlbik7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICAvLyBjb2RlXG4gICAgICBpZiAodG9rZW4gPSB0aGlzLnRva2VuaXplci5jb2Rlc3BhbihzcmMpKSB7XG4gICAgICAgIHNyYyA9IHNyYy5zdWJzdHJpbmcodG9rZW4ucmF3Lmxlbmd0aCk7XG4gICAgICAgIHRva2Vucy5wdXNoKHRva2VuKTtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIC8vIGJyXG4gICAgICBpZiAodG9rZW4gPSB0aGlzLnRva2VuaXplci5icihzcmMpKSB7XG4gICAgICAgIHNyYyA9IHNyYy5zdWJzdHJpbmcodG9rZW4ucmF3Lmxlbmd0aCk7XG4gICAgICAgIHRva2Vucy5wdXNoKHRva2VuKTtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIC8vIGRlbCAoZ2ZtKVxuICAgICAgaWYgKHRva2VuID0gdGhpcy50b2tlbml6ZXIuZGVsKHNyYykpIHtcbiAgICAgICAgc3JjID0gc3JjLnN1YnN0cmluZyh0b2tlbi5yYXcubGVuZ3RoKTtcbiAgICAgICAgdG9rZW5zLnB1c2godG9rZW4pO1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgLy8gYXV0b2xpbmtcbiAgICAgIGlmICh0b2tlbiA9IHRoaXMudG9rZW5pemVyLmF1dG9saW5rKHNyYywgbWFuZ2xlKSkge1xuICAgICAgICBzcmMgPSBzcmMuc3Vic3RyaW5nKHRva2VuLnJhdy5sZW5ndGgpO1xuICAgICAgICB0b2tlbnMucHVzaCh0b2tlbik7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICAvLyB1cmwgKGdmbSlcbiAgICAgIGlmICghdGhpcy5zdGF0ZS5pbkxpbmsgJiYgKHRva2VuID0gdGhpcy50b2tlbml6ZXIudXJsKHNyYywgbWFuZ2xlKSkpIHtcbiAgICAgICAgc3JjID0gc3JjLnN1YnN0cmluZyh0b2tlbi5yYXcubGVuZ3RoKTtcbiAgICAgICAgdG9rZW5zLnB1c2godG9rZW4pO1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgLy8gdGV4dFxuICAgICAgLy8gcHJldmVudCBpbmxpbmVUZXh0IGNvbnN1bWluZyBleHRlbnNpb25zIGJ5IGNsaXBwaW5nICdzcmMnIHRvIGV4dGVuc2lvbiBzdGFydFxuICAgICAgY3V0U3JjID0gc3JjO1xuICAgICAgaWYgKHRoaXMub3B0aW9ucy5leHRlbnNpb25zICYmIHRoaXMub3B0aW9ucy5leHRlbnNpb25zLnN0YXJ0SW5saW5lKSB7XG4gICAgICAgIChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgdmFyIHN0YXJ0SW5kZXggPSBJbmZpbml0eTtcbiAgICAgICAgICB2YXIgdGVtcFNyYyA9IHNyYy5zbGljZSgxKTtcbiAgICAgICAgICB2YXIgdGVtcFN0YXJ0ID0gdm9pZCAwO1xuICAgICAgICAgIF90aGlzMi5vcHRpb25zLmV4dGVuc2lvbnMuc3RhcnRJbmxpbmUuZm9yRWFjaChmdW5jdGlvbiAoZ2V0U3RhcnRJbmRleCkge1xuICAgICAgICAgICAgdGVtcFN0YXJ0ID0gZ2V0U3RhcnRJbmRleC5jYWxsKHtcbiAgICAgICAgICAgICAgbGV4ZXI6IHRoaXNcbiAgICAgICAgICAgIH0sIHRlbXBTcmMpO1xuICAgICAgICAgICAgaWYgKHR5cGVvZiB0ZW1wU3RhcnQgPT09ICdudW1iZXInICYmIHRlbXBTdGFydCA+PSAwKSB7XG4gICAgICAgICAgICAgIHN0YXJ0SW5kZXggPSBNYXRoLm1pbihzdGFydEluZGV4LCB0ZW1wU3RhcnQpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0pO1xuICAgICAgICAgIGlmIChzdGFydEluZGV4IDwgSW5maW5pdHkgJiYgc3RhcnRJbmRleCA+PSAwKSB7XG4gICAgICAgICAgICBjdXRTcmMgPSBzcmMuc3Vic3RyaW5nKDAsIHN0YXJ0SW5kZXggKyAxKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pKCk7XG4gICAgICB9XG4gICAgICBpZiAodG9rZW4gPSB0aGlzLnRva2VuaXplci5pbmxpbmVUZXh0KGN1dFNyYywgc21hcnR5cGFudHMpKSB7XG4gICAgICAgIHNyYyA9IHNyYy5zdWJzdHJpbmcodG9rZW4ucmF3Lmxlbmd0aCk7XG4gICAgICAgIGlmICh0b2tlbi5yYXcuc2xpY2UoLTEpICE9PSAnXycpIHtcbiAgICAgICAgICAvLyBUcmFjayBwcmV2Q2hhciBiZWZvcmUgc3RyaW5nIG9mIF9fX18gc3RhcnRlZFxuICAgICAgICAgIHByZXZDaGFyID0gdG9rZW4ucmF3LnNsaWNlKC0xKTtcbiAgICAgICAgfVxuICAgICAgICBrZWVwUHJldkNoYXIgPSB0cnVlO1xuICAgICAgICBsYXN0VG9rZW4gPSB0b2tlbnNbdG9rZW5zLmxlbmd0aCAtIDFdO1xuICAgICAgICBpZiAobGFzdFRva2VuICYmIGxhc3RUb2tlbi50eXBlID09PSAndGV4dCcpIHtcbiAgICAgICAgICBsYXN0VG9rZW4ucmF3ICs9IHRva2VuLnJhdztcbiAgICAgICAgICBsYXN0VG9rZW4udGV4dCArPSB0b2tlbi50ZXh0O1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRva2Vucy5wdXNoKHRva2VuKTtcbiAgICAgICAgfVxuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cbiAgICAgIGlmIChzcmMpIHtcbiAgICAgICAgdmFyIGVyck1zZyA9ICdJbmZpbml0ZSBsb29wIG9uIGJ5dGU6ICcgKyBzcmMuY2hhckNvZGVBdCgwKTtcbiAgICAgICAgaWYgKHRoaXMub3B0aW9ucy5zaWxlbnQpIHtcbiAgICAgICAgICBjb25zb2xlLmVycm9yKGVyck1zZyk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGVyck1zZyk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHRva2VucztcbiAgfTtcbiAgX2NyZWF0ZUNsYXNzKExleGVyLCBudWxsLCBbe1xuICAgIGtleTogXCJydWxlc1wiLFxuICAgIGdldDogZnVuY3Rpb24gZ2V0KCkge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgYmxvY2s6IGJsb2NrLFxuICAgICAgICBpbmxpbmU6IGlubGluZVxuICAgICAgfTtcbiAgICB9XG4gIH1dKTtcbiAgcmV0dXJuIExleGVyO1xufSgpO1xuXG4vKipcbiAqIFJlbmRlcmVyXG4gKi9cbnZhciBSZW5kZXJlciA9IC8qI19fUFVSRV9fKi9mdW5jdGlvbiAoKSB7XG4gIGZ1bmN0aW9uIFJlbmRlcmVyKG9wdGlvbnMpIHtcbiAgICB0aGlzLm9wdGlvbnMgPSBvcHRpb25zIHx8IGV4cG9ydHMuZGVmYXVsdHM7XG4gIH1cbiAgdmFyIF9wcm90byA9IFJlbmRlcmVyLnByb3RvdHlwZTtcbiAgX3Byb3RvLmNvZGUgPSBmdW5jdGlvbiBjb2RlKF9jb2RlLCBpbmZvc3RyaW5nLCBlc2NhcGVkKSB7XG4gICAgdmFyIGxhbmcgPSAoaW5mb3N0cmluZyB8fCAnJykubWF0Y2goL1xcUyovKVswXTtcbiAgICBpZiAodGhpcy5vcHRpb25zLmhpZ2hsaWdodCkge1xuICAgICAgdmFyIG91dCA9IHRoaXMub3B0aW9ucy5oaWdobGlnaHQoX2NvZGUsIGxhbmcpO1xuICAgICAgaWYgKG91dCAhPSBudWxsICYmIG91dCAhPT0gX2NvZGUpIHtcbiAgICAgICAgZXNjYXBlZCA9IHRydWU7XG4gICAgICAgIF9jb2RlID0gb3V0O1xuICAgICAgfVxuICAgIH1cbiAgICBfY29kZSA9IF9jb2RlLnJlcGxhY2UoL1xcbiQvLCAnJykgKyAnXFxuJztcbiAgICBpZiAoIWxhbmcpIHtcbiAgICAgIHJldHVybiAnPHByZT48Y29kZT4nICsgKGVzY2FwZWQgPyBfY29kZSA6IGVzY2FwZShfY29kZSwgdHJ1ZSkpICsgJzwvY29kZT48L3ByZT5cXG4nO1xuICAgIH1cbiAgICByZXR1cm4gJzxwcmU+PGNvZGUgY2xhc3M9XCInICsgdGhpcy5vcHRpb25zLmxhbmdQcmVmaXggKyBlc2NhcGUobGFuZykgKyAnXCI+JyArIChlc2NhcGVkID8gX2NvZGUgOiBlc2NhcGUoX2NvZGUsIHRydWUpKSArICc8L2NvZGU+PC9wcmU+XFxuJztcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gcXVvdGVcbiAgICovO1xuICBfcHJvdG8uYmxvY2txdW90ZSA9IGZ1bmN0aW9uIGJsb2NrcXVvdGUocXVvdGUpIHtcbiAgICByZXR1cm4gXCI8YmxvY2txdW90ZT5cXG5cIiArIHF1b3RlICsgXCI8L2Jsb2NrcXVvdGU+XFxuXCI7XG4gIH07XG4gIF9wcm90by5odG1sID0gZnVuY3Rpb24gaHRtbChfaHRtbCkge1xuICAgIHJldHVybiBfaHRtbDtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gdGV4dFxuICAgKiBAcGFyYW0ge3N0cmluZ30gbGV2ZWxcbiAgICogQHBhcmFtIHtzdHJpbmd9IHJhd1xuICAgKiBAcGFyYW0ge2FueX0gc2x1Z2dlclxuICAgKi87XG4gIF9wcm90by5oZWFkaW5nID0gZnVuY3Rpb24gaGVhZGluZyh0ZXh0LCBsZXZlbCwgcmF3LCBzbHVnZ2VyKSB7XG4gICAgaWYgKHRoaXMub3B0aW9ucy5oZWFkZXJJZHMpIHtcbiAgICAgIHZhciBpZCA9IHRoaXMub3B0aW9ucy5oZWFkZXJQcmVmaXggKyBzbHVnZ2VyLnNsdWcocmF3KTtcbiAgICAgIHJldHVybiBcIjxoXCIgKyBsZXZlbCArIFwiIGlkPVxcXCJcIiArIGlkICsgXCJcXFwiPlwiICsgdGV4dCArIFwiPC9oXCIgKyBsZXZlbCArIFwiPlxcblwiO1xuICAgIH1cblxuICAgIC8vIGlnbm9yZSBJRHNcbiAgICByZXR1cm4gXCI8aFwiICsgbGV2ZWwgKyBcIj5cIiArIHRleHQgKyBcIjwvaFwiICsgbGV2ZWwgKyBcIj5cXG5cIjtcbiAgfTtcbiAgX3Byb3RvLmhyID0gZnVuY3Rpb24gaHIoKSB7XG4gICAgcmV0dXJuIHRoaXMub3B0aW9ucy54aHRtbCA/ICc8aHIvPlxcbicgOiAnPGhyPlxcbic7XG4gIH07XG4gIF9wcm90by5saXN0ID0gZnVuY3Rpb24gbGlzdChib2R5LCBvcmRlcmVkLCBzdGFydCkge1xuICAgIHZhciB0eXBlID0gb3JkZXJlZCA/ICdvbCcgOiAndWwnLFxuICAgICAgc3RhcnRhdHQgPSBvcmRlcmVkICYmIHN0YXJ0ICE9PSAxID8gJyBzdGFydD1cIicgKyBzdGFydCArICdcIicgOiAnJztcbiAgICByZXR1cm4gJzwnICsgdHlwZSArIHN0YXJ0YXR0ICsgJz5cXG4nICsgYm9keSArICc8LycgKyB0eXBlICsgJz5cXG4nO1xuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSB0ZXh0XG4gICAqLztcbiAgX3Byb3RvLmxpc3RpdGVtID0gZnVuY3Rpb24gbGlzdGl0ZW0odGV4dCkge1xuICAgIHJldHVybiBcIjxsaT5cIiArIHRleHQgKyBcIjwvbGk+XFxuXCI7XG4gIH07XG4gIF9wcm90by5jaGVja2JveCA9IGZ1bmN0aW9uIGNoZWNrYm94KGNoZWNrZWQpIHtcbiAgICByZXR1cm4gJzxpbnB1dCAnICsgKGNoZWNrZWQgPyAnY2hlY2tlZD1cIlwiICcgOiAnJykgKyAnZGlzYWJsZWQ9XCJcIiB0eXBlPVwiY2hlY2tib3hcIicgKyAodGhpcy5vcHRpb25zLnhodG1sID8gJyAvJyA6ICcnKSArICc+ICc7XG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtzdHJpbmd9IHRleHRcbiAgICovO1xuICBfcHJvdG8ucGFyYWdyYXBoID0gZnVuY3Rpb24gcGFyYWdyYXBoKHRleHQpIHtcbiAgICByZXR1cm4gXCI8cD5cIiArIHRleHQgKyBcIjwvcD5cXG5cIjtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gaGVhZGVyXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBib2R5XG4gICAqLztcbiAgX3Byb3RvLnRhYmxlID0gZnVuY3Rpb24gdGFibGUoaGVhZGVyLCBib2R5KSB7XG4gICAgaWYgKGJvZHkpIGJvZHkgPSBcIjx0Ym9keT5cIiArIGJvZHkgKyBcIjwvdGJvZHk+XCI7XG4gICAgcmV0dXJuICc8dGFibGU+XFxuJyArICc8dGhlYWQ+XFxuJyArIGhlYWRlciArICc8L3RoZWFkPlxcbicgKyBib2R5ICsgJzwvdGFibGU+XFxuJztcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gY29udGVudFxuICAgKi87XG4gIF9wcm90by50YWJsZXJvdyA9IGZ1bmN0aW9uIHRhYmxlcm93KGNvbnRlbnQpIHtcbiAgICByZXR1cm4gXCI8dHI+XFxuXCIgKyBjb250ZW50ICsgXCI8L3RyPlxcblwiO1xuICB9O1xuICBfcHJvdG8udGFibGVjZWxsID0gZnVuY3Rpb24gdGFibGVjZWxsKGNvbnRlbnQsIGZsYWdzKSB7XG4gICAgdmFyIHR5cGUgPSBmbGFncy5oZWFkZXIgPyAndGgnIDogJ3RkJztcbiAgICB2YXIgdGFnID0gZmxhZ3MuYWxpZ24gPyBcIjxcIiArIHR5cGUgKyBcIiBhbGlnbj1cXFwiXCIgKyBmbGFncy5hbGlnbiArIFwiXFxcIj5cIiA6IFwiPFwiICsgdHlwZSArIFwiPlwiO1xuICAgIHJldHVybiB0YWcgKyBjb250ZW50ICsgKFwiPC9cIiArIHR5cGUgKyBcIj5cXG5cIik7XG4gIH1cblxuICAvKipcbiAgICogc3BhbiBsZXZlbCByZW5kZXJlclxuICAgKiBAcGFyYW0ge3N0cmluZ30gdGV4dFxuICAgKi87XG4gIF9wcm90by5zdHJvbmcgPSBmdW5jdGlvbiBzdHJvbmcodGV4dCkge1xuICAgIHJldHVybiBcIjxzdHJvbmc+XCIgKyB0ZXh0ICsgXCI8L3N0cm9uZz5cIjtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gdGV4dFxuICAgKi87XG4gIF9wcm90by5lbSA9IGZ1bmN0aW9uIGVtKHRleHQpIHtcbiAgICByZXR1cm4gXCI8ZW0+XCIgKyB0ZXh0ICsgXCI8L2VtPlwiO1xuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSB0ZXh0XG4gICAqLztcbiAgX3Byb3RvLmNvZGVzcGFuID0gZnVuY3Rpb24gY29kZXNwYW4odGV4dCkge1xuICAgIHJldHVybiBcIjxjb2RlPlwiICsgdGV4dCArIFwiPC9jb2RlPlwiO1xuICB9O1xuICBfcHJvdG8uYnIgPSBmdW5jdGlvbiBicigpIHtcbiAgICByZXR1cm4gdGhpcy5vcHRpb25zLnhodG1sID8gJzxici8+JyA6ICc8YnI+JztcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gdGV4dFxuICAgKi87XG4gIF9wcm90by5kZWwgPSBmdW5jdGlvbiBkZWwodGV4dCkge1xuICAgIHJldHVybiBcIjxkZWw+XCIgKyB0ZXh0ICsgXCI8L2RlbD5cIjtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gaHJlZlxuICAgKiBAcGFyYW0ge3N0cmluZ30gdGl0bGVcbiAgICogQHBhcmFtIHtzdHJpbmd9IHRleHRcbiAgICovO1xuICBfcHJvdG8ubGluayA9IGZ1bmN0aW9uIGxpbmsoaHJlZiwgdGl0bGUsIHRleHQpIHtcbiAgICBocmVmID0gY2xlYW5VcmwodGhpcy5vcHRpb25zLnNhbml0aXplLCB0aGlzLm9wdGlvbnMuYmFzZVVybCwgaHJlZik7XG4gICAgaWYgKGhyZWYgPT09IG51bGwpIHtcbiAgICAgIHJldHVybiB0ZXh0O1xuICAgIH1cbiAgICB2YXIgb3V0ID0gJzxhIGhyZWY9XCInICsgaHJlZiArICdcIic7XG4gICAgaWYgKHRpdGxlKSB7XG4gICAgICBvdXQgKz0gJyB0aXRsZT1cIicgKyB0aXRsZSArICdcIic7XG4gICAgfVxuICAgIG91dCArPSAnPicgKyB0ZXh0ICsgJzwvYT4nO1xuICAgIHJldHVybiBvdXQ7XG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtzdHJpbmd9IGhyZWZcbiAgICogQHBhcmFtIHtzdHJpbmd9IHRpdGxlXG4gICAqIEBwYXJhbSB7c3RyaW5nfSB0ZXh0XG4gICAqLztcbiAgX3Byb3RvLmltYWdlID0gZnVuY3Rpb24gaW1hZ2UoaHJlZiwgdGl0bGUsIHRleHQpIHtcbiAgICBocmVmID0gY2xlYW5VcmwodGhpcy5vcHRpb25zLnNhbml0aXplLCB0aGlzLm9wdGlvbnMuYmFzZVVybCwgaHJlZik7XG4gICAgaWYgKGhyZWYgPT09IG51bGwpIHtcbiAgICAgIHJldHVybiB0ZXh0O1xuICAgIH1cbiAgICB2YXIgb3V0ID0gXCI8aW1nIHNyYz1cXFwiXCIgKyBocmVmICsgXCJcXFwiIGFsdD1cXFwiXCIgKyB0ZXh0ICsgXCJcXFwiXCI7XG4gICAgaWYgKHRpdGxlKSB7XG4gICAgICBvdXQgKz0gXCIgdGl0bGU9XFxcIlwiICsgdGl0bGUgKyBcIlxcXCJcIjtcbiAgICB9XG4gICAgb3V0ICs9IHRoaXMub3B0aW9ucy54aHRtbCA/ICcvPicgOiAnPic7XG4gICAgcmV0dXJuIG91dDtcbiAgfTtcbiAgX3Byb3RvLnRleHQgPSBmdW5jdGlvbiB0ZXh0KF90ZXh0KSB7XG4gICAgcmV0dXJuIF90ZXh0O1xuICB9O1xuICByZXR1cm4gUmVuZGVyZXI7XG59KCk7XG5cbi8qKlxuICogVGV4dFJlbmRlcmVyXG4gKiByZXR1cm5zIG9ubHkgdGhlIHRleHR1YWwgcGFydCBvZiB0aGUgdG9rZW5cbiAqL1xudmFyIFRleHRSZW5kZXJlciA9IC8qI19fUFVSRV9fKi9mdW5jdGlvbiAoKSB7XG4gIGZ1bmN0aW9uIFRleHRSZW5kZXJlcigpIHt9XG4gIHZhciBfcHJvdG8gPSBUZXh0UmVuZGVyZXIucHJvdG90eXBlO1xuICAvLyBubyBuZWVkIGZvciBibG9jayBsZXZlbCByZW5kZXJlcnNcbiAgX3Byb3RvLnN0cm9uZyA9IGZ1bmN0aW9uIHN0cm9uZyh0ZXh0KSB7XG4gICAgcmV0dXJuIHRleHQ7XG4gIH07XG4gIF9wcm90by5lbSA9IGZ1bmN0aW9uIGVtKHRleHQpIHtcbiAgICByZXR1cm4gdGV4dDtcbiAgfTtcbiAgX3Byb3RvLmNvZGVzcGFuID0gZnVuY3Rpb24gY29kZXNwYW4odGV4dCkge1xuICAgIHJldHVybiB0ZXh0O1xuICB9O1xuICBfcHJvdG8uZGVsID0gZnVuY3Rpb24gZGVsKHRleHQpIHtcbiAgICByZXR1cm4gdGV4dDtcbiAgfTtcbiAgX3Byb3RvLmh0bWwgPSBmdW5jdGlvbiBodG1sKHRleHQpIHtcbiAgICByZXR1cm4gdGV4dDtcbiAgfTtcbiAgX3Byb3RvLnRleHQgPSBmdW5jdGlvbiB0ZXh0KF90ZXh0KSB7XG4gICAgcmV0dXJuIF90ZXh0O1xuICB9O1xuICBfcHJvdG8ubGluayA9IGZ1bmN0aW9uIGxpbmsoaHJlZiwgdGl0bGUsIHRleHQpIHtcbiAgICByZXR1cm4gJycgKyB0ZXh0O1xuICB9O1xuICBfcHJvdG8uaW1hZ2UgPSBmdW5jdGlvbiBpbWFnZShocmVmLCB0aXRsZSwgdGV4dCkge1xuICAgIHJldHVybiAnJyArIHRleHQ7XG4gIH07XG4gIF9wcm90by5iciA9IGZ1bmN0aW9uIGJyKCkge1xuICAgIHJldHVybiAnJztcbiAgfTtcbiAgcmV0dXJuIFRleHRSZW5kZXJlcjtcbn0oKTtcblxuLyoqXG4gKiBTbHVnZ2VyIGdlbmVyYXRlcyBoZWFkZXIgaWRcbiAqL1xudmFyIFNsdWdnZXIgPSAvKiNfX1BVUkVfXyovZnVuY3Rpb24gKCkge1xuICBmdW5jdGlvbiBTbHVnZ2VyKCkge1xuICAgIHRoaXMuc2VlbiA9IHt9O1xuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSB2YWx1ZVxuICAgKi9cbiAgdmFyIF9wcm90byA9IFNsdWdnZXIucHJvdG90eXBlO1xuICBfcHJvdG8uc2VyaWFsaXplID0gZnVuY3Rpb24gc2VyaWFsaXplKHZhbHVlKSB7XG4gICAgcmV0dXJuIHZhbHVlLnRvTG93ZXJDYXNlKCkudHJpbSgpXG4gICAgLy8gcmVtb3ZlIGh0bWwgdGFnc1xuICAgIC5yZXBsYWNlKC88WyFcXC9hLXpdLio/Pi9pZywgJycpXG4gICAgLy8gcmVtb3ZlIHVud2FudGVkIGNoYXJzXG4gICAgLnJlcGxhY2UoL1tcXHUyMDAwLVxcdTIwNkZcXHUyRTAwLVxcdTJFN0ZcXFxcJyFcIiMkJSYoKSorLC4vOjs8PT4/QFtcXF1eYHt8fX5dL2csICcnKS5yZXBsYWNlKC9cXHMvZywgJy0nKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBGaW5kcyB0aGUgbmV4dCBzYWZlICh1bmlxdWUpIHNsdWcgdG8gdXNlXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBvcmlnaW5hbFNsdWdcbiAgICogQHBhcmFtIHtib29sZWFufSBpc0RyeVJ1blxuICAgKi87XG4gIF9wcm90by5nZXROZXh0U2FmZVNsdWcgPSBmdW5jdGlvbiBnZXROZXh0U2FmZVNsdWcob3JpZ2luYWxTbHVnLCBpc0RyeVJ1bikge1xuICAgIHZhciBzbHVnID0gb3JpZ2luYWxTbHVnO1xuICAgIHZhciBvY2N1cmVuY2VBY2N1bXVsYXRvciA9IDA7XG4gICAgaWYgKHRoaXMuc2Vlbi5oYXNPd25Qcm9wZXJ0eShzbHVnKSkge1xuICAgICAgb2NjdXJlbmNlQWNjdW11bGF0b3IgPSB0aGlzLnNlZW5bb3JpZ2luYWxTbHVnXTtcbiAgICAgIGRvIHtcbiAgICAgICAgb2NjdXJlbmNlQWNjdW11bGF0b3IrKztcbiAgICAgICAgc2x1ZyA9IG9yaWdpbmFsU2x1ZyArICctJyArIG9jY3VyZW5jZUFjY3VtdWxhdG9yO1xuICAgICAgfSB3aGlsZSAodGhpcy5zZWVuLmhhc093blByb3BlcnR5KHNsdWcpKTtcbiAgICB9XG4gICAgaWYgKCFpc0RyeVJ1bikge1xuICAgICAgdGhpcy5zZWVuW29yaWdpbmFsU2x1Z10gPSBvY2N1cmVuY2VBY2N1bXVsYXRvcjtcbiAgICAgIHRoaXMuc2VlbltzbHVnXSA9IDA7XG4gICAgfVxuICAgIHJldHVybiBzbHVnO1xuICB9XG5cbiAgLyoqXG4gICAqIENvbnZlcnQgc3RyaW5nIHRvIHVuaXF1ZSBpZFxuICAgKiBAcGFyYW0ge29iamVjdH0gW29wdGlvbnNdXG4gICAqIEBwYXJhbSB7Ym9vbGVhbn0gW29wdGlvbnMuZHJ5cnVuXSBHZW5lcmF0ZXMgdGhlIG5leHQgdW5pcXVlIHNsdWcgd2l0aG91dFxuICAgKiB1cGRhdGluZyB0aGUgaW50ZXJuYWwgYWNjdW11bGF0b3IuXG4gICAqLztcbiAgX3Byb3RvLnNsdWcgPSBmdW5jdGlvbiBzbHVnKHZhbHVlLCBvcHRpb25zKSB7XG4gICAgaWYgKG9wdGlvbnMgPT09IHZvaWQgMCkge1xuICAgICAgb3B0aW9ucyA9IHt9O1xuICAgIH1cbiAgICB2YXIgc2x1ZyA9IHRoaXMuc2VyaWFsaXplKHZhbHVlKTtcbiAgICByZXR1cm4gdGhpcy5nZXROZXh0U2FmZVNsdWcoc2x1Zywgb3B0aW9ucy5kcnlydW4pO1xuICB9O1xuICByZXR1cm4gU2x1Z2dlcjtcbn0oKTtcblxuLyoqXG4gKiBQYXJzaW5nICYgQ29tcGlsaW5nXG4gKi9cbnZhciBQYXJzZXIgPSAvKiNfX1BVUkVfXyovZnVuY3Rpb24gKCkge1xuICBmdW5jdGlvbiBQYXJzZXIob3B0aW9ucykge1xuICAgIHRoaXMub3B0aW9ucyA9IG9wdGlvbnMgfHwgZXhwb3J0cy5kZWZhdWx0cztcbiAgICB0aGlzLm9wdGlvbnMucmVuZGVyZXIgPSB0aGlzLm9wdGlvbnMucmVuZGVyZXIgfHwgbmV3IFJlbmRlcmVyKCk7XG4gICAgdGhpcy5yZW5kZXJlciA9IHRoaXMub3B0aW9ucy5yZW5kZXJlcjtcbiAgICB0aGlzLnJlbmRlcmVyLm9wdGlvbnMgPSB0aGlzLm9wdGlvbnM7XG4gICAgdGhpcy50ZXh0UmVuZGVyZXIgPSBuZXcgVGV4dFJlbmRlcmVyKCk7XG4gICAgdGhpcy5zbHVnZ2VyID0gbmV3IFNsdWdnZXIoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTdGF0aWMgUGFyc2UgTWV0aG9kXG4gICAqL1xuICBQYXJzZXIucGFyc2UgPSBmdW5jdGlvbiBwYXJzZSh0b2tlbnMsIG9wdGlvbnMpIHtcbiAgICB2YXIgcGFyc2VyID0gbmV3IFBhcnNlcihvcHRpb25zKTtcbiAgICByZXR1cm4gcGFyc2VyLnBhcnNlKHRva2Vucyk7XG4gIH1cblxuICAvKipcbiAgICogU3RhdGljIFBhcnNlIElubGluZSBNZXRob2RcbiAgICovO1xuICBQYXJzZXIucGFyc2VJbmxpbmUgPSBmdW5jdGlvbiBwYXJzZUlubGluZSh0b2tlbnMsIG9wdGlvbnMpIHtcbiAgICB2YXIgcGFyc2VyID0gbmV3IFBhcnNlcihvcHRpb25zKTtcbiAgICByZXR1cm4gcGFyc2VyLnBhcnNlSW5saW5lKHRva2Vucyk7XG4gIH1cblxuICAvKipcbiAgICogUGFyc2UgTG9vcFxuICAgKi87XG4gIHZhciBfcHJvdG8gPSBQYXJzZXIucHJvdG90eXBlO1xuICBfcHJvdG8ucGFyc2UgPSBmdW5jdGlvbiBwYXJzZSh0b2tlbnMsIHRvcCkge1xuICAgIGlmICh0b3AgPT09IHZvaWQgMCkge1xuICAgICAgdG9wID0gdHJ1ZTtcbiAgICB9XG4gICAgdmFyIG91dCA9ICcnLFxuICAgICAgaSxcbiAgICAgIGosXG4gICAgICBrLFxuICAgICAgbDIsXG4gICAgICBsMyxcbiAgICAgIHJvdyxcbiAgICAgIGNlbGwsXG4gICAgICBoZWFkZXIsXG4gICAgICBib2R5LFxuICAgICAgdG9rZW4sXG4gICAgICBvcmRlcmVkLFxuICAgICAgc3RhcnQsXG4gICAgICBsb29zZSxcbiAgICAgIGl0ZW1Cb2R5LFxuICAgICAgaXRlbSxcbiAgICAgIGNoZWNrZWQsXG4gICAgICB0YXNrLFxuICAgICAgY2hlY2tib3gsXG4gICAgICByZXQ7XG4gICAgdmFyIGwgPSB0b2tlbnMubGVuZ3RoO1xuICAgIGZvciAoaSA9IDA7IGkgPCBsOyBpKyspIHtcbiAgICAgIHRva2VuID0gdG9rZW5zW2ldO1xuXG4gICAgICAvLyBSdW4gYW55IHJlbmRlcmVyIGV4dGVuc2lvbnNcbiAgICAgIGlmICh0aGlzLm9wdGlvbnMuZXh0ZW5zaW9ucyAmJiB0aGlzLm9wdGlvbnMuZXh0ZW5zaW9ucy5yZW5kZXJlcnMgJiYgdGhpcy5vcHRpb25zLmV4dGVuc2lvbnMucmVuZGVyZXJzW3Rva2VuLnR5cGVdKSB7XG4gICAgICAgIHJldCA9IHRoaXMub3B0aW9ucy5leHRlbnNpb25zLnJlbmRlcmVyc1t0b2tlbi50eXBlXS5jYWxsKHtcbiAgICAgICAgICBwYXJzZXI6IHRoaXNcbiAgICAgICAgfSwgdG9rZW4pO1xuICAgICAgICBpZiAocmV0ICE9PSBmYWxzZSB8fCAhWydzcGFjZScsICdocicsICdoZWFkaW5nJywgJ2NvZGUnLCAndGFibGUnLCAnYmxvY2txdW90ZScsICdsaXN0JywgJ2h0bWwnLCAncGFyYWdyYXBoJywgJ3RleHQnXS5pbmNsdWRlcyh0b2tlbi50eXBlKSkge1xuICAgICAgICAgIG91dCArPSByZXQgfHwgJyc7XG4gICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHN3aXRjaCAodG9rZW4udHlwZSkge1xuICAgICAgICBjYXNlICdzcGFjZSc6XG4gICAgICAgICAge1xuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgfVxuICAgICAgICBjYXNlICdocic6XG4gICAgICAgICAge1xuICAgICAgICAgICAgb3V0ICs9IHRoaXMucmVuZGVyZXIuaHIoKTtcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgIH1cbiAgICAgICAgY2FzZSAnaGVhZGluZyc6XG4gICAgICAgICAge1xuICAgICAgICAgICAgb3V0ICs9IHRoaXMucmVuZGVyZXIuaGVhZGluZyh0aGlzLnBhcnNlSW5saW5lKHRva2VuLnRva2VucyksIHRva2VuLmRlcHRoLCB1bmVzY2FwZSh0aGlzLnBhcnNlSW5saW5lKHRva2VuLnRva2VucywgdGhpcy50ZXh0UmVuZGVyZXIpKSwgdGhpcy5zbHVnZ2VyKTtcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgIH1cbiAgICAgICAgY2FzZSAnY29kZSc6XG4gICAgICAgICAge1xuICAgICAgICAgICAgb3V0ICs9IHRoaXMucmVuZGVyZXIuY29kZSh0b2tlbi50ZXh0LCB0b2tlbi5sYW5nLCB0b2tlbi5lc2NhcGVkKTtcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgIH1cbiAgICAgICAgY2FzZSAndGFibGUnOlxuICAgICAgICAgIHtcbiAgICAgICAgICAgIGhlYWRlciA9ICcnO1xuXG4gICAgICAgICAgICAvLyBoZWFkZXJcbiAgICAgICAgICAgIGNlbGwgPSAnJztcbiAgICAgICAgICAgIGwyID0gdG9rZW4uaGVhZGVyLmxlbmd0aDtcbiAgICAgICAgICAgIGZvciAoaiA9IDA7IGogPCBsMjsgaisrKSB7XG4gICAgICAgICAgICAgIGNlbGwgKz0gdGhpcy5yZW5kZXJlci50YWJsZWNlbGwodGhpcy5wYXJzZUlubGluZSh0b2tlbi5oZWFkZXJbal0udG9rZW5zKSwge1xuICAgICAgICAgICAgICAgIGhlYWRlcjogdHJ1ZSxcbiAgICAgICAgICAgICAgICBhbGlnbjogdG9rZW4uYWxpZ25bal1cbiAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBoZWFkZXIgKz0gdGhpcy5yZW5kZXJlci50YWJsZXJvdyhjZWxsKTtcbiAgICAgICAgICAgIGJvZHkgPSAnJztcbiAgICAgICAgICAgIGwyID0gdG9rZW4ucm93cy5sZW5ndGg7XG4gICAgICAgICAgICBmb3IgKGogPSAwOyBqIDwgbDI7IGorKykge1xuICAgICAgICAgICAgICByb3cgPSB0b2tlbi5yb3dzW2pdO1xuICAgICAgICAgICAgICBjZWxsID0gJyc7XG4gICAgICAgICAgICAgIGwzID0gcm93Lmxlbmd0aDtcbiAgICAgICAgICAgICAgZm9yIChrID0gMDsgayA8IGwzOyBrKyspIHtcbiAgICAgICAgICAgICAgICBjZWxsICs9IHRoaXMucmVuZGVyZXIudGFibGVjZWxsKHRoaXMucGFyc2VJbmxpbmUocm93W2tdLnRva2VucyksIHtcbiAgICAgICAgICAgICAgICAgIGhlYWRlcjogZmFsc2UsXG4gICAgICAgICAgICAgICAgICBhbGlnbjogdG9rZW4uYWxpZ25ba11cbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICBib2R5ICs9IHRoaXMucmVuZGVyZXIudGFibGVyb3coY2VsbCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBvdXQgKz0gdGhpcy5yZW5kZXJlci50YWJsZShoZWFkZXIsIGJvZHkpO1xuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgfVxuICAgICAgICBjYXNlICdibG9ja3F1b3RlJzpcbiAgICAgICAgICB7XG4gICAgICAgICAgICBib2R5ID0gdGhpcy5wYXJzZSh0b2tlbi50b2tlbnMpO1xuICAgICAgICAgICAgb3V0ICs9IHRoaXMucmVuZGVyZXIuYmxvY2txdW90ZShib2R5KTtcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgIH1cbiAgICAgICAgY2FzZSAnbGlzdCc6XG4gICAgICAgICAge1xuICAgICAgICAgICAgb3JkZXJlZCA9IHRva2VuLm9yZGVyZWQ7XG4gICAgICAgICAgICBzdGFydCA9IHRva2VuLnN0YXJ0O1xuICAgICAgICAgICAgbG9vc2UgPSB0b2tlbi5sb29zZTtcbiAgICAgICAgICAgIGwyID0gdG9rZW4uaXRlbXMubGVuZ3RoO1xuICAgICAgICAgICAgYm9keSA9ICcnO1xuICAgICAgICAgICAgZm9yIChqID0gMDsgaiA8IGwyOyBqKyspIHtcbiAgICAgICAgICAgICAgaXRlbSA9IHRva2VuLml0ZW1zW2pdO1xuICAgICAgICAgICAgICBjaGVja2VkID0gaXRlbS5jaGVja2VkO1xuICAgICAgICAgICAgICB0YXNrID0gaXRlbS50YXNrO1xuICAgICAgICAgICAgICBpdGVtQm9keSA9ICcnO1xuICAgICAgICAgICAgICBpZiAoaXRlbS50YXNrKSB7XG4gICAgICAgICAgICAgICAgY2hlY2tib3ggPSB0aGlzLnJlbmRlcmVyLmNoZWNrYm94KGNoZWNrZWQpO1xuICAgICAgICAgICAgICAgIGlmIChsb29zZSkge1xuICAgICAgICAgICAgICAgICAgaWYgKGl0ZW0udG9rZW5zLmxlbmd0aCA+IDAgJiYgaXRlbS50b2tlbnNbMF0udHlwZSA9PT0gJ3BhcmFncmFwaCcpIHtcbiAgICAgICAgICAgICAgICAgICAgaXRlbS50b2tlbnNbMF0udGV4dCA9IGNoZWNrYm94ICsgJyAnICsgaXRlbS50b2tlbnNbMF0udGV4dDtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGl0ZW0udG9rZW5zWzBdLnRva2VucyAmJiBpdGVtLnRva2Vuc1swXS50b2tlbnMubGVuZ3RoID4gMCAmJiBpdGVtLnRva2Vuc1swXS50b2tlbnNbMF0udHlwZSA9PT0gJ3RleHQnKSB7XG4gICAgICAgICAgICAgICAgICAgICAgaXRlbS50b2tlbnNbMF0udG9rZW5zWzBdLnRleHQgPSBjaGVja2JveCArICcgJyArIGl0ZW0udG9rZW5zWzBdLnRva2Vuc1swXS50ZXh0O1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBpdGVtLnRva2Vucy51bnNoaWZ0KHtcbiAgICAgICAgICAgICAgICAgICAgICB0eXBlOiAndGV4dCcsXG4gICAgICAgICAgICAgICAgICAgICAgdGV4dDogY2hlY2tib3hcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgIGl0ZW1Cb2R5ICs9IGNoZWNrYm94O1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICBpdGVtQm9keSArPSB0aGlzLnBhcnNlKGl0ZW0udG9rZW5zLCBsb29zZSk7XG4gICAgICAgICAgICAgIGJvZHkgKz0gdGhpcy5yZW5kZXJlci5saXN0aXRlbShpdGVtQm9keSwgdGFzaywgY2hlY2tlZCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBvdXQgKz0gdGhpcy5yZW5kZXJlci5saXN0KGJvZHksIG9yZGVyZWQsIHN0YXJ0KTtcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgIH1cbiAgICAgICAgY2FzZSAnaHRtbCc6XG4gICAgICAgICAge1xuICAgICAgICAgICAgLy8gVE9ETyBwYXJzZSBpbmxpbmUgY29udGVudCBpZiBwYXJhbWV0ZXIgbWFya2Rvd249MVxuICAgICAgICAgICAgb3V0ICs9IHRoaXMucmVuZGVyZXIuaHRtbCh0b2tlbi50ZXh0KTtcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgIH1cbiAgICAgICAgY2FzZSAncGFyYWdyYXBoJzpcbiAgICAgICAgICB7XG4gICAgICAgICAgICBvdXQgKz0gdGhpcy5yZW5kZXJlci5wYXJhZ3JhcGgodGhpcy5wYXJzZUlubGluZSh0b2tlbi50b2tlbnMpKTtcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgIH1cbiAgICAgICAgY2FzZSAndGV4dCc6XG4gICAgICAgICAge1xuICAgICAgICAgICAgYm9keSA9IHRva2VuLnRva2VucyA/IHRoaXMucGFyc2VJbmxpbmUodG9rZW4udG9rZW5zKSA6IHRva2VuLnRleHQ7XG4gICAgICAgICAgICB3aGlsZSAoaSArIDEgPCBsICYmIHRva2Vuc1tpICsgMV0udHlwZSA9PT0gJ3RleHQnKSB7XG4gICAgICAgICAgICAgIHRva2VuID0gdG9rZW5zWysraV07XG4gICAgICAgICAgICAgIGJvZHkgKz0gJ1xcbicgKyAodG9rZW4udG9rZW5zID8gdGhpcy5wYXJzZUlubGluZSh0b2tlbi50b2tlbnMpIDogdG9rZW4udGV4dCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBvdXQgKz0gdG9wID8gdGhpcy5yZW5kZXJlci5wYXJhZ3JhcGgoYm9keSkgOiBib2R5O1xuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgfVxuICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgIHtcbiAgICAgICAgICAgIHZhciBlcnJNc2cgPSAnVG9rZW4gd2l0aCBcIicgKyB0b2tlbi50eXBlICsgJ1wiIHR5cGUgd2FzIG5vdCBmb3VuZC4nO1xuICAgICAgICAgICAgaWYgKHRoaXMub3B0aW9ucy5zaWxlbnQpIHtcbiAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihlcnJNc2cpO1xuICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoZXJyTXNnKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBvdXQ7XG4gIH1cblxuICAvKipcbiAgICogUGFyc2UgSW5saW5lIFRva2Vuc1xuICAgKi87XG4gIF9wcm90by5wYXJzZUlubGluZSA9IGZ1bmN0aW9uIHBhcnNlSW5saW5lKHRva2VucywgcmVuZGVyZXIpIHtcbiAgICByZW5kZXJlciA9IHJlbmRlcmVyIHx8IHRoaXMucmVuZGVyZXI7XG4gICAgdmFyIG91dCA9ICcnLFxuICAgICAgaSxcbiAgICAgIHRva2VuLFxuICAgICAgcmV0O1xuICAgIHZhciBsID0gdG9rZW5zLmxlbmd0aDtcbiAgICBmb3IgKGkgPSAwOyBpIDwgbDsgaSsrKSB7XG4gICAgICB0b2tlbiA9IHRva2Vuc1tpXTtcblxuICAgICAgLy8gUnVuIGFueSByZW5kZXJlciBleHRlbnNpb25zXG4gICAgICBpZiAodGhpcy5vcHRpb25zLmV4dGVuc2lvbnMgJiYgdGhpcy5vcHRpb25zLmV4dGVuc2lvbnMucmVuZGVyZXJzICYmIHRoaXMub3B0aW9ucy5leHRlbnNpb25zLnJlbmRlcmVyc1t0b2tlbi50eXBlXSkge1xuICAgICAgICByZXQgPSB0aGlzLm9wdGlvbnMuZXh0ZW5zaW9ucy5yZW5kZXJlcnNbdG9rZW4udHlwZV0uY2FsbCh7XG4gICAgICAgICAgcGFyc2VyOiB0aGlzXG4gICAgICAgIH0sIHRva2VuKTtcbiAgICAgICAgaWYgKHJldCAhPT0gZmFsc2UgfHwgIVsnZXNjYXBlJywgJ2h0bWwnLCAnbGluaycsICdpbWFnZScsICdzdHJvbmcnLCAnZW0nLCAnY29kZXNwYW4nLCAnYnInLCAnZGVsJywgJ3RleHQnXS5pbmNsdWRlcyh0b2tlbi50eXBlKSkge1xuICAgICAgICAgIG91dCArPSByZXQgfHwgJyc7XG4gICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHN3aXRjaCAodG9rZW4udHlwZSkge1xuICAgICAgICBjYXNlICdlc2NhcGUnOlxuICAgICAgICAgIHtcbiAgICAgICAgICAgIG91dCArPSByZW5kZXJlci50ZXh0KHRva2VuLnRleHQpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICBjYXNlICdodG1sJzpcbiAgICAgICAgICB7XG4gICAgICAgICAgICBvdXQgKz0gcmVuZGVyZXIuaHRtbCh0b2tlbi50ZXh0KTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgY2FzZSAnbGluayc6XG4gICAgICAgICAge1xuICAgICAgICAgICAgb3V0ICs9IHJlbmRlcmVyLmxpbmsodG9rZW4uaHJlZiwgdG9rZW4udGl0bGUsIHRoaXMucGFyc2VJbmxpbmUodG9rZW4udG9rZW5zLCByZW5kZXJlcikpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICBjYXNlICdpbWFnZSc6XG4gICAgICAgICAge1xuICAgICAgICAgICAgb3V0ICs9IHJlbmRlcmVyLmltYWdlKHRva2VuLmhyZWYsIHRva2VuLnRpdGxlLCB0b2tlbi50ZXh0KTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgY2FzZSAnc3Ryb25nJzpcbiAgICAgICAgICB7XG4gICAgICAgICAgICBvdXQgKz0gcmVuZGVyZXIuc3Ryb25nKHRoaXMucGFyc2VJbmxpbmUodG9rZW4udG9rZW5zLCByZW5kZXJlcikpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICBjYXNlICdlbSc6XG4gICAgICAgICAge1xuICAgICAgICAgICAgb3V0ICs9IHJlbmRlcmVyLmVtKHRoaXMucGFyc2VJbmxpbmUodG9rZW4udG9rZW5zLCByZW5kZXJlcikpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICBjYXNlICdjb2Rlc3Bhbic6XG4gICAgICAgICAge1xuICAgICAgICAgICAgb3V0ICs9IHJlbmRlcmVyLmNvZGVzcGFuKHRva2VuLnRleHQpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICBjYXNlICdicic6XG4gICAgICAgICAge1xuICAgICAgICAgICAgb3V0ICs9IHJlbmRlcmVyLmJyKCk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgIGNhc2UgJ2RlbCc6XG4gICAgICAgICAge1xuICAgICAgICAgICAgb3V0ICs9IHJlbmRlcmVyLmRlbCh0aGlzLnBhcnNlSW5saW5lKHRva2VuLnRva2VucywgcmVuZGVyZXIpKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgY2FzZSAndGV4dCc6XG4gICAgICAgICAge1xuICAgICAgICAgICAgb3V0ICs9IHJlbmRlcmVyLnRleHQodG9rZW4udGV4dCk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAge1xuICAgICAgICAgICAgdmFyIGVyck1zZyA9ICdUb2tlbiB3aXRoIFwiJyArIHRva2VuLnR5cGUgKyAnXCIgdHlwZSB3YXMgbm90IGZvdW5kLic7XG4gICAgICAgICAgICBpZiAodGhpcy5vcHRpb25zLnNpbGVudCkge1xuICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKGVyck1zZyk7XG4gICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihlcnJNc2cpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIG91dDtcbiAgfTtcbiAgcmV0dXJuIFBhcnNlcjtcbn0oKTtcblxuLyoqXG4gKiBNYXJrZWRcbiAqL1xuZnVuY3Rpb24gbWFya2VkKHNyYywgb3B0LCBjYWxsYmFjaykge1xuICAvLyB0aHJvdyBlcnJvciBpbiBjYXNlIG9mIG5vbiBzdHJpbmcgaW5wdXRcbiAgaWYgKHR5cGVvZiBzcmMgPT09ICd1bmRlZmluZWQnIHx8IHNyYyA9PT0gbnVsbCkge1xuICAgIHRocm93IG5ldyBFcnJvcignbWFya2VkKCk6IGlucHV0IHBhcmFtZXRlciBpcyB1bmRlZmluZWQgb3IgbnVsbCcpO1xuICB9XG4gIGlmICh0eXBlb2Ygc3JjICE9PSAnc3RyaW5nJykge1xuICAgIHRocm93IG5ldyBFcnJvcignbWFya2VkKCk6IGlucHV0IHBhcmFtZXRlciBpcyBvZiB0eXBlICcgKyBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwoc3JjKSArICcsIHN0cmluZyBleHBlY3RlZCcpO1xuICB9XG4gIGlmICh0eXBlb2Ygb3B0ID09PSAnZnVuY3Rpb24nKSB7XG4gICAgY2FsbGJhY2sgPSBvcHQ7XG4gICAgb3B0ID0gbnVsbDtcbiAgfVxuICBvcHQgPSBtZXJnZSh7fSwgbWFya2VkLmRlZmF1bHRzLCBvcHQgfHwge30pO1xuICBjaGVja1Nhbml0aXplRGVwcmVjYXRpb24ob3B0KTtcbiAgaWYgKGNhbGxiYWNrKSB7XG4gICAgdmFyIGhpZ2hsaWdodCA9IG9wdC5oaWdobGlnaHQ7XG4gICAgdmFyIHRva2VucztcbiAgICB0cnkge1xuICAgICAgdG9rZW5zID0gTGV4ZXIubGV4KHNyYywgb3B0KTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICByZXR1cm4gY2FsbGJhY2soZSk7XG4gICAgfVxuICAgIHZhciBkb25lID0gZnVuY3Rpb24gZG9uZShlcnIpIHtcbiAgICAgIHZhciBvdXQ7XG4gICAgICBpZiAoIWVycikge1xuICAgICAgICB0cnkge1xuICAgICAgICAgIGlmIChvcHQud2Fsa1Rva2Vucykge1xuICAgICAgICAgICAgbWFya2VkLndhbGtUb2tlbnModG9rZW5zLCBvcHQud2Fsa1Rva2Vucyk7XG4gICAgICAgICAgfVxuICAgICAgICAgIG91dCA9IFBhcnNlci5wYXJzZSh0b2tlbnMsIG9wdCk7XG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICBlcnIgPSBlO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBvcHQuaGlnaGxpZ2h0ID0gaGlnaGxpZ2h0O1xuICAgICAgcmV0dXJuIGVyciA/IGNhbGxiYWNrKGVycikgOiBjYWxsYmFjayhudWxsLCBvdXQpO1xuICAgIH07XG4gICAgaWYgKCFoaWdobGlnaHQgfHwgaGlnaGxpZ2h0Lmxlbmd0aCA8IDMpIHtcbiAgICAgIHJldHVybiBkb25lKCk7XG4gICAgfVxuICAgIGRlbGV0ZSBvcHQuaGlnaGxpZ2h0O1xuICAgIGlmICghdG9rZW5zLmxlbmd0aCkgcmV0dXJuIGRvbmUoKTtcbiAgICB2YXIgcGVuZGluZyA9IDA7XG4gICAgbWFya2VkLndhbGtUb2tlbnModG9rZW5zLCBmdW5jdGlvbiAodG9rZW4pIHtcbiAgICAgIGlmICh0b2tlbi50eXBlID09PSAnY29kZScpIHtcbiAgICAgICAgcGVuZGluZysrO1xuICAgICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICBoaWdobGlnaHQodG9rZW4udGV4dCwgdG9rZW4ubGFuZywgZnVuY3Rpb24gKGVyciwgY29kZSkge1xuICAgICAgICAgICAgaWYgKGVycikge1xuICAgICAgICAgICAgICByZXR1cm4gZG9uZShlcnIpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGNvZGUgIT0gbnVsbCAmJiBjb2RlICE9PSB0b2tlbi50ZXh0KSB7XG4gICAgICAgICAgICAgIHRva2VuLnRleHQgPSBjb2RlO1xuICAgICAgICAgICAgICB0b2tlbi5lc2NhcGVkID0gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHBlbmRpbmctLTtcbiAgICAgICAgICAgIGlmIChwZW5kaW5nID09PSAwKSB7XG4gICAgICAgICAgICAgIGRvbmUoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9KTtcbiAgICAgICAgfSwgMCk7XG4gICAgICB9XG4gICAgfSk7XG4gICAgaWYgKHBlbmRpbmcgPT09IDApIHtcbiAgICAgIGRvbmUoKTtcbiAgICB9XG4gICAgcmV0dXJuO1xuICB9XG4gIGZ1bmN0aW9uIG9uRXJyb3IoZSkge1xuICAgIGUubWVzc2FnZSArPSAnXFxuUGxlYXNlIHJlcG9ydCB0aGlzIHRvIGh0dHBzOi8vZ2l0aHViLmNvbS9tYXJrZWRqcy9tYXJrZWQuJztcbiAgICBpZiAob3B0LnNpbGVudCkge1xuICAgICAgcmV0dXJuICc8cD5BbiBlcnJvciBvY2N1cnJlZDo8L3A+PHByZT4nICsgZXNjYXBlKGUubWVzc2FnZSArICcnLCB0cnVlKSArICc8L3ByZT4nO1xuICAgIH1cbiAgICB0aHJvdyBlO1xuICB9XG4gIHRyeSB7XG4gICAgdmFyIF90b2tlbnMgPSBMZXhlci5sZXgoc3JjLCBvcHQpO1xuICAgIGlmIChvcHQud2Fsa1Rva2Vucykge1xuICAgICAgaWYgKG9wdC5hc3luYykge1xuICAgICAgICByZXR1cm4gUHJvbWlzZS5hbGwobWFya2VkLndhbGtUb2tlbnMoX3Rva2Vucywgb3B0LndhbGtUb2tlbnMpKS50aGVuKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICByZXR1cm4gUGFyc2VyLnBhcnNlKF90b2tlbnMsIG9wdCk7XG4gICAgICAgIH0pW1wiY2F0Y2hcIl0ob25FcnJvcik7XG4gICAgICB9XG4gICAgICBtYXJrZWQud2Fsa1Rva2VucyhfdG9rZW5zLCBvcHQud2Fsa1Rva2Vucyk7XG4gICAgfVxuICAgIHJldHVybiBQYXJzZXIucGFyc2UoX3Rva2Vucywgb3B0KTtcbiAgfSBjYXRjaCAoZSkge1xuICAgIG9uRXJyb3IoZSk7XG4gIH1cbn1cblxuLyoqXG4gKiBPcHRpb25zXG4gKi9cblxubWFya2VkLm9wdGlvbnMgPSBtYXJrZWQuc2V0T3B0aW9ucyA9IGZ1bmN0aW9uIChvcHQpIHtcbiAgbWVyZ2UobWFya2VkLmRlZmF1bHRzLCBvcHQpO1xuICBjaGFuZ2VEZWZhdWx0cyhtYXJrZWQuZGVmYXVsdHMpO1xuICByZXR1cm4gbWFya2VkO1xufTtcbm1hcmtlZC5nZXREZWZhdWx0cyA9IGdldERlZmF1bHRzO1xubWFya2VkLmRlZmF1bHRzID0gZXhwb3J0cy5kZWZhdWx0cztcblxuLyoqXG4gKiBVc2UgRXh0ZW5zaW9uXG4gKi9cblxubWFya2VkLnVzZSA9IGZ1bmN0aW9uICgpIHtcbiAgdmFyIGV4dGVuc2lvbnMgPSBtYXJrZWQuZGVmYXVsdHMuZXh0ZW5zaW9ucyB8fCB7XG4gICAgcmVuZGVyZXJzOiB7fSxcbiAgICBjaGlsZFRva2Vuczoge31cbiAgfTtcbiAgZm9yICh2YXIgX2xlbiA9IGFyZ3VtZW50cy5sZW5ndGgsIGFyZ3MgPSBuZXcgQXJyYXkoX2xlbiksIF9rZXkgPSAwOyBfa2V5IDwgX2xlbjsgX2tleSsrKSB7XG4gICAgYXJnc1tfa2V5XSA9IGFyZ3VtZW50c1tfa2V5XTtcbiAgfVxuICBhcmdzLmZvckVhY2goZnVuY3Rpb24gKHBhY2spIHtcbiAgICAvLyBjb3B5IG9wdGlvbnMgdG8gbmV3IG9iamVjdFxuICAgIHZhciBvcHRzID0gbWVyZ2Uoe30sIHBhY2spO1xuXG4gICAgLy8gc2V0IGFzeW5jIHRvIHRydWUgaWYgaXQgd2FzIHNldCB0byB0cnVlIGJlZm9yZVxuICAgIG9wdHMuYXN5bmMgPSBtYXJrZWQuZGVmYXVsdHMuYXN5bmMgfHwgb3B0cy5hc3luYztcblxuICAgIC8vID09LS0gUGFyc2UgXCJhZGRvblwiIGV4dGVuc2lvbnMgLS09PSAvL1xuICAgIGlmIChwYWNrLmV4dGVuc2lvbnMpIHtcbiAgICAgIHBhY2suZXh0ZW5zaW9ucy5mb3JFYWNoKGZ1bmN0aW9uIChleHQpIHtcbiAgICAgICAgaWYgKCFleHQubmFtZSkge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcignZXh0ZW5zaW9uIG5hbWUgcmVxdWlyZWQnKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoZXh0LnJlbmRlcmVyKSB7XG4gICAgICAgICAgLy8gUmVuZGVyZXIgZXh0ZW5zaW9uc1xuICAgICAgICAgIHZhciBwcmV2UmVuZGVyZXIgPSBleHRlbnNpb25zLnJlbmRlcmVyc1tleHQubmFtZV07XG4gICAgICAgICAgaWYgKHByZXZSZW5kZXJlcikge1xuICAgICAgICAgICAgLy8gUmVwbGFjZSBleHRlbnNpb24gd2l0aCBmdW5jIHRvIHJ1biBuZXcgZXh0ZW5zaW9uIGJ1dCBmYWxsIGJhY2sgaWYgZmFsc2VcbiAgICAgICAgICAgIGV4dGVuc2lvbnMucmVuZGVyZXJzW2V4dC5uYW1lXSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgZm9yICh2YXIgX2xlbjIgPSBhcmd1bWVudHMubGVuZ3RoLCBhcmdzID0gbmV3IEFycmF5KF9sZW4yKSwgX2tleTIgPSAwOyBfa2V5MiA8IF9sZW4yOyBfa2V5MisrKSB7XG4gICAgICAgICAgICAgICAgYXJnc1tfa2V5Ml0gPSBhcmd1bWVudHNbX2tleTJdO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIHZhciByZXQgPSBleHQucmVuZGVyZXIuYXBwbHkodGhpcywgYXJncyk7XG4gICAgICAgICAgICAgIGlmIChyZXQgPT09IGZhbHNlKSB7XG4gICAgICAgICAgICAgICAgcmV0ID0gcHJldlJlbmRlcmVyLmFwcGx5KHRoaXMsIGFyZ3MpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIHJldHVybiByZXQ7XG4gICAgICAgICAgICB9O1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBleHRlbnNpb25zLnJlbmRlcmVyc1tleHQubmFtZV0gPSBleHQucmVuZGVyZXI7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmIChleHQudG9rZW5pemVyKSB7XG4gICAgICAgICAgLy8gVG9rZW5pemVyIEV4dGVuc2lvbnNcbiAgICAgICAgICBpZiAoIWV4dC5sZXZlbCB8fCBleHQubGV2ZWwgIT09ICdibG9jaycgJiYgZXh0LmxldmVsICE9PSAnaW5saW5lJykge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiZXh0ZW5zaW9uIGxldmVsIG11c3QgYmUgJ2Jsb2NrJyBvciAnaW5saW5lJ1wiKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKGV4dGVuc2lvbnNbZXh0LmxldmVsXSkge1xuICAgICAgICAgICAgZXh0ZW5zaW9uc1tleHQubGV2ZWxdLnVuc2hpZnQoZXh0LnRva2VuaXplcik7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGV4dGVuc2lvbnNbZXh0LmxldmVsXSA9IFtleHQudG9rZW5pemVyXTtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKGV4dC5zdGFydCkge1xuICAgICAgICAgICAgLy8gRnVuY3Rpb24gdG8gY2hlY2sgZm9yIHN0YXJ0IG9mIHRva2VuXG4gICAgICAgICAgICBpZiAoZXh0LmxldmVsID09PSAnYmxvY2snKSB7XG4gICAgICAgICAgICAgIGlmIChleHRlbnNpb25zLnN0YXJ0QmxvY2spIHtcbiAgICAgICAgICAgICAgICBleHRlbnNpb25zLnN0YXJ0QmxvY2sucHVzaChleHQuc3RhcnQpO1xuICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGV4dGVuc2lvbnMuc3RhcnRCbG9jayA9IFtleHQuc3RhcnRdO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2UgaWYgKGV4dC5sZXZlbCA9PT0gJ2lubGluZScpIHtcbiAgICAgICAgICAgICAgaWYgKGV4dGVuc2lvbnMuc3RhcnRJbmxpbmUpIHtcbiAgICAgICAgICAgICAgICBleHRlbnNpb25zLnN0YXJ0SW5saW5lLnB1c2goZXh0LnN0YXJ0KTtcbiAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBleHRlbnNpb25zLnN0YXJ0SW5saW5lID0gW2V4dC5zdGFydF07XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGV4dC5jaGlsZFRva2Vucykge1xuICAgICAgICAgIC8vIENoaWxkIHRva2VucyB0byBiZSB2aXNpdGVkIGJ5IHdhbGtUb2tlbnNcbiAgICAgICAgICBleHRlbnNpb25zLmNoaWxkVG9rZW5zW2V4dC5uYW1lXSA9IGV4dC5jaGlsZFRva2VucztcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgICBvcHRzLmV4dGVuc2lvbnMgPSBleHRlbnNpb25zO1xuICAgIH1cblxuICAgIC8vID09LS0gUGFyc2UgXCJvdmVyd3JpdGVcIiBleHRlbnNpb25zIC0tPT0gLy9cbiAgICBpZiAocGFjay5yZW5kZXJlcikge1xuICAgICAgKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIHJlbmRlcmVyID0gbWFya2VkLmRlZmF1bHRzLnJlbmRlcmVyIHx8IG5ldyBSZW5kZXJlcigpO1xuICAgICAgICB2YXIgX2xvb3AgPSBmdW5jdGlvbiBfbG9vcChwcm9wKSB7XG4gICAgICAgICAgdmFyIHByZXZSZW5kZXJlciA9IHJlbmRlcmVyW3Byb3BdO1xuICAgICAgICAgIC8vIFJlcGxhY2UgcmVuZGVyZXIgd2l0aCBmdW5jIHRvIHJ1biBleHRlbnNpb24sIGJ1dCBmYWxsIGJhY2sgaWYgZmFsc2VcbiAgICAgICAgICByZW5kZXJlcltwcm9wXSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGZvciAodmFyIF9sZW4zID0gYXJndW1lbnRzLmxlbmd0aCwgYXJncyA9IG5ldyBBcnJheShfbGVuMyksIF9rZXkzID0gMDsgX2tleTMgPCBfbGVuMzsgX2tleTMrKykge1xuICAgICAgICAgICAgICBhcmdzW19rZXkzXSA9IGFyZ3VtZW50c1tfa2V5M107XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB2YXIgcmV0ID0gcGFjay5yZW5kZXJlcltwcm9wXS5hcHBseShyZW5kZXJlciwgYXJncyk7XG4gICAgICAgICAgICBpZiAocmV0ID09PSBmYWxzZSkge1xuICAgICAgICAgICAgICByZXQgPSBwcmV2UmVuZGVyZXIuYXBwbHkocmVuZGVyZXIsIGFyZ3MpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHJldDtcbiAgICAgICAgICB9O1xuICAgICAgICB9O1xuICAgICAgICBmb3IgKHZhciBwcm9wIGluIHBhY2sucmVuZGVyZXIpIHtcbiAgICAgICAgICBfbG9vcChwcm9wKTtcbiAgICAgICAgfVxuICAgICAgICBvcHRzLnJlbmRlcmVyID0gcmVuZGVyZXI7XG4gICAgICB9KSgpO1xuICAgIH1cbiAgICBpZiAocGFjay50b2tlbml6ZXIpIHtcbiAgICAgIChmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciB0b2tlbml6ZXIgPSBtYXJrZWQuZGVmYXVsdHMudG9rZW5pemVyIHx8IG5ldyBUb2tlbml6ZXIoKTtcbiAgICAgICAgdmFyIF9sb29wMiA9IGZ1bmN0aW9uIF9sb29wMihwcm9wKSB7XG4gICAgICAgICAgdmFyIHByZXZUb2tlbml6ZXIgPSB0b2tlbml6ZXJbcHJvcF07XG4gICAgICAgICAgLy8gUmVwbGFjZSB0b2tlbml6ZXIgd2l0aCBmdW5jIHRvIHJ1biBleHRlbnNpb24sIGJ1dCBmYWxsIGJhY2sgaWYgZmFsc2VcbiAgICAgICAgICB0b2tlbml6ZXJbcHJvcF0gPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBmb3IgKHZhciBfbGVuNCA9IGFyZ3VtZW50cy5sZW5ndGgsIGFyZ3MgPSBuZXcgQXJyYXkoX2xlbjQpLCBfa2V5NCA9IDA7IF9rZXk0IDwgX2xlbjQ7IF9rZXk0KyspIHtcbiAgICAgICAgICAgICAgYXJnc1tfa2V5NF0gPSBhcmd1bWVudHNbX2tleTRdO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdmFyIHJldCA9IHBhY2sudG9rZW5pemVyW3Byb3BdLmFwcGx5KHRva2VuaXplciwgYXJncyk7XG4gICAgICAgICAgICBpZiAocmV0ID09PSBmYWxzZSkge1xuICAgICAgICAgICAgICByZXQgPSBwcmV2VG9rZW5pemVyLmFwcGx5KHRva2VuaXplciwgYXJncyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gcmV0O1xuICAgICAgICAgIH07XG4gICAgICAgIH07XG4gICAgICAgIGZvciAodmFyIHByb3AgaW4gcGFjay50b2tlbml6ZXIpIHtcbiAgICAgICAgICBfbG9vcDIocHJvcCk7XG4gICAgICAgIH1cbiAgICAgICAgb3B0cy50b2tlbml6ZXIgPSB0b2tlbml6ZXI7XG4gICAgICB9KSgpO1xuICAgIH1cblxuICAgIC8vID09LS0gUGFyc2UgV2Fsa1Rva2VucyBleHRlbnNpb25zIC0tPT0gLy9cbiAgICBpZiAocGFjay53YWxrVG9rZW5zKSB7XG4gICAgICB2YXIgX3dhbGtUb2tlbnMgPSBtYXJrZWQuZGVmYXVsdHMud2Fsa1Rva2VucztcbiAgICAgIG9wdHMud2Fsa1Rva2VucyA9IGZ1bmN0aW9uICh0b2tlbikge1xuICAgICAgICB2YXIgdmFsdWVzID0gW107XG4gICAgICAgIHZhbHVlcy5wdXNoKHBhY2sud2Fsa1Rva2Vucy5jYWxsKHRoaXMsIHRva2VuKSk7XG4gICAgICAgIGlmIChfd2Fsa1Rva2Vucykge1xuICAgICAgICAgIHZhbHVlcyA9IHZhbHVlcy5jb25jYXQoX3dhbGtUb2tlbnMuY2FsbCh0aGlzLCB0b2tlbikpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB2YWx1ZXM7XG4gICAgICB9O1xuICAgIH1cbiAgICBtYXJrZWQuc2V0T3B0aW9ucyhvcHRzKTtcbiAgfSk7XG59O1xuXG4vKipcbiAqIFJ1biBjYWxsYmFjayBmb3IgZXZlcnkgdG9rZW5cbiAqL1xuXG5tYXJrZWQud2Fsa1Rva2VucyA9IGZ1bmN0aW9uICh0b2tlbnMsIGNhbGxiYWNrKSB7XG4gIHZhciB2YWx1ZXMgPSBbXTtcbiAgdmFyIF9sb29wMyA9IGZ1bmN0aW9uIF9sb29wMygpIHtcbiAgICB2YXIgdG9rZW4gPSBfc3RlcC52YWx1ZTtcbiAgICB2YWx1ZXMgPSB2YWx1ZXMuY29uY2F0KGNhbGxiYWNrLmNhbGwobWFya2VkLCB0b2tlbikpO1xuICAgIHN3aXRjaCAodG9rZW4udHlwZSkge1xuICAgICAgY2FzZSAndGFibGUnOlxuICAgICAgICB7XG4gICAgICAgICAgZm9yICh2YXIgX2l0ZXJhdG9yMiA9IF9jcmVhdGVGb3JPZkl0ZXJhdG9ySGVscGVyTG9vc2UodG9rZW4uaGVhZGVyKSwgX3N0ZXAyOyAhKF9zdGVwMiA9IF9pdGVyYXRvcjIoKSkuZG9uZTspIHtcbiAgICAgICAgICAgIHZhciBjZWxsID0gX3N0ZXAyLnZhbHVlO1xuICAgICAgICAgICAgdmFsdWVzID0gdmFsdWVzLmNvbmNhdChtYXJrZWQud2Fsa1Rva2VucyhjZWxsLnRva2VucywgY2FsbGJhY2spKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgZm9yICh2YXIgX2l0ZXJhdG9yMyA9IF9jcmVhdGVGb3JPZkl0ZXJhdG9ySGVscGVyTG9vc2UodG9rZW4ucm93cyksIF9zdGVwMzsgIShfc3RlcDMgPSBfaXRlcmF0b3IzKCkpLmRvbmU7KSB7XG4gICAgICAgICAgICB2YXIgcm93ID0gX3N0ZXAzLnZhbHVlO1xuICAgICAgICAgICAgZm9yICh2YXIgX2l0ZXJhdG9yNCA9IF9jcmVhdGVGb3JPZkl0ZXJhdG9ySGVscGVyTG9vc2Uocm93KSwgX3N0ZXA0OyAhKF9zdGVwNCA9IF9pdGVyYXRvcjQoKSkuZG9uZTspIHtcbiAgICAgICAgICAgICAgdmFyIF9jZWxsID0gX3N0ZXA0LnZhbHVlO1xuICAgICAgICAgICAgICB2YWx1ZXMgPSB2YWx1ZXMuY29uY2F0KG1hcmtlZC53YWxrVG9rZW5zKF9jZWxsLnRva2VucywgY2FsbGJhY2spKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgIGNhc2UgJ2xpc3QnOlxuICAgICAgICB7XG4gICAgICAgICAgdmFsdWVzID0gdmFsdWVzLmNvbmNhdChtYXJrZWQud2Fsa1Rva2Vucyh0b2tlbi5pdGVtcywgY2FsbGJhY2spKTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgZGVmYXVsdDpcbiAgICAgICAge1xuICAgICAgICAgIGlmIChtYXJrZWQuZGVmYXVsdHMuZXh0ZW5zaW9ucyAmJiBtYXJrZWQuZGVmYXVsdHMuZXh0ZW5zaW9ucy5jaGlsZFRva2VucyAmJiBtYXJrZWQuZGVmYXVsdHMuZXh0ZW5zaW9ucy5jaGlsZFRva2Vuc1t0b2tlbi50eXBlXSkge1xuICAgICAgICAgICAgLy8gV2FsayBhbnkgZXh0ZW5zaW9uc1xuICAgICAgICAgICAgbWFya2VkLmRlZmF1bHRzLmV4dGVuc2lvbnMuY2hpbGRUb2tlbnNbdG9rZW4udHlwZV0uZm9yRWFjaChmdW5jdGlvbiAoY2hpbGRUb2tlbnMpIHtcbiAgICAgICAgICAgICAgdmFsdWVzID0gdmFsdWVzLmNvbmNhdChtYXJrZWQud2Fsa1Rva2Vucyh0b2tlbltjaGlsZFRva2Vuc10sIGNhbGxiYWNrKSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9IGVsc2UgaWYgKHRva2VuLnRva2Vucykge1xuICAgICAgICAgICAgdmFsdWVzID0gdmFsdWVzLmNvbmNhdChtYXJrZWQud2Fsa1Rva2Vucyh0b2tlbi50b2tlbnMsIGNhbGxiYWNrKSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuICB9O1xuICBmb3IgKHZhciBfaXRlcmF0b3IgPSBfY3JlYXRlRm9yT2ZJdGVyYXRvckhlbHBlckxvb3NlKHRva2VucyksIF9zdGVwOyAhKF9zdGVwID0gX2l0ZXJhdG9yKCkpLmRvbmU7KSB7XG4gICAgX2xvb3AzKCk7XG4gIH1cbiAgcmV0dXJuIHZhbHVlcztcbn07XG5cbi8qKlxuICogUGFyc2UgSW5saW5lXG4gKiBAcGFyYW0ge3N0cmluZ30gc3JjXG4gKi9cbm1hcmtlZC5wYXJzZUlubGluZSA9IGZ1bmN0aW9uIChzcmMsIG9wdCkge1xuICAvLyB0aHJvdyBlcnJvciBpbiBjYXNlIG9mIG5vbiBzdHJpbmcgaW5wdXRcbiAgaWYgKHR5cGVvZiBzcmMgPT09ICd1bmRlZmluZWQnIHx8IHNyYyA9PT0gbnVsbCkge1xuICAgIHRocm93IG5ldyBFcnJvcignbWFya2VkLnBhcnNlSW5saW5lKCk6IGlucHV0IHBhcmFtZXRlciBpcyB1bmRlZmluZWQgb3IgbnVsbCcpO1xuICB9XG4gIGlmICh0eXBlb2Ygc3JjICE9PSAnc3RyaW5nJykge1xuICAgIHRocm93IG5ldyBFcnJvcignbWFya2VkLnBhcnNlSW5saW5lKCk6IGlucHV0IHBhcmFtZXRlciBpcyBvZiB0eXBlICcgKyBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwoc3JjKSArICcsIHN0cmluZyBleHBlY3RlZCcpO1xuICB9XG4gIG9wdCA9IG1lcmdlKHt9LCBtYXJrZWQuZGVmYXVsdHMsIG9wdCB8fCB7fSk7XG4gIGNoZWNrU2FuaXRpemVEZXByZWNhdGlvbihvcHQpO1xuICB0cnkge1xuICAgIHZhciB0b2tlbnMgPSBMZXhlci5sZXhJbmxpbmUoc3JjLCBvcHQpO1xuICAgIGlmIChvcHQud2Fsa1Rva2Vucykge1xuICAgICAgbWFya2VkLndhbGtUb2tlbnModG9rZW5zLCBvcHQud2Fsa1Rva2Vucyk7XG4gICAgfVxuICAgIHJldHVybiBQYXJzZXIucGFyc2VJbmxpbmUodG9rZW5zLCBvcHQpO1xuICB9IGNhdGNoIChlKSB7XG4gICAgZS5tZXNzYWdlICs9ICdcXG5QbGVhc2UgcmVwb3J0IHRoaXMgdG8gaHR0cHM6Ly9naXRodWIuY29tL21hcmtlZGpzL21hcmtlZC4nO1xuICAgIGlmIChvcHQuc2lsZW50KSB7XG4gICAgICByZXR1cm4gJzxwPkFuIGVycm9yIG9jY3VycmVkOjwvcD48cHJlPicgKyBlc2NhcGUoZS5tZXNzYWdlICsgJycsIHRydWUpICsgJzwvcHJlPic7XG4gICAgfVxuICAgIHRocm93IGU7XG4gIH1cbn07XG5cbi8qKlxuICogRXhwb3NlXG4gKi9cbm1hcmtlZC5QYXJzZXIgPSBQYXJzZXI7XG5tYXJrZWQucGFyc2VyID0gUGFyc2VyLnBhcnNlO1xubWFya2VkLlJlbmRlcmVyID0gUmVuZGVyZXI7XG5tYXJrZWQuVGV4dFJlbmRlcmVyID0gVGV4dFJlbmRlcmVyO1xubWFya2VkLkxleGVyID0gTGV4ZXI7XG5tYXJrZWQubGV4ZXIgPSBMZXhlci5sZXg7XG5tYXJrZWQuVG9rZW5pemVyID0gVG9rZW5pemVyO1xubWFya2VkLlNsdWdnZXIgPSBTbHVnZ2VyO1xubWFya2VkLnBhcnNlID0gbWFya2VkO1xudmFyIG9wdGlvbnMgPSBtYXJrZWQub3B0aW9ucztcbnZhciBzZXRPcHRpb25zID0gbWFya2VkLnNldE9wdGlvbnM7XG52YXIgdXNlID0gbWFya2VkLnVzZTtcbnZhciB3YWxrVG9rZW5zID0gbWFya2VkLndhbGtUb2tlbnM7XG52YXIgcGFyc2VJbmxpbmUgPSBtYXJrZWQucGFyc2VJbmxpbmU7XG52YXIgcGFyc2UgPSBtYXJrZWQ7XG52YXIgcGFyc2VyID0gUGFyc2VyLnBhcnNlO1xudmFyIGxleGVyID0gTGV4ZXIubGV4O1xuXG5leHBvcnRzLkxleGVyID0gTGV4ZXI7XG5leHBvcnRzLlBhcnNlciA9IFBhcnNlcjtcbmV4cG9ydHMuUmVuZGVyZXIgPSBSZW5kZXJlcjtcbmV4cG9ydHMuU2x1Z2dlciA9IFNsdWdnZXI7XG5leHBvcnRzLlRleHRSZW5kZXJlciA9IFRleHRSZW5kZXJlcjtcbmV4cG9ydHMuVG9rZW5pemVyID0gVG9rZW5pemVyO1xuZXhwb3J0cy5nZXREZWZhdWx0cyA9IGdldERlZmF1bHRzO1xuZXhwb3J0cy5sZXhlciA9IGxleGVyO1xuZXhwb3J0cy5tYXJrZWQgPSBtYXJrZWQ7XG5leHBvcnRzLm9wdGlvbnMgPSBvcHRpb25zO1xuZXhwb3J0cy5wYXJzZSA9IHBhcnNlO1xuZXhwb3J0cy5wYXJzZUlubGluZSA9IHBhcnNlSW5saW5lO1xuZXhwb3J0cy5wYXJzZXIgPSBwYXJzZXI7XG5leHBvcnRzLnNldE9wdGlvbnMgPSBzZXRPcHRpb25zO1xuZXhwb3J0cy51c2UgPSB1c2U7XG5leHBvcnRzLndhbGtUb2tlbnMgPSB3YWxrVG9rZW5zO1xuIiwiLy8gVGhlIG1vZHVsZSBjYWNoZVxudmFyIF9fd2VicGFja19tb2R1bGVfY2FjaGVfXyA9IHt9O1xuXG4vLyBUaGUgcmVxdWlyZSBmdW5jdGlvblxuZnVuY3Rpb24gX193ZWJwYWNrX3JlcXVpcmVfXyhtb2R1bGVJZCkge1xuXHQvLyBDaGVjayBpZiBtb2R1bGUgaXMgaW4gY2FjaGVcblx0dmFyIGNhY2hlZE1vZHVsZSA9IF9fd2VicGFja19tb2R1bGVfY2FjaGVfX1ttb2R1bGVJZF07XG5cdGlmIChjYWNoZWRNb2R1bGUgIT09IHVuZGVmaW5lZCkge1xuXHRcdHJldHVybiBjYWNoZWRNb2R1bGUuZXhwb3J0cztcblx0fVxuXHQvLyBDcmVhdGUgYSBuZXcgbW9kdWxlIChhbmQgcHV0IGl0IGludG8gdGhlIGNhY2hlKVxuXHR2YXIgbW9kdWxlID0gX193ZWJwYWNrX21vZHVsZV9jYWNoZV9fW21vZHVsZUlkXSA9IHtcblx0XHRpZDogbW9kdWxlSWQsXG5cdFx0bG9hZGVkOiBmYWxzZSxcblx0XHRleHBvcnRzOiB7fVxuXHR9O1xuXG5cdC8vIEV4ZWN1dGUgdGhlIG1vZHVsZSBmdW5jdGlvblxuXHRfX3dlYnBhY2tfbW9kdWxlc19fW21vZHVsZUlkXS5jYWxsKG1vZHVsZS5leHBvcnRzLCBtb2R1bGUsIG1vZHVsZS5leHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKTtcblxuXHQvLyBGbGFnIHRoZSBtb2R1bGUgYXMgbG9hZGVkXG5cdG1vZHVsZS5sb2FkZWQgPSB0cnVlO1xuXG5cdC8vIFJldHVybiB0aGUgZXhwb3J0cyBvZiB0aGUgbW9kdWxlXG5cdHJldHVybiBtb2R1bGUuZXhwb3J0cztcbn1cblxuIiwiX193ZWJwYWNrX3JlcXVpcmVfXy5nID0gKGZ1bmN0aW9uKCkge1xuXHRpZiAodHlwZW9mIGdsb2JhbFRoaXMgPT09ICdvYmplY3QnKSByZXR1cm4gZ2xvYmFsVGhpcztcblx0dHJ5IHtcblx0XHRyZXR1cm4gdGhpcyB8fCBuZXcgRnVuY3Rpb24oJ3JldHVybiB0aGlzJykoKTtcblx0fSBjYXRjaCAoZSkge1xuXHRcdGlmICh0eXBlb2Ygd2luZG93ID09PSAnb2JqZWN0JykgcmV0dXJuIHdpbmRvdztcblx0fVxufSkoKTsiLCJfX3dlYnBhY2tfcmVxdWlyZV9fLm5tZCA9IChtb2R1bGUpID0+IHtcblx0bW9kdWxlLnBhdGhzID0gW107XG5cdGlmICghbW9kdWxlLmNoaWxkcmVuKSBtb2R1bGUuY2hpbGRyZW4gPSBbXTtcblx0cmV0dXJuIG1vZHVsZTtcbn07IiwiIiwiLy8gc3RhcnR1cFxuLy8gTG9hZCBlbnRyeSBtb2R1bGUgYW5kIHJldHVybiBleHBvcnRzXG4vLyBUaGlzIGVudHJ5IG1vZHVsZSBpcyByZWZlcmVuY2VkIGJ5IG90aGVyIG1vZHVsZXMgc28gaXQgY2FuJ3QgYmUgaW5saW5lZFxudmFyIF9fd2VicGFja19leHBvcnRzX18gPSBfX3dlYnBhY2tfcmVxdWlyZV9fKFwiLi9zcmMvY2xpZW50LnRzXCIpO1xuIiwiIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9