add help window, accessible via `?`
[apps/outliner/.git] / public / assets / bundle.js
1 /******/ (() => { // webpackBootstrap
2 /******/        var __webpack_modules__ = ({
3
4 /***/ "./node_modules/keyboardjs/dist/keyboard.js":
5 /*!**************************************************!*\
6   !*** ./node_modules/keyboardjs/dist/keyboard.js ***!
7   \**************************************************/
8 /***/ (function(module, __unused_webpack_exports, __webpack_require__) {
9
10 (function (global, factory) {
11    true ? module.exports = factory() :
12   0;
13 }(this, (function () { 'use strict';
14
15   function _typeof(obj) {
16     "@babel/helpers - typeof";
17
18     if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") {
19       _typeof = function (obj) {
20         return typeof obj;
21       };
22     } else {
23       _typeof = function (obj) {
24         return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
25       };
26     }
27
28     return _typeof(obj);
29   }
30
31   function _classCallCheck(instance, Constructor) {
32     if (!(instance instanceof Constructor)) {
33       throw new TypeError("Cannot call a class as a function");
34     }
35   }
36
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);
44     }
45   }
46
47   function _createClass(Constructor, protoProps, staticProps) {
48     if (protoProps) _defineProperties(Constructor.prototype, protoProps);
49     if (staticProps) _defineProperties(Constructor, staticProps);
50     return Constructor;
51   }
52
53   function _toConsumableArray(arr) {
54     return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread();
55   }
56
57   function _arrayWithoutHoles(arr) {
58     if (Array.isArray(arr)) return _arrayLikeToArray(arr);
59   }
60
61   function _iterableToArray(iter) {
62     if (typeof Symbol !== "undefined" && Symbol.iterator in Object(iter)) return Array.from(iter);
63   }
64
65   function _unsupportedIterableToArray(o, minLen) {
66     if (!o) return;
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);
72   }
73
74   function _arrayLikeToArray(arr, len) {
75     if (len == null || len > arr.length) len = arr.length;
76
77     for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i];
78
79     return arr2;
80   }
81
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.");
84   }
85
86   var KeyCombo = /*#__PURE__*/function () {
87     function KeyCombo(keyComboStr) {
88       _classCallCheck(this, KeyCombo);
89
90       this.sourceStr = keyComboStr;
91       this.subCombos = KeyCombo.parseComboStr(keyComboStr);
92       this.keyNames = this.subCombos.reduce(function (memo, nextSubCombo) {
93         return memo.concat(nextSubCombo);
94       }, []);
95     }
96
97     _createClass(KeyCombo, [{
98       key: "check",
99       value: function check(pressedKeyNames) {
100         var startingKeyNameIndex = 0;
101
102         for (var i = 0; i < this.subCombos.length; i += 1) {
103           startingKeyNameIndex = this._checkSubCombo(this.subCombos[i], startingKeyNameIndex, pressedKeyNames);
104
105           if (startingKeyNameIndex === -1) {
106             return false;
107           }
108         }
109
110         return true;
111       }
112     }, {
113       key: "isEqual",
114       value: function isEqual(otherKeyCombo) {
115         if (!otherKeyCombo || typeof otherKeyCombo !== 'string' && _typeof(otherKeyCombo) !== 'object') {
116           return false;
117         }
118
119         if (typeof otherKeyCombo === 'string') {
120           otherKeyCombo = new KeyCombo(otherKeyCombo);
121         }
122
123         if (this.subCombos.length !== otherKeyCombo.subCombos.length) {
124           return false;
125         }
126
127         for (var i = 0; i < this.subCombos.length; i += 1) {
128           if (this.subCombos[i].length !== otherKeyCombo.subCombos[i].length) {
129             return false;
130           }
131         }
132
133         for (var _i = 0; _i < this.subCombos.length; _i += 1) {
134           var subCombo = this.subCombos[_i];
135
136           var otherSubCombo = otherKeyCombo.subCombos[_i].slice(0);
137
138           for (var j = 0; j < subCombo.length; j += 1) {
139             var keyName = subCombo[j];
140             var index = otherSubCombo.indexOf(keyName);
141
142             if (index > -1) {
143               otherSubCombo.splice(index, 1);
144             }
145           }
146
147           if (otherSubCombo.length !== 0) {
148             return false;
149           }
150         }
151
152         return true;
153       }
154     }, {
155       key: "_checkSubCombo",
156       value: function _checkSubCombo(subCombo, startingKeyNameIndex, pressedKeyNames) {
157         subCombo = subCombo.slice(0);
158         pressedKeyNames = pressedKeyNames.slice(startingKeyNameIndex);
159         var endIndex = startingKeyNameIndex;
160
161         for (var i = 0; i < subCombo.length; i += 1) {
162           var keyName = subCombo[i];
163
164           if (keyName[0] === '\\') {
165             var escapedKeyName = keyName.slice(1);
166
167             if (escapedKeyName === KeyCombo.comboDeliminator || escapedKeyName === KeyCombo.keyDeliminator) {
168               keyName = escapedKeyName;
169             }
170           }
171
172           var index = pressedKeyNames.indexOf(keyName);
173
174           if (index > -1) {
175             subCombo.splice(i, 1);
176             i -= 1;
177
178             if (index > endIndex) {
179               endIndex = index;
180             }
181
182             if (subCombo.length === 0) {
183               return endIndex;
184             }
185           }
186         }
187
188         return -1;
189       }
190     }]);
191
192     return KeyCombo;
193   }();
194   KeyCombo.comboDeliminator = '>';
195   KeyCombo.keyDeliminator = '+';
196
197   KeyCombo.parseComboStr = function (keyComboStr) {
198     var subComboStrs = KeyCombo._splitStr(keyComboStr, KeyCombo.comboDeliminator);
199
200     var combo = [];
201
202     for (var i = 0; i < subComboStrs.length; i += 1) {
203       combo.push(KeyCombo._splitStr(subComboStrs[i], KeyCombo.keyDeliminator));
204     }
205
206     return combo;
207   };
208
209   KeyCombo._splitStr = function (str, deliminator) {
210     var s = str;
211     var d = deliminator;
212     var c = '';
213     var ca = [];
214
215     for (var ci = 0; ci < s.length; ci += 1) {
216       if (ci > 0 && s[ci] === d && s[ci - 1] !== '\\') {
217         ca.push(c.trim());
218         c = '';
219         ci += 1;
220       }
221
222       c += s[ci];
223     }
224
225     if (c) {
226       ca.push(c.trim());
227     }
228
229     return ca;
230   };
231
232   var Locale = /*#__PURE__*/function () {
233     function Locale(name) {
234       _classCallCheck(this, Locale);
235
236       this.localeName = name;
237       this.activeTargetKeys = [];
238       this.pressedKeys = [];
239       this._appliedMacros = [];
240       this._keyMap = {};
241       this._killKeyCodes = [];
242       this._macros = [];
243     }
244
245     _createClass(Locale, [{
246       key: "bindKeyCode",
247       value: function bindKeyCode(keyCode, keyNames) {
248         if (typeof keyNames === 'string') {
249           keyNames = [keyNames];
250         }
251
252         this._keyMap[keyCode] = keyNames;
253       }
254     }, {
255       key: "bindMacro",
256       value: function bindMacro(keyComboStr, keyNames) {
257         if (typeof keyNames === 'string') {
258           keyNames = [keyNames];
259         }
260
261         var handler = null;
262
263         if (typeof keyNames === 'function') {
264           handler = keyNames;
265           keyNames = null;
266         }
267
268         var macro = {
269           keyCombo: new KeyCombo(keyComboStr),
270           keyNames: keyNames,
271           handler: handler
272         };
273
274         this._macros.push(macro);
275       }
276     }, {
277       key: "getKeyCodes",
278       value: function getKeyCodes(keyName) {
279         var keyCodes = [];
280
281         for (var keyCode in this._keyMap) {
282           var index = this._keyMap[keyCode].indexOf(keyName);
283
284           if (index > -1) {
285             keyCodes.push(keyCode | 0);
286           }
287         }
288
289         return keyCodes;
290       }
291     }, {
292       key: "getKeyNames",
293       value: function getKeyNames(keyCode) {
294         return this._keyMap[keyCode] || [];
295       }
296     }, {
297       key: "setKillKey",
298       value: function setKillKey(keyCode) {
299         if (typeof keyCode === 'string') {
300           var keyCodes = this.getKeyCodes(keyCode);
301
302           for (var i = 0; i < keyCodes.length; i += 1) {
303             this.setKillKey(keyCodes[i]);
304           }
305
306           return;
307         }
308
309         this._killKeyCodes.push(keyCode);
310       }
311     }, {
312       key: "pressKey",
313       value: function pressKey(keyCode) {
314         if (typeof keyCode === 'string') {
315           var keyCodes = this.getKeyCodes(keyCode);
316
317           for (var i = 0; i < keyCodes.length; i += 1) {
318             this.pressKey(keyCodes[i]);
319           }
320
321           return;
322         }
323
324         this.activeTargetKeys.length = 0;
325         var keyNames = this.getKeyNames(keyCode);
326
327         for (var _i = 0; _i < keyNames.length; _i += 1) {
328           this.activeTargetKeys.push(keyNames[_i]);
329
330           if (this.pressedKeys.indexOf(keyNames[_i]) === -1) {
331             this.pressedKeys.push(keyNames[_i]);
332           }
333         }
334
335         this._applyMacros();
336       }
337     }, {
338       key: "releaseKey",
339       value: function releaseKey(keyCode) {
340         if (typeof keyCode === 'string') {
341           var keyCodes = this.getKeyCodes(keyCode);
342
343           for (var i = 0; i < keyCodes.length; i += 1) {
344             this.releaseKey(keyCodes[i]);
345           }
346         } else {
347           var keyNames = this.getKeyNames(keyCode);
348
349           var killKeyCodeIndex = this._killKeyCodes.indexOf(keyCode);
350
351           if (killKeyCodeIndex !== -1) {
352             this.pressedKeys.length = 0;
353           } else {
354             for (var _i2 = 0; _i2 < keyNames.length; _i2 += 1) {
355               var index = this.pressedKeys.indexOf(keyNames[_i2]);
356
357               if (index > -1) {
358                 this.pressedKeys.splice(index, 1);
359               }
360             }
361           }
362
363           this.activeTargetKeys.length = 0;
364
365           this._clearMacros();
366         }
367       }
368     }, {
369       key: "_applyMacros",
370       value: function _applyMacros() {
371         var macros = this._macros.slice(0);
372
373         for (var i = 0; i < macros.length; i += 1) {
374           var macro = macros[i];
375
376           if (macro.keyCombo.check(this.pressedKeys)) {
377             if (macro.handler) {
378               macro.keyNames = macro.handler(this.pressedKeys);
379             }
380
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]);
384               }
385             }
386
387             this._appliedMacros.push(macro);
388           }
389         }
390       }
391     }, {
392       key: "_clearMacros",
393       value: function _clearMacros() {
394         for (var i = 0; i < this._appliedMacros.length; i += 1) {
395           var macro = this._appliedMacros[i];
396
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]);
400
401               if (index > -1) {
402                 this.pressedKeys.splice(index, 1);
403               }
404             }
405
406             if (macro.handler) {
407               macro.keyNames = null;
408             }
409
410             this._appliedMacros.splice(i, 1);
411
412             i -= 1;
413           }
414         }
415       }
416     }]);
417
418     return Locale;
419   }();
420
421   var Keyboard = /*#__PURE__*/function () {
422     function Keyboard(targetWindow, targetElement, targetPlatform, targetUserAgent) {
423       _classCallCheck(this, Keyboard);
424
425       this._locale = null;
426       this._currentContext = '';
427       this._contexts = {};
428       this._listeners = [];
429       this._appliedListeners = [];
430       this._locales = {};
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
446       };
447       this.setContext('global');
448     }
449
450     _createClass(Keyboard, [{
451       key: "setLocale",
452       value: function setLocale(localeName, localeBuilder) {
453         var locale = null;
454
455         if (typeof localeName === 'string') {
456           if (localeBuilder) {
457             locale = new Locale(localeName);
458             localeBuilder(locale, this._targetPlatform, this._targetUserAgent);
459           } else {
460             locale = this._locales[localeName] || null;
461           }
462         } else {
463           locale = localeName;
464           localeName = locale._localeName;
465         }
466
467         this._locale = locale;
468         this._locales[localeName] = locale;
469
470         if (locale) {
471           this._locale.pressedKeys = locale.pressedKeys;
472         }
473
474         return this;
475       }
476     }, {
477       key: "getLocale",
478       value: function getLocale(localName) {
479         localName || (localName = this._locale.localeName);
480         return this._locales[localName] || null;
481       }
482     }, {
483       key: "bind",
484       value: function bind(keyComboStr, pressHandler, releaseHandler, preventRepeatByDefault) {
485         if (keyComboStr === null || typeof keyComboStr === 'function') {
486           preventRepeatByDefault = releaseHandler;
487           releaseHandler = pressHandler;
488           pressHandler = keyComboStr;
489           keyComboStr = null;
490         }
491
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);
495           }
496
497           return this;
498         }
499
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
507         });
508
509         return this;
510       }
511     }, {
512       key: "addListener",
513       value: function addListener(keyComboStr, pressHandler, releaseHandler, preventRepeatByDefault) {
514         return this.bind(keyComboStr, pressHandler, releaseHandler, preventRepeatByDefault);
515       }
516     }, {
517       key: "on",
518       value: function on(keyComboStr, pressHandler, releaseHandler, preventRepeatByDefault) {
519         return this.bind(keyComboStr, pressHandler, releaseHandler, preventRepeatByDefault);
520       }
521     }, {
522       key: "bindPress",
523       value: function bindPress(keyComboStr, pressHandler, preventRepeatByDefault) {
524         return this.bind(keyComboStr, pressHandler, null, preventRepeatByDefault);
525       }
526     }, {
527       key: "bindRelease",
528       value: function bindRelease(keyComboStr, releaseHandler) {
529         return this.bind(keyComboStr, null, releaseHandler, preventRepeatByDefault);
530       }
531     }, {
532       key: "unbind",
533       value: function unbind(keyComboStr, pressHandler, releaseHandler) {
534         if (keyComboStr === null || typeof keyComboStr === 'function') {
535           releaseHandler = pressHandler;
536           pressHandler = keyComboStr;
537           keyComboStr = null;
538         }
539
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);
543           }
544
545           return this;
546         }
547
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;
553
554           if (comboMatches && pressHandlerMatches && releaseHandlerMatches) {
555             this._listeners.splice(_i, 1);
556
557             _i -= 1;
558           }
559         }
560
561         return this;
562       }
563     }, {
564       key: "removeListener",
565       value: function removeListener(keyComboStr, pressHandler, releaseHandler) {
566         return this.unbind(keyComboStr, pressHandler, releaseHandler);
567       }
568     }, {
569       key: "off",
570       value: function off(keyComboStr, pressHandler, releaseHandler) {
571         return this.unbind(keyComboStr, pressHandler, releaseHandler);
572       }
573     }, {
574       key: "setContext",
575       value: function setContext(contextName) {
576         if (this._locale) {
577           this.releaseAllKeys();
578         }
579
580         if (!this._contexts[contextName]) {
581           var globalContext = this._contexts.global;
582           this._contexts[contextName] = {
583             listeners: [],
584             targetWindow: globalContext.targetWindow,
585             targetElement: globalContext.targetElement,
586             targetPlatform: globalContext.targetPlatform,
587             targetUserAgent: globalContext.targetUserAgent
588           };
589         }
590
591         var context = this._contexts[contextName];
592         this._currentContext = contextName;
593         this._listeners = context.listeners;
594         this.stop();
595         this.watch(context.targetWindow, context.targetElement, context.targetPlatform, context.targetUserAgent);
596         return this;
597       }
598     }, {
599       key: "getContext",
600       value: function getContext() {
601         return this._currentContext;
602       }
603     }, {
604       key: "withContext",
605       value: function withContext(contextName, callback) {
606         var previousContextName = this.getContext();
607         this.setContext(contextName);
608         callback();
609         this.setContext(previousContextName);
610         return this;
611       }
612     }, {
613       key: "watch",
614       value: function watch(targetWindow, targetElement, targetPlatform, targetUserAgent) {
615         var _this = this;
616
617         this.stop();
618         var win = typeof globalThis !== 'undefined' ? globalThis : typeof __webpack_require__.g !== 'undefined' ? __webpack_require__.g : typeof window !== 'undefined' ? window : {};
619
620         if (!targetWindow) {
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') {
625               return;
626             }
627
628             throw new Error('Cannot find window functions addEventListener or attachEvent.');
629           }
630
631           targetWindow = win;
632         } // Handle element bindings where a target window is not passed
633
634
635         if (typeof targetWindow.nodeType === 'number') {
636           targetUserAgent = targetPlatform;
637           targetPlatform = targetElement;
638           targetElement = targetWindow;
639           targetWindow = win;
640         }
641
642         if (!targetWindow.addEventListener && !targetWindow.attachEvent) {
643           throw new Error('Cannot find addEventListener or attachEvent methods on targetWindow.');
644         }
645
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);
652
653         this._targetKeyDownBinding = function (event) {
654           _this.pressKey(event.keyCode, event);
655
656           _this._handleCommandBug(event, platform);
657         };
658
659         this._targetKeyUpBinding = function (event) {
660           _this.releaseKey(event.keyCode, event);
661         };
662
663         this._targetResetBinding = function (event) {
664           _this.releaseAllKeys(event);
665         };
666
667         this._bindEvent(targetElement, 'keydown', this._targetKeyDownBinding);
668
669         this._bindEvent(targetElement, 'keyup', this._targetKeyUpBinding);
670
671         this._bindEvent(targetWindow, 'focus', this._targetResetBinding);
672
673         this._bindEvent(targetWindow, 'blur', this._targetResetBinding);
674
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;
684         return this;
685       }
686     }, {
687       key: "stop",
688       value: function stop() {
689         if (!this._targetElement || !this._targetWindow) {
690           return;
691         }
692
693         this._unbindEvent(this._targetElement, 'keydown', this._targetKeyDownBinding);
694
695         this._unbindEvent(this._targetElement, 'keyup', this._targetKeyUpBinding);
696
697         this._unbindEvent(this._targetWindow, 'focus', this._targetResetBinding);
698
699         this._unbindEvent(this._targetWindow, 'blur', this._targetResetBinding);
700
701         this._targetWindow = null;
702         this._targetElement = null;
703         return this;
704       }
705     }, {
706       key: "pressKey",
707       value: function pressKey(keyCode, event) {
708         if (this._paused) {
709           return this;
710         }
711
712         if (!this._locale) {
713           throw new Error('Locale not set');
714         }
715
716         this._locale.pressKey(keyCode);
717
718         this._applyBindings(event);
719
720         return this;
721       }
722     }, {
723       key: "releaseKey",
724       value: function releaseKey(keyCode, event) {
725         if (this._paused) {
726           return this;
727         }
728
729         if (!this._locale) {
730           throw new Error('Locale not set');
731         }
732
733         this._locale.releaseKey(keyCode);
734
735         this._clearBindings(event);
736
737         return this;
738       }
739     }, {
740       key: "releaseAllKeys",
741       value: function releaseAllKeys(event) {
742         if (this._paused) {
743           return this;
744         }
745
746         if (!this._locale) {
747           throw new Error('Locale not set');
748         }
749
750         this._locale.pressedKeys.length = 0;
751
752         this._clearBindings(event);
753
754         return this;
755       }
756     }, {
757       key: "pause",
758       value: function pause() {
759         if (this._paused) {
760           return this;
761         }
762
763         if (this._locale) {
764           this.releaseAllKeys();
765         }
766
767         this._paused = true;
768         return this;
769       }
770     }, {
771       key: "resume",
772       value: function resume() {
773         this._paused = false;
774         return this;
775       }
776     }, {
777       key: "reset",
778       value: function reset() {
779         this.releaseAllKeys();
780         this._listeners.length = 0;
781         return this;
782       }
783     }, {
784       key: "_bindEvent",
785       value: function _bindEvent(targetElement, eventName, handler) {
786         return this._isModernBrowser ? targetElement.addEventListener(eventName, handler, false) : targetElement.attachEvent('on' + eventName, handler);
787       }
788     }, {
789       key: "_unbindEvent",
790       value: function _unbindEvent(targetElement, eventName, handler) {
791         return this._isModernBrowser ? targetElement.removeEventListener(eventName, handler, false) : targetElement.detachEvent('on' + eventName, handler);
792       }
793     }, {
794       key: "_getGroupedListeners",
795       value: function _getGroupedListeners() {
796         var listenerGroups = [];
797         var listenerGroupMap = [];
798         var listeners = this._listeners;
799
800         if (this._currentContext !== 'global') {
801           listeners = [].concat(_toConsumableArray(listeners), _toConsumableArray(this._contexts.global.listeners));
802         }
803
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) {
807           var mapIndex = -1;
808
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)) {
811               mapIndex = i;
812             }
813           }
814
815           if (mapIndex === -1) {
816             mapIndex = listenerGroupMap.length;
817             listenerGroupMap.push(l.keyCombo);
818           }
819
820           if (!listenerGroups[mapIndex]) {
821             listenerGroups[mapIndex] = [];
822           }
823
824           listenerGroups[mapIndex].push(l);
825         });
826         return listenerGroups;
827       }
828     }, {
829       key: "_applyBindings",
830       value: function _applyBindings(event) {
831         var _this2 = this;
832
833         var preventRepeat = false;
834         event || (event = {});
835
836         event.preventRepeat = function () {
837           preventRepeat = true;
838         };
839
840         event.pressedKeys = this._locale.pressedKeys.slice(0);
841         var activeTargetKeys = this._locale.activeTargetKeys;
842
843         var pressedKeys = this._locale.pressedKeys.slice(0);
844
845         var listenerGroups = this._getGroupedListeners();
846
847         var _loop = function _loop(i) {
848           var listeners = listenerGroups[i];
849           var keyCombo = listeners[0].keyCombo;
850
851           if (keyCombo === null || keyCombo.check(pressedKeys) && activeTargetKeys.some(function (k) {
852             return keyCombo.keyNames.includes(k);
853           })) {
854             for (var j = 0; j < listeners.length; j += 1) {
855               var listener = listeners[j];
856
857               if (!listener.executingHandler && listener.pressHandler && !listener.preventRepeat) {
858                 listener.executingHandler = true;
859                 listener.pressHandler.call(_this2, event);
860                 listener.executingHandler = false;
861
862                 if (preventRepeat || listener.preventRepeatByDefault) {
863                   listener.preventRepeat = true;
864                   preventRepeat = false;
865                 }
866               }
867
868               if (_this2._appliedListeners.indexOf(listener) === -1) {
869                 _this2._appliedListeners.push(listener);
870               }
871             }
872
873             if (keyCombo) {
874               for (var _j = 0; _j < keyCombo.keyNames.length; _j += 1) {
875                 var index = pressedKeys.indexOf(keyCombo.keyNames[_j]);
876
877                 if (index !== -1) {
878                   pressedKeys.splice(index, 1);
879                   _j -= 1;
880                 }
881               }
882             }
883           }
884         };
885
886         for (var i = 0; i < listenerGroups.length; i += 1) {
887           _loop(i);
888         }
889       }
890     }, {
891       key: "_clearBindings",
892       value: function _clearBindings(event) {
893         event || (event = {});
894         event.pressedKeys = this._locale.pressedKeys.slice(0);
895
896         for (var i = 0; i < this._appliedListeners.length; i += 1) {
897           var listener = this._appliedListeners[i];
898           var keyCombo = listener.keyCombo;
899
900           if (keyCombo === null || !keyCombo.check(this._locale.pressedKeys)) {
901             listener.preventRepeat = false;
902
903             if (keyCombo !== null || event.pressedKeys.length === 0) {
904               this._appliedListeners.splice(i, 1);
905
906               i -= 1;
907             }
908
909             if (!listener.executingHandler && listener.releaseHandler) {
910               listener.executingHandler = true;
911               listener.releaseHandler.call(this, event);
912               listener.executingHandler = false;
913             }
914           }
915         }
916       }
917     }, {
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"];
923
924         if (platform.match("Mac") && this._locale.pressedKeys.includes("command") && !modifierKeys.includes(this._locale.getKeyNames(event.keyCode)[0])) {
925           this._targetKeyUpBinding(event);
926         }
927       }
928     }]);
929
930     return Keyboard;
931   }();
932
933   function us(locale, platform, userAgent) {
934     // general
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
971
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
982
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
1000
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
1025
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', '?']);
1047
1048     if (platform.match('Mac')) {
1049       locale.bindMacro('command', ['mod', 'modifier']);
1050     } else {
1051       locale.bindMacro('ctrl', ['mod', 'modifier']);
1052     } //a-z and A-Z
1053
1054
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
1062
1063
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;
1069
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;
1079     }
1080
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
1086
1087     locale.setKillKey('command');
1088   }
1089
1090   var keyboard = new Keyboard();
1091   keyboard.setLocale('us', us);
1092   keyboard.Keyboard = Keyboard;
1093   keyboard.Locale = Locale;
1094   keyboard.KeyCombo = KeyCombo;
1095
1096   return keyboard;
1097
1098 })));
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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
1100
1101
1102 /***/ }),
1103
1104 /***/ "./node_modules/lodash/lodash.js":
1105 /*!***************************************!*\
1106   !*** ./node_modules/lodash/lodash.js ***!
1107   \***************************************/
1108 /***/ (function(module, exports, __webpack_require__) {
1109
1110 /* module decorator */ module = __webpack_require__.nmd(module);
1111 var __WEBPACK_AMD_DEFINE_RESULT__;/**
1112  * @license
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
1118  */
1119 ;(function() {
1120
1121   /** Used as a safe reference for `undefined` in pre-ES5 environments. */
1122   var undefined;
1123
1124   /** Used as the semantic version number. */
1125   var VERSION = '4.17.21';
1126
1127   /** Used as the size to enable large array optimizations. */
1128   var LARGE_ARRAY_SIZE = 200;
1129
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`';
1134
1135   /** Used to stand-in for `undefined` hash values. */
1136   var HASH_UNDEFINED = '__lodash_hash_undefined__';
1137
1138   /** Used as the maximum memoize cache size. */
1139   var MAX_MEMOIZE_SIZE = 500;
1140
1141   /** Used as the internal argument placeholder. */
1142   var PLACEHOLDER = '__lodash_placeholder__';
1143
1144   /** Used to compose bitmasks for cloning. */
1145   var CLONE_DEEP_FLAG = 1,
1146       CLONE_FLAT_FLAG = 2,
1147       CLONE_SYMBOLS_FLAG = 4;
1148
1149   /** Used to compose bitmasks for value comparisons. */
1150   var COMPARE_PARTIAL_FLAG = 1,
1151       COMPARE_UNORDERED_FLAG = 2;
1152
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;
1164
1165   /** Used as default options for `_.truncate`. */
1166   var DEFAULT_TRUNC_LENGTH = 30,
1167       DEFAULT_TRUNC_OMISSION = '...';
1168
1169   /** Used to detect hot functions by number of calls within a span of milliseconds. */
1170   var HOT_COUNT = 800,
1171       HOT_SPAN = 16;
1172
1173   /** Used to indicate the type of lazy iteratees. */
1174   var LAZY_FILTER_FLAG = 1,
1175       LAZY_MAP_FLAG = 2,
1176       LAZY_WHILE_FLAG = 3;
1177
1178   /** Used as references for various `Number` constants. */
1179   var INFINITY = 1 / 0,
1180       MAX_SAFE_INTEGER = 9007199254740991,
1181       MAX_INTEGER = 1.7976931348623157e+308,
1182       NAN = 0 / 0;
1183
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;
1188
1189   /** Used to associate wrap methods with their bit flags. */
1190   var wrapFlags = [
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]
1200   ];
1201
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]';
1225
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]';
1237
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;
1242
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);
1248
1249   /** Used to match template delimiters. */
1250   var reEscape = /<%-([\s\S]+?)%>/g,
1251       reEvaluate = /<%([\s\S]+?)%>/g,
1252       reInterpolate = /<%=([\s\S]+?)%>/g;
1253
1254   /** Used to match property names within property paths. */
1255   var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,
1256       reIsPlainProp = /^\w*$/,
1257       rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g;
1258
1259   /**
1260    * Used to match `RegExp`
1261    * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns).
1262    */
1263   var reRegExpChar = /[\\^$.*+?()[\]{}|]/g,
1264       reHasRegExpChar = RegExp(reRegExpChar.source);
1265
1266   /** Used to match leading whitespace. */
1267   var reTrimStart = /^\s+/;
1268
1269   /** Used to match a single whitespace character. */
1270   var reWhitespace = /\s/;
1271
1272   /** Used to match wrap detail comments. */
1273   var reWrapComment = /\{(?:\n\/\* \[wrapped with .+\] \*\/)?\n?/,
1274       reWrapDetails = /\{\n\/\* \[wrapped with (.+)\] \*/,
1275       reSplitDetails = /,? & /;
1276
1277   /** Used to match words composed of alphanumeric characters. */
1278   var reAsciiWord = /[^\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\x7f]+/g;
1279
1280   /**
1281    * Used to validate the `validate` option in `_.template` variable.
1282    *
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)
1288    * - whitespace
1289    */
1290   var reForbiddenIdentifierChars = /[()=,{}\[\]\/\s]/;
1291
1292   /** Used to match backslashes in property paths. */
1293   var reEscapeChar = /\\(\\)?/g;
1294
1295   /**
1296    * Used to match
1297    * [ES template delimiters](http://ecma-international.org/ecma-262/7.0/#sec-template-literal-lexical-components).
1298    */
1299   var reEsTemplate = /\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g;
1300
1301   /** Used to match `RegExp` flags from their coerced string values. */
1302   var reFlags = /\w*$/;
1303
1304   /** Used to detect bad signed hexadecimal string values. */
1305   var reIsBadHex = /^[-+]0x[0-9a-f]+$/i;
1306
1307   /** Used to detect binary string values. */
1308   var reIsBinary = /^0b[01]+$/i;
1309
1310   /** Used to detect host constructors (Safari). */
1311   var reIsHostCtor = /^\[object .+?Constructor\]$/;
1312
1313   /** Used to detect octal string values. */
1314   var reIsOctal = /^0o[0-7]+$/i;
1315
1316   /** Used to detect unsigned integer values. */
1317   var reIsUint = /^(?:0|[1-9]\d*)$/;
1318
1319   /** Used to match Latin Unicode letters (excluding mathematical operators). */
1320   var reLatin = /[\xc0-\xd6\xd8-\xf6\xf8-\xff\u0100-\u017f]/g;
1321
1322   /** Used to ensure capturing order of template delimiters. */
1323   var reNoMatch = /($^)/;
1324
1325   /** Used to match unescaped characters in compiled string literals. */
1326   var reUnescapedString = /['\n\r\u2028\u2029\\]/g;
1327
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;
1343
1344   /** Used to compose unicode capture groups. */
1345   var rsApos = "['\u2019]",
1346       rsAstral = '[' + rsAstralRange + ']',
1347       rsBreak = '[' + rsBreakRange + ']',
1348       rsCombo = '[' + rsComboRange + ']',
1349       rsDigits = '\\d+',
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 + ']',
1359       rsZWJ = '\\u200d';
1360
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('|') + ')';
1374
1375   /** Used to match apostrophes. */
1376   var reApos = RegExp(rsApos, 'g');
1377
1378   /**
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).
1381    */
1382   var reComboMark = RegExp(rsCombo, 'g');
1383
1384   /** Used to match [string symbols](https://mathiasbynens.be/notes/javascript-unicode). */
1385   var reUnicode = RegExp(rsFitz + '(?=' + rsFitz + ')|' + rsSymbol + rsSeq, 'g');
1386
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,
1393     rsOrdUpper,
1394     rsOrdLower,
1395     rsDigits,
1396     rsEmoji
1397   ].join('|'), 'g');
1398
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 + ']');
1401
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 ]/;
1404
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'
1412   ];
1413
1414   /** Used to make template sourceURLs easier to identify. */
1415   var templateCounter = -1;
1416
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;
1432
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;
1448
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',
1468     '\xdf': 'ss',
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'
1505   };
1506
1507   /** Used to map characters to HTML entities. */
1508   var htmlEscapes = {
1509     '&': '&amp;',
1510     '<': '&lt;',
1511     '>': '&gt;',
1512     '"': '&quot;',
1513     "'": '&#39;'
1514   };
1515
1516   /** Used to map HTML entities to characters. */
1517   var htmlUnescapes = {
1518     '&amp;': '&',
1519     '&lt;': '<',
1520     '&gt;': '>',
1521     '&quot;': '"',
1522     '&#39;': "'"
1523   };
1524
1525   /** Used to escape characters for inclusion in compiled string literals. */
1526   var stringEscapes = {
1527     '\\': '\\',
1528     "'": "'",
1529     '\n': 'n',
1530     '\r': 'r',
1531     '\u2028': 'u2028',
1532     '\u2029': 'u2029'
1533   };
1534
1535   /** Built-in method references without a dependency on `root`. */
1536   var freeParseFloat = parseFloat,
1537       freeParseInt = parseInt;
1538
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;
1541
1542   /** Detect free variable `self`. */
1543   var freeSelf = typeof self == 'object' && self && self.Object === Object && self;
1544
1545   /** Used as a reference to the global object. */
1546   var root = freeGlobal || freeSelf || Function('return this')();
1547
1548   /** Detect free variable `exports`. */
1549   var freeExports =  true && exports && !exports.nodeType && exports;
1550
1551   /** Detect free variable `module`. */
1552   var freeModule = freeExports && "object" == 'object' && module && !module.nodeType && module;
1553
1554   /** Detect the popular CommonJS extension `module.exports`. */
1555   var moduleExports = freeModule && freeModule.exports === freeExports;
1556
1557   /** Detect free variable `process` from Node.js. */
1558   var freeProcess = moduleExports && freeGlobal.process;
1559
1560   /** Used to access faster Node.js helpers. */
1561   var nodeUtil = (function() {
1562     try {
1563       // Use `util.types` for Node.js 10+.
1564       var types = freeModule && freeModule.require && freeModule.require('util').types;
1565
1566       if (types) {
1567         return types;
1568       }
1569
1570       // Legacy `process.binding('util')` for Node.js < 10.
1571       return freeProcess && freeProcess.binding && freeProcess.binding('util');
1572     } catch (e) {}
1573   }());
1574
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;
1582
1583   /*--------------------------------------------------------------------------*/
1584
1585   /**
1586    * A faster alternative to `Function#apply`, this function invokes `func`
1587    * with the `this` binding of `thisArg` and the arguments of `args`.
1588    *
1589    * @private
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`.
1594    */
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]);
1601     }
1602     return func.apply(thisArg, args);
1603   }
1604
1605   /**
1606    * A specialized version of `baseAggregator` for arrays.
1607    *
1608    * @private
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`.
1614    */
1615   function arrayAggregator(array, setter, iteratee, accumulator) {
1616     var index = -1,
1617         length = array == null ? 0 : array.length;
1618
1619     while (++index < length) {
1620       var value = array[index];
1621       setter(accumulator, value, iteratee(value), array);
1622     }
1623     return accumulator;
1624   }
1625
1626   /**
1627    * A specialized version of `_.forEach` for arrays without support for
1628    * iteratee shorthands.
1629    *
1630    * @private
1631    * @param {Array} [array] The array to iterate over.
1632    * @param {Function} iteratee The function invoked per iteration.
1633    * @returns {Array} Returns `array`.
1634    */
1635   function arrayEach(array, iteratee) {
1636     var index = -1,
1637         length = array == null ? 0 : array.length;
1638
1639     while (++index < length) {
1640       if (iteratee(array[index], index, array) === false) {
1641         break;
1642       }
1643     }
1644     return array;
1645   }
1646
1647   /**
1648    * A specialized version of `_.forEachRight` for arrays without support for
1649    * iteratee shorthands.
1650    *
1651    * @private
1652    * @param {Array} [array] The array to iterate over.
1653    * @param {Function} iteratee The function invoked per iteration.
1654    * @returns {Array} Returns `array`.
1655    */
1656   function arrayEachRight(array, iteratee) {
1657     var length = array == null ? 0 : array.length;
1658
1659     while (length--) {
1660       if (iteratee(array[length], length, array) === false) {
1661         break;
1662       }
1663     }
1664     return array;
1665   }
1666
1667   /**
1668    * A specialized version of `_.every` for arrays without support for
1669    * iteratee shorthands.
1670    *
1671    * @private
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,
1675    *  else `false`.
1676    */
1677   function arrayEvery(array, predicate) {
1678     var index = -1,
1679         length = array == null ? 0 : array.length;
1680
1681     while (++index < length) {
1682       if (!predicate(array[index], index, array)) {
1683         return false;
1684       }
1685     }
1686     return true;
1687   }
1688
1689   /**
1690    * A specialized version of `_.filter` for arrays without support for
1691    * iteratee shorthands.
1692    *
1693    * @private
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.
1697    */
1698   function arrayFilter(array, predicate) {
1699     var index = -1,
1700         length = array == null ? 0 : array.length,
1701         resIndex = 0,
1702         result = [];
1703
1704     while (++index < length) {
1705       var value = array[index];
1706       if (predicate(value, index, array)) {
1707         result[resIndex++] = value;
1708       }
1709     }
1710     return result;
1711   }
1712
1713   /**
1714    * A specialized version of `_.includes` for arrays without support for
1715    * specifying an index to search from.
1716    *
1717    * @private
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`.
1721    */
1722   function arrayIncludes(array, value) {
1723     var length = array == null ? 0 : array.length;
1724     return !!length && baseIndexOf(array, value, 0) > -1;
1725   }
1726
1727   /**
1728    * This function is like `arrayIncludes` except that it accepts a comparator.
1729    *
1730    * @private
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`.
1735    */
1736   function arrayIncludesWith(array, value, comparator) {
1737     var index = -1,
1738         length = array == null ? 0 : array.length;
1739
1740     while (++index < length) {
1741       if (comparator(value, array[index])) {
1742         return true;
1743       }
1744     }
1745     return false;
1746   }
1747
1748   /**
1749    * A specialized version of `_.map` for arrays without support for iteratee
1750    * shorthands.
1751    *
1752    * @private
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.
1756    */
1757   function arrayMap(array, iteratee) {
1758     var index = -1,
1759         length = array == null ? 0 : array.length,
1760         result = Array(length);
1761
1762     while (++index < length) {
1763       result[index] = iteratee(array[index], index, array);
1764     }
1765     return result;
1766   }
1767
1768   /**
1769    * Appends the elements of `values` to `array`.
1770    *
1771    * @private
1772    * @param {Array} array The array to modify.
1773    * @param {Array} values The values to append.
1774    * @returns {Array} Returns `array`.
1775    */
1776   function arrayPush(array, values) {
1777     var index = -1,
1778         length = values.length,
1779         offset = array.length;
1780
1781     while (++index < length) {
1782       array[offset + index] = values[index];
1783     }
1784     return array;
1785   }
1786
1787   /**
1788    * A specialized version of `_.reduce` for arrays without support for
1789    * iteratee shorthands.
1790    *
1791    * @private
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.
1798    */
1799   function arrayReduce(array, iteratee, accumulator, initAccum) {
1800     var index = -1,
1801         length = array == null ? 0 : array.length;
1802
1803     if (initAccum && length) {
1804       accumulator = array[++index];
1805     }
1806     while (++index < length) {
1807       accumulator = iteratee(accumulator, array[index], index, array);
1808     }
1809     return accumulator;
1810   }
1811
1812   /**
1813    * A specialized version of `_.reduceRight` for arrays without support for
1814    * iteratee shorthands.
1815    *
1816    * @private
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.
1823    */
1824   function arrayReduceRight(array, iteratee, accumulator, initAccum) {
1825     var length = array == null ? 0 : array.length;
1826     if (initAccum && length) {
1827       accumulator = array[--length];
1828     }
1829     while (length--) {
1830       accumulator = iteratee(accumulator, array[length], length, array);
1831     }
1832     return accumulator;
1833   }
1834
1835   /**
1836    * A specialized version of `_.some` for arrays without support for iteratee
1837    * shorthands.
1838    *
1839    * @private
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,
1843    *  else `false`.
1844    */
1845   function arraySome(array, predicate) {
1846     var index = -1,
1847         length = array == null ? 0 : array.length;
1848
1849     while (++index < length) {
1850       if (predicate(array[index], index, array)) {
1851         return true;
1852       }
1853     }
1854     return false;
1855   }
1856
1857   /**
1858    * Gets the size of an ASCII `string`.
1859    *
1860    * @private
1861    * @param {string} string The string inspect.
1862    * @returns {number} Returns the string size.
1863    */
1864   var asciiSize = baseProperty('length');
1865
1866   /**
1867    * Converts an ASCII `string` to an array.
1868    *
1869    * @private
1870    * @param {string} string The string to convert.
1871    * @returns {Array} Returns the converted array.
1872    */
1873   function asciiToArray(string) {
1874     return string.split('');
1875   }
1876
1877   /**
1878    * Splits an ASCII `string` into an array of its words.
1879    *
1880    * @private
1881    * @param {string} The string to inspect.
1882    * @returns {Array} Returns the words of `string`.
1883    */
1884   function asciiWords(string) {
1885     return string.match(reAsciiWord) || [];
1886   }
1887
1888   /**
1889    * The base implementation of methods like `_.findKey` and `_.findLastKey`,
1890    * without support for iteratee shorthands, which iterates over `collection`
1891    * using `eachFunc`.
1892    *
1893    * @private
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`.
1898    */
1899   function baseFindKey(collection, predicate, eachFunc) {
1900     var result;
1901     eachFunc(collection, function(value, key, collection) {
1902       if (predicate(value, key, collection)) {
1903         result = key;
1904         return false;
1905       }
1906     });
1907     return result;
1908   }
1909
1910   /**
1911    * The base implementation of `_.findIndex` and `_.findLastIndex` without
1912    * support for iteratee shorthands.
1913    *
1914    * @private
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`.
1920    */
1921   function baseFindIndex(array, predicate, fromIndex, fromRight) {
1922     var length = array.length,
1923         index = fromIndex + (fromRight ? 1 : -1);
1924
1925     while ((fromRight ? index-- : ++index < length)) {
1926       if (predicate(array[index], index, array)) {
1927         return index;
1928       }
1929     }
1930     return -1;
1931   }
1932
1933   /**
1934    * The base implementation of `_.indexOf` without `fromIndex` bounds checks.
1935    *
1936    * @private
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`.
1941    */
1942   function baseIndexOf(array, value, fromIndex) {
1943     return value === value
1944       ? strictIndexOf(array, value, fromIndex)
1945       : baseFindIndex(array, baseIsNaN, fromIndex);
1946   }
1947
1948   /**
1949    * This function is like `baseIndexOf` except that it accepts a comparator.
1950    *
1951    * @private
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`.
1957    */
1958   function baseIndexOfWith(array, value, fromIndex, comparator) {
1959     var index = fromIndex - 1,
1960         length = array.length;
1961
1962     while (++index < length) {
1963       if (comparator(array[index], value)) {
1964         return index;
1965       }
1966     }
1967     return -1;
1968   }
1969
1970   /**
1971    * The base implementation of `_.isNaN` without support for number objects.
1972    *
1973    * @private
1974    * @param {*} value The value to check.
1975    * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`.
1976    */
1977   function baseIsNaN(value) {
1978     return value !== value;
1979   }
1980
1981   /**
1982    * The base implementation of `_.mean` and `_.meanBy` without support for
1983    * iteratee shorthands.
1984    *
1985    * @private
1986    * @param {Array} array The array to iterate over.
1987    * @param {Function} iteratee The function invoked per iteration.
1988    * @returns {number} Returns the mean.
1989    */
1990   function baseMean(array, iteratee) {
1991     var length = array == null ? 0 : array.length;
1992     return length ? (baseSum(array, iteratee) / length) : NAN;
1993   }
1994
1995   /**
1996    * The base implementation of `_.property` without support for deep paths.
1997    *
1998    * @private
1999    * @param {string} key The key of the property to get.
2000    * @returns {Function} Returns the new accessor function.
2001    */
2002   function baseProperty(key) {
2003     return function(object) {
2004       return object == null ? undefined : object[key];
2005     };
2006   }
2007
2008   /**
2009    * The base implementation of `_.propertyOf` without support for deep paths.
2010    *
2011    * @private
2012    * @param {Object} object The object to query.
2013    * @returns {Function} Returns the new accessor function.
2014    */
2015   function basePropertyOf(object) {
2016     return function(key) {
2017       return object == null ? undefined : object[key];
2018     };
2019   }
2020
2021   /**
2022    * The base implementation of `_.reduce` and `_.reduceRight`, without support
2023    * for iteratee shorthands, which iterates over `collection` using `eachFunc`.
2024    *
2025    * @private
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.
2033    */
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);
2039     });
2040     return accumulator;
2041   }
2042
2043   /**
2044    * The base implementation of `_.sortBy` which uses `comparer` to define the
2045    * sort order of `array` and replaces criteria objects with their corresponding
2046    * values.
2047    *
2048    * @private
2049    * @param {Array} array The array to sort.
2050    * @param {Function} comparer The function to define sort order.
2051    * @returns {Array} Returns `array`.
2052    */
2053   function baseSortBy(array, comparer) {
2054     var length = array.length;
2055
2056     array.sort(comparer);
2057     while (length--) {
2058       array[length] = array[length].value;
2059     }
2060     return array;
2061   }
2062
2063   /**
2064    * The base implementation of `_.sum` and `_.sumBy` without support for
2065    * iteratee shorthands.
2066    *
2067    * @private
2068    * @param {Array} array The array to iterate over.
2069    * @param {Function} iteratee The function invoked per iteration.
2070    * @returns {number} Returns the sum.
2071    */
2072   function baseSum(array, iteratee) {
2073     var result,
2074         index = -1,
2075         length = array.length;
2076
2077     while (++index < length) {
2078       var current = iteratee(array[index]);
2079       if (current !== undefined) {
2080         result = result === undefined ? current : (result + current);
2081       }
2082     }
2083     return result;
2084   }
2085
2086   /**
2087    * The base implementation of `_.times` without support for iteratee shorthands
2088    * or max array length checks.
2089    *
2090    * @private
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.
2094    */
2095   function baseTimes(n, iteratee) {
2096     var index = -1,
2097         result = Array(n);
2098
2099     while (++index < n) {
2100       result[index] = iteratee(index);
2101     }
2102     return result;
2103   }
2104
2105   /**
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`.
2108    *
2109    * @private
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.
2113    */
2114   function baseToPairs(object, props) {
2115     return arrayMap(props, function(key) {
2116       return [key, object[key]];
2117     });
2118   }
2119
2120   /**
2121    * The base implementation of `_.trim`.
2122    *
2123    * @private
2124    * @param {string} string The string to trim.
2125    * @returns {string} Returns the trimmed string.
2126    */
2127   function baseTrim(string) {
2128     return string
2129       ? string.slice(0, trimmedEndIndex(string) + 1).replace(reTrimStart, '')
2130       : string;
2131   }
2132
2133   /**
2134    * The base implementation of `_.unary` without support for storing metadata.
2135    *
2136    * @private
2137    * @param {Function} func The function to cap arguments for.
2138    * @returns {Function} Returns the new capped function.
2139    */
2140   function baseUnary(func) {
2141     return function(value) {
2142       return func(value);
2143     };
2144   }
2145
2146   /**
2147    * The base implementation of `_.values` and `_.valuesIn` which creates an
2148    * array of `object` property values corresponding to the property names
2149    * of `props`.
2150    *
2151    * @private
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.
2155    */
2156   function baseValues(object, props) {
2157     return arrayMap(props, function(key) {
2158       return object[key];
2159     });
2160   }
2161
2162   /**
2163    * Checks if a `cache` value for `key` exists.
2164    *
2165    * @private
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`.
2169    */
2170   function cacheHas(cache, key) {
2171     return cache.has(key);
2172   }
2173
2174   /**
2175    * Used by `_.trim` and `_.trimStart` to get the index of the first string symbol
2176    * that is not found in the character symbols.
2177    *
2178    * @private
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.
2182    */
2183   function charsStartIndex(strSymbols, chrSymbols) {
2184     var index = -1,
2185         length = strSymbols.length;
2186
2187     while (++index < length && baseIndexOf(chrSymbols, strSymbols[index], 0) > -1) {}
2188     return index;
2189   }
2190
2191   /**
2192    * Used by `_.trim` and `_.trimEnd` to get the index of the last string symbol
2193    * that is not found in the character symbols.
2194    *
2195    * @private
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.
2199    */
2200   function charsEndIndex(strSymbols, chrSymbols) {
2201     var index = strSymbols.length;
2202
2203     while (index-- && baseIndexOf(chrSymbols, strSymbols[index], 0) > -1) {}
2204     return index;
2205   }
2206
2207   /**
2208    * Gets the number of `placeholder` occurrences in `array`.
2209    *
2210    * @private
2211    * @param {Array} array The array to inspect.
2212    * @param {*} placeholder The placeholder to search for.
2213    * @returns {number} Returns the placeholder count.
2214    */
2215   function countHolders(array, placeholder) {
2216     var length = array.length,
2217         result = 0;
2218
2219     while (length--) {
2220       if (array[length] === placeholder) {
2221         ++result;
2222       }
2223     }
2224     return result;
2225   }
2226
2227   /**
2228    * Used by `_.deburr` to convert Latin-1 Supplement and Latin Extended-A
2229    * letters to basic Latin letters.
2230    *
2231    * @private
2232    * @param {string} letter The matched letter to deburr.
2233    * @returns {string} Returns the deburred letter.
2234    */
2235   var deburrLetter = basePropertyOf(deburredLetters);
2236
2237   /**
2238    * Used by `_.escape` to convert characters to HTML entities.
2239    *
2240    * @private
2241    * @param {string} chr The matched character to escape.
2242    * @returns {string} Returns the escaped character.
2243    */
2244   var escapeHtmlChar = basePropertyOf(htmlEscapes);
2245
2246   /**
2247    * Used by `_.template` to escape characters for inclusion in compiled string literals.
2248    *
2249    * @private
2250    * @param {string} chr The matched character to escape.
2251    * @returns {string} Returns the escaped character.
2252    */
2253   function escapeStringChar(chr) {
2254     return '\\' + stringEscapes[chr];
2255   }
2256
2257   /**
2258    * Gets the value at `key` of `object`.
2259    *
2260    * @private
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.
2264    */
2265   function getValue(object, key) {
2266     return object == null ? undefined : object[key];
2267   }
2268
2269   /**
2270    * Checks if `string` contains Unicode symbols.
2271    *
2272    * @private
2273    * @param {string} string The string to inspect.
2274    * @returns {boolean} Returns `true` if a symbol is found, else `false`.
2275    */
2276   function hasUnicode(string) {
2277     return reHasUnicode.test(string);
2278   }
2279
2280   /**
2281    * Checks if `string` contains a word composed of Unicode symbols.
2282    *
2283    * @private
2284    * @param {string} string The string to inspect.
2285    * @returns {boolean} Returns `true` if a word is found, else `false`.
2286    */
2287   function hasUnicodeWord(string) {
2288     return reHasUnicodeWord.test(string);
2289   }
2290
2291   /**
2292    * Converts `iterator` to an array.
2293    *
2294    * @private
2295    * @param {Object} iterator The iterator to convert.
2296    * @returns {Array} Returns the converted array.
2297    */
2298   function iteratorToArray(iterator) {
2299     var data,
2300         result = [];
2301
2302     while (!(data = iterator.next()).done) {
2303       result.push(data.value);
2304     }
2305     return result;
2306   }
2307
2308   /**
2309    * Converts `map` to its key-value pairs.
2310    *
2311    * @private
2312    * @param {Object} map The map to convert.
2313    * @returns {Array} Returns the key-value pairs.
2314    */
2315   function mapToArray(map) {
2316     var index = -1,
2317         result = Array(map.size);
2318
2319     map.forEach(function(value, key) {
2320       result[++index] = [key, value];
2321     });
2322     return result;
2323   }
2324
2325   /**
2326    * Creates a unary function that invokes `func` with its argument transformed.
2327    *
2328    * @private
2329    * @param {Function} func The function to wrap.
2330    * @param {Function} transform The argument transform.
2331    * @returns {Function} Returns the new function.
2332    */
2333   function overArg(func, transform) {
2334     return function(arg) {
2335       return func(transform(arg));
2336     };
2337   }
2338
2339   /**
2340    * Replaces all `placeholder` elements in `array` with an internal placeholder
2341    * and returns an array of their indexes.
2342    *
2343    * @private
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.
2347    */
2348   function replaceHolders(array, placeholder) {
2349     var index = -1,
2350         length = array.length,
2351         resIndex = 0,
2352         result = [];
2353
2354     while (++index < length) {
2355       var value = array[index];
2356       if (value === placeholder || value === PLACEHOLDER) {
2357         array[index] = PLACEHOLDER;
2358         result[resIndex++] = index;
2359       }
2360     }
2361     return result;
2362   }
2363
2364   /**
2365    * Converts `set` to an array of its values.
2366    *
2367    * @private
2368    * @param {Object} set The set to convert.
2369    * @returns {Array} Returns the values.
2370    */
2371   function setToArray(set) {
2372     var index = -1,
2373         result = Array(set.size);
2374
2375     set.forEach(function(value) {
2376       result[++index] = value;
2377     });
2378     return result;
2379   }
2380
2381   /**
2382    * Converts `set` to its value-value pairs.
2383    *
2384    * @private
2385    * @param {Object} set The set to convert.
2386    * @returns {Array} Returns the value-value pairs.
2387    */
2388   function setToPairs(set) {
2389     var index = -1,
2390         result = Array(set.size);
2391
2392     set.forEach(function(value) {
2393       result[++index] = [value, value];
2394     });
2395     return result;
2396   }
2397
2398   /**
2399    * A specialized version of `_.indexOf` which performs strict equality
2400    * comparisons of values, i.e. `===`.
2401    *
2402    * @private
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`.
2407    */
2408   function strictIndexOf(array, value, fromIndex) {
2409     var index = fromIndex - 1,
2410         length = array.length;
2411
2412     while (++index < length) {
2413       if (array[index] === value) {
2414         return index;
2415       }
2416     }
2417     return -1;
2418   }
2419
2420   /**
2421    * A specialized version of `_.lastIndexOf` which performs strict equality
2422    * comparisons of values, i.e. `===`.
2423    *
2424    * @private
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`.
2429    */
2430   function strictLastIndexOf(array, value, fromIndex) {
2431     var index = fromIndex + 1;
2432     while (index--) {
2433       if (array[index] === value) {
2434         return index;
2435       }
2436     }
2437     return index;
2438   }
2439
2440   /**
2441    * Gets the number of symbols in `string`.
2442    *
2443    * @private
2444    * @param {string} string The string to inspect.
2445    * @returns {number} Returns the string size.
2446    */
2447   function stringSize(string) {
2448     return hasUnicode(string)
2449       ? unicodeSize(string)
2450       : asciiSize(string);
2451   }
2452
2453   /**
2454    * Converts `string` to an array.
2455    *
2456    * @private
2457    * @param {string} string The string to convert.
2458    * @returns {Array} Returns the converted array.
2459    */
2460   function stringToArray(string) {
2461     return hasUnicode(string)
2462       ? unicodeToArray(string)
2463       : asciiToArray(string);
2464   }
2465
2466   /**
2467    * Used by `_.trim` and `_.trimEnd` to get the index of the last non-whitespace
2468    * character of `string`.
2469    *
2470    * @private
2471    * @param {string} string The string to inspect.
2472    * @returns {number} Returns the index of the last non-whitespace character.
2473    */
2474   function trimmedEndIndex(string) {
2475     var index = string.length;
2476
2477     while (index-- && reWhitespace.test(string.charAt(index))) {}
2478     return index;
2479   }
2480
2481   /**
2482    * Used by `_.unescape` to convert HTML entities to characters.
2483    *
2484    * @private
2485    * @param {string} chr The matched character to unescape.
2486    * @returns {string} Returns the unescaped character.
2487    */
2488   var unescapeHtmlChar = basePropertyOf(htmlUnescapes);
2489
2490   /**
2491    * Gets the size of a Unicode `string`.
2492    *
2493    * @private
2494    * @param {string} string The string inspect.
2495    * @returns {number} Returns the string size.
2496    */
2497   function unicodeSize(string) {
2498     var result = reUnicode.lastIndex = 0;
2499     while (reUnicode.test(string)) {
2500       ++result;
2501     }
2502     return result;
2503   }
2504
2505   /**
2506    * Converts a Unicode `string` to an array.
2507    *
2508    * @private
2509    * @param {string} string The string to convert.
2510    * @returns {Array} Returns the converted array.
2511    */
2512   function unicodeToArray(string) {
2513     return string.match(reUnicode) || [];
2514   }
2515
2516   /**
2517    * Splits a Unicode `string` into an array of its words.
2518    *
2519    * @private
2520    * @param {string} The string to inspect.
2521    * @returns {Array} Returns the words of `string`.
2522    */
2523   function unicodeWords(string) {
2524     return string.match(reUnicodeWord) || [];
2525   }
2526
2527   /*--------------------------------------------------------------------------*/
2528
2529   /**
2530    * Create a new pristine `lodash` function using the `context` object.
2531    *
2532    * @static
2533    * @memberOf _
2534    * @since 1.1.0
2535    * @category Util
2536    * @param {Object} [context=root] The context object.
2537    * @returns {Function} Returns a new `lodash` function.
2538    * @example
2539    *
2540    * _.mixin({ 'foo': _.constant('foo') });
2541    *
2542    * var lodash = _.runInContext();
2543    * lodash.mixin({ 'bar': lodash.constant('bar') });
2544    *
2545    * _.isFunction(_.foo);
2546    * // => true
2547    * _.isFunction(_.bar);
2548    * // => false
2549    *
2550    * lodash.isFunction(lodash.foo);
2551    * // => false
2552    * lodash.isFunction(lodash.bar);
2553    * // => true
2554    *
2555    * // Create a suped-up `defer` in Node.js.
2556    * var defer = _.runInContext({ 'setTimeout': setImmediate }).defer;
2557    */
2558   var runInContext = (function runInContext(context) {
2559     context = context == null ? root : _.defaults(root.Object(), context, _.pick(root, contextProps));
2560
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;
2571
2572     /** Used for built-in method references. */
2573     var arrayProto = Array.prototype,
2574         funcProto = Function.prototype,
2575         objectProto = Object.prototype;
2576
2577     /** Used to detect overreaching core-js shims. */
2578     var coreJsData = context['__core-js_shared__'];
2579
2580     /** Used to resolve the decompiled source of functions. */
2581     var funcToString = funcProto.toString;
2582
2583     /** Used to check objects for own properties. */
2584     var hasOwnProperty = objectProto.hasOwnProperty;
2585
2586     /** Used to generate unique IDs. */
2587     var idCounter = 0;
2588
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) : '';
2593     }());
2594
2595     /**
2596      * Used to resolve the
2597      * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
2598      * of values.
2599      */
2600     var nativeObjectToString = objectProto.toString;
2601
2602     /** Used to infer the `Object` constructor. */
2603     var objectCtorString = funcToString.call(Object);
2604
2605     /** Used to restore the original `_` reference in `_.noConflict`. */
2606     var oldDash = root._;
2607
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.*?') + '$'
2612     );
2613
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;
2626
2627     var defineProperty = (function() {
2628       try {
2629         var func = getNative(Object, 'defineProperty');
2630         func({}, '', {});
2631         return func;
2632       } catch (e) {}
2633     }());
2634
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;
2639
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;
2654
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');
2662
2663     /** Used to store function metadata. */
2664     var metaMap = WeakMap && new WeakMap;
2665
2666     /** Used to lookup unminified function names. */
2667     var realNames = {};
2668
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);
2675
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;
2680
2681     /*------------------------------------------------------------------------*/
2682
2683     /**
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
2689      * with `_#value`.
2690      *
2691      * Explicit chain sequences, which must be unwrapped with `_#value`, may be
2692      * enabled using `_.chain`.
2693      *
2694      * The execution of chained methods is lazy, that is, it's deferred until
2695      * `_#value` is implicitly or explicitly called.
2696      *
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.
2704      *
2705      * Chaining is supported in custom builds as long as the `_#value` method is
2706      * directly or indirectly included in the build.
2707      *
2708      * In addition to lodash methods, wrappers have `Array` and `String` methods.
2709      *
2710      * The wrapper `Array` methods are:
2711      * `concat`, `join`, `pop`, `push`, `shift`, `sort`, `splice`, and `unshift`
2712      *
2713      * The wrapper `String` methods are:
2714      * `replace` and `split`
2715      *
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`
2720      *
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`
2746      *
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`
2773      *
2774      * @name _
2775      * @constructor
2776      * @category Seq
2777      * @param {*} value The value to wrap in a `lodash` instance.
2778      * @returns {Object} Returns the new `lodash` wrapper instance.
2779      * @example
2780      *
2781      * function square(n) {
2782      *   return n * n;
2783      * }
2784      *
2785      * var wrapped = _([1, 2, 3]);
2786      *
2787      * // Returns an unwrapped value.
2788      * wrapped.reduce(_.add);
2789      * // => 6
2790      *
2791      * // Returns a wrapped value.
2792      * var squares = wrapped.map(square);
2793      *
2794      * _.isArray(squares);
2795      * // => false
2796      *
2797      * _.isArray(squares.value());
2798      * // => true
2799      */
2800     function lodash(value) {
2801       if (isObjectLike(value) && !isArray(value) && !(value instanceof LazyWrapper)) {
2802         if (value instanceof LodashWrapper) {
2803           return value;
2804         }
2805         if (hasOwnProperty.call(value, '__wrapped__')) {
2806           return wrapperClone(value);
2807         }
2808       }
2809       return new LodashWrapper(value);
2810     }
2811
2812     /**
2813      * The base implementation of `_.create` without support for assigning
2814      * properties to the created object.
2815      *
2816      * @private
2817      * @param {Object} proto The object to inherit from.
2818      * @returns {Object} Returns the new object.
2819      */
2820     var baseCreate = (function() {
2821       function object() {}
2822       return function(proto) {
2823         if (!isObject(proto)) {
2824           return {};
2825         }
2826         if (objectCreate) {
2827           return objectCreate(proto);
2828         }
2829         object.prototype = proto;
2830         var result = new object;
2831         object.prototype = undefined;
2832         return result;
2833       };
2834     }());
2835
2836     /**
2837      * The function whose prototype chain sequence wrappers inherit from.
2838      *
2839      * @private
2840      */
2841     function baseLodash() {
2842       // No operation performed.
2843     }
2844
2845     /**
2846      * The base constructor for creating `lodash` wrapper objects.
2847      *
2848      * @private
2849      * @param {*} value The value to wrap.
2850      * @param {boolean} [chainAll] Enable explicit method chain sequences.
2851      */
2852     function LodashWrapper(value, chainAll) {
2853       this.__wrapped__ = value;
2854       this.__actions__ = [];
2855       this.__chain__ = !!chainAll;
2856       this.__index__ = 0;
2857       this.__values__ = undefined;
2858     }
2859
2860     /**
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.
2864      *
2865      * @static
2866      * @memberOf _
2867      * @type {Object}
2868      */
2869     lodash.templateSettings = {
2870
2871       /**
2872        * Used to detect `data` property values to be HTML-escaped.
2873        *
2874        * @memberOf _.templateSettings
2875        * @type {RegExp}
2876        */
2877       'escape': reEscape,
2878
2879       /**
2880        * Used to detect code to be evaluated.
2881        *
2882        * @memberOf _.templateSettings
2883        * @type {RegExp}
2884        */
2885       'evaluate': reEvaluate,
2886
2887       /**
2888        * Used to detect `data` property values to inject.
2889        *
2890        * @memberOf _.templateSettings
2891        * @type {RegExp}
2892        */
2893       'interpolate': reInterpolate,
2894
2895       /**
2896        * Used to reference the data object in the template text.
2897        *
2898        * @memberOf _.templateSettings
2899        * @type {string}
2900        */
2901       'variable': '',
2902
2903       /**
2904        * Used to import variables into the compiled template.
2905        *
2906        * @memberOf _.templateSettings
2907        * @type {Object}
2908        */
2909       'imports': {
2910
2911         /**
2912          * A reference to the `lodash` function.
2913          *
2914          * @memberOf _.templateSettings.imports
2915          * @type {Function}
2916          */
2917         '_': lodash
2918       }
2919     };
2920
2921     // Ensure wrappers are instances of `baseLodash`.
2922     lodash.prototype = baseLodash.prototype;
2923     lodash.prototype.constructor = lodash;
2924
2925     LodashWrapper.prototype = baseCreate(baseLodash.prototype);
2926     LodashWrapper.prototype.constructor = LodashWrapper;
2927
2928     /*------------------------------------------------------------------------*/
2929
2930     /**
2931      * Creates a lazy wrapper object which wraps `value` to enable lazy evaluation.
2932      *
2933      * @private
2934      * @constructor
2935      * @param {*} value The value to wrap.
2936      */
2937     function LazyWrapper(value) {
2938       this.__wrapped__ = value;
2939       this.__actions__ = [];
2940       this.__dir__ = 1;
2941       this.__filtered__ = false;
2942       this.__iteratees__ = [];
2943       this.__takeCount__ = MAX_ARRAY_LENGTH;
2944       this.__views__ = [];
2945     }
2946
2947     /**
2948      * Creates a clone of the lazy wrapper object.
2949      *
2950      * @private
2951      * @name clone
2952      * @memberOf LazyWrapper
2953      * @returns {Object} Returns the cloned `LazyWrapper` object.
2954      */
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__);
2963       return result;
2964     }
2965
2966     /**
2967      * Reverses the direction of lazy iteration.
2968      *
2969      * @private
2970      * @name reverse
2971      * @memberOf LazyWrapper
2972      * @returns {Object} Returns the new reversed `LazyWrapper` object.
2973      */
2974     function lazyReverse() {
2975       if (this.__filtered__) {
2976         var result = new LazyWrapper(this);
2977         result.__dir__ = -1;
2978         result.__filtered__ = true;
2979       } else {
2980         result = this.clone();
2981         result.__dir__ *= -1;
2982       }
2983       return result;
2984     }
2985
2986     /**
2987      * Extracts the unwrapped value from its lazy wrapper.
2988      *
2989      * @private
2990      * @name value
2991      * @memberOf LazyWrapper
2992      * @returns {*} Returns the unwrapped value.
2993      */
2994     function lazyValue() {
2995       var array = this.__wrapped__.value(),
2996           dir = this.__dir__,
2997           isArr = isArray(array),
2998           isRight = dir < 0,
2999           arrLength = isArr ? array.length : 0,
3000           view = getView(0, arrLength, this.__views__),
3001           start = view.start,
3002           end = view.end,
3003           length = end - start,
3004           index = isRight ? end : (start - 1),
3005           iteratees = this.__iteratees__,
3006           iterLength = iteratees.length,
3007           resIndex = 0,
3008           takeCount = nativeMin(length, this.__takeCount__);
3009
3010       if (!isArr || (!isRight && arrLength == length && takeCount == length)) {
3011         return baseWrapperValue(array, this.__actions__);
3012       }
3013       var result = [];
3014
3015       outer:
3016       while (length-- && resIndex < takeCount) {
3017         index += dir;
3018
3019         var iterIndex = -1,
3020             value = array[index];
3021
3022         while (++iterIndex < iterLength) {
3023           var data = iteratees[iterIndex],
3024               iteratee = data.iteratee,
3025               type = data.type,
3026               computed = iteratee(value);
3027
3028           if (type == LAZY_MAP_FLAG) {
3029             value = computed;
3030           } else if (!computed) {
3031             if (type == LAZY_FILTER_FLAG) {
3032               continue outer;
3033             } else {
3034               break outer;
3035             }
3036           }
3037         }
3038         result[resIndex++] = value;
3039       }
3040       return result;
3041     }
3042
3043     // Ensure `LazyWrapper` is an instance of `baseLodash`.
3044     LazyWrapper.prototype = baseCreate(baseLodash.prototype);
3045     LazyWrapper.prototype.constructor = LazyWrapper;
3046
3047     /*------------------------------------------------------------------------*/
3048
3049     /**
3050      * Creates a hash object.
3051      *
3052      * @private
3053      * @constructor
3054      * @param {Array} [entries] The key-value pairs to cache.
3055      */
3056     function Hash(entries) {
3057       var index = -1,
3058           length = entries == null ? 0 : entries.length;
3059
3060       this.clear();
3061       while (++index < length) {
3062         var entry = entries[index];
3063         this.set(entry[0], entry[1]);
3064       }
3065     }
3066
3067     /**
3068      * Removes all key-value entries from the hash.
3069      *
3070      * @private
3071      * @name clear
3072      * @memberOf Hash
3073      */
3074     function hashClear() {
3075       this.__data__ = nativeCreate ? nativeCreate(null) : {};
3076       this.size = 0;
3077     }
3078
3079     /**
3080      * Removes `key` and its value from the hash.
3081      *
3082      * @private
3083      * @name delete
3084      * @memberOf 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`.
3088      */
3089     function hashDelete(key) {
3090       var result = this.has(key) && delete this.__data__[key];
3091       this.size -= result ? 1 : 0;
3092       return result;
3093     }
3094
3095     /**
3096      * Gets the hash value for `key`.
3097      *
3098      * @private
3099      * @name get
3100      * @memberOf Hash
3101      * @param {string} key The key of the value to get.
3102      * @returns {*} Returns the entry value.
3103      */
3104     function hashGet(key) {
3105       var data = this.__data__;
3106       if (nativeCreate) {
3107         var result = data[key];
3108         return result === HASH_UNDEFINED ? undefined : result;
3109       }
3110       return hasOwnProperty.call(data, key) ? data[key] : undefined;
3111     }
3112
3113     /**
3114      * Checks if a hash value for `key` exists.
3115      *
3116      * @private
3117      * @name has
3118      * @memberOf Hash
3119      * @param {string} key The key of the entry to check.
3120      * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
3121      */
3122     function hashHas(key) {
3123       var data = this.__data__;
3124       return nativeCreate ? (data[key] !== undefined) : hasOwnProperty.call(data, key);
3125     }
3126
3127     /**
3128      * Sets the hash `key` to `value`.
3129      *
3130      * @private
3131      * @name set
3132      * @memberOf Hash
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.
3136      */
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;
3141       return this;
3142     }
3143
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;
3150
3151     /*------------------------------------------------------------------------*/
3152
3153     /**
3154      * Creates an list cache object.
3155      *
3156      * @private
3157      * @constructor
3158      * @param {Array} [entries] The key-value pairs to cache.
3159      */
3160     function ListCache(entries) {
3161       var index = -1,
3162           length = entries == null ? 0 : entries.length;
3163
3164       this.clear();
3165       while (++index < length) {
3166         var entry = entries[index];
3167         this.set(entry[0], entry[1]);
3168       }
3169     }
3170
3171     /**
3172      * Removes all key-value entries from the list cache.
3173      *
3174      * @private
3175      * @name clear
3176      * @memberOf ListCache
3177      */
3178     function listCacheClear() {
3179       this.__data__ = [];
3180       this.size = 0;
3181     }
3182
3183     /**
3184      * Removes `key` and its value from the list cache.
3185      *
3186      * @private
3187      * @name delete
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`.
3191      */
3192     function listCacheDelete(key) {
3193       var data = this.__data__,
3194           index = assocIndexOf(data, key);
3195
3196       if (index < 0) {
3197         return false;
3198       }
3199       var lastIndex = data.length - 1;
3200       if (index == lastIndex) {
3201         data.pop();
3202       } else {
3203         splice.call(data, index, 1);
3204       }
3205       --this.size;
3206       return true;
3207     }
3208
3209     /**
3210      * Gets the list cache value for `key`.
3211      *
3212      * @private
3213      * @name get
3214      * @memberOf ListCache
3215      * @param {string} key The key of the value to get.
3216      * @returns {*} Returns the entry value.
3217      */
3218     function listCacheGet(key) {
3219       var data = this.__data__,
3220           index = assocIndexOf(data, key);
3221
3222       return index < 0 ? undefined : data[index][1];
3223     }
3224
3225     /**
3226      * Checks if a list cache value for `key` exists.
3227      *
3228      * @private
3229      * @name has
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`.
3233      */
3234     function listCacheHas(key) {
3235       return assocIndexOf(this.__data__, key) > -1;
3236     }
3237
3238     /**
3239      * Sets the list cache `key` to `value`.
3240      *
3241      * @private
3242      * @name set
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.
3247      */
3248     function listCacheSet(key, value) {
3249       var data = this.__data__,
3250           index = assocIndexOf(data, key);
3251
3252       if (index < 0) {
3253         ++this.size;
3254         data.push([key, value]);
3255       } else {
3256         data[index][1] = value;
3257       }
3258       return this;
3259     }
3260
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;
3267
3268     /*------------------------------------------------------------------------*/
3269
3270     /**
3271      * Creates a map cache object to store key-value pairs.
3272      *
3273      * @private
3274      * @constructor
3275      * @param {Array} [entries] The key-value pairs to cache.
3276      */
3277     function MapCache(entries) {
3278       var index = -1,
3279           length = entries == null ? 0 : entries.length;
3280
3281       this.clear();
3282       while (++index < length) {
3283         var entry = entries[index];
3284         this.set(entry[0], entry[1]);
3285       }
3286     }
3287
3288     /**
3289      * Removes all key-value entries from the map.
3290      *
3291      * @private
3292      * @name clear
3293      * @memberOf MapCache
3294      */
3295     function mapCacheClear() {
3296       this.size = 0;
3297       this.__data__ = {
3298         'hash': new Hash,
3299         'map': new (Map || ListCache),
3300         'string': new Hash
3301       };
3302     }
3303
3304     /**
3305      * Removes `key` and its value from the map.
3306      *
3307      * @private
3308      * @name delete
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`.
3312      */
3313     function mapCacheDelete(key) {
3314       var result = getMapData(this, key)['delete'](key);
3315       this.size -= result ? 1 : 0;
3316       return result;
3317     }
3318
3319     /**
3320      * Gets the map value for `key`.
3321      *
3322      * @private
3323      * @name get
3324      * @memberOf MapCache
3325      * @param {string} key The key of the value to get.
3326      * @returns {*} Returns the entry value.
3327      */
3328     function mapCacheGet(key) {
3329       return getMapData(this, key).get(key);
3330     }
3331
3332     /**
3333      * Checks if a map value for `key` exists.
3334      *
3335      * @private
3336      * @name has
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`.
3340      */
3341     function mapCacheHas(key) {
3342       return getMapData(this, key).has(key);
3343     }
3344
3345     /**
3346      * Sets the map `key` to `value`.
3347      *
3348      * @private
3349      * @name set
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.
3354      */
3355     function mapCacheSet(key, value) {
3356       var data = getMapData(this, key),
3357           size = data.size;
3358
3359       data.set(key, value);
3360       this.size += data.size == size ? 0 : 1;
3361       return this;
3362     }
3363
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;
3370
3371     /*------------------------------------------------------------------------*/
3372
3373     /**
3374      *
3375      * Creates an array cache object to store unique values.
3376      *
3377      * @private
3378      * @constructor
3379      * @param {Array} [values] The values to cache.
3380      */
3381     function SetCache(values) {
3382       var index = -1,
3383           length = values == null ? 0 : values.length;
3384
3385       this.__data__ = new MapCache;
3386       while (++index < length) {
3387         this.add(values[index]);
3388       }
3389     }
3390
3391     /**
3392      * Adds `value` to the array cache.
3393      *
3394      * @private
3395      * @name add
3396      * @memberOf SetCache
3397      * @alias push
3398      * @param {*} value The value to cache.
3399      * @returns {Object} Returns the cache instance.
3400      */
3401     function setCacheAdd(value) {
3402       this.__data__.set(value, HASH_UNDEFINED);
3403       return this;
3404     }
3405
3406     /**
3407      * Checks if `value` is in the array cache.
3408      *
3409      * @private
3410      * @name has
3411      * @memberOf SetCache
3412      * @param {*} value The value to search for.
3413      * @returns {number} Returns `true` if `value` is found, else `false`.
3414      */
3415     function setCacheHas(value) {
3416       return this.__data__.has(value);
3417     }
3418
3419     // Add methods to `SetCache`.
3420     SetCache.prototype.add = SetCache.prototype.push = setCacheAdd;
3421     SetCache.prototype.has = setCacheHas;
3422
3423     /*------------------------------------------------------------------------*/
3424
3425     /**
3426      * Creates a stack cache object to store key-value pairs.
3427      *
3428      * @private
3429      * @constructor
3430      * @param {Array} [entries] The key-value pairs to cache.
3431      */
3432     function Stack(entries) {
3433       var data = this.__data__ = new ListCache(entries);
3434       this.size = data.size;
3435     }
3436
3437     /**
3438      * Removes all key-value entries from the stack.
3439      *
3440      * @private
3441      * @name clear
3442      * @memberOf Stack
3443      */
3444     function stackClear() {
3445       this.__data__ = new ListCache;
3446       this.size = 0;
3447     }
3448
3449     /**
3450      * Removes `key` and its value from the stack.
3451      *
3452      * @private
3453      * @name delete
3454      * @memberOf Stack
3455      * @param {string} key The key of the value to remove.
3456      * @returns {boolean} Returns `true` if the entry was removed, else `false`.
3457      */
3458     function stackDelete(key) {
3459       var data = this.__data__,
3460           result = data['delete'](key);
3461
3462       this.size = data.size;
3463       return result;
3464     }
3465
3466     /**
3467      * Gets the stack value for `key`.
3468      *
3469      * @private
3470      * @name get
3471      * @memberOf Stack
3472      * @param {string} key The key of the value to get.
3473      * @returns {*} Returns the entry value.
3474      */
3475     function stackGet(key) {
3476       return this.__data__.get(key);
3477     }
3478
3479     /**
3480      * Checks if a stack value for `key` exists.
3481      *
3482      * @private
3483      * @name has
3484      * @memberOf Stack
3485      * @param {string} key The key of the entry to check.
3486      * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
3487      */
3488     function stackHas(key) {
3489       return this.__data__.has(key);
3490     }
3491
3492     /**
3493      * Sets the stack `key` to `value`.
3494      *
3495      * @private
3496      * @name set
3497      * @memberOf Stack
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.
3501      */
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;
3509           return this;
3510         }
3511         data = this.__data__ = new MapCache(pairs);
3512       }
3513       data.set(key, value);
3514       this.size = data.size;
3515       return this;
3516     }
3517
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;
3524
3525     /*------------------------------------------------------------------------*/
3526
3527     /**
3528      * Creates an array of the enumerable property names of the array-like `value`.
3529      *
3530      * @private
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.
3534      */
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;
3543
3544       for (var key in value) {
3545         if ((inherited || hasOwnProperty.call(value, key)) &&
3546             !(skipIndexes && (
3547                // Safari 9 has enumerable `arguments.length` in strict mode.
3548                key == 'length' ||
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)
3555             ))) {
3556           result.push(key);
3557         }
3558       }
3559       return result;
3560     }
3561
3562     /**
3563      * A specialized version of `_.sample` for arrays.
3564      *
3565      * @private
3566      * @param {Array} array The array to sample.
3567      * @returns {*} Returns the random element.
3568      */
3569     function arraySample(array) {
3570       var length = array.length;
3571       return length ? array[baseRandom(0, length - 1)] : undefined;
3572     }
3573
3574     /**
3575      * A specialized version of `_.sampleSize` for arrays.
3576      *
3577      * @private
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.
3581      */
3582     function arraySampleSize(array, n) {
3583       return shuffleSelf(copyArray(array), baseClamp(n, 0, array.length));
3584     }
3585
3586     /**
3587      * A specialized version of `_.shuffle` for arrays.
3588      *
3589      * @private
3590      * @param {Array} array The array to shuffle.
3591      * @returns {Array} Returns the new shuffled array.
3592      */
3593     function arrayShuffle(array) {
3594       return shuffleSelf(copyArray(array));
3595     }
3596
3597     /**
3598      * This function is like `assignValue` except that it doesn't assign
3599      * `undefined` values.
3600      *
3601      * @private
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.
3605      */
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);
3610       }
3611     }
3612
3613     /**
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.
3617      *
3618      * @private
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.
3622      */
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);
3628       }
3629     }
3630
3631     /**
3632      * Gets the index at which the `key` is found in `array` of key-value pairs.
3633      *
3634      * @private
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`.
3638      */
3639     function assocIndexOf(array, key) {
3640       var length = array.length;
3641       while (length--) {
3642         if (eq(array[length][0], key)) {
3643           return length;
3644         }
3645       }
3646       return -1;
3647     }
3648
3649     /**
3650      * Aggregates elements of `collection` on `accumulator` with keys transformed
3651      * by `iteratee` and values set by `setter`.
3652      *
3653      * @private
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`.
3659      */
3660     function baseAggregator(collection, setter, iteratee, accumulator) {
3661       baseEach(collection, function(value, key, collection) {
3662         setter(accumulator, value, iteratee(value), collection);
3663       });
3664       return accumulator;
3665     }
3666
3667     /**
3668      * The base implementation of `_.assign` without support for multiple sources
3669      * or `customizer` functions.
3670      *
3671      * @private
3672      * @param {Object} object The destination object.
3673      * @param {Object} source The source object.
3674      * @returns {Object} Returns `object`.
3675      */
3676     function baseAssign(object, source) {
3677       return object && copyObject(source, keys(source), object);
3678     }
3679
3680     /**
3681      * The base implementation of `_.assignIn` without support for multiple sources
3682      * or `customizer` functions.
3683      *
3684      * @private
3685      * @param {Object} object The destination object.
3686      * @param {Object} source The source object.
3687      * @returns {Object} Returns `object`.
3688      */
3689     function baseAssignIn(object, source) {
3690       return object && copyObject(source, keysIn(source), object);
3691     }
3692
3693     /**
3694      * The base implementation of `assignValue` and `assignMergeValue` without
3695      * value checks.
3696      *
3697      * @private
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.
3701      */
3702     function baseAssignValue(object, key, value) {
3703       if (key == '__proto__' && defineProperty) {
3704         defineProperty(object, key, {
3705           'configurable': true,
3706           'enumerable': true,
3707           'value': value,
3708           'writable': true
3709         });
3710       } else {
3711         object[key] = value;
3712       }
3713     }
3714
3715     /**
3716      * The base implementation of `_.at` without support for individual paths.
3717      *
3718      * @private
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.
3722      */
3723     function baseAt(object, paths) {
3724       var index = -1,
3725           length = paths.length,
3726           result = Array(length),
3727           skip = object == null;
3728
3729       while (++index < length) {
3730         result[index] = skip ? undefined : get(object, paths[index]);
3731       }
3732       return result;
3733     }
3734
3735     /**
3736      * The base implementation of `_.clamp` which doesn't coerce arguments.
3737      *
3738      * @private
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.
3743      */
3744     function baseClamp(number, lower, upper) {
3745       if (number === number) {
3746         if (upper !== undefined) {
3747           number = number <= upper ? number : upper;
3748         }
3749         if (lower !== undefined) {
3750           number = number >= lower ? number : lower;
3751         }
3752       }
3753       return number;
3754     }
3755
3756     /**
3757      * The base implementation of `_.clone` and `_.cloneDeep` which tracks
3758      * traversed objects.
3759      *
3760      * @private
3761      * @param {*} value The value to clone.
3762      * @param {boolean} bitmask The bitmask flags.
3763      *  1 - Deep clone
3764      *  2 - Flatten inherited properties
3765      *  4 - Clone symbols
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.
3771      */
3772     function baseClone(value, bitmask, customizer, key, object, stack) {
3773       var result,
3774           isDeep = bitmask & CLONE_DEEP_FLAG,
3775           isFlat = bitmask & CLONE_FLAT_FLAG,
3776           isFull = bitmask & CLONE_SYMBOLS_FLAG;
3777
3778       if (customizer) {
3779         result = object ? customizer(value, key, object, stack) : customizer(value);
3780       }
3781       if (result !== undefined) {
3782         return result;
3783       }
3784       if (!isObject(value)) {
3785         return value;
3786       }
3787       var isArr = isArray(value);
3788       if (isArr) {
3789         result = initCloneArray(value);
3790         if (!isDeep) {
3791           return copyArray(value, result);
3792         }
3793       } else {
3794         var tag = getTag(value),
3795             isFunc = tag == funcTag || tag == genTag;
3796
3797         if (isBuffer(value)) {
3798           return cloneBuffer(value, isDeep);
3799         }
3800         if (tag == objectTag || tag == argsTag || (isFunc && !object)) {
3801           result = (isFlat || isFunc) ? {} : initCloneObject(value);
3802           if (!isDeep) {
3803             return isFlat
3804               ? copySymbolsIn(value, baseAssignIn(result, value))
3805               : copySymbols(value, baseAssign(result, value));
3806           }
3807         } else {
3808           if (!cloneableTags[tag]) {
3809             return object ? value : {};
3810           }
3811           result = initCloneByTag(value, tag, isDeep);
3812         }
3813       }
3814       // Check for circular references and return its corresponding clone.
3815       stack || (stack = new Stack);
3816       var stacked = stack.get(value);
3817       if (stacked) {
3818         return stacked;
3819       }
3820       stack.set(value, result);
3821
3822       if (isSet(value)) {
3823         value.forEach(function(subValue) {
3824           result.add(baseClone(subValue, bitmask, customizer, subValue, value, stack));
3825         });
3826       } else if (isMap(value)) {
3827         value.forEach(function(subValue, key) {
3828           result.set(key, baseClone(subValue, bitmask, customizer, key, value, stack));
3829         });
3830       }
3831
3832       var keysFunc = isFull
3833         ? (isFlat ? getAllKeysIn : getAllKeys)
3834         : (isFlat ? keysIn : keys);
3835
3836       var props = isArr ? undefined : keysFunc(value);
3837       arrayEach(props || value, function(subValue, key) {
3838         if (props) {
3839           key = subValue;
3840           subValue = value[key];
3841         }
3842         // Recursively populate clone (susceptible to call stack limits).
3843         assignValue(result, key, baseClone(subValue, bitmask, customizer, key, value, stack));
3844       });
3845       return result;
3846     }
3847
3848     /**
3849      * The base implementation of `_.conforms` which doesn't clone `source`.
3850      *
3851      * @private
3852      * @param {Object} source The object of property predicates to conform to.
3853      * @returns {Function} Returns the new spec function.
3854      */
3855     function baseConforms(source) {
3856       var props = keys(source);
3857       return function(object) {
3858         return baseConformsTo(object, source, props);
3859       };
3860     }
3861
3862     /**
3863      * The base implementation of `_.conformsTo` which accepts `props` to check.
3864      *
3865      * @private
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`.
3869      */
3870     function baseConformsTo(object, source, props) {
3871       var length = props.length;
3872       if (object == null) {
3873         return !length;
3874       }
3875       object = Object(object);
3876       while (length--) {
3877         var key = props[length],
3878             predicate = source[key],
3879             value = object[key];
3880
3881         if ((value === undefined && !(key in object)) || !predicate(value)) {
3882           return false;
3883         }
3884       }
3885       return true;
3886     }
3887
3888     /**
3889      * The base implementation of `_.delay` and `_.defer` which accepts `args`
3890      * to provide to `func`.
3891      *
3892      * @private
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.
3897      */
3898     function baseDelay(func, wait, args) {
3899       if (typeof func != 'function') {
3900         throw new TypeError(FUNC_ERROR_TEXT);
3901       }
3902       return setTimeout(function() { func.apply(undefined, args); }, wait);
3903     }
3904
3905     /**
3906      * The base implementation of methods like `_.difference` without support
3907      * for excluding multiple arrays or iteratee shorthands.
3908      *
3909      * @private
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.
3915      */
3916     function baseDifference(array, values, iteratee, comparator) {
3917       var index = -1,
3918           includes = arrayIncludes,
3919           isCommon = true,
3920           length = array.length,
3921           result = [],
3922           valuesLength = values.length;
3923
3924       if (!length) {
3925         return result;
3926       }
3927       if (iteratee) {
3928         values = arrayMap(values, baseUnary(iteratee));
3929       }
3930       if (comparator) {
3931         includes = arrayIncludesWith;
3932         isCommon = false;
3933       }
3934       else if (values.length >= LARGE_ARRAY_SIZE) {
3935         includes = cacheHas;
3936         isCommon = false;
3937         values = new SetCache(values);
3938       }
3939       outer:
3940       while (++index < length) {
3941         var value = array[index],
3942             computed = iteratee == null ? value : iteratee(value);
3943
3944         value = (comparator || value !== 0) ? value : 0;
3945         if (isCommon && computed === computed) {
3946           var valuesIndex = valuesLength;
3947           while (valuesIndex--) {
3948             if (values[valuesIndex] === computed) {
3949               continue outer;
3950             }
3951           }
3952           result.push(value);
3953         }
3954         else if (!includes(values, computed, comparator)) {
3955           result.push(value);
3956         }
3957       }
3958       return result;
3959     }
3960
3961     /**
3962      * The base implementation of `_.forEach` without support for iteratee shorthands.
3963      *
3964      * @private
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`.
3968      */
3969     var baseEach = createBaseEach(baseForOwn);
3970
3971     /**
3972      * The base implementation of `_.forEachRight` without support for iteratee shorthands.
3973      *
3974      * @private
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`.
3978      */
3979     var baseEachRight = createBaseEach(baseForOwnRight, true);
3980
3981     /**
3982      * The base implementation of `_.every` without support for iteratee shorthands.
3983      *
3984      * @private
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,
3988      *  else `false`
3989      */
3990     function baseEvery(collection, predicate) {
3991       var result = true;
3992       baseEach(collection, function(value, index, collection) {
3993         result = !!predicate(value, index, collection);
3994         return result;
3995       });
3996       return result;
3997     }
3998
3999     /**
4000      * The base implementation of methods like `_.max` and `_.min` which accepts a
4001      * `comparator` to determine the extremum value.
4002      *
4003      * @private
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.
4008      */
4009     function baseExtremum(array, iteratee, comparator) {
4010       var index = -1,
4011           length = array.length;
4012
4013       while (++index < length) {
4014         var value = array[index],
4015             current = iteratee(value);
4016
4017         if (current != null && (computed === undefined
4018               ? (current === current && !isSymbol(current))
4019               : comparator(current, computed)
4020             )) {
4021           var computed = current,
4022               result = value;
4023         }
4024       }
4025       return result;
4026     }
4027
4028     /**
4029      * The base implementation of `_.fill` without an iteratee call guard.
4030      *
4031      * @private
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`.
4037      */
4038     function baseFill(array, value, start, end) {
4039       var length = array.length;
4040
4041       start = toInteger(start);
4042       if (start < 0) {
4043         start = -start > length ? 0 : (length + start);
4044       }
4045       end = (end === undefined || end > length) ? length : toInteger(end);
4046       if (end < 0) {
4047         end += length;
4048       }
4049       end = start > end ? 0 : toLength(end);
4050       while (start < end) {
4051         array[start++] = value;
4052       }
4053       return array;
4054     }
4055
4056     /**
4057      * The base implementation of `_.filter` without support for iteratee shorthands.
4058      *
4059      * @private
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.
4063      */
4064     function baseFilter(collection, predicate) {
4065       var result = [];
4066       baseEach(collection, function(value, index, collection) {
4067         if (predicate(value, index, collection)) {
4068           result.push(value);
4069         }
4070       });
4071       return result;
4072     }
4073
4074     /**
4075      * The base implementation of `_.flatten` with support for restricting flattening.
4076      *
4077      * @private
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.
4084      */
4085     function baseFlatten(array, depth, predicate, isStrict, result) {
4086       var index = -1,
4087           length = array.length;
4088
4089       predicate || (predicate = isFlattenable);
4090       result || (result = []);
4091
4092       while (++index < length) {
4093         var value = array[index];
4094         if (depth > 0 && predicate(value)) {
4095           if (depth > 1) {
4096             // Recursively flatten arrays (susceptible to call stack limits).
4097             baseFlatten(value, depth - 1, predicate, isStrict, result);
4098           } else {
4099             arrayPush(result, value);
4100           }
4101         } else if (!isStrict) {
4102           result[result.length] = value;
4103         }
4104       }
4105       return result;
4106     }
4107
4108     /**
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`.
4112      *
4113      * @private
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`.
4118      */
4119     var baseFor = createBaseFor();
4120
4121     /**
4122      * This function is like `baseFor` except that it iterates over properties
4123      * in the opposite order.
4124      *
4125      * @private
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`.
4130      */
4131     var baseForRight = createBaseFor(true);
4132
4133     /**
4134      * The base implementation of `_.forOwn` without support for iteratee shorthands.
4135      *
4136      * @private
4137      * @param {Object} object The object to iterate over.
4138      * @param {Function} iteratee The function invoked per iteration.
4139      * @returns {Object} Returns `object`.
4140      */
4141     function baseForOwn(object, iteratee) {
4142       return object && baseFor(object, iteratee, keys);
4143     }
4144
4145     /**
4146      * The base implementation of `_.forOwnRight` without support for iteratee shorthands.
4147      *
4148      * @private
4149      * @param {Object} object The object to iterate over.
4150      * @param {Function} iteratee The function invoked per iteration.
4151      * @returns {Object} Returns `object`.
4152      */
4153     function baseForOwnRight(object, iteratee) {
4154       return object && baseForRight(object, iteratee, keys);
4155     }
4156
4157     /**
4158      * The base implementation of `_.functions` which creates an array of
4159      * `object` function property names filtered from `props`.
4160      *
4161      * @private
4162      * @param {Object} object The object to inspect.
4163      * @param {Array} props The property names to filter.
4164      * @returns {Array} Returns the function names.
4165      */
4166     function baseFunctions(object, props) {
4167       return arrayFilter(props, function(key) {
4168         return isFunction(object[key]);
4169       });
4170     }
4171
4172     /**
4173      * The base implementation of `_.get` without support for default values.
4174      *
4175      * @private
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.
4179      */
4180     function baseGet(object, path) {
4181       path = castPath(path, object);
4182
4183       var index = 0,
4184           length = path.length;
4185
4186       while (object != null && index < length) {
4187         object = object[toKey(path[index++])];
4188       }
4189       return (index && index == length) ? object : undefined;
4190     }
4191
4192     /**
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`.
4196      *
4197      * @private
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.
4202      */
4203     function baseGetAllKeys(object, keysFunc, symbolsFunc) {
4204       var result = keysFunc(object);
4205       return isArray(object) ? result : arrayPush(result, symbolsFunc(object));
4206     }
4207
4208     /**
4209      * The base implementation of `getTag` without fallbacks for buggy environments.
4210      *
4211      * @private
4212      * @param {*} value The value to query.
4213      * @returns {string} Returns the `toStringTag`.
4214      */
4215     function baseGetTag(value) {
4216       if (value == null) {
4217         return value === undefined ? undefinedTag : nullTag;
4218       }
4219       return (symToStringTag && symToStringTag in Object(value))
4220         ? getRawTag(value)
4221         : objectToString(value);
4222     }
4223
4224     /**
4225      * The base implementation of `_.gt` which doesn't coerce arguments.
4226      *
4227      * @private
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`,
4231      *  else `false`.
4232      */
4233     function baseGt(value, other) {
4234       return value > other;
4235     }
4236
4237     /**
4238      * The base implementation of `_.has` without support for deep paths.
4239      *
4240      * @private
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`.
4244      */
4245     function baseHas(object, key) {
4246       return object != null && hasOwnProperty.call(object, key);
4247     }
4248
4249     /**
4250      * The base implementation of `_.hasIn` without support for deep paths.
4251      *
4252      * @private
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`.
4256      */
4257     function baseHasIn(object, key) {
4258       return object != null && key in Object(object);
4259     }
4260
4261     /**
4262      * The base implementation of `_.inRange` which doesn't coerce arguments.
4263      *
4264      * @private
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`.
4269      */
4270     function baseInRange(number, start, end) {
4271       return number >= nativeMin(start, end) && number < nativeMax(start, end);
4272     }
4273
4274     /**
4275      * The base implementation of methods like `_.intersection`, without support
4276      * for iteratee shorthands, that accepts an array of arrays to inspect.
4277      *
4278      * @private
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.
4283      */
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,
4291           result = [];
4292
4293       while (othIndex--) {
4294         var array = arrays[othIndex];
4295         if (othIndex && iteratee) {
4296           array = arrayMap(array, baseUnary(iteratee));
4297         }
4298         maxLength = nativeMin(array.length, maxLength);
4299         caches[othIndex] = !comparator && (iteratee || (length >= 120 && array.length >= 120))
4300           ? new SetCache(othIndex && array)
4301           : undefined;
4302       }
4303       array = arrays[0];
4304
4305       var index = -1,
4306           seen = caches[0];
4307
4308       outer:
4309       while (++index < length && result.length < maxLength) {
4310         var value = array[index],
4311             computed = iteratee ? iteratee(value) : value;
4312
4313         value = (comparator || value !== 0) ? value : 0;
4314         if (!(seen
4315               ? cacheHas(seen, computed)
4316               : includes(result, computed, comparator)
4317             )) {
4318           othIndex = othLength;
4319           while (--othIndex) {
4320             var cache = caches[othIndex];
4321             if (!(cache
4322                   ? cacheHas(cache, computed)
4323                   : includes(arrays[othIndex], computed, comparator))
4324                 ) {
4325               continue outer;
4326             }
4327           }
4328           if (seen) {
4329             seen.push(computed);
4330           }
4331           result.push(value);
4332         }
4333       }
4334       return result;
4335     }
4336
4337     /**
4338      * The base implementation of `_.invert` and `_.invertBy` which inverts
4339      * `object` with values transformed by `iteratee` and set by `setter`.
4340      *
4341      * @private
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`.
4347      */
4348     function baseInverter(object, setter, iteratee, accumulator) {
4349       baseForOwn(object, function(value, key, object) {
4350         setter(accumulator, iteratee(value), key, object);
4351       });
4352       return accumulator;
4353     }
4354
4355     /**
4356      * The base implementation of `_.invoke` without support for individual
4357      * method arguments.
4358      *
4359      * @private
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.
4364      */
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);
4370     }
4371
4372     /**
4373      * The base implementation of `_.isArguments`.
4374      *
4375      * @private
4376      * @param {*} value The value to check.
4377      * @returns {boolean} Returns `true` if `value` is an `arguments` object,
4378      */
4379     function baseIsArguments(value) {
4380       return isObjectLike(value) && baseGetTag(value) == argsTag;
4381     }
4382
4383     /**
4384      * The base implementation of `_.isArrayBuffer` without Node.js optimizations.
4385      *
4386      * @private
4387      * @param {*} value The value to check.
4388      * @returns {boolean} Returns `true` if `value` is an array buffer, else `false`.
4389      */
4390     function baseIsArrayBuffer(value) {
4391       return isObjectLike(value) && baseGetTag(value) == arrayBufferTag;
4392     }
4393
4394     /**
4395      * The base implementation of `_.isDate` without Node.js optimizations.
4396      *
4397      * @private
4398      * @param {*} value The value to check.
4399      * @returns {boolean} Returns `true` if `value` is a date object, else `false`.
4400      */
4401     function baseIsDate(value) {
4402       return isObjectLike(value) && baseGetTag(value) == dateTag;
4403     }
4404
4405     /**
4406      * The base implementation of `_.isEqual` which supports partial comparisons
4407      * and tracks traversed objects.
4408      *
4409      * @private
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`.
4418      */
4419     function baseIsEqual(value, other, bitmask, customizer, stack) {
4420       if (value === other) {
4421         return true;
4422       }
4423       if (value == null || other == null || (!isObjectLike(value) && !isObjectLike(other))) {
4424         return value !== value && other !== other;
4425       }
4426       return baseIsEqualDeep(value, other, bitmask, customizer, baseIsEqual, stack);
4427     }
4428
4429     /**
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.
4433      *
4434      * @private
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`.
4442      */
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);
4448
4449       objTag = objTag == argsTag ? objectTag : objTag;
4450       othTag = othTag == argsTag ? objectTag : othTag;
4451
4452       var objIsObj = objTag == objectTag,
4453           othIsObj = othTag == objectTag,
4454           isSameTag = objTag == othTag;
4455
4456       if (isSameTag && isBuffer(object)) {
4457         if (!isBuffer(other)) {
4458           return false;
4459         }
4460         objIsArr = true;
4461         objIsObj = false;
4462       }
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);
4468       }
4469       if (!(bitmask & COMPARE_PARTIAL_FLAG)) {
4470         var objIsWrapped = objIsObj && hasOwnProperty.call(object, '__wrapped__'),
4471             othIsWrapped = othIsObj && hasOwnProperty.call(other, '__wrapped__');
4472
4473         if (objIsWrapped || othIsWrapped) {
4474           var objUnwrapped = objIsWrapped ? object.value() : object,
4475               othUnwrapped = othIsWrapped ? other.value() : other;
4476
4477           stack || (stack = new Stack);
4478           return equalFunc(objUnwrapped, othUnwrapped, bitmask, customizer, stack);
4479         }
4480       }
4481       if (!isSameTag) {
4482         return false;
4483       }
4484       stack || (stack = new Stack);
4485       return equalObjects(object, other, bitmask, customizer, equalFunc, stack);
4486     }
4487
4488     /**
4489      * The base implementation of `_.isMap` without Node.js optimizations.
4490      *
4491      * @private
4492      * @param {*} value The value to check.
4493      * @returns {boolean} Returns `true` if `value` is a map, else `false`.
4494      */
4495     function baseIsMap(value) {
4496       return isObjectLike(value) && getTag(value) == mapTag;
4497     }
4498
4499     /**
4500      * The base implementation of `_.isMatch` without support for iteratee shorthands.
4501      *
4502      * @private
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`.
4508      */
4509     function baseIsMatch(object, source, matchData, customizer) {
4510       var index = matchData.length,
4511           length = index,
4512           noCustomizer = !customizer;
4513
4514       if (object == null) {
4515         return !length;
4516       }
4517       object = Object(object);
4518       while (index--) {
4519         var data = matchData[index];
4520         if ((noCustomizer && data[2])
4521               ? data[1] !== object[data[0]]
4522               : !(data[0] in object)
4523             ) {
4524           return false;
4525         }
4526       }
4527       while (++index < length) {
4528         data = matchData[index];
4529         var key = data[0],
4530             objValue = object[key],
4531             srcValue = data[1];
4532
4533         if (noCustomizer && data[2]) {
4534           if (objValue === undefined && !(key in object)) {
4535             return false;
4536           }
4537         } else {
4538           var stack = new Stack;
4539           if (customizer) {
4540             var result = customizer(objValue, srcValue, key, object, source, stack);
4541           }
4542           if (!(result === undefined
4543                 ? baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG | COMPARE_UNORDERED_FLAG, customizer, stack)
4544                 : result
4545               )) {
4546             return false;
4547           }
4548         }
4549       }
4550       return true;
4551     }
4552
4553     /**
4554      * The base implementation of `_.isNative` without bad shim checks.
4555      *
4556      * @private
4557      * @param {*} value The value to check.
4558      * @returns {boolean} Returns `true` if `value` is a native function,
4559      *  else `false`.
4560      */
4561     function baseIsNative(value) {
4562       if (!isObject(value) || isMasked(value)) {
4563         return false;
4564       }
4565       var pattern = isFunction(value) ? reIsNative : reIsHostCtor;
4566       return pattern.test(toSource(value));
4567     }
4568
4569     /**
4570      * The base implementation of `_.isRegExp` without Node.js optimizations.
4571      *
4572      * @private
4573      * @param {*} value The value to check.
4574      * @returns {boolean} Returns `true` if `value` is a regexp, else `false`.
4575      */
4576     function baseIsRegExp(value) {
4577       return isObjectLike(value) && baseGetTag(value) == regexpTag;
4578     }
4579
4580     /**
4581      * The base implementation of `_.isSet` without Node.js optimizations.
4582      *
4583      * @private
4584      * @param {*} value The value to check.
4585      * @returns {boolean} Returns `true` if `value` is a set, else `false`.
4586      */
4587     function baseIsSet(value) {
4588       return isObjectLike(value) && getTag(value) == setTag;
4589     }
4590
4591     /**
4592      * The base implementation of `_.isTypedArray` without Node.js optimizations.
4593      *
4594      * @private
4595      * @param {*} value The value to check.
4596      * @returns {boolean} Returns `true` if `value` is a typed array, else `false`.
4597      */
4598     function baseIsTypedArray(value) {
4599       return isObjectLike(value) &&
4600         isLength(value.length) && !!typedArrayTags[baseGetTag(value)];
4601     }
4602
4603     /**
4604      * The base implementation of `_.iteratee`.
4605      *
4606      * @private
4607      * @param {*} [value=_.identity] The value to convert to an iteratee.
4608      * @returns {Function} Returns the iteratee.
4609      */
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') {
4614         return value;
4615       }
4616       if (value == null) {
4617         return identity;
4618       }
4619       if (typeof value == 'object') {
4620         return isArray(value)
4621           ? baseMatchesProperty(value[0], value[1])
4622           : baseMatches(value);
4623       }
4624       return property(value);
4625     }
4626
4627     /**
4628      * The base implementation of `_.keys` which doesn't treat sparse arrays as dense.
4629      *
4630      * @private
4631      * @param {Object} object The object to query.
4632      * @returns {Array} Returns the array of property names.
4633      */
4634     function baseKeys(object) {
4635       if (!isPrototype(object)) {
4636         return nativeKeys(object);
4637       }
4638       var result = [];
4639       for (var key in Object(object)) {
4640         if (hasOwnProperty.call(object, key) && key != 'constructor') {
4641           result.push(key);
4642         }
4643       }
4644       return result;
4645     }
4646
4647     /**
4648      * The base implementation of `_.keysIn` which doesn't treat sparse arrays as dense.
4649      *
4650      * @private
4651      * @param {Object} object The object to query.
4652      * @returns {Array} Returns the array of property names.
4653      */
4654     function baseKeysIn(object) {
4655       if (!isObject(object)) {
4656         return nativeKeysIn(object);
4657       }
4658       var isProto = isPrototype(object),
4659           result = [];
4660
4661       for (var key in object) {
4662         if (!(key == 'constructor' && (isProto || !hasOwnProperty.call(object, key)))) {
4663           result.push(key);
4664         }
4665       }
4666       return result;
4667     }
4668
4669     /**
4670      * The base implementation of `_.lt` which doesn't coerce arguments.
4671      *
4672      * @private
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`,
4676      *  else `false`.
4677      */
4678     function baseLt(value, other) {
4679       return value < other;
4680     }
4681
4682     /**
4683      * The base implementation of `_.map` without support for iteratee shorthands.
4684      *
4685      * @private
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.
4689      */
4690     function baseMap(collection, iteratee) {
4691       var index = -1,
4692           result = isArrayLike(collection) ? Array(collection.length) : [];
4693
4694       baseEach(collection, function(value, key, collection) {
4695         result[++index] = iteratee(value, key, collection);
4696       });
4697       return result;
4698     }
4699
4700     /**
4701      * The base implementation of `_.matches` which doesn't clone `source`.
4702      *
4703      * @private
4704      * @param {Object} source The object of property values to match.
4705      * @returns {Function} Returns the new spec function.
4706      */
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]);
4711       }
4712       return function(object) {
4713         return object === source || baseIsMatch(object, source, matchData);
4714       };
4715     }
4716
4717     /**
4718      * The base implementation of `_.matchesProperty` which doesn't clone `srcValue`.
4719      *
4720      * @private
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.
4724      */
4725     function baseMatchesProperty(path, srcValue) {
4726       if (isKey(path) && isStrictComparable(srcValue)) {
4727         return matchesStrictComparable(toKey(path), srcValue);
4728       }
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);
4734       };
4735     }
4736
4737     /**
4738      * The base implementation of `_.merge` without support for multiple sources.
4739      *
4740      * @private
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
4746      *  counterparts.
4747      */
4748     function baseMerge(object, source, srcIndex, customizer, stack) {
4749       if (object === source) {
4750         return;
4751       }
4752       baseFor(source, function(srcValue, key) {
4753         stack || (stack = new Stack);
4754         if (isObject(srcValue)) {
4755           baseMergeDeep(object, source, key, srcIndex, baseMerge, customizer, stack);
4756         }
4757         else {
4758           var newValue = customizer
4759             ? customizer(safeGet(object, key), srcValue, (key + ''), object, source, stack)
4760             : undefined;
4761
4762           if (newValue === undefined) {
4763             newValue = srcValue;
4764           }
4765           assignMergeValue(object, key, newValue);
4766         }
4767       }, keysIn);
4768     }
4769
4770     /**
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.
4774      *
4775      * @private
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
4783      *  counterparts.
4784      */
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);
4789
4790       if (stacked) {
4791         assignMergeValue(object, key, stacked);
4792         return;
4793       }
4794       var newValue = customizer
4795         ? customizer(objValue, srcValue, (key + ''), object, source, stack)
4796         : undefined;
4797
4798       var isCommon = newValue === undefined;
4799
4800       if (isCommon) {
4801         var isArr = isArray(srcValue),
4802             isBuff = !isArr && isBuffer(srcValue),
4803             isTyped = !isArr && !isBuff && isTypedArray(srcValue);
4804
4805         newValue = srcValue;
4806         if (isArr || isBuff || isTyped) {
4807           if (isArray(objValue)) {
4808             newValue = objValue;
4809           }
4810           else if (isArrayLikeObject(objValue)) {
4811             newValue = copyArray(objValue);
4812           }
4813           else if (isBuff) {
4814             isCommon = false;
4815             newValue = cloneBuffer(srcValue, true);
4816           }
4817           else if (isTyped) {
4818             isCommon = false;
4819             newValue = cloneTypedArray(srcValue, true);
4820           }
4821           else {
4822             newValue = [];
4823           }
4824         }
4825         else if (isPlainObject(srcValue) || isArguments(srcValue)) {
4826           newValue = objValue;
4827           if (isArguments(objValue)) {
4828             newValue = toPlainObject(objValue);
4829           }
4830           else if (!isObject(objValue) || isFunction(objValue)) {
4831             newValue = initCloneObject(srcValue);
4832           }
4833         }
4834         else {
4835           isCommon = false;
4836         }
4837       }
4838       if (isCommon) {
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);
4843       }
4844       assignMergeValue(object, key, newValue);
4845     }
4846
4847     /**
4848      * The base implementation of `_.nth` which doesn't coerce arguments.
4849      *
4850      * @private
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`.
4854      */
4855     function baseNth(array, n) {
4856       var length = array.length;
4857       if (!length) {
4858         return;
4859       }
4860       n += n < 0 ? length : 0;
4861       return isIndex(n, length) ? array[n] : undefined;
4862     }
4863
4864     /**
4865      * The base implementation of `_.orderBy` without param guards.
4866      *
4867      * @private
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.
4872      */
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);
4879             }
4880           }
4881           return iteratee;
4882         });
4883       } else {
4884         iteratees = [identity];
4885       }
4886
4887       var index = -1;
4888       iteratees = arrayMap(iteratees, baseUnary(getIteratee()));
4889
4890       var result = baseMap(collection, function(value, key, collection) {
4891         var criteria = arrayMap(iteratees, function(iteratee) {
4892           return iteratee(value);
4893         });
4894         return { 'criteria': criteria, 'index': ++index, 'value': value };
4895       });
4896
4897       return baseSortBy(result, function(object, other) {
4898         return compareMultiple(object, other, orders);
4899       });
4900     }
4901
4902     /**
4903      * The base implementation of `_.pick` without support for individual
4904      * property identifiers.
4905      *
4906      * @private
4907      * @param {Object} object The source object.
4908      * @param {string[]} paths The property paths to pick.
4909      * @returns {Object} Returns the new object.
4910      */
4911     function basePick(object, paths) {
4912       return basePickBy(object, paths, function(value, path) {
4913         return hasIn(object, path);
4914       });
4915     }
4916
4917     /**
4918      * The base implementation of  `_.pickBy` without support for iteratee shorthands.
4919      *
4920      * @private
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.
4925      */
4926     function basePickBy(object, paths, predicate) {
4927       var index = -1,
4928           length = paths.length,
4929           result = {};
4930
4931       while (++index < length) {
4932         var path = paths[index],
4933             value = baseGet(object, path);
4934
4935         if (predicate(value, path)) {
4936           baseSet(result, castPath(path, object), value);
4937         }
4938       }
4939       return result;
4940     }
4941
4942     /**
4943      * A specialized version of `baseProperty` which supports deep paths.
4944      *
4945      * @private
4946      * @param {Array|string} path The path of the property to get.
4947      * @returns {Function} Returns the new accessor function.
4948      */
4949     function basePropertyDeep(path) {
4950       return function(object) {
4951         return baseGet(object, path);
4952       };
4953     }
4954
4955     /**
4956      * The base implementation of `_.pullAllBy` without support for iteratee
4957      * shorthands.
4958      *
4959      * @private
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`.
4965      */
4966     function basePullAll(array, values, iteratee, comparator) {
4967       var indexOf = comparator ? baseIndexOfWith : baseIndexOf,
4968           index = -1,
4969           length = values.length,
4970           seen = array;
4971
4972       if (array === values) {
4973         values = copyArray(values);
4974       }
4975       if (iteratee) {
4976         seen = arrayMap(array, baseUnary(iteratee));
4977       }
4978       while (++index < length) {
4979         var fromIndex = 0,
4980             value = values[index],
4981             computed = iteratee ? iteratee(value) : value;
4982
4983         while ((fromIndex = indexOf(seen, computed, fromIndex, comparator)) > -1) {
4984           if (seen !== array) {
4985             splice.call(seen, fromIndex, 1);
4986           }
4987           splice.call(array, fromIndex, 1);
4988         }
4989       }
4990       return array;
4991     }
4992
4993     /**
4994      * The base implementation of `_.pullAt` without support for individual
4995      * indexes or capturing the removed elements.
4996      *
4997      * @private
4998      * @param {Array} array The array to modify.
4999      * @param {number[]} indexes The indexes of elements to remove.
5000      * @returns {Array} Returns `array`.
5001      */
5002     function basePullAt(array, indexes) {
5003       var length = array ? indexes.length : 0,
5004           lastIndex = length - 1;
5005
5006       while (length--) {
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);
5012           } else {
5013             baseUnset(array, index);
5014           }
5015         }
5016       }
5017       return array;
5018     }
5019
5020     /**
5021      * The base implementation of `_.random` without support for returning
5022      * floating-point numbers.
5023      *
5024      * @private
5025      * @param {number} lower The lower bound.
5026      * @param {number} upper The upper bound.
5027      * @returns {number} Returns the random number.
5028      */
5029     function baseRandom(lower, upper) {
5030       return lower + nativeFloor(nativeRandom() * (upper - lower + 1));
5031     }
5032
5033     /**
5034      * The base implementation of `_.range` and `_.rangeRight` which doesn't
5035      * coerce arguments.
5036      *
5037      * @private
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.
5043      */
5044     function baseRange(start, end, step, fromRight) {
5045       var index = -1,
5046           length = nativeMax(nativeCeil((end - start) / (step || 1)), 0),
5047           result = Array(length);
5048
5049       while (length--) {
5050         result[fromRight ? length : ++index] = start;
5051         start += step;
5052       }
5053       return result;
5054     }
5055
5056     /**
5057      * The base implementation of `_.repeat` which doesn't coerce arguments.
5058      *
5059      * @private
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.
5063      */
5064     function baseRepeat(string, n) {
5065       var result = '';
5066       if (!string || n < 1 || n > MAX_SAFE_INTEGER) {
5067         return result;
5068       }
5069       // Leverage the exponentiation by squaring algorithm for a faster repeat.
5070       // See https://en.wikipedia.org/wiki/Exponentiation_by_squaring for more details.
5071       do {
5072         if (n % 2) {
5073           result += string;
5074         }
5075         n = nativeFloor(n / 2);
5076         if (n) {
5077           string += string;
5078         }
5079       } while (n);
5080
5081       return result;
5082     }
5083
5084     /**
5085      * The base implementation of `_.rest` which doesn't validate or coerce arguments.
5086      *
5087      * @private
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.
5091      */
5092     function baseRest(func, start) {
5093       return setToString(overRest(func, start, identity), func + '');
5094     }
5095
5096     /**
5097      * The base implementation of `_.sample`.
5098      *
5099      * @private
5100      * @param {Array|Object} collection The collection to sample.
5101      * @returns {*} Returns the random element.
5102      */
5103     function baseSample(collection) {
5104       return arraySample(values(collection));
5105     }
5106
5107     /**
5108      * The base implementation of `_.sampleSize` without param guards.
5109      *
5110      * @private
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.
5114      */
5115     function baseSampleSize(collection, n) {
5116       var array = values(collection);
5117       return shuffleSelf(array, baseClamp(n, 0, array.length));
5118     }
5119
5120     /**
5121      * The base implementation of `_.set`.
5122      *
5123      * @private
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`.
5129      */
5130     function baseSet(object, path, value, customizer) {
5131       if (!isObject(object)) {
5132         return object;
5133       }
5134       path = castPath(path, object);
5135
5136       var index = -1,
5137           length = path.length,
5138           lastIndex = length - 1,
5139           nested = object;
5140
5141       while (nested != null && ++index < length) {
5142         var key = toKey(path[index]),
5143             newValue = value;
5144
5145         if (key === '__proto__' || key === 'constructor' || key === 'prototype') {
5146           return object;
5147         }
5148
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)
5154               ? objValue
5155               : (isIndex(path[index + 1]) ? [] : {});
5156           }
5157         }
5158         assignValue(nested, key, newValue);
5159         nested = nested[key];
5160       }
5161       return object;
5162     }
5163
5164     /**
5165      * The base implementation of `setData` without support for hot loop shorting.
5166      *
5167      * @private
5168      * @param {Function} func The function to associate metadata with.
5169      * @param {*} data The metadata.
5170      * @returns {Function} Returns `func`.
5171      */
5172     var baseSetData = !metaMap ? identity : function(func, data) {
5173       metaMap.set(func, data);
5174       return func;
5175     };
5176
5177     /**
5178      * The base implementation of `setToString` without support for hot loop shorting.
5179      *
5180      * @private
5181      * @param {Function} func The function to modify.
5182      * @param {Function} string The `toString` result.
5183      * @returns {Function} Returns `func`.
5184      */
5185     var baseSetToString = !defineProperty ? identity : function(func, string) {
5186       return defineProperty(func, 'toString', {
5187         'configurable': true,
5188         'enumerable': false,
5189         'value': constant(string),
5190         'writable': true
5191       });
5192     };
5193
5194     /**
5195      * The base implementation of `_.shuffle`.
5196      *
5197      * @private
5198      * @param {Array|Object} collection The collection to shuffle.
5199      * @returns {Array} Returns the new shuffled array.
5200      */
5201     function baseShuffle(collection) {
5202       return shuffleSelf(values(collection));
5203     }
5204
5205     /**
5206      * The base implementation of `_.slice` without an iteratee call guard.
5207      *
5208      * @private
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`.
5213      */
5214     function baseSlice(array, start, end) {
5215       var index = -1,
5216           length = array.length;
5217
5218       if (start < 0) {
5219         start = -start > length ? 0 : (length + start);
5220       }
5221       end = end > length ? length : end;
5222       if (end < 0) {
5223         end += length;
5224       }
5225       length = start > end ? 0 : ((end - start) >>> 0);
5226       start >>>= 0;
5227
5228       var result = Array(length);
5229       while (++index < length) {
5230         result[index] = array[index + start];
5231       }
5232       return result;
5233     }
5234
5235     /**
5236      * The base implementation of `_.some` without support for iteratee shorthands.
5237      *
5238      * @private
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,
5242      *  else `false`.
5243      */
5244     function baseSome(collection, predicate) {
5245       var result;
5246
5247       baseEach(collection, function(value, index, collection) {
5248         result = predicate(value, index, collection);
5249         return !result;
5250       });
5251       return !!result;
5252     }
5253
5254     /**
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.
5258      *
5259      * @private
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
5264      *  into `array`.
5265      */
5266     function baseSortedIndex(array, value, retHighest) {
5267       var low = 0,
5268           high = array == null ? low : array.length;
5269
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];
5274
5275           if (computed !== null && !isSymbol(computed) &&
5276               (retHighest ? (computed <= value) : (computed < value))) {
5277             low = mid + 1;
5278           } else {
5279             high = mid;
5280           }
5281         }
5282         return high;
5283       }
5284       return baseSortedIndexBy(array, value, identity, retHighest);
5285     }
5286
5287     /**
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).
5291      *
5292      * @private
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
5298      *  into `array`.
5299      */
5300     function baseSortedIndexBy(array, value, iteratee, retHighest) {
5301       var low = 0,
5302           high = array == null ? 0 : array.length;
5303       if (high === 0) {
5304         return 0;
5305       }
5306
5307       value = iteratee(value);
5308       var valIsNaN = value !== value,
5309           valIsNull = value === null,
5310           valIsSymbol = isSymbol(value),
5311           valIsUndefined = value === undefined;
5312
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);
5320
5321         if (valIsNaN) {
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) {
5330           setLow = false;
5331         } else {
5332           setLow = retHighest ? (computed <= value) : (computed < value);
5333         }
5334         if (setLow) {
5335           low = mid + 1;
5336         } else {
5337           high = mid;
5338         }
5339       }
5340       return nativeMin(high, MAX_ARRAY_INDEX);
5341     }
5342
5343     /**
5344      * The base implementation of `_.sortedUniq` and `_.sortedUniqBy` without
5345      * support for iteratee shorthands.
5346      *
5347      * @private
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.
5351      */
5352     function baseSortedUniq(array, iteratee) {
5353       var index = -1,
5354           length = array.length,
5355           resIndex = 0,
5356           result = [];
5357
5358       while (++index < length) {
5359         var value = array[index],
5360             computed = iteratee ? iteratee(value) : value;
5361
5362         if (!index || !eq(computed, seen)) {
5363           var seen = computed;
5364           result[resIndex++] = value === 0 ? 0 : value;
5365         }
5366       }
5367       return result;
5368     }
5369
5370     /**
5371      * The base implementation of `_.toNumber` which doesn't ensure correct
5372      * conversions of binary, hexadecimal, or octal string values.
5373      *
5374      * @private
5375      * @param {*} value The value to process.
5376      * @returns {number} Returns the number.
5377      */
5378     function baseToNumber(value) {
5379       if (typeof value == 'number') {
5380         return value;
5381       }
5382       if (isSymbol(value)) {
5383         return NAN;
5384       }
5385       return +value;
5386     }
5387
5388     /**
5389      * The base implementation of `_.toString` which doesn't convert nullish
5390      * values to empty strings.
5391      *
5392      * @private
5393      * @param {*} value The value to process.
5394      * @returns {string} Returns the string.
5395      */
5396     function baseToString(value) {
5397       // Exit early for strings to avoid a performance hit in some environments.
5398       if (typeof value == 'string') {
5399         return value;
5400       }
5401       if (isArray(value)) {
5402         // Recursively convert values (susceptible to call stack limits).
5403         return arrayMap(value, baseToString) + '';
5404       }
5405       if (isSymbol(value)) {
5406         return symbolToString ? symbolToString.call(value) : '';
5407       }
5408       var result = (value + '');
5409       return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;
5410     }
5411
5412     /**
5413      * The base implementation of `_.uniqBy` without support for iteratee shorthands.
5414      *
5415      * @private
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.
5420      */
5421     function baseUniq(array, iteratee, comparator) {
5422       var index = -1,
5423           includes = arrayIncludes,
5424           length = array.length,
5425           isCommon = true,
5426           result = [],
5427           seen = result;
5428
5429       if (comparator) {
5430         isCommon = false;
5431         includes = arrayIncludesWith;
5432       }
5433       else if (length >= LARGE_ARRAY_SIZE) {
5434         var set = iteratee ? null : createSet(array);
5435         if (set) {
5436           return setToArray(set);
5437         }
5438         isCommon = false;
5439         includes = cacheHas;
5440         seen = new SetCache;
5441       }
5442       else {
5443         seen = iteratee ? [] : result;
5444       }
5445       outer:
5446       while (++index < length) {
5447         var value = array[index],
5448             computed = iteratee ? iteratee(value) : value;
5449
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) {
5455               continue outer;
5456             }
5457           }
5458           if (iteratee) {
5459             seen.push(computed);
5460           }
5461           result.push(value);
5462         }
5463         else if (!includes(seen, computed, comparator)) {
5464           if (seen !== result) {
5465             seen.push(computed);
5466           }
5467           result.push(value);
5468         }
5469       }
5470       return result;
5471     }
5472
5473     /**
5474      * The base implementation of `_.unset`.
5475      *
5476      * @private
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`.
5480      */
5481     function baseUnset(object, path) {
5482       path = castPath(path, object);
5483       object = parent(object, path);
5484       return object == null || delete object[toKey(last(path))];
5485     }
5486
5487     /**
5488      * The base implementation of `_.update`.
5489      *
5490      * @private
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`.
5496      */
5497     function baseUpdate(object, path, updater, customizer) {
5498       return baseSet(object, path, updater(baseGet(object, path)), customizer);
5499     }
5500
5501     /**
5502      * The base implementation of methods like `_.dropWhile` and `_.takeWhile`
5503      * without support for iteratee shorthands.
5504      *
5505      * @private
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`.
5511      */
5512     function baseWhile(array, predicate, isDrop, fromRight) {
5513       var length = array.length,
5514           index = fromRight ? length : -1;
5515
5516       while ((fromRight ? index-- : ++index < length) &&
5517         predicate(array[index], index, array)) {}
5518
5519       return isDrop
5520         ? baseSlice(array, (fromRight ? 0 : index), (fromRight ? index + 1 : length))
5521         : baseSlice(array, (fromRight ? index + 1 : 0), (fromRight ? length : index));
5522     }
5523
5524     /**
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.
5528      *
5529      * @private
5530      * @param {*} value The unwrapped value.
5531      * @param {Array} actions Actions to perform to resolve the unwrapped value.
5532      * @returns {*} Returns the resolved value.
5533      */
5534     function baseWrapperValue(value, actions) {
5535       var result = value;
5536       if (result instanceof LazyWrapper) {
5537         result = result.value();
5538       }
5539       return arrayReduce(actions, function(result, action) {
5540         return action.func.apply(action.thisArg, arrayPush([result], action.args));
5541       }, result);
5542     }
5543
5544     /**
5545      * The base implementation of methods like `_.xor`, without support for
5546      * iteratee shorthands, that accepts an array of arrays to inspect.
5547      *
5548      * @private
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.
5553      */
5554     function baseXor(arrays, iteratee, comparator) {
5555       var length = arrays.length;
5556       if (length < 2) {
5557         return length ? baseUniq(arrays[0]) : [];
5558       }
5559       var index = -1,
5560           result = Array(length);
5561
5562       while (++index < length) {
5563         var array = arrays[index],
5564             othIndex = -1;
5565
5566         while (++othIndex < length) {
5567           if (othIndex != index) {
5568             result[index] = baseDifference(result[index] || array, arrays[othIndex], iteratee, comparator);
5569           }
5570         }
5571       }
5572       return baseUniq(baseFlatten(result, 1), iteratee, comparator);
5573     }
5574
5575     /**
5576      * This base implementation of `_.zipObject` which assigns values using `assignFunc`.
5577      *
5578      * @private
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.
5583      */
5584     function baseZipObject(props, values, assignFunc) {
5585       var index = -1,
5586           length = props.length,
5587           valsLength = values.length,
5588           result = {};
5589
5590       while (++index < length) {
5591         var value = index < valsLength ? values[index] : undefined;
5592         assignFunc(result, props[index], value);
5593       }
5594       return result;
5595     }
5596
5597     /**
5598      * Casts `value` to an empty array if it's not an array like object.
5599      *
5600      * @private
5601      * @param {*} value The value to inspect.
5602      * @returns {Array|Object} Returns the cast array-like object.
5603      */
5604     function castArrayLikeObject(value) {
5605       return isArrayLikeObject(value) ? value : [];
5606     }
5607
5608     /**
5609      * Casts `value` to `identity` if it's not a function.
5610      *
5611      * @private
5612      * @param {*} value The value to inspect.
5613      * @returns {Function} Returns cast function.
5614      */
5615     function castFunction(value) {
5616       return typeof value == 'function' ? value : identity;
5617     }
5618
5619     /**
5620      * Casts `value` to a path array if it's not one.
5621      *
5622      * @private
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.
5626      */
5627     function castPath(value, object) {
5628       if (isArray(value)) {
5629         return value;
5630       }
5631       return isKey(value, object) ? [value] : stringToPath(toString(value));
5632     }
5633
5634     /**
5635      * A `baseRest` alias which can be replaced with `identity` by module
5636      * replacement plugins.
5637      *
5638      * @private
5639      * @type {Function}
5640      * @param {Function} func The function to apply a rest parameter to.
5641      * @returns {Function} Returns the new function.
5642      */
5643     var castRest = baseRest;
5644
5645     /**
5646      * Casts `array` to a slice if it's needed.
5647      *
5648      * @private
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.
5653      */
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);
5658     }
5659
5660     /**
5661      * A simple wrapper around the global [`clearTimeout`](https://mdn.io/clearTimeout).
5662      *
5663      * @private
5664      * @param {number|Object} id The timer id or timeout object of the timer to clear.
5665      */
5666     var clearTimeout = ctxClearTimeout || function(id) {
5667       return root.clearTimeout(id);
5668     };
5669
5670     /**
5671      * Creates a clone of  `buffer`.
5672      *
5673      * @private
5674      * @param {Buffer} buffer The buffer to clone.
5675      * @param {boolean} [isDeep] Specify a deep clone.
5676      * @returns {Buffer} Returns the cloned buffer.
5677      */
5678     function cloneBuffer(buffer, isDeep) {
5679       if (isDeep) {
5680         return buffer.slice();
5681       }
5682       var length = buffer.length,
5683           result = allocUnsafe ? allocUnsafe(length) : new buffer.constructor(length);
5684
5685       buffer.copy(result);
5686       return result;
5687     }
5688
5689     /**
5690      * Creates a clone of `arrayBuffer`.
5691      *
5692      * @private
5693      * @param {ArrayBuffer} arrayBuffer The array buffer to clone.
5694      * @returns {ArrayBuffer} Returns the cloned array buffer.
5695      */
5696     function cloneArrayBuffer(arrayBuffer) {
5697       var result = new arrayBuffer.constructor(arrayBuffer.byteLength);
5698       new Uint8Array(result).set(new Uint8Array(arrayBuffer));
5699       return result;
5700     }
5701
5702     /**
5703      * Creates a clone of `dataView`.
5704      *
5705      * @private
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.
5709      */
5710     function cloneDataView(dataView, isDeep) {
5711       var buffer = isDeep ? cloneArrayBuffer(dataView.buffer) : dataView.buffer;
5712       return new dataView.constructor(buffer, dataView.byteOffset, dataView.byteLength);
5713     }
5714
5715     /**
5716      * Creates a clone of `regexp`.
5717      *
5718      * @private
5719      * @param {Object} regexp The regexp to clone.
5720      * @returns {Object} Returns the cloned regexp.
5721      */
5722     function cloneRegExp(regexp) {
5723       var result = new regexp.constructor(regexp.source, reFlags.exec(regexp));
5724       result.lastIndex = regexp.lastIndex;
5725       return result;
5726     }
5727
5728     /**
5729      * Creates a clone of the `symbol` object.
5730      *
5731      * @private
5732      * @param {Object} symbol The symbol object to clone.
5733      * @returns {Object} Returns the cloned symbol object.
5734      */
5735     function cloneSymbol(symbol) {
5736       return symbolValueOf ? Object(symbolValueOf.call(symbol)) : {};
5737     }
5738
5739     /**
5740      * Creates a clone of `typedArray`.
5741      *
5742      * @private
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.
5746      */
5747     function cloneTypedArray(typedArray, isDeep) {
5748       var buffer = isDeep ? cloneArrayBuffer(typedArray.buffer) : typedArray.buffer;
5749       return new typedArray.constructor(buffer, typedArray.byteOffset, typedArray.length);
5750     }
5751
5752     /**
5753      * Compares values to sort them in ascending order.
5754      *
5755      * @private
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`.
5759      */
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);
5766
5767         var othIsDefined = other !== undefined,
5768             othIsNull = other === null,
5769             othIsReflexive = other === other,
5770             othIsSymbol = isSymbol(other);
5771
5772         if ((!othIsNull && !othIsSymbol && !valIsSymbol && value > other) ||
5773             (valIsSymbol && othIsDefined && othIsReflexive && !othIsNull && !othIsSymbol) ||
5774             (valIsNull && othIsDefined && othIsReflexive) ||
5775             (!valIsDefined && othIsReflexive) ||
5776             !valIsReflexive) {
5777           return 1;
5778         }
5779         if ((!valIsNull && !valIsSymbol && !othIsSymbol && value < other) ||
5780             (othIsSymbol && valIsDefined && valIsReflexive && !valIsNull && !valIsSymbol) ||
5781             (othIsNull && valIsDefined && valIsReflexive) ||
5782             (!othIsDefined && valIsReflexive) ||
5783             !othIsReflexive) {
5784           return -1;
5785         }
5786       }
5787       return 0;
5788     }
5789
5790     /**
5791      * Used by `_.orderBy` to compare multiple properties of a value to another
5792      * and stable sort them.
5793      *
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.
5797      *
5798      * @private
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`.
5803      */
5804     function compareMultiple(object, other, orders) {
5805       var index = -1,
5806           objCriteria = object.criteria,
5807           othCriteria = other.criteria,
5808           length = objCriteria.length,
5809           ordersLength = orders.length;
5810
5811       while (++index < length) {
5812         var result = compareAscending(objCriteria[index], othCriteria[index]);
5813         if (result) {
5814           if (index >= ordersLength) {
5815             return result;
5816           }
5817           var order = orders[index];
5818           return result * (order == 'desc' ? -1 : 1);
5819         }
5820       }
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.
5825       //
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;
5829     }
5830
5831     /**
5832      * Creates an array that is the composition of partially applied arguments,
5833      * placeholders, and provided arguments into a single array of arguments.
5834      *
5835      * @private
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.
5841      */
5842     function composeArgs(args, partials, holders, isCurried) {
5843       var argsIndex = -1,
5844           argsLength = args.length,
5845           holdersLength = holders.length,
5846           leftIndex = -1,
5847           leftLength = partials.length,
5848           rangeLength = nativeMax(argsLength - holdersLength, 0),
5849           result = Array(leftLength + rangeLength),
5850           isUncurried = !isCurried;
5851
5852       while (++leftIndex < leftLength) {
5853         result[leftIndex] = partials[leftIndex];
5854       }
5855       while (++argsIndex < holdersLength) {
5856         if (isUncurried || argsIndex < argsLength) {
5857           result[holders[argsIndex]] = args[argsIndex];
5858         }
5859       }
5860       while (rangeLength--) {
5861         result[leftIndex++] = args[argsIndex++];
5862       }
5863       return result;
5864     }
5865
5866     /**
5867      * This function is like `composeArgs` except that the arguments composition
5868      * is tailored for `_.partialRight`.
5869      *
5870      * @private
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.
5876      */
5877     function composeArgsRight(args, partials, holders, isCurried) {
5878       var argsIndex = -1,
5879           argsLength = args.length,
5880           holdersIndex = -1,
5881           holdersLength = holders.length,
5882           rightIndex = -1,
5883           rightLength = partials.length,
5884           rangeLength = nativeMax(argsLength - holdersLength, 0),
5885           result = Array(rangeLength + rightLength),
5886           isUncurried = !isCurried;
5887
5888       while (++argsIndex < rangeLength) {
5889         result[argsIndex] = args[argsIndex];
5890       }
5891       var offset = argsIndex;
5892       while (++rightIndex < rightLength) {
5893         result[offset + rightIndex] = partials[rightIndex];
5894       }
5895       while (++holdersIndex < holdersLength) {
5896         if (isUncurried || argsIndex < argsLength) {
5897           result[offset + holders[holdersIndex]] = args[argsIndex++];
5898         }
5899       }
5900       return result;
5901     }
5902
5903     /**
5904      * Copies the values of `source` to `array`.
5905      *
5906      * @private
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`.
5910      */
5911     function copyArray(source, array) {
5912       var index = -1,
5913           length = source.length;
5914
5915       array || (array = Array(length));
5916       while (++index < length) {
5917         array[index] = source[index];
5918       }
5919       return array;
5920     }
5921
5922     /**
5923      * Copies properties of `source` to `object`.
5924      *
5925      * @private
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`.
5931      */
5932     function copyObject(source, props, object, customizer) {
5933       var isNew = !object;
5934       object || (object = {});
5935
5936       var index = -1,
5937           length = props.length;
5938
5939       while (++index < length) {
5940         var key = props[index];
5941
5942         var newValue = customizer
5943           ? customizer(object[key], source[key], key, object, source)
5944           : undefined;
5945
5946         if (newValue === undefined) {
5947           newValue = source[key];
5948         }
5949         if (isNew) {
5950           baseAssignValue(object, key, newValue);
5951         } else {
5952           assignValue(object, key, newValue);
5953         }
5954       }
5955       return object;
5956     }
5957
5958     /**
5959      * Copies own symbols of `source` to `object`.
5960      *
5961      * @private
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`.
5965      */
5966     function copySymbols(source, object) {
5967       return copyObject(source, getSymbols(source), object);
5968     }
5969
5970     /**
5971      * Copies own and inherited symbols of `source` to `object`.
5972      *
5973      * @private
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`.
5977      */
5978     function copySymbolsIn(source, object) {
5979       return copyObject(source, getSymbolsIn(source), object);
5980     }
5981
5982     /**
5983      * Creates a function like `_.groupBy`.
5984      *
5985      * @private
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.
5989      */
5990     function createAggregator(setter, initializer) {
5991       return function(collection, iteratee) {
5992         var func = isArray(collection) ? arrayAggregator : baseAggregator,
5993             accumulator = initializer ? initializer() : {};
5994
5995         return func(collection, setter, getIteratee(iteratee, 2), accumulator);
5996       };
5997     }
5998
5999     /**
6000      * Creates a function like `_.assign`.
6001      *
6002      * @private
6003      * @param {Function} assigner The function to assign values.
6004      * @returns {Function} Returns the new assigner function.
6005      */
6006     function createAssigner(assigner) {
6007       return baseRest(function(object, sources) {
6008         var index = -1,
6009             length = sources.length,
6010             customizer = length > 1 ? sources[length - 1] : undefined,
6011             guard = length > 2 ? sources[2] : undefined;
6012
6013         customizer = (assigner.length > 3 && typeof customizer == 'function')
6014           ? (length--, customizer)
6015           : undefined;
6016
6017         if (guard && isIterateeCall(sources[0], sources[1], guard)) {
6018           customizer = length < 3 ? undefined : customizer;
6019           length = 1;
6020         }
6021         object = Object(object);
6022         while (++index < length) {
6023           var source = sources[index];
6024           if (source) {
6025             assigner(object, source, index, customizer);
6026           }
6027         }
6028         return object;
6029       });
6030     }
6031
6032     /**
6033      * Creates a `baseEach` or `baseEachRight` function.
6034      *
6035      * @private
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.
6039      */
6040     function createBaseEach(eachFunc, fromRight) {
6041       return function(collection, iteratee) {
6042         if (collection == null) {
6043           return collection;
6044         }
6045         if (!isArrayLike(collection)) {
6046           return eachFunc(collection, iteratee);
6047         }
6048         var length = collection.length,
6049             index = fromRight ? length : -1,
6050             iterable = Object(collection);
6051
6052         while ((fromRight ? index-- : ++index < length)) {
6053           if (iteratee(iterable[index], index, iterable) === false) {
6054             break;
6055           }
6056         }
6057         return collection;
6058       };
6059     }
6060
6061     /**
6062      * Creates a base function for methods like `_.forIn` and `_.forOwn`.
6063      *
6064      * @private
6065      * @param {boolean} [fromRight] Specify iterating from right to left.
6066      * @returns {Function} Returns the new base function.
6067      */
6068     function createBaseFor(fromRight) {
6069       return function(object, iteratee, keysFunc) {
6070         var index = -1,
6071             iterable = Object(object),
6072             props = keysFunc(object),
6073             length = props.length;
6074
6075         while (length--) {
6076           var key = props[fromRight ? length : ++index];
6077           if (iteratee(iterable[key], key, iterable) === false) {
6078             break;
6079           }
6080         }
6081         return object;
6082       };
6083     }
6084
6085     /**
6086      * Creates a function that wraps `func` to invoke it with the optional `this`
6087      * binding of `thisArg`.
6088      *
6089      * @private
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.
6094      */
6095     function createBind(func, bitmask, thisArg) {
6096       var isBind = bitmask & WRAP_BIND_FLAG,
6097           Ctor = createCtor(func);
6098
6099       function wrapper() {
6100         var fn = (this && this !== root && this instanceof wrapper) ? Ctor : func;
6101         return fn.apply(isBind ? thisArg : this, arguments);
6102       }
6103       return wrapper;
6104     }
6105
6106     /**
6107      * Creates a function like `_.lowerFirst`.
6108      *
6109      * @private
6110      * @param {string} methodName The name of the `String` case method to use.
6111      * @returns {Function} Returns the new case function.
6112      */
6113     function createCaseFirst(methodName) {
6114       return function(string) {
6115         string = toString(string);
6116
6117         var strSymbols = hasUnicode(string)
6118           ? stringToArray(string)
6119           : undefined;
6120
6121         var chr = strSymbols
6122           ? strSymbols[0]
6123           : string.charAt(0);
6124
6125         var trailing = strSymbols
6126           ? castSlice(strSymbols, 1).join('')
6127           : string.slice(1);
6128
6129         return chr[methodName]() + trailing;
6130       };
6131     }
6132
6133     /**
6134      * Creates a function like `_.camelCase`.
6135      *
6136      * @private
6137      * @param {Function} callback The function to combine each word.
6138      * @returns {Function} Returns the new compounder function.
6139      */
6140     function createCompounder(callback) {
6141       return function(string) {
6142         return arrayReduce(words(deburr(string).replace(reApos, '')), callback, '');
6143       };
6144     }
6145
6146     /**
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`.
6149      *
6150      * @private
6151      * @param {Function} Ctor The constructor to wrap.
6152      * @returns {Function} Returns the new wrapped function.
6153      */
6154     function createCtor(Ctor) {
6155       return function() {
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]);
6169         }
6170         var thisBinding = baseCreate(Ctor.prototype),
6171             result = Ctor.apply(thisBinding, args);
6172
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;
6176       };
6177     }
6178
6179     /**
6180      * Creates a function that wraps `func` to enable currying.
6181      *
6182      * @private
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.
6187      */
6188     function createCurry(func, bitmask, arity) {
6189       var Ctor = createCtor(func);
6190
6191       function wrapper() {
6192         var length = arguments.length,
6193             args = Array(length),
6194             index = length,
6195             placeholder = getHolder(wrapper);
6196
6197         while (index--) {
6198           args[index] = arguments[index];
6199         }
6200         var holders = (length < 3 && args[0] !== placeholder && args[length - 1] !== placeholder)
6201           ? []
6202           : replaceHolders(args, placeholder);
6203
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);
6209         }
6210         var fn = (this && this !== root && this instanceof wrapper) ? Ctor : func;
6211         return apply(fn, this, args);
6212       }
6213       return wrapper;
6214     }
6215
6216     /**
6217      * Creates a `_.find` or `_.findLast` function.
6218      *
6219      * @private
6220      * @param {Function} findIndexFunc The function to find the collection index.
6221      * @returns {Function} Returns the new find function.
6222      */
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); };
6230         }
6231         var index = findIndexFunc(collection, predicate, fromIndex);
6232         return index > -1 ? iterable[iteratee ? collection[index] : index] : undefined;
6233       };
6234     }
6235
6236     /**
6237      * Creates a `_.flow` or `_.flowRight` function.
6238      *
6239      * @private
6240      * @param {boolean} [fromRight] Specify iterating from right to left.
6241      * @returns {Function} Returns the new flow function.
6242      */
6243     function createFlow(fromRight) {
6244       return flatRest(function(funcs) {
6245         var length = funcs.length,
6246             index = length,
6247             prereq = LodashWrapper.prototype.thru;
6248
6249         if (fromRight) {
6250           funcs.reverse();
6251         }
6252         while (index--) {
6253           var func = funcs[index];
6254           if (typeof func != 'function') {
6255             throw new TypeError(FUNC_ERROR_TEXT);
6256           }
6257           if (prereq && !wrapper && getFuncName(func) == 'wrapper') {
6258             var wrapper = new LodashWrapper([], true);
6259           }
6260         }
6261         index = wrapper ? index : length;
6262         while (++index < length) {
6263           func = funcs[index];
6264
6265           var funcName = getFuncName(func),
6266               data = funcName == 'wrapper' ? getData(func) : undefined;
6267
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
6271               ) {
6272             wrapper = wrapper[getFuncName(data[0])].apply(wrapper, data[3]);
6273           } else {
6274             wrapper = (func.length == 1 && isLaziable(func))
6275               ? wrapper[funcName]()
6276               : wrapper.thru(func);
6277           }
6278         }
6279         return function() {
6280           var args = arguments,
6281               value = args[0];
6282
6283           if (wrapper && args.length == 1 && isArray(value)) {
6284             return wrapper.plant(value).value();
6285           }
6286           var index = 0,
6287               result = length ? funcs[index].apply(this, args) : value;
6288
6289           while (++index < length) {
6290             result = funcs[index].call(this, result);
6291           }
6292           return result;
6293         };
6294       });
6295     }
6296
6297     /**
6298      * Creates a function that wraps `func` to invoke it with optional `this`
6299      * binding of `thisArg`, partial application, and currying.
6300      *
6301      * @private
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
6306      *  the new function.
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.
6315      */
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);
6323
6324       function wrapper() {
6325         var length = arguments.length,
6326             args = Array(length),
6327             index = length;
6328
6329         while (index--) {
6330           args[index] = arguments[index];
6331         }
6332         if (isCurried) {
6333           var placeholder = getHolder(wrapper),
6334               holdersCount = countHolders(args, placeholder);
6335         }
6336         if (partials) {
6337           args = composeArgs(args, partials, holders, isCurried);
6338         }
6339         if (partialsRight) {
6340           args = composeArgsRight(args, partialsRight, holdersRight, isCurried);
6341         }
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
6348           );
6349         }
6350         var thisBinding = isBind ? thisArg : this,
6351             fn = isBindKey ? thisBinding[func] : func;
6352
6353         length = args.length;
6354         if (argPos) {
6355           args = reorder(args, argPos);
6356         } else if (isFlip && length > 1) {
6357           args.reverse();
6358         }
6359         if (isAry && ary < length) {
6360           args.length = ary;
6361         }
6362         if (this && this !== root && this instanceof wrapper) {
6363           fn = Ctor || createCtor(fn);
6364         }
6365         return fn.apply(thisBinding, args);
6366       }
6367       return wrapper;
6368     }
6369
6370     /**
6371      * Creates a function like `_.invertBy`.
6372      *
6373      * @private
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.
6377      */
6378     function createInverter(setter, toIteratee) {
6379       return function(object, iteratee) {
6380         return baseInverter(object, setter, toIteratee(iteratee), {});
6381       };
6382     }
6383
6384     /**
6385      * Creates a function that performs a mathematical operation on two values.
6386      *
6387      * @private
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.
6391      */
6392     function createMathOperation(operator, defaultValue) {
6393       return function(value, other) {
6394         var result;
6395         if (value === undefined && other === undefined) {
6396           return defaultValue;
6397         }
6398         if (value !== undefined) {
6399           result = value;
6400         }
6401         if (other !== undefined) {
6402           if (result === undefined) {
6403             return other;
6404           }
6405           if (typeof value == 'string' || typeof other == 'string') {
6406             value = baseToString(value);
6407             other = baseToString(other);
6408           } else {
6409             value = baseToNumber(value);
6410             other = baseToNumber(other);
6411           }
6412           result = operator(value, other);
6413         }
6414         return result;
6415       };
6416     }
6417
6418     /**
6419      * Creates a function like `_.over`.
6420      *
6421      * @private
6422      * @param {Function} arrayFunc The function to iterate over iteratees.
6423      * @returns {Function} Returns the new over function.
6424      */
6425     function createOver(arrayFunc) {
6426       return flatRest(function(iteratees) {
6427         iteratees = arrayMap(iteratees, baseUnary(getIteratee()));
6428         return baseRest(function(args) {
6429           var thisArg = this;
6430           return arrayFunc(iteratees, function(iteratee) {
6431             return apply(iteratee, thisArg, args);
6432           });
6433         });
6434       });
6435     }
6436
6437     /**
6438      * Creates the padding for `string` based on `length`. The `chars` string
6439      * is truncated if the number of characters exceeds `length`.
6440      *
6441      * @private
6442      * @param {number} length The padding length.
6443      * @param {string} [chars=' '] The string used as padding.
6444      * @returns {string} Returns the padding for `string`.
6445      */
6446     function createPadding(length, chars) {
6447       chars = chars === undefined ? ' ' : baseToString(chars);
6448
6449       var charsLength = chars.length;
6450       if (charsLength < 2) {
6451         return charsLength ? baseRepeat(chars, length) : chars;
6452       }
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);
6457     }
6458
6459     /**
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.
6462      *
6463      * @private
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
6468      *  the new function.
6469      * @returns {Function} Returns the new wrapped function.
6470      */
6471     function createPartial(func, bitmask, thisArg, partials) {
6472       var isBind = bitmask & WRAP_BIND_FLAG,
6473           Ctor = createCtor(func);
6474
6475       function wrapper() {
6476         var argsIndex = -1,
6477             argsLength = arguments.length,
6478             leftIndex = -1,
6479             leftLength = partials.length,
6480             args = Array(leftLength + argsLength),
6481             fn = (this && this !== root && this instanceof wrapper) ? Ctor : func;
6482
6483         while (++leftIndex < leftLength) {
6484           args[leftIndex] = partials[leftIndex];
6485         }
6486         while (argsLength--) {
6487           args[leftIndex++] = arguments[++argsIndex];
6488         }
6489         return apply(fn, isBind ? thisArg : this, args);
6490       }
6491       return wrapper;
6492     }
6493
6494     /**
6495      * Creates a `_.range` or `_.rangeRight` function.
6496      *
6497      * @private
6498      * @param {boolean} [fromRight] Specify iterating from right to left.
6499      * @returns {Function} Returns the new range function.
6500      */
6501     function createRange(fromRight) {
6502       return function(start, end, step) {
6503         if (step && typeof step != 'number' && isIterateeCall(start, end, step)) {
6504           end = step = undefined;
6505         }
6506         // Ensure the sign of `-0` is preserved.
6507         start = toFinite(start);
6508         if (end === undefined) {
6509           end = start;
6510           start = 0;
6511         } else {
6512           end = toFinite(end);
6513         }
6514         step = step === undefined ? (start < end ? 1 : -1) : toFinite(step);
6515         return baseRange(start, end, step, fromRight);
6516       };
6517     }
6518
6519     /**
6520      * Creates a function that performs a relational operation on two values.
6521      *
6522      * @private
6523      * @param {Function} operator The function to perform the operation.
6524      * @returns {Function} Returns the new relational operation function.
6525      */
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);
6531         }
6532         return operator(value, other);
6533       };
6534     }
6535
6536     /**
6537      * Creates a function that wraps `func` to continue currying.
6538      *
6539      * @private
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
6546      *  the new function.
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.
6552      */
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;
6559
6560       bitmask |= (isCurry ? WRAP_PARTIAL_FLAG : WRAP_PARTIAL_RIGHT_FLAG);
6561       bitmask &= ~(isCurry ? WRAP_PARTIAL_RIGHT_FLAG : WRAP_PARTIAL_FLAG);
6562
6563       if (!(bitmask & WRAP_CURRY_BOUND_FLAG)) {
6564         bitmask &= ~(WRAP_BIND_FLAG | WRAP_BIND_KEY_FLAG);
6565       }
6566       var newData = [
6567         func, bitmask, thisArg, newPartials, newHolders, newPartialsRight,
6568         newHoldersRight, argPos, ary, arity
6569       ];
6570
6571       var result = wrapFunc.apply(undefined, newData);
6572       if (isLaziable(func)) {
6573         setData(result, newData);
6574       }
6575       result.placeholder = placeholder;
6576       return setWrapToString(result, func, bitmask);
6577     }
6578
6579     /**
6580      * Creates a function like `_.round`.
6581      *
6582      * @private
6583      * @param {string} methodName The name of the `Math` method to use when rounding.
6584      * @returns {Function} Returns the new round function.
6585      */
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));
6596
6597           pair = (toString(value) + 'e').split('e');
6598           return +(pair[0] + 'e' + (+pair[1] - precision));
6599         }
6600         return func(number);
6601       };
6602     }
6603
6604     /**
6605      * Creates a set object of `values`.
6606      *
6607      * @private
6608      * @param {Array} values The values to add to the set.
6609      * @returns {Object} Returns the new set.
6610      */
6611     var createSet = !(Set && (1 / setToArray(new Set([,-0]))[1]) == INFINITY) ? noop : function(values) {
6612       return new Set(values);
6613     };
6614
6615     /**
6616      * Creates a `_.toPairs` or `_.toPairsIn` function.
6617      *
6618      * @private
6619      * @param {Function} keysFunc The function to get the keys of a given object.
6620      * @returns {Function} Returns the new pairs function.
6621      */
6622     function createToPairs(keysFunc) {
6623       return function(object) {
6624         var tag = getTag(object);
6625         if (tag == mapTag) {
6626           return mapToArray(object);
6627         }
6628         if (tag == setTag) {
6629           return setToPairs(object);
6630         }
6631         return baseToPairs(object, keysFunc(object));
6632       };
6633     }
6634
6635     /**
6636      * Creates a function that either curries or invokes `func` with optional
6637      * `this` binding and partially applied arguments.
6638      *
6639      * @private
6640      * @param {Function|string} func The function or method name to wrap.
6641      * @param {number} bitmask The bitmask flags.
6642      *    1 - `_.bind`
6643      *    2 - `_.bindKey`
6644      *    4 - `_.curry` or `_.curryRight` of a bound function
6645      *    8 - `_.curry`
6646      *   16 - `_.curryRight`
6647      *   32 - `_.partial`
6648      *   64 - `_.partialRight`
6649      *  128 - `_.rearg`
6650      *  256 - `_.ary`
6651      *  512 - `_.flip`
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.
6659      */
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);
6664       }
6665       var length = partials ? partials.length : 0;
6666       if (!length) {
6667         bitmask &= ~(WRAP_PARTIAL_FLAG | WRAP_PARTIAL_RIGHT_FLAG);
6668         partials = holders = undefined;
6669       }
6670       ary = ary === undefined ? ary : nativeMax(toInteger(ary), 0);
6671       arity = arity === undefined ? arity : toInteger(arity);
6672       length -= holders ? holders.length : 0;
6673
6674       if (bitmask & WRAP_PARTIAL_RIGHT_FLAG) {
6675         var partialsRight = partials,
6676             holdersRight = holders;
6677
6678         partials = holders = undefined;
6679       }
6680       var data = isBindKey ? undefined : getData(func);
6681
6682       var newData = [
6683         func, bitmask, thisArg, partials, holders, partialsRight, holdersRight,
6684         argPos, ary, arity
6685       ];
6686
6687       if (data) {
6688         mergeData(newData, data);
6689       }
6690       func = newData[0];
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);
6698
6699       if (!arity && bitmask & (WRAP_CURRY_FLAG | WRAP_CURRY_RIGHT_FLAG)) {
6700         bitmask &= ~(WRAP_CURRY_FLAG | WRAP_CURRY_RIGHT_FLAG);
6701       }
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);
6708       } else {
6709         result = createHybrid.apply(undefined, newData);
6710       }
6711       var setter = data ? baseSetData : setData;
6712       return setWrapToString(setter(result, newData), func, bitmask);
6713     }
6714
6715     /**
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`.
6719      *
6720      * @private
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.
6726      */
6727     function customDefaultsAssignIn(objValue, srcValue, key, object) {
6728       if (objValue === undefined ||
6729           (eq(objValue, objectProto[key]) && !hasOwnProperty.call(object, key))) {
6730         return srcValue;
6731       }
6732       return objValue;
6733     }
6734
6735     /**
6736      * Used by `_.defaultsDeep` to customize its `_.merge` use to merge source
6737      * objects into destination objects that are passed thru.
6738      *
6739      * @private
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
6746      *  counterparts.
6747      * @returns {*} Returns the value to assign.
6748      */
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);
6755       }
6756       return objValue;
6757     }
6758
6759     /**
6760      * Used by `_.omit` to customize its `_.cloneDeep` use to only clone plain
6761      * objects.
6762      *
6763      * @private
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`.
6767      */
6768     function customOmitClone(value) {
6769       return isPlainObject(value) ? undefined : value;
6770     }
6771
6772     /**
6773      * A specialized version of `baseIsEqualDeep` for arrays with support for
6774      * partial deep comparisons.
6775      *
6776      * @private
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`.
6784      */
6785     function equalArrays(array, other, bitmask, customizer, equalFunc, stack) {
6786       var isPartial = bitmask & COMPARE_PARTIAL_FLAG,
6787           arrLength = array.length,
6788           othLength = other.length;
6789
6790       if (arrLength != othLength && !(isPartial && othLength > arrLength)) {
6791         return false;
6792       }
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;
6798       }
6799       var index = -1,
6800           result = true,
6801           seen = (bitmask & COMPARE_UNORDERED_FLAG) ? new SetCache : undefined;
6802
6803       stack.set(array, other);
6804       stack.set(other, array);
6805
6806       // Ignore non-index properties.
6807       while (++index < arrLength) {
6808         var arrValue = array[index],
6809             othValue = other[index];
6810
6811         if (customizer) {
6812           var compared = isPartial
6813             ? customizer(othValue, arrValue, index, other, array, stack)
6814             : customizer(arrValue, othValue, index, array, other, stack);
6815         }
6816         if (compared !== undefined) {
6817           if (compared) {
6818             continue;
6819           }
6820           result = false;
6821           break;
6822         }
6823         // Recursively compare arrays (susceptible to call stack limits).
6824         if (seen) {
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);
6829                 }
6830               })) {
6831             result = false;
6832             break;
6833           }
6834         } else if (!(
6835               arrValue === othValue ||
6836                 equalFunc(arrValue, othValue, bitmask, customizer, stack)
6837             )) {
6838           result = false;
6839           break;
6840         }
6841       }
6842       stack['delete'](array);
6843       stack['delete'](other);
6844       return result;
6845     }
6846
6847     /**
6848      * A specialized version of `baseIsEqualDeep` for comparing objects of
6849      * the same `toStringTag`.
6850      *
6851      * **Note:** This function only supports comparing values with tags of
6852      * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`.
6853      *
6854      * @private
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`.
6863      */
6864     function equalByTag(object, other, tag, bitmask, customizer, equalFunc, stack) {
6865       switch (tag) {
6866         case dataViewTag:
6867           if ((object.byteLength != other.byteLength) ||
6868               (object.byteOffset != other.byteOffset)) {
6869             return false;
6870           }
6871           object = object.buffer;
6872           other = other.buffer;
6873
6874         case arrayBufferTag:
6875           if ((object.byteLength != other.byteLength) ||
6876               !equalFunc(new Uint8Array(object), new Uint8Array(other))) {
6877             return false;
6878           }
6879           return true;
6880
6881         case boolTag:
6882         case dateTag:
6883         case numberTag:
6884           // Coerce booleans to `1` or `0` and dates to milliseconds.
6885           // Invalid dates are coerced to `NaN`.
6886           return eq(+object, +other);
6887
6888         case errorTag:
6889           return object.name == other.name && object.message == other.message;
6890
6891         case regexpTag:
6892         case stringTag:
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 + '');
6897
6898         case mapTag:
6899           var convert = mapToArray;
6900
6901         case setTag:
6902           var isPartial = bitmask & COMPARE_PARTIAL_FLAG;
6903           convert || (convert = setToArray);
6904
6905           if (object.size != other.size && !isPartial) {
6906             return false;
6907           }
6908           // Assume cyclic values are equal.
6909           var stacked = stack.get(object);
6910           if (stacked) {
6911             return stacked == other;
6912           }
6913           bitmask |= COMPARE_UNORDERED_FLAG;
6914
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);
6919           return result;
6920
6921         case symbolTag:
6922           if (symbolValueOf) {
6923             return symbolValueOf.call(object) == symbolValueOf.call(other);
6924           }
6925       }
6926       return false;
6927     }
6928
6929     /**
6930      * A specialized version of `baseIsEqualDeep` for objects with support for
6931      * partial deep comparisons.
6932      *
6933      * @private
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`.
6941      */
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;
6948
6949       if (objLength != othLength && !isPartial) {
6950         return false;
6951       }
6952       var index = objLength;
6953       while (index--) {
6954         var key = objProps[index];
6955         if (!(isPartial ? key in other : hasOwnProperty.call(other, key))) {
6956           return false;
6957         }
6958       }
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;
6964       }
6965       var result = true;
6966       stack.set(object, other);
6967       stack.set(other, object);
6968
6969       var skipCtor = isPartial;
6970       while (++index < objLength) {
6971         key = objProps[index];
6972         var objValue = object[key],
6973             othValue = other[key];
6974
6975         if (customizer) {
6976           var compared = isPartial
6977             ? customizer(othValue, objValue, key, other, object, stack)
6978             : customizer(objValue, othValue, key, object, other, stack);
6979         }
6980         // Recursively compare objects (susceptible to call stack limits).
6981         if (!(compared === undefined
6982               ? (objValue === othValue || equalFunc(objValue, othValue, bitmask, customizer, stack))
6983               : compared
6984             )) {
6985           result = false;
6986           break;
6987         }
6988         skipCtor || (skipCtor = key == 'constructor');
6989       }
6990       if (result && !skipCtor) {
6991         var objCtor = object.constructor,
6992             othCtor = other.constructor;
6993
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)) {
6999           result = false;
7000         }
7001       }
7002       stack['delete'](object);
7003       stack['delete'](other);
7004       return result;
7005     }
7006
7007     /**
7008      * A specialized version of `baseRest` which flattens the rest array.
7009      *
7010      * @private
7011      * @param {Function} func The function to apply a rest parameter to.
7012      * @returns {Function} Returns the new function.
7013      */
7014     function flatRest(func) {
7015       return setToString(overRest(func, undefined, flatten), func + '');
7016     }
7017
7018     /**
7019      * Creates an array of own enumerable property names and symbols of `object`.
7020      *
7021      * @private
7022      * @param {Object} object The object to query.
7023      * @returns {Array} Returns the array of property names and symbols.
7024      */
7025     function getAllKeys(object) {
7026       return baseGetAllKeys(object, keys, getSymbols);
7027     }
7028
7029     /**
7030      * Creates an array of own and inherited enumerable property names and
7031      * symbols of `object`.
7032      *
7033      * @private
7034      * @param {Object} object The object to query.
7035      * @returns {Array} Returns the array of property names and symbols.
7036      */
7037     function getAllKeysIn(object) {
7038       return baseGetAllKeys(object, keysIn, getSymbolsIn);
7039     }
7040
7041     /**
7042      * Gets metadata for `func`.
7043      *
7044      * @private
7045      * @param {Function} func The function to query.
7046      * @returns {*} Returns the metadata for `func`.
7047      */
7048     var getData = !metaMap ? noop : function(func) {
7049       return metaMap.get(func);
7050     };
7051
7052     /**
7053      * Gets the name of `func`.
7054      *
7055      * @private
7056      * @param {Function} func The function to query.
7057      * @returns {string} Returns the function name.
7058      */
7059     function getFuncName(func) {
7060       var result = (func.name + ''),
7061           array = realNames[result],
7062           length = hasOwnProperty.call(realNames, result) ? array.length : 0;
7063
7064       while (length--) {
7065         var data = array[length],
7066             otherFunc = data.func;
7067         if (otherFunc == null || otherFunc == func) {
7068           return data.name;
7069         }
7070       }
7071       return result;
7072     }
7073
7074     /**
7075      * Gets the argument placeholder value for `func`.
7076      *
7077      * @private
7078      * @param {Function} func The function to inspect.
7079      * @returns {*} Returns the placeholder value.
7080      */
7081     function getHolder(func) {
7082       var object = hasOwnProperty.call(lodash, 'placeholder') ? lodash : func;
7083       return object.placeholder;
7084     }
7085
7086     /**
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.
7091      *
7092      * @private
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.
7096      */
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;
7101     }
7102
7103     /**
7104      * Gets the data for `map`.
7105      *
7106      * @private
7107      * @param {Object} map The map to query.
7108      * @param {string} key The reference key.
7109      * @returns {*} Returns the map data.
7110      */
7111     function getMapData(map, key) {
7112       var data = map.__data__;
7113       return isKeyable(key)
7114         ? data[typeof key == 'string' ? 'string' : 'hash']
7115         : data.map;
7116     }
7117
7118     /**
7119      * Gets the property names, values, and compare flags of `object`.
7120      *
7121      * @private
7122      * @param {Object} object The object to query.
7123      * @returns {Array} Returns the match data of `object`.
7124      */
7125     function getMatchData(object) {
7126       var result = keys(object),
7127           length = result.length;
7128
7129       while (length--) {
7130         var key = result[length],
7131             value = object[key];
7132
7133         result[length] = [key, value, isStrictComparable(value)];
7134       }
7135       return result;
7136     }
7137
7138     /**
7139      * Gets the native function at `key` of `object`.
7140      *
7141      * @private
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`.
7145      */
7146     function getNative(object, key) {
7147       var value = getValue(object, key);
7148       return baseIsNative(value) ? value : undefined;
7149     }
7150
7151     /**
7152      * A specialized version of `baseGetTag` which ignores `Symbol.toStringTag` values.
7153      *
7154      * @private
7155      * @param {*} value The value to query.
7156      * @returns {string} Returns the raw `toStringTag`.
7157      */
7158     function getRawTag(value) {
7159       var isOwn = hasOwnProperty.call(value, symToStringTag),
7160           tag = value[symToStringTag];
7161
7162       try {
7163         value[symToStringTag] = undefined;
7164         var unmasked = true;
7165       } catch (e) {}
7166
7167       var result = nativeObjectToString.call(value);
7168       if (unmasked) {
7169         if (isOwn) {
7170           value[symToStringTag] = tag;
7171         } else {
7172           delete value[symToStringTag];
7173         }
7174       }
7175       return result;
7176     }
7177
7178     /**
7179      * Creates an array of the own enumerable symbols of `object`.
7180      *
7181      * @private
7182      * @param {Object} object The object to query.
7183      * @returns {Array} Returns the array of symbols.
7184      */
7185     var getSymbols = !nativeGetSymbols ? stubArray : function(object) {
7186       if (object == null) {
7187         return [];
7188       }
7189       object = Object(object);
7190       return arrayFilter(nativeGetSymbols(object), function(symbol) {
7191         return propertyIsEnumerable.call(object, symbol);
7192       });
7193     };
7194
7195     /**
7196      * Creates an array of the own and inherited enumerable symbols of `object`.
7197      *
7198      * @private
7199      * @param {Object} object The object to query.
7200      * @returns {Array} Returns the array of symbols.
7201      */
7202     var getSymbolsIn = !nativeGetSymbols ? stubArray : function(object) {
7203       var result = [];
7204       while (object) {
7205         arrayPush(result, getSymbols(object));
7206         object = getPrototype(object);
7207       }
7208       return result;
7209     };
7210
7211     /**
7212      * Gets the `toStringTag` of `value`.
7213      *
7214      * @private
7215      * @param {*} value The value to query.
7216      * @returns {string} Returns the `toStringTag`.
7217      */
7218     var getTag = baseGetTag;
7219
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) : '';
7230
7231         if (ctorString) {
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;
7238           }
7239         }
7240         return result;
7241       };
7242     }
7243
7244     /**
7245      * Gets the view, applying any `transforms` to the `start` and `end` positions.
7246      *
7247      * @private
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.
7253      */
7254     function getView(start, end, transforms) {
7255       var index = -1,
7256           length = transforms.length;
7257
7258       while (++index < length) {
7259         var data = transforms[index],
7260             size = data.size;
7261
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;
7267         }
7268       }
7269       return { 'start': start, 'end': end };
7270     }
7271
7272     /**
7273      * Extracts wrapper details from the `source` body comment.
7274      *
7275      * @private
7276      * @param {string} source The source to inspect.
7277      * @returns {Array} Returns the wrapper details.
7278      */
7279     function getWrapDetails(source) {
7280       var match = source.match(reWrapDetails);
7281       return match ? match[1].split(reSplitDetails) : [];
7282     }
7283
7284     /**
7285      * Checks if `path` exists on `object`.
7286      *
7287      * @private
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`.
7292      */
7293     function hasPath(object, path, hasFunc) {
7294       path = castPath(path, object);
7295
7296       var index = -1,
7297           length = path.length,
7298           result = false;
7299
7300       while (++index < length) {
7301         var key = toKey(path[index]);
7302         if (!(result = object != null && hasFunc(object, key))) {
7303           break;
7304         }
7305         object = object[key];
7306       }
7307       if (result || ++index != length) {
7308         return result;
7309       }
7310       length = object == null ? 0 : object.length;
7311       return !!length && isLength(length) && isIndex(key, length) &&
7312         (isArray(object) || isArguments(object));
7313     }
7314
7315     /**
7316      * Initializes an array clone.
7317      *
7318      * @private
7319      * @param {Array} array The array to clone.
7320      * @returns {Array} Returns the initialized clone.
7321      */
7322     function initCloneArray(array) {
7323       var length = array.length,
7324           result = new array.constructor(length);
7325
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;
7330       }
7331       return result;
7332     }
7333
7334     /**
7335      * Initializes an object clone.
7336      *
7337      * @private
7338      * @param {Object} object The object to clone.
7339      * @returns {Object} Returns the initialized clone.
7340      */
7341     function initCloneObject(object) {
7342       return (typeof object.constructor == 'function' && !isPrototype(object))
7343         ? baseCreate(getPrototype(object))
7344         : {};
7345     }
7346
7347     /**
7348      * Initializes an object clone based on its `toStringTag`.
7349      *
7350      * **Note:** This function only supports cloning values with tags of
7351      * `Boolean`, `Date`, `Error`, `Map`, `Number`, `RegExp`, `Set`, or `String`.
7352      *
7353      * @private
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.
7358      */
7359     function initCloneByTag(object, tag, isDeep) {
7360       var Ctor = object.constructor;
7361       switch (tag) {
7362         case arrayBufferTag:
7363           return cloneArrayBuffer(object);
7364
7365         case boolTag:
7366         case dateTag:
7367           return new Ctor(+object);
7368
7369         case dataViewTag:
7370           return cloneDataView(object, isDeep);
7371
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);
7376
7377         case mapTag:
7378           return new Ctor;
7379
7380         case numberTag:
7381         case stringTag:
7382           return new Ctor(object);
7383
7384         case regexpTag:
7385           return cloneRegExp(object);
7386
7387         case setTag:
7388           return new Ctor;
7389
7390         case symbolTag:
7391           return cloneSymbol(object);
7392       }
7393     }
7394
7395     /**
7396      * Inserts wrapper `details` in a comment at the top of the `source` body.
7397      *
7398      * @private
7399      * @param {string} source The source to modify.
7400      * @returns {Array} details The details to insert.
7401      * @returns {string} Returns the modified source.
7402      */
7403     function insertWrapDetails(source, details) {
7404       var length = details.length;
7405       if (!length) {
7406         return source;
7407       }
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');
7412     }
7413
7414     /**
7415      * Checks if `value` is a flattenable `arguments` object or array.
7416      *
7417      * @private
7418      * @param {*} value The value to check.
7419      * @returns {boolean} Returns `true` if `value` is flattenable, else `false`.
7420      */
7421     function isFlattenable(value) {
7422       return isArray(value) || isArguments(value) ||
7423         !!(spreadableSymbol && value && value[spreadableSymbol]);
7424     }
7425
7426     /**
7427      * Checks if `value` is a valid array-like index.
7428      *
7429      * @private
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`.
7433      */
7434     function isIndex(value, length) {
7435       var type = typeof value;
7436       length = length == null ? MAX_SAFE_INTEGER : length;
7437
7438       return !!length &&
7439         (type == 'number' ||
7440           (type != 'symbol' && reIsUint.test(value))) &&
7441             (value > -1 && value % 1 == 0 && value < length);
7442     }
7443
7444     /**
7445      * Checks if the given arguments are from an iteratee call.
7446      *
7447      * @private
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,
7452      *  else `false`.
7453      */
7454     function isIterateeCall(value, index, object) {
7455       if (!isObject(object)) {
7456         return false;
7457       }
7458       var type = typeof index;
7459       if (type == 'number'
7460             ? (isArrayLike(object) && isIndex(index, object.length))
7461             : (type == 'string' && index in object)
7462           ) {
7463         return eq(object[index], value);
7464       }
7465       return false;
7466     }
7467
7468     /**
7469      * Checks if `value` is a property name and not a property path.
7470      *
7471      * @private
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`.
7475      */
7476     function isKey(value, object) {
7477       if (isArray(value)) {
7478         return false;
7479       }
7480       var type = typeof value;
7481       if (type == 'number' || type == 'symbol' || type == 'boolean' ||
7482           value == null || isSymbol(value)) {
7483         return true;
7484       }
7485       return reIsPlainProp.test(value) || !reIsDeepProp.test(value) ||
7486         (object != null && value in Object(object));
7487     }
7488
7489     /**
7490      * Checks if `value` is suitable for use as unique object key.
7491      *
7492      * @private
7493      * @param {*} value The value to check.
7494      * @returns {boolean} Returns `true` if `value` is suitable, else `false`.
7495      */
7496     function isKeyable(value) {
7497       var type = typeof value;
7498       return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean')
7499         ? (value !== '__proto__')
7500         : (value === null);
7501     }
7502
7503     /**
7504      * Checks if `func` has a lazy counterpart.
7505      *
7506      * @private
7507      * @param {Function} func The function to check.
7508      * @returns {boolean} Returns `true` if `func` has a lazy counterpart,
7509      *  else `false`.
7510      */
7511     function isLaziable(func) {
7512       var funcName = getFuncName(func),
7513           other = lodash[funcName];
7514
7515       if (typeof other != 'function' || !(funcName in LazyWrapper.prototype)) {
7516         return false;
7517       }
7518       if (func === other) {
7519         return true;
7520       }
7521       var data = getData(other);
7522       return !!data && func === data[0];
7523     }
7524
7525     /**
7526      * Checks if `func` has its source masked.
7527      *
7528      * @private
7529      * @param {Function} func The function to check.
7530      * @returns {boolean} Returns `true` if `func` is masked, else `false`.
7531      */
7532     function isMasked(func) {
7533       return !!maskSrcKey && (maskSrcKey in func);
7534     }
7535
7536     /**
7537      * Checks if `func` is capable of being masked.
7538      *
7539      * @private
7540      * @param {*} value The value to check.
7541      * @returns {boolean} Returns `true` if `func` is maskable, else `false`.
7542      */
7543     var isMaskable = coreJsData ? isFunction : stubFalse;
7544
7545     /**
7546      * Checks if `value` is likely a prototype object.
7547      *
7548      * @private
7549      * @param {*} value The value to check.
7550      * @returns {boolean} Returns `true` if `value` is a prototype, else `false`.
7551      */
7552     function isPrototype(value) {
7553       var Ctor = value && value.constructor,
7554           proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto;
7555
7556       return value === proto;
7557     }
7558
7559     /**
7560      * Checks if `value` is suitable for strict equality comparisons, i.e. `===`.
7561      *
7562      * @private
7563      * @param {*} value The value to check.
7564      * @returns {boolean} Returns `true` if `value` if suitable for strict
7565      *  equality comparisons, else `false`.
7566      */
7567     function isStrictComparable(value) {
7568       return value === value && !isObject(value);
7569     }
7570
7571     /**
7572      * A specialized version of `matchesProperty` for source values suitable
7573      * for strict equality comparisons, i.e. `===`.
7574      *
7575      * @private
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.
7579      */
7580     function matchesStrictComparable(key, srcValue) {
7581       return function(object) {
7582         if (object == null) {
7583           return false;
7584         }
7585         return object[key] === srcValue &&
7586           (srcValue !== undefined || (key in Object(object)));
7587       };
7588     }
7589
7590     /**
7591      * A specialized version of `_.memoize` which clears the memoized function's
7592      * cache when it exceeds `MAX_MEMOIZE_SIZE`.
7593      *
7594      * @private
7595      * @param {Function} func The function to have its output memoized.
7596      * @returns {Function} Returns the new memoized function.
7597      */
7598     function memoizeCapped(func) {
7599       var result = memoize(func, function(key) {
7600         if (cache.size === MAX_MEMOIZE_SIZE) {
7601           cache.clear();
7602         }
7603         return key;
7604       });
7605
7606       var cache = result.cache;
7607       return result;
7608     }
7609
7610     /**
7611      * Merges the function metadata of `source` into `data`.
7612      *
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.
7620      *
7621      * @private
7622      * @param {Array} data The destination metadata.
7623      * @param {Array} source The source metadata.
7624      * @returns {Array} Returns `data`.
7625      */
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);
7631
7632       var isCombo =
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));
7636
7637       // Exit early if metadata can't be merged.
7638       if (!(isCommon || isCombo)) {
7639         return data;
7640       }
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;
7646       }
7647       // Compose partial arguments.
7648       var value = source[3];
7649       if (value) {
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];
7653       }
7654       // Compose partial right arguments.
7655       value = source[5];
7656       if (value) {
7657         partials = data[5];
7658         data[5] = partials ? composeArgsRight(partials, value, source[6]) : value;
7659         data[6] = partials ? replaceHolders(data[5], PLACEHOLDER) : source[6];
7660       }
7661       // Use source `argPos` if available.
7662       value = source[7];
7663       if (value) {
7664         data[7] = value;
7665       }
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]);
7669       }
7670       // Use source `arity` if one is not provided.
7671       if (data[9] == null) {
7672         data[9] = source[9];
7673       }
7674       // Use source `func` and merge bitmasks.
7675       data[0] = source[0];
7676       data[1] = newBitmask;
7677
7678       return data;
7679     }
7680
7681     /**
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.
7685      *
7686      * @private
7687      * @param {Object} object The object to query.
7688      * @returns {Array} Returns the array of property names.
7689      */
7690     function nativeKeysIn(object) {
7691       var result = [];
7692       if (object != null) {
7693         for (var key in Object(object)) {
7694           result.push(key);
7695         }
7696       }
7697       return result;
7698     }
7699
7700     /**
7701      * Converts `value` to a string using `Object.prototype.toString`.
7702      *
7703      * @private
7704      * @param {*} value The value to convert.
7705      * @returns {string} Returns the converted string.
7706      */
7707     function objectToString(value) {
7708       return nativeObjectToString.call(value);
7709     }
7710
7711     /**
7712      * A specialized version of `baseRest` which transforms the rest array.
7713      *
7714      * @private
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.
7719      */
7720     function overRest(func, start, transform) {
7721       start = nativeMax(start === undefined ? (func.length - 1) : start, 0);
7722       return function() {
7723         var args = arguments,
7724             index = -1,
7725             length = nativeMax(args.length - start, 0),
7726             array = Array(length);
7727
7728         while (++index < length) {
7729           array[index] = args[start + index];
7730         }
7731         index = -1;
7732         var otherArgs = Array(start + 1);
7733         while (++index < start) {
7734           otherArgs[index] = args[index];
7735         }
7736         otherArgs[start] = transform(array);
7737         return apply(func, this, otherArgs);
7738       };
7739     }
7740
7741     /**
7742      * Gets the parent value at `path` of `object`.
7743      *
7744      * @private
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.
7748      */
7749     function parent(object, path) {
7750       return path.length < 2 ? object : baseGet(object, baseSlice(path, 0, -1));
7751     }
7752
7753     /**
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.
7757      *
7758      * @private
7759      * @param {Array} array The array to reorder.
7760      * @param {Array} indexes The arranged array indexes.
7761      * @returns {Array} Returns `array`.
7762      */
7763     function reorder(array, indexes) {
7764       var arrLength = array.length,
7765           length = nativeMin(indexes.length, arrLength),
7766           oldArray = copyArray(array);
7767
7768       while (length--) {
7769         var index = indexes[length];
7770         array[length] = isIndex(index, arrLength) ? oldArray[index] : undefined;
7771       }
7772       return array;
7773     }
7774
7775     /**
7776      * Gets the value at `key`, unless `key` is "__proto__" or "constructor".
7777      *
7778      * @private
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.
7782      */
7783     function safeGet(object, key) {
7784       if (key === 'constructor' && typeof object[key] === 'function') {
7785         return;
7786       }
7787
7788       if (key == '__proto__') {
7789         return;
7790       }
7791
7792       return object[key];
7793     }
7794
7795     /**
7796      * Sets metadata for `func`.
7797      *
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)
7802      * for more details.
7803      *
7804      * @private
7805      * @param {Function} func The function to associate metadata with.
7806      * @param {*} data The metadata.
7807      * @returns {Function} Returns `func`.
7808      */
7809     var setData = shortOut(baseSetData);
7810
7811     /**
7812      * A simple wrapper around the global [`setTimeout`](https://mdn.io/setTimeout).
7813      *
7814      * @private
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.
7818      */
7819     var setTimeout = ctxSetTimeout || function(func, wait) {
7820       return root.setTimeout(func, wait);
7821     };
7822
7823     /**
7824      * Sets the `toString` method of `func` to return `string`.
7825      *
7826      * @private
7827      * @param {Function} func The function to modify.
7828      * @param {Function} string The `toString` result.
7829      * @returns {Function} Returns `func`.
7830      */
7831     var setToString = shortOut(baseSetToString);
7832
7833     /**
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.
7836      *
7837      * @private
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`.
7842      */
7843     function setWrapToString(wrapper, reference, bitmask) {
7844       var source = (reference + '');
7845       return setToString(wrapper, insertWrapDetails(source, updateWrapDetails(getWrapDetails(source), bitmask)));
7846     }
7847
7848     /**
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`
7851      * milliseconds.
7852      *
7853      * @private
7854      * @param {Function} func The function to restrict.
7855      * @returns {Function} Returns the new shortable function.
7856      */
7857     function shortOut(func) {
7858       var count = 0,
7859           lastCalled = 0;
7860
7861       return function() {
7862         var stamp = nativeNow(),
7863             remaining = HOT_SPAN - (stamp - lastCalled);
7864
7865         lastCalled = stamp;
7866         if (remaining > 0) {
7867           if (++count >= HOT_COUNT) {
7868             return arguments[0];
7869           }
7870         } else {
7871           count = 0;
7872         }
7873         return func.apply(undefined, arguments);
7874       };
7875     }
7876
7877     /**
7878      * A specialized version of `_.shuffle` which mutates and sets the size of `array`.
7879      *
7880      * @private
7881      * @param {Array} array The array to shuffle.
7882      * @param {number} [size=array.length] The size of `array`.
7883      * @returns {Array} Returns `array`.
7884      */
7885     function shuffleSelf(array, size) {
7886       var index = -1,
7887           length = array.length,
7888           lastIndex = length - 1;
7889
7890       size = size === undefined ? length : size;
7891       while (++index < size) {
7892         var rand = baseRandom(index, lastIndex),
7893             value = array[rand];
7894
7895         array[rand] = array[index];
7896         array[index] = value;
7897       }
7898       array.length = size;
7899       return array;
7900     }
7901
7902     /**
7903      * Converts `string` to a property path array.
7904      *
7905      * @private
7906      * @param {string} string The string to convert.
7907      * @returns {Array} Returns the property path array.
7908      */
7909     var stringToPath = memoizeCapped(function(string) {
7910       var result = [];
7911       if (string.charCodeAt(0) === 46 /* . */) {
7912         result.push('');
7913       }
7914       string.replace(rePropName, function(match, number, quote, subString) {
7915         result.push(quote ? subString.replace(reEscapeChar, '$1') : (number || match));
7916       });
7917       return result;
7918     });
7919
7920     /**
7921      * Converts `value` to a string key if it's not a string or symbol.
7922      *
7923      * @private
7924      * @param {*} value The value to inspect.
7925      * @returns {string|symbol} Returns the key.
7926      */
7927     function toKey(value) {
7928       if (typeof value == 'string' || isSymbol(value)) {
7929         return value;
7930       }
7931       var result = (value + '');
7932       return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;
7933     }
7934
7935     /**
7936      * Converts `func` to its source code.
7937      *
7938      * @private
7939      * @param {Function} func The function to convert.
7940      * @returns {string} Returns the source code.
7941      */
7942     function toSource(func) {
7943       if (func != null) {
7944         try {
7945           return funcToString.call(func);
7946         } catch (e) {}
7947         try {
7948           return (func + '');
7949         } catch (e) {}
7950       }
7951       return '';
7952     }
7953
7954     /**
7955      * Updates wrapper `details` based on `bitmask` flags.
7956      *
7957      * @private
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`.
7961      */
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);
7967         }
7968       });
7969       return details.sort();
7970     }
7971
7972     /**
7973      * Creates a clone of `wrapper`.
7974      *
7975      * @private
7976      * @param {Object} wrapper The wrapper to clone.
7977      * @returns {Object} Returns the cloned wrapper.
7978      */
7979     function wrapperClone(wrapper) {
7980       if (wrapper instanceof LazyWrapper) {
7981         return wrapper.clone();
7982       }
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__;
7987       return result;
7988     }
7989
7990     /*------------------------------------------------------------------------*/
7991
7992     /**
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
7995      * elements.
7996      *
7997      * @static
7998      * @memberOf _
7999      * @since 3.0.0
8000      * @category Array
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.
8005      * @example
8006      *
8007      * _.chunk(['a', 'b', 'c', 'd'], 2);
8008      * // => [['a', 'b'], ['c', 'd']]
8009      *
8010      * _.chunk(['a', 'b', 'c', 'd'], 3);
8011      * // => [['a', 'b', 'c'], ['d']]
8012      */
8013     function chunk(array, size, guard) {
8014       if ((guard ? isIterateeCall(array, size, guard) : size === undefined)) {
8015         size = 1;
8016       } else {
8017         size = nativeMax(toInteger(size), 0);
8018       }
8019       var length = array == null ? 0 : array.length;
8020       if (!length || size < 1) {
8021         return [];
8022       }
8023       var index = 0,
8024           resIndex = 0,
8025           result = Array(nativeCeil(length / size));
8026
8027       while (index < length) {
8028         result[resIndex++] = baseSlice(array, index, (index += size));
8029       }
8030       return result;
8031     }
8032
8033     /**
8034      * Creates an array with all falsey values removed. The values `false`, `null`,
8035      * `0`, `""`, `undefined`, and `NaN` are falsey.
8036      *
8037      * @static
8038      * @memberOf _
8039      * @since 0.1.0
8040      * @category Array
8041      * @param {Array} array The array to compact.
8042      * @returns {Array} Returns the new array of filtered values.
8043      * @example
8044      *
8045      * _.compact([0, 1, false, 2, '', 3]);
8046      * // => [1, 2, 3]
8047      */
8048     function compact(array) {
8049       var index = -1,
8050           length = array == null ? 0 : array.length,
8051           resIndex = 0,
8052           result = [];
8053
8054       while (++index < length) {
8055         var value = array[index];
8056         if (value) {
8057           result[resIndex++] = value;
8058         }
8059       }
8060       return result;
8061     }
8062
8063     /**
8064      * Creates a new array concatenating `array` with any additional arrays
8065      * and/or values.
8066      *
8067      * @static
8068      * @memberOf _
8069      * @since 4.0.0
8070      * @category Array
8071      * @param {Array} array The array to concatenate.
8072      * @param {...*} [values] The values to concatenate.
8073      * @returns {Array} Returns the new concatenated array.
8074      * @example
8075      *
8076      * var array = [1];
8077      * var other = _.concat(array, 2, [3], [[4]]);
8078      *
8079      * console.log(other);
8080      * // => [1, 2, 3, [4]]
8081      *
8082      * console.log(array);
8083      * // => [1]
8084      */
8085     function concat() {
8086       var length = arguments.length;
8087       if (!length) {
8088         return [];
8089       }
8090       var args = Array(length - 1),
8091           array = arguments[0],
8092           index = length;
8093
8094       while (index--) {
8095         args[index - 1] = arguments[index];
8096       }
8097       return arrayPush(isArray(array) ? copyArray(array) : [array], baseFlatten(args, 1));
8098     }
8099
8100     /**
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.
8105      *
8106      * **Note:** Unlike `_.pullAll`, this method returns a new array.
8107      *
8108      * @static
8109      * @memberOf _
8110      * @since 0.1.0
8111      * @category 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
8116      * @example
8117      *
8118      * _.difference([2, 1], [2, 3]);
8119      * // => [1]
8120      */
8121     var difference = baseRest(function(array, values) {
8122       return isArrayLikeObject(array)
8123         ? baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true))
8124         : [];
8125     });
8126
8127     /**
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:
8132      * (value).
8133      *
8134      * **Note:** Unlike `_.pullAllBy`, this method returns a new array.
8135      *
8136      * @static
8137      * @memberOf _
8138      * @since 4.0.0
8139      * @category 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.
8144      * @example
8145      *
8146      * _.differenceBy([2.1, 1.2], [2.3, 3.4], Math.floor);
8147      * // => [1.2]
8148      *
8149      * // The `_.property` iteratee shorthand.
8150      * _.differenceBy([{ 'x': 2 }, { 'x': 1 }], [{ 'x': 1 }], 'x');
8151      * // => [{ 'x': 2 }]
8152      */
8153     var differenceBy = baseRest(function(array, values) {
8154       var iteratee = last(values);
8155       if (isArrayLikeObject(iteratee)) {
8156         iteratee = undefined;
8157       }
8158       return isArrayLikeObject(array)
8159         ? baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true), getIteratee(iteratee, 2))
8160         : [];
8161     });
8162
8163     /**
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).
8168      *
8169      * **Note:** Unlike `_.pullAllWith`, this method returns a new array.
8170      *
8171      * @static
8172      * @memberOf _
8173      * @since 4.0.0
8174      * @category 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.
8179      * @example
8180      *
8181      * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
8182      *
8183      * _.differenceWith(objects, [{ 'x': 1, 'y': 2 }], _.isEqual);
8184      * // => [{ 'x': 2, 'y': 1 }]
8185      */
8186     var differenceWith = baseRest(function(array, values) {
8187       var comparator = last(values);
8188       if (isArrayLikeObject(comparator)) {
8189         comparator = undefined;
8190       }
8191       return isArrayLikeObject(array)
8192         ? baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true), undefined, comparator)
8193         : [];
8194     });
8195
8196     /**
8197      * Creates a slice of `array` with `n` elements dropped from the beginning.
8198      *
8199      * @static
8200      * @memberOf _
8201      * @since 0.5.0
8202      * @category Array
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`.
8207      * @example
8208      *
8209      * _.drop([1, 2, 3]);
8210      * // => [2, 3]
8211      *
8212      * _.drop([1, 2, 3], 2);
8213      * // => [3]
8214      *
8215      * _.drop([1, 2, 3], 5);
8216      * // => []
8217      *
8218      * _.drop([1, 2, 3], 0);
8219      * // => [1, 2, 3]
8220      */
8221     function drop(array, n, guard) {
8222       var length = array == null ? 0 : array.length;
8223       if (!length) {
8224         return [];
8225       }
8226       n = (guard || n === undefined) ? 1 : toInteger(n);
8227       return baseSlice(array, n < 0 ? 0 : n, length);
8228     }
8229
8230     /**
8231      * Creates a slice of `array` with `n` elements dropped from the end.
8232      *
8233      * @static
8234      * @memberOf _
8235      * @since 3.0.0
8236      * @category Array
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`.
8241      * @example
8242      *
8243      * _.dropRight([1, 2, 3]);
8244      * // => [1, 2]
8245      *
8246      * _.dropRight([1, 2, 3], 2);
8247      * // => [1]
8248      *
8249      * _.dropRight([1, 2, 3], 5);
8250      * // => []
8251      *
8252      * _.dropRight([1, 2, 3], 0);
8253      * // => [1, 2, 3]
8254      */
8255     function dropRight(array, n, guard) {
8256       var length = array == null ? 0 : array.length;
8257       if (!length) {
8258         return [];
8259       }
8260       n = (guard || n === undefined) ? 1 : toInteger(n);
8261       n = length - n;
8262       return baseSlice(array, 0, n < 0 ? 0 : n);
8263     }
8264
8265     /**
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).
8269      *
8270      * @static
8271      * @memberOf _
8272      * @since 3.0.0
8273      * @category 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`.
8277      * @example
8278      *
8279      * var users = [
8280      *   { 'user': 'barney',  'active': true },
8281      *   { 'user': 'fred',    'active': false },
8282      *   { 'user': 'pebbles', 'active': false }
8283      * ];
8284      *
8285      * _.dropRightWhile(users, function(o) { return !o.active; });
8286      * // => objects for ['barney']
8287      *
8288      * // The `_.matches` iteratee shorthand.
8289      * _.dropRightWhile(users, { 'user': 'pebbles', 'active': false });
8290      * // => objects for ['barney', 'fred']
8291      *
8292      * // The `_.matchesProperty` iteratee shorthand.
8293      * _.dropRightWhile(users, ['active', false]);
8294      * // => objects for ['barney']
8295      *
8296      * // The `_.property` iteratee shorthand.
8297      * _.dropRightWhile(users, 'active');
8298      * // => objects for ['barney', 'fred', 'pebbles']
8299      */
8300     function dropRightWhile(array, predicate) {
8301       return (array && array.length)
8302         ? baseWhile(array, getIteratee(predicate, 3), true, true)
8303         : [];
8304     }
8305
8306     /**
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).
8310      *
8311      * @static
8312      * @memberOf _
8313      * @since 3.0.0
8314      * @category 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`.
8318      * @example
8319      *
8320      * var users = [
8321      *   { 'user': 'barney',  'active': false },
8322      *   { 'user': 'fred',    'active': false },
8323      *   { 'user': 'pebbles', 'active': true }
8324      * ];
8325      *
8326      * _.dropWhile(users, function(o) { return !o.active; });
8327      * // => objects for ['pebbles']
8328      *
8329      * // The `_.matches` iteratee shorthand.
8330      * _.dropWhile(users, { 'user': 'barney', 'active': false });
8331      * // => objects for ['fred', 'pebbles']
8332      *
8333      * // The `_.matchesProperty` iteratee shorthand.
8334      * _.dropWhile(users, ['active', false]);
8335      * // => objects for ['pebbles']
8336      *
8337      * // The `_.property` iteratee shorthand.
8338      * _.dropWhile(users, 'active');
8339      * // => objects for ['barney', 'fred', 'pebbles']
8340      */
8341     function dropWhile(array, predicate) {
8342       return (array && array.length)
8343         ? baseWhile(array, getIteratee(predicate, 3), true)
8344         : [];
8345     }
8346
8347     /**
8348      * Fills elements of `array` with `value` from `start` up to, but not
8349      * including, `end`.
8350      *
8351      * **Note:** This method mutates `array`.
8352      *
8353      * @static
8354      * @memberOf _
8355      * @since 3.2.0
8356      * @category 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`.
8362      * @example
8363      *
8364      * var array = [1, 2, 3];
8365      *
8366      * _.fill(array, 'a');
8367      * console.log(array);
8368      * // => ['a', 'a', 'a']
8369      *
8370      * _.fill(Array(3), 2);
8371      * // => [2, 2, 2]
8372      *
8373      * _.fill([4, 6, 8, 10], '*', 1, 3);
8374      * // => [4, '*', '*', 10]
8375      */
8376     function fill(array, value, start, end) {
8377       var length = array == null ? 0 : array.length;
8378       if (!length) {
8379         return [];
8380       }
8381       if (start && typeof start != 'number' && isIterateeCall(array, value, start)) {
8382         start = 0;
8383         end = length;
8384       }
8385       return baseFill(array, value, start, end);
8386     }
8387
8388     /**
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.
8391      *
8392      * @static
8393      * @memberOf _
8394      * @since 1.1.0
8395      * @category Array
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`.
8400      * @example
8401      *
8402      * var users = [
8403      *   { 'user': 'barney',  'active': false },
8404      *   { 'user': 'fred',    'active': false },
8405      *   { 'user': 'pebbles', 'active': true }
8406      * ];
8407      *
8408      * _.findIndex(users, function(o) { return o.user == 'barney'; });
8409      * // => 0
8410      *
8411      * // The `_.matches` iteratee shorthand.
8412      * _.findIndex(users, { 'user': 'fred', 'active': false });
8413      * // => 1
8414      *
8415      * // The `_.matchesProperty` iteratee shorthand.
8416      * _.findIndex(users, ['active', false]);
8417      * // => 0
8418      *
8419      * // The `_.property` iteratee shorthand.
8420      * _.findIndex(users, 'active');
8421      * // => 2
8422      */
8423     function findIndex(array, predicate, fromIndex) {
8424       var length = array == null ? 0 : array.length;
8425       if (!length) {
8426         return -1;
8427       }
8428       var index = fromIndex == null ? 0 : toInteger(fromIndex);
8429       if (index < 0) {
8430         index = nativeMax(length + index, 0);
8431       }
8432       return baseFindIndex(array, getIteratee(predicate, 3), index);
8433     }
8434
8435     /**
8436      * This method is like `_.findIndex` except that it iterates over elements
8437      * of `collection` from right to left.
8438      *
8439      * @static
8440      * @memberOf _
8441      * @since 2.0.0
8442      * @category Array
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`.
8447      * @example
8448      *
8449      * var users = [
8450      *   { 'user': 'barney',  'active': true },
8451      *   { 'user': 'fred',    'active': false },
8452      *   { 'user': 'pebbles', 'active': false }
8453      * ];
8454      *
8455      * _.findLastIndex(users, function(o) { return o.user == 'pebbles'; });
8456      * // => 2
8457      *
8458      * // The `_.matches` iteratee shorthand.
8459      * _.findLastIndex(users, { 'user': 'barney', 'active': true });
8460      * // => 0
8461      *
8462      * // The `_.matchesProperty` iteratee shorthand.
8463      * _.findLastIndex(users, ['active', false]);
8464      * // => 2
8465      *
8466      * // The `_.property` iteratee shorthand.
8467      * _.findLastIndex(users, 'active');
8468      * // => 0
8469      */
8470     function findLastIndex(array, predicate, fromIndex) {
8471       var length = array == null ? 0 : array.length;
8472       if (!length) {
8473         return -1;
8474       }
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);
8481       }
8482       return baseFindIndex(array, getIteratee(predicate, 3), index, true);
8483     }
8484
8485     /**
8486      * Flattens `array` a single level deep.
8487      *
8488      * @static
8489      * @memberOf _
8490      * @since 0.1.0
8491      * @category Array
8492      * @param {Array} array The array to flatten.
8493      * @returns {Array} Returns the new flattened array.
8494      * @example
8495      *
8496      * _.flatten([1, [2, [3, [4]], 5]]);
8497      * // => [1, 2, [3, [4]], 5]
8498      */
8499     function flatten(array) {
8500       var length = array == null ? 0 : array.length;
8501       return length ? baseFlatten(array, 1) : [];
8502     }
8503
8504     /**
8505      * Recursively flattens `array`.
8506      *
8507      * @static
8508      * @memberOf _
8509      * @since 3.0.0
8510      * @category Array
8511      * @param {Array} array The array to flatten.
8512      * @returns {Array} Returns the new flattened array.
8513      * @example
8514      *
8515      * _.flattenDeep([1, [2, [3, [4]], 5]]);
8516      * // => [1, 2, 3, 4, 5]
8517      */
8518     function flattenDeep(array) {
8519       var length = array == null ? 0 : array.length;
8520       return length ? baseFlatten(array, INFINITY) : [];
8521     }
8522
8523     /**
8524      * Recursively flatten `array` up to `depth` times.
8525      *
8526      * @static
8527      * @memberOf _
8528      * @since 4.4.0
8529      * @category Array
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.
8533      * @example
8534      *
8535      * var array = [1, [2, [3, [4]], 5]];
8536      *
8537      * _.flattenDepth(array, 1);
8538      * // => [1, 2, [3, [4]], 5]
8539      *
8540      * _.flattenDepth(array, 2);
8541      * // => [1, 2, 3, [4], 5]
8542      */
8543     function flattenDepth(array, depth) {
8544       var length = array == null ? 0 : array.length;
8545       if (!length) {
8546         return [];
8547       }
8548       depth = depth === undefined ? 1 : toInteger(depth);
8549       return baseFlatten(array, depth);
8550     }
8551
8552     /**
8553      * The inverse of `_.toPairs`; this method returns an object composed
8554      * from key-value `pairs`.
8555      *
8556      * @static
8557      * @memberOf _
8558      * @since 4.0.0
8559      * @category Array
8560      * @param {Array} pairs The key-value pairs.
8561      * @returns {Object} Returns the new object.
8562      * @example
8563      *
8564      * _.fromPairs([['a', 1], ['b', 2]]);
8565      * // => { 'a': 1, 'b': 2 }
8566      */
8567     function fromPairs(pairs) {
8568       var index = -1,
8569           length = pairs == null ? 0 : pairs.length,
8570           result = {};
8571
8572       while (++index < length) {
8573         var pair = pairs[index];
8574         result[pair[0]] = pair[1];
8575       }
8576       return result;
8577     }
8578
8579     /**
8580      * Gets the first element of `array`.
8581      *
8582      * @static
8583      * @memberOf _
8584      * @since 0.1.0
8585      * @alias first
8586      * @category Array
8587      * @param {Array} array The array to query.
8588      * @returns {*} Returns the first element of `array`.
8589      * @example
8590      *
8591      * _.head([1, 2, 3]);
8592      * // => 1
8593      *
8594      * _.head([]);
8595      * // => undefined
8596      */
8597     function head(array) {
8598       return (array && array.length) ? array[0] : undefined;
8599     }
8600
8601     /**
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`.
8606      *
8607      * @static
8608      * @memberOf _
8609      * @since 0.1.0
8610      * @category 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`.
8615      * @example
8616      *
8617      * _.indexOf([1, 2, 1, 2], 2);
8618      * // => 1
8619      *
8620      * // Search from the `fromIndex`.
8621      * _.indexOf([1, 2, 1, 2], 2, 2);
8622      * // => 3
8623      */
8624     function indexOf(array, value, fromIndex) {
8625       var length = array == null ? 0 : array.length;
8626       if (!length) {
8627         return -1;
8628       }
8629       var index = fromIndex == null ? 0 : toInteger(fromIndex);
8630       if (index < 0) {
8631         index = nativeMax(length + index, 0);
8632       }
8633       return baseIndexOf(array, value, index);
8634     }
8635
8636     /**
8637      * Gets all but the last element of `array`.
8638      *
8639      * @static
8640      * @memberOf _
8641      * @since 0.1.0
8642      * @category Array
8643      * @param {Array} array The array to query.
8644      * @returns {Array} Returns the slice of `array`.
8645      * @example
8646      *
8647      * _.initial([1, 2, 3]);
8648      * // => [1, 2]
8649      */
8650     function initial(array) {
8651       var length = array == null ? 0 : array.length;
8652       return length ? baseSlice(array, 0, -1) : [];
8653     }
8654
8655     /**
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.
8660      *
8661      * @static
8662      * @memberOf _
8663      * @since 0.1.0
8664      * @category Array
8665      * @param {...Array} [arrays] The arrays to inspect.
8666      * @returns {Array} Returns the new array of intersecting values.
8667      * @example
8668      *
8669      * _.intersection([2, 1], [2, 3]);
8670      * // => [2]
8671      */
8672     var intersection = baseRest(function(arrays) {
8673       var mapped = arrayMap(arrays, castArrayLikeObject);
8674       return (mapped.length && mapped[0] === arrays[0])
8675         ? baseIntersection(mapped)
8676         : [];
8677     });
8678
8679     /**
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:
8684      * (value).
8685      *
8686      * @static
8687      * @memberOf _
8688      * @since 4.0.0
8689      * @category Array
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.
8693      * @example
8694      *
8695      * _.intersectionBy([2.1, 1.2], [2.3, 3.4], Math.floor);
8696      * // => [2.1]
8697      *
8698      * // The `_.property` iteratee shorthand.
8699      * _.intersectionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');
8700      * // => [{ 'x': 1 }]
8701      */
8702     var intersectionBy = baseRest(function(arrays) {
8703       var iteratee = last(arrays),
8704           mapped = arrayMap(arrays, castArrayLikeObject);
8705
8706       if (iteratee === last(mapped)) {
8707         iteratee = undefined;
8708       } else {
8709         mapped.pop();
8710       }
8711       return (mapped.length && mapped[0] === arrays[0])
8712         ? baseIntersection(mapped, getIteratee(iteratee, 2))
8713         : [];
8714     });
8715
8716     /**
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).
8721      *
8722      * @static
8723      * @memberOf _
8724      * @since 4.0.0
8725      * @category Array
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.
8729      * @example
8730      *
8731      * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
8732      * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }];
8733      *
8734      * _.intersectionWith(objects, others, _.isEqual);
8735      * // => [{ 'x': 1, 'y': 2 }]
8736      */
8737     var intersectionWith = baseRest(function(arrays) {
8738       var comparator = last(arrays),
8739           mapped = arrayMap(arrays, castArrayLikeObject);
8740
8741       comparator = typeof comparator == 'function' ? comparator : undefined;
8742       if (comparator) {
8743         mapped.pop();
8744       }
8745       return (mapped.length && mapped[0] === arrays[0])
8746         ? baseIntersection(mapped, undefined, comparator)
8747         : [];
8748     });
8749
8750     /**
8751      * Converts all elements in `array` into a string separated by `separator`.
8752      *
8753      * @static
8754      * @memberOf _
8755      * @since 4.0.0
8756      * @category Array
8757      * @param {Array} array The array to convert.
8758      * @param {string} [separator=','] The element separator.
8759      * @returns {string} Returns the joined string.
8760      * @example
8761      *
8762      * _.join(['a', 'b', 'c'], '~');
8763      * // => 'a~b~c'
8764      */
8765     function join(array, separator) {
8766       return array == null ? '' : nativeJoin.call(array, separator);
8767     }
8768
8769     /**
8770      * Gets the last element of `array`.
8771      *
8772      * @static
8773      * @memberOf _
8774      * @since 0.1.0
8775      * @category Array
8776      * @param {Array} array The array to query.
8777      * @returns {*} Returns the last element of `array`.
8778      * @example
8779      *
8780      * _.last([1, 2, 3]);
8781      * // => 3
8782      */
8783     function last(array) {
8784       var length = array == null ? 0 : array.length;
8785       return length ? array[length - 1] : undefined;
8786     }
8787
8788     /**
8789      * This method is like `_.indexOf` except that it iterates over elements of
8790      * `array` from right to left.
8791      *
8792      * @static
8793      * @memberOf _
8794      * @since 0.1.0
8795      * @category Array
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`.
8800      * @example
8801      *
8802      * _.lastIndexOf([1, 2, 1, 2], 2);
8803      * // => 3
8804      *
8805      * // Search from the `fromIndex`.
8806      * _.lastIndexOf([1, 2, 1, 2], 2, 2);
8807      * // => 1
8808      */
8809     function lastIndexOf(array, value, fromIndex) {
8810       var length = array == null ? 0 : array.length;
8811       if (!length) {
8812         return -1;
8813       }
8814       var index = length;
8815       if (fromIndex !== undefined) {
8816         index = toInteger(fromIndex);
8817         index = index < 0 ? nativeMax(length + index, 0) : nativeMin(index, length - 1);
8818       }
8819       return value === value
8820         ? strictLastIndexOf(array, value, index)
8821         : baseFindIndex(array, baseIsNaN, index, true);
8822     }
8823
8824     /**
8825      * Gets the element at index `n` of `array`. If `n` is negative, the nth
8826      * element from the end is returned.
8827      *
8828      * @static
8829      * @memberOf _
8830      * @since 4.11.0
8831      * @category Array
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`.
8835      * @example
8836      *
8837      * var array = ['a', 'b', 'c', 'd'];
8838      *
8839      * _.nth(array, 1);
8840      * // => 'b'
8841      *
8842      * _.nth(array, -2);
8843      * // => 'c';
8844      */
8845     function nth(array, n) {
8846       return (array && array.length) ? baseNth(array, toInteger(n)) : undefined;
8847     }
8848
8849     /**
8850      * Removes all given values from `array` using
8851      * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
8852      * for equality comparisons.
8853      *
8854      * **Note:** Unlike `_.without`, this method mutates `array`. Use `_.remove`
8855      * to remove elements from an array by predicate.
8856      *
8857      * @static
8858      * @memberOf _
8859      * @since 2.0.0
8860      * @category Array
8861      * @param {Array} array The array to modify.
8862      * @param {...*} [values] The values to remove.
8863      * @returns {Array} Returns `array`.
8864      * @example
8865      *
8866      * var array = ['a', 'b', 'c', 'a', 'b', 'c'];
8867      *
8868      * _.pull(array, 'a', 'c');
8869      * console.log(array);
8870      * // => ['b', 'b']
8871      */
8872     var pull = baseRest(pullAll);
8873
8874     /**
8875      * This method is like `_.pull` except that it accepts an array of values to remove.
8876      *
8877      * **Note:** Unlike `_.difference`, this method mutates `array`.
8878      *
8879      * @static
8880      * @memberOf _
8881      * @since 4.0.0
8882      * @category Array
8883      * @param {Array} array The array to modify.
8884      * @param {Array} values The values to remove.
8885      * @returns {Array} Returns `array`.
8886      * @example
8887      *
8888      * var array = ['a', 'b', 'c', 'a', 'b', 'c'];
8889      *
8890      * _.pullAll(array, ['a', 'c']);
8891      * console.log(array);
8892      * // => ['b', 'b']
8893      */
8894     function pullAll(array, values) {
8895       return (array && array.length && values && values.length)
8896         ? basePullAll(array, values)
8897         : array;
8898     }
8899
8900     /**
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).
8904      *
8905      * **Note:** Unlike `_.differenceBy`, this method mutates `array`.
8906      *
8907      * @static
8908      * @memberOf _
8909      * @since 4.0.0
8910      * @category 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`.
8915      * @example
8916      *
8917      * var array = [{ 'x': 1 }, { 'x': 2 }, { 'x': 3 }, { 'x': 1 }];
8918      *
8919      * _.pullAllBy(array, [{ 'x': 1 }, { 'x': 3 }], 'x');
8920      * console.log(array);
8921      * // => [{ 'x': 2 }]
8922      */
8923     function pullAllBy(array, values, iteratee) {
8924       return (array && array.length && values && values.length)
8925         ? basePullAll(array, values, getIteratee(iteratee, 2))
8926         : array;
8927     }
8928
8929     /**
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).
8933      *
8934      * **Note:** Unlike `_.differenceWith`, this method mutates `array`.
8935      *
8936      * @static
8937      * @memberOf _
8938      * @since 4.6.0
8939      * @category 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`.
8944      * @example
8945      *
8946      * var array = [{ 'x': 1, 'y': 2 }, { 'x': 3, 'y': 4 }, { 'x': 5, 'y': 6 }];
8947      *
8948      * _.pullAllWith(array, [{ 'x': 3, 'y': 4 }], _.isEqual);
8949      * console.log(array);
8950      * // => [{ 'x': 1, 'y': 2 }, { 'x': 5, 'y': 6 }]
8951      */
8952     function pullAllWith(array, values, comparator) {
8953       return (array && array.length && values && values.length)
8954         ? basePullAll(array, values, undefined, comparator)
8955         : array;
8956     }
8957
8958     /**
8959      * Removes elements from `array` corresponding to `indexes` and returns an
8960      * array of removed elements.
8961      *
8962      * **Note:** Unlike `_.at`, this method mutates `array`.
8963      *
8964      * @static
8965      * @memberOf _
8966      * @since 3.0.0
8967      * @category 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.
8971      * @example
8972      *
8973      * var array = ['a', 'b', 'c', 'd'];
8974      * var pulled = _.pullAt(array, [1, 3]);
8975      *
8976      * console.log(array);
8977      * // => ['a', 'c']
8978      *
8979      * console.log(pulled);
8980      * // => ['b', 'd']
8981      */
8982     var pullAt = flatRest(function(array, indexes) {
8983       var length = array == null ? 0 : array.length,
8984           result = baseAt(array, indexes);
8985
8986       basePullAt(array, arrayMap(indexes, function(index) {
8987         return isIndex(index, length) ? +index : index;
8988       }).sort(compareAscending));
8989
8990       return result;
8991     });
8992
8993     /**
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).
8997      *
8998      * **Note:** Unlike `_.filter`, this method mutates `array`. Use `_.pull`
8999      * to pull elements from an array by value.
9000      *
9001      * @static
9002      * @memberOf _
9003      * @since 2.0.0
9004      * @category Array
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.
9008      * @example
9009      *
9010      * var array = [1, 2, 3, 4];
9011      * var evens = _.remove(array, function(n) {
9012      *   return n % 2 == 0;
9013      * });
9014      *
9015      * console.log(array);
9016      * // => [1, 3]
9017      *
9018      * console.log(evens);
9019      * // => [2, 4]
9020      */
9021     function remove(array, predicate) {
9022       var result = [];
9023       if (!(array && array.length)) {
9024         return result;
9025       }
9026       var index = -1,
9027           indexes = [],
9028           length = array.length;
9029
9030       predicate = getIteratee(predicate, 3);
9031       while (++index < length) {
9032         var value = array[index];
9033         if (predicate(value, index, array)) {
9034           result.push(value);
9035           indexes.push(index);
9036         }
9037       }
9038       basePullAt(array, indexes);
9039       return result;
9040     }
9041
9042     /**
9043      * Reverses `array` so that the first element becomes the last, the second
9044      * element becomes the second to last, and so on.
9045      *
9046      * **Note:** This method mutates `array` and is based on
9047      * [`Array#reverse`](https://mdn.io/Array/reverse).
9048      *
9049      * @static
9050      * @memberOf _
9051      * @since 4.0.0
9052      * @category Array
9053      * @param {Array} array The array to modify.
9054      * @returns {Array} Returns `array`.
9055      * @example
9056      *
9057      * var array = [1, 2, 3];
9058      *
9059      * _.reverse(array);
9060      * // => [3, 2, 1]
9061      *
9062      * console.log(array);
9063      * // => [3, 2, 1]
9064      */
9065     function reverse(array) {
9066       return array == null ? array : nativeReverse.call(array);
9067     }
9068
9069     /**
9070      * Creates a slice of `array` from `start` up to, but not including, `end`.
9071      *
9072      * **Note:** This method is used instead of
9073      * [`Array#slice`](https://mdn.io/Array/slice) to ensure dense arrays are
9074      * returned.
9075      *
9076      * @static
9077      * @memberOf _
9078      * @since 3.0.0
9079      * @category Array
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`.
9084      */
9085     function slice(array, start, end) {
9086       var length = array == null ? 0 : array.length;
9087       if (!length) {
9088         return [];
9089       }
9090       if (end && typeof end != 'number' && isIterateeCall(array, start, end)) {
9091         start = 0;
9092         end = length;
9093       }
9094       else {
9095         start = start == null ? 0 : toInteger(start);
9096         end = end === undefined ? length : toInteger(end);
9097       }
9098       return baseSlice(array, start, end);
9099     }
9100
9101     /**
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.
9104      *
9105      * @static
9106      * @memberOf _
9107      * @since 0.1.0
9108      * @category Array
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
9112      *  into `array`.
9113      * @example
9114      *
9115      * _.sortedIndex([30, 50], 40);
9116      * // => 1
9117      */
9118     function sortedIndex(array, value) {
9119       return baseSortedIndex(array, value);
9120     }
9121
9122     /**
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).
9126      *
9127      * @static
9128      * @memberOf _
9129      * @since 4.0.0
9130      * @category Array
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
9135      *  into `array`.
9136      * @example
9137      *
9138      * var objects = [{ 'x': 4 }, { 'x': 5 }];
9139      *
9140      * _.sortedIndexBy(objects, { 'x': 4 }, function(o) { return o.x; });
9141      * // => 0
9142      *
9143      * // The `_.property` iteratee shorthand.
9144      * _.sortedIndexBy(objects, { 'x': 4 }, 'x');
9145      * // => 0
9146      */
9147     function sortedIndexBy(array, value, iteratee) {
9148       return baseSortedIndexBy(array, value, getIteratee(iteratee, 2));
9149     }
9150
9151     /**
9152      * This method is like `_.indexOf` except that it performs a binary
9153      * search on a sorted `array`.
9154      *
9155      * @static
9156      * @memberOf _
9157      * @since 4.0.0
9158      * @category 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`.
9162      * @example
9163      *
9164      * _.sortedIndexOf([4, 5, 5, 5, 6], 5);
9165      * // => 1
9166      */
9167     function sortedIndexOf(array, value) {
9168       var length = array == null ? 0 : array.length;
9169       if (length) {
9170         var index = baseSortedIndex(array, value);
9171         if (index < length && eq(array[index], value)) {
9172           return index;
9173         }
9174       }
9175       return -1;
9176     }
9177
9178     /**
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.
9182      *
9183      * @static
9184      * @memberOf _
9185      * @since 3.0.0
9186      * @category Array
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
9190      *  into `array`.
9191      * @example
9192      *
9193      * _.sortedLastIndex([4, 5, 5, 5, 6], 5);
9194      * // => 4
9195      */
9196     function sortedLastIndex(array, value) {
9197       return baseSortedIndex(array, value, true);
9198     }
9199
9200     /**
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).
9204      *
9205      * @static
9206      * @memberOf _
9207      * @since 4.0.0
9208      * @category Array
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
9213      *  into `array`.
9214      * @example
9215      *
9216      * var objects = [{ 'x': 4 }, { 'x': 5 }];
9217      *
9218      * _.sortedLastIndexBy(objects, { 'x': 4 }, function(o) { return o.x; });
9219      * // => 1
9220      *
9221      * // The `_.property` iteratee shorthand.
9222      * _.sortedLastIndexBy(objects, { 'x': 4 }, 'x');
9223      * // => 1
9224      */
9225     function sortedLastIndexBy(array, value, iteratee) {
9226       return baseSortedIndexBy(array, value, getIteratee(iteratee, 2), true);
9227     }
9228
9229     /**
9230      * This method is like `_.lastIndexOf` except that it performs a binary
9231      * search on a sorted `array`.
9232      *
9233      * @static
9234      * @memberOf _
9235      * @since 4.0.0
9236      * @category 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`.
9240      * @example
9241      *
9242      * _.sortedLastIndexOf([4, 5, 5, 5, 6], 5);
9243      * // => 3
9244      */
9245     function sortedLastIndexOf(array, value) {
9246       var length = array == null ? 0 : array.length;
9247       if (length) {
9248         var index = baseSortedIndex(array, value, true) - 1;
9249         if (eq(array[index], value)) {
9250           return index;
9251         }
9252       }
9253       return -1;
9254     }
9255
9256     /**
9257      * This method is like `_.uniq` except that it's designed and optimized
9258      * for sorted arrays.
9259      *
9260      * @static
9261      * @memberOf _
9262      * @since 4.0.0
9263      * @category Array
9264      * @param {Array} array The array to inspect.
9265      * @returns {Array} Returns the new duplicate free array.
9266      * @example
9267      *
9268      * _.sortedUniq([1, 1, 2]);
9269      * // => [1, 2]
9270      */
9271     function sortedUniq(array) {
9272       return (array && array.length)
9273         ? baseSortedUniq(array)
9274         : [];
9275     }
9276
9277     /**
9278      * This method is like `_.uniqBy` except that it's designed and optimized
9279      * for sorted arrays.
9280      *
9281      * @static
9282      * @memberOf _
9283      * @since 4.0.0
9284      * @category Array
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.
9288      * @example
9289      *
9290      * _.sortedUniqBy([1.1, 1.2, 2.3, 2.4], Math.floor);
9291      * // => [1.1, 2.3]
9292      */
9293     function sortedUniqBy(array, iteratee) {
9294       return (array && array.length)
9295         ? baseSortedUniq(array, getIteratee(iteratee, 2))
9296         : [];
9297     }
9298
9299     /**
9300      * Gets all but the first element of `array`.
9301      *
9302      * @static
9303      * @memberOf _
9304      * @since 4.0.0
9305      * @category Array
9306      * @param {Array} array The array to query.
9307      * @returns {Array} Returns the slice of `array`.
9308      * @example
9309      *
9310      * _.tail([1, 2, 3]);
9311      * // => [2, 3]
9312      */
9313     function tail(array) {
9314       var length = array == null ? 0 : array.length;
9315       return length ? baseSlice(array, 1, length) : [];
9316     }
9317
9318     /**
9319      * Creates a slice of `array` with `n` elements taken from the beginning.
9320      *
9321      * @static
9322      * @memberOf _
9323      * @since 0.1.0
9324      * @category Array
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`.
9329      * @example
9330      *
9331      * _.take([1, 2, 3]);
9332      * // => [1]
9333      *
9334      * _.take([1, 2, 3], 2);
9335      * // => [1, 2]
9336      *
9337      * _.take([1, 2, 3], 5);
9338      * // => [1, 2, 3]
9339      *
9340      * _.take([1, 2, 3], 0);
9341      * // => []
9342      */
9343     function take(array, n, guard) {
9344       if (!(array && array.length)) {
9345         return [];
9346       }
9347       n = (guard || n === undefined) ? 1 : toInteger(n);
9348       return baseSlice(array, 0, n < 0 ? 0 : n);
9349     }
9350
9351     /**
9352      * Creates a slice of `array` with `n` elements taken from the end.
9353      *
9354      * @static
9355      * @memberOf _
9356      * @since 3.0.0
9357      * @category Array
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`.
9362      * @example
9363      *
9364      * _.takeRight([1, 2, 3]);
9365      * // => [3]
9366      *
9367      * _.takeRight([1, 2, 3], 2);
9368      * // => [2, 3]
9369      *
9370      * _.takeRight([1, 2, 3], 5);
9371      * // => [1, 2, 3]
9372      *
9373      * _.takeRight([1, 2, 3], 0);
9374      * // => []
9375      */
9376     function takeRight(array, n, guard) {
9377       var length = array == null ? 0 : array.length;
9378       if (!length) {
9379         return [];
9380       }
9381       n = (guard || n === undefined) ? 1 : toInteger(n);
9382       n = length - n;
9383       return baseSlice(array, n < 0 ? 0 : n, length);
9384     }
9385
9386     /**
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).
9390      *
9391      * @static
9392      * @memberOf _
9393      * @since 3.0.0
9394      * @category 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`.
9398      * @example
9399      *
9400      * var users = [
9401      *   { 'user': 'barney',  'active': true },
9402      *   { 'user': 'fred',    'active': false },
9403      *   { 'user': 'pebbles', 'active': false }
9404      * ];
9405      *
9406      * _.takeRightWhile(users, function(o) { return !o.active; });
9407      * // => objects for ['fred', 'pebbles']
9408      *
9409      * // The `_.matches` iteratee shorthand.
9410      * _.takeRightWhile(users, { 'user': 'pebbles', 'active': false });
9411      * // => objects for ['pebbles']
9412      *
9413      * // The `_.matchesProperty` iteratee shorthand.
9414      * _.takeRightWhile(users, ['active', false]);
9415      * // => objects for ['fred', 'pebbles']
9416      *
9417      * // The `_.property` iteratee shorthand.
9418      * _.takeRightWhile(users, 'active');
9419      * // => []
9420      */
9421     function takeRightWhile(array, predicate) {
9422       return (array && array.length)
9423         ? baseWhile(array, getIteratee(predicate, 3), false, true)
9424         : [];
9425     }
9426
9427     /**
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).
9431      *
9432      * @static
9433      * @memberOf _
9434      * @since 3.0.0
9435      * @category 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`.
9439      * @example
9440      *
9441      * var users = [
9442      *   { 'user': 'barney',  'active': false },
9443      *   { 'user': 'fred',    'active': false },
9444      *   { 'user': 'pebbles', 'active': true }
9445      * ];
9446      *
9447      * _.takeWhile(users, function(o) { return !o.active; });
9448      * // => objects for ['barney', 'fred']
9449      *
9450      * // The `_.matches` iteratee shorthand.
9451      * _.takeWhile(users, { 'user': 'barney', 'active': false });
9452      * // => objects for ['barney']
9453      *
9454      * // The `_.matchesProperty` iteratee shorthand.
9455      * _.takeWhile(users, ['active', false]);
9456      * // => objects for ['barney', 'fred']
9457      *
9458      * // The `_.property` iteratee shorthand.
9459      * _.takeWhile(users, 'active');
9460      * // => []
9461      */
9462     function takeWhile(array, predicate) {
9463       return (array && array.length)
9464         ? baseWhile(array, getIteratee(predicate, 3))
9465         : [];
9466     }
9467
9468     /**
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.
9472      *
9473      * @static
9474      * @memberOf _
9475      * @since 0.1.0
9476      * @category Array
9477      * @param {...Array} [arrays] The arrays to inspect.
9478      * @returns {Array} Returns the new array of combined values.
9479      * @example
9480      *
9481      * _.union([2], [1, 2]);
9482      * // => [2, 1]
9483      */
9484     var union = baseRest(function(arrays) {
9485       return baseUniq(baseFlatten(arrays, 1, isArrayLikeObject, true));
9486     });
9487
9488     /**
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:
9493      * (value).
9494      *
9495      * @static
9496      * @memberOf _
9497      * @since 4.0.0
9498      * @category Array
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.
9502      * @example
9503      *
9504      * _.unionBy([2.1], [1.2, 2.3], Math.floor);
9505      * // => [2.1, 1.2]
9506      *
9507      * // The `_.property` iteratee shorthand.
9508      * _.unionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');
9509      * // => [{ 'x': 1 }, { 'x': 2 }]
9510      */
9511     var unionBy = baseRest(function(arrays) {
9512       var iteratee = last(arrays);
9513       if (isArrayLikeObject(iteratee)) {
9514         iteratee = undefined;
9515       }
9516       return baseUniq(baseFlatten(arrays, 1, isArrayLikeObject, true), getIteratee(iteratee, 2));
9517     });
9518
9519     /**
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).
9524      *
9525      * @static
9526      * @memberOf _
9527      * @since 4.0.0
9528      * @category Array
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.
9532      * @example
9533      *
9534      * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
9535      * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }];
9536      *
9537      * _.unionWith(objects, others, _.isEqual);
9538      * // => [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }, { 'x': 1, 'y': 1 }]
9539      */
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);
9544     });
9545
9546     /**
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
9551      * in the array.
9552      *
9553      * @static
9554      * @memberOf _
9555      * @since 0.1.0
9556      * @category Array
9557      * @param {Array} array The array to inspect.
9558      * @returns {Array} Returns the new duplicate free array.
9559      * @example
9560      *
9561      * _.uniq([2, 1, 2]);
9562      * // => [2, 1]
9563      */
9564     function uniq(array) {
9565       return (array && array.length) ? baseUniq(array) : [];
9566     }
9567
9568     /**
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:
9573      * (value).
9574      *
9575      * @static
9576      * @memberOf _
9577      * @since 4.0.0
9578      * @category Array
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.
9582      * @example
9583      *
9584      * _.uniqBy([2.1, 1.2, 2.3], Math.floor);
9585      * // => [2.1, 1.2]
9586      *
9587      * // The `_.property` iteratee shorthand.
9588      * _.uniqBy([{ 'x': 1 }, { 'x': 2 }, { 'x': 1 }], 'x');
9589      * // => [{ 'x': 1 }, { 'x': 2 }]
9590      */
9591     function uniqBy(array, iteratee) {
9592       return (array && array.length) ? baseUniq(array, getIteratee(iteratee, 2)) : [];
9593     }
9594
9595     /**
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).
9600      *
9601      * @static
9602      * @memberOf _
9603      * @since 4.0.0
9604      * @category Array
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.
9608      * @example
9609      *
9610      * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }, { 'x': 1, 'y': 2 }];
9611      *
9612      * _.uniqWith(objects, _.isEqual);
9613      * // => [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }]
9614      */
9615     function uniqWith(array, comparator) {
9616       comparator = typeof comparator == 'function' ? comparator : undefined;
9617       return (array && array.length) ? baseUniq(array, undefined, comparator) : [];
9618     }
9619
9620     /**
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
9623      * configuration.
9624      *
9625      * @static
9626      * @memberOf _
9627      * @since 1.2.0
9628      * @category Array
9629      * @param {Array} array The array of grouped elements to process.
9630      * @returns {Array} Returns the new array of regrouped elements.
9631      * @example
9632      *
9633      * var zipped = _.zip(['a', 'b'], [1, 2], [true, false]);
9634      * // => [['a', 1, true], ['b', 2, false]]
9635      *
9636      * _.unzip(zipped);
9637      * // => [['a', 'b'], [1, 2], [true, false]]
9638      */
9639     function unzip(array) {
9640       if (!(array && array.length)) {
9641         return [];
9642       }
9643       var length = 0;
9644       array = arrayFilter(array, function(group) {
9645         if (isArrayLikeObject(group)) {
9646           length = nativeMax(group.length, length);
9647           return true;
9648         }
9649       });
9650       return baseTimes(length, function(index) {
9651         return arrayMap(array, baseProperty(index));
9652       });
9653     }
9654
9655     /**
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).
9659      *
9660      * @static
9661      * @memberOf _
9662      * @since 3.8.0
9663      * @category Array
9664      * @param {Array} array The array of grouped elements to process.
9665      * @param {Function} [iteratee=_.identity] The function to combine
9666      *  regrouped values.
9667      * @returns {Array} Returns the new array of regrouped elements.
9668      * @example
9669      *
9670      * var zipped = _.zip([1, 2], [10, 20], [100, 200]);
9671      * // => [[1, 10, 100], [2, 20, 200]]
9672      *
9673      * _.unzipWith(zipped, _.add);
9674      * // => [3, 30, 300]
9675      */
9676     function unzipWith(array, iteratee) {
9677       if (!(array && array.length)) {
9678         return [];
9679       }
9680       var result = unzip(array);
9681       if (iteratee == null) {
9682         return result;
9683       }
9684       return arrayMap(result, function(group) {
9685         return apply(iteratee, undefined, group);
9686       });
9687     }
9688
9689     /**
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.
9693      *
9694      * **Note:** Unlike `_.pull`, this method returns a new array.
9695      *
9696      * @static
9697      * @memberOf _
9698      * @since 0.1.0
9699      * @category 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
9704      * @example
9705      *
9706      * _.without([2, 1, 2, 3], 1, 2);
9707      * // => [3]
9708      */
9709     var without = baseRest(function(array, values) {
9710       return isArrayLikeObject(array)
9711         ? baseDifference(array, values)
9712         : [];
9713     });
9714
9715     /**
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.
9720      *
9721      * @static
9722      * @memberOf _
9723      * @since 2.4.0
9724      * @category Array
9725      * @param {...Array} [arrays] The arrays to inspect.
9726      * @returns {Array} Returns the new array of filtered values.
9727      * @see _.difference, _.without
9728      * @example
9729      *
9730      * _.xor([2, 1], [2, 3]);
9731      * // => [1, 3]
9732      */
9733     var xor = baseRest(function(arrays) {
9734       return baseXor(arrayFilter(arrays, isArrayLikeObject));
9735     });
9736
9737     /**
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).
9743      *
9744      * @static
9745      * @memberOf _
9746      * @since 4.0.0
9747      * @category Array
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.
9751      * @example
9752      *
9753      * _.xorBy([2.1, 1.2], [2.3, 3.4], Math.floor);
9754      * // => [1.2, 3.4]
9755      *
9756      * // The `_.property` iteratee shorthand.
9757      * _.xorBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');
9758      * // => [{ 'x': 2 }]
9759      */
9760     var xorBy = baseRest(function(arrays) {
9761       var iteratee = last(arrays);
9762       if (isArrayLikeObject(iteratee)) {
9763         iteratee = undefined;
9764       }
9765       return baseXor(arrayFilter(arrays, isArrayLikeObject), getIteratee(iteratee, 2));
9766     });
9767
9768     /**
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).
9773      *
9774      * @static
9775      * @memberOf _
9776      * @since 4.0.0
9777      * @category Array
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.
9781      * @example
9782      *
9783      * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
9784      * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }];
9785      *
9786      * _.xorWith(objects, others, _.isEqual);
9787      * // => [{ 'x': 2, 'y': 1 }, { 'x': 1, 'y': 1 }]
9788      */
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);
9793     });
9794
9795     /**
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.
9799      *
9800      * @static
9801      * @memberOf _
9802      * @since 0.1.0
9803      * @category Array
9804      * @param {...Array} [arrays] The arrays to process.
9805      * @returns {Array} Returns the new array of grouped elements.
9806      * @example
9807      *
9808      * _.zip(['a', 'b'], [1, 2], [true, false]);
9809      * // => [['a', 1, true], ['b', 2, false]]
9810      */
9811     var zip = baseRest(unzip);
9812
9813     /**
9814      * This method is like `_.fromPairs` except that it accepts two arrays,
9815      * one of property identifiers and one of corresponding values.
9816      *
9817      * @static
9818      * @memberOf _
9819      * @since 0.4.0
9820      * @category Array
9821      * @param {Array} [props=[]] The property identifiers.
9822      * @param {Array} [values=[]] The property values.
9823      * @returns {Object} Returns the new object.
9824      * @example
9825      *
9826      * _.zipObject(['a', 'b'], [1, 2]);
9827      * // => { 'a': 1, 'b': 2 }
9828      */
9829     function zipObject(props, values) {
9830       return baseZipObject(props || [], values || [], assignValue);
9831     }
9832
9833     /**
9834      * This method is like `_.zipObject` except that it supports property paths.
9835      *
9836      * @static
9837      * @memberOf _
9838      * @since 4.1.0
9839      * @category Array
9840      * @param {Array} [props=[]] The property identifiers.
9841      * @param {Array} [values=[]] The property values.
9842      * @returns {Object} Returns the new object.
9843      * @example
9844      *
9845      * _.zipObjectDeep(['a.b[0].c', 'a.b[1].d'], [1, 2]);
9846      * // => { 'a': { 'b': [{ 'c': 1 }, { 'd': 2 }] } }
9847      */
9848     function zipObjectDeep(props, values) {
9849       return baseZipObject(props || [], values || [], baseSet);
9850     }
9851
9852     /**
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).
9856      *
9857      * @static
9858      * @memberOf _
9859      * @since 3.8.0
9860      * @category Array
9861      * @param {...Array} [arrays] The arrays to process.
9862      * @param {Function} [iteratee=_.identity] The function to combine
9863      *  grouped values.
9864      * @returns {Array} Returns the new array of grouped elements.
9865      * @example
9866      *
9867      * _.zipWith([1, 2], [10, 20], [100, 200], function(a, b, c) {
9868      *   return a + b + c;
9869      * });
9870      * // => [111, 222]
9871      */
9872     var zipWith = baseRest(function(arrays) {
9873       var length = arrays.length,
9874           iteratee = length > 1 ? arrays[length - 1] : undefined;
9875
9876       iteratee = typeof iteratee == 'function' ? (arrays.pop(), iteratee) : undefined;
9877       return unzipWith(arrays, iteratee);
9878     });
9879
9880     /*------------------------------------------------------------------------*/
9881
9882     /**
9883      * Creates a `lodash` wrapper instance that wraps `value` with explicit method
9884      * chain sequences enabled. The result of such sequences must be unwrapped
9885      * with `_#value`.
9886      *
9887      * @static
9888      * @memberOf _
9889      * @since 1.3.0
9890      * @category Seq
9891      * @param {*} value The value to wrap.
9892      * @returns {Object} Returns the new `lodash` wrapper instance.
9893      * @example
9894      *
9895      * var users = [
9896      *   { 'user': 'barney',  'age': 36 },
9897      *   { 'user': 'fred',    'age': 40 },
9898      *   { 'user': 'pebbles', 'age': 1 }
9899      * ];
9900      *
9901      * var youngest = _
9902      *   .chain(users)
9903      *   .sortBy('age')
9904      *   .map(function(o) {
9905      *     return o.user + ' is ' + o.age;
9906      *   })
9907      *   .head()
9908      *   .value();
9909      * // => 'pebbles is 1'
9910      */
9911     function chain(value) {
9912       var result = lodash(value);
9913       result.__chain__ = true;
9914       return result;
9915     }
9916
9917     /**
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.
9921      *
9922      * @static
9923      * @memberOf _
9924      * @since 0.1.0
9925      * @category Seq
9926      * @param {*} value The value to provide to `interceptor`.
9927      * @param {Function} interceptor The function to invoke.
9928      * @returns {*} Returns `value`.
9929      * @example
9930      *
9931      * _([1, 2, 3])
9932      *  .tap(function(array) {
9933      *    // Mutate input array.
9934      *    array.pop();
9935      *  })
9936      *  .reverse()
9937      *  .value();
9938      * // => [2, 1]
9939      */
9940     function tap(value, interceptor) {
9941       interceptor(value);
9942       return value;
9943     }
9944
9945     /**
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.
9949      *
9950      * @static
9951      * @memberOf _
9952      * @since 3.0.0
9953      * @category Seq
9954      * @param {*} value The value to provide to `interceptor`.
9955      * @param {Function} interceptor The function to invoke.
9956      * @returns {*} Returns the result of `interceptor`.
9957      * @example
9958      *
9959      * _('  abc  ')
9960      *  .chain()
9961      *  .trim()
9962      *  .thru(function(value) {
9963      *    return [value];
9964      *  })
9965      *  .value();
9966      * // => ['abc']
9967      */
9968     function thru(value, interceptor) {
9969       return interceptor(value);
9970     }
9971
9972     /**
9973      * This method is the wrapper version of `_.at`.
9974      *
9975      * @name at
9976      * @memberOf _
9977      * @since 1.0.0
9978      * @category Seq
9979      * @param {...(string|string[])} [paths] The property paths to pick.
9980      * @returns {Object} Returns the new `lodash` wrapper instance.
9981      * @example
9982      *
9983      * var object = { 'a': [{ 'b': { 'c': 3 } }, 4] };
9984      *
9985      * _(object).at(['a[0].b.c', 'a[1]']).value();
9986      * // => [3, 4]
9987      */
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); };
9993
9994       if (length > 1 || this.__actions__.length ||
9995           !(value instanceof LazyWrapper) || !isIndex(start)) {
9996         return this.thru(interceptor);
9997       }
9998       value = value.slice(start, +start + (length ? 1 : 0));
9999       value.__actions__.push({
10000         'func': thru,
10001         'args': [interceptor],
10002         'thisArg': undefined
10003       });
10004       return new LodashWrapper(value, this.__chain__).thru(function(array) {
10005         if (length && !array.length) {
10006           array.push(undefined);
10007         }
10008         return array;
10009       });
10010     });
10011
10012     /**
10013      * Creates a `lodash` wrapper instance with explicit method chain sequences enabled.
10014      *
10015      * @name chain
10016      * @memberOf _
10017      * @since 0.1.0
10018      * @category Seq
10019      * @returns {Object} Returns the new `lodash` wrapper instance.
10020      * @example
10021      *
10022      * var users = [
10023      *   { 'user': 'barney', 'age': 36 },
10024      *   { 'user': 'fred',   'age': 40 }
10025      * ];
10026      *
10027      * // A sequence without explicit chaining.
10028      * _(users).head();
10029      * // => { 'user': 'barney', 'age': 36 }
10030      *
10031      * // A sequence with explicit chaining.
10032      * _(users)
10033      *   .chain()
10034      *   .head()
10035      *   .pick('user')
10036      *   .value();
10037      * // => { 'user': 'barney' }
10038      */
10039     function wrapperChain() {
10040       return chain(this);
10041     }
10042
10043     /**
10044      * Executes the chain sequence and returns the wrapped result.
10045      *
10046      * @name commit
10047      * @memberOf _
10048      * @since 3.2.0
10049      * @category Seq
10050      * @returns {Object} Returns the new `lodash` wrapper instance.
10051      * @example
10052      *
10053      * var array = [1, 2];
10054      * var wrapped = _(array).push(3);
10055      *
10056      * console.log(array);
10057      * // => [1, 2]
10058      *
10059      * wrapped = wrapped.commit();
10060      * console.log(array);
10061      * // => [1, 2, 3]
10062      *
10063      * wrapped.last();
10064      * // => 3
10065      *
10066      * console.log(array);
10067      * // => [1, 2, 3]
10068      */
10069     function wrapperCommit() {
10070       return new LodashWrapper(this.value(), this.__chain__);
10071     }
10072
10073     /**
10074      * Gets the next value on a wrapped object following the
10075      * [iterator protocol](https://mdn.io/iteration_protocols#iterator).
10076      *
10077      * @name next
10078      * @memberOf _
10079      * @since 4.0.0
10080      * @category Seq
10081      * @returns {Object} Returns the next iterator value.
10082      * @example
10083      *
10084      * var wrapped = _([1, 2]);
10085      *
10086      * wrapped.next();
10087      * // => { 'done': false, 'value': 1 }
10088      *
10089      * wrapped.next();
10090      * // => { 'done': false, 'value': 2 }
10091      *
10092      * wrapped.next();
10093      * // => { 'done': true, 'value': undefined }
10094      */
10095     function wrapperNext() {
10096       if (this.__values__ === undefined) {
10097         this.__values__ = toArray(this.value());
10098       }
10099       var done = this.__index__ >= this.__values__.length,
10100           value = done ? undefined : this.__values__[this.__index__++];
10101
10102       return { 'done': done, 'value': value };
10103     }
10104
10105     /**
10106      * Enables the wrapper to be iterable.
10107      *
10108      * @name Symbol.iterator
10109      * @memberOf _
10110      * @since 4.0.0
10111      * @category Seq
10112      * @returns {Object} Returns the wrapper object.
10113      * @example
10114      *
10115      * var wrapped = _([1, 2]);
10116      *
10117      * wrapped[Symbol.iterator]() === wrapped;
10118      * // => true
10119      *
10120      * Array.from(wrapped);
10121      * // => [1, 2]
10122      */
10123     function wrapperToIterator() {
10124       return this;
10125     }
10126
10127     /**
10128      * Creates a clone of the chain sequence planting `value` as the wrapped value.
10129      *
10130      * @name plant
10131      * @memberOf _
10132      * @since 3.2.0
10133      * @category Seq
10134      * @param {*} value The value to plant.
10135      * @returns {Object} Returns the new `lodash` wrapper instance.
10136      * @example
10137      *
10138      * function square(n) {
10139      *   return n * n;
10140      * }
10141      *
10142      * var wrapped = _([1, 2]).map(square);
10143      * var other = wrapped.plant([3, 4]);
10144      *
10145      * other.value();
10146      * // => [9, 16]
10147      *
10148      * wrapped.value();
10149      * // => [1, 4]
10150      */
10151     function wrapperPlant(value) {
10152       var result,
10153           parent = this;
10154
10155       while (parent instanceof baseLodash) {
10156         var clone = wrapperClone(parent);
10157         clone.__index__ = 0;
10158         clone.__values__ = undefined;
10159         if (result) {
10160           previous.__wrapped__ = clone;
10161         } else {
10162           result = clone;
10163         }
10164         var previous = clone;
10165         parent = parent.__wrapped__;
10166       }
10167       previous.__wrapped__ = value;
10168       return result;
10169     }
10170
10171     /**
10172      * This method is the wrapper version of `_.reverse`.
10173      *
10174      * **Note:** This method mutates the wrapped array.
10175      *
10176      * @name reverse
10177      * @memberOf _
10178      * @since 0.1.0
10179      * @category Seq
10180      * @returns {Object} Returns the new `lodash` wrapper instance.
10181      * @example
10182      *
10183      * var array = [1, 2, 3];
10184      *
10185      * _(array).reverse().value()
10186      * // => [3, 2, 1]
10187      *
10188      * console.log(array);
10189      * // => [3, 2, 1]
10190      */
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);
10197         }
10198         wrapped = wrapped.reverse();
10199         wrapped.__actions__.push({
10200           'func': thru,
10201           'args': [reverse],
10202           'thisArg': undefined
10203         });
10204         return new LodashWrapper(wrapped, this.__chain__);
10205       }
10206       return this.thru(reverse);
10207     }
10208
10209     /**
10210      * Executes the chain sequence to resolve the unwrapped value.
10211      *
10212      * @name value
10213      * @memberOf _
10214      * @since 0.1.0
10215      * @alias toJSON, valueOf
10216      * @category Seq
10217      * @returns {*} Returns the resolved unwrapped value.
10218      * @example
10219      *
10220      * _([1, 2, 3]).value();
10221      * // => [1, 2, 3]
10222      */
10223     function wrapperValue() {
10224       return baseWrapperValue(this.__wrapped__, this.__actions__);
10225     }
10226
10227     /*------------------------------------------------------------------------*/
10228
10229     /**
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).
10234      *
10235      * @static
10236      * @memberOf _
10237      * @since 0.5.0
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.
10242      * @example
10243      *
10244      * _.countBy([6.1, 4.2, 6.3], Math.floor);
10245      * // => { '4': 1, '6': 2 }
10246      *
10247      * // The `_.property` iteratee shorthand.
10248      * _.countBy(['one', 'two', 'three'], 'length');
10249      * // => { '3': 2, '5': 1 }
10250      */
10251     var countBy = createAggregator(function(result, value, key) {
10252       if (hasOwnProperty.call(result, key)) {
10253         ++result[key];
10254       } else {
10255         baseAssignValue(result, key, 1);
10256       }
10257     });
10258
10259     /**
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).
10263      *
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.
10268      *
10269      * @static
10270      * @memberOf _
10271      * @since 0.1.0
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,
10277      *  else `false`.
10278      * @example
10279      *
10280      * _.every([true, 1, null, 'yes'], Boolean);
10281      * // => false
10282      *
10283      * var users = [
10284      *   { 'user': 'barney', 'age': 36, 'active': false },
10285      *   { 'user': 'fred',   'age': 40, 'active': false }
10286      * ];
10287      *
10288      * // The `_.matches` iteratee shorthand.
10289      * _.every(users, { 'user': 'barney', 'active': false });
10290      * // => false
10291      *
10292      * // The `_.matchesProperty` iteratee shorthand.
10293      * _.every(users, ['active', false]);
10294      * // => true
10295      *
10296      * // The `_.property` iteratee shorthand.
10297      * _.every(users, 'active');
10298      * // => false
10299      */
10300     function every(collection, predicate, guard) {
10301       var func = isArray(collection) ? arrayEvery : baseEvery;
10302       if (guard && isIterateeCall(collection, predicate, guard)) {
10303         predicate = undefined;
10304       }
10305       return func(collection, getIteratee(predicate, 3));
10306     }
10307
10308     /**
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).
10312      *
10313      * **Note:** Unlike `_.remove`, this method returns a new array.
10314      *
10315      * @static
10316      * @memberOf _
10317      * @since 0.1.0
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.
10322      * @see _.reject
10323      * @example
10324      *
10325      * var users = [
10326      *   { 'user': 'barney', 'age': 36, 'active': true },
10327      *   { 'user': 'fred',   'age': 40, 'active': false }
10328      * ];
10329      *
10330      * _.filter(users, function(o) { return !o.active; });
10331      * // => objects for ['fred']
10332      *
10333      * // The `_.matches` iteratee shorthand.
10334      * _.filter(users, { 'age': 36, 'active': true });
10335      * // => objects for ['barney']
10336      *
10337      * // The `_.matchesProperty` iteratee shorthand.
10338      * _.filter(users, ['active', false]);
10339      * // => objects for ['fred']
10340      *
10341      * // The `_.property` iteratee shorthand.
10342      * _.filter(users, 'active');
10343      * // => objects for ['barney']
10344      *
10345      * // Combining several predicates using `_.overEvery` or `_.overSome`.
10346      * _.filter(users, _.overSome([{ 'age': 36 }, ['age', 40]]));
10347      * // => objects for ['fred', 'barney']
10348      */
10349     function filter(collection, predicate) {
10350       var func = isArray(collection) ? arrayFilter : baseFilter;
10351       return func(collection, getIteratee(predicate, 3));
10352     }
10353
10354     /**
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).
10358      *
10359      * @static
10360      * @memberOf _
10361      * @since 0.1.0
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`.
10367      * @example
10368      *
10369      * var users = [
10370      *   { 'user': 'barney',  'age': 36, 'active': true },
10371      *   { 'user': 'fred',    'age': 40, 'active': false },
10372      *   { 'user': 'pebbles', 'age': 1,  'active': true }
10373      * ];
10374      *
10375      * _.find(users, function(o) { return o.age < 40; });
10376      * // => object for 'barney'
10377      *
10378      * // The `_.matches` iteratee shorthand.
10379      * _.find(users, { 'age': 1, 'active': true });
10380      * // => object for 'pebbles'
10381      *
10382      * // The `_.matchesProperty` iteratee shorthand.
10383      * _.find(users, ['active', false]);
10384      * // => object for 'fred'
10385      *
10386      * // The `_.property` iteratee shorthand.
10387      * _.find(users, 'active');
10388      * // => object for 'barney'
10389      */
10390     var find = createFind(findIndex);
10391
10392     /**
10393      * This method is like `_.find` except that it iterates over elements of
10394      * `collection` from right to left.
10395      *
10396      * @static
10397      * @memberOf _
10398      * @since 2.0.0
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`.
10404      * @example
10405      *
10406      * _.findLast([1, 2, 3, 4], function(n) {
10407      *   return n % 2 == 1;
10408      * });
10409      * // => 3
10410      */
10411     var findLast = createFind(findLastIndex);
10412
10413     /**
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).
10417      *
10418      * @static
10419      * @memberOf _
10420      * @since 4.0.0
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.
10425      * @example
10426      *
10427      * function duplicate(n) {
10428      *   return [n, n];
10429      * }
10430      *
10431      * _.flatMap([1, 2], duplicate);
10432      * // => [1, 1, 2, 2]
10433      */
10434     function flatMap(collection, iteratee) {
10435       return baseFlatten(map(collection, iteratee), 1);
10436     }
10437
10438     /**
10439      * This method is like `_.flatMap` except that it recursively flattens the
10440      * mapped results.
10441      *
10442      * @static
10443      * @memberOf _
10444      * @since 4.7.0
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.
10449      * @example
10450      *
10451      * function duplicate(n) {
10452      *   return [[[n, n]]];
10453      * }
10454      *
10455      * _.flatMapDeep([1, 2], duplicate);
10456      * // => [1, 1, 2, 2]
10457      */
10458     function flatMapDeep(collection, iteratee) {
10459       return baseFlatten(map(collection, iteratee), INFINITY);
10460     }
10461
10462     /**
10463      * This method is like `_.flatMap` except that it recursively flattens the
10464      * mapped results up to `depth` times.
10465      *
10466      * @static
10467      * @memberOf _
10468      * @since 4.7.0
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.
10474      * @example
10475      *
10476      * function duplicate(n) {
10477      *   return [[[n, n]]];
10478      * }
10479      *
10480      * _.flatMapDepth([1, 2], duplicate, 2);
10481      * // => [[1, 1], [2, 2]]
10482      */
10483     function flatMapDepth(collection, iteratee, depth) {
10484       depth = depth === undefined ? 1 : toInteger(depth);
10485       return baseFlatten(map(collection, iteratee), depth);
10486     }
10487
10488     /**
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`.
10492      *
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.
10496      *
10497      * @static
10498      * @memberOf _
10499      * @since 0.1.0
10500      * @alias each
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
10506      * @example
10507      *
10508      * _.forEach([1, 2], function(value) {
10509      *   console.log(value);
10510      * });
10511      * // => Logs `1` then `2`.
10512      *
10513      * _.forEach({ 'a': 1, 'b': 2 }, function(value, key) {
10514      *   console.log(key);
10515      * });
10516      * // => Logs 'a' then 'b' (iteration order is not guaranteed).
10517      */
10518     function forEach(collection, iteratee) {
10519       var func = isArray(collection) ? arrayEach : baseEach;
10520       return func(collection, getIteratee(iteratee, 3));
10521     }
10522
10523     /**
10524      * This method is like `_.forEach` except that it iterates over elements of
10525      * `collection` from right to left.
10526      *
10527      * @static
10528      * @memberOf _
10529      * @since 2.0.0
10530      * @alias eachRight
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`.
10535      * @see _.forEach
10536      * @example
10537      *
10538      * _.forEachRight([1, 2], function(value) {
10539      *   console.log(value);
10540      * });
10541      * // => Logs `2` then `1`.
10542      */
10543     function forEachRight(collection, iteratee) {
10544       var func = isArray(collection) ? arrayEachRight : baseEachRight;
10545       return func(collection, getIteratee(iteratee, 3));
10546     }
10547
10548     /**
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).
10554      *
10555      * @static
10556      * @memberOf _
10557      * @since 0.1.0
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.
10562      * @example
10563      *
10564      * _.groupBy([6.1, 4.2, 6.3], Math.floor);
10565      * // => { '4': [4.2], '6': [6.1, 6.3] }
10566      *
10567      * // The `_.property` iteratee shorthand.
10568      * _.groupBy(['one', 'two', 'three'], 'length');
10569      * // => { '3': ['one', 'two'], '5': ['three'] }
10570      */
10571     var groupBy = createAggregator(function(result, value, key) {
10572       if (hasOwnProperty.call(result, key)) {
10573         result[key].push(value);
10574       } else {
10575         baseAssignValue(result, key, [value]);
10576       }
10577     });
10578
10579     /**
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`.
10585      *
10586      * @static
10587      * @memberOf _
10588      * @since 0.1.0
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`.
10595      * @example
10596      *
10597      * _.includes([1, 2, 3], 1);
10598      * // => true
10599      *
10600      * _.includes([1, 2, 3], 1, 2);
10601      * // => false
10602      *
10603      * _.includes({ 'a': 1, 'b': 2 }, 1);
10604      * // => true
10605      *
10606      * _.includes('abcd', 'bc');
10607      * // => true
10608      */
10609     function includes(collection, value, fromIndex, guard) {
10610       collection = isArrayLike(collection) ? collection : values(collection);
10611       fromIndex = (fromIndex && !guard) ? toInteger(fromIndex) : 0;
10612
10613       var length = collection.length;
10614       if (fromIndex < 0) {
10615         fromIndex = nativeMax(length + fromIndex, 0);
10616       }
10617       return isString(collection)
10618         ? (fromIndex <= length && collection.indexOf(value, fromIndex) > -1)
10619         : (!!length && baseIndexOf(collection, value, fromIndex) > -1);
10620     }
10621
10622     /**
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`.
10627      *
10628      * @static
10629      * @memberOf _
10630      * @since 4.0.0
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.
10637      * @example
10638      *
10639      * _.invokeMap([[5, 1, 7], [3, 2, 1]], 'sort');
10640      * // => [[1, 5, 7], [1, 2, 3]]
10641      *
10642      * _.invokeMap([123, 456], String.prototype.split, '');
10643      * // => [['1', '2', '3'], ['4', '5', '6']]
10644      */
10645     var invokeMap = baseRest(function(collection, path, args) {
10646       var index = -1,
10647           isFunc = typeof path == 'function',
10648           result = isArrayLike(collection) ? Array(collection.length) : [];
10649
10650       baseEach(collection, function(value) {
10651         result[++index] = isFunc ? apply(path, value, args) : baseInvoke(value, path, args);
10652       });
10653       return result;
10654     });
10655
10656     /**
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).
10661      *
10662      * @static
10663      * @memberOf _
10664      * @since 4.0.0
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.
10669      * @example
10670      *
10671      * var array = [
10672      *   { 'dir': 'left', 'code': 97 },
10673      *   { 'dir': 'right', 'code': 100 }
10674      * ];
10675      *
10676      * _.keyBy(array, function(o) {
10677      *   return String.fromCharCode(o.code);
10678      * });
10679      * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } }
10680      *
10681      * _.keyBy(array, 'dir');
10682      * // => { 'left': { 'dir': 'left', 'code': 97 }, 'right': { 'dir': 'right', 'code': 100 } }
10683      */
10684     var keyBy = createAggregator(function(result, value, key) {
10685       baseAssignValue(result, key, value);
10686     });
10687
10688     /**
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).
10692      *
10693      * Many lodash methods are guarded to work as iteratees for methods like
10694      * `_.every`, `_.filter`, `_.map`, `_.mapValues`, `_.reject`, and `_.some`.
10695      *
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`
10701      *
10702      * @static
10703      * @memberOf _
10704      * @since 0.1.0
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.
10709      * @example
10710      *
10711      * function square(n) {
10712      *   return n * n;
10713      * }
10714      *
10715      * _.map([4, 8], square);
10716      * // => [16, 64]
10717      *
10718      * _.map({ 'a': 4, 'b': 8 }, square);
10719      * // => [16, 64] (iteration order is not guaranteed)
10720      *
10721      * var users = [
10722      *   { 'user': 'barney' },
10723      *   { 'user': 'fred' }
10724      * ];
10725      *
10726      * // The `_.property` iteratee shorthand.
10727      * _.map(users, 'user');
10728      * // => ['barney', 'fred']
10729      */
10730     function map(collection, iteratee) {
10731       var func = isArray(collection) ? arrayMap : baseMap;
10732       return func(collection, getIteratee(iteratee, 3));
10733     }
10734
10735     /**
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.
10740      *
10741      * @static
10742      * @memberOf _
10743      * @since 4.0.0
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.
10751      * @example
10752      *
10753      * var users = [
10754      *   { 'user': 'fred',   'age': 48 },
10755      *   { 'user': 'barney', 'age': 34 },
10756      *   { 'user': 'fred',   'age': 40 },
10757      *   { 'user': 'barney', 'age': 36 }
10758      * ];
10759      *
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]]
10763      */
10764     function orderBy(collection, iteratees, orders, guard) {
10765       if (collection == null) {
10766         return [];
10767       }
10768       if (!isArray(iteratees)) {
10769         iteratees = iteratees == null ? [] : [iteratees];
10770       }
10771       orders = guard ? undefined : orders;
10772       if (!isArray(orders)) {
10773         orders = orders == null ? [] : [orders];
10774       }
10775       return baseOrderBy(collection, iteratees, orders);
10776     }
10777
10778     /**
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).
10783      *
10784      * @static
10785      * @memberOf _
10786      * @since 3.0.0
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.
10791      * @example
10792      *
10793      * var users = [
10794      *   { 'user': 'barney',  'age': 36, 'active': false },
10795      *   { 'user': 'fred',    'age': 40, 'active': true },
10796      *   { 'user': 'pebbles', 'age': 1,  'active': false }
10797      * ];
10798      *
10799      * _.partition(users, function(o) { return o.active; });
10800      * // => objects for [['fred'], ['barney', 'pebbles']]
10801      *
10802      * // The `_.matches` iteratee shorthand.
10803      * _.partition(users, { 'age': 1, 'active': false });
10804      * // => objects for [['pebbles'], ['barney', 'fred']]
10805      *
10806      * // The `_.matchesProperty` iteratee shorthand.
10807      * _.partition(users, ['active', false]);
10808      * // => objects for [['barney', 'pebbles'], ['fred']]
10809      *
10810      * // The `_.property` iteratee shorthand.
10811      * _.partition(users, 'active');
10812      * // => objects for [['fred'], ['barney', 'pebbles']]
10813      */
10814     var partition = createAggregator(function(result, value, key) {
10815       result[key ? 0 : 1].push(value);
10816     }, function() { return [[], []]; });
10817
10818     /**
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).
10825      *
10826      * Many lodash methods are guarded to work as iteratees for methods like
10827      * `_.reduce`, `_.reduceRight`, and `_.transform`.
10828      *
10829      * The guarded methods are:
10830      * `assign`, `defaults`, `defaultsDeep`, `includes`, `merge`, `orderBy`,
10831      * and `sortBy`
10832      *
10833      * @static
10834      * @memberOf _
10835      * @since 0.1.0
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
10842      * @example
10843      *
10844      * _.reduce([1, 2], function(sum, n) {
10845      *   return sum + n;
10846      * }, 0);
10847      * // => 3
10848      *
10849      * _.reduce({ 'a': 1, 'b': 2, 'c': 1 }, function(result, value, key) {
10850      *   (result[value] || (result[value] = [])).push(key);
10851      *   return result;
10852      * }, {});
10853      * // => { '1': ['a', 'c'], '2': ['b'] } (iteration order is not guaranteed)
10854      */
10855     function reduce(collection, iteratee, accumulator) {
10856       var func = isArray(collection) ? arrayReduce : baseReduce,
10857           initAccum = arguments.length < 3;
10858
10859       return func(collection, getIteratee(iteratee, 4), accumulator, initAccum, baseEach);
10860     }
10861
10862     /**
10863      * This method is like `_.reduce` except that it iterates over elements of
10864      * `collection` from right to left.
10865      *
10866      * @static
10867      * @memberOf _
10868      * @since 0.1.0
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.
10874      * @see _.reduce
10875      * @example
10876      *
10877      * var array = [[0, 1], [2, 3], [4, 5]];
10878      *
10879      * _.reduceRight(array, function(flattened, other) {
10880      *   return flattened.concat(other);
10881      * }, []);
10882      * // => [4, 5, 2, 3, 0, 1]
10883      */
10884     function reduceRight(collection, iteratee, accumulator) {
10885       var func = isArray(collection) ? arrayReduceRight : baseReduce,
10886           initAccum = arguments.length < 3;
10887
10888       return func(collection, getIteratee(iteratee, 4), accumulator, initAccum, baseEachRight);
10889     }
10890
10891     /**
10892      * The opposite of `_.filter`; this method returns the elements of `collection`
10893      * that `predicate` does **not** return truthy for.
10894      *
10895      * @static
10896      * @memberOf _
10897      * @since 0.1.0
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.
10902      * @see _.filter
10903      * @example
10904      *
10905      * var users = [
10906      *   { 'user': 'barney', 'age': 36, 'active': false },
10907      *   { 'user': 'fred',   'age': 40, 'active': true }
10908      * ];
10909      *
10910      * _.reject(users, function(o) { return !o.active; });
10911      * // => objects for ['fred']
10912      *
10913      * // The `_.matches` iteratee shorthand.
10914      * _.reject(users, { 'age': 40, 'active': true });
10915      * // => objects for ['barney']
10916      *
10917      * // The `_.matchesProperty` iteratee shorthand.
10918      * _.reject(users, ['active', false]);
10919      * // => objects for ['fred']
10920      *
10921      * // The `_.property` iteratee shorthand.
10922      * _.reject(users, 'active');
10923      * // => objects for ['barney']
10924      */
10925     function reject(collection, predicate) {
10926       var func = isArray(collection) ? arrayFilter : baseFilter;
10927       return func(collection, negate(getIteratee(predicate, 3)));
10928     }
10929
10930     /**
10931      * Gets a random element from `collection`.
10932      *
10933      * @static
10934      * @memberOf _
10935      * @since 2.0.0
10936      * @category Collection
10937      * @param {Array|Object} collection The collection to sample.
10938      * @returns {*} Returns the random element.
10939      * @example
10940      *
10941      * _.sample([1, 2, 3, 4]);
10942      * // => 2
10943      */
10944     function sample(collection) {
10945       var func = isArray(collection) ? arraySample : baseSample;
10946       return func(collection);
10947     }
10948
10949     /**
10950      * Gets `n` random elements at unique keys from `collection` up to the
10951      * size of `collection`.
10952      *
10953      * @static
10954      * @memberOf _
10955      * @since 4.0.0
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.
10961      * @example
10962      *
10963      * _.sampleSize([1, 2, 3], 2);
10964      * // => [3, 1]
10965      *
10966      * _.sampleSize([1, 2, 3], 4);
10967      * // => [2, 3, 1]
10968      */
10969     function sampleSize(collection, n, guard) {
10970       if ((guard ? isIterateeCall(collection, n, guard) : n === undefined)) {
10971         n = 1;
10972       } else {
10973         n = toInteger(n);
10974       }
10975       var func = isArray(collection) ? arraySampleSize : baseSampleSize;
10976       return func(collection, n);
10977     }
10978
10979     /**
10980      * Creates an array of shuffled values, using a version of the
10981      * [Fisher-Yates shuffle](https://en.wikipedia.org/wiki/Fisher-Yates_shuffle).
10982      *
10983      * @static
10984      * @memberOf _
10985      * @since 0.1.0
10986      * @category Collection
10987      * @param {Array|Object} collection The collection to shuffle.
10988      * @returns {Array} Returns the new shuffled array.
10989      * @example
10990      *
10991      * _.shuffle([1, 2, 3, 4]);
10992      * // => [4, 1, 3, 2]
10993      */
10994     function shuffle(collection) {
10995       var func = isArray(collection) ? arrayShuffle : baseShuffle;
10996       return func(collection);
10997     }
10998
10999     /**
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.
11002      *
11003      * @static
11004      * @memberOf _
11005      * @since 0.1.0
11006      * @category Collection
11007      * @param {Array|Object|string} collection The collection to inspect.
11008      * @returns {number} Returns the collection size.
11009      * @example
11010      *
11011      * _.size([1, 2, 3]);
11012      * // => 3
11013      *
11014      * _.size({ 'a': 1, 'b': 2 });
11015      * // => 2
11016      *
11017      * _.size('pebbles');
11018      * // => 7
11019      */
11020     function size(collection) {
11021       if (collection == null) {
11022         return 0;
11023       }
11024       if (isArrayLike(collection)) {
11025         return isString(collection) ? stringSize(collection) : collection.length;
11026       }
11027       var tag = getTag(collection);
11028       if (tag == mapTag || tag == setTag) {
11029         return collection.size;
11030       }
11031       return baseKeys(collection).length;
11032     }
11033
11034     /**
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).
11038      *
11039      * @static
11040      * @memberOf _
11041      * @since 0.1.0
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,
11047      *  else `false`.
11048      * @example
11049      *
11050      * _.some([null, 0, 'yes', false], Boolean);
11051      * // => true
11052      *
11053      * var users = [
11054      *   { 'user': 'barney', 'active': true },
11055      *   { 'user': 'fred',   'active': false }
11056      * ];
11057      *
11058      * // The `_.matches` iteratee shorthand.
11059      * _.some(users, { 'user': 'barney', 'active': false });
11060      * // => false
11061      *
11062      * // The `_.matchesProperty` iteratee shorthand.
11063      * _.some(users, ['active', false]);
11064      * // => true
11065      *
11066      * // The `_.property` iteratee shorthand.
11067      * _.some(users, 'active');
11068      * // => true
11069      */
11070     function some(collection, predicate, guard) {
11071       var func = isArray(collection) ? arraySome : baseSome;
11072       if (guard && isIterateeCall(collection, predicate, guard)) {
11073         predicate = undefined;
11074       }
11075       return func(collection, getIteratee(predicate, 3));
11076     }
11077
11078     /**
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).
11083      *
11084      * @static
11085      * @memberOf _
11086      * @since 0.1.0
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.
11092      * @example
11093      *
11094      * var users = [
11095      *   { 'user': 'fred',   'age': 48 },
11096      *   { 'user': 'barney', 'age': 36 },
11097      *   { 'user': 'fred',   'age': 30 },
11098      *   { 'user': 'barney', 'age': 34 }
11099      * ];
11100      *
11101      * _.sortBy(users, [function(o) { return o.user; }]);
11102      * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 30]]
11103      *
11104      * _.sortBy(users, ['user', 'age']);
11105      * // => objects for [['barney', 34], ['barney', 36], ['fred', 30], ['fred', 48]]
11106      */
11107     var sortBy = baseRest(function(collection, iteratees) {
11108       if (collection == null) {
11109         return [];
11110       }
11111       var length = iteratees.length;
11112       if (length > 1 && isIterateeCall(collection, iteratees[0], iteratees[1])) {
11113         iteratees = [];
11114       } else if (length > 2 && isIterateeCall(iteratees[0], iteratees[1], iteratees[2])) {
11115         iteratees = [iteratees[0]];
11116       }
11117       return baseOrderBy(collection, baseFlatten(iteratees, 1), []);
11118     });
11119
11120     /*------------------------------------------------------------------------*/
11121
11122     /**
11123      * Gets the timestamp of the number of milliseconds that have elapsed since
11124      * the Unix epoch (1 January 1970 00:00:00 UTC).
11125      *
11126      * @static
11127      * @memberOf _
11128      * @since 2.4.0
11129      * @category Date
11130      * @returns {number} Returns the timestamp.
11131      * @example
11132      *
11133      * _.defer(function(stamp) {
11134      *   console.log(_.now() - stamp);
11135      * }, _.now());
11136      * // => Logs the number of milliseconds it took for the deferred invocation.
11137      */
11138     var now = ctxNow || function() {
11139       return root.Date.now();
11140     };
11141
11142     /*------------------------------------------------------------------------*/
11143
11144     /**
11145      * The opposite of `_.before`; this method creates a function that invokes
11146      * `func` once it's called `n` or more times.
11147      *
11148      * @static
11149      * @memberOf _
11150      * @since 0.1.0
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.
11155      * @example
11156      *
11157      * var saves = ['profile', 'settings'];
11158      *
11159      * var done = _.after(saves.length, function() {
11160      *   console.log('done saving!');
11161      * });
11162      *
11163      * _.forEach(saves, function(type) {
11164      *   asyncSave({ 'type': type, 'complete': done });
11165      * });
11166      * // => Logs 'done saving!' after the two async saves have completed.
11167      */
11168     function after(n, func) {
11169       if (typeof func != 'function') {
11170         throw new TypeError(FUNC_ERROR_TEXT);
11171       }
11172       n = toInteger(n);
11173       return function() {
11174         if (--n < 1) {
11175           return func.apply(this, arguments);
11176         }
11177       };
11178     }
11179
11180     /**
11181      * Creates a function that invokes `func`, with up to `n` arguments,
11182      * ignoring any additional arguments.
11183      *
11184      * @static
11185      * @memberOf _
11186      * @since 3.0.0
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.
11192      * @example
11193      *
11194      * _.map(['6', '8', '10'], _.ary(parseInt, 1));
11195      * // => [6, 8, 10]
11196      */
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);
11201     }
11202
11203     /**
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.
11207      *
11208      * @static
11209      * @memberOf _
11210      * @since 3.0.0
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.
11215      * @example
11216      *
11217      * jQuery(element).on('click', _.before(5, addContactToList));
11218      * // => Allows adding up to 4 contacts to the list.
11219      */
11220     function before(n, func) {
11221       var result;
11222       if (typeof func != 'function') {
11223         throw new TypeError(FUNC_ERROR_TEXT);
11224       }
11225       n = toInteger(n);
11226       return function() {
11227         if (--n > 0) {
11228           result = func.apply(this, arguments);
11229         }
11230         if (n <= 1) {
11231           func = undefined;
11232         }
11233         return result;
11234       };
11235     }
11236
11237     /**
11238      * Creates a function that invokes `func` with the `this` binding of `thisArg`
11239      * and `partials` prepended to the arguments it receives.
11240      *
11241      * The `_.bind.placeholder` value, which defaults to `_` in monolithic builds,
11242      * may be used as a placeholder for partially applied arguments.
11243      *
11244      * **Note:** Unlike native `Function#bind`, this method doesn't set the "length"
11245      * property of bound functions.
11246      *
11247      * @static
11248      * @memberOf _
11249      * @since 0.1.0
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.
11255      * @example
11256      *
11257      * function greet(greeting, punctuation) {
11258      *   return greeting + ' ' + this.user + punctuation;
11259      * }
11260      *
11261      * var object = { 'user': 'fred' };
11262      *
11263      * var bound = _.bind(greet, object, 'hi');
11264      * bound('!');
11265      * // => 'hi fred!'
11266      *
11267      * // Bound with placeholders.
11268      * var bound = _.bind(greet, object, _, '!');
11269      * bound('hi');
11270      * // => 'hi fred!'
11271      */
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;
11277       }
11278       return createWrap(func, bitmask, thisArg, partials, holders);
11279     });
11280
11281     /**
11282      * Creates a function that invokes the method at `object[key]` with `partials`
11283      * prepended to the arguments it receives.
11284      *
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.
11289      *
11290      * The `_.bindKey.placeholder` value, which defaults to `_` in monolithic
11291      * builds, may be used as a placeholder for partially applied arguments.
11292      *
11293      * @static
11294      * @memberOf _
11295      * @since 0.10.0
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.
11301      * @example
11302      *
11303      * var object = {
11304      *   'user': 'fred',
11305      *   'greet': function(greeting, punctuation) {
11306      *     return greeting + ' ' + this.user + punctuation;
11307      *   }
11308      * };
11309      *
11310      * var bound = _.bindKey(object, 'greet', 'hi');
11311      * bound('!');
11312      * // => 'hi fred!'
11313      *
11314      * object.greet = function(greeting, punctuation) {
11315      *   return greeting + 'ya ' + this.user + punctuation;
11316      * };
11317      *
11318      * bound('!');
11319      * // => 'hiya fred!'
11320      *
11321      * // Bound with placeholders.
11322      * var bound = _.bindKey(object, 'greet', _, '!');
11323      * bound('hi');
11324      * // => 'hiya fred!'
11325      */
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;
11331       }
11332       return createWrap(key, bitmask, object, partials, holders);
11333     });
11334
11335     /**
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.
11341      *
11342      * The `_.curry.placeholder` value, which defaults to `_` in monolithic builds,
11343      * may be used as a placeholder for provided arguments.
11344      *
11345      * **Note:** This method doesn't set the "length" property of curried functions.
11346      *
11347      * @static
11348      * @memberOf _
11349      * @since 2.0.0
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.
11355      * @example
11356      *
11357      * var abc = function(a, b, c) {
11358      *   return [a, b, c];
11359      * };
11360      *
11361      * var curried = _.curry(abc);
11362      *
11363      * curried(1)(2)(3);
11364      * // => [1, 2, 3]
11365      *
11366      * curried(1, 2)(3);
11367      * // => [1, 2, 3]
11368      *
11369      * curried(1, 2, 3);
11370      * // => [1, 2, 3]
11371      *
11372      * // Curried with placeholders.
11373      * curried(1)(_, 3)(2);
11374      * // => [1, 2, 3]
11375      */
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;
11380       return result;
11381     }
11382
11383     /**
11384      * This method is like `_.curry` except that arguments are applied to `func`
11385      * in the manner of `_.partialRight` instead of `_.partial`.
11386      *
11387      * The `_.curryRight.placeholder` value, which defaults to `_` in monolithic
11388      * builds, may be used as a placeholder for provided arguments.
11389      *
11390      * **Note:** This method doesn't set the "length" property of curried functions.
11391      *
11392      * @static
11393      * @memberOf _
11394      * @since 3.0.0
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.
11400      * @example
11401      *
11402      * var abc = function(a, b, c) {
11403      *   return [a, b, c];
11404      * };
11405      *
11406      * var curried = _.curryRight(abc);
11407      *
11408      * curried(3)(2)(1);
11409      * // => [1, 2, 3]
11410      *
11411      * curried(2, 3)(1);
11412      * // => [1, 2, 3]
11413      *
11414      * curried(1, 2, 3);
11415      * // => [1, 2, 3]
11416      *
11417      * // Curried with placeholders.
11418      * curried(3)(1, _)(2);
11419      * // => [1, 2, 3]
11420      */
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;
11425       return result;
11426     }
11427
11428     /**
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`
11437      * invocation.
11438      *
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.
11442      *
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`.
11445      *
11446      * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/)
11447      * for details over the differences between `_.debounce` and `_.throttle`.
11448      *
11449      * @static
11450      * @memberOf _
11451      * @since 0.1.0
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.
11463      * @example
11464      *
11465      * // Avoid costly calculations while the window size is in flux.
11466      * jQuery(window).on('resize', _.debounce(calculateLayout, 150));
11467      *
11468      * // Invoke `sendMail` when clicked, debouncing subsequent calls.
11469      * jQuery(element).on('click', _.debounce(sendMail, 300, {
11470      *   'leading': true,
11471      *   'trailing': false
11472      * }));
11473      *
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);
11478      *
11479      * // Cancel the trailing debounced invocation.
11480      * jQuery(window).on('popstate', debounced.cancel);
11481      */
11482     function debounce(func, wait, options) {
11483       var lastArgs,
11484           lastThis,
11485           maxWait,
11486           result,
11487           timerId,
11488           lastCallTime,
11489           lastInvokeTime = 0,
11490           leading = false,
11491           maxing = false,
11492           trailing = true;
11493
11494       if (typeof func != 'function') {
11495         throw new TypeError(FUNC_ERROR_TEXT);
11496       }
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;
11503       }
11504
11505       function invokeFunc(time) {
11506         var args = lastArgs,
11507             thisArg = lastThis;
11508
11509         lastArgs = lastThis = undefined;
11510         lastInvokeTime = time;
11511         result = func.apply(thisArg, args);
11512         return result;
11513       }
11514
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;
11522       }
11523
11524       function remainingWait(time) {
11525         var timeSinceLastCall = time - lastCallTime,
11526             timeSinceLastInvoke = time - lastInvokeTime,
11527             timeWaiting = wait - timeSinceLastCall;
11528
11529         return maxing
11530           ? nativeMin(timeWaiting, maxWait - timeSinceLastInvoke)
11531           : timeWaiting;
11532       }
11533
11534       function shouldInvoke(time) {
11535         var timeSinceLastCall = time - lastCallTime,
11536             timeSinceLastInvoke = time - lastInvokeTime;
11537
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));
11543       }
11544
11545       function timerExpired() {
11546         var time = now();
11547         if (shouldInvoke(time)) {
11548           return trailingEdge(time);
11549         }
11550         // Restart the timer.
11551         timerId = setTimeout(timerExpired, remainingWait(time));
11552       }
11553
11554       function trailingEdge(time) {
11555         timerId = undefined;
11556
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);
11561         }
11562         lastArgs = lastThis = undefined;
11563         return result;
11564       }
11565
11566       function cancel() {
11567         if (timerId !== undefined) {
11568           clearTimeout(timerId);
11569         }
11570         lastInvokeTime = 0;
11571         lastArgs = lastCallTime = lastThis = timerId = undefined;
11572       }
11573
11574       function flush() {
11575         return timerId === undefined ? result : trailingEdge(now());
11576       }
11577
11578       function debounced() {
11579         var time = now(),
11580             isInvoking = shouldInvoke(time);
11581
11582         lastArgs = arguments;
11583         lastThis = this;
11584         lastCallTime = time;
11585
11586         if (isInvoking) {
11587           if (timerId === undefined) {
11588             return leadingEdge(lastCallTime);
11589           }
11590           if (maxing) {
11591             // Handle invocations in a tight loop.
11592             clearTimeout(timerId);
11593             timerId = setTimeout(timerExpired, wait);
11594             return invokeFunc(lastCallTime);
11595           }
11596         }
11597         if (timerId === undefined) {
11598           timerId = setTimeout(timerExpired, wait);
11599         }
11600         return result;
11601       }
11602       debounced.cancel = cancel;
11603       debounced.flush = flush;
11604       return debounced;
11605     }
11606
11607     /**
11608      * Defers invoking the `func` until the current call stack has cleared. Any
11609      * additional arguments are provided to `func` when it's invoked.
11610      *
11611      * @static
11612      * @memberOf _
11613      * @since 0.1.0
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.
11618      * @example
11619      *
11620      * _.defer(function(text) {
11621      *   console.log(text);
11622      * }, 'deferred');
11623      * // => Logs 'deferred' after one millisecond.
11624      */
11625     var defer = baseRest(function(func, args) {
11626       return baseDelay(func, 1, args);
11627     });
11628
11629     /**
11630      * Invokes `func` after `wait` milliseconds. Any additional arguments are
11631      * provided to `func` when it's invoked.
11632      *
11633      * @static
11634      * @memberOf _
11635      * @since 0.1.0
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.
11641      * @example
11642      *
11643      * _.delay(function(text) {
11644      *   console.log(text);
11645      * }, 1000, 'later');
11646      * // => Logs 'later' after one second.
11647      */
11648     var delay = baseRest(function(func, wait, args) {
11649       return baseDelay(func, toNumber(wait) || 0, args);
11650     });
11651
11652     /**
11653      * Creates a function that invokes `func` with arguments reversed.
11654      *
11655      * @static
11656      * @memberOf _
11657      * @since 4.0.0
11658      * @category Function
11659      * @param {Function} func The function to flip arguments for.
11660      * @returns {Function} Returns the new flipped function.
11661      * @example
11662      *
11663      * var flipped = _.flip(function() {
11664      *   return _.toArray(arguments);
11665      * });
11666      *
11667      * flipped('a', 'b', 'c', 'd');
11668      * // => ['d', 'c', 'b', 'a']
11669      */
11670     function flip(func) {
11671       return createWrap(func, WRAP_FLIP_FLAG);
11672     }
11673
11674     /**
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.
11680      *
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`.
11686      *
11687      * @static
11688      * @memberOf _
11689      * @since 0.1.0
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.
11694      * @example
11695      *
11696      * var object = { 'a': 1, 'b': 2 };
11697      * var other = { 'c': 3, 'd': 4 };
11698      *
11699      * var values = _.memoize(_.values);
11700      * values(object);
11701      * // => [1, 2]
11702      *
11703      * values(other);
11704      * // => [3, 4]
11705      *
11706      * object.a = 2;
11707      * values(object);
11708      * // => [1, 2]
11709      *
11710      * // Modify the result cache.
11711      * values.cache.set(object, ['a', 'b']);
11712      * values(object);
11713      * // => ['a', 'b']
11714      *
11715      * // Replace `_.memoize.Cache`.
11716      * _.memoize.Cache = WeakMap;
11717      */
11718     function memoize(func, resolver) {
11719       if (typeof func != 'function' || (resolver != null && typeof resolver != 'function')) {
11720         throw new TypeError(FUNC_ERROR_TEXT);
11721       }
11722       var memoized = function() {
11723         var args = arguments,
11724             key = resolver ? resolver.apply(this, args) : args[0],
11725             cache = memoized.cache;
11726
11727         if (cache.has(key)) {
11728           return cache.get(key);
11729         }
11730         var result = func.apply(this, args);
11731         memoized.cache = cache.set(key, result) || cache;
11732         return result;
11733       };
11734       memoized.cache = new (memoize.Cache || MapCache);
11735       return memoized;
11736     }
11737
11738     // Expose `MapCache`.
11739     memoize.Cache = MapCache;
11740
11741     /**
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.
11745      *
11746      * @static
11747      * @memberOf _
11748      * @since 3.0.0
11749      * @category Function
11750      * @param {Function} predicate The predicate to negate.
11751      * @returns {Function} Returns the new negated function.
11752      * @example
11753      *
11754      * function isEven(n) {
11755      *   return n % 2 == 0;
11756      * }
11757      *
11758      * _.filter([1, 2, 3, 4, 5, 6], _.negate(isEven));
11759      * // => [1, 3, 5]
11760      */
11761     function negate(predicate) {
11762       if (typeof predicate != 'function') {
11763         throw new TypeError(FUNC_ERROR_TEXT);
11764       }
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]);
11772         }
11773         return !predicate.apply(this, args);
11774       };
11775     }
11776
11777     /**
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.
11781      *
11782      * @static
11783      * @memberOf _
11784      * @since 0.1.0
11785      * @category Function
11786      * @param {Function} func The function to restrict.
11787      * @returns {Function} Returns the new restricted function.
11788      * @example
11789      *
11790      * var initialize = _.once(createApplication);
11791      * initialize();
11792      * initialize();
11793      * // => `createApplication` is invoked once
11794      */
11795     function once(func) {
11796       return before(2, func);
11797     }
11798
11799     /**
11800      * Creates a function that invokes `func` with its arguments transformed.
11801      *
11802      * @static
11803      * @since 4.0.0
11804      * @memberOf _
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.
11810      * @example
11811      *
11812      * function doubled(n) {
11813      *   return n * 2;
11814      * }
11815      *
11816      * function square(n) {
11817      *   return n * n;
11818      * }
11819      *
11820      * var func = _.overArgs(function(x, y) {
11821      *   return [x, y];
11822      * }, [square, doubled]);
11823      *
11824      * func(9, 3);
11825      * // => [81, 6]
11826      *
11827      * func(10, 5);
11828      * // => [100, 10]
11829      */
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()));
11834
11835       var funcsLength = transforms.length;
11836       return baseRest(function(args) {
11837         var index = -1,
11838             length = nativeMin(args.length, funcsLength);
11839
11840         while (++index < length) {
11841           args[index] = transforms[index].call(this, args[index]);
11842         }
11843         return apply(func, this, args);
11844       });
11845     });
11846
11847     /**
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.
11851      *
11852      * The `_.partial.placeholder` value, which defaults to `_` in monolithic
11853      * builds, may be used as a placeholder for partially applied arguments.
11854      *
11855      * **Note:** This method doesn't set the "length" property of partially
11856      * applied functions.
11857      *
11858      * @static
11859      * @memberOf _
11860      * @since 0.2.0
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.
11865      * @example
11866      *
11867      * function greet(greeting, name) {
11868      *   return greeting + ' ' + name;
11869      * }
11870      *
11871      * var sayHelloTo = _.partial(greet, 'hello');
11872      * sayHelloTo('fred');
11873      * // => 'hello fred'
11874      *
11875      * // Partially applied with placeholders.
11876      * var greetFred = _.partial(greet, _, 'fred');
11877      * greetFred('hi');
11878      * // => 'hi fred'
11879      */
11880     var partial = baseRest(function(func, partials) {
11881       var holders = replaceHolders(partials, getHolder(partial));
11882       return createWrap(func, WRAP_PARTIAL_FLAG, undefined, partials, holders);
11883     });
11884
11885     /**
11886      * This method is like `_.partial` except that partially applied arguments
11887      * are appended to the arguments it receives.
11888      *
11889      * The `_.partialRight.placeholder` value, which defaults to `_` in monolithic
11890      * builds, may be used as a placeholder for partially applied arguments.
11891      *
11892      * **Note:** This method doesn't set the "length" property of partially
11893      * applied functions.
11894      *
11895      * @static
11896      * @memberOf _
11897      * @since 1.0.0
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.
11902      * @example
11903      *
11904      * function greet(greeting, name) {
11905      *   return greeting + ' ' + name;
11906      * }
11907      *
11908      * var greetFred = _.partialRight(greet, 'fred');
11909      * greetFred('hi');
11910      * // => 'hi fred'
11911      *
11912      * // Partially applied with placeholders.
11913      * var sayHelloTo = _.partialRight(greet, 'hello', _);
11914      * sayHelloTo('fred');
11915      * // => 'hello fred'
11916      */
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);
11920     });
11921
11922     /**
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.
11927      *
11928      * @static
11929      * @memberOf _
11930      * @since 3.0.0
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.
11935      * @example
11936      *
11937      * var rearged = _.rearg(function(a, b, c) {
11938      *   return [a, b, c];
11939      * }, [2, 0, 1]);
11940      *
11941      * rearged('b', 'c', 'a')
11942      * // => ['a', 'b', 'c']
11943      */
11944     var rearg = flatRest(function(func, indexes) {
11945       return createWrap(func, WRAP_REARG_FLAG, undefined, undefined, undefined, indexes);
11946     });
11947
11948     /**
11949      * Creates a function that invokes `func` with the `this` binding of the
11950      * created function and arguments from `start` and beyond provided as
11951      * an array.
11952      *
11953      * **Note:** This method is based on the
11954      * [rest parameter](https://mdn.io/rest_parameters).
11955      *
11956      * @static
11957      * @memberOf _
11958      * @since 4.0.0
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.
11963      * @example
11964      *
11965      * var say = _.rest(function(what, names) {
11966      *   return what + ' ' + _.initial(names).join(', ') +
11967      *     (_.size(names) > 1 ? ', & ' : '') + _.last(names);
11968      * });
11969      *
11970      * say('hello', 'fred', 'barney', 'pebbles');
11971      * // => 'hello fred, barney, & pebbles'
11972      */
11973     function rest(func, start) {
11974       if (typeof func != 'function') {
11975         throw new TypeError(FUNC_ERROR_TEXT);
11976       }
11977       start = start === undefined ? start : toInteger(start);
11978       return baseRest(func, start);
11979     }
11980
11981     /**
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).
11985      *
11986      * **Note:** This method is based on the
11987      * [spread operator](https://mdn.io/spread_operator).
11988      *
11989      * @static
11990      * @memberOf _
11991      * @since 3.2.0
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.
11996      * @example
11997      *
11998      * var say = _.spread(function(who, what) {
11999      *   return who + ' says ' + what;
12000      * });
12001      *
12002      * say(['fred', 'hello']);
12003      * // => 'fred says hello'
12004      *
12005      * var numbers = Promise.all([
12006      *   Promise.resolve(40),
12007      *   Promise.resolve(36)
12008      * ]);
12009      *
12010      * numbers.then(_.spread(function(x, y) {
12011      *   return x + y;
12012      * }));
12013      * // => a Promise of 76
12014      */
12015     function spread(func, start) {
12016       if (typeof func != 'function') {
12017         throw new TypeError(FUNC_ERROR_TEXT);
12018       }
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);
12023
12024         if (array) {
12025           arrayPush(otherArgs, array);
12026         }
12027         return apply(func, this, otherArgs);
12028       });
12029     }
12030
12031     /**
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.
12040      *
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.
12044      *
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`.
12047      *
12048      * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/)
12049      * for details over the differences between `_.throttle` and `_.debounce`.
12050      *
12051      * @static
12052      * @memberOf _
12053      * @since 0.1.0
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.
12063      * @example
12064      *
12065      * // Avoid excessively updating the position while scrolling.
12066      * jQuery(window).on('scroll', _.throttle(updatePosition, 100));
12067      *
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);
12071      *
12072      * // Cancel the trailing throttled invocation.
12073      * jQuery(window).on('popstate', throttled.cancel);
12074      */
12075     function throttle(func, wait, options) {
12076       var leading = true,
12077           trailing = true;
12078
12079       if (typeof func != 'function') {
12080         throw new TypeError(FUNC_ERROR_TEXT);
12081       }
12082       if (isObject(options)) {
12083         leading = 'leading' in options ? !!options.leading : leading;
12084         trailing = 'trailing' in options ? !!options.trailing : trailing;
12085       }
12086       return debounce(func, wait, {
12087         'leading': leading,
12088         'maxWait': wait,
12089         'trailing': trailing
12090       });
12091     }
12092
12093     /**
12094      * Creates a function that accepts up to one argument, ignoring any
12095      * additional arguments.
12096      *
12097      * @static
12098      * @memberOf _
12099      * @since 4.0.0
12100      * @category Function
12101      * @param {Function} func The function to cap arguments for.
12102      * @returns {Function} Returns the new capped function.
12103      * @example
12104      *
12105      * _.map(['6', '8', '10'], _.unary(parseInt));
12106      * // => [6, 8, 10]
12107      */
12108     function unary(func) {
12109       return ary(func, 1);
12110     }
12111
12112     /**
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.
12117      *
12118      * @static
12119      * @memberOf _
12120      * @since 0.1.0
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.
12125      * @example
12126      *
12127      * var p = _.wrap(_.escape, function(func, text) {
12128      *   return '<p>' + func(text) + '</p>';
12129      * });
12130      *
12131      * p('fred, barney, & pebbles');
12132      * // => '<p>fred, barney, &amp; pebbles</p>'
12133      */
12134     function wrap(value, wrapper) {
12135       return partial(castFunction(wrapper), value);
12136     }
12137
12138     /*------------------------------------------------------------------------*/
12139
12140     /**
12141      * Casts `value` as an array if it's not one.
12142      *
12143      * @static
12144      * @memberOf _
12145      * @since 4.4.0
12146      * @category Lang
12147      * @param {*} value The value to inspect.
12148      * @returns {Array} Returns the cast array.
12149      * @example
12150      *
12151      * _.castArray(1);
12152      * // => [1]
12153      *
12154      * _.castArray({ 'a': 1 });
12155      * // => [{ 'a': 1 }]
12156      *
12157      * _.castArray('abc');
12158      * // => ['abc']
12159      *
12160      * _.castArray(null);
12161      * // => [null]
12162      *
12163      * _.castArray(undefined);
12164      * // => [undefined]
12165      *
12166      * _.castArray();
12167      * // => []
12168      *
12169      * var array = [1, 2, 3];
12170      * console.log(_.castArray(array) === array);
12171      * // => true
12172      */
12173     function castArray() {
12174       if (!arguments.length) {
12175         return [];
12176       }
12177       var value = arguments[0];
12178       return isArray(value) ? value : [value];
12179     }
12180
12181     /**
12182      * Creates a shallow clone of `value`.
12183      *
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.
12191      *
12192      * @static
12193      * @memberOf _
12194      * @since 0.1.0
12195      * @category Lang
12196      * @param {*} value The value to clone.
12197      * @returns {*} Returns the cloned value.
12198      * @see _.cloneDeep
12199      * @example
12200      *
12201      * var objects = [{ 'a': 1 }, { 'b': 2 }];
12202      *
12203      * var shallow = _.clone(objects);
12204      * console.log(shallow[0] === objects[0]);
12205      * // => true
12206      */
12207     function clone(value) {
12208       return baseClone(value, CLONE_SYMBOLS_FLAG);
12209     }
12210
12211     /**
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]).
12216      *
12217      * @static
12218      * @memberOf _
12219      * @since 4.0.0
12220      * @category Lang
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
12225      * @example
12226      *
12227      * function customizer(value) {
12228      *   if (_.isElement(value)) {
12229      *     return value.cloneNode(false);
12230      *   }
12231      * }
12232      *
12233      * var el = _.cloneWith(document.body, customizer);
12234      *
12235      * console.log(el === document.body);
12236      * // => false
12237      * console.log(el.nodeName);
12238      * // => 'BODY'
12239      * console.log(el.childNodes.length);
12240      * // => 0
12241      */
12242     function cloneWith(value, customizer) {
12243       customizer = typeof customizer == 'function' ? customizer : undefined;
12244       return baseClone(value, CLONE_SYMBOLS_FLAG, customizer);
12245     }
12246
12247     /**
12248      * This method is like `_.clone` except that it recursively clones `value`.
12249      *
12250      * @static
12251      * @memberOf _
12252      * @since 1.0.0
12253      * @category Lang
12254      * @param {*} value The value to recursively clone.
12255      * @returns {*} Returns the deep cloned value.
12256      * @see _.clone
12257      * @example
12258      *
12259      * var objects = [{ 'a': 1 }, { 'b': 2 }];
12260      *
12261      * var deep = _.cloneDeep(objects);
12262      * console.log(deep[0] === objects[0]);
12263      * // => false
12264      */
12265     function cloneDeep(value) {
12266       return baseClone(value, CLONE_DEEP_FLAG | CLONE_SYMBOLS_FLAG);
12267     }
12268
12269     /**
12270      * This method is like `_.cloneWith` except that it recursively clones `value`.
12271      *
12272      * @static
12273      * @memberOf _
12274      * @since 4.0.0
12275      * @category Lang
12276      * @param {*} value The value to recursively clone.
12277      * @param {Function} [customizer] The function to customize cloning.
12278      * @returns {*} Returns the deep cloned value.
12279      * @see _.cloneWith
12280      * @example
12281      *
12282      * function customizer(value) {
12283      *   if (_.isElement(value)) {
12284      *     return value.cloneNode(true);
12285      *   }
12286      * }
12287      *
12288      * var el = _.cloneDeepWith(document.body, customizer);
12289      *
12290      * console.log(el === document.body);
12291      * // => false
12292      * console.log(el.nodeName);
12293      * // => 'BODY'
12294      * console.log(el.childNodes.length);
12295      * // => 20
12296      */
12297     function cloneDeepWith(value, customizer) {
12298       customizer = typeof customizer == 'function' ? customizer : undefined;
12299       return baseClone(value, CLONE_DEEP_FLAG | CLONE_SYMBOLS_FLAG, customizer);
12300     }
12301
12302     /**
12303      * Checks if `object` conforms to `source` by invoking the predicate
12304      * properties of `source` with the corresponding property values of `object`.
12305      *
12306      * **Note:** This method is equivalent to `_.conforms` when `source` is
12307      * partially applied.
12308      *
12309      * @static
12310      * @memberOf _
12311      * @since 4.14.0
12312      * @category Lang
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`.
12316      * @example
12317      *
12318      * var object = { 'a': 1, 'b': 2 };
12319      *
12320      * _.conformsTo(object, { 'b': function(n) { return n > 1; } });
12321      * // => true
12322      *
12323      * _.conformsTo(object, { 'b': function(n) { return n > 2; } });
12324      * // => false
12325      */
12326     function conformsTo(object, source) {
12327       return source == null || baseConformsTo(object, source, keys(source));
12328     }
12329
12330     /**
12331      * Performs a
12332      * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
12333      * comparison between two values to determine if they are equivalent.
12334      *
12335      * @static
12336      * @memberOf _
12337      * @since 4.0.0
12338      * @category Lang
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`.
12342      * @example
12343      *
12344      * var object = { 'a': 1 };
12345      * var other = { 'a': 1 };
12346      *
12347      * _.eq(object, object);
12348      * // => true
12349      *
12350      * _.eq(object, other);
12351      * // => false
12352      *
12353      * _.eq('a', 'a');
12354      * // => true
12355      *
12356      * _.eq('a', Object('a'));
12357      * // => false
12358      *
12359      * _.eq(NaN, NaN);
12360      * // => true
12361      */
12362     function eq(value, other) {
12363       return value === other || (value !== value && other !== other);
12364     }
12365
12366     /**
12367      * Checks if `value` is greater than `other`.
12368      *
12369      * @static
12370      * @memberOf _
12371      * @since 3.9.0
12372      * @category Lang
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`,
12376      *  else `false`.
12377      * @see _.lt
12378      * @example
12379      *
12380      * _.gt(3, 1);
12381      * // => true
12382      *
12383      * _.gt(3, 3);
12384      * // => false
12385      *
12386      * _.gt(1, 3);
12387      * // => false
12388      */
12389     var gt = createRelationalOperation(baseGt);
12390
12391     /**
12392      * Checks if `value` is greater than or equal to `other`.
12393      *
12394      * @static
12395      * @memberOf _
12396      * @since 3.9.0
12397      * @category Lang
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`.
12402      * @see _.lte
12403      * @example
12404      *
12405      * _.gte(3, 1);
12406      * // => true
12407      *
12408      * _.gte(3, 3);
12409      * // => true
12410      *
12411      * _.gte(1, 3);
12412      * // => false
12413      */
12414     var gte = createRelationalOperation(function(value, other) {
12415       return value >= other;
12416     });
12417
12418     /**
12419      * Checks if `value` is likely an `arguments` object.
12420      *
12421      * @static
12422      * @memberOf _
12423      * @since 0.1.0
12424      * @category Lang
12425      * @param {*} value The value to check.
12426      * @returns {boolean} Returns `true` if `value` is an `arguments` object,
12427      *  else `false`.
12428      * @example
12429      *
12430      * _.isArguments(function() { return arguments; }());
12431      * // => true
12432      *
12433      * _.isArguments([1, 2, 3]);
12434      * // => false
12435      */
12436     var isArguments = baseIsArguments(function() { return arguments; }()) ? baseIsArguments : function(value) {
12437       return isObjectLike(value) && hasOwnProperty.call(value, 'callee') &&
12438         !propertyIsEnumerable.call(value, 'callee');
12439     };
12440
12441     /**
12442      * Checks if `value` is classified as an `Array` object.
12443      *
12444      * @static
12445      * @memberOf _
12446      * @since 0.1.0
12447      * @category Lang
12448      * @param {*} value The value to check.
12449      * @returns {boolean} Returns `true` if `value` is an array, else `false`.
12450      * @example
12451      *
12452      * _.isArray([1, 2, 3]);
12453      * // => true
12454      *
12455      * _.isArray(document.body.children);
12456      * // => false
12457      *
12458      * _.isArray('abc');
12459      * // => false
12460      *
12461      * _.isArray(_.noop);
12462      * // => false
12463      */
12464     var isArray = Array.isArray;
12465
12466     /**
12467      * Checks if `value` is classified as an `ArrayBuffer` object.
12468      *
12469      * @static
12470      * @memberOf _
12471      * @since 4.3.0
12472      * @category Lang
12473      * @param {*} value The value to check.
12474      * @returns {boolean} Returns `true` if `value` is an array buffer, else `false`.
12475      * @example
12476      *
12477      * _.isArrayBuffer(new ArrayBuffer(2));
12478      * // => true
12479      *
12480      * _.isArrayBuffer(new Array(2));
12481      * // => false
12482      */
12483     var isArrayBuffer = nodeIsArrayBuffer ? baseUnary(nodeIsArrayBuffer) : baseIsArrayBuffer;
12484
12485     /**
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`.
12489      *
12490      * @static
12491      * @memberOf _
12492      * @since 4.0.0
12493      * @category Lang
12494      * @param {*} value The value to check.
12495      * @returns {boolean} Returns `true` if `value` is array-like, else `false`.
12496      * @example
12497      *
12498      * _.isArrayLike([1, 2, 3]);
12499      * // => true
12500      *
12501      * _.isArrayLike(document.body.children);
12502      * // => true
12503      *
12504      * _.isArrayLike('abc');
12505      * // => true
12506      *
12507      * _.isArrayLike(_.noop);
12508      * // => false
12509      */
12510     function isArrayLike(value) {
12511       return value != null && isLength(value.length) && !isFunction(value);
12512     }
12513
12514     /**
12515      * This method is like `_.isArrayLike` except that it also checks if `value`
12516      * is an object.
12517      *
12518      * @static
12519      * @memberOf _
12520      * @since 4.0.0
12521      * @category Lang
12522      * @param {*} value The value to check.
12523      * @returns {boolean} Returns `true` if `value` is an array-like object,
12524      *  else `false`.
12525      * @example
12526      *
12527      * _.isArrayLikeObject([1, 2, 3]);
12528      * // => true
12529      *
12530      * _.isArrayLikeObject(document.body.children);
12531      * // => true
12532      *
12533      * _.isArrayLikeObject('abc');
12534      * // => false
12535      *
12536      * _.isArrayLikeObject(_.noop);
12537      * // => false
12538      */
12539     function isArrayLikeObject(value) {
12540       return isObjectLike(value) && isArrayLike(value);
12541     }
12542
12543     /**
12544      * Checks if `value` is classified as a boolean primitive or object.
12545      *
12546      * @static
12547      * @memberOf _
12548      * @since 0.1.0
12549      * @category Lang
12550      * @param {*} value The value to check.
12551      * @returns {boolean} Returns `true` if `value` is a boolean, else `false`.
12552      * @example
12553      *
12554      * _.isBoolean(false);
12555      * // => true
12556      *
12557      * _.isBoolean(null);
12558      * // => false
12559      */
12560     function isBoolean(value) {
12561       return value === true || value === false ||
12562         (isObjectLike(value) && baseGetTag(value) == boolTag);
12563     }
12564
12565     /**
12566      * Checks if `value` is a buffer.
12567      *
12568      * @static
12569      * @memberOf _
12570      * @since 4.3.0
12571      * @category Lang
12572      * @param {*} value The value to check.
12573      * @returns {boolean} Returns `true` if `value` is a buffer, else `false`.
12574      * @example
12575      *
12576      * _.isBuffer(new Buffer(2));
12577      * // => true
12578      *
12579      * _.isBuffer(new Uint8Array(2));
12580      * // => false
12581      */
12582     var isBuffer = nativeIsBuffer || stubFalse;
12583
12584     /**
12585      * Checks if `value` is classified as a `Date` object.
12586      *
12587      * @static
12588      * @memberOf _
12589      * @since 0.1.0
12590      * @category Lang
12591      * @param {*} value The value to check.
12592      * @returns {boolean} Returns `true` if `value` is a date object, else `false`.
12593      * @example
12594      *
12595      * _.isDate(new Date);
12596      * // => true
12597      *
12598      * _.isDate('Mon April 23 2012');
12599      * // => false
12600      */
12601     var isDate = nodeIsDate ? baseUnary(nodeIsDate) : baseIsDate;
12602
12603     /**
12604      * Checks if `value` is likely a DOM element.
12605      *
12606      * @static
12607      * @memberOf _
12608      * @since 0.1.0
12609      * @category Lang
12610      * @param {*} value The value to check.
12611      * @returns {boolean} Returns `true` if `value` is a DOM element, else `false`.
12612      * @example
12613      *
12614      * _.isElement(document.body);
12615      * // => true
12616      *
12617      * _.isElement('<body>');
12618      * // => false
12619      */
12620     function isElement(value) {
12621       return isObjectLike(value) && value.nodeType === 1 && !isPlainObject(value);
12622     }
12623
12624     /**
12625      * Checks if `value` is an empty object, collection, map, or set.
12626      *
12627      * Objects are considered empty if they have no own enumerable string keyed
12628      * properties.
12629      *
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`.
12633      *
12634      * @static
12635      * @memberOf _
12636      * @since 0.1.0
12637      * @category Lang
12638      * @param {*} value The value to check.
12639      * @returns {boolean} Returns `true` if `value` is empty, else `false`.
12640      * @example
12641      *
12642      * _.isEmpty(null);
12643      * // => true
12644      *
12645      * _.isEmpty(true);
12646      * // => true
12647      *
12648      * _.isEmpty(1);
12649      * // => true
12650      *
12651      * _.isEmpty([1, 2, 3]);
12652      * // => false
12653      *
12654      * _.isEmpty({ 'a': 1 });
12655      * // => false
12656      */
12657     function isEmpty(value) {
12658       if (value == null) {
12659         return true;
12660       }
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;
12665       }
12666       var tag = getTag(value);
12667       if (tag == mapTag || tag == setTag) {
12668         return !value.size;
12669       }
12670       if (isPrototype(value)) {
12671         return !baseKeys(value).length;
12672       }
12673       for (var key in value) {
12674         if (hasOwnProperty.call(value, key)) {
12675           return false;
12676         }
12677       }
12678       return true;
12679     }
12680
12681     /**
12682      * Performs a deep comparison between two values to determine if they are
12683      * equivalent.
12684      *
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. `===`.
12690      *
12691      * @static
12692      * @memberOf _
12693      * @since 0.1.0
12694      * @category Lang
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`.
12698      * @example
12699      *
12700      * var object = { 'a': 1 };
12701      * var other = { 'a': 1 };
12702      *
12703      * _.isEqual(object, other);
12704      * // => true
12705      *
12706      * object === other;
12707      * // => false
12708      */
12709     function isEqual(value, other) {
12710       return baseIsEqual(value, other);
12711     }
12712
12713     /**
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]).
12718      *
12719      * @static
12720      * @memberOf _
12721      * @since 4.0.0
12722      * @category Lang
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`.
12727      * @example
12728      *
12729      * function isGreeting(value) {
12730      *   return /^h(?:i|ello)$/.test(value);
12731      * }
12732      *
12733      * function customizer(objValue, othValue) {
12734      *   if (isGreeting(objValue) && isGreeting(othValue)) {
12735      *     return true;
12736      *   }
12737      * }
12738      *
12739      * var array = ['hello', 'goodbye'];
12740      * var other = ['hi', 'goodbye'];
12741      *
12742      * _.isEqualWith(array, other, customizer);
12743      * // => true
12744      */
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;
12749     }
12750
12751     /**
12752      * Checks if `value` is an `Error`, `EvalError`, `RangeError`, `ReferenceError`,
12753      * `SyntaxError`, `TypeError`, or `URIError` object.
12754      *
12755      * @static
12756      * @memberOf _
12757      * @since 3.0.0
12758      * @category Lang
12759      * @param {*} value The value to check.
12760      * @returns {boolean} Returns `true` if `value` is an error object, else `false`.
12761      * @example
12762      *
12763      * _.isError(new Error);
12764      * // => true
12765      *
12766      * _.isError(Error);
12767      * // => false
12768      */
12769     function isError(value) {
12770       if (!isObjectLike(value)) {
12771         return false;
12772       }
12773       var tag = baseGetTag(value);
12774       return tag == errorTag || tag == domExcTag ||
12775         (typeof value.message == 'string' && typeof value.name == 'string' && !isPlainObject(value));
12776     }
12777
12778     /**
12779      * Checks if `value` is a finite primitive number.
12780      *
12781      * **Note:** This method is based on
12782      * [`Number.isFinite`](https://mdn.io/Number/isFinite).
12783      *
12784      * @static
12785      * @memberOf _
12786      * @since 0.1.0
12787      * @category Lang
12788      * @param {*} value The value to check.
12789      * @returns {boolean} Returns `true` if `value` is a finite number, else `false`.
12790      * @example
12791      *
12792      * _.isFinite(3);
12793      * // => true
12794      *
12795      * _.isFinite(Number.MIN_VALUE);
12796      * // => true
12797      *
12798      * _.isFinite(Infinity);
12799      * // => false
12800      *
12801      * _.isFinite('3');
12802      * // => false
12803      */
12804     function isFinite(value) {
12805       return typeof value == 'number' && nativeIsFinite(value);
12806     }
12807
12808     /**
12809      * Checks if `value` is classified as a `Function` object.
12810      *
12811      * @static
12812      * @memberOf _
12813      * @since 0.1.0
12814      * @category Lang
12815      * @param {*} value The value to check.
12816      * @returns {boolean} Returns `true` if `value` is a function, else `false`.
12817      * @example
12818      *
12819      * _.isFunction(_);
12820      * // => true
12821      *
12822      * _.isFunction(/abc/);
12823      * // => false
12824      */
12825     function isFunction(value) {
12826       if (!isObject(value)) {
12827         return false;
12828       }
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;
12833     }
12834
12835     /**
12836      * Checks if `value` is an integer.
12837      *
12838      * **Note:** This method is based on
12839      * [`Number.isInteger`](https://mdn.io/Number/isInteger).
12840      *
12841      * @static
12842      * @memberOf _
12843      * @since 4.0.0
12844      * @category Lang
12845      * @param {*} value The value to check.
12846      * @returns {boolean} Returns `true` if `value` is an integer, else `false`.
12847      * @example
12848      *
12849      * _.isInteger(3);
12850      * // => true
12851      *
12852      * _.isInteger(Number.MIN_VALUE);
12853      * // => false
12854      *
12855      * _.isInteger(Infinity);
12856      * // => false
12857      *
12858      * _.isInteger('3');
12859      * // => false
12860      */
12861     function isInteger(value) {
12862       return typeof value == 'number' && value == toInteger(value);
12863     }
12864
12865     /**
12866      * Checks if `value` is a valid array-like length.
12867      *
12868      * **Note:** This method is loosely based on
12869      * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength).
12870      *
12871      * @static
12872      * @memberOf _
12873      * @since 4.0.0
12874      * @category Lang
12875      * @param {*} value The value to check.
12876      * @returns {boolean} Returns `true` if `value` is a valid length, else `false`.
12877      * @example
12878      *
12879      * _.isLength(3);
12880      * // => true
12881      *
12882      * _.isLength(Number.MIN_VALUE);
12883      * // => false
12884      *
12885      * _.isLength(Infinity);
12886      * // => false
12887      *
12888      * _.isLength('3');
12889      * // => false
12890      */
12891     function isLength(value) {
12892       return typeof value == 'number' &&
12893         value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;
12894     }
12895
12896     /**
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('')`)
12900      *
12901      * @static
12902      * @memberOf _
12903      * @since 0.1.0
12904      * @category Lang
12905      * @param {*} value The value to check.
12906      * @returns {boolean} Returns `true` if `value` is an object, else `false`.
12907      * @example
12908      *
12909      * _.isObject({});
12910      * // => true
12911      *
12912      * _.isObject([1, 2, 3]);
12913      * // => true
12914      *
12915      * _.isObject(_.noop);
12916      * // => true
12917      *
12918      * _.isObject(null);
12919      * // => false
12920      */
12921     function isObject(value) {
12922       var type = typeof value;
12923       return value != null && (type == 'object' || type == 'function');
12924     }
12925
12926     /**
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".
12929      *
12930      * @static
12931      * @memberOf _
12932      * @since 4.0.0
12933      * @category Lang
12934      * @param {*} value The value to check.
12935      * @returns {boolean} Returns `true` if `value` is object-like, else `false`.
12936      * @example
12937      *
12938      * _.isObjectLike({});
12939      * // => true
12940      *
12941      * _.isObjectLike([1, 2, 3]);
12942      * // => true
12943      *
12944      * _.isObjectLike(_.noop);
12945      * // => false
12946      *
12947      * _.isObjectLike(null);
12948      * // => false
12949      */
12950     function isObjectLike(value) {
12951       return value != null && typeof value == 'object';
12952     }
12953
12954     /**
12955      * Checks if `value` is classified as a `Map` object.
12956      *
12957      * @static
12958      * @memberOf _
12959      * @since 4.3.0
12960      * @category Lang
12961      * @param {*} value The value to check.
12962      * @returns {boolean} Returns `true` if `value` is a map, else `false`.
12963      * @example
12964      *
12965      * _.isMap(new Map);
12966      * // => true
12967      *
12968      * _.isMap(new WeakMap);
12969      * // => false
12970      */
12971     var isMap = nodeIsMap ? baseUnary(nodeIsMap) : baseIsMap;
12972
12973     /**
12974      * Performs a partial deep comparison between `object` and `source` to
12975      * determine if `object` contains equivalent property values.
12976      *
12977      * **Note:** This method is equivalent to `_.matches` when `source` is
12978      * partially applied.
12979      *
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.
12983      *
12984      * @static
12985      * @memberOf _
12986      * @since 3.0.0
12987      * @category Lang
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`.
12991      * @example
12992      *
12993      * var object = { 'a': 1, 'b': 2 };
12994      *
12995      * _.isMatch(object, { 'b': 2 });
12996      * // => true
12997      *
12998      * _.isMatch(object, { 'b': 1 });
12999      * // => false
13000      */
13001     function isMatch(object, source) {
13002       return object === source || baseIsMatch(object, source, getMatchData(source));
13003     }
13004
13005     /**
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).
13010      *
13011      * @static
13012      * @memberOf _
13013      * @since 4.0.0
13014      * @category Lang
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`.
13019      * @example
13020      *
13021      * function isGreeting(value) {
13022      *   return /^h(?:i|ello)$/.test(value);
13023      * }
13024      *
13025      * function customizer(objValue, srcValue) {
13026      *   if (isGreeting(objValue) && isGreeting(srcValue)) {
13027      *     return true;
13028      *   }
13029      * }
13030      *
13031      * var object = { 'greeting': 'hello' };
13032      * var source = { 'greeting': 'hi' };
13033      *
13034      * _.isMatchWith(object, source, customizer);
13035      * // => true
13036      */
13037     function isMatchWith(object, source, customizer) {
13038       customizer = typeof customizer == 'function' ? customizer : undefined;
13039       return baseIsMatch(object, source, getMatchData(source), customizer);
13040     }
13041
13042     /**
13043      * Checks if `value` is `NaN`.
13044      *
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.
13049      *
13050      * @static
13051      * @memberOf _
13052      * @since 0.1.0
13053      * @category Lang
13054      * @param {*} value The value to check.
13055      * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`.
13056      * @example
13057      *
13058      * _.isNaN(NaN);
13059      * // => true
13060      *
13061      * _.isNaN(new Number(NaN));
13062      * // => true
13063      *
13064      * isNaN(undefined);
13065      * // => true
13066      *
13067      * _.isNaN(undefined);
13068      * // => false
13069      */
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;
13075     }
13076
13077     /**
13078      * Checks if `value` is a pristine native function.
13079      *
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.
13087      *
13088      * @static
13089      * @memberOf _
13090      * @since 3.0.0
13091      * @category Lang
13092      * @param {*} value The value to check.
13093      * @returns {boolean} Returns `true` if `value` is a native function,
13094      *  else `false`.
13095      * @example
13096      *
13097      * _.isNative(Array.prototype.push);
13098      * // => true
13099      *
13100      * _.isNative(_);
13101      * // => false
13102      */
13103     function isNative(value) {
13104       if (isMaskable(value)) {
13105         throw new Error(CORE_ERROR_TEXT);
13106       }
13107       return baseIsNative(value);
13108     }
13109
13110     /**
13111      * Checks if `value` is `null`.
13112      *
13113      * @static
13114      * @memberOf _
13115      * @since 0.1.0
13116      * @category Lang
13117      * @param {*} value The value to check.
13118      * @returns {boolean} Returns `true` if `value` is `null`, else `false`.
13119      * @example
13120      *
13121      * _.isNull(null);
13122      * // => true
13123      *
13124      * _.isNull(void 0);
13125      * // => false
13126      */
13127     function isNull(value) {
13128       return value === null;
13129     }
13130
13131     /**
13132      * Checks if `value` is `null` or `undefined`.
13133      *
13134      * @static
13135      * @memberOf _
13136      * @since 4.0.0
13137      * @category Lang
13138      * @param {*} value The value to check.
13139      * @returns {boolean} Returns `true` if `value` is nullish, else `false`.
13140      * @example
13141      *
13142      * _.isNil(null);
13143      * // => true
13144      *
13145      * _.isNil(void 0);
13146      * // => true
13147      *
13148      * _.isNil(NaN);
13149      * // => false
13150      */
13151     function isNil(value) {
13152       return value == null;
13153     }
13154
13155     /**
13156      * Checks if `value` is classified as a `Number` primitive or object.
13157      *
13158      * **Note:** To exclude `Infinity`, `-Infinity`, and `NaN`, which are
13159      * classified as numbers, use the `_.isFinite` method.
13160      *
13161      * @static
13162      * @memberOf _
13163      * @since 0.1.0
13164      * @category Lang
13165      * @param {*} value The value to check.
13166      * @returns {boolean} Returns `true` if `value` is a number, else `false`.
13167      * @example
13168      *
13169      * _.isNumber(3);
13170      * // => true
13171      *
13172      * _.isNumber(Number.MIN_VALUE);
13173      * // => true
13174      *
13175      * _.isNumber(Infinity);
13176      * // => true
13177      *
13178      * _.isNumber('3');
13179      * // => false
13180      */
13181     function isNumber(value) {
13182       return typeof value == 'number' ||
13183         (isObjectLike(value) && baseGetTag(value) == numberTag);
13184     }
13185
13186     /**
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`.
13189      *
13190      * @static
13191      * @memberOf _
13192      * @since 0.8.0
13193      * @category Lang
13194      * @param {*} value The value to check.
13195      * @returns {boolean} Returns `true` if `value` is a plain object, else `false`.
13196      * @example
13197      *
13198      * function Foo() {
13199      *   this.a = 1;
13200      * }
13201      *
13202      * _.isPlainObject(new Foo);
13203      * // => false
13204      *
13205      * _.isPlainObject([1, 2, 3]);
13206      * // => false
13207      *
13208      * _.isPlainObject({ 'x': 0, 'y': 0 });
13209      * // => true
13210      *
13211      * _.isPlainObject(Object.create(null));
13212      * // => true
13213      */
13214     function isPlainObject(value) {
13215       if (!isObjectLike(value) || baseGetTag(value) != objectTag) {
13216         return false;
13217       }
13218       var proto = getPrototype(value);
13219       if (proto === null) {
13220         return true;
13221       }
13222       var Ctor = hasOwnProperty.call(proto, 'constructor') && proto.constructor;
13223       return typeof Ctor == 'function' && Ctor instanceof Ctor &&
13224         funcToString.call(Ctor) == objectCtorString;
13225     }
13226
13227     /**
13228      * Checks if `value` is classified as a `RegExp` object.
13229      *
13230      * @static
13231      * @memberOf _
13232      * @since 0.1.0
13233      * @category Lang
13234      * @param {*} value The value to check.
13235      * @returns {boolean} Returns `true` if `value` is a regexp, else `false`.
13236      * @example
13237      *
13238      * _.isRegExp(/abc/);
13239      * // => true
13240      *
13241      * _.isRegExp('/abc/');
13242      * // => false
13243      */
13244     var isRegExp = nodeIsRegExp ? baseUnary(nodeIsRegExp) : baseIsRegExp;
13245
13246     /**
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.
13249      *
13250      * **Note:** This method is based on
13251      * [`Number.isSafeInteger`](https://mdn.io/Number/isSafeInteger).
13252      *
13253      * @static
13254      * @memberOf _
13255      * @since 4.0.0
13256      * @category Lang
13257      * @param {*} value The value to check.
13258      * @returns {boolean} Returns `true` if `value` is a safe integer, else `false`.
13259      * @example
13260      *
13261      * _.isSafeInteger(3);
13262      * // => true
13263      *
13264      * _.isSafeInteger(Number.MIN_VALUE);
13265      * // => false
13266      *
13267      * _.isSafeInteger(Infinity);
13268      * // => false
13269      *
13270      * _.isSafeInteger('3');
13271      * // => false
13272      */
13273     function isSafeInteger(value) {
13274       return isInteger(value) && value >= -MAX_SAFE_INTEGER && value <= MAX_SAFE_INTEGER;
13275     }
13276
13277     /**
13278      * Checks if `value` is classified as a `Set` object.
13279      *
13280      * @static
13281      * @memberOf _
13282      * @since 4.3.0
13283      * @category Lang
13284      * @param {*} value The value to check.
13285      * @returns {boolean} Returns `true` if `value` is a set, else `false`.
13286      * @example
13287      *
13288      * _.isSet(new Set);
13289      * // => true
13290      *
13291      * _.isSet(new WeakSet);
13292      * // => false
13293      */
13294     var isSet = nodeIsSet ? baseUnary(nodeIsSet) : baseIsSet;
13295
13296     /**
13297      * Checks if `value` is classified as a `String` primitive or object.
13298      *
13299      * @static
13300      * @since 0.1.0
13301      * @memberOf _
13302      * @category Lang
13303      * @param {*} value The value to check.
13304      * @returns {boolean} Returns `true` if `value` is a string, else `false`.
13305      * @example
13306      *
13307      * _.isString('abc');
13308      * // => true
13309      *
13310      * _.isString(1);
13311      * // => false
13312      */
13313     function isString(value) {
13314       return typeof value == 'string' ||
13315         (!isArray(value) && isObjectLike(value) && baseGetTag(value) == stringTag);
13316     }
13317
13318     /**
13319      * Checks if `value` is classified as a `Symbol` primitive or object.
13320      *
13321      * @static
13322      * @memberOf _
13323      * @since 4.0.0
13324      * @category Lang
13325      * @param {*} value The value to check.
13326      * @returns {boolean} Returns `true` if `value` is a symbol, else `false`.
13327      * @example
13328      *
13329      * _.isSymbol(Symbol.iterator);
13330      * // => true
13331      *
13332      * _.isSymbol('abc');
13333      * // => false
13334      */
13335     function isSymbol(value) {
13336       return typeof value == 'symbol' ||
13337         (isObjectLike(value) && baseGetTag(value) == symbolTag);
13338     }
13339
13340     /**
13341      * Checks if `value` is classified as a typed array.
13342      *
13343      * @static
13344      * @memberOf _
13345      * @since 3.0.0
13346      * @category Lang
13347      * @param {*} value The value to check.
13348      * @returns {boolean} Returns `true` if `value` is a typed array, else `false`.
13349      * @example
13350      *
13351      * _.isTypedArray(new Uint8Array);
13352      * // => true
13353      *
13354      * _.isTypedArray([]);
13355      * // => false
13356      */
13357     var isTypedArray = nodeIsTypedArray ? baseUnary(nodeIsTypedArray) : baseIsTypedArray;
13358
13359     /**
13360      * Checks if `value` is `undefined`.
13361      *
13362      * @static
13363      * @since 0.1.0
13364      * @memberOf _
13365      * @category Lang
13366      * @param {*} value The value to check.
13367      * @returns {boolean} Returns `true` if `value` is `undefined`, else `false`.
13368      * @example
13369      *
13370      * _.isUndefined(void 0);
13371      * // => true
13372      *
13373      * _.isUndefined(null);
13374      * // => false
13375      */
13376     function isUndefined(value) {
13377       return value === undefined;
13378     }
13379
13380     /**
13381      * Checks if `value` is classified as a `WeakMap` object.
13382      *
13383      * @static
13384      * @memberOf _
13385      * @since 4.3.0
13386      * @category Lang
13387      * @param {*} value The value to check.
13388      * @returns {boolean} Returns `true` if `value` is a weak map, else `false`.
13389      * @example
13390      *
13391      * _.isWeakMap(new WeakMap);
13392      * // => true
13393      *
13394      * _.isWeakMap(new Map);
13395      * // => false
13396      */
13397     function isWeakMap(value) {
13398       return isObjectLike(value) && getTag(value) == weakMapTag;
13399     }
13400
13401     /**
13402      * Checks if `value` is classified as a `WeakSet` object.
13403      *
13404      * @static
13405      * @memberOf _
13406      * @since 4.3.0
13407      * @category Lang
13408      * @param {*} value The value to check.
13409      * @returns {boolean} Returns `true` if `value` is a weak set, else `false`.
13410      * @example
13411      *
13412      * _.isWeakSet(new WeakSet);
13413      * // => true
13414      *
13415      * _.isWeakSet(new Set);
13416      * // => false
13417      */
13418     function isWeakSet(value) {
13419       return isObjectLike(value) && baseGetTag(value) == weakSetTag;
13420     }
13421
13422     /**
13423      * Checks if `value` is less than `other`.
13424      *
13425      * @static
13426      * @memberOf _
13427      * @since 3.9.0
13428      * @category Lang
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`,
13432      *  else `false`.
13433      * @see _.gt
13434      * @example
13435      *
13436      * _.lt(1, 3);
13437      * // => true
13438      *
13439      * _.lt(3, 3);
13440      * // => false
13441      *
13442      * _.lt(3, 1);
13443      * // => false
13444      */
13445     var lt = createRelationalOperation(baseLt);
13446
13447     /**
13448      * Checks if `value` is less than or equal to `other`.
13449      *
13450      * @static
13451      * @memberOf _
13452      * @since 3.9.0
13453      * @category Lang
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`.
13458      * @see _.gte
13459      * @example
13460      *
13461      * _.lte(1, 3);
13462      * // => true
13463      *
13464      * _.lte(3, 3);
13465      * // => true
13466      *
13467      * _.lte(3, 1);
13468      * // => false
13469      */
13470     var lte = createRelationalOperation(function(value, other) {
13471       return value <= other;
13472     });
13473
13474     /**
13475      * Converts `value` to an array.
13476      *
13477      * @static
13478      * @since 0.1.0
13479      * @memberOf _
13480      * @category Lang
13481      * @param {*} value The value to convert.
13482      * @returns {Array} Returns the converted array.
13483      * @example
13484      *
13485      * _.toArray({ 'a': 1, 'b': 2 });
13486      * // => [1, 2]
13487      *
13488      * _.toArray('abc');
13489      * // => ['a', 'b', 'c']
13490      *
13491      * _.toArray(1);
13492      * // => []
13493      *
13494      * _.toArray(null);
13495      * // => []
13496      */
13497     function toArray(value) {
13498       if (!value) {
13499         return [];
13500       }
13501       if (isArrayLike(value)) {
13502         return isString(value) ? stringToArray(value) : copyArray(value);
13503       }
13504       if (symIterator && value[symIterator]) {
13505         return iteratorToArray(value[symIterator]());
13506       }
13507       var tag = getTag(value),
13508           func = tag == mapTag ? mapToArray : (tag == setTag ? setToArray : values);
13509
13510       return func(value);
13511     }
13512
13513     /**
13514      * Converts `value` to a finite number.
13515      *
13516      * @static
13517      * @memberOf _
13518      * @since 4.12.0
13519      * @category Lang
13520      * @param {*} value The value to convert.
13521      * @returns {number} Returns the converted number.
13522      * @example
13523      *
13524      * _.toFinite(3.2);
13525      * // => 3.2
13526      *
13527      * _.toFinite(Number.MIN_VALUE);
13528      * // => 5e-324
13529      *
13530      * _.toFinite(Infinity);
13531      * // => 1.7976931348623157e+308
13532      *
13533      * _.toFinite('3.2');
13534      * // => 3.2
13535      */
13536     function toFinite(value) {
13537       if (!value) {
13538         return value === 0 ? value : 0;
13539       }
13540       value = toNumber(value);
13541       if (value === INFINITY || value === -INFINITY) {
13542         var sign = (value < 0 ? -1 : 1);
13543         return sign * MAX_INTEGER;
13544       }
13545       return value === value ? value : 0;
13546     }
13547
13548     /**
13549      * Converts `value` to an integer.
13550      *
13551      * **Note:** This method is loosely based on
13552      * [`ToInteger`](http://www.ecma-international.org/ecma-262/7.0/#sec-tointeger).
13553      *
13554      * @static
13555      * @memberOf _
13556      * @since 4.0.0
13557      * @category Lang
13558      * @param {*} value The value to convert.
13559      * @returns {number} Returns the converted integer.
13560      * @example
13561      *
13562      * _.toInteger(3.2);
13563      * // => 3
13564      *
13565      * _.toInteger(Number.MIN_VALUE);
13566      * // => 0
13567      *
13568      * _.toInteger(Infinity);
13569      * // => 1.7976931348623157e+308
13570      *
13571      * _.toInteger('3.2');
13572      * // => 3
13573      */
13574     function toInteger(value) {
13575       var result = toFinite(value),
13576           remainder = result % 1;
13577
13578       return result === result ? (remainder ? result - remainder : result) : 0;
13579     }
13580
13581     /**
13582      * Converts `value` to an integer suitable for use as the length of an
13583      * array-like object.
13584      *
13585      * **Note:** This method is based on
13586      * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength).
13587      *
13588      * @static
13589      * @memberOf _
13590      * @since 4.0.0
13591      * @category Lang
13592      * @param {*} value The value to convert.
13593      * @returns {number} Returns the converted integer.
13594      * @example
13595      *
13596      * _.toLength(3.2);
13597      * // => 3
13598      *
13599      * _.toLength(Number.MIN_VALUE);
13600      * // => 0
13601      *
13602      * _.toLength(Infinity);
13603      * // => 4294967295
13604      *
13605      * _.toLength('3.2');
13606      * // => 3
13607      */
13608     function toLength(value) {
13609       return value ? baseClamp(toInteger(value), 0, MAX_ARRAY_LENGTH) : 0;
13610     }
13611
13612     /**
13613      * Converts `value` to a number.
13614      *
13615      * @static
13616      * @memberOf _
13617      * @since 4.0.0
13618      * @category Lang
13619      * @param {*} value The value to process.
13620      * @returns {number} Returns the number.
13621      * @example
13622      *
13623      * _.toNumber(3.2);
13624      * // => 3.2
13625      *
13626      * _.toNumber(Number.MIN_VALUE);
13627      * // => 5e-324
13628      *
13629      * _.toNumber(Infinity);
13630      * // => Infinity
13631      *
13632      * _.toNumber('3.2');
13633      * // => 3.2
13634      */
13635     function toNumber(value) {
13636       if (typeof value == 'number') {
13637         return value;
13638       }
13639       if (isSymbol(value)) {
13640         return NAN;
13641       }
13642       if (isObject(value)) {
13643         var other = typeof value.valueOf == 'function' ? value.valueOf() : value;
13644         value = isObject(other) ? (other + '') : other;
13645       }
13646       if (typeof value != 'string') {
13647         return value === 0 ? value : +value;
13648       }
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);
13654     }
13655
13656     /**
13657      * Converts `value` to a plain object flattening inherited enumerable string
13658      * keyed properties of `value` to own properties of the plain object.
13659      *
13660      * @static
13661      * @memberOf _
13662      * @since 3.0.0
13663      * @category Lang
13664      * @param {*} value The value to convert.
13665      * @returns {Object} Returns the converted plain object.
13666      * @example
13667      *
13668      * function Foo() {
13669      *   this.b = 2;
13670      * }
13671      *
13672      * Foo.prototype.c = 3;
13673      *
13674      * _.assign({ 'a': 1 }, new Foo);
13675      * // => { 'a': 1, 'b': 2 }
13676      *
13677      * _.assign({ 'a': 1 }, _.toPlainObject(new Foo));
13678      * // => { 'a': 1, 'b': 2, 'c': 3 }
13679      */
13680     function toPlainObject(value) {
13681       return copyObject(value, keysIn(value));
13682     }
13683
13684     /**
13685      * Converts `value` to a safe integer. A safe integer can be compared and
13686      * represented correctly.
13687      *
13688      * @static
13689      * @memberOf _
13690      * @since 4.0.0
13691      * @category Lang
13692      * @param {*} value The value to convert.
13693      * @returns {number} Returns the converted integer.
13694      * @example
13695      *
13696      * _.toSafeInteger(3.2);
13697      * // => 3
13698      *
13699      * _.toSafeInteger(Number.MIN_VALUE);
13700      * // => 0
13701      *
13702      * _.toSafeInteger(Infinity);
13703      * // => 9007199254740991
13704      *
13705      * _.toSafeInteger('3.2');
13706      * // => 3
13707      */
13708     function toSafeInteger(value) {
13709       return value
13710         ? baseClamp(toInteger(value), -MAX_SAFE_INTEGER, MAX_SAFE_INTEGER)
13711         : (value === 0 ? value : 0);
13712     }
13713
13714     /**
13715      * Converts `value` to a string. An empty string is returned for `null`
13716      * and `undefined` values. The sign of `-0` is preserved.
13717      *
13718      * @static
13719      * @memberOf _
13720      * @since 4.0.0
13721      * @category Lang
13722      * @param {*} value The value to convert.
13723      * @returns {string} Returns the converted string.
13724      * @example
13725      *
13726      * _.toString(null);
13727      * // => ''
13728      *
13729      * _.toString(-0);
13730      * // => '-0'
13731      *
13732      * _.toString([1, 2, 3]);
13733      * // => '1,2,3'
13734      */
13735     function toString(value) {
13736       return value == null ? '' : baseToString(value);
13737     }
13738
13739     /*------------------------------------------------------------------------*/
13740
13741     /**
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.
13745      *
13746      * **Note:** This method mutates `object` and is loosely based on
13747      * [`Object.assign`](https://mdn.io/Object/assign).
13748      *
13749      * @static
13750      * @memberOf _
13751      * @since 0.10.0
13752      * @category Object
13753      * @param {Object} object The destination object.
13754      * @param {...Object} [sources] The source objects.
13755      * @returns {Object} Returns `object`.
13756      * @see _.assignIn
13757      * @example
13758      *
13759      * function Foo() {
13760      *   this.a = 1;
13761      * }
13762      *
13763      * function Bar() {
13764      *   this.c = 3;
13765      * }
13766      *
13767      * Foo.prototype.b = 2;
13768      * Bar.prototype.d = 4;
13769      *
13770      * _.assign({ 'a': 0 }, new Foo, new Bar);
13771      * // => { 'a': 1, 'c': 3 }
13772      */
13773     var assign = createAssigner(function(object, source) {
13774       if (isPrototype(source) || isArrayLike(source)) {
13775         copyObject(source, keys(source), object);
13776         return;
13777       }
13778       for (var key in source) {
13779         if (hasOwnProperty.call(source, key)) {
13780           assignValue(object, key, source[key]);
13781         }
13782       }
13783     });
13784
13785     /**
13786      * This method is like `_.assign` except that it iterates over own and
13787      * inherited source properties.
13788      *
13789      * **Note:** This method mutates `object`.
13790      *
13791      * @static
13792      * @memberOf _
13793      * @since 4.0.0
13794      * @alias extend
13795      * @category Object
13796      * @param {Object} object The destination object.
13797      * @param {...Object} [sources] The source objects.
13798      * @returns {Object} Returns `object`.
13799      * @see _.assign
13800      * @example
13801      *
13802      * function Foo() {
13803      *   this.a = 1;
13804      * }
13805      *
13806      * function Bar() {
13807      *   this.c = 3;
13808      * }
13809      *
13810      * Foo.prototype.b = 2;
13811      * Bar.prototype.d = 4;
13812      *
13813      * _.assignIn({ 'a': 0 }, new Foo, new Bar);
13814      * // => { 'a': 1, 'b': 2, 'c': 3, 'd': 4 }
13815      */
13816     var assignIn = createAssigner(function(object, source) {
13817       copyObject(source, keysIn(source), object);
13818     });
13819
13820     /**
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).
13825      *
13826      * **Note:** This method mutates `object`.
13827      *
13828      * @static
13829      * @memberOf _
13830      * @since 4.0.0
13831      * @alias extendWith
13832      * @category Object
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
13838      * @example
13839      *
13840      * function customizer(objValue, srcValue) {
13841      *   return _.isUndefined(objValue) ? srcValue : objValue;
13842      * }
13843      *
13844      * var defaults = _.partialRight(_.assignInWith, customizer);
13845      *
13846      * defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 });
13847      * // => { 'a': 1, 'b': 2 }
13848      */
13849     var assignInWith = createAssigner(function(object, source, srcIndex, customizer) {
13850       copyObject(source, keysIn(source), object, customizer);
13851     });
13852
13853     /**
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).
13858      *
13859      * **Note:** This method mutates `object`.
13860      *
13861      * @static
13862      * @memberOf _
13863      * @since 4.0.0
13864      * @category 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
13870      * @example
13871      *
13872      * function customizer(objValue, srcValue) {
13873      *   return _.isUndefined(objValue) ? srcValue : objValue;
13874      * }
13875      *
13876      * var defaults = _.partialRight(_.assignWith, customizer);
13877      *
13878      * defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 });
13879      * // => { 'a': 1, 'b': 2 }
13880      */
13881     var assignWith = createAssigner(function(object, source, srcIndex, customizer) {
13882       copyObject(source, keys(source), object, customizer);
13883     });
13884
13885     /**
13886      * Creates an array of values corresponding to `paths` of `object`.
13887      *
13888      * @static
13889      * @memberOf _
13890      * @since 1.0.0
13891      * @category 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.
13895      * @example
13896      *
13897      * var object = { 'a': [{ 'b': { 'c': 3 } }, 4] };
13898      *
13899      * _.at(object, ['a[0].b.c', 'a[1]']);
13900      * // => [3, 4]
13901      */
13902     var at = flatRest(baseAt);
13903
13904     /**
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.
13908      *
13909      * @static
13910      * @memberOf _
13911      * @since 2.3.0
13912      * @category 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.
13916      * @example
13917      *
13918      * function Shape() {
13919      *   this.x = 0;
13920      *   this.y = 0;
13921      * }
13922      *
13923      * function Circle() {
13924      *   Shape.call(this);
13925      * }
13926      *
13927      * Circle.prototype = _.create(Shape.prototype, {
13928      *   'constructor': Circle
13929      * });
13930      *
13931      * var circle = new Circle;
13932      * circle instanceof Circle;
13933      * // => true
13934      *
13935      * circle instanceof Shape;
13936      * // => true
13937      */
13938     function create(prototype, properties) {
13939       var result = baseCreate(prototype);
13940       return properties == null ? result : baseAssign(result, properties);
13941     }
13942
13943     /**
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.
13948      *
13949      * **Note:** This method mutates `object`.
13950      *
13951      * @static
13952      * @since 0.1.0
13953      * @memberOf _
13954      * @category Object
13955      * @param {Object} object The destination object.
13956      * @param {...Object} [sources] The source objects.
13957      * @returns {Object} Returns `object`.
13958      * @see _.defaultsDeep
13959      * @example
13960      *
13961      * _.defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 });
13962      * // => { 'a': 1, 'b': 2 }
13963      */
13964     var defaults = baseRest(function(object, sources) {
13965       object = Object(object);
13966
13967       var index = -1;
13968       var length = sources.length;
13969       var guard = length > 2 ? sources[2] : undefined;
13970
13971       if (guard && isIterateeCall(sources[0], sources[1], guard)) {
13972         length = 1;
13973       }
13974
13975       while (++index < length) {
13976         var source = sources[index];
13977         var props = keysIn(source);
13978         var propsIndex = -1;
13979         var propsLength = props.length;
13980
13981         while (++propsIndex < propsLength) {
13982           var key = props[propsIndex];
13983           var value = object[key];
13984
13985           if (value === undefined ||
13986               (eq(value, objectProto[key]) && !hasOwnProperty.call(object, key))) {
13987             object[key] = source[key];
13988           }
13989         }
13990       }
13991
13992       return object;
13993     });
13994
13995     /**
13996      * This method is like `_.defaults` except that it recursively assigns
13997      * default properties.
13998      *
13999      * **Note:** This method mutates `object`.
14000      *
14001      * @static
14002      * @memberOf _
14003      * @since 3.10.0
14004      * @category Object
14005      * @param {Object} object The destination object.
14006      * @param {...Object} [sources] The source objects.
14007      * @returns {Object} Returns `object`.
14008      * @see _.defaults
14009      * @example
14010      *
14011      * _.defaultsDeep({ 'a': { 'b': 2 } }, { 'a': { 'b': 1, 'c': 3 } });
14012      * // => { 'a': { 'b': 2, 'c': 3 } }
14013      */
14014     var defaultsDeep = baseRest(function(args) {
14015       args.push(undefined, customDefaultsMerge);
14016       return apply(mergeWith, undefined, args);
14017     });
14018
14019     /**
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.
14022      *
14023      * @static
14024      * @memberOf _
14025      * @since 1.1.0
14026      * @category Object
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`.
14031      * @example
14032      *
14033      * var users = {
14034      *   'barney':  { 'age': 36, 'active': true },
14035      *   'fred':    { 'age': 40, 'active': false },
14036      *   'pebbles': { 'age': 1,  'active': true }
14037      * };
14038      *
14039      * _.findKey(users, function(o) { return o.age < 40; });
14040      * // => 'barney' (iteration order is not guaranteed)
14041      *
14042      * // The `_.matches` iteratee shorthand.
14043      * _.findKey(users, { 'age': 1, 'active': true });
14044      * // => 'pebbles'
14045      *
14046      * // The `_.matchesProperty` iteratee shorthand.
14047      * _.findKey(users, ['active', false]);
14048      * // => 'fred'
14049      *
14050      * // The `_.property` iteratee shorthand.
14051      * _.findKey(users, 'active');
14052      * // => 'barney'
14053      */
14054     function findKey(object, predicate) {
14055       return baseFindKey(object, getIteratee(predicate, 3), baseForOwn);
14056     }
14057
14058     /**
14059      * This method is like `_.findKey` except that it iterates over elements of
14060      * a collection in the opposite order.
14061      *
14062      * @static
14063      * @memberOf _
14064      * @since 2.0.0
14065      * @category Object
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`.
14070      * @example
14071      *
14072      * var users = {
14073      *   'barney':  { 'age': 36, 'active': true },
14074      *   'fred':    { 'age': 40, 'active': false },
14075      *   'pebbles': { 'age': 1,  'active': true }
14076      * };
14077      *
14078      * _.findLastKey(users, function(o) { return o.age < 40; });
14079      * // => returns 'pebbles' assuming `_.findKey` returns 'barney'
14080      *
14081      * // The `_.matches` iteratee shorthand.
14082      * _.findLastKey(users, { 'age': 36, 'active': true });
14083      * // => 'barney'
14084      *
14085      * // The `_.matchesProperty` iteratee shorthand.
14086      * _.findLastKey(users, ['active', false]);
14087      * // => 'fred'
14088      *
14089      * // The `_.property` iteratee shorthand.
14090      * _.findLastKey(users, 'active');
14091      * // => 'pebbles'
14092      */
14093     function findLastKey(object, predicate) {
14094       return baseFindKey(object, getIteratee(predicate, 3), baseForOwnRight);
14095     }
14096
14097     /**
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`.
14102      *
14103      * @static
14104      * @memberOf _
14105      * @since 0.3.0
14106      * @category Object
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
14111      * @example
14112      *
14113      * function Foo() {
14114      *   this.a = 1;
14115      *   this.b = 2;
14116      * }
14117      *
14118      * Foo.prototype.c = 3;
14119      *
14120      * _.forIn(new Foo, function(value, key) {
14121      *   console.log(key);
14122      * });
14123      * // => Logs 'a', 'b', then 'c' (iteration order is not guaranteed).
14124      */
14125     function forIn(object, iteratee) {
14126       return object == null
14127         ? object
14128         : baseFor(object, getIteratee(iteratee, 3), keysIn);
14129     }
14130
14131     /**
14132      * This method is like `_.forIn` except that it iterates over properties of
14133      * `object` in the opposite order.
14134      *
14135      * @static
14136      * @memberOf _
14137      * @since 2.0.0
14138      * @category Object
14139      * @param {Object} object The object to iterate over.
14140      * @param {Function} [iteratee=_.identity] The function invoked per iteration.
14141      * @returns {Object} Returns `object`.
14142      * @see _.forIn
14143      * @example
14144      *
14145      * function Foo() {
14146      *   this.a = 1;
14147      *   this.b = 2;
14148      * }
14149      *
14150      * Foo.prototype.c = 3;
14151      *
14152      * _.forInRight(new Foo, function(value, key) {
14153      *   console.log(key);
14154      * });
14155      * // => Logs 'c', 'b', then 'a' assuming `_.forIn` logs 'a', 'b', then 'c'.
14156      */
14157     function forInRight(object, iteratee) {
14158       return object == null
14159         ? object
14160         : baseForRight(object, getIteratee(iteratee, 3), keysIn);
14161     }
14162
14163     /**
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`.
14168      *
14169      * @static
14170      * @memberOf _
14171      * @since 0.3.0
14172      * @category Object
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
14177      * @example
14178      *
14179      * function Foo() {
14180      *   this.a = 1;
14181      *   this.b = 2;
14182      * }
14183      *
14184      * Foo.prototype.c = 3;
14185      *
14186      * _.forOwn(new Foo, function(value, key) {
14187      *   console.log(key);
14188      * });
14189      * // => Logs 'a' then 'b' (iteration order is not guaranteed).
14190      */
14191     function forOwn(object, iteratee) {
14192       return object && baseForOwn(object, getIteratee(iteratee, 3));
14193     }
14194
14195     /**
14196      * This method is like `_.forOwn` except that it iterates over properties of
14197      * `object` in the opposite order.
14198      *
14199      * @static
14200      * @memberOf _
14201      * @since 2.0.0
14202      * @category Object
14203      * @param {Object} object The object to iterate over.
14204      * @param {Function} [iteratee=_.identity] The function invoked per iteration.
14205      * @returns {Object} Returns `object`.
14206      * @see _.forOwn
14207      * @example
14208      *
14209      * function Foo() {
14210      *   this.a = 1;
14211      *   this.b = 2;
14212      * }
14213      *
14214      * Foo.prototype.c = 3;
14215      *
14216      * _.forOwnRight(new Foo, function(value, key) {
14217      *   console.log(key);
14218      * });
14219      * // => Logs 'b' then 'a' assuming `_.forOwn` logs 'a' then 'b'.
14220      */
14221     function forOwnRight(object, iteratee) {
14222       return object && baseForOwnRight(object, getIteratee(iteratee, 3));
14223     }
14224
14225     /**
14226      * Creates an array of function property names from own enumerable properties
14227      * of `object`.
14228      *
14229      * @static
14230      * @since 0.1.0
14231      * @memberOf _
14232      * @category Object
14233      * @param {Object} object The object to inspect.
14234      * @returns {Array} Returns the function names.
14235      * @see _.functionsIn
14236      * @example
14237      *
14238      * function Foo() {
14239      *   this.a = _.constant('a');
14240      *   this.b = _.constant('b');
14241      * }
14242      *
14243      * Foo.prototype.c = _.constant('c');
14244      *
14245      * _.functions(new Foo);
14246      * // => ['a', 'b']
14247      */
14248     function functions(object) {
14249       return object == null ? [] : baseFunctions(object, keys(object));
14250     }
14251
14252     /**
14253      * Creates an array of function property names from own and inherited
14254      * enumerable properties of `object`.
14255      *
14256      * @static
14257      * @memberOf _
14258      * @since 4.0.0
14259      * @category Object
14260      * @param {Object} object The object to inspect.
14261      * @returns {Array} Returns the function names.
14262      * @see _.functions
14263      * @example
14264      *
14265      * function Foo() {
14266      *   this.a = _.constant('a');
14267      *   this.b = _.constant('b');
14268      * }
14269      *
14270      * Foo.prototype.c = _.constant('c');
14271      *
14272      * _.functionsIn(new Foo);
14273      * // => ['a', 'b', 'c']
14274      */
14275     function functionsIn(object) {
14276       return object == null ? [] : baseFunctions(object, keysIn(object));
14277     }
14278
14279     /**
14280      * Gets the value at `path` of `object`. If the resolved value is
14281      * `undefined`, the `defaultValue` is returned in its place.
14282      *
14283      * @static
14284      * @memberOf _
14285      * @since 3.7.0
14286      * @category Object
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.
14291      * @example
14292      *
14293      * var object = { 'a': [{ 'b': { 'c': 3 } }] };
14294      *
14295      * _.get(object, 'a[0].b.c');
14296      * // => 3
14297      *
14298      * _.get(object, ['a', '0', 'b', 'c']);
14299      * // => 3
14300      *
14301      * _.get(object, 'a.b.c', 'default');
14302      * // => 'default'
14303      */
14304     function get(object, path, defaultValue) {
14305       var result = object == null ? undefined : baseGet(object, path);
14306       return result === undefined ? defaultValue : result;
14307     }
14308
14309     /**
14310      * Checks if `path` is a direct property of `object`.
14311      *
14312      * @static
14313      * @since 0.1.0
14314      * @memberOf _
14315      * @category 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`.
14319      * @example
14320      *
14321      * var object = { 'a': { 'b': 2 } };
14322      * var other = _.create({ 'a': _.create({ 'b': 2 }) });
14323      *
14324      * _.has(object, 'a');
14325      * // => true
14326      *
14327      * _.has(object, 'a.b');
14328      * // => true
14329      *
14330      * _.has(object, ['a', 'b']);
14331      * // => true
14332      *
14333      * _.has(other, 'a');
14334      * // => false
14335      */
14336     function has(object, path) {
14337       return object != null && hasPath(object, path, baseHas);
14338     }
14339
14340     /**
14341      * Checks if `path` is a direct or inherited property of `object`.
14342      *
14343      * @static
14344      * @memberOf _
14345      * @since 4.0.0
14346      * @category 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`.
14350      * @example
14351      *
14352      * var object = _.create({ 'a': _.create({ 'b': 2 }) });
14353      *
14354      * _.hasIn(object, 'a');
14355      * // => true
14356      *
14357      * _.hasIn(object, 'a.b');
14358      * // => true
14359      *
14360      * _.hasIn(object, ['a', 'b']);
14361      * // => true
14362      *
14363      * _.hasIn(object, 'b');
14364      * // => false
14365      */
14366     function hasIn(object, path) {
14367       return object != null && hasPath(object, path, baseHasIn);
14368     }
14369
14370     /**
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.
14374      *
14375      * @static
14376      * @memberOf _
14377      * @since 0.7.0
14378      * @category Object
14379      * @param {Object} object The object to invert.
14380      * @returns {Object} Returns the new inverted object.
14381      * @example
14382      *
14383      * var object = { 'a': 1, 'b': 2, 'c': 1 };
14384      *
14385      * _.invert(object);
14386      * // => { '1': 'c', '2': 'b' }
14387      */
14388     var invert = createInverter(function(result, value, key) {
14389       if (value != null &&
14390           typeof value.toString != 'function') {
14391         value = nativeObjectToString.call(value);
14392       }
14393
14394       result[value] = key;
14395     }, constant(identity));
14396
14397     /**
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).
14403      *
14404      * @static
14405      * @memberOf _
14406      * @since 4.1.0
14407      * @category Object
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.
14411      * @example
14412      *
14413      * var object = { 'a': 1, 'b': 2, 'c': 1 };
14414      *
14415      * _.invertBy(object);
14416      * // => { '1': ['a', 'c'], '2': ['b'] }
14417      *
14418      * _.invertBy(object, function(value) {
14419      *   return 'group' + value;
14420      * });
14421      * // => { 'group1': ['a', 'c'], 'group2': ['b'] }
14422      */
14423     var invertBy = createInverter(function(result, value, key) {
14424       if (value != null &&
14425           typeof value.toString != 'function') {
14426         value = nativeObjectToString.call(value);
14427       }
14428
14429       if (hasOwnProperty.call(result, value)) {
14430         result[value].push(key);
14431       } else {
14432         result[value] = [key];
14433       }
14434     }, getIteratee);
14435
14436     /**
14437      * Invokes the method at `path` of `object`.
14438      *
14439      * @static
14440      * @memberOf _
14441      * @since 4.0.0
14442      * @category 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.
14447      * @example
14448      *
14449      * var object = { 'a': [{ 'b': { 'c': [1, 2, 3, 4] } }] };
14450      *
14451      * _.invoke(object, 'a[0].b.c.slice', 1, 3);
14452      * // => [2, 3]
14453      */
14454     var invoke = baseRest(baseInvoke);
14455
14456     /**
14457      * Creates an array of the own enumerable property names of `object`.
14458      *
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.
14462      *
14463      * @static
14464      * @since 0.1.0
14465      * @memberOf _
14466      * @category Object
14467      * @param {Object} object The object to query.
14468      * @returns {Array} Returns the array of property names.
14469      * @example
14470      *
14471      * function Foo() {
14472      *   this.a = 1;
14473      *   this.b = 2;
14474      * }
14475      *
14476      * Foo.prototype.c = 3;
14477      *
14478      * _.keys(new Foo);
14479      * // => ['a', 'b'] (iteration order is not guaranteed)
14480      *
14481      * _.keys('hi');
14482      * // => ['0', '1']
14483      */
14484     function keys(object) {
14485       return isArrayLike(object) ? arrayLikeKeys(object) : baseKeys(object);
14486     }
14487
14488     /**
14489      * Creates an array of the own and inherited enumerable property names of `object`.
14490      *
14491      * **Note:** Non-object values are coerced to objects.
14492      *
14493      * @static
14494      * @memberOf _
14495      * @since 3.0.0
14496      * @category Object
14497      * @param {Object} object The object to query.
14498      * @returns {Array} Returns the array of property names.
14499      * @example
14500      *
14501      * function Foo() {
14502      *   this.a = 1;
14503      *   this.b = 2;
14504      * }
14505      *
14506      * Foo.prototype.c = 3;
14507      *
14508      * _.keysIn(new Foo);
14509      * // => ['a', 'b', 'c'] (iteration order is not guaranteed)
14510      */
14511     function keysIn(object) {
14512       return isArrayLike(object) ? arrayLikeKeys(object, true) : baseKeysIn(object);
14513     }
14514
14515     /**
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).
14520      *
14521      * @static
14522      * @memberOf _
14523      * @since 3.8.0
14524      * @category 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.
14528      * @see _.mapValues
14529      * @example
14530      *
14531      * _.mapKeys({ 'a': 1, 'b': 2 }, function(value, key) {
14532      *   return key + value;
14533      * });
14534      * // => { 'a1': 1, 'b2': 2 }
14535      */
14536     function mapKeys(object, iteratee) {
14537       var result = {};
14538       iteratee = getIteratee(iteratee, 3);
14539
14540       baseForOwn(object, function(value, key, object) {
14541         baseAssignValue(result, iteratee(value, key, object), value);
14542       });
14543       return result;
14544     }
14545
14546     /**
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).
14551      *
14552      * @static
14553      * @memberOf _
14554      * @since 2.4.0
14555      * @category 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.
14559      * @see _.mapKeys
14560      * @example
14561      *
14562      * var users = {
14563      *   'fred':    { 'user': 'fred',    'age': 40 },
14564      *   'pebbles': { 'user': 'pebbles', 'age': 1 }
14565      * };
14566      *
14567      * _.mapValues(users, function(o) { return o.age; });
14568      * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed)
14569      *
14570      * // The `_.property` iteratee shorthand.
14571      * _.mapValues(users, 'age');
14572      * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed)
14573      */
14574     function mapValues(object, iteratee) {
14575       var result = {};
14576       iteratee = getIteratee(iteratee, 3);
14577
14578       baseForOwn(object, function(value, key, object) {
14579         baseAssignValue(result, key, iteratee(value, key, object));
14580       });
14581       return result;
14582     }
14583
14584     /**
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.
14592      *
14593      * **Note:** This method mutates `object`.
14594      *
14595      * @static
14596      * @memberOf _
14597      * @since 0.5.0
14598      * @category Object
14599      * @param {Object} object The destination object.
14600      * @param {...Object} [sources] The source objects.
14601      * @returns {Object} Returns `object`.
14602      * @example
14603      *
14604      * var object = {
14605      *   'a': [{ 'b': 2 }, { 'd': 4 }]
14606      * };
14607      *
14608      * var other = {
14609      *   'a': [{ 'c': 3 }, { 'e': 5 }]
14610      * };
14611      *
14612      * _.merge(object, other);
14613      * // => { 'a': [{ 'b': 2, 'c': 3 }, { 'd': 4, 'e': 5 }] }
14614      */
14615     var merge = createAssigner(function(object, source, srcIndex) {
14616       baseMerge(object, source, srcIndex);
14617     });
14618
14619     /**
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).
14625      *
14626      * **Note:** This method mutates `object`.
14627      *
14628      * @static
14629      * @memberOf _
14630      * @since 4.0.0
14631      * @category 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`.
14636      * @example
14637      *
14638      * function customizer(objValue, srcValue) {
14639      *   if (_.isArray(objValue)) {
14640      *     return objValue.concat(srcValue);
14641      *   }
14642      * }
14643      *
14644      * var object = { 'a': [1], 'b': [2] };
14645      * var other = { 'a': [3], 'b': [4] };
14646      *
14647      * _.mergeWith(object, other, customizer);
14648      * // => { 'a': [1, 3], 'b': [2, 4] }
14649      */
14650     var mergeWith = createAssigner(function(object, source, srcIndex, customizer) {
14651       baseMerge(object, source, srcIndex, customizer);
14652     });
14653
14654     /**
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.
14657      *
14658      * **Note:** This method is considerably slower than `_.pick`.
14659      *
14660      * @static
14661      * @since 0.1.0
14662      * @memberOf _
14663      * @category Object
14664      * @param {Object} object The source object.
14665      * @param {...(string|string[])} [paths] The property paths to omit.
14666      * @returns {Object} Returns the new object.
14667      * @example
14668      *
14669      * var object = { 'a': 1, 'b': '2', 'c': 3 };
14670      *
14671      * _.omit(object, ['a', 'c']);
14672      * // => { 'b': '2' }
14673      */
14674     var omit = flatRest(function(object, paths) {
14675       var result = {};
14676       if (object == null) {
14677         return result;
14678       }
14679       var isDeep = false;
14680       paths = arrayMap(paths, function(path) {
14681         path = castPath(path, object);
14682         isDeep || (isDeep = path.length > 1);
14683         return path;
14684       });
14685       copyObject(object, getAllKeysIn(object), result);
14686       if (isDeep) {
14687         result = baseClone(result, CLONE_DEEP_FLAG | CLONE_FLAT_FLAG | CLONE_SYMBOLS_FLAG, customOmitClone);
14688       }
14689       var length = paths.length;
14690       while (length--) {
14691         baseUnset(result, paths[length]);
14692       }
14693       return result;
14694     });
14695
14696     /**
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).
14701      *
14702      * @static
14703      * @memberOf _
14704      * @since 4.0.0
14705      * @category Object
14706      * @param {Object} object The source object.
14707      * @param {Function} [predicate=_.identity] The function invoked per property.
14708      * @returns {Object} Returns the new object.
14709      * @example
14710      *
14711      * var object = { 'a': 1, 'b': '2', 'c': 3 };
14712      *
14713      * _.omitBy(object, _.isNumber);
14714      * // => { 'b': '2' }
14715      */
14716     function omitBy(object, predicate) {
14717       return pickBy(object, negate(getIteratee(predicate)));
14718     }
14719
14720     /**
14721      * Creates an object composed of the picked `object` properties.
14722      *
14723      * @static
14724      * @since 0.1.0
14725      * @memberOf _
14726      * @category Object
14727      * @param {Object} object The source object.
14728      * @param {...(string|string[])} [paths] The property paths to pick.
14729      * @returns {Object} Returns the new object.
14730      * @example
14731      *
14732      * var object = { 'a': 1, 'b': '2', 'c': 3 };
14733      *
14734      * _.pick(object, ['a', 'c']);
14735      * // => { 'a': 1, 'c': 3 }
14736      */
14737     var pick = flatRest(function(object, paths) {
14738       return object == null ? {} : basePick(object, paths);
14739     });
14740
14741     /**
14742      * Creates an object composed of the `object` properties `predicate` returns
14743      * truthy for. The predicate is invoked with two arguments: (value, key).
14744      *
14745      * @static
14746      * @memberOf _
14747      * @since 4.0.0
14748      * @category Object
14749      * @param {Object} object The source object.
14750      * @param {Function} [predicate=_.identity] The function invoked per property.
14751      * @returns {Object} Returns the new object.
14752      * @example
14753      *
14754      * var object = { 'a': 1, 'b': '2', 'c': 3 };
14755      *
14756      * _.pickBy(object, _.isNumber);
14757      * // => { 'a': 1, 'c': 3 }
14758      */
14759     function pickBy(object, predicate) {
14760       if (object == null) {
14761         return {};
14762       }
14763       var props = arrayMap(getAllKeysIn(object), function(prop) {
14764         return [prop];
14765       });
14766       predicate = getIteratee(predicate);
14767       return basePickBy(object, props, function(value, path) {
14768         return predicate(value, path[0]);
14769       });
14770     }
14771
14772     /**
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.
14776      *
14777      * @static
14778      * @since 0.1.0
14779      * @memberOf _
14780      * @category Object
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.
14785      * @example
14786      *
14787      * var object = { 'a': [{ 'b': { 'c1': 3, 'c2': _.constant(4) } }] };
14788      *
14789      * _.result(object, 'a[0].b.c1');
14790      * // => 3
14791      *
14792      * _.result(object, 'a[0].b.c2');
14793      * // => 4
14794      *
14795      * _.result(object, 'a[0].b.c3', 'default');
14796      * // => 'default'
14797      *
14798      * _.result(object, 'a[0].b.c3', _.constant('default'));
14799      * // => 'default'
14800      */
14801     function result(object, path, defaultValue) {
14802       path = castPath(path, object);
14803
14804       var index = -1,
14805           length = path.length;
14806
14807       // Ensure the loop is entered when path is empty.
14808       if (!length) {
14809         length = 1;
14810         object = undefined;
14811       }
14812       while (++index < length) {
14813         var value = object == null ? undefined : object[toKey(path[index])];
14814         if (value === undefined) {
14815           index = length;
14816           value = defaultValue;
14817         }
14818         object = isFunction(value) ? value.call(object) : value;
14819       }
14820       return object;
14821     }
14822
14823     /**
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
14827      * `path` creation.
14828      *
14829      * **Note:** This method mutates `object`.
14830      *
14831      * @static
14832      * @memberOf _
14833      * @since 3.7.0
14834      * @category 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`.
14839      * @example
14840      *
14841      * var object = { 'a': [{ 'b': { 'c': 3 } }] };
14842      *
14843      * _.set(object, 'a[0].b.c', 4);
14844      * console.log(object.a[0].b.c);
14845      * // => 4
14846      *
14847      * _.set(object, ['x', '0', 'y', 'z'], 5);
14848      * console.log(object.x[0].y.z);
14849      * // => 5
14850      */
14851     function set(object, path, value) {
14852       return object == null ? object : baseSet(object, path, value);
14853     }
14854
14855     /**
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).
14860      *
14861      * **Note:** This method mutates `object`.
14862      *
14863      * @static
14864      * @memberOf _
14865      * @since 4.0.0
14866      * @category 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`.
14872      * @example
14873      *
14874      * var object = {};
14875      *
14876      * _.setWith(object, '[0][1]', 'a', Object);
14877      * // => { '0': { '1': 'a' } }
14878      */
14879     function setWith(object, path, value, customizer) {
14880       customizer = typeof customizer == 'function' ? customizer : undefined;
14881       return object == null ? object : baseSet(object, path, value, customizer);
14882     }
14883
14884     /**
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.
14888      *
14889      * @static
14890      * @memberOf _
14891      * @since 4.0.0
14892      * @alias entries
14893      * @category Object
14894      * @param {Object} object The object to query.
14895      * @returns {Array} Returns the key-value pairs.
14896      * @example
14897      *
14898      * function Foo() {
14899      *   this.a = 1;
14900      *   this.b = 2;
14901      * }
14902      *
14903      * Foo.prototype.c = 3;
14904      *
14905      * _.toPairs(new Foo);
14906      * // => [['a', 1], ['b', 2]] (iteration order is not guaranteed)
14907      */
14908     var toPairs = createToPairs(keys);
14909
14910     /**
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.
14914      *
14915      * @static
14916      * @memberOf _
14917      * @since 4.0.0
14918      * @alias entriesIn
14919      * @category Object
14920      * @param {Object} object The object to query.
14921      * @returns {Array} Returns the key-value pairs.
14922      * @example
14923      *
14924      * function Foo() {
14925      *   this.a = 1;
14926      *   this.b = 2;
14927      * }
14928      *
14929      * Foo.prototype.c = 3;
14930      *
14931      * _.toPairsIn(new Foo);
14932      * // => [['a', 1], ['b', 2], ['c', 3]] (iteration order is not guaranteed)
14933      */
14934     var toPairsIn = createToPairs(keysIn);
14935
14936     /**
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`.
14944      *
14945      * @static
14946      * @memberOf _
14947      * @since 1.3.0
14948      * @category Object
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.
14953      * @example
14954      *
14955      * _.transform([2, 3, 4], function(result, n) {
14956      *   result.push(n *= n);
14957      *   return n % 2 == 0;
14958      * }, []);
14959      * // => [4, 9]
14960      *
14961      * _.transform({ 'a': 1, 'b': 2, 'c': 1 }, function(result, value, key) {
14962      *   (result[value] || (result[value] = [])).push(key);
14963      * }, {});
14964      * // => { '1': ['a', 'c'], '2': ['b'] }
14965      */
14966     function transform(object, iteratee, accumulator) {
14967       var isArr = isArray(object),
14968           isArrLike = isArr || isBuffer(object) || isTypedArray(object);
14969
14970       iteratee = getIteratee(iteratee, 4);
14971       if (accumulator == null) {
14972         var Ctor = object && object.constructor;
14973         if (isArrLike) {
14974           accumulator = isArr ? new Ctor : [];
14975         }
14976         else if (isObject(object)) {
14977           accumulator = isFunction(Ctor) ? baseCreate(getPrototype(object)) : {};
14978         }
14979         else {
14980           accumulator = {};
14981         }
14982       }
14983       (isArrLike ? arrayEach : baseForOwn)(object, function(value, index, object) {
14984         return iteratee(accumulator, value, index, object);
14985       });
14986       return accumulator;
14987     }
14988
14989     /**
14990      * Removes the property at `path` of `object`.
14991      *
14992      * **Note:** This method mutates `object`.
14993      *
14994      * @static
14995      * @memberOf _
14996      * @since 4.0.0
14997      * @category 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`.
15001      * @example
15002      *
15003      * var object = { 'a': [{ 'b': { 'c': 7 } }] };
15004      * _.unset(object, 'a[0].b.c');
15005      * // => true
15006      *
15007      * console.log(object);
15008      * // => { 'a': [{ 'b': {} }] };
15009      *
15010      * _.unset(object, ['a', '0', 'b', 'c']);
15011      * // => true
15012      *
15013      * console.log(object);
15014      * // => { 'a': [{ 'b': {} }] };
15015      */
15016     function unset(object, path) {
15017       return object == null ? true : baseUnset(object, path);
15018     }
15019
15020     /**
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).
15024      *
15025      * **Note:** This method mutates `object`.
15026      *
15027      * @static
15028      * @memberOf _
15029      * @since 4.6.0
15030      * @category 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`.
15035      * @example
15036      *
15037      * var object = { 'a': [{ 'b': { 'c': 3 } }] };
15038      *
15039      * _.update(object, 'a[0].b.c', function(n) { return n * n; });
15040      * console.log(object.a[0].b.c);
15041      * // => 9
15042      *
15043      * _.update(object, 'x[0].y.z', function(n) { return n ? n + 1 : 0; });
15044      * console.log(object.x[0].y.z);
15045      * // => 0
15046      */
15047     function update(object, path, updater) {
15048       return object == null ? object : baseUpdate(object, path, castFunction(updater));
15049     }
15050
15051     /**
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).
15056      *
15057      * **Note:** This method mutates `object`.
15058      *
15059      * @static
15060      * @memberOf _
15061      * @since 4.6.0
15062      * @category 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`.
15068      * @example
15069      *
15070      * var object = {};
15071      *
15072      * _.updateWith(object, '[0][1]', _.constant('a'), Object);
15073      * // => { '0': { '1': 'a' } }
15074      */
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);
15078     }
15079
15080     /**
15081      * Creates an array of the own enumerable string keyed property values of `object`.
15082      *
15083      * **Note:** Non-object values are coerced to objects.
15084      *
15085      * @static
15086      * @since 0.1.0
15087      * @memberOf _
15088      * @category Object
15089      * @param {Object} object The object to query.
15090      * @returns {Array} Returns the array of property values.
15091      * @example
15092      *
15093      * function Foo() {
15094      *   this.a = 1;
15095      *   this.b = 2;
15096      * }
15097      *
15098      * Foo.prototype.c = 3;
15099      *
15100      * _.values(new Foo);
15101      * // => [1, 2] (iteration order is not guaranteed)
15102      *
15103      * _.values('hi');
15104      * // => ['h', 'i']
15105      */
15106     function values(object) {
15107       return object == null ? [] : baseValues(object, keys(object));
15108     }
15109
15110     /**
15111      * Creates an array of the own and inherited enumerable string keyed property
15112      * values of `object`.
15113      *
15114      * **Note:** Non-object values are coerced to objects.
15115      *
15116      * @static
15117      * @memberOf _
15118      * @since 3.0.0
15119      * @category Object
15120      * @param {Object} object The object to query.
15121      * @returns {Array} Returns the array of property values.
15122      * @example
15123      *
15124      * function Foo() {
15125      *   this.a = 1;
15126      *   this.b = 2;
15127      * }
15128      *
15129      * Foo.prototype.c = 3;
15130      *
15131      * _.valuesIn(new Foo);
15132      * // => [1, 2, 3] (iteration order is not guaranteed)
15133      */
15134     function valuesIn(object) {
15135       return object == null ? [] : baseValues(object, keysIn(object));
15136     }
15137
15138     /*------------------------------------------------------------------------*/
15139
15140     /**
15141      * Clamps `number` within the inclusive `lower` and `upper` bounds.
15142      *
15143      * @static
15144      * @memberOf _
15145      * @since 4.0.0
15146      * @category Number
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.
15151      * @example
15152      *
15153      * _.clamp(-10, -5, 5);
15154      * // => -5
15155      *
15156      * _.clamp(10, -5, 5);
15157      * // => 5
15158      */
15159     function clamp(number, lower, upper) {
15160       if (upper === undefined) {
15161         upper = lower;
15162         lower = undefined;
15163       }
15164       if (upper !== undefined) {
15165         upper = toNumber(upper);
15166         upper = upper === upper ? upper : 0;
15167       }
15168       if (lower !== undefined) {
15169         lower = toNumber(lower);
15170         lower = lower === lower ? lower : 0;
15171       }
15172       return baseClamp(toNumber(number), lower, upper);
15173     }
15174
15175     /**
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
15179      * negative ranges.
15180      *
15181      * @static
15182      * @memberOf _
15183      * @since 3.3.0
15184      * @category Number
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
15190      * @example
15191      *
15192      * _.inRange(3, 2, 4);
15193      * // => true
15194      *
15195      * _.inRange(4, 8);
15196      * // => true
15197      *
15198      * _.inRange(4, 2);
15199      * // => false
15200      *
15201      * _.inRange(2, 2);
15202      * // => false
15203      *
15204      * _.inRange(1.2, 2);
15205      * // => true
15206      *
15207      * _.inRange(5.2, 4);
15208      * // => false
15209      *
15210      * _.inRange(-3, -2, -6);
15211      * // => true
15212      */
15213     function inRange(number, start, end) {
15214       start = toFinite(start);
15215       if (end === undefined) {
15216         end = start;
15217         start = 0;
15218       } else {
15219         end = toFinite(end);
15220       }
15221       number = toNumber(number);
15222       return baseInRange(number, start, end);
15223     }
15224
15225     /**
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.
15230      *
15231      * **Note:** JavaScript follows the IEEE-754 standard for resolving
15232      * floating-point values which can produce unexpected results.
15233      *
15234      * @static
15235      * @memberOf _
15236      * @since 0.7.0
15237      * @category Number
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.
15242      * @example
15243      *
15244      * _.random(0, 5);
15245      * // => an integer between 0 and 5
15246      *
15247      * _.random(5);
15248      * // => also an integer between 0 and 5
15249      *
15250      * _.random(5, true);
15251      * // => a floating-point number between 0 and 5
15252      *
15253      * _.random(1.2, 5.2);
15254      * // => a floating-point number between 1.2 and 5.2
15255      */
15256     function random(lower, upper, floating) {
15257       if (floating && typeof floating != 'boolean' && isIterateeCall(lower, upper, floating)) {
15258         upper = floating = undefined;
15259       }
15260       if (floating === undefined) {
15261         if (typeof upper == 'boolean') {
15262           floating = upper;
15263           upper = undefined;
15264         }
15265         else if (typeof lower == 'boolean') {
15266           floating = lower;
15267           lower = undefined;
15268         }
15269       }
15270       if (lower === undefined && upper === undefined) {
15271         lower = 0;
15272         upper = 1;
15273       }
15274       else {
15275         lower = toFinite(lower);
15276         if (upper === undefined) {
15277           upper = lower;
15278           lower = 0;
15279         } else {
15280           upper = toFinite(upper);
15281         }
15282       }
15283       if (lower > upper) {
15284         var temp = lower;
15285         lower = upper;
15286         upper = temp;
15287       }
15288       if (floating || lower % 1 || upper % 1) {
15289         var rand = nativeRandom();
15290         return nativeMin(lower + (rand * (upper - lower + freeParseFloat('1e-' + ((rand + '').length - 1)))), upper);
15291       }
15292       return baseRandom(lower, upper);
15293     }
15294
15295     /*------------------------------------------------------------------------*/
15296
15297     /**
15298      * Converts `string` to [camel case](https://en.wikipedia.org/wiki/CamelCase).
15299      *
15300      * @static
15301      * @memberOf _
15302      * @since 3.0.0
15303      * @category String
15304      * @param {string} [string=''] The string to convert.
15305      * @returns {string} Returns the camel cased string.
15306      * @example
15307      *
15308      * _.camelCase('Foo Bar');
15309      * // => 'fooBar'
15310      *
15311      * _.camelCase('--foo-bar--');
15312      * // => 'fooBar'
15313      *
15314      * _.camelCase('__FOO_BAR__');
15315      * // => 'fooBar'
15316      */
15317     var camelCase = createCompounder(function(result, word, index) {
15318       word = word.toLowerCase();
15319       return result + (index ? capitalize(word) : word);
15320     });
15321
15322     /**
15323      * Converts the first character of `string` to upper case and the remaining
15324      * to lower case.
15325      *
15326      * @static
15327      * @memberOf _
15328      * @since 3.0.0
15329      * @category String
15330      * @param {string} [string=''] The string to capitalize.
15331      * @returns {string} Returns the capitalized string.
15332      * @example
15333      *
15334      * _.capitalize('FRED');
15335      * // => 'Fred'
15336      */
15337     function capitalize(string) {
15338       return upperFirst(toString(string).toLowerCase());
15339     }
15340
15341     /**
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).
15347      *
15348      * @static
15349      * @memberOf _
15350      * @since 3.0.0
15351      * @category String
15352      * @param {string} [string=''] The string to deburr.
15353      * @returns {string} Returns the deburred string.
15354      * @example
15355      *
15356      * _.deburr('déjà vu');
15357      * // => 'deja vu'
15358      */
15359     function deburr(string) {
15360       string = toString(string);
15361       return string && string.replace(reLatin, deburrLetter).replace(reComboMark, '');
15362     }
15363
15364     /**
15365      * Checks if `string` ends with the given target string.
15366      *
15367      * @static
15368      * @memberOf _
15369      * @since 3.0.0
15370      * @category 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`,
15375      *  else `false`.
15376      * @example
15377      *
15378      * _.endsWith('abc', 'c');
15379      * // => true
15380      *
15381      * _.endsWith('abc', 'b');
15382      * // => false
15383      *
15384      * _.endsWith('abc', 'b', 2);
15385      * // => true
15386      */
15387     function endsWith(string, target, position) {
15388       string = toString(string);
15389       target = baseToString(target);
15390
15391       var length = string.length;
15392       position = position === undefined
15393         ? length
15394         : baseClamp(toInteger(position), 0, length);
15395
15396       var end = position;
15397       position -= target.length;
15398       return position >= 0 && string.slice(position, end) == target;
15399     }
15400
15401     /**
15402      * Converts the characters "&", "<", ">", '"', and "'" in `string` to their
15403      * corresponding HTML entities.
15404      *
15405      * **Note:** No other characters are escaped. To escape additional
15406      * characters use a third-party library like [_he_](https://mths.be/he).
15407      *
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.
15413      *
15414      * When working with HTML you should always
15415      * [quote attribute values](http://wonko.com/post/html-escaping) to reduce
15416      * XSS vectors.
15417      *
15418      * @static
15419      * @since 0.1.0
15420      * @memberOf _
15421      * @category String
15422      * @param {string} [string=''] The string to escape.
15423      * @returns {string} Returns the escaped string.
15424      * @example
15425      *
15426      * _.escape('fred, barney, & pebbles');
15427      * // => 'fred, barney, &amp; pebbles'
15428      */
15429     function escape(string) {
15430       string = toString(string);
15431       return (string && reHasUnescapedHtml.test(string))
15432         ? string.replace(reUnescapedHtml, escapeHtmlChar)
15433         : string;
15434     }
15435
15436     /**
15437      * Escapes the `RegExp` special characters "^", "$", "\", ".", "*", "+",
15438      * "?", "(", ")", "[", "]", "{", "}", and "|" in `string`.
15439      *
15440      * @static
15441      * @memberOf _
15442      * @since 3.0.0
15443      * @category String
15444      * @param {string} [string=''] The string to escape.
15445      * @returns {string} Returns the escaped string.
15446      * @example
15447      *
15448      * _.escapeRegExp('[lodash](https://lodash.com/)');
15449      * // => '\[lodash\]\(https://lodash\.com/\)'
15450      */
15451     function escapeRegExp(string) {
15452       string = toString(string);
15453       return (string && reHasRegExpChar.test(string))
15454         ? string.replace(reRegExpChar, '\\$&')
15455         : string;
15456     }
15457
15458     /**
15459      * Converts `string` to
15460      * [kebab case](https://en.wikipedia.org/wiki/Letter_case#Special_case_styles).
15461      *
15462      * @static
15463      * @memberOf _
15464      * @since 3.0.0
15465      * @category String
15466      * @param {string} [string=''] The string to convert.
15467      * @returns {string} Returns the kebab cased string.
15468      * @example
15469      *
15470      * _.kebabCase('Foo Bar');
15471      * // => 'foo-bar'
15472      *
15473      * _.kebabCase('fooBar');
15474      * // => 'foo-bar'
15475      *
15476      * _.kebabCase('__FOO_BAR__');
15477      * // => 'foo-bar'
15478      */
15479     var kebabCase = createCompounder(function(result, word, index) {
15480       return result + (index ? '-' : '') + word.toLowerCase();
15481     });
15482
15483     /**
15484      * Converts `string`, as space separated words, to lower case.
15485      *
15486      * @static
15487      * @memberOf _
15488      * @since 4.0.0
15489      * @category String
15490      * @param {string} [string=''] The string to convert.
15491      * @returns {string} Returns the lower cased string.
15492      * @example
15493      *
15494      * _.lowerCase('--Foo-Bar--');
15495      * // => 'foo bar'
15496      *
15497      * _.lowerCase('fooBar');
15498      * // => 'foo bar'
15499      *
15500      * _.lowerCase('__FOO_BAR__');
15501      * // => 'foo bar'
15502      */
15503     var lowerCase = createCompounder(function(result, word, index) {
15504       return result + (index ? ' ' : '') + word.toLowerCase();
15505     });
15506
15507     /**
15508      * Converts the first character of `string` to lower case.
15509      *
15510      * @static
15511      * @memberOf _
15512      * @since 4.0.0
15513      * @category String
15514      * @param {string} [string=''] The string to convert.
15515      * @returns {string} Returns the converted string.
15516      * @example
15517      *
15518      * _.lowerFirst('Fred');
15519      * // => 'fred'
15520      *
15521      * _.lowerFirst('FRED');
15522      * // => 'fRED'
15523      */
15524     var lowerFirst = createCaseFirst('toLowerCase');
15525
15526     /**
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`.
15529      *
15530      * @static
15531      * @memberOf _
15532      * @since 3.0.0
15533      * @category String
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.
15538      * @example
15539      *
15540      * _.pad('abc', 8);
15541      * // => '  abc   '
15542      *
15543      * _.pad('abc', 8, '_-');
15544      * // => '_-abc_-_'
15545      *
15546      * _.pad('abc', 3);
15547      * // => 'abc'
15548      */
15549     function pad(string, length, chars) {
15550       string = toString(string);
15551       length = toInteger(length);
15552
15553       var strLength = length ? stringSize(string) : 0;
15554       if (!length || strLength >= length) {
15555         return string;
15556       }
15557       var mid = (length - strLength) / 2;
15558       return (
15559         createPadding(nativeFloor(mid), chars) +
15560         string +
15561         createPadding(nativeCeil(mid), chars)
15562       );
15563     }
15564
15565     /**
15566      * Pads `string` on the right side if it's shorter than `length`. Padding
15567      * characters are truncated if they exceed `length`.
15568      *
15569      * @static
15570      * @memberOf _
15571      * @since 4.0.0
15572      * @category String
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.
15577      * @example
15578      *
15579      * _.padEnd('abc', 6);
15580      * // => 'abc   '
15581      *
15582      * _.padEnd('abc', 6, '_-');
15583      * // => 'abc_-_'
15584      *
15585      * _.padEnd('abc', 3);
15586      * // => 'abc'
15587      */
15588     function padEnd(string, length, chars) {
15589       string = toString(string);
15590       length = toInteger(length);
15591
15592       var strLength = length ? stringSize(string) : 0;
15593       return (length && strLength < length)
15594         ? (string + createPadding(length - strLength, chars))
15595         : string;
15596     }
15597
15598     /**
15599      * Pads `string` on the left side if it's shorter than `length`. Padding
15600      * characters are truncated if they exceed `length`.
15601      *
15602      * @static
15603      * @memberOf _
15604      * @since 4.0.0
15605      * @category String
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.
15610      * @example
15611      *
15612      * _.padStart('abc', 6);
15613      * // => '   abc'
15614      *
15615      * _.padStart('abc', 6, '_-');
15616      * // => '_-_abc'
15617      *
15618      * _.padStart('abc', 3);
15619      * // => 'abc'
15620      */
15621     function padStart(string, length, chars) {
15622       string = toString(string);
15623       length = toInteger(length);
15624
15625       var strLength = length ? stringSize(string) : 0;
15626       return (length && strLength < length)
15627         ? (createPadding(length - strLength, chars) + string)
15628         : string;
15629     }
15630
15631     /**
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.
15635      *
15636      * **Note:** This method aligns with the
15637      * [ES5 implementation](https://es5.github.io/#x15.1.2.2) of `parseInt`.
15638      *
15639      * @static
15640      * @memberOf _
15641      * @since 1.1.0
15642      * @category String
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.
15647      * @example
15648      *
15649      * _.parseInt('08');
15650      * // => 8
15651      *
15652      * _.map(['6', '08', '10'], _.parseInt);
15653      * // => [6, 8, 10]
15654      */
15655     function parseInt(string, radix, guard) {
15656       if (guard || radix == null) {
15657         radix = 0;
15658       } else if (radix) {
15659         radix = +radix;
15660       }
15661       return nativeParseInt(toString(string).replace(reTrimStart, ''), radix || 0);
15662     }
15663
15664     /**
15665      * Repeats the given string `n` times.
15666      *
15667      * @static
15668      * @memberOf _
15669      * @since 3.0.0
15670      * @category String
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.
15675      * @example
15676      *
15677      * _.repeat('*', 3);
15678      * // => '***'
15679      *
15680      * _.repeat('abc', 2);
15681      * // => 'abcabc'
15682      *
15683      * _.repeat('abc', 0);
15684      * // => ''
15685      */
15686     function repeat(string, n, guard) {
15687       if ((guard ? isIterateeCall(string, n, guard) : n === undefined)) {
15688         n = 1;
15689       } else {
15690         n = toInteger(n);
15691       }
15692       return baseRepeat(toString(string), n);
15693     }
15694
15695     /**
15696      * Replaces matches for `pattern` in `string` with `replacement`.
15697      *
15698      * **Note:** This method is based on
15699      * [`String#replace`](https://mdn.io/String/replace).
15700      *
15701      * @static
15702      * @memberOf _
15703      * @since 4.0.0
15704      * @category String
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.
15709      * @example
15710      *
15711      * _.replace('Hi Fred', 'Fred', 'Barney');
15712      * // => 'Hi Barney'
15713      */
15714     function replace() {
15715       var args = arguments,
15716           string = toString(args[0]);
15717
15718       return args.length < 3 ? string : string.replace(args[1], args[2]);
15719     }
15720
15721     /**
15722      * Converts `string` to
15723      * [snake case](https://en.wikipedia.org/wiki/Snake_case).
15724      *
15725      * @static
15726      * @memberOf _
15727      * @since 3.0.0
15728      * @category String
15729      * @param {string} [string=''] The string to convert.
15730      * @returns {string} Returns the snake cased string.
15731      * @example
15732      *
15733      * _.snakeCase('Foo Bar');
15734      * // => 'foo_bar'
15735      *
15736      * _.snakeCase('fooBar');
15737      * // => 'foo_bar'
15738      *
15739      * _.snakeCase('--FOO-BAR--');
15740      * // => 'foo_bar'
15741      */
15742     var snakeCase = createCompounder(function(result, word, index) {
15743       return result + (index ? '_' : '') + word.toLowerCase();
15744     });
15745
15746     /**
15747      * Splits `string` by `separator`.
15748      *
15749      * **Note:** This method is based on
15750      * [`String#split`](https://mdn.io/String/split).
15751      *
15752      * @static
15753      * @memberOf _
15754      * @since 4.0.0
15755      * @category String
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.
15760      * @example
15761      *
15762      * _.split('a-b-c', '-', 2);
15763      * // => ['a', 'b']
15764      */
15765     function split(string, separator, limit) {
15766       if (limit && typeof limit != 'number' && isIterateeCall(string, separator, limit)) {
15767         separator = limit = undefined;
15768       }
15769       limit = limit === undefined ? MAX_ARRAY_LENGTH : limit >>> 0;
15770       if (!limit) {
15771         return [];
15772       }
15773       string = toString(string);
15774       if (string && (
15775             typeof separator == 'string' ||
15776             (separator != null && !isRegExp(separator))
15777           )) {
15778         separator = baseToString(separator);
15779         if (!separator && hasUnicode(string)) {
15780           return castSlice(stringToArray(string), 0, limit);
15781         }
15782       }
15783       return string.split(separator, limit);
15784     }
15785
15786     /**
15787      * Converts `string` to
15788      * [start case](https://en.wikipedia.org/wiki/Letter_case#Stylistic_or_specialised_usage).
15789      *
15790      * @static
15791      * @memberOf _
15792      * @since 3.1.0
15793      * @category String
15794      * @param {string} [string=''] The string to convert.
15795      * @returns {string} Returns the start cased string.
15796      * @example
15797      *
15798      * _.startCase('--foo-bar--');
15799      * // => 'Foo Bar'
15800      *
15801      * _.startCase('fooBar');
15802      * // => 'Foo Bar'
15803      *
15804      * _.startCase('__FOO_BAR__');
15805      * // => 'FOO BAR'
15806      */
15807     var startCase = createCompounder(function(result, word, index) {
15808       return result + (index ? ' ' : '') + upperFirst(word);
15809     });
15810
15811     /**
15812      * Checks if `string` starts with the given target string.
15813      *
15814      * @static
15815      * @memberOf _
15816      * @since 3.0.0
15817      * @category 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`,
15822      *  else `false`.
15823      * @example
15824      *
15825      * _.startsWith('abc', 'a');
15826      * // => true
15827      *
15828      * _.startsWith('abc', 'b');
15829      * // => false
15830      *
15831      * _.startsWith('abc', 'b', 1);
15832      * // => true
15833      */
15834     function startsWith(string, target, position) {
15835       string = toString(string);
15836       position = position == null
15837         ? 0
15838         : baseClamp(toInteger(position), 0, string.length);
15839
15840       target = baseToString(target);
15841       return string.slice(position, position + target.length) == target;
15842     }
15843
15844     /**
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.
15850      *
15851      * **Note:** In the development build `_.template` utilizes
15852      * [sourceURLs](http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl)
15853      * for easier debugging.
15854      *
15855      * For more information on precompiling templates see
15856      * [lodash's custom builds documentation](https://lodash.com/custom-builds).
15857      *
15858      * For more information on Chrome extension sandboxes see
15859      * [Chrome's extensions documentation](https://developer.chrome.com/extensions/sandboxingEval).
15860      *
15861      * @static
15862      * @since 0.1.0
15863      * @memberOf _
15864      * @category String
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.
15881      * @example
15882      *
15883      * // Use the "interpolate" delimiter to create a compiled template.
15884      * var compiled = _.template('hello <%= user %>!');
15885      * compiled({ 'user': 'fred' });
15886      * // => 'hello fred!'
15887      *
15888      * // Use the HTML "escape" delimiter to escape data property values.
15889      * var compiled = _.template('<b><%- value %></b>');
15890      * compiled({ 'value': '<script>' });
15891      * // => '<b>&lt;script&gt;</b>'
15892      *
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>'
15897      *
15898      * // Use the internal `print` function in "evaluate" delimiters.
15899      * var compiled = _.template('<% print("hello " + user); %>!');
15900      * compiled({ 'user': 'barney' });
15901      * // => 'hello barney!'
15902      *
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!'
15908      *
15909      * // Use backslashes to treat delimiters as plain text.
15910      * var compiled = _.template('<%= "\\<%- value %\\>" %>');
15911      * compiled({ 'value': 'ignored' });
15912      * // => '<%- value %>'
15913      *
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>'
15919      *
15920      * // Use the `sourceURL` option to specify a custom sourceURL for the template.
15921      * var compiled = _.template('hello <%= user %>!', { 'sourceURL': '/basic/greeting.jst' });
15922      * compiled(data);
15923      * // => Find the source of "greeting.jst" under the Sources tab or Resources panel of the web inspector.
15924      *
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' });
15927      * compiled.source;
15928      * // => function(data) {
15929      * //   var __t, __p = '';
15930      * //   __p += 'hi ' + ((__t = ( data.user )) == null ? '' : __t) + '!';
15931      * //   return __p;
15932      * // }
15933      *
15934      * // Use custom template delimiters.
15935      * _.templateSettings.interpolate = /{{([\s\S]+?)}}/g;
15936      * var compiled = _.template('hello {{ user }}!');
15937      * compiled({ 'user': 'mustache' });
15938      * // => 'hello mustache!'
15939      *
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'), '\
15943      *   var JST = {\
15944      *     "main": ' + _.template(mainText).source + '\
15945      *   };\
15946      * ');
15947      */
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;
15953
15954       if (guard && isIterateeCall(string, options, guard)) {
15955         options = undefined;
15956       }
15957       string = toString(string);
15958       options = assignInWith({}, options, settings, customDefaultsAssignIn);
15959
15960       var imports = assignInWith({}, options.imports, settings.imports, customDefaultsAssignIn),
15961           importsKeys = keys(imports),
15962           importsValues = baseValues(imports, importsKeys);
15963
15964       var isEscaping,
15965           isEvaluating,
15966           index = 0,
15967           interpolate = options.interpolate || reNoMatch,
15968           source = "__p += '";
15969
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 + '|$'
15976       , 'g');
15977
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) + ']')
15986         ) + '\n';
15987
15988       string.replace(reDelimiters, function(match, escapeValue, interpolateValue, esTemplateValue, evaluateValue, offset) {
15989         interpolateValue || (interpolateValue = esTemplateValue);
15990
15991         // Escape characters that can't be included in string literals.
15992         source += string.slice(index, offset).replace(reUnescapedString, escapeStringChar);
15993
15994         // Replace delimiters with snippets.
15995         if (escapeValue) {
15996           isEscaping = true;
15997           source += "' +\n__e(" + escapeValue + ") +\n'";
15998         }
15999         if (evaluateValue) {
16000           isEvaluating = true;
16001           source += "';\n" + evaluateValue + ";\n__p += '";
16002         }
16003         if (interpolateValue) {
16004           source += "' +\n((__t = (" + interpolateValue + ")) == null ? '' : __t) +\n'";
16005         }
16006         index = offset + match.length;
16007
16008         // The JS engine embedded in Adobe products needs `match` returned in
16009         // order to produce the correct `offset` value.
16010         return match;
16011       });
16012
16013       source += "';\n";
16014
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;
16018       if (!variable) {
16019         source = 'with (obj) {\n' + source + '\n}\n';
16020       }
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);
16025       }
16026
16027       // Cleanup code by stripping empty strings.
16028       source = (isEvaluating ? source.replace(reEmptyStringLeading, '') : source)
16029         .replace(reEmptyStringMiddle, '$1')
16030         .replace(reEmptyStringTrailing, '$1;');
16031
16032       // Frame code as the function body.
16033       source = 'function(' + (variable || 'obj') + ') {\n' +
16034         (variable
16035           ? ''
16036           : 'obj || (obj = {});\n'
16037         ) +
16038         "var __t, __p = ''" +
16039         (isEscaping
16040            ? ', __e = _.escape'
16041            : ''
16042         ) +
16043         (isEvaluating
16044           ? ', __j = Array.prototype.join;\n' +
16045             "function print() { __p += __j.call(arguments, '') }\n"
16046           : ';\n'
16047         ) +
16048         source +
16049         'return __p\n}';
16050
16051       var result = attempt(function() {
16052         return Function(importsKeys, sourceURL + 'return ' + source)
16053           .apply(undefined, importsValues);
16054       });
16055
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)) {
16060         throw result;
16061       }
16062       return result;
16063     }
16064
16065     /**
16066      * Converts `string`, as a whole, to lower case just like
16067      * [String#toLowerCase](https://mdn.io/toLowerCase).
16068      *
16069      * @static
16070      * @memberOf _
16071      * @since 4.0.0
16072      * @category String
16073      * @param {string} [string=''] The string to convert.
16074      * @returns {string} Returns the lower cased string.
16075      * @example
16076      *
16077      * _.toLower('--Foo-Bar--');
16078      * // => '--foo-bar--'
16079      *
16080      * _.toLower('fooBar');
16081      * // => 'foobar'
16082      *
16083      * _.toLower('__FOO_BAR__');
16084      * // => '__foo_bar__'
16085      */
16086     function toLower(value) {
16087       return toString(value).toLowerCase();
16088     }
16089
16090     /**
16091      * Converts `string`, as a whole, to upper case just like
16092      * [String#toUpperCase](https://mdn.io/toUpperCase).
16093      *
16094      * @static
16095      * @memberOf _
16096      * @since 4.0.0
16097      * @category String
16098      * @param {string} [string=''] The string to convert.
16099      * @returns {string} Returns the upper cased string.
16100      * @example
16101      *
16102      * _.toUpper('--foo-bar--');
16103      * // => '--FOO-BAR--'
16104      *
16105      * _.toUpper('fooBar');
16106      * // => 'FOOBAR'
16107      *
16108      * _.toUpper('__foo_bar__');
16109      * // => '__FOO_BAR__'
16110      */
16111     function toUpper(value) {
16112       return toString(value).toUpperCase();
16113     }
16114
16115     /**
16116      * Removes leading and trailing whitespace or specified characters from `string`.
16117      *
16118      * @static
16119      * @memberOf _
16120      * @since 3.0.0
16121      * @category 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.
16126      * @example
16127      *
16128      * _.trim('  abc  ');
16129      * // => 'abc'
16130      *
16131      * _.trim('-_-abc-_-', '_-');
16132      * // => 'abc'
16133      *
16134      * _.map(['  foo  ', '  bar  '], _.trim);
16135      * // => ['foo', 'bar']
16136      */
16137     function trim(string, chars, guard) {
16138       string = toString(string);
16139       if (string && (guard || chars === undefined)) {
16140         return baseTrim(string);
16141       }
16142       if (!string || !(chars = baseToString(chars))) {
16143         return string;
16144       }
16145       var strSymbols = stringToArray(string),
16146           chrSymbols = stringToArray(chars),
16147           start = charsStartIndex(strSymbols, chrSymbols),
16148           end = charsEndIndex(strSymbols, chrSymbols) + 1;
16149
16150       return castSlice(strSymbols, start, end).join('');
16151     }
16152
16153     /**
16154      * Removes trailing whitespace or specified characters from `string`.
16155      *
16156      * @static
16157      * @memberOf _
16158      * @since 4.0.0
16159      * @category 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.
16164      * @example
16165      *
16166      * _.trimEnd('  abc  ');
16167      * // => '  abc'
16168      *
16169      * _.trimEnd('-_-abc-_-', '_-');
16170      * // => '-_-abc'
16171      */
16172     function trimEnd(string, chars, guard) {
16173       string = toString(string);
16174       if (string && (guard || chars === undefined)) {
16175         return string.slice(0, trimmedEndIndex(string) + 1);
16176       }
16177       if (!string || !(chars = baseToString(chars))) {
16178         return string;
16179       }
16180       var strSymbols = stringToArray(string),
16181           end = charsEndIndex(strSymbols, stringToArray(chars)) + 1;
16182
16183       return castSlice(strSymbols, 0, end).join('');
16184     }
16185
16186     /**
16187      * Removes leading whitespace or specified characters from `string`.
16188      *
16189      * @static
16190      * @memberOf _
16191      * @since 4.0.0
16192      * @category 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.
16197      * @example
16198      *
16199      * _.trimStart('  abc  ');
16200      * // => 'abc  '
16201      *
16202      * _.trimStart('-_-abc-_-', '_-');
16203      * // => 'abc-_-'
16204      */
16205     function trimStart(string, chars, guard) {
16206       string = toString(string);
16207       if (string && (guard || chars === undefined)) {
16208         return string.replace(reTrimStart, '');
16209       }
16210       if (!string || !(chars = baseToString(chars))) {
16211         return string;
16212       }
16213       var strSymbols = stringToArray(string),
16214           start = charsStartIndex(strSymbols, stringToArray(chars));
16215
16216       return castSlice(strSymbols, start).join('');
16217     }
16218
16219     /**
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 "...".
16223      *
16224      * @static
16225      * @memberOf _
16226      * @since 4.0.0
16227      * @category String
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.
16234      * @example
16235      *
16236      * _.truncate('hi-diddly-ho there, neighborino');
16237      * // => 'hi-diddly-ho there, neighbo...'
16238      *
16239      * _.truncate('hi-diddly-ho there, neighborino', {
16240      *   'length': 24,
16241      *   'separator': ' '
16242      * });
16243      * // => 'hi-diddly-ho there,...'
16244      *
16245      * _.truncate('hi-diddly-ho there, neighborino', {
16246      *   'length': 24,
16247      *   'separator': /,? +/
16248      * });
16249      * // => 'hi-diddly-ho there...'
16250      *
16251      * _.truncate('hi-diddly-ho there, neighborino', {
16252      *   'omission': ' [...]'
16253      * });
16254      * // => 'hi-diddly-ho there, neig [...]'
16255      */
16256     function truncate(string, options) {
16257       var length = DEFAULT_TRUNC_LENGTH,
16258           omission = DEFAULT_TRUNC_OMISSION;
16259
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;
16264       }
16265       string = toString(string);
16266
16267       var strLength = string.length;
16268       if (hasUnicode(string)) {
16269         var strSymbols = stringToArray(string);
16270         strLength = strSymbols.length;
16271       }
16272       if (length >= strLength) {
16273         return string;
16274       }
16275       var end = length - stringSize(omission);
16276       if (end < 1) {
16277         return omission;
16278       }
16279       var result = strSymbols
16280         ? castSlice(strSymbols, 0, end).join('')
16281         : string.slice(0, end);
16282
16283       if (separator === undefined) {
16284         return result + omission;
16285       }
16286       if (strSymbols) {
16287         end += (result.length - end);
16288       }
16289       if (isRegExp(separator)) {
16290         if (string.slice(end).search(separator)) {
16291           var match,
16292               substring = result;
16293
16294           if (!separator.global) {
16295             separator = RegExp(separator.source, toString(reFlags.exec(separator)) + 'g');
16296           }
16297           separator.lastIndex = 0;
16298           while ((match = separator.exec(substring))) {
16299             var newEnd = match.index;
16300           }
16301           result = result.slice(0, newEnd === undefined ? end : newEnd);
16302         }
16303       } else if (string.indexOf(baseToString(separator), end) != end) {
16304         var index = result.lastIndexOf(separator);
16305         if (index > -1) {
16306           result = result.slice(0, index);
16307         }
16308       }
16309       return result + omission;
16310     }
16311
16312     /**
16313      * The inverse of `_.escape`; this method converts the HTML entities
16314      * `&amp;`, `&lt;`, `&gt;`, `&quot;`, and `&#39;` in `string` to
16315      * their corresponding characters.
16316      *
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).
16319      *
16320      * @static
16321      * @memberOf _
16322      * @since 0.6.0
16323      * @category String
16324      * @param {string} [string=''] The string to unescape.
16325      * @returns {string} Returns the unescaped string.
16326      * @example
16327      *
16328      * _.unescape('fred, barney, &amp; pebbles');
16329      * // => 'fred, barney, & pebbles'
16330      */
16331     function unescape(string) {
16332       string = toString(string);
16333       return (string && reHasEscapedHtml.test(string))
16334         ? string.replace(reEscapedHtml, unescapeHtmlChar)
16335         : string;
16336     }
16337
16338     /**
16339      * Converts `string`, as space separated words, to upper case.
16340      *
16341      * @static
16342      * @memberOf _
16343      * @since 4.0.0
16344      * @category String
16345      * @param {string} [string=''] The string to convert.
16346      * @returns {string} Returns the upper cased string.
16347      * @example
16348      *
16349      * _.upperCase('--foo-bar');
16350      * // => 'FOO BAR'
16351      *
16352      * _.upperCase('fooBar');
16353      * // => 'FOO BAR'
16354      *
16355      * _.upperCase('__foo_bar__');
16356      * // => 'FOO BAR'
16357      */
16358     var upperCase = createCompounder(function(result, word, index) {
16359       return result + (index ? ' ' : '') + word.toUpperCase();
16360     });
16361
16362     /**
16363      * Converts the first character of `string` to upper case.
16364      *
16365      * @static
16366      * @memberOf _
16367      * @since 4.0.0
16368      * @category String
16369      * @param {string} [string=''] The string to convert.
16370      * @returns {string} Returns the converted string.
16371      * @example
16372      *
16373      * _.upperFirst('fred');
16374      * // => 'Fred'
16375      *
16376      * _.upperFirst('FRED');
16377      * // => 'FRED'
16378      */
16379     var upperFirst = createCaseFirst('toUpperCase');
16380
16381     /**
16382      * Splits `string` into an array of its words.
16383      *
16384      * @static
16385      * @memberOf _
16386      * @since 3.0.0
16387      * @category String
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`.
16392      * @example
16393      *
16394      * _.words('fred, barney, & pebbles');
16395      * // => ['fred', 'barney', 'pebbles']
16396      *
16397      * _.words('fred, barney, & pebbles', /[^, ]+/g);
16398      * // => ['fred', 'barney', '&', 'pebbles']
16399      */
16400     function words(string, pattern, guard) {
16401       string = toString(string);
16402       pattern = guard ? undefined : pattern;
16403
16404       if (pattern === undefined) {
16405         return hasUnicodeWord(string) ? unicodeWords(string) : asciiWords(string);
16406       }
16407       return string.match(pattern) || [];
16408     }
16409
16410     /*------------------------------------------------------------------------*/
16411
16412     /**
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.
16415      *
16416      * @static
16417      * @memberOf _
16418      * @since 3.0.0
16419      * @category Util
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.
16423      * @example
16424      *
16425      * // Avoid throwing errors for invalid selectors.
16426      * var elements = _.attempt(function(selector) {
16427      *   return document.querySelectorAll(selector);
16428      * }, '>_>');
16429      *
16430      * if (_.isError(elements)) {
16431      *   elements = [];
16432      * }
16433      */
16434     var attempt = baseRest(function(func, args) {
16435       try {
16436         return apply(func, undefined, args);
16437       } catch (e) {
16438         return isError(e) ? e : new Error(e);
16439       }
16440     });
16441
16442     /**
16443      * Binds methods of an object to the object itself, overwriting the existing
16444      * method.
16445      *
16446      * **Note:** This method doesn't set the "length" property of bound functions.
16447      *
16448      * @static
16449      * @since 0.1.0
16450      * @memberOf _
16451      * @category Util
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`.
16455      * @example
16456      *
16457      * var view = {
16458      *   'label': 'docs',
16459      *   'click': function() {
16460      *     console.log('clicked ' + this.label);
16461      *   }
16462      * };
16463      *
16464      * _.bindAll(view, ['click']);
16465      * jQuery(element).on('click', view.click);
16466      * // => Logs 'clicked docs' when clicked.
16467      */
16468     var bindAll = flatRest(function(object, methodNames) {
16469       arrayEach(methodNames, function(key) {
16470         key = toKey(key);
16471         baseAssignValue(object, key, bind(object[key], object));
16472       });
16473       return object;
16474     });
16475
16476     /**
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
16480      * function.
16481      *
16482      * @static
16483      * @memberOf _
16484      * @since 4.0.0
16485      * @category Util
16486      * @param {Array} pairs The predicate-function pairs.
16487      * @returns {Function} Returns the new composite function.
16488      * @example
16489      *
16490      * var func = _.cond([
16491      *   [_.matches({ 'a': 1 }),           _.constant('matches A')],
16492      *   [_.conforms({ 'b': _.isNumber }), _.constant('matches B')],
16493      *   [_.stubTrue,                      _.constant('no match')]
16494      * ]);
16495      *
16496      * func({ 'a': 1, 'b': 2 });
16497      * // => 'matches A'
16498      *
16499      * func({ 'a': 0, 'b': 1 });
16500      * // => 'matches B'
16501      *
16502      * func({ 'a': '1', 'b': '2' });
16503      * // => 'no match'
16504      */
16505     function cond(pairs) {
16506       var length = pairs == null ? 0 : pairs.length,
16507           toIteratee = getIteratee();
16508
16509       pairs = !length ? [] : arrayMap(pairs, function(pair) {
16510         if (typeof pair[1] != 'function') {
16511           throw new TypeError(FUNC_ERROR_TEXT);
16512         }
16513         return [toIteratee(pair[0]), pair[1]];
16514       });
16515
16516       return baseRest(function(args) {
16517         var index = -1;
16518         while (++index < length) {
16519           var pair = pairs[index];
16520           if (apply(pair[0], this, args)) {
16521             return apply(pair[1], this, args);
16522           }
16523         }
16524       });
16525     }
16526
16527     /**
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`.
16531      *
16532      * **Note:** The created function is equivalent to `_.conformsTo` with
16533      * `source` partially applied.
16534      *
16535      * @static
16536      * @memberOf _
16537      * @since 4.0.0
16538      * @category Util
16539      * @param {Object} source The object of property predicates to conform to.
16540      * @returns {Function} Returns the new spec function.
16541      * @example
16542      *
16543      * var objects = [
16544      *   { 'a': 2, 'b': 1 },
16545      *   { 'a': 1, 'b': 2 }
16546      * ];
16547      *
16548      * _.filter(objects, _.conforms({ 'b': function(n) { return n > 1; } }));
16549      * // => [{ 'a': 1, 'b': 2 }]
16550      */
16551     function conforms(source) {
16552       return baseConforms(baseClone(source, CLONE_DEEP_FLAG));
16553     }
16554
16555     /**
16556      * Creates a function that returns `value`.
16557      *
16558      * @static
16559      * @memberOf _
16560      * @since 2.4.0
16561      * @category Util
16562      * @param {*} value The value to return from the new function.
16563      * @returns {Function} Returns the new constant function.
16564      * @example
16565      *
16566      * var objects = _.times(2, _.constant({ 'a': 1 }));
16567      *
16568      * console.log(objects);
16569      * // => [{ 'a': 1 }, { 'a': 1 }]
16570      *
16571      * console.log(objects[0] === objects[1]);
16572      * // => true
16573      */
16574     function constant(value) {
16575       return function() {
16576         return value;
16577       };
16578     }
16579
16580     /**
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`,
16583      * or `undefined`.
16584      *
16585      * @static
16586      * @memberOf _
16587      * @since 4.14.0
16588      * @category Util
16589      * @param {*} value The value to check.
16590      * @param {*} defaultValue The default value.
16591      * @returns {*} Returns the resolved value.
16592      * @example
16593      *
16594      * _.defaultTo(1, 10);
16595      * // => 1
16596      *
16597      * _.defaultTo(undefined, 10);
16598      * // => 10
16599      */
16600     function defaultTo(value, defaultValue) {
16601       return (value == null || value !== value) ? defaultValue : value;
16602     }
16603
16604     /**
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.
16608      *
16609      * @static
16610      * @memberOf _
16611      * @since 3.0.0
16612      * @category Util
16613      * @param {...(Function|Function[])} [funcs] The functions to invoke.
16614      * @returns {Function} Returns the new composite function.
16615      * @see _.flowRight
16616      * @example
16617      *
16618      * function square(n) {
16619      *   return n * n;
16620      * }
16621      *
16622      * var addSquare = _.flow([_.add, square]);
16623      * addSquare(1, 2);
16624      * // => 9
16625      */
16626     var flow = createFlow();
16627
16628     /**
16629      * This method is like `_.flow` except that it creates a function that
16630      * invokes the given functions from right to left.
16631      *
16632      * @static
16633      * @since 3.0.0
16634      * @memberOf _
16635      * @category Util
16636      * @param {...(Function|Function[])} [funcs] The functions to invoke.
16637      * @returns {Function} Returns the new composite function.
16638      * @see _.flow
16639      * @example
16640      *
16641      * function square(n) {
16642      *   return n * n;
16643      * }
16644      *
16645      * var addSquare = _.flowRight([square, _.add]);
16646      * addSquare(1, 2);
16647      * // => 9
16648      */
16649     var flowRight = createFlow(true);
16650
16651     /**
16652      * This method returns the first argument it receives.
16653      *
16654      * @static
16655      * @since 0.1.0
16656      * @memberOf _
16657      * @category Util
16658      * @param {*} value Any value.
16659      * @returns {*} Returns `value`.
16660      * @example
16661      *
16662      * var object = { 'a': 1 };
16663      *
16664      * console.log(_.identity(object) === object);
16665      * // => true
16666      */
16667     function identity(value) {
16668       return value;
16669     }
16670
16671     /**
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`.
16677      *
16678      * @static
16679      * @since 4.0.0
16680      * @memberOf _
16681      * @category Util
16682      * @param {*} [func=_.identity] The value to convert to a callback.
16683      * @returns {Function} Returns the callback.
16684      * @example
16685      *
16686      * var users = [
16687      *   { 'user': 'barney', 'age': 36, 'active': true },
16688      *   { 'user': 'fred',   'age': 40, 'active': false }
16689      * ];
16690      *
16691      * // The `_.matches` iteratee shorthand.
16692      * _.filter(users, _.iteratee({ 'user': 'barney', 'active': true }));
16693      * // => [{ 'user': 'barney', 'age': 36, 'active': true }]
16694      *
16695      * // The `_.matchesProperty` iteratee shorthand.
16696      * _.filter(users, _.iteratee(['user', 'fred']));
16697      * // => [{ 'user': 'fred', 'age': 40 }]
16698      *
16699      * // The `_.property` iteratee shorthand.
16700      * _.map(users, _.iteratee('user'));
16701      * // => ['barney', 'fred']
16702      *
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);
16707      *   };
16708      * });
16709      *
16710      * _.filter(['abc', 'def'], /ef/);
16711      * // => ['def']
16712      */
16713     function iteratee(func) {
16714       return baseIteratee(typeof func == 'function' ? func : baseClone(func, CLONE_DEEP_FLAG));
16715     }
16716
16717     /**
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`.
16721      *
16722      * **Note:** The created function is equivalent to `_.isMatch` with `source`
16723      * partially applied.
16724      *
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.
16728      *
16729      * **Note:** Multiple values can be checked by combining several matchers
16730      * using `_.overSome`
16731      *
16732      * @static
16733      * @memberOf _
16734      * @since 3.0.0
16735      * @category Util
16736      * @param {Object} source The object of property values to match.
16737      * @returns {Function} Returns the new spec function.
16738      * @example
16739      *
16740      * var objects = [
16741      *   { 'a': 1, 'b': 2, 'c': 3 },
16742      *   { 'a': 4, 'b': 5, 'c': 6 }
16743      * ];
16744      *
16745      * _.filter(objects, _.matches({ 'a': 4, 'c': 6 }));
16746      * // => [{ 'a': 4, 'b': 5, 'c': 6 }]
16747      *
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 }]
16751      */
16752     function matches(source) {
16753       return baseMatches(baseClone(source, CLONE_DEEP_FLAG));
16754     }
16755
16756     /**
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`.
16760      *
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.
16764      *
16765      * **Note:** Multiple values can be checked by combining several matchers
16766      * using `_.overSome`
16767      *
16768      * @static
16769      * @memberOf _
16770      * @since 3.2.0
16771      * @category Util
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.
16775      * @example
16776      *
16777      * var objects = [
16778      *   { 'a': 1, 'b': 2, 'c': 3 },
16779      *   { 'a': 4, 'b': 5, 'c': 6 }
16780      * ];
16781      *
16782      * _.find(objects, _.matchesProperty('a', 4));
16783      * // => { 'a': 4, 'b': 5, 'c': 6 }
16784      *
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 }]
16788      */
16789     function matchesProperty(path, srcValue) {
16790       return baseMatchesProperty(path, baseClone(srcValue, CLONE_DEEP_FLAG));
16791     }
16792
16793     /**
16794      * Creates a function that invokes the method at `path` of a given object.
16795      * Any additional arguments are provided to the invoked method.
16796      *
16797      * @static
16798      * @memberOf _
16799      * @since 3.7.0
16800      * @category Util
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.
16804      * @example
16805      *
16806      * var objects = [
16807      *   { 'a': { 'b': _.constant(2) } },
16808      *   { 'a': { 'b': _.constant(1) } }
16809      * ];
16810      *
16811      * _.map(objects, _.method('a.b'));
16812      * // => [2, 1]
16813      *
16814      * _.map(objects, _.method(['a', 'b']));
16815      * // => [2, 1]
16816      */
16817     var method = baseRest(function(path, args) {
16818       return function(object) {
16819         return baseInvoke(object, path, args);
16820       };
16821     });
16822
16823     /**
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.
16827      *
16828      * @static
16829      * @memberOf _
16830      * @since 3.7.0
16831      * @category Util
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.
16835      * @example
16836      *
16837      * var array = _.times(3, _.constant),
16838      *     object = { 'a': array, 'b': array, 'c': array };
16839      *
16840      * _.map(['a[2]', 'c[0]'], _.methodOf(object));
16841      * // => [2, 0]
16842      *
16843      * _.map([['a', '2'], ['c', '0']], _.methodOf(object));
16844      * // => [2, 0]
16845      */
16846     var methodOf = baseRest(function(object, args) {
16847       return function(path) {
16848         return baseInvoke(object, path, args);
16849       };
16850     });
16851
16852     /**
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.
16856      *
16857      * **Note:** Use `_.runInContext` to create a pristine `lodash` function to
16858      * avoid conflicts caused by modifying the original.
16859      *
16860      * @static
16861      * @since 0.1.0
16862      * @memberOf _
16863      * @category Util
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`.
16869      * @example
16870      *
16871      * function vowels(string) {
16872      *   return _.filter(string, function(v) {
16873      *     return /[aeiou]/i.test(v);
16874      *   });
16875      * }
16876      *
16877      * _.mixin({ 'vowels': vowels });
16878      * _.vowels('fred');
16879      * // => ['e']
16880      *
16881      * _('fred').vowels().value();
16882      * // => ['e']
16883      *
16884      * _.mixin({ 'vowels': vowels }, { 'chain': false });
16885      * _('fred').vowels();
16886      * // => ['e']
16887      */
16888     function mixin(object, source, options) {
16889       var props = keys(source),
16890           methodNames = baseFunctions(source, props);
16891
16892       if (options == null &&
16893           !(isObject(source) && (methodNames.length || !props.length))) {
16894         options = source;
16895         source = object;
16896         object = this;
16897         methodNames = baseFunctions(source, keys(source));
16898       }
16899       var chain = !(isObject(options) && 'chain' in options) || !!options.chain,
16900           isFunc = isFunction(object);
16901
16902       arrayEach(methodNames, function(methodName) {
16903         var func = source[methodName];
16904         object[methodName] = func;
16905         if (isFunc) {
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__);
16911
16912               actions.push({ 'func': func, 'args': arguments, 'thisArg': object });
16913               result.__chain__ = chainAll;
16914               return result;
16915             }
16916             return func.apply(object, arrayPush([this.value()], arguments));
16917           };
16918         }
16919       });
16920
16921       return object;
16922     }
16923
16924     /**
16925      * Reverts the `_` variable to its previous value and returns a reference to
16926      * the `lodash` function.
16927      *
16928      * @static
16929      * @since 0.1.0
16930      * @memberOf _
16931      * @category Util
16932      * @returns {Function} Returns the `lodash` function.
16933      * @example
16934      *
16935      * var lodash = _.noConflict();
16936      */
16937     function noConflict() {
16938       if (root._ === this) {
16939         root._ = oldDash;
16940       }
16941       return this;
16942     }
16943
16944     /**
16945      * This method returns `undefined`.
16946      *
16947      * @static
16948      * @memberOf _
16949      * @since 2.3.0
16950      * @category Util
16951      * @example
16952      *
16953      * _.times(2, _.noop);
16954      * // => [undefined, undefined]
16955      */
16956     function noop() {
16957       // No operation performed.
16958     }
16959
16960     /**
16961      * Creates a function that gets the argument at index `n`. If `n` is negative,
16962      * the nth argument from the end is returned.
16963      *
16964      * @static
16965      * @memberOf _
16966      * @since 4.0.0
16967      * @category Util
16968      * @param {number} [n=0] The index of the argument to return.
16969      * @returns {Function} Returns the new pass-thru function.
16970      * @example
16971      *
16972      * var func = _.nthArg(1);
16973      * func('a', 'b', 'c', 'd');
16974      * // => 'b'
16975      *
16976      * var func = _.nthArg(-2);
16977      * func('a', 'b', 'c', 'd');
16978      * // => 'c'
16979      */
16980     function nthArg(n) {
16981       n = toInteger(n);
16982       return baseRest(function(args) {
16983         return baseNth(args, n);
16984       });
16985     }
16986
16987     /**
16988      * Creates a function that invokes `iteratees` with the arguments it receives
16989      * and returns their results.
16990      *
16991      * @static
16992      * @memberOf _
16993      * @since 4.0.0
16994      * @category Util
16995      * @param {...(Function|Function[])} [iteratees=[_.identity]]
16996      *  The iteratees to invoke.
16997      * @returns {Function} Returns the new function.
16998      * @example
16999      *
17000      * var func = _.over([Math.max, Math.min]);
17001      *
17002      * func(1, 2, 3, 4);
17003      * // => [4, 1]
17004      */
17005     var over = createOver(arrayMap);
17006
17007     /**
17008      * Creates a function that checks if **all** of the `predicates` return
17009      * truthy when invoked with the arguments it receives.
17010      *
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.
17014      *
17015      * @static
17016      * @memberOf _
17017      * @since 4.0.0
17018      * @category Util
17019      * @param {...(Function|Function[])} [predicates=[_.identity]]
17020      *  The predicates to check.
17021      * @returns {Function} Returns the new function.
17022      * @example
17023      *
17024      * var func = _.overEvery([Boolean, isFinite]);
17025      *
17026      * func('1');
17027      * // => true
17028      *
17029      * func(null);
17030      * // => false
17031      *
17032      * func(NaN);
17033      * // => false
17034      */
17035     var overEvery = createOver(arrayEvery);
17036
17037     /**
17038      * Creates a function that checks if **any** of the `predicates` return
17039      * truthy when invoked with the arguments it receives.
17040      *
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.
17044      *
17045      * @static
17046      * @memberOf _
17047      * @since 4.0.0
17048      * @category Util
17049      * @param {...(Function|Function[])} [predicates=[_.identity]]
17050      *  The predicates to check.
17051      * @returns {Function} Returns the new function.
17052      * @example
17053      *
17054      * var func = _.overSome([Boolean, isFinite]);
17055      *
17056      * func('1');
17057      * // => true
17058      *
17059      * func(null);
17060      * // => true
17061      *
17062      * func(NaN);
17063      * // => false
17064      *
17065      * var matchesFunc = _.overSome([{ 'a': 1 }, { 'a': 2 }])
17066      * var matchesPropertyFunc = _.overSome([['a', 1], ['a', 2]])
17067      */
17068     var overSome = createOver(arraySome);
17069
17070     /**
17071      * Creates a function that returns the value at `path` of a given object.
17072      *
17073      * @static
17074      * @memberOf _
17075      * @since 2.4.0
17076      * @category Util
17077      * @param {Array|string} path The path of the property to get.
17078      * @returns {Function} Returns the new accessor function.
17079      * @example
17080      *
17081      * var objects = [
17082      *   { 'a': { 'b': 2 } },
17083      *   { 'a': { 'b': 1 } }
17084      * ];
17085      *
17086      * _.map(objects, _.property('a.b'));
17087      * // => [2, 1]
17088      *
17089      * _.map(_.sortBy(objects, _.property(['a', 'b'])), 'a.b');
17090      * // => [1, 2]
17091      */
17092     function property(path) {
17093       return isKey(path) ? baseProperty(toKey(path)) : basePropertyDeep(path);
17094     }
17095
17096     /**
17097      * The opposite of `_.property`; this method creates a function that returns
17098      * the value at a given path of `object`.
17099      *
17100      * @static
17101      * @memberOf _
17102      * @since 3.0.0
17103      * @category Util
17104      * @param {Object} object The object to query.
17105      * @returns {Function} Returns the new accessor function.
17106      * @example
17107      *
17108      * var array = [0, 1, 2],
17109      *     object = { 'a': array, 'b': array, 'c': array };
17110      *
17111      * _.map(['a[2]', 'c[0]'], _.propertyOf(object));
17112      * // => [2, 0]
17113      *
17114      * _.map([['a', '2'], ['c', '0']], _.propertyOf(object));
17115      * // => [2, 0]
17116      */
17117     function propertyOf(object) {
17118       return function(path) {
17119         return object == null ? undefined : baseGet(object, path);
17120       };
17121     }
17122
17123     /**
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`.
17128      *
17129      * **Note:** JavaScript follows the IEEE-754 standard for resolving
17130      * floating-point values which can produce unexpected results.
17131      *
17132      * @static
17133      * @since 0.1.0
17134      * @memberOf _
17135      * @category Util
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
17141      * @example
17142      *
17143      * _.range(4);
17144      * // => [0, 1, 2, 3]
17145      *
17146      * _.range(-4);
17147      * // => [0, -1, -2, -3]
17148      *
17149      * _.range(1, 5);
17150      * // => [1, 2, 3, 4]
17151      *
17152      * _.range(0, 20, 5);
17153      * // => [0, 5, 10, 15]
17154      *
17155      * _.range(0, -4, -1);
17156      * // => [0, -1, -2, -3]
17157      *
17158      * _.range(1, 4, 0);
17159      * // => [1, 1, 1]
17160      *
17161      * _.range(0);
17162      * // => []
17163      */
17164     var range = createRange();
17165
17166     /**
17167      * This method is like `_.range` except that it populates values in
17168      * descending order.
17169      *
17170      * @static
17171      * @memberOf _
17172      * @since 4.0.0
17173      * @category Util
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
17179      * @example
17180      *
17181      * _.rangeRight(4);
17182      * // => [3, 2, 1, 0]
17183      *
17184      * _.rangeRight(-4);
17185      * // => [-3, -2, -1, 0]
17186      *
17187      * _.rangeRight(1, 5);
17188      * // => [4, 3, 2, 1]
17189      *
17190      * _.rangeRight(0, 20, 5);
17191      * // => [15, 10, 5, 0]
17192      *
17193      * _.rangeRight(0, -4, -1);
17194      * // => [-3, -2, -1, 0]
17195      *
17196      * _.rangeRight(1, 4, 0);
17197      * // => [1, 1, 1]
17198      *
17199      * _.rangeRight(0);
17200      * // => []
17201      */
17202     var rangeRight = createRange(true);
17203
17204     /**
17205      * This method returns a new empty array.
17206      *
17207      * @static
17208      * @memberOf _
17209      * @since 4.13.0
17210      * @category Util
17211      * @returns {Array} Returns the new empty array.
17212      * @example
17213      *
17214      * var arrays = _.times(2, _.stubArray);
17215      *
17216      * console.log(arrays);
17217      * // => [[], []]
17218      *
17219      * console.log(arrays[0] === arrays[1]);
17220      * // => false
17221      */
17222     function stubArray() {
17223       return [];
17224     }
17225
17226     /**
17227      * This method returns `false`.
17228      *
17229      * @static
17230      * @memberOf _
17231      * @since 4.13.0
17232      * @category Util
17233      * @returns {boolean} Returns `false`.
17234      * @example
17235      *
17236      * _.times(2, _.stubFalse);
17237      * // => [false, false]
17238      */
17239     function stubFalse() {
17240       return false;
17241     }
17242
17243     /**
17244      * This method returns a new empty object.
17245      *
17246      * @static
17247      * @memberOf _
17248      * @since 4.13.0
17249      * @category Util
17250      * @returns {Object} Returns the new empty object.
17251      * @example
17252      *
17253      * var objects = _.times(2, _.stubObject);
17254      *
17255      * console.log(objects);
17256      * // => [{}, {}]
17257      *
17258      * console.log(objects[0] === objects[1]);
17259      * // => false
17260      */
17261     function stubObject() {
17262       return {};
17263     }
17264
17265     /**
17266      * This method returns an empty string.
17267      *
17268      * @static
17269      * @memberOf _
17270      * @since 4.13.0
17271      * @category Util
17272      * @returns {string} Returns the empty string.
17273      * @example
17274      *
17275      * _.times(2, _.stubString);
17276      * // => ['', '']
17277      */
17278     function stubString() {
17279       return '';
17280     }
17281
17282     /**
17283      * This method returns `true`.
17284      *
17285      * @static
17286      * @memberOf _
17287      * @since 4.13.0
17288      * @category Util
17289      * @returns {boolean} Returns `true`.
17290      * @example
17291      *
17292      * _.times(2, _.stubTrue);
17293      * // => [true, true]
17294      */
17295     function stubTrue() {
17296       return true;
17297     }
17298
17299     /**
17300      * Invokes the iteratee `n` times, returning an array of the results of
17301      * each invocation. The iteratee is invoked with one argument; (index).
17302      *
17303      * @static
17304      * @since 0.1.0
17305      * @memberOf _
17306      * @category Util
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.
17310      * @example
17311      *
17312      * _.times(3, String);
17313      * // => ['0', '1', '2']
17314      *
17315      *  _.times(4, _.constant(0));
17316      * // => [0, 0, 0, 0]
17317      */
17318     function times(n, iteratee) {
17319       n = toInteger(n);
17320       if (n < 1 || n > MAX_SAFE_INTEGER) {
17321         return [];
17322       }
17323       var index = MAX_ARRAY_LENGTH,
17324           length = nativeMin(n, MAX_ARRAY_LENGTH);
17325
17326       iteratee = getIteratee(iteratee);
17327       n -= MAX_ARRAY_LENGTH;
17328
17329       var result = baseTimes(length, iteratee);
17330       while (++index < n) {
17331         iteratee(index);
17332       }
17333       return result;
17334     }
17335
17336     /**
17337      * Converts `value` to a property path array.
17338      *
17339      * @static
17340      * @memberOf _
17341      * @since 4.0.0
17342      * @category Util
17343      * @param {*} value The value to convert.
17344      * @returns {Array} Returns the new property path array.
17345      * @example
17346      *
17347      * _.toPath('a.b.c');
17348      * // => ['a', 'b', 'c']
17349      *
17350      * _.toPath('a[0].b.c');
17351      * // => ['a', '0', 'b', 'c']
17352      */
17353     function toPath(value) {
17354       if (isArray(value)) {
17355         return arrayMap(value, toKey);
17356       }
17357       return isSymbol(value) ? [value] : copyArray(stringToPath(toString(value)));
17358     }
17359
17360     /**
17361      * Generates a unique ID. If `prefix` is given, the ID is appended to it.
17362      *
17363      * @static
17364      * @since 0.1.0
17365      * @memberOf _
17366      * @category Util
17367      * @param {string} [prefix=''] The value to prefix the ID with.
17368      * @returns {string} Returns the unique ID.
17369      * @example
17370      *
17371      * _.uniqueId('contact_');
17372      * // => 'contact_104'
17373      *
17374      * _.uniqueId();
17375      * // => '105'
17376      */
17377     function uniqueId(prefix) {
17378       var id = ++idCounter;
17379       return toString(prefix) + id;
17380     }
17381
17382     /*------------------------------------------------------------------------*/
17383
17384     /**
17385      * Adds two numbers.
17386      *
17387      * @static
17388      * @memberOf _
17389      * @since 3.4.0
17390      * @category Math
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.
17394      * @example
17395      *
17396      * _.add(6, 4);
17397      * // => 10
17398      */
17399     var add = createMathOperation(function(augend, addend) {
17400       return augend + addend;
17401     }, 0);
17402
17403     /**
17404      * Computes `number` rounded up to `precision`.
17405      *
17406      * @static
17407      * @memberOf _
17408      * @since 3.10.0
17409      * @category Math
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.
17413      * @example
17414      *
17415      * _.ceil(4.006);
17416      * // => 5
17417      *
17418      * _.ceil(6.004, 2);
17419      * // => 6.01
17420      *
17421      * _.ceil(6040, -2);
17422      * // => 6100
17423      */
17424     var ceil = createRound('ceil');
17425
17426     /**
17427      * Divide two numbers.
17428      *
17429      * @static
17430      * @memberOf _
17431      * @since 4.7.0
17432      * @category Math
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.
17436      * @example
17437      *
17438      * _.divide(6, 4);
17439      * // => 1.5
17440      */
17441     var divide = createMathOperation(function(dividend, divisor) {
17442       return dividend / divisor;
17443     }, 1);
17444
17445     /**
17446      * Computes `number` rounded down to `precision`.
17447      *
17448      * @static
17449      * @memberOf _
17450      * @since 3.10.0
17451      * @category Math
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.
17455      * @example
17456      *
17457      * _.floor(4.006);
17458      * // => 4
17459      *
17460      * _.floor(0.046, 2);
17461      * // => 0.04
17462      *
17463      * _.floor(4060, -2);
17464      * // => 4000
17465      */
17466     var floor = createRound('floor');
17467
17468     /**
17469      * Computes the maximum value of `array`. If `array` is empty or falsey,
17470      * `undefined` is returned.
17471      *
17472      * @static
17473      * @since 0.1.0
17474      * @memberOf _
17475      * @category Math
17476      * @param {Array} array The array to iterate over.
17477      * @returns {*} Returns the maximum value.
17478      * @example
17479      *
17480      * _.max([4, 2, 8, 6]);
17481      * // => 8
17482      *
17483      * _.max([]);
17484      * // => undefined
17485      */
17486     function max(array) {
17487       return (array && array.length)
17488         ? baseExtremum(array, identity, baseGt)
17489         : undefined;
17490     }
17491
17492     /**
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).
17496      *
17497      * @static
17498      * @memberOf _
17499      * @since 4.0.0
17500      * @category Math
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.
17504      * @example
17505      *
17506      * var objects = [{ 'n': 1 }, { 'n': 2 }];
17507      *
17508      * _.maxBy(objects, function(o) { return o.n; });
17509      * // => { 'n': 2 }
17510      *
17511      * // The `_.property` iteratee shorthand.
17512      * _.maxBy(objects, 'n');
17513      * // => { 'n': 2 }
17514      */
17515     function maxBy(array, iteratee) {
17516       return (array && array.length)
17517         ? baseExtremum(array, getIteratee(iteratee, 2), baseGt)
17518         : undefined;
17519     }
17520
17521     /**
17522      * Computes the mean of the values in `array`.
17523      *
17524      * @static
17525      * @memberOf _
17526      * @since 4.0.0
17527      * @category Math
17528      * @param {Array} array The array to iterate over.
17529      * @returns {number} Returns the mean.
17530      * @example
17531      *
17532      * _.mean([4, 2, 8, 6]);
17533      * // => 5
17534      */
17535     function mean(array) {
17536       return baseMean(array, identity);
17537     }
17538
17539     /**
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).
17543      *
17544      * @static
17545      * @memberOf _
17546      * @since 4.7.0
17547      * @category Math
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.
17551      * @example
17552      *
17553      * var objects = [{ 'n': 4 }, { 'n': 2 }, { 'n': 8 }, { 'n': 6 }];
17554      *
17555      * _.meanBy(objects, function(o) { return o.n; });
17556      * // => 5
17557      *
17558      * // The `_.property` iteratee shorthand.
17559      * _.meanBy(objects, 'n');
17560      * // => 5
17561      */
17562     function meanBy(array, iteratee) {
17563       return baseMean(array, getIteratee(iteratee, 2));
17564     }
17565
17566     /**
17567      * Computes the minimum value of `array`. If `array` is empty or falsey,
17568      * `undefined` is returned.
17569      *
17570      * @static
17571      * @since 0.1.0
17572      * @memberOf _
17573      * @category Math
17574      * @param {Array} array The array to iterate over.
17575      * @returns {*} Returns the minimum value.
17576      * @example
17577      *
17578      * _.min([4, 2, 8, 6]);
17579      * // => 2
17580      *
17581      * _.min([]);
17582      * // => undefined
17583      */
17584     function min(array) {
17585       return (array && array.length)
17586         ? baseExtremum(array, identity, baseLt)
17587         : undefined;
17588     }
17589
17590     /**
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).
17594      *
17595      * @static
17596      * @memberOf _
17597      * @since 4.0.0
17598      * @category Math
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.
17602      * @example
17603      *
17604      * var objects = [{ 'n': 1 }, { 'n': 2 }];
17605      *
17606      * _.minBy(objects, function(o) { return o.n; });
17607      * // => { 'n': 1 }
17608      *
17609      * // The `_.property` iteratee shorthand.
17610      * _.minBy(objects, 'n');
17611      * // => { 'n': 1 }
17612      */
17613     function minBy(array, iteratee) {
17614       return (array && array.length)
17615         ? baseExtremum(array, getIteratee(iteratee, 2), baseLt)
17616         : undefined;
17617     }
17618
17619     /**
17620      * Multiply two numbers.
17621      *
17622      * @static
17623      * @memberOf _
17624      * @since 4.7.0
17625      * @category Math
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.
17629      * @example
17630      *
17631      * _.multiply(6, 4);
17632      * // => 24
17633      */
17634     var multiply = createMathOperation(function(multiplier, multiplicand) {
17635       return multiplier * multiplicand;
17636     }, 1);
17637
17638     /**
17639      * Computes `number` rounded to `precision`.
17640      *
17641      * @static
17642      * @memberOf _
17643      * @since 3.10.0
17644      * @category Math
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.
17648      * @example
17649      *
17650      * _.round(4.006);
17651      * // => 4
17652      *
17653      * _.round(4.006, 2);
17654      * // => 4.01
17655      *
17656      * _.round(4060, -2);
17657      * // => 4100
17658      */
17659     var round = createRound('round');
17660
17661     /**
17662      * Subtract two numbers.
17663      *
17664      * @static
17665      * @memberOf _
17666      * @since 4.0.0
17667      * @category Math
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.
17671      * @example
17672      *
17673      * _.subtract(6, 4);
17674      * // => 2
17675      */
17676     var subtract = createMathOperation(function(minuend, subtrahend) {
17677       return minuend - subtrahend;
17678     }, 0);
17679
17680     /**
17681      * Computes the sum of the values in `array`.
17682      *
17683      * @static
17684      * @memberOf _
17685      * @since 3.4.0
17686      * @category Math
17687      * @param {Array} array The array to iterate over.
17688      * @returns {number} Returns the sum.
17689      * @example
17690      *
17691      * _.sum([4, 2, 8, 6]);
17692      * // => 20
17693      */
17694     function sum(array) {
17695       return (array && array.length)
17696         ? baseSum(array, identity)
17697         : 0;
17698     }
17699
17700     /**
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).
17704      *
17705      * @static
17706      * @memberOf _
17707      * @since 4.0.0
17708      * @category Math
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.
17712      * @example
17713      *
17714      * var objects = [{ 'n': 4 }, { 'n': 2 }, { 'n': 8 }, { 'n': 6 }];
17715      *
17716      * _.sumBy(objects, function(o) { return o.n; });
17717      * // => 20
17718      *
17719      * // The `_.property` iteratee shorthand.
17720      * _.sumBy(objects, 'n');
17721      * // => 20
17722      */
17723     function sumBy(array, iteratee) {
17724       return (array && array.length)
17725         ? baseSum(array, getIteratee(iteratee, 2))
17726         : 0;
17727     }
17728
17729     /*------------------------------------------------------------------------*/
17730
17731     // Add methods that return wrapped values in chain sequences.
17732     lodash.after = after;
17733     lodash.ary = ary;
17734     lodash.assign = assign;
17735     lodash.assignIn = assignIn;
17736     lodash.assignInWith = assignInWith;
17737     lodash.assignWith = assignWith;
17738     lodash.at = at;
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;
17793     lodash.map = map;
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;
17834     lodash.set = set;
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;
17848     lodash.tap = tap;
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;
17874     lodash.xor = xor;
17875     lodash.xorBy = xorBy;
17876     lodash.xorWith = xorWith;
17877     lodash.zip = zip;
17878     lodash.zipObject = zipObject;
17879     lodash.zipObjectDeep = zipObjectDeep;
17880     lodash.zipWith = zipWith;
17881
17882     // Add aliases.
17883     lodash.entries = toPairs;
17884     lodash.entriesIn = toPairsIn;
17885     lodash.extend = assignIn;
17886     lodash.extendWith = assignInWith;
17887
17888     // Add methods to `lodash.prototype`.
17889     mixin(lodash, lodash);
17890
17891     /*------------------------------------------------------------------------*/
17892
17893     // Add methods that return unwrapped values in chain sequences.
17894     lodash.add = add;
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;
17909     lodash.eq = eq;
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;
17926     lodash.get = get;
17927     lodash.gt = gt;
17928     lodash.gte = gte;
17929     lodash.has = has;
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;
17980     lodash.lt = lt;
17981     lodash.lte = lte;
17982     lodash.max = max;
17983     lodash.maxBy = maxBy;
17984     lodash.mean = mean;
17985     lodash.meanBy = meanBy;
17986     lodash.min = min;
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;
17994     lodash.nth = nth;
17995     lodash.noConflict = noConflict;
17996     lodash.noop = noop;
17997     lodash.now = now;
17998     lodash.pad = pad;
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;
18023     lodash.sum = sum;
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;
18043
18044     // Add aliases.
18045     lodash.each = forEach;
18046     lodash.eachRight = forEachRight;
18047     lodash.first = head;
18048
18049     mixin(lodash, (function() {
18050       var source = {};
18051       baseForOwn(lodash, function(func, methodName) {
18052         if (!hasOwnProperty.call(lodash.prototype, methodName)) {
18053           source[methodName] = func;
18054         }
18055       });
18056       return source;
18057     }()), { 'chain': false });
18058
18059     /*------------------------------------------------------------------------*/
18060
18061     /**
18062      * The semantic version number.
18063      *
18064      * @static
18065      * @memberOf _
18066      * @type {string}
18067      */
18068     lodash.VERSION = VERSION;
18069
18070     // Assign default placeholders.
18071     arrayEach(['bind', 'bindKey', 'curry', 'curryRight', 'partial', 'partialRight'], function(methodName) {
18072       lodash[methodName].placeholder = lodash;
18073     });
18074
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);
18079
18080         var result = (this.__filtered__ && !index)
18081           ? new LazyWrapper(this)
18082           : this.clone();
18083
18084         if (result.__filtered__) {
18085           result.__takeCount__ = nativeMin(n, result.__takeCount__);
18086         } else {
18087           result.__views__.push({
18088             'size': nativeMin(n, MAX_ARRAY_LENGTH),
18089             'type': methodName + (result.__dir__ < 0 ? 'Right' : '')
18090           });
18091         }
18092         return result;
18093       };
18094
18095       LazyWrapper.prototype[methodName + 'Right'] = function(n) {
18096         return this.reverse()[methodName](n).reverse();
18097       };
18098     });
18099
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;
18104
18105       LazyWrapper.prototype[methodName] = function(iteratee) {
18106         var result = this.clone();
18107         result.__iteratees__.push({
18108           'iteratee': getIteratee(iteratee, 3),
18109           'type': type
18110         });
18111         result.__filtered__ = result.__filtered__ || isFilter;
18112         return result;
18113       };
18114     });
18115
18116     // Add `LazyWrapper` methods for `_.head` and `_.last`.
18117     arrayEach(['head', 'last'], function(methodName, index) {
18118       var takeName = 'take' + (index ? 'Right' : '');
18119
18120       LazyWrapper.prototype[methodName] = function() {
18121         return this[takeName](1).value()[0];
18122       };
18123     });
18124
18125     // Add `LazyWrapper` methods for `_.initial` and `_.tail`.
18126     arrayEach(['initial', 'tail'], function(methodName, index) {
18127       var dropName = 'drop' + (index ? '' : 'Right');
18128
18129       LazyWrapper.prototype[methodName] = function() {
18130         return this.__filtered__ ? new LazyWrapper(this) : this[dropName](1);
18131       };
18132     });
18133
18134     LazyWrapper.prototype.compact = function() {
18135       return this.filter(identity);
18136     };
18137
18138     LazyWrapper.prototype.find = function(predicate) {
18139       return this.filter(predicate).head();
18140     };
18141
18142     LazyWrapper.prototype.findLast = function(predicate) {
18143       return this.reverse().find(predicate);
18144     };
18145
18146     LazyWrapper.prototype.invokeMap = baseRest(function(path, args) {
18147       if (typeof path == 'function') {
18148         return new LazyWrapper(this);
18149       }
18150       return this.map(function(value) {
18151         return baseInvoke(value, path, args);
18152       });
18153     });
18154
18155     LazyWrapper.prototype.reject = function(predicate) {
18156       return this.filter(negate(getIteratee(predicate)));
18157     };
18158
18159     LazyWrapper.prototype.slice = function(start, end) {
18160       start = toInteger(start);
18161
18162       var result = this;
18163       if (result.__filtered__ && (start > 0 || end < 0)) {
18164         return new LazyWrapper(result);
18165       }
18166       if (start < 0) {
18167         result = result.takeRight(-start);
18168       } else if (start) {
18169         result = result.drop(start);
18170       }
18171       if (end !== undefined) {
18172         end = toInteger(end);
18173         result = end < 0 ? result.dropRight(-end) : result.take(end - start);
18174       }
18175       return result;
18176     };
18177
18178     LazyWrapper.prototype.takeRightWhile = function(predicate) {
18179       return this.reverse().takeWhile(predicate).reverse();
18180     };
18181
18182     LazyWrapper.prototype.toArray = function() {
18183       return this.take(MAX_ARRAY_LENGTH);
18184     };
18185
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);
18192
18193       if (!lodashFunc) {
18194         return;
18195       }
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);
18202
18203         var interceptor = function(value) {
18204           var result = lodashFunc.apply(lodash, arrayPush([value], args));
18205           return (isTaker && chainAll) ? result[0] : result;
18206         };
18207
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;
18211         }
18212         var chainAll = this.__chain__,
18213             isHybrid = !!this.__actions__.length,
18214             isUnwrapped = retUnwrapped && !chainAll,
18215             onlyLazy = isLazy && !isHybrid;
18216
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);
18222         }
18223         if (isUnwrapped && onlyLazy) {
18224           return func.apply(this, args);
18225         }
18226         result = this.thru(interceptor);
18227         return isUnwrapped ? (isTaker ? result.value()[0] : result.value()) : result;
18228       };
18229     });
18230
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);
18236
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);
18242         }
18243         return this[chainName](function(value) {
18244           return func.apply(isArray(value) ? value : [], args);
18245         });
18246       };
18247     });
18248
18249     // Map minified method names to their real names.
18250     baseForOwn(LazyWrapper.prototype, function(func, methodName) {
18251       var lodashFunc = lodash[methodName];
18252       if (lodashFunc) {
18253         var key = lodashFunc.name + '';
18254         if (!hasOwnProperty.call(realNames, key)) {
18255           realNames[key] = [];
18256         }
18257         realNames[key].push({ 'name': methodName, 'func': lodashFunc });
18258       }
18259     });
18260
18261     realNames[createHybrid(undefined, WRAP_BIND_KEY_FLAG).name] = [{
18262       'name': 'wrapper',
18263       'func': undefined
18264     }];
18265
18266     // Add methods to `LazyWrapper`.
18267     LazyWrapper.prototype.clone = lazyClone;
18268     LazyWrapper.prototype.reverse = lazyReverse;
18269     LazyWrapper.prototype.value = lazyValue;
18270
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;
18279
18280     // Add lazy aliases.
18281     lodash.prototype.first = lodash.prototype.head;
18282
18283     if (symIterator) {
18284       lodash.prototype[symIterator] = wrapperToIterator;
18285     }
18286     return lodash;
18287   });
18288
18289   /*--------------------------------------------------------------------------*/
18290
18291   // Export lodash.
18292   var _ = runInContext();
18293
18294   // Some AMD build optimizers, like r.js, check for condition patterns like:
18295   if (true) {
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.
18300     root._ = _;
18301
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() {
18305       return _;
18306     }).call(exports, __webpack_require__, exports, module),
18307                 __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
18308   }
18309   // Check for `exports` after `define` in case a build optimizer adds it.
18310   else {}
18311 }.call(this));
18312
18313
18314 /***/ }),
18315
18316 /***/ "./src/client.ts":
18317 /*!***********************!*\
18318   !*** ./src/client.ts ***!
18319   \***********************/
18320 /***/ (function(__unused_webpack_module, exports, __webpack_require__) {
18321
18322 "use strict";
18323
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]; } };
18329     }
18330     Object.defineProperty(o, k2, desc);
18331 }) : (function(o, m, k, k2) {
18332     if (k2 === undefined) k2 = k;
18333     o[k2] = m[k];
18334 }));
18335 var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
18336     Object.defineProperty(o, "default", { enumerable: true, value: v });
18337 }) : function(o, v) {
18338     o["default"] = v;
18339 });
18340 var __importStar = (this && this.__importStar) || function (mod) {
18341     if (mod && mod.__esModule) return mod;
18342     var result = {};
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);
18345     return result;
18346 };
18347 var __importDefault = (this && this.__importDefault) || function (mod) {
18348     return (mod && mod.__esModule) ? mod : { "default": mod };
18349 };
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 const help_1 = __webpack_require__(/*! help */ "./src/help.ts");
18356 let outlineData = rawOutline;
18357 if (localStorage.getItem('activeOutline')) {
18358     const outlineId = localStorage.getItem('activeOutline');
18359     outlineData = JSON.parse(localStorage.getItem(outlineId));
18360 }
18361 const state = new Map();
18362 const outline = new outline_1.Outline(outlineData);
18363 outliner().innerHTML = outline.render();
18364 const cursor = new cursor_1.Cursor();
18365 cursor.set('.node');
18366 function outliner() {
18367     return document.querySelector('#outliner');
18368 }
18369 document.getElementById('display-help').addEventListener('click', e => {
18370     e.preventDefault();
18371     e.stopPropagation();
18372     (0, help_1.showHelp)();
18373 });
18374 keyboardjs_1.default.withContext('navigation', () => {
18375     keyboardjs_1.default.bind('j', e => {
18376         const sibling = cursor.get().nextElementSibling;
18377         if (sibling) {
18378             if (e.shiftKey) {
18379                 const res = outline.swapNodeWithNextSibling(cursor.getIdOfNode());
18380                 const html = outline.renderNode(res.parentNode);
18381                 if (res.parentNode.id === '000000') {
18382                     cursor.get().parentElement.innerHTML = html;
18383                 }
18384                 else {
18385                     cursor.get().parentElement.outerHTML = html;
18386                 }
18387                 cursor.set(`#id-${res.targetNode.id}`);
18388                 save();
18389             }
18390             else {
18391                 cursor.set(`#id-${sibling.getAttribute('data-id')}`);
18392             }
18393         }
18394     });
18395     keyboardjs_1.default.bind('shift + /', e => {
18396         (0, help_1.showHelp)();
18397     });
18398     keyboardjs_1.default.bind('k', e => {
18399         const sibling = cursor.get().previousElementSibling;
18400         if (sibling && !sibling.classList.contains('nodeContent')) {
18401             if (e.shiftKey) {
18402                 const res = outline.swapNodeWithPreviousSibling(cursor.getIdOfNode());
18403                 const html = outline.renderNode(res.parentNode);
18404                 if (res.parentNode.id === '000000') {
18405                     cursor.get().parentElement.innerHTML = html;
18406                 }
18407                 else {
18408                     cursor.get().parentElement.outerHTML = html;
18409                 }
18410                 cursor.set(`#id-${res.targetNode.id}`);
18411                 save();
18412             }
18413             else {
18414                 cursor.set(`#id-${sibling.getAttribute('data-id')}`);
18415             }
18416         }
18417     });
18418     keyboardjs_1.default.bind('l', e => {
18419         if (cursor.isNodeCollapsed()) {
18420             return;
18421         }
18422         if (e.shiftKey) {
18423             const res = outline.lowerNodeToChild(cursor.getIdOfNode());
18424             const html = outline.renderNode(res.oldParentNode);
18425             if (res.oldParentNode.id === '000000') {
18426                 cursor.get().parentElement.innerHTML = html;
18427             }
18428             else {
18429                 cursor.get().parentElement.outerHTML = html;
18430             }
18431             cursor.set(`#id-${res.targetNode.id}`);
18432         }
18433         else {
18434             const children = cursor.get().querySelector('.node');
18435             if (children) {
18436                 cursor.set(`#id-${children.getAttribute('data-id')}`);
18437             }
18438         }
18439     });
18440     keyboardjs_1.default.bind('h', e => {
18441         const parent = cursor.get().parentElement;
18442         if (parent && parent.classList.contains('node')) {
18443             if (e.shiftKey) {
18444                 if (outline.data.tree.children.map(n => n.id).includes(cursor.getIdOfNode())) {
18445                     return;
18446                 }
18447                 const res = outline.liftNodeToParent(cursor.getIdOfNode());
18448                 const html = outline.renderNode(res.parentNode);
18449                 if (res.parentNode.id === '000000') {
18450                     cursor.get().parentElement.parentElement.innerHTML = html;
18451                 }
18452                 else {
18453                     cursor.get().parentElement.parentElement.outerHTML = html;
18454                 }
18455                 cursor.set(`#id-${res.targetNode.id}`);
18456                 save();
18457             }
18458             else {
18459                 cursor.set(`#id-${parent.getAttribute('data-id')}`);
18460             }
18461         }
18462     });
18463     keyboardjs_1.default.bind('z', e => {
18464         if (cursor.isNodeExpanded()) {
18465             cursor.collapse();
18466             outline.fold(cursor.getIdOfNode());
18467         }
18468         else if (cursor.isNodeCollapsed()) {
18469             cursor.expand();
18470             outline.unfold(cursor.getIdOfNode());
18471         }
18472         save();
18473     });
18474     keyboardjs_1.default.bind('shift + 4', e => {
18475         e.preventDefault();
18476         cursor.get().classList.add('hidden-cursor');
18477         const contentNode = cursor.get().querySelector('.nodeContent');
18478         contentNode.innerHTML = outline.data.contentNodes[cursor.getIdOfNode()].content;
18479         contentNode.contentEditable = "true";
18480         const range = document.createRange();
18481         range.selectNodeContents(contentNode);
18482         range.collapse(false);
18483         const selection = window.getSelection();
18484         selection.removeAllRanges();
18485         selection.addRange(range);
18486         contentNode.focus();
18487         keyboardjs_1.default.setContext('editing');
18488     });
18489     keyboardjs_1.default.bind('i', e => {
18490         e.preventDefault();
18491         cursor.get().classList.add('hidden-cursor');
18492         const contentNode = cursor.get().querySelector('.nodeContent');
18493         contentNode.innerHTML = outline.data.contentNodes[cursor.getIdOfNode()].content;
18494         contentNode.contentEditable = "true";
18495         contentNode.focus();
18496         keyboardjs_1.default.setContext('editing');
18497     });
18498     keyboardjs_1.default.bind('tab', e => {
18499         e.preventDefault();
18500         const res = outline.createChildNode(cursor.getIdOfNode());
18501         const html = outline.renderNode(res.parentNode);
18502         cursor.get().outerHTML = html;
18503         cursor.set(`#id-${res.node.id}`);
18504         save();
18505     });
18506     keyboardjs_1.default.bind('enter', e => {
18507         if (e.shiftKey) {
18508             return;
18509         }
18510         e.preventDefault();
18511         e.preventRepeat();
18512         const res = outline.createSiblingNode(cursor.getIdOfNode());
18513         const html = outline.renderNode(res.parentNode);
18514         if (res.parentNode.id === '000000') {
18515             cursor.get().parentElement.innerHTML = html;
18516         }
18517         else {
18518             cursor.get().parentElement.outerHTML = html;
18519         }
18520         cursor.set(`#id-${res.node.id}`);
18521         save();
18522     });
18523     keyboardjs_1.default.bind('d', e => {
18524         if (!e.shiftKey) {
18525             return;
18526         }
18527         const res = outline.removeNode(cursor.getIdOfNode());
18528         const html = outline.renderNode(res.parentNode);
18529         const prevSibling = cursor.get().previousElementSibling;
18530         const nextSibling = cursor.get().nextElementSibling;
18531         if (res.parentNode.id === '000000') {
18532             cursor.get().parentElement.innerHTML = html;
18533         }
18534         else {
18535             cursor.get().parentElement.outerHTML = html;
18536         }
18537         if (prevSibling.getAttribute('data-id')) {
18538             cursor.set(`#id-${prevSibling.getAttribute('data-id')}`);
18539         }
18540         else if (nextSibling.getAttribute('data-id')) {
18541             cursor.set(`#id-${nextSibling.getAttribute('data-id')}`);
18542         }
18543         else {
18544             console.log(res.parentNode.id);
18545             cursor.set(`#id-${res.parentNode.id}`);
18546         }
18547         save();
18548     });
18549 });
18550 keyboardjs_1.default.withContext('editing', () => {
18551     keyboardjs_1.default.bind(['esc', 'enter'], e => {
18552         cursor.get().classList.remove('hidden-cursor');
18553         const contentNode = cursor.get().querySelector('.nodeContent');
18554         contentNode.contentEditable = "false";
18555         contentNode.blur();
18556         keyboardjs_1.default.setContext('navigation');
18557         outline.updateContent(cursor.getIdOfNode(), contentNode.innerHTML.trim());
18558         contentNode.innerHTML = outline.renderContent(cursor.getIdOfNode());
18559         save();
18560     });
18561 });
18562 keyboardjs_1.default.setContext('navigation');
18563 function saveImmediate() {
18564     localStorage.setItem(outline.data.id, JSON.stringify(outline.data));
18565     localStorage.setItem('activeOutline', outline.data.id);
18566     console.log('saved...', outline.data);
18567     state.delete('saveTimeout');
18568 }
18569 function save() {
18570     if (!state.has('saveTimeout')) {
18571         state.set('saveTimeout', setTimeout(saveImmediate, 2000));
18572     }
18573 }
18574 save();
18575
18576
18577 /***/ }),
18578
18579 /***/ "./src/cursor.ts":
18580 /*!***********************!*\
18581   !*** ./src/cursor.ts ***!
18582   \***********************/
18583 /***/ ((__unused_webpack_module, exports) => {
18584
18585 "use strict";
18586
18587 Object.defineProperty(exports, "__esModule", ({ value: true }));
18588 exports.Cursor = void 0;
18589 class Cursor {
18590     constructor() {
18591     }
18592     get() {
18593         return document.querySelector('.cursor');
18594     }
18595     getIdOfNode() {
18596         return this.get().getAttribute('data-id');
18597     }
18598     unset() {
18599         const el = this.get();
18600         if (el) {
18601             el.classList.remove('cursor');
18602         }
18603     }
18604     set(elementId) {
18605         this.unset();
18606         const el = document.querySelector(elementId);
18607         if (el) {
18608             el.classList.add('cursor');
18609             if (!this.isVisible(elementId)) {
18610                 el.scrollIntoView(true);
18611             }
18612         }
18613     }
18614     collapse() {
18615         this.get().classList.remove('expanded');
18616         this.get().classList.add('collapsed');
18617     }
18618     expand() {
18619         this.get().classList.remove('collapsed');
18620         this.get().classList.add('expanded');
18621     }
18622     isNodeCollapsed() {
18623         return this.get().classList.contains('collapsed');
18624     }
18625     isNodeExpanded() {
18626         return this.get().classList.contains('expanded');
18627     }
18628     isVisible(elementId) {
18629         const el = document.querySelector(elementId);
18630         var rect = el.getBoundingClientRect();
18631         return (rect.top >= 0 &&
18632             rect.left >= 0 &&
18633             rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) &&
18634             rect.right <= (window.innerWidth || document.documentElement.clientWidth));
18635     }
18636 }
18637 exports.Cursor = Cursor;
18638
18639
18640 /***/ }),
18641
18642 /***/ "./src/help.ts":
18643 /*!*********************!*\
18644   !*** ./src/help.ts ***!
18645   \*********************/
18646 /***/ (function(__unused_webpack_module, exports, __webpack_require__) {
18647
18648 "use strict";
18649
18650 var __importDefault = (this && this.__importDefault) || function (mod) {
18651     return (mod && mod.__esModule) ? mod : { "default": mod };
18652 };
18653 Object.defineProperty(exports, "__esModule", ({ value: true }));
18654 exports.showHelp = void 0;
18655 const keyboardjs_1 = __importDefault(__webpack_require__(/*! keyboardjs */ "./node_modules/keyboardjs/dist/keyboard.js"));
18656 const lodash_1 = __webpack_require__(/*! lodash */ "./node_modules/lodash/lodash.js");
18657 const keyboardCommands = {
18658     'h': 'Move the cursor to the Parent Element of the current node',
18659     'l': 'Move the cursor to the first Child Element of the current node',
18660     'j': 'Move the cursor to the next sibling of the current node',
18661     'k': 'Move the cursor to the previous sibling of the current node',
18662     'enter': 'Add a new node as a sibling to the current node',
18663     'tab': 'Add a new node as the child of the current node',
18664     'shift + j': 'Swap the current node with next sibling node',
18665     'shift + k': 'Swap the current node with the previous sibling node',
18666     'shift + h': 'Lift the current node to be a sibling of the parent node',
18667     'shift + l': 'Lower the current node to be a child of the previous sibling node',
18668     'shift + d': 'Delete the current node',
18669     'i': 'Enter "edit" mode, and place the cursor at the start of the editable content',
18670     '$': 'Enter "edit" mode, and place the cursor at the end of the editable content',
18671     'escape': 'Exit the current mode and return to "navigation" mode',
18672     '?': 'Display this help dialogue'
18673 };
18674 const modalHTML = `
18675   <div class="modal">
18676   <div class="modal-content">
18677     <h1>Help</h1>
18678     <table>
18679     <thead>
18680     <tr>
18681     <th>Key</th>
18682     <th>Action</th>
18683     </tr>
18684     </thead>
18685     <tbody>
18686     ${(0, lodash_1.map)(keyboardCommands, (text, key) => {
18687     return `
18688       <tr>
18689         <td>
18690           <kbd>${key}</kbd>
18691         </td>
18692         <td>
18693           ${text}
18694         </td>
18695       </tr>
18696       `;
18697 }).join("\n")}
18698     </tbody>
18699     </table>
18700   </div>
18701   </div>
18702 `;
18703 function showHelp() {
18704     document.querySelector('body').innerHTML += modalHTML;
18705     keyboardjs_1.default.setContext('help');
18706 }
18707 exports.showHelp = showHelp;
18708 keyboardjs_1.default.withContext('help', () => {
18709     keyboardjs_1.default.bind('escape', e => {
18710         document.querySelector('.modal').remove();
18711         keyboardjs_1.default.setContext('navigation');
18712     });
18713 });
18714
18715
18716 /***/ }),
18717
18718 /***/ "./src/outline.ts":
18719 /*!************************!*\
18720   !*** ./src/outline.ts ***!
18721   \************************/
18722 /***/ (function(__unused_webpack_module, exports, __webpack_require__) {
18723
18724 "use strict";
18725
18726 var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
18727     if (k2 === undefined) k2 = k;
18728     var desc = Object.getOwnPropertyDescriptor(m, k);
18729     if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
18730       desc = { enumerable: true, get: function() { return m[k]; } };
18731     }
18732     Object.defineProperty(o, k2, desc);
18733 }) : (function(o, m, k, k2) {
18734     if (k2 === undefined) k2 = k;
18735     o[k2] = m[k];
18736 }));
18737 var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
18738     Object.defineProperty(o, "default", { enumerable: true, value: v });
18739 }) : function(o, v) {
18740     o["default"] = v;
18741 });
18742 var __importStar = (this && this.__importStar) || function (mod) {
18743     if (mod && mod.__esModule) return mod;
18744     var result = {};
18745     if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
18746     __setModuleDefault(result, mod);
18747     return result;
18748 };
18749 Object.defineProperty(exports, "__esModule", ({ value: true }));
18750 exports.Outline = void 0;
18751 const _ = __importStar(__webpack_require__(/*! lodash */ "./node_modules/lodash/lodash.js"));
18752 const uuid_1 = __webpack_require__(/*! uuid */ "./node_modules/uuid/dist/commonjs-browser/index.js");
18753 const marked_1 = __webpack_require__(/*! marked */ "./node_modules/marked/lib/marked.cjs");
18754 ;
18755 class Outline {
18756     constructor(outlineData) {
18757         this.data = outlineData;
18758     }
18759     findNodeInTree(root, id, action, runState = false) {
18760         let run = runState;
18761         if (run) {
18762             return;
18763         }
18764         _.each(root.children, (childNode, idx) => {
18765             if (childNode.id === id) {
18766                 action(childNode, root);
18767                 run = true;
18768                 return false;
18769             }
18770             else if (childNode.children) {
18771                 this.findNodeInTree(childNode, id, action, run);
18772             }
18773         });
18774     }
18775     fold(nodeId) {
18776         this.findNodeInTree(this.data.tree, nodeId, item => {
18777             item.collapsed = true;
18778         });
18779     }
18780     unfold(nodeId) {
18781         this.findNodeInTree(this.data.tree, nodeId, item => {
18782             item.collapsed = true;
18783         });
18784     }
18785     flattenOutlineTreeChildren(tree) {
18786         return tree.children.map(node => node.id);
18787     }
18788     liftNodeToParent(nodeId) {
18789         let run = false;
18790         let targetNode, parentNode;
18791         this.findNodeInTree(this.data.tree, nodeId, (tNode, pNode) => {
18792             targetNode = tNode;
18793             this.findNodeInTree(this.data.tree, pNode.id, (originalParentNode, newParentNode) => {
18794                 ;
18795                 if (run) {
18796                     return;
18797                 }
18798                 parentNode = newParentNode;
18799                 run = true;
18800                 const flatId = newParentNode.children.map(n => n.id);
18801                 const originalNodePosition = originalParentNode.children.map(n => n.id).indexOf(targetNode.id);
18802                 const newNodePosition = flatId.indexOf(originalParentNode.id);
18803                 originalParentNode.children.splice(originalNodePosition, 1);
18804                 newParentNode.children.splice(newNodePosition + 1, 0, targetNode);
18805             });
18806         });
18807         return {
18808             targetNode,
18809             parentNode
18810         };
18811     }
18812     lowerNodeToChild(nodeId) {
18813         let run = false;
18814         let targetNode, newParentNode, oldParentNode;
18815         this.findNodeInTree(this.data.tree, nodeId, (tNode, pNode) => {
18816             if (run) {
18817                 return;
18818             }
18819             run = true;
18820             targetNode = tNode;
18821             let idList = pNode.children.map(n => n.id);
18822             if (idList.length === 1) {
18823                 return;
18824             }
18825             const position = idList.indexOf(targetNode.id);
18826             const prevSiblingPosition = position - 1;
18827             pNode.children[prevSiblingPosition].children.splice(0, 0, targetNode);
18828             pNode.children.splice(position, 1);
18829             newParentNode = pNode.children[prevSiblingPosition];
18830             oldParentNode = pNode;
18831         });
18832         return {
18833             targetNode,
18834             newParentNode,
18835             oldParentNode
18836         };
18837     }
18838     swapNodeWithNextSibling(nodeId) {
18839         let targetNode, parentNode;
18840         this.findNodeInTree(this.data.tree, nodeId, (tNode, pNode) => {
18841             targetNode = tNode;
18842             parentNode = pNode;
18843             const flatId = parentNode.children.map(n => n.id);
18844             const nodePosition = flatId.indexOf(targetNode.id);
18845             if (nodePosition === (flatId.length - 1)) {
18846                 return;
18847             }
18848             parentNode.children.splice(nodePosition, 1);
18849             parentNode.children.splice(nodePosition + 1, 0, targetNode);
18850         });
18851         return {
18852             targetNode,
18853             parentNode
18854         };
18855     }
18856     swapNodeWithPreviousSibling(nodeId) {
18857         let targetNode, parentNode;
18858         this.findNodeInTree(this.data.tree, nodeId, (tNode, pNode) => {
18859             targetNode = tNode;
18860             parentNode = pNode;
18861             const flatId = parentNode.children.map(n => n.id);
18862             const nodePosition = flatId.indexOf(targetNode.id);
18863             if (nodePosition === 0) {
18864                 return;
18865             }
18866             parentNode.children.splice(nodePosition, 1);
18867             parentNode.children.splice(nodePosition - 1, 0, targetNode);
18868         });
18869         return {
18870             targetNode,
18871             parentNode
18872         };
18873     }
18874     createSiblingNode(targetNode, nodeData) {
18875         const outlineNode = nodeData || {
18876             id: (0, uuid_1.v4)(),
18877             created: Date.now(),
18878             type: 'text',
18879             content: '---'
18880         };
18881         this.data.contentNodes[outlineNode.id] = outlineNode;
18882         let parentNode;
18883         this.findNodeInTree(this.data.tree, targetNode, (node, parent) => {
18884             const position = parent.children.map(n => n.id).indexOf(targetNode);
18885             parent.children.splice(position + 1, 0, {
18886                 id: outlineNode.id,
18887                 collapsed: false,
18888                 children: []
18889             });
18890             parentNode = parent;
18891         });
18892         return {
18893             node: outlineNode,
18894             parentNode
18895         };
18896     }
18897     createChildNode(currentNode, nodeId) {
18898         const node = nodeId ? this.data.contentNodes[nodeId] :
18899             {
18900                 id: (0, uuid_1.v4)(),
18901                 created: Date.now(),
18902                 type: 'text',
18903                 content: '---'
18904             };
18905         if (!nodeId) {
18906             this.data.contentNodes[node.id] = node;
18907         }
18908         let parentNode;
18909         this.findNodeInTree(this.data.tree, currentNode, (foundNode, parent) => {
18910             foundNode.children.unshift({
18911                 id: node.id,
18912                 children: [],
18913                 collapsed: false
18914             });
18915             parentNode = foundNode;
18916         });
18917         return {
18918             node,
18919             parentNode
18920         };
18921     }
18922     removeNode(nodeId) {
18923         let run = false;
18924         let removedNode, parentNode;
18925         this.findNodeInTree(this.data.tree, nodeId, (tNode, pNode) => {
18926             if (run) {
18927                 return;
18928             }
18929             run = true;
18930             removedNode = tNode;
18931             parentNode = pNode;
18932             let position = parentNode.children.map(n => n.id).indexOf(tNode.id);
18933             parentNode.children.splice(position, 1);
18934         });
18935         return {
18936             removedNode,
18937             parentNode
18938         };
18939     }
18940     updateContent(id, content) {
18941         if (!this.data.contentNodes[id]) {
18942             throw new Error('Invalid node');
18943         }
18944         this.data.contentNodes[id].content = content;
18945     }
18946     renderContent(nodeId) {
18947         let node = this.data.contentNodes[nodeId];
18948         let content;
18949         switch (node.type) {
18950             case 'text':
18951                 content = marked_1.marked.parse(node.content);
18952                 break;
18953             default:
18954                 content = node.content;
18955                 break;
18956         }
18957         return content;
18958     }
18959     renderNode(node) {
18960         if (node.id === '000000') {
18961             return this.render();
18962         }
18963         const collapse = node.collapsed ? 'collapsed' : 'expanded';
18964         const content = this.data.contentNodes[node.id] || {
18965             id: node.id,
18966             created: Date.now(),
18967             type: 'text',
18968             content: ''
18969         };
18970         let html = `<div class="node ${collapse}" data-id="${node.id}" id="id-${node.id}">
18971     <div class="nodeContent" data-type="${content.type}">
18972       ${this.renderContent(node.id)}
18973     </div>
18974     ${node.children.length ? _.map(node.children, this.renderNode.bind(this)).join("\n") : ''}
18975     </div>`;
18976         return html;
18977     }
18978     render() {
18979         return _.map(this.data.tree.children, this.renderNode.bind(this)).join("\n");
18980     }
18981 }
18982 exports.Outline = Outline;
18983
18984
18985 /***/ }),
18986
18987 /***/ "./node_modules/uuid/dist/commonjs-browser/index.js":
18988 /*!**********************************************************!*\
18989   !*** ./node_modules/uuid/dist/commonjs-browser/index.js ***!
18990   \**********************************************************/
18991 /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
18992
18993 "use strict";
18994
18995
18996 Object.defineProperty(exports, "__esModule", ({
18997   value: true
18998 }));
18999 Object.defineProperty(exports, "NIL", ({
19000   enumerable: true,
19001   get: function get() {
19002     return _nil.default;
19003   }
19004 }));
19005 Object.defineProperty(exports, "parse", ({
19006   enumerable: true,
19007   get: function get() {
19008     return _parse.default;
19009   }
19010 }));
19011 Object.defineProperty(exports, "stringify", ({
19012   enumerable: true,
19013   get: function get() {
19014     return _stringify.default;
19015   }
19016 }));
19017 Object.defineProperty(exports, "v1", ({
19018   enumerable: true,
19019   get: function get() {
19020     return _v.default;
19021   }
19022 }));
19023 Object.defineProperty(exports, "v3", ({
19024   enumerable: true,
19025   get: function get() {
19026     return _v2.default;
19027   }
19028 }));
19029 Object.defineProperty(exports, "v4", ({
19030   enumerable: true,
19031   get: function get() {
19032     return _v3.default;
19033   }
19034 }));
19035 Object.defineProperty(exports, "v5", ({
19036   enumerable: true,
19037   get: function get() {
19038     return _v4.default;
19039   }
19040 }));
19041 Object.defineProperty(exports, "validate", ({
19042   enumerable: true,
19043   get: function get() {
19044     return _validate.default;
19045   }
19046 }));
19047 Object.defineProperty(exports, "version", ({
19048   enumerable: true,
19049   get: function get() {
19050     return _version.default;
19051   }
19052 }));
19053
19054 var _v = _interopRequireDefault(__webpack_require__(/*! ./v1.js */ "./node_modules/uuid/dist/commonjs-browser/v1.js"));
19055
19056 var _v2 = _interopRequireDefault(__webpack_require__(/*! ./v3.js */ "./node_modules/uuid/dist/commonjs-browser/v3.js"));
19057
19058 var _v3 = _interopRequireDefault(__webpack_require__(/*! ./v4.js */ "./node_modules/uuid/dist/commonjs-browser/v4.js"));
19059
19060 var _v4 = _interopRequireDefault(__webpack_require__(/*! ./v5.js */ "./node_modules/uuid/dist/commonjs-browser/v5.js"));
19061
19062 var _nil = _interopRequireDefault(__webpack_require__(/*! ./nil.js */ "./node_modules/uuid/dist/commonjs-browser/nil.js"));
19063
19064 var _version = _interopRequireDefault(__webpack_require__(/*! ./version.js */ "./node_modules/uuid/dist/commonjs-browser/version.js"));
19065
19066 var _validate = _interopRequireDefault(__webpack_require__(/*! ./validate.js */ "./node_modules/uuid/dist/commonjs-browser/validate.js"));
19067
19068 var _stringify = _interopRequireDefault(__webpack_require__(/*! ./stringify.js */ "./node_modules/uuid/dist/commonjs-browser/stringify.js"));
19069
19070 var _parse = _interopRequireDefault(__webpack_require__(/*! ./parse.js */ "./node_modules/uuid/dist/commonjs-browser/parse.js"));
19071
19072 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
19073
19074 /***/ }),
19075
19076 /***/ "./node_modules/uuid/dist/commonjs-browser/md5.js":
19077 /*!********************************************************!*\
19078   !*** ./node_modules/uuid/dist/commonjs-browser/md5.js ***!
19079   \********************************************************/
19080 /***/ ((__unused_webpack_module, exports) => {
19081
19082 "use strict";
19083
19084
19085 Object.defineProperty(exports, "__esModule", ({
19086   value: true
19087 }));
19088 exports["default"] = void 0;
19089
19090 /*
19091  * Browser-compatible JavaScript MD5
19092  *
19093  * Modification of JavaScript MD5
19094  * https://github.com/blueimp/JavaScript-MD5
19095  *
19096  * Copyright 2011, Sebastian Tschan
19097  * https://blueimp.net
19098  *
19099  * Licensed under the MIT license:
19100  * https://opensource.org/licenses/MIT
19101  *
19102  * Based on
19103  * A JavaScript implementation of the RSA Data Security, Inc. MD5 Message
19104  * Digest Algorithm, as defined in RFC 1321.
19105  * Version 2.2 Copyright (C) Paul Johnston 1999 - 2009
19106  * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
19107  * Distributed under the BSD License
19108  * See http://pajhome.org.uk/crypt/md5 for more info.
19109  */
19110 function md5(bytes) {
19111   if (typeof bytes === 'string') {
19112     const msg = unescape(encodeURIComponent(bytes)); // UTF8 escape
19113
19114     bytes = new Uint8Array(msg.length);
19115
19116     for (let i = 0; i < msg.length; ++i) {
19117       bytes[i] = msg.charCodeAt(i);
19118     }
19119   }
19120
19121   return md5ToHexEncodedArray(wordsToMd5(bytesToWords(bytes), bytes.length * 8));
19122 }
19123 /*
19124  * Convert an array of little-endian words to an array of bytes
19125  */
19126
19127
19128 function md5ToHexEncodedArray(input) {
19129   const output = [];
19130   const length32 = input.length * 32;
19131   const hexTab = '0123456789abcdef';
19132
19133   for (let i = 0; i < length32; i += 8) {
19134     const x = input[i >> 5] >>> i % 32 & 0xff;
19135     const hex = parseInt(hexTab.charAt(x >>> 4 & 0x0f) + hexTab.charAt(x & 0x0f), 16);
19136     output.push(hex);
19137   }
19138
19139   return output;
19140 }
19141 /**
19142  * Calculate output length with padding and bit length
19143  */
19144
19145
19146 function getOutputLength(inputLength8) {
19147   return (inputLength8 + 64 >>> 9 << 4) + 14 + 1;
19148 }
19149 /*
19150  * Calculate the MD5 of an array of little-endian words, and a bit length.
19151  */
19152
19153
19154 function wordsToMd5(x, len) {
19155   /* append padding */
19156   x[len >> 5] |= 0x80 << len % 32;
19157   x[getOutputLength(len) - 1] = len;
19158   let a = 1732584193;
19159   let b = -271733879;
19160   let c = -1732584194;
19161   let d = 271733878;
19162
19163   for (let i = 0; i < x.length; i += 16) {
19164     const olda = a;
19165     const oldb = b;
19166     const oldc = c;
19167     const oldd = d;
19168     a = md5ff(a, b, c, d, x[i], 7, -680876936);
19169     d = md5ff(d, a, b, c, x[i + 1], 12, -389564586);
19170     c = md5ff(c, d, a, b, x[i + 2], 17, 606105819);
19171     b = md5ff(b, c, d, a, x[i + 3], 22, -1044525330);
19172     a = md5ff(a, b, c, d, x[i + 4], 7, -176418897);
19173     d = md5ff(d, a, b, c, x[i + 5], 12, 1200080426);
19174     c = md5ff(c, d, a, b, x[i + 6], 17, -1473231341);
19175     b = md5ff(b, c, d, a, x[i + 7], 22, -45705983);
19176     a = md5ff(a, b, c, d, x[i + 8], 7, 1770035416);
19177     d = md5ff(d, a, b, c, x[i + 9], 12, -1958414417);
19178     c = md5ff(c, d, a, b, x[i + 10], 17, -42063);
19179     b = md5ff(b, c, d, a, x[i + 11], 22, -1990404162);
19180     a = md5ff(a, b, c, d, x[i + 12], 7, 1804603682);
19181     d = md5ff(d, a, b, c, x[i + 13], 12, -40341101);
19182     c = md5ff(c, d, a, b, x[i + 14], 17, -1502002290);
19183     b = md5ff(b, c, d, a, x[i + 15], 22, 1236535329);
19184     a = md5gg(a, b, c, d, x[i + 1], 5, -165796510);
19185     d = md5gg(d, a, b, c, x[i + 6], 9, -1069501632);
19186     c = md5gg(c, d, a, b, x[i + 11], 14, 643717713);
19187     b = md5gg(b, c, d, a, x[i], 20, -373897302);
19188     a = md5gg(a, b, c, d, x[i + 5], 5, -701558691);
19189     d = md5gg(d, a, b, c, x[i + 10], 9, 38016083);
19190     c = md5gg(c, d, a, b, x[i + 15], 14, -660478335);
19191     b = md5gg(b, c, d, a, x[i + 4], 20, -405537848);
19192     a = md5gg(a, b, c, d, x[i + 9], 5, 568446438);
19193     d = md5gg(d, a, b, c, x[i + 14], 9, -1019803690);
19194     c = md5gg(c, d, a, b, x[i + 3], 14, -187363961);
19195     b = md5gg(b, c, d, a, x[i + 8], 20, 1163531501);
19196     a = md5gg(a, b, c, d, x[i + 13], 5, -1444681467);
19197     d = md5gg(d, a, b, c, x[i + 2], 9, -51403784);
19198     c = md5gg(c, d, a, b, x[i + 7], 14, 1735328473);
19199     b = md5gg(b, c, d, a, x[i + 12], 20, -1926607734);
19200     a = md5hh(a, b, c, d, x[i + 5], 4, -378558);
19201     d = md5hh(d, a, b, c, x[i + 8], 11, -2022574463);
19202     c = md5hh(c, d, a, b, x[i + 11], 16, 1839030562);
19203     b = md5hh(b, c, d, a, x[i + 14], 23, -35309556);
19204     a = md5hh(a, b, c, d, x[i + 1], 4, -1530992060);
19205     d = md5hh(d, a, b, c, x[i + 4], 11, 1272893353);
19206     c = md5hh(c, d, a, b, x[i + 7], 16, -155497632);
19207     b = md5hh(b, c, d, a, x[i + 10], 23, -1094730640);
19208     a = md5hh(a, b, c, d, x[i + 13], 4, 681279174);
19209     d = md5hh(d, a, b, c, x[i], 11, -358537222);
19210     c = md5hh(c, d, a, b, x[i + 3], 16, -722521979);
19211     b = md5hh(b, c, d, a, x[i + 6], 23, 76029189);
19212     a = md5hh(a, b, c, d, x[i + 9], 4, -640364487);
19213     d = md5hh(d, a, b, c, x[i + 12], 11, -421815835);
19214     c = md5hh(c, d, a, b, x[i + 15], 16, 530742520);
19215     b = md5hh(b, c, d, a, x[i + 2], 23, -995338651);
19216     a = md5ii(a, b, c, d, x[i], 6, -198630844);
19217     d = md5ii(d, a, b, c, x[i + 7], 10, 1126891415);
19218     c = md5ii(c, d, a, b, x[i + 14], 15, -1416354905);
19219     b = md5ii(b, c, d, a, x[i + 5], 21, -57434055);
19220     a = md5ii(a, b, c, d, x[i + 12], 6, 1700485571);
19221     d = md5ii(d, a, b, c, x[i + 3], 10, -1894986606);
19222     c = md5ii(c, d, a, b, x[i + 10], 15, -1051523);
19223     b = md5ii(b, c, d, a, x[i + 1], 21, -2054922799);
19224     a = md5ii(a, b, c, d, x[i + 8], 6, 1873313359);
19225     d = md5ii(d, a, b, c, x[i + 15], 10, -30611744);
19226     c = md5ii(c, d, a, b, x[i + 6], 15, -1560198380);
19227     b = md5ii(b, c, d, a, x[i + 13], 21, 1309151649);
19228     a = md5ii(a, b, c, d, x[i + 4], 6, -145523070);
19229     d = md5ii(d, a, b, c, x[i + 11], 10, -1120210379);
19230     c = md5ii(c, d, a, b, x[i + 2], 15, 718787259);
19231     b = md5ii(b, c, d, a, x[i + 9], 21, -343485551);
19232     a = safeAdd(a, olda);
19233     b = safeAdd(b, oldb);
19234     c = safeAdd(c, oldc);
19235     d = safeAdd(d, oldd);
19236   }
19237
19238   return [a, b, c, d];
19239 }
19240 /*
19241  * Convert an array bytes to an array of little-endian words
19242  * Characters >255 have their high-byte silently ignored.
19243  */
19244
19245
19246 function bytesToWords(input) {
19247   if (input.length === 0) {
19248     return [];
19249   }
19250
19251   const length8 = input.length * 8;
19252   const output = new Uint32Array(getOutputLength(length8));
19253
19254   for (let i = 0; i < length8; i += 8) {
19255     output[i >> 5] |= (input[i / 8] & 0xff) << i % 32;
19256   }
19257
19258   return output;
19259 }
19260 /*
19261  * Add integers, wrapping at 2^32. This uses 16-bit operations internally
19262  * to work around bugs in some JS interpreters.
19263  */
19264
19265
19266 function safeAdd(x, y) {
19267   const lsw = (x & 0xffff) + (y & 0xffff);
19268   const msw = (x >> 16) + (y >> 16) + (lsw >> 16);
19269   return msw << 16 | lsw & 0xffff;
19270 }
19271 /*
19272  * Bitwise rotate a 32-bit number to the left.
19273  */
19274
19275
19276 function bitRotateLeft(num, cnt) {
19277   return num << cnt | num >>> 32 - cnt;
19278 }
19279 /*
19280  * These functions implement the four basic operations the algorithm uses.
19281  */
19282
19283
19284 function md5cmn(q, a, b, x, s, t) {
19285   return safeAdd(bitRotateLeft(safeAdd(safeAdd(a, q), safeAdd(x, t)), s), b);
19286 }
19287
19288 function md5ff(a, b, c, d, x, s, t) {
19289   return md5cmn(b & c | ~b & d, a, b, x, s, t);
19290 }
19291
19292 function md5gg(a, b, c, d, x, s, t) {
19293   return md5cmn(b & d | c & ~d, a, b, x, s, t);
19294 }
19295
19296 function md5hh(a, b, c, d, x, s, t) {
19297   return md5cmn(b ^ c ^ d, a, b, x, s, t);
19298 }
19299
19300 function md5ii(a, b, c, d, x, s, t) {
19301   return md5cmn(c ^ (b | ~d), a, b, x, s, t);
19302 }
19303
19304 var _default = md5;
19305 exports["default"] = _default;
19306
19307 /***/ }),
19308
19309 /***/ "./node_modules/uuid/dist/commonjs-browser/native.js":
19310 /*!***********************************************************!*\
19311   !*** ./node_modules/uuid/dist/commonjs-browser/native.js ***!
19312   \***********************************************************/
19313 /***/ ((__unused_webpack_module, exports) => {
19314
19315 "use strict";
19316
19317
19318 Object.defineProperty(exports, "__esModule", ({
19319   value: true
19320 }));
19321 exports["default"] = void 0;
19322 const randomUUID = typeof crypto !== 'undefined' && crypto.randomUUID && crypto.randomUUID.bind(crypto);
19323 var _default = {
19324   randomUUID
19325 };
19326 exports["default"] = _default;
19327
19328 /***/ }),
19329
19330 /***/ "./node_modules/uuid/dist/commonjs-browser/nil.js":
19331 /*!********************************************************!*\
19332   !*** ./node_modules/uuid/dist/commonjs-browser/nil.js ***!
19333   \********************************************************/
19334 /***/ ((__unused_webpack_module, exports) => {
19335
19336 "use strict";
19337
19338
19339 Object.defineProperty(exports, "__esModule", ({
19340   value: true
19341 }));
19342 exports["default"] = void 0;
19343 var _default = '00000000-0000-0000-0000-000000000000';
19344 exports["default"] = _default;
19345
19346 /***/ }),
19347
19348 /***/ "./node_modules/uuid/dist/commonjs-browser/parse.js":
19349 /*!**********************************************************!*\
19350   !*** ./node_modules/uuid/dist/commonjs-browser/parse.js ***!
19351   \**********************************************************/
19352 /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
19353
19354 "use strict";
19355
19356
19357 Object.defineProperty(exports, "__esModule", ({
19358   value: true
19359 }));
19360 exports["default"] = void 0;
19361
19362 var _validate = _interopRequireDefault(__webpack_require__(/*! ./validate.js */ "./node_modules/uuid/dist/commonjs-browser/validate.js"));
19363
19364 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
19365
19366 function parse(uuid) {
19367   if (!(0, _validate.default)(uuid)) {
19368     throw TypeError('Invalid UUID');
19369   }
19370
19371   let v;
19372   const arr = new Uint8Array(16); // Parse ########-....-....-....-............
19373
19374   arr[0] = (v = parseInt(uuid.slice(0, 8), 16)) >>> 24;
19375   arr[1] = v >>> 16 & 0xff;
19376   arr[2] = v >>> 8 & 0xff;
19377   arr[3] = v & 0xff; // Parse ........-####-....-....-............
19378
19379   arr[4] = (v = parseInt(uuid.slice(9, 13), 16)) >>> 8;
19380   arr[5] = v & 0xff; // Parse ........-....-####-....-............
19381
19382   arr[6] = (v = parseInt(uuid.slice(14, 18), 16)) >>> 8;
19383   arr[7] = v & 0xff; // Parse ........-....-....-####-............
19384
19385   arr[8] = (v = parseInt(uuid.slice(19, 23), 16)) >>> 8;
19386   arr[9] = v & 0xff; // Parse ........-....-....-....-############
19387   // (Use "/" to avoid 32-bit truncation when bit-shifting high-order bytes)
19388
19389   arr[10] = (v = parseInt(uuid.slice(24, 36), 16)) / 0x10000000000 & 0xff;
19390   arr[11] = v / 0x100000000 & 0xff;
19391   arr[12] = v >>> 24 & 0xff;
19392   arr[13] = v >>> 16 & 0xff;
19393   arr[14] = v >>> 8 & 0xff;
19394   arr[15] = v & 0xff;
19395   return arr;
19396 }
19397
19398 var _default = parse;
19399 exports["default"] = _default;
19400
19401 /***/ }),
19402
19403 /***/ "./node_modules/uuid/dist/commonjs-browser/regex.js":
19404 /*!**********************************************************!*\
19405   !*** ./node_modules/uuid/dist/commonjs-browser/regex.js ***!
19406   \**********************************************************/
19407 /***/ ((__unused_webpack_module, exports) => {
19408
19409 "use strict";
19410
19411
19412 Object.defineProperty(exports, "__esModule", ({
19413   value: true
19414 }));
19415 exports["default"] = void 0;
19416 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;
19417 exports["default"] = _default;
19418
19419 /***/ }),
19420
19421 /***/ "./node_modules/uuid/dist/commonjs-browser/rng.js":
19422 /*!********************************************************!*\
19423   !*** ./node_modules/uuid/dist/commonjs-browser/rng.js ***!
19424   \********************************************************/
19425 /***/ ((__unused_webpack_module, exports) => {
19426
19427 "use strict";
19428
19429
19430 Object.defineProperty(exports, "__esModule", ({
19431   value: true
19432 }));
19433 exports["default"] = rng;
19434 // Unique ID creation requires a high quality random # generator. In the browser we therefore
19435 // require the crypto API and do not support built-in fallback to lower quality random number
19436 // generators (like Math.random()).
19437 let getRandomValues;
19438 const rnds8 = new Uint8Array(16);
19439
19440 function rng() {
19441   // lazy load so that environments that need to polyfill have a chance to do so
19442   if (!getRandomValues) {
19443     // getRandomValues needs to be invoked in a context where "this" is a Crypto implementation.
19444     getRandomValues = typeof crypto !== 'undefined' && crypto.getRandomValues && crypto.getRandomValues.bind(crypto);
19445
19446     if (!getRandomValues) {
19447       throw new Error('crypto.getRandomValues() not supported. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported');
19448     }
19449   }
19450
19451   return getRandomValues(rnds8);
19452 }
19453
19454 /***/ }),
19455
19456 /***/ "./node_modules/uuid/dist/commonjs-browser/sha1.js":
19457 /*!*********************************************************!*\
19458   !*** ./node_modules/uuid/dist/commonjs-browser/sha1.js ***!
19459   \*********************************************************/
19460 /***/ ((__unused_webpack_module, exports) => {
19461
19462 "use strict";
19463
19464
19465 Object.defineProperty(exports, "__esModule", ({
19466   value: true
19467 }));
19468 exports["default"] = void 0;
19469
19470 // Adapted from Chris Veness' SHA1 code at
19471 // http://www.movable-type.co.uk/scripts/sha1.html
19472 function f(s, x, y, z) {
19473   switch (s) {
19474     case 0:
19475       return x & y ^ ~x & z;
19476
19477     case 1:
19478       return x ^ y ^ z;
19479
19480     case 2:
19481       return x & y ^ x & z ^ y & z;
19482
19483     case 3:
19484       return x ^ y ^ z;
19485   }
19486 }
19487
19488 function ROTL(x, n) {
19489   return x << n | x >>> 32 - n;
19490 }
19491
19492 function sha1(bytes) {
19493   const K = [0x5a827999, 0x6ed9eba1, 0x8f1bbcdc, 0xca62c1d6];
19494   const H = [0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0];
19495
19496   if (typeof bytes === 'string') {
19497     const msg = unescape(encodeURIComponent(bytes)); // UTF8 escape
19498
19499     bytes = [];
19500
19501     for (let i = 0; i < msg.length; ++i) {
19502       bytes.push(msg.charCodeAt(i));
19503     }
19504   } else if (!Array.isArray(bytes)) {
19505     // Convert Array-like to Array
19506     bytes = Array.prototype.slice.call(bytes);
19507   }
19508
19509   bytes.push(0x80);
19510   const l = bytes.length / 4 + 2;
19511   const N = Math.ceil(l / 16);
19512   const M = new Array(N);
19513
19514   for (let i = 0; i < N; ++i) {
19515     const arr = new Uint32Array(16);
19516
19517     for (let j = 0; j < 16; ++j) {
19518       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];
19519     }
19520
19521     M[i] = arr;
19522   }
19523
19524   M[N - 1][14] = (bytes.length - 1) * 8 / Math.pow(2, 32);
19525   M[N - 1][14] = Math.floor(M[N - 1][14]);
19526   M[N - 1][15] = (bytes.length - 1) * 8 & 0xffffffff;
19527
19528   for (let i = 0; i < N; ++i) {
19529     const W = new Uint32Array(80);
19530
19531     for (let t = 0; t < 16; ++t) {
19532       W[t] = M[i][t];
19533     }
19534
19535     for (let t = 16; t < 80; ++t) {
19536       W[t] = ROTL(W[t - 3] ^ W[t - 8] ^ W[t - 14] ^ W[t - 16], 1);
19537     }
19538
19539     let a = H[0];
19540     let b = H[1];
19541     let c = H[2];
19542     let d = H[3];
19543     let e = H[4];
19544
19545     for (let t = 0; t < 80; ++t) {
19546       const s = Math.floor(t / 20);
19547       const T = ROTL(a, 5) + f(s, b, c, d) + e + K[s] + W[t] >>> 0;
19548       e = d;
19549       d = c;
19550       c = ROTL(b, 30) >>> 0;
19551       b = a;
19552       a = T;
19553     }
19554
19555     H[0] = H[0] + a >>> 0;
19556     H[1] = H[1] + b >>> 0;
19557     H[2] = H[2] + c >>> 0;
19558     H[3] = H[3] + d >>> 0;
19559     H[4] = H[4] + e >>> 0;
19560   }
19561
19562   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];
19563 }
19564
19565 var _default = sha1;
19566 exports["default"] = _default;
19567
19568 /***/ }),
19569
19570 /***/ "./node_modules/uuid/dist/commonjs-browser/stringify.js":
19571 /*!**************************************************************!*\
19572   !*** ./node_modules/uuid/dist/commonjs-browser/stringify.js ***!
19573   \**************************************************************/
19574 /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
19575
19576 "use strict";
19577
19578
19579 Object.defineProperty(exports, "__esModule", ({
19580   value: true
19581 }));
19582 exports["default"] = void 0;
19583 exports.unsafeStringify = unsafeStringify;
19584
19585 var _validate = _interopRequireDefault(__webpack_require__(/*! ./validate.js */ "./node_modules/uuid/dist/commonjs-browser/validate.js"));
19586
19587 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
19588
19589 /**
19590  * Convert array of 16 byte values to UUID string format of the form:
19591  * XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
19592  */
19593 const byteToHex = [];
19594
19595 for (let i = 0; i < 256; ++i) {
19596   byteToHex.push((i + 0x100).toString(16).slice(1));
19597 }
19598
19599 function unsafeStringify(arr, offset = 0) {
19600   // Note: Be careful editing this code!  It's been tuned for performance
19601   // and works in ways you may not expect. See https://github.com/uuidjs/uuid/pull/434
19602   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();
19603 }
19604
19605 function stringify(arr, offset = 0) {
19606   const uuid = unsafeStringify(arr, offset); // Consistency check for valid UUID.  If this throws, it's likely due to one
19607   // of the following:
19608   // - One or more input array values don't map to a hex octet (leading to
19609   // "undefined" in the uuid)
19610   // - Invalid input values for the RFC `version` or `variant` fields
19611
19612   if (!(0, _validate.default)(uuid)) {
19613     throw TypeError('Stringified UUID is invalid');
19614   }
19615
19616   return uuid;
19617 }
19618
19619 var _default = stringify;
19620 exports["default"] = _default;
19621
19622 /***/ }),
19623
19624 /***/ "./node_modules/uuid/dist/commonjs-browser/v1.js":
19625 /*!*******************************************************!*\
19626   !*** ./node_modules/uuid/dist/commonjs-browser/v1.js ***!
19627   \*******************************************************/
19628 /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
19629
19630 "use strict";
19631
19632
19633 Object.defineProperty(exports, "__esModule", ({
19634   value: true
19635 }));
19636 exports["default"] = void 0;
19637
19638 var _rng = _interopRequireDefault(__webpack_require__(/*! ./rng.js */ "./node_modules/uuid/dist/commonjs-browser/rng.js"));
19639
19640 var _stringify = __webpack_require__(/*! ./stringify.js */ "./node_modules/uuid/dist/commonjs-browser/stringify.js");
19641
19642 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
19643
19644 // **`v1()` - Generate time-based UUID**
19645 //
19646 // Inspired by https://github.com/LiosK/UUID.js
19647 // and http://docs.python.org/library/uuid.html
19648 let _nodeId;
19649
19650 let _clockseq; // Previous uuid creation time
19651
19652
19653 let _lastMSecs = 0;
19654 let _lastNSecs = 0; // See https://github.com/uuidjs/uuid for API details
19655
19656 function v1(options, buf, offset) {
19657   let i = buf && offset || 0;
19658   const b = buf || new Array(16);
19659   options = options || {};
19660   let node = options.node || _nodeId;
19661   let clockseq = options.clockseq !== undefined ? options.clockseq : _clockseq; // node and clockseq need to be initialized to random values if they're not
19662   // specified.  We do this lazily to minimize issues related to insufficient
19663   // system entropy.  See #189
19664
19665   if (node == null || clockseq == null) {
19666     const seedBytes = options.random || (options.rng || _rng.default)();
19667
19668     if (node == null) {
19669       // Per 4.5, create and 48-bit node id, (47 random bits + multicast bit = 1)
19670       node = _nodeId = [seedBytes[0] | 0x01, seedBytes[1], seedBytes[2], seedBytes[3], seedBytes[4], seedBytes[5]];
19671     }
19672
19673     if (clockseq == null) {
19674       // Per 4.2.2, randomize (14 bit) clockseq
19675       clockseq = _clockseq = (seedBytes[6] << 8 | seedBytes[7]) & 0x3fff;
19676     }
19677   } // UUID timestamps are 100 nano-second units since the Gregorian epoch,
19678   // (1582-10-15 00:00).  JSNumbers aren't precise enough for this, so
19679   // time is handled internally as 'msecs' (integer milliseconds) and 'nsecs'
19680   // (100-nanoseconds offset from msecs) since unix epoch, 1970-01-01 00:00.
19681
19682
19683   let msecs = options.msecs !== undefined ? options.msecs : Date.now(); // Per 4.2.1.2, use count of uuid's generated during the current clock
19684   // cycle to simulate higher resolution clock
19685
19686   let nsecs = options.nsecs !== undefined ? options.nsecs : _lastNSecs + 1; // Time since last uuid creation (in msecs)
19687
19688   const dt = msecs - _lastMSecs + (nsecs - _lastNSecs) / 10000; // Per 4.2.1.2, Bump clockseq on clock regression
19689
19690   if (dt < 0 && options.clockseq === undefined) {
19691     clockseq = clockseq + 1 & 0x3fff;
19692   } // Reset nsecs if clock regresses (new clockseq) or we've moved onto a new
19693   // time interval
19694
19695
19696   if ((dt < 0 || msecs > _lastMSecs) && options.nsecs === undefined) {
19697     nsecs = 0;
19698   } // Per 4.2.1.2 Throw error if too many uuids are requested
19699
19700
19701   if (nsecs >= 10000) {
19702     throw new Error("uuid.v1(): Can't create more than 10M uuids/sec");
19703   }
19704
19705   _lastMSecs = msecs;
19706   _lastNSecs = nsecs;
19707   _clockseq = clockseq; // Per 4.1.4 - Convert from unix epoch to Gregorian epoch
19708
19709   msecs += 12219292800000; // `time_low`
19710
19711   const tl = ((msecs & 0xfffffff) * 10000 + nsecs) % 0x100000000;
19712   b[i++] = tl >>> 24 & 0xff;
19713   b[i++] = tl >>> 16 & 0xff;
19714   b[i++] = tl >>> 8 & 0xff;
19715   b[i++] = tl & 0xff; // `time_mid`
19716
19717   const tmh = msecs / 0x100000000 * 10000 & 0xfffffff;
19718   b[i++] = tmh >>> 8 & 0xff;
19719   b[i++] = tmh & 0xff; // `time_high_and_version`
19720
19721   b[i++] = tmh >>> 24 & 0xf | 0x10; // include version
19722
19723   b[i++] = tmh >>> 16 & 0xff; // `clock_seq_hi_and_reserved` (Per 4.2.2 - include variant)
19724
19725   b[i++] = clockseq >>> 8 | 0x80; // `clock_seq_low`
19726
19727   b[i++] = clockseq & 0xff; // `node`
19728
19729   for (let n = 0; n < 6; ++n) {
19730     b[i + n] = node[n];
19731   }
19732
19733   return buf || (0, _stringify.unsafeStringify)(b);
19734 }
19735
19736 var _default = v1;
19737 exports["default"] = _default;
19738
19739 /***/ }),
19740
19741 /***/ "./node_modules/uuid/dist/commonjs-browser/v3.js":
19742 /*!*******************************************************!*\
19743   !*** ./node_modules/uuid/dist/commonjs-browser/v3.js ***!
19744   \*******************************************************/
19745 /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
19746
19747 "use strict";
19748
19749
19750 Object.defineProperty(exports, "__esModule", ({
19751   value: true
19752 }));
19753 exports["default"] = void 0;
19754
19755 var _v = _interopRequireDefault(__webpack_require__(/*! ./v35.js */ "./node_modules/uuid/dist/commonjs-browser/v35.js"));
19756
19757 var _md = _interopRequireDefault(__webpack_require__(/*! ./md5.js */ "./node_modules/uuid/dist/commonjs-browser/md5.js"));
19758
19759 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
19760
19761 const v3 = (0, _v.default)('v3', 0x30, _md.default);
19762 var _default = v3;
19763 exports["default"] = _default;
19764
19765 /***/ }),
19766
19767 /***/ "./node_modules/uuid/dist/commonjs-browser/v35.js":
19768 /*!********************************************************!*\
19769   !*** ./node_modules/uuid/dist/commonjs-browser/v35.js ***!
19770   \********************************************************/
19771 /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
19772
19773 "use strict";
19774
19775
19776 Object.defineProperty(exports, "__esModule", ({
19777   value: true
19778 }));
19779 exports.URL = exports.DNS = void 0;
19780 exports["default"] = v35;
19781
19782 var _stringify = __webpack_require__(/*! ./stringify.js */ "./node_modules/uuid/dist/commonjs-browser/stringify.js");
19783
19784 var _parse = _interopRequireDefault(__webpack_require__(/*! ./parse.js */ "./node_modules/uuid/dist/commonjs-browser/parse.js"));
19785
19786 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
19787
19788 function stringToBytes(str) {
19789   str = unescape(encodeURIComponent(str)); // UTF8 escape
19790
19791   const bytes = [];
19792
19793   for (let i = 0; i < str.length; ++i) {
19794     bytes.push(str.charCodeAt(i));
19795   }
19796
19797   return bytes;
19798 }
19799
19800 const DNS = '6ba7b810-9dad-11d1-80b4-00c04fd430c8';
19801 exports.DNS = DNS;
19802 const URL = '6ba7b811-9dad-11d1-80b4-00c04fd430c8';
19803 exports.URL = URL;
19804
19805 function v35(name, version, hashfunc) {
19806   function generateUUID(value, namespace, buf, offset) {
19807     var _namespace;
19808
19809     if (typeof value === 'string') {
19810       value = stringToBytes(value);
19811     }
19812
19813     if (typeof namespace === 'string') {
19814       namespace = (0, _parse.default)(namespace);
19815     }
19816
19817     if (((_namespace = namespace) === null || _namespace === void 0 ? void 0 : _namespace.length) !== 16) {
19818       throw TypeError('Namespace must be array-like (16 iterable integer values, 0-255)');
19819     } // Compute hash of namespace and value, Per 4.3
19820     // Future: Use spread syntax when supported on all platforms, e.g. `bytes =
19821     // hashfunc([...namespace, ... value])`
19822
19823
19824     let bytes = new Uint8Array(16 + value.length);
19825     bytes.set(namespace);
19826     bytes.set(value, namespace.length);
19827     bytes = hashfunc(bytes);
19828     bytes[6] = bytes[6] & 0x0f | version;
19829     bytes[8] = bytes[8] & 0x3f | 0x80;
19830
19831     if (buf) {
19832       offset = offset || 0;
19833
19834       for (let i = 0; i < 16; ++i) {
19835         buf[offset + i] = bytes[i];
19836       }
19837
19838       return buf;
19839     }
19840
19841     return (0, _stringify.unsafeStringify)(bytes);
19842   } // Function#name is not settable on some platforms (#270)
19843
19844
19845   try {
19846     generateUUID.name = name; // eslint-disable-next-line no-empty
19847   } catch (err) {} // For CommonJS default export support
19848
19849
19850   generateUUID.DNS = DNS;
19851   generateUUID.URL = URL;
19852   return generateUUID;
19853 }
19854
19855 /***/ }),
19856
19857 /***/ "./node_modules/uuid/dist/commonjs-browser/v4.js":
19858 /*!*******************************************************!*\
19859   !*** ./node_modules/uuid/dist/commonjs-browser/v4.js ***!
19860   \*******************************************************/
19861 /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
19862
19863 "use strict";
19864
19865
19866 Object.defineProperty(exports, "__esModule", ({
19867   value: true
19868 }));
19869 exports["default"] = void 0;
19870
19871 var _native = _interopRequireDefault(__webpack_require__(/*! ./native.js */ "./node_modules/uuid/dist/commonjs-browser/native.js"));
19872
19873 var _rng = _interopRequireDefault(__webpack_require__(/*! ./rng.js */ "./node_modules/uuid/dist/commonjs-browser/rng.js"));
19874
19875 var _stringify = __webpack_require__(/*! ./stringify.js */ "./node_modules/uuid/dist/commonjs-browser/stringify.js");
19876
19877 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
19878
19879 function v4(options, buf, offset) {
19880   if (_native.default.randomUUID && !buf && !options) {
19881     return _native.default.randomUUID();
19882   }
19883
19884   options = options || {};
19885
19886   const rnds = options.random || (options.rng || _rng.default)(); // Per 4.4, set bits for version and `clock_seq_hi_and_reserved`
19887
19888
19889   rnds[6] = rnds[6] & 0x0f | 0x40;
19890   rnds[8] = rnds[8] & 0x3f | 0x80; // Copy bytes to buffer, if provided
19891
19892   if (buf) {
19893     offset = offset || 0;
19894
19895     for (let i = 0; i < 16; ++i) {
19896       buf[offset + i] = rnds[i];
19897     }
19898
19899     return buf;
19900   }
19901
19902   return (0, _stringify.unsafeStringify)(rnds);
19903 }
19904
19905 var _default = v4;
19906 exports["default"] = _default;
19907
19908 /***/ }),
19909
19910 /***/ "./node_modules/uuid/dist/commonjs-browser/v5.js":
19911 /*!*******************************************************!*\
19912   !*** ./node_modules/uuid/dist/commonjs-browser/v5.js ***!
19913   \*******************************************************/
19914 /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
19915
19916 "use strict";
19917
19918
19919 Object.defineProperty(exports, "__esModule", ({
19920   value: true
19921 }));
19922 exports["default"] = void 0;
19923
19924 var _v = _interopRequireDefault(__webpack_require__(/*! ./v35.js */ "./node_modules/uuid/dist/commonjs-browser/v35.js"));
19925
19926 var _sha = _interopRequireDefault(__webpack_require__(/*! ./sha1.js */ "./node_modules/uuid/dist/commonjs-browser/sha1.js"));
19927
19928 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
19929
19930 const v5 = (0, _v.default)('v5', 0x50, _sha.default);
19931 var _default = v5;
19932 exports["default"] = _default;
19933
19934 /***/ }),
19935
19936 /***/ "./node_modules/uuid/dist/commonjs-browser/validate.js":
19937 /*!*************************************************************!*\
19938   !*** ./node_modules/uuid/dist/commonjs-browser/validate.js ***!
19939   \*************************************************************/
19940 /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
19941
19942 "use strict";
19943
19944
19945 Object.defineProperty(exports, "__esModule", ({
19946   value: true
19947 }));
19948 exports["default"] = void 0;
19949
19950 var _regex = _interopRequireDefault(__webpack_require__(/*! ./regex.js */ "./node_modules/uuid/dist/commonjs-browser/regex.js"));
19951
19952 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
19953
19954 function validate(uuid) {
19955   return typeof uuid === 'string' && _regex.default.test(uuid);
19956 }
19957
19958 var _default = validate;
19959 exports["default"] = _default;
19960
19961 /***/ }),
19962
19963 /***/ "./node_modules/uuid/dist/commonjs-browser/version.js":
19964 /*!************************************************************!*\
19965   !*** ./node_modules/uuid/dist/commonjs-browser/version.js ***!
19966   \************************************************************/
19967 /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
19968
19969 "use strict";
19970
19971
19972 Object.defineProperty(exports, "__esModule", ({
19973   value: true
19974 }));
19975 exports["default"] = void 0;
19976
19977 var _validate = _interopRequireDefault(__webpack_require__(/*! ./validate.js */ "./node_modules/uuid/dist/commonjs-browser/validate.js"));
19978
19979 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
19980
19981 function version(uuid) {
19982   if (!(0, _validate.default)(uuid)) {
19983     throw TypeError('Invalid UUID');
19984   }
19985
19986   return parseInt(uuid.slice(14, 15), 16);
19987 }
19988
19989 var _default = version;
19990 exports["default"] = _default;
19991
19992 /***/ }),
19993
19994 /***/ "./node_modules/marked/lib/marked.cjs":
19995 /*!********************************************!*\
19996   !*** ./node_modules/marked/lib/marked.cjs ***!
19997   \********************************************/
19998 /***/ ((__unused_webpack_module, exports) => {
19999
20000 "use strict";
20001 /**
20002  * marked v4.2.12 - a markdown parser
20003  * Copyright (c) 2011-2023, Christopher Jeffrey. (MIT Licensed)
20004  * https://github.com/markedjs/marked
20005  */
20006
20007 /**
20008  * DO NOT EDIT THIS FILE
20009  * The code in this file is generated from files in ./src/
20010  */
20011
20012
20013
20014 function _defineProperties(target, props) {
20015   for (var i = 0; i < props.length; i++) {
20016     var descriptor = props[i];
20017     descriptor.enumerable = descriptor.enumerable || false;
20018     descriptor.configurable = true;
20019     if ("value" in descriptor) descriptor.writable = true;
20020     Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor);
20021   }
20022 }
20023 function _createClass(Constructor, protoProps, staticProps) {
20024   if (protoProps) _defineProperties(Constructor.prototype, protoProps);
20025   if (staticProps) _defineProperties(Constructor, staticProps);
20026   Object.defineProperty(Constructor, "prototype", {
20027     writable: false
20028   });
20029   return Constructor;
20030 }
20031 function _unsupportedIterableToArray(o, minLen) {
20032   if (!o) return;
20033   if (typeof o === "string") return _arrayLikeToArray(o, minLen);
20034   var n = Object.prototype.toString.call(o).slice(8, -1);
20035   if (n === "Object" && o.constructor) n = o.constructor.name;
20036   if (n === "Map" || n === "Set") return Array.from(o);
20037   if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen);
20038 }
20039 function _arrayLikeToArray(arr, len) {
20040   if (len == null || len > arr.length) len = arr.length;
20041   for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i];
20042   return arr2;
20043 }
20044 function _createForOfIteratorHelperLoose(o, allowArrayLike) {
20045   var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"];
20046   if (it) return (it = it.call(o)).next.bind(it);
20047   if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") {
20048     if (it) o = it;
20049     var i = 0;
20050     return function () {
20051       if (i >= o.length) return {
20052         done: true
20053       };
20054       return {
20055         done: false,
20056         value: o[i++]
20057       };
20058     };
20059   }
20060   throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
20061 }
20062 function _toPrimitive(input, hint) {
20063   if (typeof input !== "object" || input === null) return input;
20064   var prim = input[Symbol.toPrimitive];
20065   if (prim !== undefined) {
20066     var res = prim.call(input, hint || "default");
20067     if (typeof res !== "object") return res;
20068     throw new TypeError("@@toPrimitive must return a primitive value.");
20069   }
20070   return (hint === "string" ? String : Number)(input);
20071 }
20072 function _toPropertyKey(arg) {
20073   var key = _toPrimitive(arg, "string");
20074   return typeof key === "symbol" ? key : String(key);
20075 }
20076
20077 function getDefaults() {
20078   return {
20079     async: false,
20080     baseUrl: null,
20081     breaks: false,
20082     extensions: null,
20083     gfm: true,
20084     headerIds: true,
20085     headerPrefix: '',
20086     highlight: null,
20087     langPrefix: 'language-',
20088     mangle: true,
20089     pedantic: false,
20090     renderer: null,
20091     sanitize: false,
20092     sanitizer: null,
20093     silent: false,
20094     smartypants: false,
20095     tokenizer: null,
20096     walkTokens: null,
20097     xhtml: false
20098   };
20099 }
20100 exports.defaults = getDefaults();
20101 function changeDefaults(newDefaults) {
20102   exports.defaults = newDefaults;
20103 }
20104
20105 /**
20106  * Helpers
20107  */
20108 var escapeTest = /[&<>"']/;
20109 var escapeReplace = new RegExp(escapeTest.source, 'g');
20110 var escapeTestNoEncode = /[<>"']|&(?!(#\d{1,7}|#[Xx][a-fA-F0-9]{1,6}|\w+);)/;
20111 var escapeReplaceNoEncode = new RegExp(escapeTestNoEncode.source, 'g');
20112 var escapeReplacements = {
20113   '&': '&amp;',
20114   '<': '&lt;',
20115   '>': '&gt;',
20116   '"': '&quot;',
20117   "'": '&#39;'
20118 };
20119 var getEscapeReplacement = function getEscapeReplacement(ch) {
20120   return escapeReplacements[ch];
20121 };
20122 function escape(html, encode) {
20123   if (encode) {
20124     if (escapeTest.test(html)) {
20125       return html.replace(escapeReplace, getEscapeReplacement);
20126     }
20127   } else {
20128     if (escapeTestNoEncode.test(html)) {
20129       return html.replace(escapeReplaceNoEncode, getEscapeReplacement);
20130     }
20131   }
20132   return html;
20133 }
20134 var unescapeTest = /&(#(?:\d+)|(?:#x[0-9A-Fa-f]+)|(?:\w+));?/ig;
20135
20136 /**
20137  * @param {string} html
20138  */
20139 function unescape(html) {
20140   // explicitly match decimal, hex, and named HTML entities
20141   return html.replace(unescapeTest, function (_, n) {
20142     n = n.toLowerCase();
20143     if (n === 'colon') return ':';
20144     if (n.charAt(0) === '#') {
20145       return n.charAt(1) === 'x' ? String.fromCharCode(parseInt(n.substring(2), 16)) : String.fromCharCode(+n.substring(1));
20146     }
20147     return '';
20148   });
20149 }
20150 var caret = /(^|[^\[])\^/g;
20151
20152 /**
20153  * @param {string | RegExp} regex
20154  * @param {string} opt
20155  */
20156 function edit(regex, opt) {
20157   regex = typeof regex === 'string' ? regex : regex.source;
20158   opt = opt || '';
20159   var obj = {
20160     replace: function replace(name, val) {
20161       val = val.source || val;
20162       val = val.replace(caret, '$1');
20163       regex = regex.replace(name, val);
20164       return obj;
20165     },
20166     getRegex: function getRegex() {
20167       return new RegExp(regex, opt);
20168     }
20169   };
20170   return obj;
20171 }
20172 var nonWordAndColonTest = /[^\w:]/g;
20173 var originIndependentUrl = /^$|^[a-z][a-z0-9+.-]*:|^[?#]/i;
20174
20175 /**
20176  * @param {boolean} sanitize
20177  * @param {string} base
20178  * @param {string} href
20179  */
20180 function cleanUrl(sanitize, base, href) {
20181   if (sanitize) {
20182     var prot;
20183     try {
20184       prot = decodeURIComponent(unescape(href)).replace(nonWordAndColonTest, '').toLowerCase();
20185     } catch (e) {
20186       return null;
20187     }
20188     if (prot.indexOf('javascript:') === 0 || prot.indexOf('vbscript:') === 0 || prot.indexOf('data:') === 0) {
20189       return null;
20190     }
20191   }
20192   if (base && !originIndependentUrl.test(href)) {
20193     href = resolveUrl(base, href);
20194   }
20195   try {
20196     href = encodeURI(href).replace(/%25/g, '%');
20197   } catch (e) {
20198     return null;
20199   }
20200   return href;
20201 }
20202 var baseUrls = {};
20203 var justDomain = /^[^:]+:\/*[^/]*$/;
20204 var protocol = /^([^:]+:)[\s\S]*$/;
20205 var domain = /^([^:]+:\/*[^/]*)[\s\S]*$/;
20206
20207 /**
20208  * @param {string} base
20209  * @param {string} href
20210  */
20211 function resolveUrl(base, href) {
20212   if (!baseUrls[' ' + base]) {
20213     // we can ignore everything in base after the last slash of its path component,
20214     // but we might need to add _that_
20215     // https://tools.ietf.org/html/rfc3986#section-3
20216     if (justDomain.test(base)) {
20217       baseUrls[' ' + base] = base + '/';
20218     } else {
20219       baseUrls[' ' + base] = rtrim(base, '/', true);
20220     }
20221   }
20222   base = baseUrls[' ' + base];
20223   var relativeBase = base.indexOf(':') === -1;
20224   if (href.substring(0, 2) === '//') {
20225     if (relativeBase) {
20226       return href;
20227     }
20228     return base.replace(protocol, '$1') + href;
20229   } else if (href.charAt(0) === '/') {
20230     if (relativeBase) {
20231       return href;
20232     }
20233     return base.replace(domain, '$1') + href;
20234   } else {
20235     return base + href;
20236   }
20237 }
20238 var noopTest = {
20239   exec: function noopTest() {}
20240 };
20241 function merge(obj) {
20242   var i = 1,
20243     target,
20244     key;
20245   for (; i < arguments.length; i++) {
20246     target = arguments[i];
20247     for (key in target) {
20248       if (Object.prototype.hasOwnProperty.call(target, key)) {
20249         obj[key] = target[key];
20250       }
20251     }
20252   }
20253   return obj;
20254 }
20255 function splitCells(tableRow, count) {
20256   // ensure that every cell-delimiting pipe has a space
20257   // before it to distinguish it from an escaped pipe
20258   var row = tableRow.replace(/\|/g, function (match, offset, str) {
20259       var escaped = false,
20260         curr = offset;
20261       while (--curr >= 0 && str[curr] === '\\') {
20262         escaped = !escaped;
20263       }
20264       if (escaped) {
20265         // odd number of slashes means | is escaped
20266         // so we leave it alone
20267         return '|';
20268       } else {
20269         // add space before unescaped |
20270         return ' |';
20271       }
20272     }),
20273     cells = row.split(/ \|/);
20274   var i = 0;
20275
20276   // First/last cell in a row cannot be empty if it has no leading/trailing pipe
20277   if (!cells[0].trim()) {
20278     cells.shift();
20279   }
20280   if (cells.length > 0 && !cells[cells.length - 1].trim()) {
20281     cells.pop();
20282   }
20283   if (cells.length > count) {
20284     cells.splice(count);
20285   } else {
20286     while (cells.length < count) {
20287       cells.push('');
20288     }
20289   }
20290   for (; i < cells.length; i++) {
20291     // leading or trailing whitespace is ignored per the gfm spec
20292     cells[i] = cells[i].trim().replace(/\\\|/g, '|');
20293   }
20294   return cells;
20295 }
20296
20297 /**
20298  * Remove trailing 'c's. Equivalent to str.replace(/c*$/, '').
20299  * /c*$/ is vulnerable to REDOS.
20300  *
20301  * @param {string} str
20302  * @param {string} c
20303  * @param {boolean} invert Remove suffix of non-c chars instead. Default falsey.
20304  */
20305 function rtrim(str, c, invert) {
20306   var l = str.length;
20307   if (l === 0) {
20308     return '';
20309   }
20310
20311   // Length of suffix matching the invert condition.
20312   var suffLen = 0;
20313
20314   // Step left until we fail to match the invert condition.
20315   while (suffLen < l) {
20316     var currChar = str.charAt(l - suffLen - 1);
20317     if (currChar === c && !invert) {
20318       suffLen++;
20319     } else if (currChar !== c && invert) {
20320       suffLen++;
20321     } else {
20322       break;
20323     }
20324   }
20325   return str.slice(0, l - suffLen);
20326 }
20327 function findClosingBracket(str, b) {
20328   if (str.indexOf(b[1]) === -1) {
20329     return -1;
20330   }
20331   var l = str.length;
20332   var level = 0,
20333     i = 0;
20334   for (; i < l; i++) {
20335     if (str[i] === '\\') {
20336       i++;
20337     } else if (str[i] === b[0]) {
20338       level++;
20339     } else if (str[i] === b[1]) {
20340       level--;
20341       if (level < 0) {
20342         return i;
20343       }
20344     }
20345   }
20346   return -1;
20347 }
20348 function checkSanitizeDeprecation(opt) {
20349   if (opt && opt.sanitize && !opt.silent) {
20350     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');
20351   }
20352 }
20353
20354 // copied from https://stackoverflow.com/a/5450113/806777
20355 /**
20356  * @param {string} pattern
20357  * @param {number} count
20358  */
20359 function repeatString(pattern, count) {
20360   if (count < 1) {
20361     return '';
20362   }
20363   var result = '';
20364   while (count > 1) {
20365     if (count & 1) {
20366       result += pattern;
20367     }
20368     count >>= 1;
20369     pattern += pattern;
20370   }
20371   return result + pattern;
20372 }
20373
20374 function outputLink(cap, link, raw, lexer) {
20375   var href = link.href;
20376   var title = link.title ? escape(link.title) : null;
20377   var text = cap[1].replace(/\\([\[\]])/g, '$1');
20378   if (cap[0].charAt(0) !== '!') {
20379     lexer.state.inLink = true;
20380     var token = {
20381       type: 'link',
20382       raw: raw,
20383       href: href,
20384       title: title,
20385       text: text,
20386       tokens: lexer.inlineTokens(text)
20387     };
20388     lexer.state.inLink = false;
20389     return token;
20390   }
20391   return {
20392     type: 'image',
20393     raw: raw,
20394     href: href,
20395     title: title,
20396     text: escape(text)
20397   };
20398 }
20399 function indentCodeCompensation(raw, text) {
20400   var matchIndentToCode = raw.match(/^(\s+)(?:```)/);
20401   if (matchIndentToCode === null) {
20402     return text;
20403   }
20404   var indentToCode = matchIndentToCode[1];
20405   return text.split('\n').map(function (node) {
20406     var matchIndentInNode = node.match(/^\s+/);
20407     if (matchIndentInNode === null) {
20408       return node;
20409     }
20410     var indentInNode = matchIndentInNode[0];
20411     if (indentInNode.length >= indentToCode.length) {
20412       return node.slice(indentToCode.length);
20413     }
20414     return node;
20415   }).join('\n');
20416 }
20417
20418 /**
20419  * Tokenizer
20420  */
20421 var Tokenizer = /*#__PURE__*/function () {
20422   function Tokenizer(options) {
20423     this.options = options || exports.defaults;
20424   }
20425   var _proto = Tokenizer.prototype;
20426   _proto.space = function space(src) {
20427     var cap = this.rules.block.newline.exec(src);
20428     if (cap && cap[0].length > 0) {
20429       return {
20430         type: 'space',
20431         raw: cap[0]
20432       };
20433     }
20434   };
20435   _proto.code = function code(src) {
20436     var cap = this.rules.block.code.exec(src);
20437     if (cap) {
20438       var text = cap[0].replace(/^ {1,4}/gm, '');
20439       return {
20440         type: 'code',
20441         raw: cap[0],
20442         codeBlockStyle: 'indented',
20443         text: !this.options.pedantic ? rtrim(text, '\n') : text
20444       };
20445     }
20446   };
20447   _proto.fences = function fences(src) {
20448     var cap = this.rules.block.fences.exec(src);
20449     if (cap) {
20450       var raw = cap[0];
20451       var text = indentCodeCompensation(raw, cap[3] || '');
20452       return {
20453         type: 'code',
20454         raw: raw,
20455         lang: cap[2] ? cap[2].trim().replace(this.rules.inline._escapes, '$1') : cap[2],
20456         text: text
20457       };
20458     }
20459   };
20460   _proto.heading = function heading(src) {
20461     var cap = this.rules.block.heading.exec(src);
20462     if (cap) {
20463       var text = cap[2].trim();
20464
20465       // remove trailing #s
20466       if (/#$/.test(text)) {
20467         var trimmed = rtrim(text, '#');
20468         if (this.options.pedantic) {
20469           text = trimmed.trim();
20470         } else if (!trimmed || / $/.test(trimmed)) {
20471           // CommonMark requires space before trailing #s
20472           text = trimmed.trim();
20473         }
20474       }
20475       return {
20476         type: 'heading',
20477         raw: cap[0],
20478         depth: cap[1].length,
20479         text: text,
20480         tokens: this.lexer.inline(text)
20481       };
20482     }
20483   };
20484   _proto.hr = function hr(src) {
20485     var cap = this.rules.block.hr.exec(src);
20486     if (cap) {
20487       return {
20488         type: 'hr',
20489         raw: cap[0]
20490       };
20491     }
20492   };
20493   _proto.blockquote = function blockquote(src) {
20494     var cap = this.rules.block.blockquote.exec(src);
20495     if (cap) {
20496       var text = cap[0].replace(/^ *>[ \t]?/gm, '');
20497       var top = this.lexer.state.top;
20498       this.lexer.state.top = true;
20499       var tokens = this.lexer.blockTokens(text);
20500       this.lexer.state.top = top;
20501       return {
20502         type: 'blockquote',
20503         raw: cap[0],
20504         tokens: tokens,
20505         text: text
20506       };
20507     }
20508   };
20509   _proto.list = function list(src) {
20510     var cap = this.rules.block.list.exec(src);
20511     if (cap) {
20512       var raw, istask, ischecked, indent, i, blankLine, endsWithBlankLine, line, nextLine, rawLine, itemContents, endEarly;
20513       var bull = cap[1].trim();
20514       var isordered = bull.length > 1;
20515       var list = {
20516         type: 'list',
20517         raw: '',
20518         ordered: isordered,
20519         start: isordered ? +bull.slice(0, -1) : '',
20520         loose: false,
20521         items: []
20522       };
20523       bull = isordered ? "\\d{1,9}\\" + bull.slice(-1) : "\\" + bull;
20524       if (this.options.pedantic) {
20525         bull = isordered ? bull : '[*+-]';
20526       }
20527
20528       // Get next list item
20529       var itemRegex = new RegExp("^( {0,3}" + bull + ")((?:[\t ][^\\n]*)?(?:\\n|$))");
20530
20531       // Check if current bullet point can start a new List Item
20532       while (src) {
20533         endEarly = false;
20534         if (!(cap = itemRegex.exec(src))) {
20535           break;
20536         }
20537         if (this.rules.block.hr.test(src)) {
20538           // End list if bullet was actually HR (possibly move into itemRegex?)
20539           break;
20540         }
20541         raw = cap[0];
20542         src = src.substring(raw.length);
20543         line = cap[2].split('\n', 1)[0].replace(/^\t+/, function (t) {
20544           return ' '.repeat(3 * t.length);
20545         });
20546         nextLine = src.split('\n', 1)[0];
20547         if (this.options.pedantic) {
20548           indent = 2;
20549           itemContents = line.trimLeft();
20550         } else {
20551           indent = cap[2].search(/[^ ]/); // Find first non-space char
20552           indent = indent > 4 ? 1 : indent; // Treat indented code blocks (> 4 spaces) as having only 1 indent
20553           itemContents = line.slice(indent);
20554           indent += cap[1].length;
20555         }
20556         blankLine = false;
20557         if (!line && /^ *$/.test(nextLine)) {
20558           // Items begin with at most one blank line
20559           raw += nextLine + '\n';
20560           src = src.substring(nextLine.length + 1);
20561           endEarly = true;
20562         }
20563         if (!endEarly) {
20564           var nextBulletRegex = new RegExp("^ {0," + Math.min(3, indent - 1) + "}(?:[*+-]|\\d{1,9}[.)])((?:[ \t][^\\n]*)?(?:\\n|$))");
20565           var hrRegex = new RegExp("^ {0," + Math.min(3, indent - 1) + "}((?:- *){3,}|(?:_ *){3,}|(?:\\* *){3,})(?:\\n+|$)");
20566           var fencesBeginRegex = new RegExp("^ {0," + Math.min(3, indent - 1) + "}(?:```|~~~)");
20567           var headingBeginRegex = new RegExp("^ {0," + Math.min(3, indent - 1) + "}#");
20568
20569           // Check if following lines should be included in List Item
20570           while (src) {
20571             rawLine = src.split('\n', 1)[0];
20572             nextLine = rawLine;
20573
20574             // Re-align to follow commonmark nesting rules
20575             if (this.options.pedantic) {
20576               nextLine = nextLine.replace(/^ {1,4}(?=( {4})*[^ ])/g, '  ');
20577             }
20578
20579             // End list item if found code fences
20580             if (fencesBeginRegex.test(nextLine)) {
20581               break;
20582             }
20583
20584             // End list item if found start of new heading
20585             if (headingBeginRegex.test(nextLine)) {
20586               break;
20587             }
20588
20589             // End list item if found start of new bullet
20590             if (nextBulletRegex.test(nextLine)) {
20591               break;
20592             }
20593
20594             // Horizontal rule found
20595             if (hrRegex.test(src)) {
20596               break;
20597             }
20598             if (nextLine.search(/[^ ]/) >= indent || !nextLine.trim()) {
20599               // Dedent if possible
20600               itemContents += '\n' + nextLine.slice(indent);
20601             } else {
20602               // not enough indentation
20603               if (blankLine) {
20604                 break;
20605               }
20606
20607               // paragraph continuation unless last line was a different block level element
20608               if (line.search(/[^ ]/) >= 4) {
20609                 // indented code block
20610                 break;
20611               }
20612               if (fencesBeginRegex.test(line)) {
20613                 break;
20614               }
20615               if (headingBeginRegex.test(line)) {
20616                 break;
20617               }
20618               if (hrRegex.test(line)) {
20619                 break;
20620               }
20621               itemContents += '\n' + nextLine;
20622             }
20623             if (!blankLine && !nextLine.trim()) {
20624               // Check if current line is blank
20625               blankLine = true;
20626             }
20627             raw += rawLine + '\n';
20628             src = src.substring(rawLine.length + 1);
20629             line = nextLine.slice(indent);
20630           }
20631         }
20632         if (!list.loose) {
20633           // If the previous item ended with a blank line, the list is loose
20634           if (endsWithBlankLine) {
20635             list.loose = true;
20636           } else if (/\n *\n *$/.test(raw)) {
20637             endsWithBlankLine = true;
20638           }
20639         }
20640
20641         // Check for task list items
20642         if (this.options.gfm) {
20643           istask = /^\[[ xX]\] /.exec(itemContents);
20644           if (istask) {
20645             ischecked = istask[0] !== '[ ] ';
20646             itemContents = itemContents.replace(/^\[[ xX]\] +/, '');
20647           }
20648         }
20649         list.items.push({
20650           type: 'list_item',
20651           raw: raw,
20652           task: !!istask,
20653           checked: ischecked,
20654           loose: false,
20655           text: itemContents
20656         });
20657         list.raw += raw;
20658       }
20659
20660       // Do not consume newlines at end of final item. Alternatively, make itemRegex *start* with any newlines to simplify/speed up endsWithBlankLine logic
20661       list.items[list.items.length - 1].raw = raw.trimRight();
20662       list.items[list.items.length - 1].text = itemContents.trimRight();
20663       list.raw = list.raw.trimRight();
20664       var l = list.items.length;
20665
20666       // Item child tokens handled here at end because we needed to have the final item to trim it first
20667       for (i = 0; i < l; i++) {
20668         this.lexer.state.top = false;
20669         list.items[i].tokens = this.lexer.blockTokens(list.items[i].text, []);
20670         if (!list.loose) {
20671           // Check if list should be loose
20672           var spacers = list.items[i].tokens.filter(function (t) {
20673             return t.type === 'space';
20674           });
20675           var hasMultipleLineBreaks = spacers.length > 0 && spacers.some(function (t) {
20676             return /\n.*\n/.test(t.raw);
20677           });
20678           list.loose = hasMultipleLineBreaks;
20679         }
20680       }
20681
20682       // Set all items to loose if list is loose
20683       if (list.loose) {
20684         for (i = 0; i < l; i++) {
20685           list.items[i].loose = true;
20686         }
20687       }
20688       return list;
20689     }
20690   };
20691   _proto.html = function html(src) {
20692     var cap = this.rules.block.html.exec(src);
20693     if (cap) {
20694       var token = {
20695         type: 'html',
20696         raw: cap[0],
20697         pre: !this.options.sanitizer && (cap[1] === 'pre' || cap[1] === 'script' || cap[1] === 'style'),
20698         text: cap[0]
20699       };
20700       if (this.options.sanitize) {
20701         var text = this.options.sanitizer ? this.options.sanitizer(cap[0]) : escape(cap[0]);
20702         token.type = 'paragraph';
20703         token.text = text;
20704         token.tokens = this.lexer.inline(text);
20705       }
20706       return token;
20707     }
20708   };
20709   _proto.def = function def(src) {
20710     var cap = this.rules.block.def.exec(src);
20711     if (cap) {
20712       var tag = cap[1].toLowerCase().replace(/\s+/g, ' ');
20713       var href = cap[2] ? cap[2].replace(/^<(.*)>$/, '$1').replace(this.rules.inline._escapes, '$1') : '';
20714       var title = cap[3] ? cap[3].substring(1, cap[3].length - 1).replace(this.rules.inline._escapes, '$1') : cap[3];
20715       return {
20716         type: 'def',
20717         tag: tag,
20718         raw: cap[0],
20719         href: href,
20720         title: title
20721       };
20722     }
20723   };
20724   _proto.table = function table(src) {
20725     var cap = this.rules.block.table.exec(src);
20726     if (cap) {
20727       var item = {
20728         type: 'table',
20729         header: splitCells(cap[1]).map(function (c) {
20730           return {
20731             text: c
20732           };
20733         }),
20734         align: cap[2].replace(/^ *|\| *$/g, '').split(/ *\| */),
20735         rows: cap[3] && cap[3].trim() ? cap[3].replace(/\n[ \t]*$/, '').split('\n') : []
20736       };
20737       if (item.header.length === item.align.length) {
20738         item.raw = cap[0];
20739         var l = item.align.length;
20740         var i, j, k, row;
20741         for (i = 0; i < l; i++) {
20742           if (/^ *-+: *$/.test(item.align[i])) {
20743             item.align[i] = 'right';
20744           } else if (/^ *:-+: *$/.test(item.align[i])) {
20745             item.align[i] = 'center';
20746           } else if (/^ *:-+ *$/.test(item.align[i])) {
20747             item.align[i] = 'left';
20748           } else {
20749             item.align[i] = null;
20750           }
20751         }
20752         l = item.rows.length;
20753         for (i = 0; i < l; i++) {
20754           item.rows[i] = splitCells(item.rows[i], item.header.length).map(function (c) {
20755             return {
20756               text: c
20757             };
20758           });
20759         }
20760
20761         // parse child tokens inside headers and cells
20762
20763         // header child tokens
20764         l = item.header.length;
20765         for (j = 0; j < l; j++) {
20766           item.header[j].tokens = this.lexer.inline(item.header[j].text);
20767         }
20768
20769         // cell child tokens
20770         l = item.rows.length;
20771         for (j = 0; j < l; j++) {
20772           row = item.rows[j];
20773           for (k = 0; k < row.length; k++) {
20774             row[k].tokens = this.lexer.inline(row[k].text);
20775           }
20776         }
20777         return item;
20778       }
20779     }
20780   };
20781   _proto.lheading = function lheading(src) {
20782     var cap = this.rules.block.lheading.exec(src);
20783     if (cap) {
20784       return {
20785         type: 'heading',
20786         raw: cap[0],
20787         depth: cap[2].charAt(0) === '=' ? 1 : 2,
20788         text: cap[1],
20789         tokens: this.lexer.inline(cap[1])
20790       };
20791     }
20792   };
20793   _proto.paragraph = function paragraph(src) {
20794     var cap = this.rules.block.paragraph.exec(src);
20795     if (cap) {
20796       var text = cap[1].charAt(cap[1].length - 1) === '\n' ? cap[1].slice(0, -1) : cap[1];
20797       return {
20798         type: 'paragraph',
20799         raw: cap[0],
20800         text: text,
20801         tokens: this.lexer.inline(text)
20802       };
20803     }
20804   };
20805   _proto.text = function text(src) {
20806     var cap = this.rules.block.text.exec(src);
20807     if (cap) {
20808       return {
20809         type: 'text',
20810         raw: cap[0],
20811         text: cap[0],
20812         tokens: this.lexer.inline(cap[0])
20813       };
20814     }
20815   };
20816   _proto.escape = function escape$1(src) {
20817     var cap = this.rules.inline.escape.exec(src);
20818     if (cap) {
20819       return {
20820         type: 'escape',
20821         raw: cap[0],
20822         text: escape(cap[1])
20823       };
20824     }
20825   };
20826   _proto.tag = function tag(src) {
20827     var cap = this.rules.inline.tag.exec(src);
20828     if (cap) {
20829       if (!this.lexer.state.inLink && /^<a /i.test(cap[0])) {
20830         this.lexer.state.inLink = true;
20831       } else if (this.lexer.state.inLink && /^<\/a>/i.test(cap[0])) {
20832         this.lexer.state.inLink = false;
20833       }
20834       if (!this.lexer.state.inRawBlock && /^<(pre|code|kbd|script)(\s|>)/i.test(cap[0])) {
20835         this.lexer.state.inRawBlock = true;
20836       } else if (this.lexer.state.inRawBlock && /^<\/(pre|code|kbd|script)(\s|>)/i.test(cap[0])) {
20837         this.lexer.state.inRawBlock = false;
20838       }
20839       return {
20840         type: this.options.sanitize ? 'text' : 'html',
20841         raw: cap[0],
20842         inLink: this.lexer.state.inLink,
20843         inRawBlock: this.lexer.state.inRawBlock,
20844         text: this.options.sanitize ? this.options.sanitizer ? this.options.sanitizer(cap[0]) : escape(cap[0]) : cap[0]
20845       };
20846     }
20847   };
20848   _proto.link = function link(src) {
20849     var cap = this.rules.inline.link.exec(src);
20850     if (cap) {
20851       var trimmedUrl = cap[2].trim();
20852       if (!this.options.pedantic && /^</.test(trimmedUrl)) {
20853         // commonmark requires matching angle brackets
20854         if (!/>$/.test(trimmedUrl)) {
20855           return;
20856         }
20857
20858         // ending angle bracket cannot be escaped
20859         var rtrimSlash = rtrim(trimmedUrl.slice(0, -1), '\\');
20860         if ((trimmedUrl.length - rtrimSlash.length) % 2 === 0) {
20861           return;
20862         }
20863       } else {
20864         // find closing parenthesis
20865         var lastParenIndex = findClosingBracket(cap[2], '()');
20866         if (lastParenIndex > -1) {
20867           var start = cap[0].indexOf('!') === 0 ? 5 : 4;
20868           var linkLen = start + cap[1].length + lastParenIndex;
20869           cap[2] = cap[2].substring(0, lastParenIndex);
20870           cap[0] = cap[0].substring(0, linkLen).trim();
20871           cap[3] = '';
20872         }
20873       }
20874       var href = cap[2];
20875       var title = '';
20876       if (this.options.pedantic) {
20877         // split pedantic href and title
20878         var link = /^([^'"]*[^\s])\s+(['"])(.*)\2/.exec(href);
20879         if (link) {
20880           href = link[1];
20881           title = link[3];
20882         }
20883       } else {
20884         title = cap[3] ? cap[3].slice(1, -1) : '';
20885       }
20886       href = href.trim();
20887       if (/^</.test(href)) {
20888         if (this.options.pedantic && !/>$/.test(trimmedUrl)) {
20889           // pedantic allows starting angle bracket without ending angle bracket
20890           href = href.slice(1);
20891         } else {
20892           href = href.slice(1, -1);
20893         }
20894       }
20895       return outputLink(cap, {
20896         href: href ? href.replace(this.rules.inline._escapes, '$1') : href,
20897         title: title ? title.replace(this.rules.inline._escapes, '$1') : title
20898       }, cap[0], this.lexer);
20899     }
20900   };
20901   _proto.reflink = function reflink(src, links) {
20902     var cap;
20903     if ((cap = this.rules.inline.reflink.exec(src)) || (cap = this.rules.inline.nolink.exec(src))) {
20904       var link = (cap[2] || cap[1]).replace(/\s+/g, ' ');
20905       link = links[link.toLowerCase()];
20906       if (!link) {
20907         var text = cap[0].charAt(0);
20908         return {
20909           type: 'text',
20910           raw: text,
20911           text: text
20912         };
20913       }
20914       return outputLink(cap, link, cap[0], this.lexer);
20915     }
20916   };
20917   _proto.emStrong = function emStrong(src, maskedSrc, prevChar) {
20918     if (prevChar === void 0) {
20919       prevChar = '';
20920     }
20921     var match = this.rules.inline.emStrong.lDelim.exec(src);
20922     if (!match) return;
20923
20924     // _ can't be between two alphanumerics. \p{L}\p{N} includes non-english alphabet/numbers as well
20925     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;
20926     var nextChar = match[1] || match[2] || '';
20927     if (!nextChar || nextChar && (prevChar === '' || this.rules.inline.punctuation.exec(prevChar))) {
20928       var lLength = match[0].length - 1;
20929       var rDelim,
20930         rLength,
20931         delimTotal = lLength,
20932         midDelimTotal = 0;
20933       var endReg = match[0][0] === '*' ? this.rules.inline.emStrong.rDelimAst : this.rules.inline.emStrong.rDelimUnd;
20934       endReg.lastIndex = 0;
20935
20936       // Clip maskedSrc to same section of string as src (move to lexer?)
20937       maskedSrc = maskedSrc.slice(-1 * src.length + lLength);
20938       while ((match = endReg.exec(maskedSrc)) != null) {
20939         rDelim = match[1] || match[2] || match[3] || match[4] || match[5] || match[6];
20940         if (!rDelim) continue; // skip single * in __abc*abc__
20941
20942         rLength = rDelim.length;
20943         if (match[3] || match[4]) {
20944           // found another Left Delim
20945           delimTotal += rLength;
20946           continue;
20947         } else if (match[5] || match[6]) {
20948           // either Left or Right Delim
20949           if (lLength % 3 && !((lLength + rLength) % 3)) {
20950             midDelimTotal += rLength;
20951             continue; // CommonMark Emphasis Rules 9-10
20952           }
20953         }
20954
20955         delimTotal -= rLength;
20956         if (delimTotal > 0) continue; // Haven't found enough closing delimiters
20957
20958         // Remove extra characters. *a*** -> *a*
20959         rLength = Math.min(rLength, rLength + delimTotal + midDelimTotal);
20960         var raw = src.slice(0, lLength + match.index + (match[0].length - rDelim.length) + rLength);
20961
20962         // Create `em` if smallest delimiter has odd char count. *a***
20963         if (Math.min(lLength, rLength) % 2) {
20964           var _text = raw.slice(1, -1);
20965           return {
20966             type: 'em',
20967             raw: raw,
20968             text: _text,
20969             tokens: this.lexer.inlineTokens(_text)
20970           };
20971         }
20972
20973         // Create 'strong' if smallest delimiter has even char count. **a***
20974         var text = raw.slice(2, -2);
20975         return {
20976           type: 'strong',
20977           raw: raw,
20978           text: text,
20979           tokens: this.lexer.inlineTokens(text)
20980         };
20981       }
20982     }
20983   };
20984   _proto.codespan = function codespan(src) {
20985     var cap = this.rules.inline.code.exec(src);
20986     if (cap) {
20987       var text = cap[2].replace(/\n/g, ' ');
20988       var hasNonSpaceChars = /[^ ]/.test(text);
20989       var hasSpaceCharsOnBothEnds = /^ /.test(text) && / $/.test(text);
20990       if (hasNonSpaceChars && hasSpaceCharsOnBothEnds) {
20991         text = text.substring(1, text.length - 1);
20992       }
20993       text = escape(text, true);
20994       return {
20995         type: 'codespan',
20996         raw: cap[0],
20997         text: text
20998       };
20999     }
21000   };
21001   _proto.br = function br(src) {
21002     var cap = this.rules.inline.br.exec(src);
21003     if (cap) {
21004       return {
21005         type: 'br',
21006         raw: cap[0]
21007       };
21008     }
21009   };
21010   _proto.del = function del(src) {
21011     var cap = this.rules.inline.del.exec(src);
21012     if (cap) {
21013       return {
21014         type: 'del',
21015         raw: cap[0],
21016         text: cap[2],
21017         tokens: this.lexer.inlineTokens(cap[2])
21018       };
21019     }
21020   };
21021   _proto.autolink = function autolink(src, mangle) {
21022     var cap = this.rules.inline.autolink.exec(src);
21023     if (cap) {
21024       var text, href;
21025       if (cap[2] === '@') {
21026         text = escape(this.options.mangle ? mangle(cap[1]) : cap[1]);
21027         href = 'mailto:' + text;
21028       } else {
21029         text = escape(cap[1]);
21030         href = text;
21031       }
21032       return {
21033         type: 'link',
21034         raw: cap[0],
21035         text: text,
21036         href: href,
21037         tokens: [{
21038           type: 'text',
21039           raw: text,
21040           text: text
21041         }]
21042       };
21043     }
21044   };
21045   _proto.url = function url(src, mangle) {
21046     var cap;
21047     if (cap = this.rules.inline.url.exec(src)) {
21048       var text, href;
21049       if (cap[2] === '@') {
21050         text = escape(this.options.mangle ? mangle(cap[0]) : cap[0]);
21051         href = 'mailto:' + text;
21052       } else {
21053         // do extended autolink path validation
21054         var prevCapZero;
21055         do {
21056           prevCapZero = cap[0];
21057           cap[0] = this.rules.inline._backpedal.exec(cap[0])[0];
21058         } while (prevCapZero !== cap[0]);
21059         text = escape(cap[0]);
21060         if (cap[1] === 'www.') {
21061           href = 'http://' + cap[0];
21062         } else {
21063           href = cap[0];
21064         }
21065       }
21066       return {
21067         type: 'link',
21068         raw: cap[0],
21069         text: text,
21070         href: href,
21071         tokens: [{
21072           type: 'text',
21073           raw: text,
21074           text: text
21075         }]
21076       };
21077     }
21078   };
21079   _proto.inlineText = function inlineText(src, smartypants) {
21080     var cap = this.rules.inline.text.exec(src);
21081     if (cap) {
21082       var text;
21083       if (this.lexer.state.inRawBlock) {
21084         text = this.options.sanitize ? this.options.sanitizer ? this.options.sanitizer(cap[0]) : escape(cap[0]) : cap[0];
21085       } else {
21086         text = escape(this.options.smartypants ? smartypants(cap[0]) : cap[0]);
21087       }
21088       return {
21089         type: 'text',
21090         raw: cap[0],
21091         text: text
21092       };
21093     }
21094   };
21095   return Tokenizer;
21096 }();
21097
21098 /**
21099  * Block-Level Grammar
21100  */
21101 var block = {
21102   newline: /^(?: *(?:\n|$))+/,
21103   code: /^( {4}[^\n]+(?:\n(?: *(?:\n|$))*)?)+/,
21104   fences: /^ {0,3}(`{3,}(?=[^`\n]*\n)|~{3,})([^\n]*)\n(?:|([\s\S]*?)\n)(?: {0,3}\1[~`]* *(?=\n|$)|$)/,
21105   hr: /^ {0,3}((?:-[\t ]*){3,}|(?:_[ \t]*){3,}|(?:\*[ \t]*){3,})(?:\n+|$)/,
21106   heading: /^ {0,3}(#{1,6})(?=\s|$)(.*)(?:\n+|$)/,
21107   blockquote: /^( {0,3}> ?(paragraph|[^\n]*)(?:\n|$))+/,
21108   list: /^( {0,3}bull)([ \t][^\n]+?)?(?:\n|$)/,
21109   html: '^ {0,3}(?:' // optional indentation
21110   + '<(script|pre|style|textarea)[\\s>][\\s\\S]*?(?:</\\1>[^\\n]*\\n+|$)' // (1)
21111   + '|comment[^\\n]*(\\n+|$)' // (2)
21112   + '|<\\?[\\s\\S]*?(?:\\?>\\n*|$)' // (3)
21113   + '|<![A-Z][\\s\\S]*?(?:>\\n*|$)' // (4)
21114   + '|<!\\[CDATA\\[[\\s\\S]*?(?:\\]\\]>\\n*|$)' // (5)
21115   + '|</?(tag)(?: +|\\n|/?>)[\\s\\S]*?(?:(?:\\n *)+\\n|$)' // (6)
21116   + '|<(?!script|pre|style|textarea)([a-z][\\w-]*)(?:attribute)*? */?>(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n *)+\\n|$)' // (7) open tag
21117   + '|</(?!script|pre|style|textarea)[a-z][\\w-]*\\s*>(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n *)+\\n|$)' // (7) closing tag
21118   + ')',
21119   def: /^ {0,3}\[(label)\]: *(?:\n *)?([^<\s][^\s]*|<.*?>)(?:(?: +(?:\n *)?| *\n *)(title))? *(?:\n+|$)/,
21120   table: noopTest,
21121   lheading: /^((?:.|\n(?!\n))+?)\n {0,3}(=+|-+) *(?:\n+|$)/,
21122   // regex template, placeholders will be replaced according to different paragraph
21123   // interruption rules of commonmark and the original markdown spec:
21124   _paragraph: /^([^\n]+(?:\n(?!hr|heading|lheading|blockquote|fences|list|html|table| +\n)[^\n]+)*)/,
21125   text: /^[^\n]+/
21126 };
21127 block._label = /(?!\s*\])(?:\\.|[^\[\]\\])+/;
21128 block._title = /(?:"(?:\\"?|[^"\\])*"|'[^'\n]*(?:\n[^'\n]+)*\n?'|\([^()]*\))/;
21129 block.def = edit(block.def).replace('label', block._label).replace('title', block._title).getRegex();
21130 block.bullet = /(?:[*+-]|\d{1,9}[.)])/;
21131 block.listItemStart = edit(/^( *)(bull) */).replace('bull', block.bullet).getRegex();
21132 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();
21133 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';
21134 block._comment = /<!--(?!-?>)[\s\S]*?(?:-->|$)/;
21135 block.html = edit(block.html, 'i').replace('comment', block._comment).replace('tag', block._tag).replace('attribute', / +[a-zA-Z:_][\w.:-]*(?: *= *"[^"\n]*"| *= *'[^'\n]*'| *= *[^\s"'=<>`]+)?/).getRegex();
21136 block.paragraph = edit(block._paragraph).replace('hr', block.hr).replace('heading', ' {0,3}#{1,6} ').replace('|lheading', '') // setex headings don't interrupt commonmark paragraphs
21137 .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
21138 .replace('html', '</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)').replace('tag', block._tag) // pars can be interrupted by type (6) html blocks
21139 .getRegex();
21140 block.blockquote = edit(block.blockquote).replace('paragraph', block.paragraph).getRegex();
21141
21142 /**
21143  * Normal Block Grammar
21144  */
21145
21146 block.normal = merge({}, block);
21147
21148 /**
21149  * GFM Block Grammar
21150  */
21151
21152 block.gfm = merge({}, block.normal, {
21153   table: '^ *([^\\n ].*\\|.*)\\n' // Header
21154   + ' {0,3}(?:\\| *)?(:?-+:? *(?:\\| *:?-+:? *)*)(?:\\| *)?' // Align
21155   + '(?:\\n((?:(?! *\\n|hr|heading|blockquote|code|fences|list|html).*(?:\\n|$))*)\\n*|$)' // Cells
21156 });
21157
21158 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
21159 .replace('html', '</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)').replace('tag', block._tag) // tables can be interrupted by type (6) html blocks
21160 .getRegex();
21161 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
21162 .replace('table', block.gfm.table) // interrupt paragraphs with table
21163 .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
21164 .replace('html', '</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)').replace('tag', block._tag) // pars can be interrupted by type (6) html blocks
21165 .getRegex();
21166 /**
21167  * Pedantic grammar (original John Gruber's loose markdown specification)
21168  */
21169
21170 block.pedantic = merge({}, block.normal, {
21171   html: edit('^ *(?:comment *(?:\\n|\\s*$)' + '|<(tag)[\\s\\S]+?</\\1> *(?:\\n{2,}|\\s*$)' // closed tag
21172   + '|<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(),
21173   def: /^ *\[([^\]]+)\]: *<?([^\s>]+)>?(?: +(["(][^\n]+[")]))? *(?:\n+|$)/,
21174   heading: /^(#{1,6})(.*)(?:\n+|$)/,
21175   fences: noopTest,
21176   // fences not supported
21177   lheading: /^(.+?)\n {0,3}(=+|-+) *(?:\n+|$)/,
21178   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()
21179 });
21180
21181 /**
21182  * Inline-Level Grammar
21183  */
21184 var inline = {
21185   escape: /^\\([!"#$%&'()*+,\-./:;<=>?@\[\]\\^_`{|}~])/,
21186   autolink: /^<(scheme:[^\s\x00-\x1f<>]*|email)>/,
21187   url: noopTest,
21188   tag: '^comment' + '|^</[a-zA-Z][\\w:-]*\\s*>' // self-closing tag
21189   + '|^<[a-zA-Z][\\w-]*(?:attribute)*?\\s*/?>' // open tag
21190   + '|^<\\?[\\s\\S]*?\\?>' // processing instruction, e.g. <?php ?>
21191   + '|^<![a-zA-Z]+\\s[\\s\\S]*?>' // declaration, e.g. <!DOCTYPE html>
21192   + '|^<!\\[CDATA\\[[\\s\\S]*?\\]\\]>',
21193   // CDATA section
21194   link: /^!?\[(label)\]\(\s*(href)(?:\s+(title))?\s*\)/,
21195   reflink: /^!?\[(label)\]\[(ref)\]/,
21196   nolink: /^!?\[(ref)\](?:\[\])?/,
21197   reflinkSearch: 'reflink|nolink(?!\\()',
21198   emStrong: {
21199     lDelim: /^(?:\*+(?:([punct_])|[^\s*]))|^_+(?:([punct*])|([^\s_]))/,
21200     //        (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.
21201     //          () Skip orphan inside strong                                      () Consume to delim     (1) #***                (2) a***#, a***                             (3) #***a, ***a                 (4) ***#              (5) #***#                 (6) a***a
21202     rDelimAst: /^(?:[^_*\\]|\\.)*?\_\_(?:[^_*\\]|\\.)*?\*(?:[^_*\\]|\\.)*?(?=\_\_)|(?:[^*\\]|\\.)+(?=[^*])|[punct_](\*+)(?=[\s]|$)|(?:[^punct*_\s\\]|\\.)(\*+)(?=[punct_\s]|$)|[punct_\s](\*+)(?=[^punct*_\s])|[\s](\*+)(?=[punct_])|[punct_](\*+)(?=[punct_])|(?:[^punct*_\s\\]|\\.)(\*+)(?=[^punct*_\s])/,
21203     rDelimUnd: /^(?:[^_*\\]|\\.)*?\*\*(?:[^_*\\]|\\.)*?\_(?:[^_*\\]|\\.)*?(?=\*\*)|(?:[^_\\]|\\.)+(?=[^_])|[punct*](\_+)(?=[\s]|$)|(?:[^punct*_\s\\]|\\.)(\_+)(?=[punct*\s]|$)|[punct*\s](\_+)(?=[^punct*_\s])|[\s](\_+)(?=[punct*])|[punct*](\_+)(?=[punct*])/ // ^- Not allowed for _
21204   },
21205
21206   code: /^(`+)([^`]|[^`][\s\S]*?[^`])\1(?!`)/,
21207   br: /^( {2,}|\\)\n(?!\s*$)/,
21208   del: noopTest,
21209   text: /^(`+|[^`])(?:(?= {2,}\n)|[\s\S]*?(?:(?=[\\<!\[`*_]|\b_|$)|[^ ](?= {2,}\n)))/,
21210   punctuation: /^([\spunctuation])/
21211 };
21212
21213 // list of punctuation marks from CommonMark spec
21214 // without * and _ to handle the different emphasis markers * and _
21215 inline._punctuation = '!"#$%&\'()+\\-.,/:;<=>?@\\[\\]`^{|}~';
21216 inline.punctuation = edit(inline.punctuation).replace(/punctuation/g, inline._punctuation).getRegex();
21217
21218 // sequences em should skip over [title](link), `code`, <html>
21219 inline.blockSkip = /\[[^\]]*?\]\([^\)]*?\)|`[^`]*?`|<[^>]*?>/g;
21220 // lookbehind is not available on Safari as of version 16
21221 // inline.escapedEmSt = /(?<=(?:^|[^\\)(?:\\[^])*)\\[*_]/g;
21222 inline.escapedEmSt = /(?:^|[^\\])(?:\\\\)*\\[*_]/g;
21223 inline._comment = edit(block._comment).replace('(?:-->|$)', '-->').getRegex();
21224 inline.emStrong.lDelim = edit(inline.emStrong.lDelim).replace(/punct/g, inline._punctuation).getRegex();
21225 inline.emStrong.rDelimAst = edit(inline.emStrong.rDelimAst, 'g').replace(/punct/g, inline._punctuation).getRegex();
21226 inline.emStrong.rDelimUnd = edit(inline.emStrong.rDelimUnd, 'g').replace(/punct/g, inline._punctuation).getRegex();
21227 inline._escapes = /\\([!"#$%&'()*+,\-./:;<=>?@\[\]\\^_`{|}~])/g;
21228 inline._scheme = /[a-zA-Z][a-zA-Z0-9+.-]{1,31}/;
21229 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])?)+(?![-_])/;
21230 inline.autolink = edit(inline.autolink).replace('scheme', inline._scheme).replace('email', inline._email).getRegex();
21231 inline._attribute = /\s+[a-zA-Z:_][\w.:-]*(?:\s*=\s*"[^"]*"|\s*=\s*'[^']*'|\s*=\s*[^\s"'=<>`]+)?/;
21232 inline.tag = edit(inline.tag).replace('comment', inline._comment).replace('attribute', inline._attribute).getRegex();
21233 inline._label = /(?:\[(?:\\.|[^\[\]\\])*\]|\\.|`[^`]*`|[^\[\]\\`])*?/;
21234 inline._href = /<(?:\\.|[^\n<>\\])+>|[^\s\x00-\x1f]*/;
21235 inline._title = /"(?:\\"?|[^"\\])*"|'(?:\\'?|[^'\\])*'|\((?:\\\)?|[^)\\])*\)/;
21236 inline.link = edit(inline.link).replace('label', inline._label).replace('href', inline._href).replace('title', inline._title).getRegex();
21237 inline.reflink = edit(inline.reflink).replace('label', inline._label).replace('ref', block._label).getRegex();
21238 inline.nolink = edit(inline.nolink).replace('ref', block._label).getRegex();
21239 inline.reflinkSearch = edit(inline.reflinkSearch, 'g').replace('reflink', inline.reflink).replace('nolink', inline.nolink).getRegex();
21240
21241 /**
21242  * Normal Inline Grammar
21243  */
21244
21245 inline.normal = merge({}, inline);
21246
21247 /**
21248  * Pedantic Inline Grammar
21249  */
21250
21251 inline.pedantic = merge({}, inline.normal, {
21252   strong: {
21253     start: /^__|\*\*/,
21254     middle: /^__(?=\S)([\s\S]*?\S)__(?!_)|^\*\*(?=\S)([\s\S]*?\S)\*\*(?!\*)/,
21255     endAst: /\*\*(?!\*)/g,
21256     endUnd: /__(?!_)/g
21257   },
21258   em: {
21259     start: /^_|\*/,
21260     middle: /^()\*(?=\S)([\s\S]*?\S)\*(?!\*)|^_(?=\S)([\s\S]*?\S)_(?!_)/,
21261     endAst: /\*(?!\*)/g,
21262     endUnd: /_(?!_)/g
21263   },
21264   link: edit(/^!?\[(label)\]\((.*?)\)/).replace('label', inline._label).getRegex(),
21265   reflink: edit(/^!?\[(label)\]\s*\[([^\]]*)\]/).replace('label', inline._label).getRegex()
21266 });
21267
21268 /**
21269  * GFM Inline Grammar
21270  */
21271
21272 inline.gfm = merge({}, inline.normal, {
21273   escape: edit(inline.escape).replace('])', '~|])').getRegex(),
21274   _extended_email: /[A-Za-z0-9._+-]+(@)[a-zA-Z0-9-_]+(?:\.[a-zA-Z0-9-_]*[a-zA-Z0-9])+(?![-_])/,
21275   url: /^((?:ftp|https?):\/\/|www\.)(?:[a-zA-Z0-9\-]+\.?)+[^\s<]*|^email/,
21276   _backpedal: /(?:[^?!.,:;*_'"~()&]+|\([^)]*\)|&(?![a-zA-Z0-9]+;$)|[?!.,:;*_'"~)]+(?!$))+/,
21277   del: /^(~~?)(?=[^\s~])([\s\S]*?[^\s~])\1(?=[^~]|$)/,
21278   text: /^([`~]+|[^`~])(?:(?= {2,}\n)|(?=[a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-]+@)|[\s\S]*?(?:(?=[\\<!\[`*~_]|\b_|https?:\/\/|ftp:\/\/|www\.|$)|[^ ](?= {2,}\n)|[^a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-](?=[a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-]+@)))/
21279 });
21280 inline.gfm.url = edit(inline.gfm.url, 'i').replace('email', inline.gfm._extended_email).getRegex();
21281 /**
21282  * GFM + Line Breaks Inline Grammar
21283  */
21284
21285 inline.breaks = merge({}, inline.gfm, {
21286   br: edit(inline.br).replace('{2,}', '*').getRegex(),
21287   text: edit(inline.gfm.text).replace('\\b_', '\\b_| {2,}\\n').replace(/\{2,\}/g, '*').getRegex()
21288 });
21289
21290 /**
21291  * smartypants text replacement
21292  * @param {string} text
21293  */
21294 function smartypants(text) {
21295   return text
21296   // em-dashes
21297   .replace(/---/g, "\u2014")
21298   // en-dashes
21299   .replace(/--/g, "\u2013")
21300   // opening singles
21301   .replace(/(^|[-\u2014/(\[{"\s])'/g, "$1\u2018")
21302   // closing singles & apostrophes
21303   .replace(/'/g, "\u2019")
21304   // opening doubles
21305   .replace(/(^|[-\u2014/(\[{\u2018\s])"/g, "$1\u201C")
21306   // closing doubles
21307   .replace(/"/g, "\u201D")
21308   // ellipses
21309   .replace(/\.{3}/g, "\u2026");
21310 }
21311
21312 /**
21313  * mangle email addresses
21314  * @param {string} text
21315  */
21316 function mangle(text) {
21317   var out = '',
21318     i,
21319     ch;
21320   var l = text.length;
21321   for (i = 0; i < l; i++) {
21322     ch = text.charCodeAt(i);
21323     if (Math.random() > 0.5) {
21324       ch = 'x' + ch.toString(16);
21325     }
21326     out += '&#' + ch + ';';
21327   }
21328   return out;
21329 }
21330
21331 /**
21332  * Block Lexer
21333  */
21334 var Lexer = /*#__PURE__*/function () {
21335   function Lexer(options) {
21336     this.tokens = [];
21337     this.tokens.links = Object.create(null);
21338     this.options = options || exports.defaults;
21339     this.options.tokenizer = this.options.tokenizer || new Tokenizer();
21340     this.tokenizer = this.options.tokenizer;
21341     this.tokenizer.options = this.options;
21342     this.tokenizer.lexer = this;
21343     this.inlineQueue = [];
21344     this.state = {
21345       inLink: false,
21346       inRawBlock: false,
21347       top: true
21348     };
21349     var rules = {
21350       block: block.normal,
21351       inline: inline.normal
21352     };
21353     if (this.options.pedantic) {
21354       rules.block = block.pedantic;
21355       rules.inline = inline.pedantic;
21356     } else if (this.options.gfm) {
21357       rules.block = block.gfm;
21358       if (this.options.breaks) {
21359         rules.inline = inline.breaks;
21360       } else {
21361         rules.inline = inline.gfm;
21362       }
21363     }
21364     this.tokenizer.rules = rules;
21365   }
21366
21367   /**
21368    * Expose Rules
21369    */
21370   /**
21371    * Static Lex Method
21372    */
21373   Lexer.lex = function lex(src, options) {
21374     var lexer = new Lexer(options);
21375     return lexer.lex(src);
21376   }
21377
21378   /**
21379    * Static Lex Inline Method
21380    */;
21381   Lexer.lexInline = function lexInline(src, options) {
21382     var lexer = new Lexer(options);
21383     return lexer.inlineTokens(src);
21384   }
21385
21386   /**
21387    * Preprocessing
21388    */;
21389   var _proto = Lexer.prototype;
21390   _proto.lex = function lex(src) {
21391     src = src.replace(/\r\n|\r/g, '\n');
21392     this.blockTokens(src, this.tokens);
21393     var next;
21394     while (next = this.inlineQueue.shift()) {
21395       this.inlineTokens(next.src, next.tokens);
21396     }
21397     return this.tokens;
21398   }
21399
21400   /**
21401    * Lexing
21402    */;
21403   _proto.blockTokens = function blockTokens(src, tokens) {
21404     var _this = this;
21405     if (tokens === void 0) {
21406       tokens = [];
21407     }
21408     if (this.options.pedantic) {
21409       src = src.replace(/\t/g, '    ').replace(/^ +$/gm, '');
21410     } else {
21411       src = src.replace(/^( *)(\t+)/gm, function (_, leading, tabs) {
21412         return leading + '    '.repeat(tabs.length);
21413       });
21414     }
21415     var token, lastToken, cutSrc, lastParagraphClipped;
21416     while (src) {
21417       if (this.options.extensions && this.options.extensions.block && this.options.extensions.block.some(function (extTokenizer) {
21418         if (token = extTokenizer.call({
21419           lexer: _this
21420         }, src, tokens)) {
21421           src = src.substring(token.raw.length);
21422           tokens.push(token);
21423           return true;
21424         }
21425         return false;
21426       })) {
21427         continue;
21428       }
21429
21430       // newline
21431       if (token = this.tokenizer.space(src)) {
21432         src = src.substring(token.raw.length);
21433         if (token.raw.length === 1 && tokens.length > 0) {
21434           // if there's a single \n as a spacer, it's terminating the last line,
21435           // so move it there so that we don't get unecessary paragraph tags
21436           tokens[tokens.length - 1].raw += '\n';
21437         } else {
21438           tokens.push(token);
21439         }
21440         continue;
21441       }
21442
21443       // code
21444       if (token = this.tokenizer.code(src)) {
21445         src = src.substring(token.raw.length);
21446         lastToken = tokens[tokens.length - 1];
21447         // An indented code block cannot interrupt a paragraph.
21448         if (lastToken && (lastToken.type === 'paragraph' || lastToken.type === 'text')) {
21449           lastToken.raw += '\n' + token.raw;
21450           lastToken.text += '\n' + token.text;
21451           this.inlineQueue[this.inlineQueue.length - 1].src = lastToken.text;
21452         } else {
21453           tokens.push(token);
21454         }
21455         continue;
21456       }
21457
21458       // fences
21459       if (token = this.tokenizer.fences(src)) {
21460         src = src.substring(token.raw.length);
21461         tokens.push(token);
21462         continue;
21463       }
21464
21465       // heading
21466       if (token = this.tokenizer.heading(src)) {
21467         src = src.substring(token.raw.length);
21468         tokens.push(token);
21469         continue;
21470       }
21471
21472       // hr
21473       if (token = this.tokenizer.hr(src)) {
21474         src = src.substring(token.raw.length);
21475         tokens.push(token);
21476         continue;
21477       }
21478
21479       // blockquote
21480       if (token = this.tokenizer.blockquote(src)) {
21481         src = src.substring(token.raw.length);
21482         tokens.push(token);
21483         continue;
21484       }
21485
21486       // list
21487       if (token = this.tokenizer.list(src)) {
21488         src = src.substring(token.raw.length);
21489         tokens.push(token);
21490         continue;
21491       }
21492
21493       // html
21494       if (token = this.tokenizer.html(src)) {
21495         src = src.substring(token.raw.length);
21496         tokens.push(token);
21497         continue;
21498       }
21499
21500       // def
21501       if (token = this.tokenizer.def(src)) {
21502         src = src.substring(token.raw.length);
21503         lastToken = tokens[tokens.length - 1];
21504         if (lastToken && (lastToken.type === 'paragraph' || lastToken.type === 'text')) {
21505           lastToken.raw += '\n' + token.raw;
21506           lastToken.text += '\n' + token.raw;
21507           this.inlineQueue[this.inlineQueue.length - 1].src = lastToken.text;
21508         } else if (!this.tokens.links[token.tag]) {
21509           this.tokens.links[token.tag] = {
21510             href: token.href,
21511             title: token.title
21512           };
21513         }
21514         continue;
21515       }
21516
21517       // table (gfm)
21518       if (token = this.tokenizer.table(src)) {
21519         src = src.substring(token.raw.length);
21520         tokens.push(token);
21521         continue;
21522       }
21523
21524       // lheading
21525       if (token = this.tokenizer.lheading(src)) {
21526         src = src.substring(token.raw.length);
21527         tokens.push(token);
21528         continue;
21529       }
21530
21531       // top-level paragraph
21532       // prevent paragraph consuming extensions by clipping 'src' to extension start
21533       cutSrc = src;
21534       if (this.options.extensions && this.options.extensions.startBlock) {
21535         (function () {
21536           var startIndex = Infinity;
21537           var tempSrc = src.slice(1);
21538           var tempStart = void 0;
21539           _this.options.extensions.startBlock.forEach(function (getStartIndex) {
21540             tempStart = getStartIndex.call({
21541               lexer: this
21542             }, tempSrc);
21543             if (typeof tempStart === 'number' && tempStart >= 0) {
21544               startIndex = Math.min(startIndex, tempStart);
21545             }
21546           });
21547           if (startIndex < Infinity && startIndex >= 0) {
21548             cutSrc = src.substring(0, startIndex + 1);
21549           }
21550         })();
21551       }
21552       if (this.state.top && (token = this.tokenizer.paragraph(cutSrc))) {
21553         lastToken = tokens[tokens.length - 1];
21554         if (lastParagraphClipped && lastToken.type === 'paragraph') {
21555           lastToken.raw += '\n' + token.raw;
21556           lastToken.text += '\n' + token.text;
21557           this.inlineQueue.pop();
21558           this.inlineQueue[this.inlineQueue.length - 1].src = lastToken.text;
21559         } else {
21560           tokens.push(token);
21561         }
21562         lastParagraphClipped = cutSrc.length !== src.length;
21563         src = src.substring(token.raw.length);
21564         continue;
21565       }
21566
21567       // text
21568       if (token = this.tokenizer.text(src)) {
21569         src = src.substring(token.raw.length);
21570         lastToken = tokens[tokens.length - 1];
21571         if (lastToken && lastToken.type === 'text') {
21572           lastToken.raw += '\n' + token.raw;
21573           lastToken.text += '\n' + token.text;
21574           this.inlineQueue.pop();
21575           this.inlineQueue[this.inlineQueue.length - 1].src = lastToken.text;
21576         } else {
21577           tokens.push(token);
21578         }
21579         continue;
21580       }
21581       if (src) {
21582         var errMsg = 'Infinite loop on byte: ' + src.charCodeAt(0);
21583         if (this.options.silent) {
21584           console.error(errMsg);
21585           break;
21586         } else {
21587           throw new Error(errMsg);
21588         }
21589       }
21590     }
21591     this.state.top = true;
21592     return tokens;
21593   };
21594   _proto.inline = function inline(src, tokens) {
21595     if (tokens === void 0) {
21596       tokens = [];
21597     }
21598     this.inlineQueue.push({
21599       src: src,
21600       tokens: tokens
21601     });
21602     return tokens;
21603   }
21604
21605   /**
21606    * Lexing/Compiling
21607    */;
21608   _proto.inlineTokens = function inlineTokens(src, tokens) {
21609     var _this2 = this;
21610     if (tokens === void 0) {
21611       tokens = [];
21612     }
21613     var token, lastToken, cutSrc;
21614
21615     // String with links masked to avoid interference with em and strong
21616     var maskedSrc = src;
21617     var match;
21618     var keepPrevChar, prevChar;
21619
21620     // Mask out reflinks
21621     if (this.tokens.links) {
21622       var links = Object.keys(this.tokens.links);
21623       if (links.length > 0) {
21624         while ((match = this.tokenizer.rules.inline.reflinkSearch.exec(maskedSrc)) != null) {
21625           if (links.includes(match[0].slice(match[0].lastIndexOf('[') + 1, -1))) {
21626             maskedSrc = maskedSrc.slice(0, match.index) + '[' + repeatString('a', match[0].length - 2) + ']' + maskedSrc.slice(this.tokenizer.rules.inline.reflinkSearch.lastIndex);
21627           }
21628         }
21629       }
21630     }
21631     // Mask out other blocks
21632     while ((match = this.tokenizer.rules.inline.blockSkip.exec(maskedSrc)) != null) {
21633       maskedSrc = maskedSrc.slice(0, match.index) + '[' + repeatString('a', match[0].length - 2) + ']' + maskedSrc.slice(this.tokenizer.rules.inline.blockSkip.lastIndex);
21634     }
21635
21636     // Mask out escaped em & strong delimiters
21637     while ((match = this.tokenizer.rules.inline.escapedEmSt.exec(maskedSrc)) != null) {
21638       maskedSrc = maskedSrc.slice(0, match.index + match[0].length - 2) + '++' + maskedSrc.slice(this.tokenizer.rules.inline.escapedEmSt.lastIndex);
21639       this.tokenizer.rules.inline.escapedEmSt.lastIndex--;
21640     }
21641     while (src) {
21642       if (!keepPrevChar) {
21643         prevChar = '';
21644       }
21645       keepPrevChar = false;
21646
21647       // extensions
21648       if (this.options.extensions && this.options.extensions.inline && this.options.extensions.inline.some(function (extTokenizer) {
21649         if (token = extTokenizer.call({
21650           lexer: _this2
21651         }, src, tokens)) {
21652           src = src.substring(token.raw.length);
21653           tokens.push(token);
21654           return true;
21655         }
21656         return false;
21657       })) {
21658         continue;
21659       }
21660
21661       // escape
21662       if (token = this.tokenizer.escape(src)) {
21663         src = src.substring(token.raw.length);
21664         tokens.push(token);
21665         continue;
21666       }
21667
21668       // tag
21669       if (token = this.tokenizer.tag(src)) {
21670         src = src.substring(token.raw.length);
21671         lastToken = tokens[tokens.length - 1];
21672         if (lastToken && token.type === 'text' && lastToken.type === 'text') {
21673           lastToken.raw += token.raw;
21674           lastToken.text += token.text;
21675         } else {
21676           tokens.push(token);
21677         }
21678         continue;
21679       }
21680
21681       // link
21682       if (token = this.tokenizer.link(src)) {
21683         src = src.substring(token.raw.length);
21684         tokens.push(token);
21685         continue;
21686       }
21687
21688       // reflink, nolink
21689       if (token = this.tokenizer.reflink(src, this.tokens.links)) {
21690         src = src.substring(token.raw.length);
21691         lastToken = tokens[tokens.length - 1];
21692         if (lastToken && token.type === 'text' && lastToken.type === 'text') {
21693           lastToken.raw += token.raw;
21694           lastToken.text += token.text;
21695         } else {
21696           tokens.push(token);
21697         }
21698         continue;
21699       }
21700
21701       // em & strong
21702       if (token = this.tokenizer.emStrong(src, maskedSrc, prevChar)) {
21703         src = src.substring(token.raw.length);
21704         tokens.push(token);
21705         continue;
21706       }
21707
21708       // code
21709       if (token = this.tokenizer.codespan(src)) {
21710         src = src.substring(token.raw.length);
21711         tokens.push(token);
21712         continue;
21713       }
21714
21715       // br
21716       if (token = this.tokenizer.br(src)) {
21717         src = src.substring(token.raw.length);
21718         tokens.push(token);
21719         continue;
21720       }
21721
21722       // del (gfm)
21723       if (token = this.tokenizer.del(src)) {
21724         src = src.substring(token.raw.length);
21725         tokens.push(token);
21726         continue;
21727       }
21728
21729       // autolink
21730       if (token = this.tokenizer.autolink(src, mangle)) {
21731         src = src.substring(token.raw.length);
21732         tokens.push(token);
21733         continue;
21734       }
21735
21736       // url (gfm)
21737       if (!this.state.inLink && (token = this.tokenizer.url(src, mangle))) {
21738         src = src.substring(token.raw.length);
21739         tokens.push(token);
21740         continue;
21741       }
21742
21743       // text
21744       // prevent inlineText consuming extensions by clipping 'src' to extension start
21745       cutSrc = src;
21746       if (this.options.extensions && this.options.extensions.startInline) {
21747         (function () {
21748           var startIndex = Infinity;
21749           var tempSrc = src.slice(1);
21750           var tempStart = void 0;
21751           _this2.options.extensions.startInline.forEach(function (getStartIndex) {
21752             tempStart = getStartIndex.call({
21753               lexer: this
21754             }, tempSrc);
21755             if (typeof tempStart === 'number' && tempStart >= 0) {
21756               startIndex = Math.min(startIndex, tempStart);
21757             }
21758           });
21759           if (startIndex < Infinity && startIndex >= 0) {
21760             cutSrc = src.substring(0, startIndex + 1);
21761           }
21762         })();
21763       }
21764       if (token = this.tokenizer.inlineText(cutSrc, smartypants)) {
21765         src = src.substring(token.raw.length);
21766         if (token.raw.slice(-1) !== '_') {
21767           // Track prevChar before string of ____ started
21768           prevChar = token.raw.slice(-1);
21769         }
21770         keepPrevChar = true;
21771         lastToken = tokens[tokens.length - 1];
21772         if (lastToken && lastToken.type === 'text') {
21773           lastToken.raw += token.raw;
21774           lastToken.text += token.text;
21775         } else {
21776           tokens.push(token);
21777         }
21778         continue;
21779       }
21780       if (src) {
21781         var errMsg = 'Infinite loop on byte: ' + src.charCodeAt(0);
21782         if (this.options.silent) {
21783           console.error(errMsg);
21784           break;
21785         } else {
21786           throw new Error(errMsg);
21787         }
21788       }
21789     }
21790     return tokens;
21791   };
21792   _createClass(Lexer, null, [{
21793     key: "rules",
21794     get: function get() {
21795       return {
21796         block: block,
21797         inline: inline
21798       };
21799     }
21800   }]);
21801   return Lexer;
21802 }();
21803
21804 /**
21805  * Renderer
21806  */
21807 var Renderer = /*#__PURE__*/function () {
21808   function Renderer(options) {
21809     this.options = options || exports.defaults;
21810   }
21811   var _proto = Renderer.prototype;
21812   _proto.code = function code(_code, infostring, escaped) {
21813     var lang = (infostring || '').match(/\S*/)[0];
21814     if (this.options.highlight) {
21815       var out = this.options.highlight(_code, lang);
21816       if (out != null && out !== _code) {
21817         escaped = true;
21818         _code = out;
21819       }
21820     }
21821     _code = _code.replace(/\n$/, '') + '\n';
21822     if (!lang) {
21823       return '<pre><code>' + (escaped ? _code : escape(_code, true)) + '</code></pre>\n';
21824     }
21825     return '<pre><code class="' + this.options.langPrefix + escape(lang) + '">' + (escaped ? _code : escape(_code, true)) + '</code></pre>\n';
21826   }
21827
21828   /**
21829    * @param {string} quote
21830    */;
21831   _proto.blockquote = function blockquote(quote) {
21832     return "<blockquote>\n" + quote + "</blockquote>\n";
21833   };
21834   _proto.html = function html(_html) {
21835     return _html;
21836   }
21837
21838   /**
21839    * @param {string} text
21840    * @param {string} level
21841    * @param {string} raw
21842    * @param {any} slugger
21843    */;
21844   _proto.heading = function heading(text, level, raw, slugger) {
21845     if (this.options.headerIds) {
21846       var id = this.options.headerPrefix + slugger.slug(raw);
21847       return "<h" + level + " id=\"" + id + "\">" + text + "</h" + level + ">\n";
21848     }
21849
21850     // ignore IDs
21851     return "<h" + level + ">" + text + "</h" + level + ">\n";
21852   };
21853   _proto.hr = function hr() {
21854     return this.options.xhtml ? '<hr/>\n' : '<hr>\n';
21855   };
21856   _proto.list = function list(body, ordered, start) {
21857     var type = ordered ? 'ol' : 'ul',
21858       startatt = ordered && start !== 1 ? ' start="' + start + '"' : '';
21859     return '<' + type + startatt + '>\n' + body + '</' + type + '>\n';
21860   }
21861
21862   /**
21863    * @param {string} text
21864    */;
21865   _proto.listitem = function listitem(text) {
21866     return "<li>" + text + "</li>\n";
21867   };
21868   _proto.checkbox = function checkbox(checked) {
21869     return '<input ' + (checked ? 'checked="" ' : '') + 'disabled="" type="checkbox"' + (this.options.xhtml ? ' /' : '') + '> ';
21870   }
21871
21872   /**
21873    * @param {string} text
21874    */;
21875   _proto.paragraph = function paragraph(text) {
21876     return "<p>" + text + "</p>\n";
21877   }
21878
21879   /**
21880    * @param {string} header
21881    * @param {string} body
21882    */;
21883   _proto.table = function table(header, body) {
21884     if (body) body = "<tbody>" + body + "</tbody>";
21885     return '<table>\n' + '<thead>\n' + header + '</thead>\n' + body + '</table>\n';
21886   }
21887
21888   /**
21889    * @param {string} content
21890    */;
21891   _proto.tablerow = function tablerow(content) {
21892     return "<tr>\n" + content + "</tr>\n";
21893   };
21894   _proto.tablecell = function tablecell(content, flags) {
21895     var type = flags.header ? 'th' : 'td';
21896     var tag = flags.align ? "<" + type + " align=\"" + flags.align + "\">" : "<" + type + ">";
21897     return tag + content + ("</" + type + ">\n");
21898   }
21899
21900   /**
21901    * span level renderer
21902    * @param {string} text
21903    */;
21904   _proto.strong = function strong(text) {
21905     return "<strong>" + text + "</strong>";
21906   }
21907
21908   /**
21909    * @param {string} text
21910    */;
21911   _proto.em = function em(text) {
21912     return "<em>" + text + "</em>";
21913   }
21914
21915   /**
21916    * @param {string} text
21917    */;
21918   _proto.codespan = function codespan(text) {
21919     return "<code>" + text + "</code>";
21920   };
21921   _proto.br = function br() {
21922     return this.options.xhtml ? '<br/>' : '<br>';
21923   }
21924
21925   /**
21926    * @param {string} text
21927    */;
21928   _proto.del = function del(text) {
21929     return "<del>" + text + "</del>";
21930   }
21931
21932   /**
21933    * @param {string} href
21934    * @param {string} title
21935    * @param {string} text
21936    */;
21937   _proto.link = function link(href, title, text) {
21938     href = cleanUrl(this.options.sanitize, this.options.baseUrl, href);
21939     if (href === null) {
21940       return text;
21941     }
21942     var out = '<a href="' + href + '"';
21943     if (title) {
21944       out += ' title="' + title + '"';
21945     }
21946     out += '>' + text + '</a>';
21947     return out;
21948   }
21949
21950   /**
21951    * @param {string} href
21952    * @param {string} title
21953    * @param {string} text
21954    */;
21955   _proto.image = function image(href, title, text) {
21956     href = cleanUrl(this.options.sanitize, this.options.baseUrl, href);
21957     if (href === null) {
21958       return text;
21959     }
21960     var out = "<img src=\"" + href + "\" alt=\"" + text + "\"";
21961     if (title) {
21962       out += " title=\"" + title + "\"";
21963     }
21964     out += this.options.xhtml ? '/>' : '>';
21965     return out;
21966   };
21967   _proto.text = function text(_text) {
21968     return _text;
21969   };
21970   return Renderer;
21971 }();
21972
21973 /**
21974  * TextRenderer
21975  * returns only the textual part of the token
21976  */
21977 var TextRenderer = /*#__PURE__*/function () {
21978   function TextRenderer() {}
21979   var _proto = TextRenderer.prototype;
21980   // no need for block level renderers
21981   _proto.strong = function strong(text) {
21982     return text;
21983   };
21984   _proto.em = function em(text) {
21985     return text;
21986   };
21987   _proto.codespan = function codespan(text) {
21988     return text;
21989   };
21990   _proto.del = function del(text) {
21991     return text;
21992   };
21993   _proto.html = function html(text) {
21994     return text;
21995   };
21996   _proto.text = function text(_text) {
21997     return _text;
21998   };
21999   _proto.link = function link(href, title, text) {
22000     return '' + text;
22001   };
22002   _proto.image = function image(href, title, text) {
22003     return '' + text;
22004   };
22005   _proto.br = function br() {
22006     return '';
22007   };
22008   return TextRenderer;
22009 }();
22010
22011 /**
22012  * Slugger generates header id
22013  */
22014 var Slugger = /*#__PURE__*/function () {
22015   function Slugger() {
22016     this.seen = {};
22017   }
22018
22019   /**
22020    * @param {string} value
22021    */
22022   var _proto = Slugger.prototype;
22023   _proto.serialize = function serialize(value) {
22024     return value.toLowerCase().trim()
22025     // remove html tags
22026     .replace(/<[!\/a-z].*?>/ig, '')
22027     // remove unwanted chars
22028     .replace(/[\u2000-\u206F\u2E00-\u2E7F\\'!"#$%&()*+,./:;<=>?@[\]^`{|}~]/g, '').replace(/\s/g, '-');
22029   }
22030
22031   /**
22032    * Finds the next safe (unique) slug to use
22033    * @param {string} originalSlug
22034    * @param {boolean} isDryRun
22035    */;
22036   _proto.getNextSafeSlug = function getNextSafeSlug(originalSlug, isDryRun) {
22037     var slug = originalSlug;
22038     var occurenceAccumulator = 0;
22039     if (this.seen.hasOwnProperty(slug)) {
22040       occurenceAccumulator = this.seen[originalSlug];
22041       do {
22042         occurenceAccumulator++;
22043         slug = originalSlug + '-' + occurenceAccumulator;
22044       } while (this.seen.hasOwnProperty(slug));
22045     }
22046     if (!isDryRun) {
22047       this.seen[originalSlug] = occurenceAccumulator;
22048       this.seen[slug] = 0;
22049     }
22050     return slug;
22051   }
22052
22053   /**
22054    * Convert string to unique id
22055    * @param {object} [options]
22056    * @param {boolean} [options.dryrun] Generates the next unique slug without
22057    * updating the internal accumulator.
22058    */;
22059   _proto.slug = function slug(value, options) {
22060     if (options === void 0) {
22061       options = {};
22062     }
22063     var slug = this.serialize(value);
22064     return this.getNextSafeSlug(slug, options.dryrun);
22065   };
22066   return Slugger;
22067 }();
22068
22069 /**
22070  * Parsing & Compiling
22071  */
22072 var Parser = /*#__PURE__*/function () {
22073   function Parser(options) {
22074     this.options = options || exports.defaults;
22075     this.options.renderer = this.options.renderer || new Renderer();
22076     this.renderer = this.options.renderer;
22077     this.renderer.options = this.options;
22078     this.textRenderer = new TextRenderer();
22079     this.slugger = new Slugger();
22080   }
22081
22082   /**
22083    * Static Parse Method
22084    */
22085   Parser.parse = function parse(tokens, options) {
22086     var parser = new Parser(options);
22087     return parser.parse(tokens);
22088   }
22089
22090   /**
22091    * Static Parse Inline Method
22092    */;
22093   Parser.parseInline = function parseInline(tokens, options) {
22094     var parser = new Parser(options);
22095     return parser.parseInline(tokens);
22096   }
22097
22098   /**
22099    * Parse Loop
22100    */;
22101   var _proto = Parser.prototype;
22102   _proto.parse = function parse(tokens, top) {
22103     if (top === void 0) {
22104       top = true;
22105     }
22106     var out = '',
22107       i,
22108       j,
22109       k,
22110       l2,
22111       l3,
22112       row,
22113       cell,
22114       header,
22115       body,
22116       token,
22117       ordered,
22118       start,
22119       loose,
22120       itemBody,
22121       item,
22122       checked,
22123       task,
22124       checkbox,
22125       ret;
22126     var l = tokens.length;
22127     for (i = 0; i < l; i++) {
22128       token = tokens[i];
22129
22130       // Run any renderer extensions
22131       if (this.options.extensions && this.options.extensions.renderers && this.options.extensions.renderers[token.type]) {
22132         ret = this.options.extensions.renderers[token.type].call({
22133           parser: this
22134         }, token);
22135         if (ret !== false || !['space', 'hr', 'heading', 'code', 'table', 'blockquote', 'list', 'html', 'paragraph', 'text'].includes(token.type)) {
22136           out += ret || '';
22137           continue;
22138         }
22139       }
22140       switch (token.type) {
22141         case 'space':
22142           {
22143             continue;
22144           }
22145         case 'hr':
22146           {
22147             out += this.renderer.hr();
22148             continue;
22149           }
22150         case 'heading':
22151           {
22152             out += this.renderer.heading(this.parseInline(token.tokens), token.depth, unescape(this.parseInline(token.tokens, this.textRenderer)), this.slugger);
22153             continue;
22154           }
22155         case 'code':
22156           {
22157             out += this.renderer.code(token.text, token.lang, token.escaped);
22158             continue;
22159           }
22160         case 'table':
22161           {
22162             header = '';
22163
22164             // header
22165             cell = '';
22166             l2 = token.header.length;
22167             for (j = 0; j < l2; j++) {
22168               cell += this.renderer.tablecell(this.parseInline(token.header[j].tokens), {
22169                 header: true,
22170                 align: token.align[j]
22171               });
22172             }
22173             header += this.renderer.tablerow(cell);
22174             body = '';
22175             l2 = token.rows.length;
22176             for (j = 0; j < l2; j++) {
22177               row = token.rows[j];
22178               cell = '';
22179               l3 = row.length;
22180               for (k = 0; k < l3; k++) {
22181                 cell += this.renderer.tablecell(this.parseInline(row[k].tokens), {
22182                   header: false,
22183                   align: token.align[k]
22184                 });
22185               }
22186               body += this.renderer.tablerow(cell);
22187             }
22188             out += this.renderer.table(header, body);
22189             continue;
22190           }
22191         case 'blockquote':
22192           {
22193             body = this.parse(token.tokens);
22194             out += this.renderer.blockquote(body);
22195             continue;
22196           }
22197         case 'list':
22198           {
22199             ordered = token.ordered;
22200             start = token.start;
22201             loose = token.loose;
22202             l2 = token.items.length;
22203             body = '';
22204             for (j = 0; j < l2; j++) {
22205               item = token.items[j];
22206               checked = item.checked;
22207               task = item.task;
22208               itemBody = '';
22209               if (item.task) {
22210                 checkbox = this.renderer.checkbox(checked);
22211                 if (loose) {
22212                   if (item.tokens.length > 0 && item.tokens[0].type === 'paragraph') {
22213                     item.tokens[0].text = checkbox + ' ' + item.tokens[0].text;
22214                     if (item.tokens[0].tokens && item.tokens[0].tokens.length > 0 && item.tokens[0].tokens[0].type === 'text') {
22215                       item.tokens[0].tokens[0].text = checkbox + ' ' + item.tokens[0].tokens[0].text;
22216                     }
22217                   } else {
22218                     item.tokens.unshift({
22219                       type: 'text',
22220                       text: checkbox
22221                     });
22222                   }
22223                 } else {
22224                   itemBody += checkbox;
22225                 }
22226               }
22227               itemBody += this.parse(item.tokens, loose);
22228               body += this.renderer.listitem(itemBody, task, checked);
22229             }
22230             out += this.renderer.list(body, ordered, start);
22231             continue;
22232           }
22233         case 'html':
22234           {
22235             // TODO parse inline content if parameter markdown=1
22236             out += this.renderer.html(token.text);
22237             continue;
22238           }
22239         case 'paragraph':
22240           {
22241             out += this.renderer.paragraph(this.parseInline(token.tokens));
22242             continue;
22243           }
22244         case 'text':
22245           {
22246             body = token.tokens ? this.parseInline(token.tokens) : token.text;
22247             while (i + 1 < l && tokens[i + 1].type === 'text') {
22248               token = tokens[++i];
22249               body += '\n' + (token.tokens ? this.parseInline(token.tokens) : token.text);
22250             }
22251             out += top ? this.renderer.paragraph(body) : body;
22252             continue;
22253           }
22254         default:
22255           {
22256             var errMsg = 'Token with "' + token.type + '" type was not found.';
22257             if (this.options.silent) {
22258               console.error(errMsg);
22259               return;
22260             } else {
22261               throw new Error(errMsg);
22262             }
22263           }
22264       }
22265     }
22266     return out;
22267   }
22268
22269   /**
22270    * Parse Inline Tokens
22271    */;
22272   _proto.parseInline = function parseInline(tokens, renderer) {
22273     renderer = renderer || this.renderer;
22274     var out = '',
22275       i,
22276       token,
22277       ret;
22278     var l = tokens.length;
22279     for (i = 0; i < l; i++) {
22280       token = tokens[i];
22281
22282       // Run any renderer extensions
22283       if (this.options.extensions && this.options.extensions.renderers && this.options.extensions.renderers[token.type]) {
22284         ret = this.options.extensions.renderers[token.type].call({
22285           parser: this
22286         }, token);
22287         if (ret !== false || !['escape', 'html', 'link', 'image', 'strong', 'em', 'codespan', 'br', 'del', 'text'].includes(token.type)) {
22288           out += ret || '';
22289           continue;
22290         }
22291       }
22292       switch (token.type) {
22293         case 'escape':
22294           {
22295             out += renderer.text(token.text);
22296             break;
22297           }
22298         case 'html':
22299           {
22300             out += renderer.html(token.text);
22301             break;
22302           }
22303         case 'link':
22304           {
22305             out += renderer.link(token.href, token.title, this.parseInline(token.tokens, renderer));
22306             break;
22307           }
22308         case 'image':
22309           {
22310             out += renderer.image(token.href, token.title, token.text);
22311             break;
22312           }
22313         case 'strong':
22314           {
22315             out += renderer.strong(this.parseInline(token.tokens, renderer));
22316             break;
22317           }
22318         case 'em':
22319           {
22320             out += renderer.em(this.parseInline(token.tokens, renderer));
22321             break;
22322           }
22323         case 'codespan':
22324           {
22325             out += renderer.codespan(token.text);
22326             break;
22327           }
22328         case 'br':
22329           {
22330             out += renderer.br();
22331             break;
22332           }
22333         case 'del':
22334           {
22335             out += renderer.del(this.parseInline(token.tokens, renderer));
22336             break;
22337           }
22338         case 'text':
22339           {
22340             out += renderer.text(token.text);
22341             break;
22342           }
22343         default:
22344           {
22345             var errMsg = 'Token with "' + token.type + '" type was not found.';
22346             if (this.options.silent) {
22347               console.error(errMsg);
22348               return;
22349             } else {
22350               throw new Error(errMsg);
22351             }
22352           }
22353       }
22354     }
22355     return out;
22356   };
22357   return Parser;
22358 }();
22359
22360 /**
22361  * Marked
22362  */
22363 function marked(src, opt, callback) {
22364   // throw error in case of non string input
22365   if (typeof src === 'undefined' || src === null) {
22366     throw new Error('marked(): input parameter is undefined or null');
22367   }
22368   if (typeof src !== 'string') {
22369     throw new Error('marked(): input parameter is of type ' + Object.prototype.toString.call(src) + ', string expected');
22370   }
22371   if (typeof opt === 'function') {
22372     callback = opt;
22373     opt = null;
22374   }
22375   opt = merge({}, marked.defaults, opt || {});
22376   checkSanitizeDeprecation(opt);
22377   if (callback) {
22378     var highlight = opt.highlight;
22379     var tokens;
22380     try {
22381       tokens = Lexer.lex(src, opt);
22382     } catch (e) {
22383       return callback(e);
22384     }
22385     var done = function done(err) {
22386       var out;
22387       if (!err) {
22388         try {
22389           if (opt.walkTokens) {
22390             marked.walkTokens(tokens, opt.walkTokens);
22391           }
22392           out = Parser.parse(tokens, opt);
22393         } catch (e) {
22394           err = e;
22395         }
22396       }
22397       opt.highlight = highlight;
22398       return err ? callback(err) : callback(null, out);
22399     };
22400     if (!highlight || highlight.length < 3) {
22401       return done();
22402     }
22403     delete opt.highlight;
22404     if (!tokens.length) return done();
22405     var pending = 0;
22406     marked.walkTokens(tokens, function (token) {
22407       if (token.type === 'code') {
22408         pending++;
22409         setTimeout(function () {
22410           highlight(token.text, token.lang, function (err, code) {
22411             if (err) {
22412               return done(err);
22413             }
22414             if (code != null && code !== token.text) {
22415               token.text = code;
22416               token.escaped = true;
22417             }
22418             pending--;
22419             if (pending === 0) {
22420               done();
22421             }
22422           });
22423         }, 0);
22424       }
22425     });
22426     if (pending === 0) {
22427       done();
22428     }
22429     return;
22430   }
22431   function onError(e) {
22432     e.message += '\nPlease report this to https://github.com/markedjs/marked.';
22433     if (opt.silent) {
22434       return '<p>An error occurred:</p><pre>' + escape(e.message + '', true) + '</pre>';
22435     }
22436     throw e;
22437   }
22438   try {
22439     var _tokens = Lexer.lex(src, opt);
22440     if (opt.walkTokens) {
22441       if (opt.async) {
22442         return Promise.all(marked.walkTokens(_tokens, opt.walkTokens)).then(function () {
22443           return Parser.parse(_tokens, opt);
22444         })["catch"](onError);
22445       }
22446       marked.walkTokens(_tokens, opt.walkTokens);
22447     }
22448     return Parser.parse(_tokens, opt);
22449   } catch (e) {
22450     onError(e);
22451   }
22452 }
22453
22454 /**
22455  * Options
22456  */
22457
22458 marked.options = marked.setOptions = function (opt) {
22459   merge(marked.defaults, opt);
22460   changeDefaults(marked.defaults);
22461   return marked;
22462 };
22463 marked.getDefaults = getDefaults;
22464 marked.defaults = exports.defaults;
22465
22466 /**
22467  * Use Extension
22468  */
22469
22470 marked.use = function () {
22471   var extensions = marked.defaults.extensions || {
22472     renderers: {},
22473     childTokens: {}
22474   };
22475   for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
22476     args[_key] = arguments[_key];
22477   }
22478   args.forEach(function (pack) {
22479     // copy options to new object
22480     var opts = merge({}, pack);
22481
22482     // set async to true if it was set to true before
22483     opts.async = marked.defaults.async || opts.async;
22484
22485     // ==-- Parse "addon" extensions --== //
22486     if (pack.extensions) {
22487       pack.extensions.forEach(function (ext) {
22488         if (!ext.name) {
22489           throw new Error('extension name required');
22490         }
22491         if (ext.renderer) {
22492           // Renderer extensions
22493           var prevRenderer = extensions.renderers[ext.name];
22494           if (prevRenderer) {
22495             // Replace extension with func to run new extension but fall back if false
22496             extensions.renderers[ext.name] = function () {
22497               for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
22498                 args[_key2] = arguments[_key2];
22499               }
22500               var ret = ext.renderer.apply(this, args);
22501               if (ret === false) {
22502                 ret = prevRenderer.apply(this, args);
22503               }
22504               return ret;
22505             };
22506           } else {
22507             extensions.renderers[ext.name] = ext.renderer;
22508           }
22509         }
22510         if (ext.tokenizer) {
22511           // Tokenizer Extensions
22512           if (!ext.level || ext.level !== 'block' && ext.level !== 'inline') {
22513             throw new Error("extension level must be 'block' or 'inline'");
22514           }
22515           if (extensions[ext.level]) {
22516             extensions[ext.level].unshift(ext.tokenizer);
22517           } else {
22518             extensions[ext.level] = [ext.tokenizer];
22519           }
22520           if (ext.start) {
22521             // Function to check for start of token
22522             if (ext.level === 'block') {
22523               if (extensions.startBlock) {
22524                 extensions.startBlock.push(ext.start);
22525               } else {
22526                 extensions.startBlock = [ext.start];
22527               }
22528             } else if (ext.level === 'inline') {
22529               if (extensions.startInline) {
22530                 extensions.startInline.push(ext.start);
22531               } else {
22532                 extensions.startInline = [ext.start];
22533               }
22534             }
22535           }
22536         }
22537         if (ext.childTokens) {
22538           // Child tokens to be visited by walkTokens
22539           extensions.childTokens[ext.name] = ext.childTokens;
22540         }
22541       });
22542       opts.extensions = extensions;
22543     }
22544
22545     // ==-- Parse "overwrite" extensions --== //
22546     if (pack.renderer) {
22547       (function () {
22548         var renderer = marked.defaults.renderer || new Renderer();
22549         var _loop = function _loop(prop) {
22550           var prevRenderer = renderer[prop];
22551           // Replace renderer with func to run extension, but fall back if false
22552           renderer[prop] = function () {
22553             for (var _len3 = arguments.length, args = new Array(_len3), _key3 = 0; _key3 < _len3; _key3++) {
22554               args[_key3] = arguments[_key3];
22555             }
22556             var ret = pack.renderer[prop].apply(renderer, args);
22557             if (ret === false) {
22558               ret = prevRenderer.apply(renderer, args);
22559             }
22560             return ret;
22561           };
22562         };
22563         for (var prop in pack.renderer) {
22564           _loop(prop);
22565         }
22566         opts.renderer = renderer;
22567       })();
22568     }
22569     if (pack.tokenizer) {
22570       (function () {
22571         var tokenizer = marked.defaults.tokenizer || new Tokenizer();
22572         var _loop2 = function _loop2(prop) {
22573           var prevTokenizer = tokenizer[prop];
22574           // Replace tokenizer with func to run extension, but fall back if false
22575           tokenizer[prop] = function () {
22576             for (var _len4 = arguments.length, args = new Array(_len4), _key4 = 0; _key4 < _len4; _key4++) {
22577               args[_key4] = arguments[_key4];
22578             }
22579             var ret = pack.tokenizer[prop].apply(tokenizer, args);
22580             if (ret === false) {
22581               ret = prevTokenizer.apply(tokenizer, args);
22582             }
22583             return ret;
22584           };
22585         };
22586         for (var prop in pack.tokenizer) {
22587           _loop2(prop);
22588         }
22589         opts.tokenizer = tokenizer;
22590       })();
22591     }
22592
22593     // ==-- Parse WalkTokens extensions --== //
22594     if (pack.walkTokens) {
22595       var _walkTokens = marked.defaults.walkTokens;
22596       opts.walkTokens = function (token) {
22597         var values = [];
22598         values.push(pack.walkTokens.call(this, token));
22599         if (_walkTokens) {
22600           values = values.concat(_walkTokens.call(this, token));
22601         }
22602         return values;
22603       };
22604     }
22605     marked.setOptions(opts);
22606   });
22607 };
22608
22609 /**
22610  * Run callback for every token
22611  */
22612
22613 marked.walkTokens = function (tokens, callback) {
22614   var values = [];
22615   var _loop3 = function _loop3() {
22616     var token = _step.value;
22617     values = values.concat(callback.call(marked, token));
22618     switch (token.type) {
22619       case 'table':
22620         {
22621           for (var _iterator2 = _createForOfIteratorHelperLoose(token.header), _step2; !(_step2 = _iterator2()).done;) {
22622             var cell = _step2.value;
22623             values = values.concat(marked.walkTokens(cell.tokens, callback));
22624           }
22625           for (var _iterator3 = _createForOfIteratorHelperLoose(token.rows), _step3; !(_step3 = _iterator3()).done;) {
22626             var row = _step3.value;
22627             for (var _iterator4 = _createForOfIteratorHelperLoose(row), _step4; !(_step4 = _iterator4()).done;) {
22628               var _cell = _step4.value;
22629               values = values.concat(marked.walkTokens(_cell.tokens, callback));
22630             }
22631           }
22632           break;
22633         }
22634       case 'list':
22635         {
22636           values = values.concat(marked.walkTokens(token.items, callback));
22637           break;
22638         }
22639       default:
22640         {
22641           if (marked.defaults.extensions && marked.defaults.extensions.childTokens && marked.defaults.extensions.childTokens[token.type]) {
22642             // Walk any extensions
22643             marked.defaults.extensions.childTokens[token.type].forEach(function (childTokens) {
22644               values = values.concat(marked.walkTokens(token[childTokens], callback));
22645             });
22646           } else if (token.tokens) {
22647             values = values.concat(marked.walkTokens(token.tokens, callback));
22648           }
22649         }
22650     }
22651   };
22652   for (var _iterator = _createForOfIteratorHelperLoose(tokens), _step; !(_step = _iterator()).done;) {
22653     _loop3();
22654   }
22655   return values;
22656 };
22657
22658 /**
22659  * Parse Inline
22660  * @param {string} src
22661  */
22662 marked.parseInline = function (src, opt) {
22663   // throw error in case of non string input
22664   if (typeof src === 'undefined' || src === null) {
22665     throw new Error('marked.parseInline(): input parameter is undefined or null');
22666   }
22667   if (typeof src !== 'string') {
22668     throw new Error('marked.parseInline(): input parameter is of type ' + Object.prototype.toString.call(src) + ', string expected');
22669   }
22670   opt = merge({}, marked.defaults, opt || {});
22671   checkSanitizeDeprecation(opt);
22672   try {
22673     var tokens = Lexer.lexInline(src, opt);
22674     if (opt.walkTokens) {
22675       marked.walkTokens(tokens, opt.walkTokens);
22676     }
22677     return Parser.parseInline(tokens, opt);
22678   } catch (e) {
22679     e.message += '\nPlease report this to https://github.com/markedjs/marked.';
22680     if (opt.silent) {
22681       return '<p>An error occurred:</p><pre>' + escape(e.message + '', true) + '</pre>';
22682     }
22683     throw e;
22684   }
22685 };
22686
22687 /**
22688  * Expose
22689  */
22690 marked.Parser = Parser;
22691 marked.parser = Parser.parse;
22692 marked.Renderer = Renderer;
22693 marked.TextRenderer = TextRenderer;
22694 marked.Lexer = Lexer;
22695 marked.lexer = Lexer.lex;
22696 marked.Tokenizer = Tokenizer;
22697 marked.Slugger = Slugger;
22698 marked.parse = marked;
22699 var options = marked.options;
22700 var setOptions = marked.setOptions;
22701 var use = marked.use;
22702 var walkTokens = marked.walkTokens;
22703 var parseInline = marked.parseInline;
22704 var parse = marked;
22705 var parser = Parser.parse;
22706 var lexer = Lexer.lex;
22707
22708 exports.Lexer = Lexer;
22709 exports.Parser = Parser;
22710 exports.Renderer = Renderer;
22711 exports.Slugger = Slugger;
22712 exports.TextRenderer = TextRenderer;
22713 exports.Tokenizer = Tokenizer;
22714 exports.getDefaults = getDefaults;
22715 exports.lexer = lexer;
22716 exports.marked = marked;
22717 exports.options = options;
22718 exports.parse = parse;
22719 exports.parseInline = parseInline;
22720 exports.parser = parser;
22721 exports.setOptions = setOptions;
22722 exports.use = use;
22723 exports.walkTokens = walkTokens;
22724
22725
22726 /***/ }),
22727
22728 /***/ "./src/test-data.json":
22729 /*!****************************!*\
22730   !*** ./src/test-data.json ***!
22731   \****************************/
22732 /***/ ((module) => {
22733
22734 "use strict";
22735 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"}}}');
22736
22737 /***/ })
22738
22739 /******/        });
22740 /************************************************************************/
22741 /******/        // The module cache
22742 /******/        var __webpack_module_cache__ = {};
22743 /******/        
22744 /******/        // The require function
22745 /******/        function __webpack_require__(moduleId) {
22746 /******/                // Check if module is in cache
22747 /******/                var cachedModule = __webpack_module_cache__[moduleId];
22748 /******/                if (cachedModule !== undefined) {
22749 /******/                        return cachedModule.exports;
22750 /******/                }
22751 /******/                // Create a new module (and put it into the cache)
22752 /******/                var module = __webpack_module_cache__[moduleId] = {
22753 /******/                        id: moduleId,
22754 /******/                        loaded: false,
22755 /******/                        exports: {}
22756 /******/                };
22757 /******/        
22758 /******/                // Execute the module function
22759 /******/                __webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__);
22760 /******/        
22761 /******/                // Flag the module as loaded
22762 /******/                module.loaded = true;
22763 /******/        
22764 /******/                // Return the exports of the module
22765 /******/                return module.exports;
22766 /******/        }
22767 /******/        
22768 /************************************************************************/
22769 /******/        /* webpack/runtime/global */
22770 /******/        (() => {
22771 /******/                __webpack_require__.g = (function() {
22772 /******/                        if (typeof globalThis === 'object') return globalThis;
22773 /******/                        try {
22774 /******/                                return this || new Function('return this')();
22775 /******/                        } catch (e) {
22776 /******/                                if (typeof window === 'object') return window;
22777 /******/                        }
22778 /******/                })();
22779 /******/        })();
22780 /******/        
22781 /******/        /* webpack/runtime/node module decorator */
22782 /******/        (() => {
22783 /******/                __webpack_require__.nmd = (module) => {
22784 /******/                        module.paths = [];
22785 /******/                        if (!module.children) module.children = [];
22786 /******/                        return module;
22787 /******/                };
22788 /******/        })();
22789 /******/        
22790 /************************************************************************/
22791 /******/        
22792 /******/        // startup
22793 /******/        // Load entry module and return exports
22794 /******/        // This entry module is referenced by other modules so it can't be inlined
22795 /******/        var __webpack_exports__ = __webpack_require__("./src/client.ts");
22796 /******/        
22797 /******/ })()
22798 ;
22799 //# 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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O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxVQUFVO0FBQ3pCLGVBQWUsU0FBUztBQUN4QixpQkFBaUIsVUFBVTtBQUMzQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsU0FBUztBQUN4QixpQkFBaUIsVUFBVTtBQUMzQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsVUFBVTtBQUN6QixlQUFlLFFBQVE7QUFDdkIsZUFBZSxHQUFHO0FBQ2xCLGlCQUFpQixVQUFVO0FBQzNCO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsUUFBUTtBQUN2QixpQkFBaUIsVUFBVTtBQUMzQjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLFVBQVU7QUFDekIsaUJBQWlCLFVBQVU7QUFDM0I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLFVBQVU7QUFDekIsaUJBQWlCLFVBQVU7QUFDM0I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNB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Q0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLFFBQVE7QUFDdkIsZUFBZSxRQUFRO0FBQ3ZCLGVBQWUsUUFBUTtBQUN2QixlQUFlLFVBQVU7QUFDekIsZUFBZSxVQUFVO0FBQ3pCLGVBQWUsUUFBUTtBQUN2QixpQkFBaUIsU0FBUztBQUMxQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLFVBQVU7QUFDekIsaUJBQWlCLFVBQVU7QUFDM0I7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLFFBQVE7QUFDdkIsaUJBQWlCLE9BQU87QUFDeEI7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsUUFBUTtBQUN2QixpQkFBaUIsT0FBTztBQUN4QjtBQUNBO0FBQ0E7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QTtBQUNBLGVBQWU7QUFDZjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWU7QUFDZjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQixRQUFRO0FBQ3pCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCLFFBQVE7QUFDekI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWU7QUFDZjtBQUNBO0FBQ0EsZUFBZTtBQUNmO0FBQ0E7QUFDQSxlQUFlO0FBQ2Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsZUFBZTtBQUNmOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCLFFBQVE7QUFDekI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLEdBQUc7QUFDbEIsaUJBQWlCLFFBQVE7QUFDekI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQixRQUFRO0FBQ3pCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7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QUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxVQUFVO0FBQ3pCLGVBQWUsUUFBUTtBQUN2QixlQUFlLFFBQVEsV0FBVztBQUNsQyxlQUFlLFNBQVM7QUFDeEI7QUFDQSxlQUFlLFFBQVE7QUFDdkI7QUFDQSxlQUFlLFNBQVM7QUFDeEI7QUFDQSxpQkFBaUIsVUFBVTtBQUMzQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxRQUFRO0FBQ1I7QUFDQTtBQUNBLG1EQUFtRCxpQkFBaUI7QUFDcEU7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxVQUFVO0FBQ3pCLGVBQWUsTUFBTTtBQUNyQixpQkFBaUIsUUFBUTtBQUN6QjtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQVE7QUFDUjtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7O0FBRUw7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsVUFBVTtBQUN6QixlQUFlLFFBQVE7QUFDdkIsZUFBZSxNQUFNO0FBQ3JCLGlCQUFpQixRQUFRO0FBQ3pCO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsUUFBUTtBQUNSO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSzs7QUFFTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsVUFBVTtBQUN6QixpQkFBaUIsVUFBVTtBQUMzQjtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQVE7QUFDUjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxVQUFVO0FBQ3pCLGVBQWUsVUFBVTtBQUN6QixpQkFBaUIsVUFBVTtBQUMzQjtBQUNBO0FBQ0Esc0JBQXNCO0FBQ3RCLHFCQUFxQjtBQUNyQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsVUFBVTtBQUN6QixpQkFBaUIsVUFBVTtBQUMzQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxVQUFVO0FBQ3pCLGlCQUFpQixVQUFVO0FBQzNCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxVQUFVO0FBQ3pCLGVBQWUsMEJBQTBCO0FBQ3pDO0FBQ0EsaUJBQWlCLFVBQVU7QUFDM0I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsUUFBUTtBQUNSO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1AsS0FBSzs7QUFFTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLFVBQVU7QUFDekIsZUFBZSxNQUFNO0FBQ3JCLGlCQUFpQixVQUFVO0FBQzNCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7O0FBRUw7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsVUFBVTtBQUN6QixlQUFlLE1BQU07QUFDckIsaUJBQWlCLFVBQVU7QUFDM0I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSzs7QUFFTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsVUFBVTtBQUN6QixlQUFlLHNCQUFzQjtBQUNyQyxpQkFBaUIsVUFBVTtBQUMzQjtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQVE7QUFDUjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLOztBQUVMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsVUFBVTtBQUN6QixlQUFlLFFBQVE7QUFDdkIsaUJBQWlCLFVBQVU7QUFDM0I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQVE7QUFDUjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsVUFBVTtBQUN6QixlQUFlLFFBQVE7QUFDdkIsaUJBQWlCLFVBQVU7QUFDM0I7QUFDQTtBQUNBO0FBQ0E7QUFDQSxRQUFRO0FBQ1I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQVE7QUFDUjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNB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QUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxHQUFHO0FBQ2xCLGlCQUFpQixTQUFTO0FBQzFCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLEdBQUc7QUFDbEIsaUJBQWlCLFNBQVM7QUFDMUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxHQUFHO0FBQ2xCLGlCQUFpQixTQUFTO0FBQzFCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsR0FBRztBQUNsQixpQkFBaUIsU0FBUztBQUMxQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLEdBQUc7QUFDbEIsaUJBQWlCLFNBQVM7QUFDMUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxHQUFHO0FBQ2xCLGlCQUFpQixTQUFTO0FBQzFCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsR0FBRztBQUNsQixpQkFBaUIsU0FBUztBQUMxQjtB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QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsR0FBRztBQUNsQixpQkFBaUIsU0FBUztBQUMxQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsR0FBRztBQUNsQixpQkFBaUIsU0FBUztBQUMxQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxHQUFHO0FBQ2xCLGlCQUFpQixTQUFTO0FBQzFCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsR0FBRztBQUNsQixpQkFBaUIsU0FBUztBQUMxQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLEdBQUc7QUFDbEIsaUJBQWlCLFNBQVM7QUFDMUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxHQUFHO0FBQ2xCLGlCQUFpQixTQUFTO0FBQzFCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsR0FBRztBQUNsQixpQkFBaUIsU0FBUztBQUMxQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7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Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxRQUFRO0FBQ3ZCLGVBQWUsUUFBUTtBQUN2QixlQUFlLFFBQVE7QUFDdkIsaUJBQWlCLFNBQVM7QUFDMUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQVE7QUFDUjtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxRQUFRO0FBQ3ZCLGVBQWUsUUFBUTtBQUN2QixlQUFlLFNBQVM7QUFDeEIsaUJBQWlCLFFBQVE7QUFDekI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsUUFBUTtBQUN2QixpQkFBaUIsUUFBUTtBQUN6QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSzs7QUFFTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxRQUFRO0FBQ3ZCLGlCQUFpQixRQUFRO0FBQ3pCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsUUFBUTtBQUN2QixpQkFBaUIsUUFBUTtBQUN6QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLFFBQVE7QUFDdkIsZUFBZSxRQUFRO0FBQ3ZCLGVBQWUsUUFBUTtBQUN2QixpQkFBaUIsU0FBUztBQUMxQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxRQUFRO0FBQ3ZCLGlCQUFpQixRQUFRO0FBQ3pCO0FBQ0E7QUFDQTtBQUNBLGtDQUFrQztBQUNsQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0Esa0NBQWtDLEtBQUs7QUFDdkM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsUUFBUTtBQUN2QixpQkFBaUIsUUFBUTtBQUN6QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLFFBQVE7QUFDdkIsaUJBQWlCLFFBQVE7QUFDekI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLOztBQUVMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxRQUFRO0FBQ3ZCLGlCQUFpQixRQUFRO0FBQ3pCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSzs7QUFFTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsUUFBUTtBQUN2QixpQkFBaUIsUUFBUTtBQUN6QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsUUFBUTtBQUN2QixlQUFlLFFBQVE7QUFDdkIsZUFBZSxRQUFRO0FBQ3ZCLGlCQUFpQixRQUFRO0FBQ3pCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxRQUFRO0FBQ3ZCLGVBQWUsUUFBUTtBQUN2QixlQUFlLFFBQVE7QUFDdkIsaUJBQWlCLFFBQVE7QUFDekI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLFFBQVE7QUFDdkIsZUFBZSxRQUFRO0FBQ3ZCLGVBQWUsUUFBUTtBQUN2QixpQkFBaUIsUUFBUTtBQUN6QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxRQUFRO0FBQ3ZCLGVBQWUsUUFBUTtBQUN2QixnQkFBZ0IsUUFBUTtBQUN4QixpQkFBaUIsUUFBUTtBQUN6QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsUUFBUTtBQUNSO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxRQUFRO0FBQ3ZCLGVBQWUsUUFBUTtBQUN2QixnQkFBZ0IsUUFBUTtBQUN4QixpQkFBaUIsUUFBUTtBQUN6QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsUUFBUTtBQUNSO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxRQUFRO0FBQ3ZCLGVBQWUsZUFBZTtBQUM5QixlQUFlLGlCQUFpQjtBQUNoQyxpQkFBaUIsUUFBUTtBQUN6QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsUUFBUTtBQUN2QixpQkFBaUIsUUFBUTtBQUN6QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7O0FBRUw7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLFFBQVE7QUFDdkIsZUFBZSxlQUFlO0FBQzlCLGVBQWUsUUFBUTtBQUN2QixpQkFBaUIsT0FBTztBQUN4QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxRQUFRO0FBQ3ZCLGlCQUFpQixRQUFRO0FBQ3pCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSzs7QUFFTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsUUFBUTtBQUN2QixlQUFlLFFBQVE7QUFDdkIsZUFBZSxRQUFRO0FBQ3ZCLGlCQUFpQixTQUFTO0FBQzFCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsUUFBUTtBQUN2QixlQUFlLFFBQVEsV0FBVztBQUNsQyxlQUFlLFFBQVE7QUFDdkI7QUFDQSxlQUFlLFFBQVE7QUFDdkI7QUFDQSxlQUFlLFFBQVE7QUFDdkI7QUFDQSxlQUFlLFFBQVE7QUFDdkI7QUFDQSxlQUFlLFFBQVE7QUFDdkI7QUFDQSxlQUFlLFFBQVE7QUFDdkI7QUFDQSxnQkFBZ0IsUUFBUTtBQUN4QixpQkFBaUIsVUFBVTtBQUMzQjtBQUNBO0FBQ0E7QUFDQTtBQUNBLGtCQUFrQixnQkFBZ0I7QUFDbEM7QUFDQTtBQUNBO0FBQ0E7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QTtBQUNBLGVBQWUsT0FBTztBQUN0QixlQUFlLFVBQVU7QUFDekIsaUJBQWlCLFFBQVE7QUFDekI7QUFDQTtBQUNBLHdCQUF3QixRQUFRLElBQUksUUFBUSxJQUFJLFFBQVEsSUFBSSxRQUFRO0FBQ3BFO0FBQ0Esc0NBQXNDLGFBQWE7QUFDbkQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQSxLQUFLLE9BQU8sZ0JBQWdCOztBQUU1Qjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYztBQUNkO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsS0FBSzs7QUFFTDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0E7QUFDQSxXQUFXO0FBQ1g7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7O0FBRUw7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQSxLQUFLOztBQUVMO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxLQUFLOztBQUVMO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxLQUFLOztBQUVMO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUCxLQUFLOztBQUVMO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQVE7QUFDUjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLG9DQUFvQywyREFBMkQ7QUFDL0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7O0FBRUw7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FB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QUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVMsc0JBQXNCO0FBQy9CO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsUUFBUTtBQUNSO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVMsa0JBQWtCO0FBQzNCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxXQUFXLFFBQVE7QUFDbkIsV0FBVyxRQUFRO0FBQ25CLFdBQVcsU0FBUztBQUNwQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVMsT0FBTztBQUNoQjtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxXQUFXLFFBQVE7QUFDbkIsV0FBVyxRQUFRO0FBQ25CO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxvQ0FBb0MsSUFBSTtBQUN4QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsOEJBQThCLElBQUk7QUFDbEM7QUFDQTtBQUNBOztBQUVBO0FBQ0Esc0NBQXNDLElBQUk7O0FBRTFDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1YsMENBQTBDO0FBQzFDLDRDQUE0QztBQUM1QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsK0NBQStDLGtDQUFrQyxhQUFhLElBQUk7QUFDbEcsdUNBQXVDLGtDQUFrQyxTQUFTLEdBQUcsU0FBUyxHQUFHLFdBQVcsR0FBRztBQUMvRyxnREFBZ0Qsa0NBQWtDO0FBQ2xGLGlEQUFpRCxrQ0FBa0M7O0FBRW5GO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSw4Q0FBOEMsSUFBSSxNQUFNLEVBQUU7QUFDMUQ7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFlBQVk7QUFDWjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLGtCQUFrQixPQUFPO0FBQ3pCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFdBQVc7QUFDWDtBQUNBO0FBQ0EsV0FBVztBQUNYO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0Esb0JBQW9CLE9BQU87QUFDM0I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esb0JBQW9CLE9BQU87QUFDM0I7QUFDQTtBQUNBLFlBQVk7QUFDWjtBQUNBLFlBQVk7QUFDWjtBQUNBLFlBQVk7QUFDWjtBQUNBO0FBQ0E7QUFDQTtBQUNBLG9CQUFvQixPQUFPO0FBQzNCO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsV0FBVztBQUNYOztBQUVBOztBQUVBO0FBQ0E7QUFDQSxvQkFBb0IsT0FBTztBQUMzQjtBQUNBOztBQUVBO0FBQ0E7QUFDQSxvQkFBb0IsT0FBTztBQUMzQjtBQUNBLHNCQUFzQixnQkFBZ0I7QUFDdEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsUUFBUTtBQUNSO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsUUFBUTtBQUNSO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQVE7QUFDUjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQVE7QUFDUjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLGdEQUFnRCxFQUFFLEdBQUcsR0FBRztBQUN4RDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLCtCQUErQjs7QUFFL0I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0E7QUFDQSxzQkFBc0I7QUFDdEI7QUFDQTs7QUFFQTtBQUNBLHNDQUFzQzs7QUFFdEM7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsUUFBUTtBQUNSO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNB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QTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0EsV0FBVztBQUNYO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0EsV0FBVztBQUNYO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQSxDQUFDOztBQUVEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxhQUFhLFFBQVE7QUFDckI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxhQUFhLFFBQVE7QUFDckIsYUFBYSxRQUFRO0FBQ3JCLGFBQWEsUUFBUTtBQUNyQixhQUFhLEtBQUs7QUFDbEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxhQUFhLFFBQVE7QUFDckI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxhQUFhLFFBQVE7QUFDckI7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxhQUFhLFFBQVE7QUFDckIsYUFBYSxRQUFRO0FBQ3JCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxhQUFhLFFBQVE7QUFDckI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxhQUFhLFFBQVE7QUFDckI7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxhQUFhLFFBQVE7QUFDckI7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxhQUFhLFFBQVE7QUFDckI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxhQUFhLFFBQVE7QUFDckI7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxhQUFhLFFBQVE7QUFDckIsYUFBYSxRQUFRO0FBQ3JCLGFBQWEsUUFBUTtBQUNyQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLGFBQWEsUUFBUTtBQUNyQixhQUFhLFFBQVE7QUFDckIsYUFBYSxRQUFRO0FBQ3JCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDOztBQUVEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7O0FBRUQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxhQUFhLFFBQVE7QUFDckI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSwyREFBMkQsV0FBVyxFQUFFO0FBQ3hFOztBQUVBO0FBQ0E7QUFDQSxhQUFhLFFBQVE7QUFDckIsYUFBYSxTQUFTO0FBQ3RCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQVE7QUFDUjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsYUFBYSxRQUFRO0FBQ3JCLGFBQWEsU0FBUztBQUN0QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7O0FBRUQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQkFBZ0IsT0FBTztBQUN2Qjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSx3QkFBd0IsUUFBUTtBQUNoQztBQUNBO0FBQ0E7QUFDQSxlQUFlO0FBQ2Y7QUFDQTtBQUNBO0FBQ0E7QUFDQSx3QkFBd0IsUUFBUTtBQUNoQztBQUNBO0FBQ0E7QUFDQSwwQkFBMEIsUUFBUTtBQUNsQztBQUNBO0FBQ0E7QUFDQSxpQkFBaUI7QUFDakI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx3QkFBd0IsUUFBUTtBQUNoQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxvQkFBb0I7QUFDcEI7QUFDQTtBQUNBO0FBQ0EscUJBQXFCO0FBQ3JCO0FBQ0Esa0JBQWtCO0FBQ2xCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWM7QUFDZDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdCQUFnQixPQUFPO0FBQ3ZCOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7O0FBRUQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0JBQWdCLDRCQUE0QjtBQUM1QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBO0FB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O0FBQ3BCLGlCQUFpQjtBQUNqQixtQkFBbUI7QUFDbkIsYUFBYTtBQUNiLGNBQWM7QUFDZCxlQUFlO0FBQ2YsYUFBYTtBQUNiLG1CQUFtQjtBQUNuQixjQUFjO0FBQ2Qsa0JBQWtCO0FBQ2xCLFdBQVc7QUFDWCxrQkFBa0I7Ozs7Ozs7Ozs7Ozs7Ozs7OztVQ2xxRmxCO1VBQ0E7O1VBRUE7VUFDQTtVQUNBO1VBQ0E7VUFDQTtVQUNBO1VBQ0E7VUFDQTtVQUNBO1VBQ0E7VUFDQTtVQUNBO1VBQ0E7O1VBRUE7VUFDQTs7VUFFQTtVQUNBOztVQUVBO1VBQ0E7VUFDQTs7Ozs7V0N6QkE7V0FDQTtXQUNBO1dBQ0E7V0FDQSxHQUFHO1dBQ0g7V0FDQTtXQUNBLENBQUM7Ozs7O1dDUEQ7V0FDQTtXQUNBO1dBQ0E7V0FDQTs7Ozs7VUVKQTtVQUNBO1VBQ0E7VUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL291dGxpbmUtYnJvd3Nlci8uL25vZGVfbW9kdWxlcy9rZXlib2FyZGpzL2Rpc3Qva2V5Ym9hcmQuanMiLCJ3ZWJwYWNrOi8vb3V0bGluZS1icm93c2VyLy4vbm9kZV9tb2R1bGVzL2xvZGFzaC9sb2Rhc2guanMiLCJ3ZWJwYWNrOi8vb3V0bGluZS1icm93c2VyLy4vc3JjL2NsaWVudC50cyIsIndlYnBhY2s6Ly9vdXRsaW5lLWJyb3dzZXIvLi9zcmMvY3Vyc29yLnRzIiwid2VicGFjazovL291dGxpbmUtYnJvd3Nlci8uL3NyYy9oZWxwLnRzIiwid2VicGFjazovL291dGxpbmUtYnJvd3Nlci8uL3NyYy9vdXRsaW5lLnRzIiwid2VicGFjazovL291dGxpbmUtYnJvd3Nlci8uL25vZGVfbW9kdWxlcy91dWlkL2Rpc3QvY29tbW9uanMtYnJvd3Nlci9pbmRleC5qcyIsIndlYnBhY2s6Ly9vdXRsaW5lLWJyb3dzZXIvLi9ub2RlX21vZHVsZXMvdXVpZC9kaXN0L2NvbW1vbmpzLWJyb3dzZXIvbWQ1LmpzIiwid2VicGFjazovL291dGxpbmUtYnJvd3Nlci8uL25vZGVfbW9kdWxlcy91dWlkL2Rpc3QvY29tbW9uanMtYnJvd3Nlci9uYXRpdmUuanMiLCJ3ZWJwYWNrOi8vb3V0bGluZS1icm93c2VyLy4vbm9kZV9tb2R1bGVzL3V1aWQvZGlzdC9jb21tb25qcy1icm93c2VyL25pbC5qcyIsIndlYnBhY2s6Ly9vdXRsaW5lLWJyb3dzZXIvLi9ub2RlX21vZHVsZXMvdXVpZC9kaXN0L2NvbW1vbmpzLWJyb3dzZXIvcGFyc2UuanMiLCJ3ZWJwYWNrOi8vb3V0bGluZS1icm93c2VyLy4vbm9kZV9tb2R1bGVzL3V1aWQvZGlzdC9jb21tb25qcy1icm93c2VyL3JlZ2V4LmpzIiwid2VicGFjazovL291dGxpbmUtYnJvd3Nlci8uL25vZGVfbW9kdWxlcy91dWlkL2Rpc3QvY29tbW9uanMtYnJvd3Nlci9ybmcuanMiLCJ3ZWJwYWNrOi8vb3V0bGluZS1icm93c2VyLy4vbm9kZV9tb2R1bGVzL3V1aWQvZGlzdC9jb21tb25qcy1icm93c2VyL3NoYTEuanMiLCJ3ZWJwYWNrOi8vb3V0bGluZS1icm93c2VyLy4vbm9kZV9tb2R1bGVzL3V1aWQvZGlzdC9jb21tb25qcy1icm93c2VyL3N0cmluZ2lmeS5qcyIsIndlYnBhY2s6Ly9vdXRsaW5lLWJyb3dzZXIvLi9ub2RlX21vZHVsZXMvdXVpZC9kaXN0L2NvbW1vbmpzLWJyb3dzZXIvdjEuanMiLCJ3ZWJwYWNrOi8vb3V0bGluZS1icm93c2VyLy4vbm9kZV9tb2R1bGVzL3V1aWQvZGlzdC9jb21tb25qcy1icm93c2VyL3YzLmpzIiwid2VicGFjazovL291dGxpbmUtYnJvd3Nlci8uL25vZGVfbW9kdWxlcy91dWlkL2Rpc3QvY29tbW9uanMtYnJvd3Nlci92MzUuanMiLCJ3ZWJwYWNrOi8vb3V0bGluZS1icm93c2VyLy4vbm9kZV9tb2R1bGVzL3V1aWQvZGlzdC9jb21tb25qcy1icm93c2VyL3Y0LmpzIiwid2VicGFjazovL291dGxpbmUtYnJvd3Nlci8uL25vZGVfbW9kdWxlcy91dWlkL2Rpc3QvY29tbW9uanMtYnJvd3Nlci92NS5qcyIsIndlYnBhY2s6Ly9vdXRsaW5lLWJyb3dzZXIvLi9ub2RlX21vZHVsZXMvdXVpZC9kaXN0L2NvbW1vbmpzLWJyb3dzZXIvdmFsaWRhdGUuanMiLCJ3ZWJwYWNrOi8vb3V0bGluZS1icm93c2VyLy4vbm9kZV9tb2R1bGVzL3V1aWQvZGlzdC9jb21tb25qcy1icm93c2VyL3ZlcnNpb24uanMiLCJ3ZWJwYWNrOi8vb3V0bGluZS1icm93c2VyLy4vbm9kZV9tb2R1bGVzL21hcmtlZC9saWIvbWFya2VkLmNqcyIsIndlYnBhY2s6Ly9vdXRsaW5lLWJyb3dzZXIvd2VicGFjay9ib290c3RyYXAiLCJ3ZWJwYWNrOi8vb3V0bGluZS1icm93c2VyL3dlYnBhY2svcnVudGltZS9nbG9iYWwiLCJ3ZWJwYWNrOi8vb3V0bGluZS1icm93c2VyL3dlYnBhY2svcnVudGltZS9ub2RlIG1vZHVsZSBkZWNvcmF0b3IiLCJ3ZWJwYWNrOi8vb3V0bGluZS1icm93c2VyL3dlYnBhY2svYmVmb3JlLXN0YXJ0dXAiLCJ3ZWJwYWNrOi8vb3V0bGluZS1icm93c2VyL3dlYnBhY2svc3RhcnR1cCIsIndlYnBhY2s6Ly9vdXRsaW5lLWJyb3dzZXIvd2VicGFjay9hZnRlci1zdGFydHVwIl0sInNvdXJjZXNDb250ZW50IjpbIihmdW5jdGlvbiAoZ2xvYmFsLCBmYWN0b3J5KSB7XG4gIHR5cGVvZiBleHBvcnRzID09PSAnb2JqZWN0JyAmJiB0eXBlb2YgbW9kdWxlICE9PSAndW5kZWZpbmVkJyA/IG1vZHVsZS5leHBvcnRzID0gZmFjdG9yeSgpIDpcbiAgdHlwZW9mIGRlZmluZSA9PT0gJ2Z1bmN0aW9uJyAmJiBkZWZpbmUuYW1kID8gZGVmaW5lKGZhY3RvcnkpIDpcbiAgKGdsb2JhbCA9IGdsb2JhbCB8fCBzZWxmLCBnbG9iYWwua2V5Ym9hcmRKUyA9IGZhY3RvcnkoKSk7XG59KHRoaXMsIChmdW5jdGlvbiAoKSB7ICd1c2Ugc3RyaWN0JztcblxuICBmdW5jdGlvbiBfdHlwZW9mKG9iaikge1xuICAgIFwiQGJhYmVsL2hlbHBlcnMgLSB0eXBlb2ZcIjtcblxuICAgIGlmICh0eXBlb2YgU3ltYm9sID09PSBcImZ1bmN0aW9uXCIgJiYgdHlwZW9mIFN5bWJvbC5pdGVyYXRvciA9PT0gXCJzeW1ib2xcIikge1xuICAgICAgX3R5cGVvZiA9IGZ1bmN0aW9uIChvYmopIHtcbiAgICAgICAgcmV0dXJuIHR5cGVvZiBvYmo7XG4gICAgICB9O1xuICAgIH0gZWxzZSB7XG4gICAgICBfdHlwZW9mID0gZnVuY3Rpb24gKG9iaikge1xuICAgICAgICByZXR1cm4gb2JqICYmIHR5cGVvZiBTeW1ib2wgPT09IFwiZnVuY3Rpb25cIiAmJiBvYmouY29uc3RydWN0b3IgPT09IFN5bWJvbCAmJiBvYmogIT09IFN5bWJvbC5wcm90b3R5cGUgPyBcInN5bWJvbFwiIDogdHlwZW9mIG9iajtcbiAgICAgIH07XG4gICAgfVxuXG4gICAgcmV0dXJuIF90eXBlb2Yob2JqKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIF9jbGFzc0NhbGxDaGVjayhpbnN0YW5jZSwgQ29uc3RydWN0b3IpIHtcbiAgICBpZiAoIShpbnN0YW5jZSBpbnN0YW5jZW9mIENvbnN0cnVjdG9yKSkge1xuICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkNhbm5vdCBjYWxsIGEgY2xhc3MgYXMgYSBmdW5jdGlvblwiKTtcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiBfZGVmaW5lUHJvcGVydGllcyh0YXJnZXQsIHByb3BzKSB7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBwcm9wcy5sZW5ndGg7IGkrKykge1xuICAgICAgdmFyIGRlc2NyaXB0b3IgPSBwcm9wc1tpXTtcbiAgICAgIGRlc2NyaXB0b3IuZW51bWVyYWJsZSA9IGRlc2NyaXB0b3IuZW51bWVyYWJsZSB8fCBmYWxzZTtcbiAgICAgIGRlc2NyaXB0b3IuY29uZmlndXJhYmxlID0gdHJ1ZTtcbiAgICAgIGlmIChcInZhbHVlXCIgaW4gZGVzY3JpcHRvcikgZGVzY3JpcHRvci53cml0YWJsZSA9IHRydWU7XG4gICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkodGFyZ2V0LCBkZXNjcmlwdG9yLmtleSwgZGVzY3JpcHRvcik7XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gX2NyZWF0ZUNsYXNzKENvbnN0cnVjdG9yLCBwcm90b1Byb3BzLCBzdGF0aWNQcm9wcykge1xuICAgIGlmIChwcm90b1Byb3BzKSBfZGVmaW5lUHJvcGVydGllcyhDb25zdHJ1Y3Rvci5wcm90b3R5cGUsIHByb3RvUHJvcHMpO1xuICAgIGlmIChzdGF0aWNQcm9wcykgX2RlZmluZVByb3BlcnRpZXMoQ29uc3RydWN0b3IsIHN0YXRpY1Byb3BzKTtcbiAgICByZXR1cm4gQ29uc3RydWN0b3I7XG4gIH1cblxuICBmdW5jdGlvbiBfdG9Db25zdW1hYmxlQXJyYXkoYXJyKSB7XG4gICAgcmV0dXJuIF9hcnJheVdpdGhvdXRIb2xlcyhhcnIpIHx8IF9pdGVyYWJsZVRvQXJyYXkoYXJyKSB8fCBfdW5zdXBwb3J0ZWRJdGVyYWJsZVRvQXJyYXkoYXJyKSB8fCBfbm9uSXRlcmFibGVTcHJlYWQoKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIF9hcnJheVdpdGhvdXRIb2xlcyhhcnIpIHtcbiAgICBpZiAoQXJyYXkuaXNBcnJheShhcnIpKSByZXR1cm4gX2FycmF5TGlrZVRvQXJyYXkoYXJyKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIF9pdGVyYWJsZVRvQXJyYXkoaXRlcikge1xuICAgIGlmICh0eXBlb2YgU3ltYm9sICE9PSBcInVuZGVmaW5lZFwiICYmIFN5bWJvbC5pdGVyYXRvciBpbiBPYmplY3QoaXRlcikpIHJldHVybiBBcnJheS5mcm9tKGl0ZXIpO1xuICB9XG5cbiAgZnVuY3Rpb24gX3Vuc3VwcG9ydGVkSXRlcmFibGVUb0FycmF5KG8sIG1pbkxlbikge1xuICAgIGlmICghbykgcmV0dXJuO1xuICAgIGlmICh0eXBlb2YgbyA9PT0gXCJzdHJpbmdcIikgcmV0dXJuIF9hcnJheUxpa2VUb0FycmF5KG8sIG1pbkxlbik7XG4gICAgdmFyIG4gPSBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwobykuc2xpY2UoOCwgLTEpO1xuICAgIGlmIChuID09PSBcIk9iamVjdFwiICYmIG8uY29uc3RydWN0b3IpIG4gPSBvLmNvbnN0cnVjdG9yLm5hbWU7XG4gICAgaWYgKG4gPT09IFwiTWFwXCIgfHwgbiA9PT0gXCJTZXRcIikgcmV0dXJuIEFycmF5LmZyb20obyk7XG4gICAgaWYgKG4gPT09IFwiQXJndW1lbnRzXCIgfHwgL14oPzpVaXxJKW50KD86OHwxNnwzMikoPzpDbGFtcGVkKT9BcnJheSQvLnRlc3QobikpIHJldHVybiBfYXJyYXlMaWtlVG9BcnJheShvLCBtaW5MZW4pO1xuICB9XG5cbiAgZnVuY3Rpb24gX2FycmF5TGlrZVRvQXJyYXkoYXJyLCBsZW4pIHtcbiAgICBpZiAobGVuID09IG51bGwgfHwgbGVuID4gYXJyLmxlbmd0aCkgbGVuID0gYXJyLmxlbmd0aDtcblxuICAgIGZvciAodmFyIGkgPSAwLCBhcnIyID0gbmV3IEFycmF5KGxlbik7IGkgPCBsZW47IGkrKykgYXJyMltpXSA9IGFycltpXTtcblxuICAgIHJldHVybiBhcnIyO1xuICB9XG5cbiAgZnVuY3Rpb24gX25vbkl0ZXJhYmxlU3ByZWFkKCkge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJJbnZhbGlkIGF0dGVtcHQgdG8gc3ByZWFkIG5vbi1pdGVyYWJsZSBpbnN0YW5jZS5cXG5JbiBvcmRlciB0byBiZSBpdGVyYWJsZSwgbm9uLWFycmF5IG9iamVjdHMgbXVzdCBoYXZlIGEgW1N5bWJvbC5pdGVyYXRvcl0oKSBtZXRob2QuXCIpO1xuICB9XG5cbiAgdmFyIEtleUNvbWJvID0gLyojX19QVVJFX18qL2Z1bmN0aW9uICgpIHtcbiAgICBmdW5jdGlvbiBLZXlDb21ibyhrZXlDb21ib1N0cikge1xuICAgICAgX2NsYXNzQ2FsbENoZWNrKHRoaXMsIEtleUNvbWJvKTtcblxuICAgICAgdGhpcy5zb3VyY2VTdHIgPSBrZXlDb21ib1N0cjtcbiAgICAgIHRoaXMuc3ViQ29tYm9zID0gS2V5Q29tYm8ucGFyc2VDb21ib1N0cihrZXlDb21ib1N0cik7XG4gICAgICB0aGlzLmtleU5hbWVzID0gdGhpcy5zdWJDb21ib3MucmVkdWNlKGZ1bmN0aW9uIChtZW1vLCBuZXh0U3ViQ29tYm8pIHtcbiAgICAgICAgcmV0dXJuIG1lbW8uY29uY2F0KG5leHRTdWJDb21ibyk7XG4gICAgICB9LCBbXSk7XG4gICAgfVxuXG4gICAgX2NyZWF0ZUNsYXNzKEtleUNvbWJvLCBbe1xuICAgICAga2V5OiBcImNoZWNrXCIsXG4gICAgICB2YWx1ZTogZnVuY3Rpb24gY2hlY2socHJlc3NlZEtleU5hbWVzKSB7XG4gICAgICAgIHZhciBzdGFydGluZ0tleU5hbWVJbmRleCA9IDA7XG5cbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0aGlzLnN1YkNvbWJvcy5sZW5ndGg7IGkgKz0gMSkge1xuICAgICAgICAgIHN0YXJ0aW5nS2V5TmFtZUluZGV4ID0gdGhpcy5fY2hlY2tTdWJDb21ibyh0aGlzLnN1YkNvbWJvc1tpXSwgc3RhcnRpbmdLZXlOYW1lSW5kZXgsIHByZXNzZWRLZXlOYW1lcyk7XG5cbiAgICAgICAgICBpZiAoc3RhcnRpbmdLZXlOYW1lSW5kZXggPT09IC0xKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9XG4gICAgfSwge1xuICAgICAga2V5OiBcImlzRXF1YWxcIixcbiAgICAgIHZhbHVlOiBmdW5jdGlvbiBpc0VxdWFsKG90aGVyS2V5Q29tYm8pIHtcbiAgICAgICAgaWYgKCFvdGhlcktleUNvbWJvIHx8IHR5cGVvZiBvdGhlcktleUNvbWJvICE9PSAnc3RyaW5nJyAmJiBfdHlwZW9mKG90aGVyS2V5Q29tYm8pICE9PSAnb2JqZWN0Jykge1xuICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0eXBlb2Ygb3RoZXJLZXlDb21ibyA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgICBvdGhlcktleUNvbWJvID0gbmV3IEtleUNvbWJvKG90aGVyS2V5Q29tYm8pO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRoaXMuc3ViQ29tYm9zLmxlbmd0aCAhPT0gb3RoZXJLZXlDb21iby5zdWJDb21ib3MubGVuZ3RoKSB7XG4gICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG5cbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0aGlzLnN1YkNvbWJvcy5sZW5ndGg7IGkgKz0gMSkge1xuICAgICAgICAgIGlmICh0aGlzLnN1YkNvbWJvc1tpXS5sZW5ndGggIT09IG90aGVyS2V5Q29tYm8uc3ViQ29tYm9zW2ldLmxlbmd0aCkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGZvciAodmFyIF9pID0gMDsgX2kgPCB0aGlzLnN1YkNvbWJvcy5sZW5ndGg7IF9pICs9IDEpIHtcbiAgICAgICAgICB2YXIgc3ViQ29tYm8gPSB0aGlzLnN1YkNvbWJvc1tfaV07XG5cbiAgICAgICAgICB2YXIgb3RoZXJTdWJDb21ibyA9IG90aGVyS2V5Q29tYm8uc3ViQ29tYm9zW19pXS5zbGljZSgwKTtcblxuICAgICAgICAgIGZvciAodmFyIGogPSAwOyBqIDwgc3ViQ29tYm8ubGVuZ3RoOyBqICs9IDEpIHtcbiAgICAgICAgICAgIHZhciBrZXlOYW1lID0gc3ViQ29tYm9bal07XG4gICAgICAgICAgICB2YXIgaW5kZXggPSBvdGhlclN1YkNvbWJvLmluZGV4T2Yoa2V5TmFtZSk7XG5cbiAgICAgICAgICAgIGlmIChpbmRleCA+IC0xKSB7XG4gICAgICAgICAgICAgIG90aGVyU3ViQ29tYm8uc3BsaWNlKGluZGV4LCAxKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAob3RoZXJTdWJDb21iby5sZW5ndGggIT09IDApIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIH1cbiAgICB9LCB7XG4gICAgICBrZXk6IFwiX2NoZWNrU3ViQ29tYm9cIixcbiAgICAgIHZhbHVlOiBmdW5jdGlvbiBfY2hlY2tTdWJDb21ibyhzdWJDb21ibywgc3RhcnRpbmdLZXlOYW1lSW5kZXgsIHByZXNzZWRLZXlOYW1lcykge1xuICAgICAgICBzdWJDb21ibyA9IHN1YkNvbWJvLnNsaWNlKDApO1xuICAgICAgICBwcmVzc2VkS2V5TmFtZXMgPSBwcmVzc2VkS2V5TmFtZXMuc2xpY2Uoc3RhcnRpbmdLZXlOYW1lSW5kZXgpO1xuICAgICAgICB2YXIgZW5kSW5kZXggPSBzdGFydGluZ0tleU5hbWVJbmRleDtcblxuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHN1YkNvbWJvLmxlbmd0aDsgaSArPSAxKSB7XG4gICAgICAgICAgdmFyIGtleU5hbWUgPSBzdWJDb21ib1tpXTtcblxuICAgICAgICAgIGlmIChrZXlOYW1lWzBdID09PSAnXFxcXCcpIHtcbiAgICAgICAgICAgIHZhciBlc2NhcGVkS2V5TmFtZSA9IGtleU5hbWUuc2xpY2UoMSk7XG5cbiAgICAgICAgICAgIGlmIChlc2NhcGVkS2V5TmFtZSA9PT0gS2V5Q29tYm8uY29tYm9EZWxpbWluYXRvciB8fCBlc2NhcGVkS2V5TmFtZSA9PT0gS2V5Q29tYm8ua2V5RGVsaW1pbmF0b3IpIHtcbiAgICAgICAgICAgICAga2V5TmFtZSA9IGVzY2FwZWRLZXlOYW1lO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cblxuICAgICAgICAgIHZhciBpbmRleCA9IHByZXNzZWRLZXlOYW1lcy5pbmRleE9mKGtleU5hbWUpO1xuXG4gICAgICAgICAgaWYgKGluZGV4ID4gLTEpIHtcbiAgICAgICAgICAgIHN1YkNvbWJvLnNwbGljZShpLCAxKTtcbiAgICAgICAgICAgIGkgLT0gMTtcblxuICAgICAgICAgICAgaWYgKGluZGV4ID4gZW5kSW5kZXgpIHtcbiAgICAgICAgICAgICAgZW5kSW5kZXggPSBpbmRleDtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKHN1YkNvbWJvLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgICByZXR1cm4gZW5kSW5kZXg7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIC0xO1xuICAgICAgfVxuICAgIH1dKTtcblxuICAgIHJldHVybiBLZXlDb21ibztcbiAgfSgpO1xuICBLZXlDb21iby5jb21ib0RlbGltaW5hdG9yID0gJz4nO1xuICBLZXlDb21iby5rZXlEZWxpbWluYXRvciA9ICcrJztcblxuICBLZXlDb21iby5wYXJzZUNvbWJvU3RyID0gZnVuY3Rpb24gKGtleUNvbWJvU3RyKSB7XG4gICAgdmFyIHN1YkNvbWJvU3RycyA9IEtleUNvbWJvLl9zcGxpdFN0cihrZXlDb21ib1N0ciwgS2V5Q29tYm8uY29tYm9EZWxpbWluYXRvcik7XG5cbiAgICB2YXIgY29tYm8gPSBbXTtcblxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgc3ViQ29tYm9TdHJzLmxlbmd0aDsgaSArPSAxKSB7XG4gICAgICBjb21iby5wdXNoKEtleUNvbWJvLl9zcGxpdFN0cihzdWJDb21ib1N0cnNbaV0sIEtleUNvbWJvLmtleURlbGltaW5hdG9yKSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGNvbWJvO1xuICB9O1xuXG4gIEtleUNvbWJvLl9zcGxpdFN0ciA9IGZ1bmN0aW9uIChzdHIsIGRlbGltaW5hdG9yKSB7XG4gICAgdmFyIHMgPSBzdHI7XG4gICAgdmFyIGQgPSBkZWxpbWluYXRvcjtcbiAgICB2YXIgYyA9ICcnO1xuICAgIHZhciBjYSA9IFtdO1xuXG4gICAgZm9yICh2YXIgY2kgPSAwOyBjaSA8IHMubGVuZ3RoOyBjaSArPSAxKSB7XG4gICAgICBpZiAoY2kgPiAwICYmIHNbY2ldID09PSBkICYmIHNbY2kgLSAxXSAhPT0gJ1xcXFwnKSB7XG4gICAgICAgIGNhLnB1c2goYy50cmltKCkpO1xuICAgICAgICBjID0gJyc7XG4gICAgICAgIGNpICs9IDE7XG4gICAgICB9XG5cbiAgICAgIGMgKz0gc1tjaV07XG4gICAgfVxuXG4gICAgaWYgKGMpIHtcbiAgICAgIGNhLnB1c2goYy50cmltKCkpO1xuICAgIH1cblxuICAgIHJldHVybiBjYTtcbiAgfTtcblxuICB2YXIgTG9jYWxlID0gLyojX19QVVJFX18qL2Z1bmN0aW9uICgpIHtcbiAgICBmdW5jdGlvbiBMb2NhbGUobmFtZSkge1xuICAgICAgX2NsYXNzQ2FsbENoZWNrKHRoaXMsIExvY2FsZSk7XG5cbiAgICAgIHRoaXMubG9jYWxlTmFtZSA9IG5hbWU7XG4gICAgICB0aGlzLmFjdGl2ZVRhcmdldEtleXMgPSBbXTtcbiAgICAgIHRoaXMucHJlc3NlZEtleXMgPSBbXTtcbiAgICAgIHRoaXMuX2FwcGxpZWRNYWNyb3MgPSBbXTtcbiAgICAgIHRoaXMuX2tleU1hcCA9IHt9O1xuICAgICAgdGhpcy5fa2lsbEtleUNvZGVzID0gW107XG4gICAgICB0aGlzLl9tYWNyb3MgPSBbXTtcbiAgICB9XG5cbiAgICBfY3JlYXRlQ2xhc3MoTG9jYWxlLCBbe1xuICAgICAga2V5OiBcImJpbmRLZXlDb2RlXCIsXG4gICAgICB2YWx1ZTogZnVuY3Rpb24gYmluZEtleUNvZGUoa2V5Q29kZSwga2V5TmFtZXMpIHtcbiAgICAgICAgaWYgKHR5cGVvZiBrZXlOYW1lcyA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgICBrZXlOYW1lcyA9IFtrZXlOYW1lc107XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLl9rZXlNYXBba2V5Q29kZV0gPSBrZXlOYW1lcztcbiAgICAgIH1cbiAgICB9LCB7XG4gICAgICBrZXk6IFwiYmluZE1hY3JvXCIsXG4gICAgICB2YWx1ZTogZnVuY3Rpb24gYmluZE1hY3JvKGtleUNvbWJvU3RyLCBrZXlOYW1lcykge1xuICAgICAgICBpZiAodHlwZW9mIGtleU5hbWVzID09PSAnc3RyaW5nJykge1xuICAgICAgICAgIGtleU5hbWVzID0gW2tleU5hbWVzXTtcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBoYW5kbGVyID0gbnVsbDtcblxuICAgICAgICBpZiAodHlwZW9mIGtleU5hbWVzID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgaGFuZGxlciA9IGtleU5hbWVzO1xuICAgICAgICAgIGtleU5hbWVzID0gbnVsbDtcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBtYWNybyA9IHtcbiAgICAgICAgICBrZXlDb21ibzogbmV3IEtleUNvbWJvKGtleUNvbWJvU3RyKSxcbiAgICAgICAgICBrZXlOYW1lczoga2V5TmFtZXMsXG4gICAgICAgICAgaGFuZGxlcjogaGFuZGxlclxuICAgICAgICB9O1xuXG4gICAgICAgIHRoaXMuX21hY3Jvcy5wdXNoKG1hY3JvKTtcbiAgICAgIH1cbiAgICB9LCB7XG4gICAgICBrZXk6IFwiZ2V0S2V5Q29kZXNcIixcbiAgICAgIHZhbHVlOiBmdW5jdGlvbiBnZXRLZXlDb2RlcyhrZXlOYW1lKSB7XG4gICAgICAgIHZhciBrZXlDb2RlcyA9IFtdO1xuXG4gICAgICAgIGZvciAodmFyIGtleUNvZGUgaW4gdGhpcy5fa2V5TWFwKSB7XG4gICAgICAgICAgdmFyIGluZGV4ID0gdGhpcy5fa2V5TWFwW2tleUNvZGVdLmluZGV4T2Yoa2V5TmFtZSk7XG5cbiAgICAgICAgICBpZiAoaW5kZXggPiAtMSkge1xuICAgICAgICAgICAga2V5Q29kZXMucHVzaChrZXlDb2RlIHwgMCk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGtleUNvZGVzO1xuICAgICAgfVxuICAgIH0sIHtcbiAgICAgIGtleTogXCJnZXRLZXlOYW1lc1wiLFxuICAgICAgdmFsdWU6IGZ1bmN0aW9uIGdldEtleU5hbWVzKGtleUNvZGUpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2tleU1hcFtrZXlDb2RlXSB8fCBbXTtcbiAgICAgIH1cbiAgICB9LCB7XG4gICAgICBrZXk6IFwic2V0S2lsbEtleVwiLFxuICAgICAgdmFsdWU6IGZ1bmN0aW9uIHNldEtpbGxLZXkoa2V5Q29kZSkge1xuICAgICAgICBpZiAodHlwZW9mIGtleUNvZGUgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgdmFyIGtleUNvZGVzID0gdGhpcy5nZXRLZXlDb2RlcyhrZXlDb2RlKTtcblxuICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwga2V5Q29kZXMubGVuZ3RoOyBpICs9IDEpIHtcbiAgICAgICAgICAgIHRoaXMuc2V0S2lsbEtleShrZXlDb2Rlc1tpXSk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5fa2lsbEtleUNvZGVzLnB1c2goa2V5Q29kZSk7XG4gICAgICB9XG4gICAgfSwge1xuICAgICAga2V5OiBcInByZXNzS2V5XCIsXG4gICAgICB2YWx1ZTogZnVuY3Rpb24gcHJlc3NLZXkoa2V5Q29kZSkge1xuICAgICAgICBpZiAodHlwZW9mIGtleUNvZGUgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgdmFyIGtleUNvZGVzID0gdGhpcy5nZXRLZXlDb2RlcyhrZXlDb2RlKTtcblxuICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwga2V5Q29kZXMubGVuZ3RoOyBpICs9IDEpIHtcbiAgICAgICAgICAgIHRoaXMucHJlc3NLZXkoa2V5Q29kZXNbaV0pO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuYWN0aXZlVGFyZ2V0S2V5cy5sZW5ndGggPSAwO1xuICAgICAgICB2YXIga2V5TmFtZXMgPSB0aGlzLmdldEtleU5hbWVzKGtleUNvZGUpO1xuXG4gICAgICAgIGZvciAodmFyIF9pID0gMDsgX2kgPCBrZXlOYW1lcy5sZW5ndGg7IF9pICs9IDEpIHtcbiAgICAgICAgICB0aGlzLmFjdGl2ZVRhcmdldEtleXMucHVzaChrZXlOYW1lc1tfaV0pO1xuXG4gICAgICAgICAgaWYgKHRoaXMucHJlc3NlZEtleXMuaW5kZXhPZihrZXlOYW1lc1tfaV0pID09PSAtMSkge1xuICAgICAgICAgICAgdGhpcy5wcmVzc2VkS2V5cy5wdXNoKGtleU5hbWVzW19pXSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5fYXBwbHlNYWNyb3MoKTtcbiAgICAgIH1cbiAgICB9LCB7XG4gICAgICBrZXk6IFwicmVsZWFzZUtleVwiLFxuICAgICAgdmFsdWU6IGZ1bmN0aW9uIHJlbGVhc2VLZXkoa2V5Q29kZSkge1xuICAgICAgICBpZiAodHlwZW9mIGtleUNvZGUgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgdmFyIGtleUNvZGVzID0gdGhpcy5nZXRLZXlDb2RlcyhrZXlDb2RlKTtcblxuICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwga2V5Q29kZXMubGVuZ3RoOyBpICs9IDEpIHtcbiAgICAgICAgICAgIHRoaXMucmVsZWFzZUtleShrZXlDb2Rlc1tpXSk7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHZhciBrZXlOYW1lcyA9IHRoaXMuZ2V0S2V5TmFtZXMoa2V5Q29kZSk7XG5cbiAgICAgICAgICB2YXIga2lsbEtleUNvZGVJbmRleCA9IHRoaXMuX2tpbGxLZXlDb2Rlcy5pbmRleE9mKGtleUNvZGUpO1xuXG4gICAgICAgICAgaWYgKGtpbGxLZXlDb2RlSW5kZXggIT09IC0xKSB7XG4gICAgICAgICAgICB0aGlzLnByZXNzZWRLZXlzLmxlbmd0aCA9IDA7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGZvciAodmFyIF9pMiA9IDA7IF9pMiA8IGtleU5hbWVzLmxlbmd0aDsgX2kyICs9IDEpIHtcbiAgICAgICAgICAgICAgdmFyIGluZGV4ID0gdGhpcy5wcmVzc2VkS2V5cy5pbmRleE9mKGtleU5hbWVzW19pMl0pO1xuXG4gICAgICAgICAgICAgIGlmIChpbmRleCA+IC0xKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5wcmVzc2VkS2V5cy5zcGxpY2UoaW5kZXgsIDEpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgdGhpcy5hY3RpdmVUYXJnZXRLZXlzLmxlbmd0aCA9IDA7XG5cbiAgICAgICAgICB0aGlzLl9jbGVhck1hY3JvcygpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSwge1xuICAgICAga2V5OiBcIl9hcHBseU1hY3Jvc1wiLFxuICAgICAgdmFsdWU6IGZ1bmN0aW9uIF9hcHBseU1hY3JvcygpIHtcbiAgICAgICAgdmFyIG1hY3JvcyA9IHRoaXMuX21hY3Jvcy5zbGljZSgwKTtcblxuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG1hY3Jvcy5sZW5ndGg7IGkgKz0gMSkge1xuICAgICAgICAgIHZhciBtYWNybyA9IG1hY3Jvc1tpXTtcblxuICAgICAgICAgIGlmIChtYWNyby5rZXlDb21iby5jaGVjayh0aGlzLnByZXNzZWRLZXlzKSkge1xuICAgICAgICAgICAgaWYgKG1hY3JvLmhhbmRsZXIpIHtcbiAgICAgICAgICAgICAgbWFjcm8ua2V5TmFtZXMgPSBtYWNyby5oYW5kbGVyKHRoaXMucHJlc3NlZEtleXMpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBmb3IgKHZhciBqID0gMDsgaiA8IG1hY3JvLmtleU5hbWVzLmxlbmd0aDsgaiArPSAxKSB7XG4gICAgICAgICAgICAgIGlmICh0aGlzLnByZXNzZWRLZXlzLmluZGV4T2YobWFjcm8ua2V5TmFtZXNbal0pID09PSAtMSkge1xuICAgICAgICAgICAgICAgIHRoaXMucHJlc3NlZEtleXMucHVzaChtYWNyby5rZXlOYW1lc1tqXSk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdGhpcy5fYXBwbGllZE1hY3Jvcy5wdXNoKG1hY3JvKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9LCB7XG4gICAgICBrZXk6IFwiX2NsZWFyTWFjcm9zXCIsXG4gICAgICB2YWx1ZTogZnVuY3Rpb24gX2NsZWFyTWFjcm9zKCkge1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMuX2FwcGxpZWRNYWNyb3MubGVuZ3RoOyBpICs9IDEpIHtcbiAgICAgICAgICB2YXIgbWFjcm8gPSB0aGlzLl9hcHBsaWVkTWFjcm9zW2ldO1xuXG4gICAgICAgICAgaWYgKCFtYWNyby5rZXlDb21iby5jaGVjayh0aGlzLnByZXNzZWRLZXlzKSkge1xuICAgICAgICAgICAgZm9yICh2YXIgaiA9IDA7IGogPCBtYWNyby5rZXlOYW1lcy5sZW5ndGg7IGogKz0gMSkge1xuICAgICAgICAgICAgICB2YXIgaW5kZXggPSB0aGlzLnByZXNzZWRLZXlzLmluZGV4T2YobWFjcm8ua2V5TmFtZXNbal0pO1xuXG4gICAgICAgICAgICAgIGlmIChpbmRleCA+IC0xKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5wcmVzc2VkS2V5cy5zcGxpY2UoaW5kZXgsIDEpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChtYWNyby5oYW5kbGVyKSB7XG4gICAgICAgICAgICAgIG1hY3JvLmtleU5hbWVzID0gbnVsbDtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdGhpcy5fYXBwbGllZE1hY3Jvcy5zcGxpY2UoaSwgMSk7XG5cbiAgICAgICAgICAgIGkgLT0gMTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XSk7XG5cbiAgICByZXR1cm4gTG9jYWxlO1xuICB9KCk7XG5cbiAgdmFyIEtleWJvYXJkID0gLyojX19QVVJFX18qL2Z1bmN0aW9uICgpIHtcbiAgICBmdW5jdGlvbiBLZXlib2FyZCh0YXJnZXRXaW5kb3csIHRhcmdldEVsZW1lbnQsIHRhcmdldFBsYXRmb3JtLCB0YXJnZXRVc2VyQWdlbnQpIHtcbiAgICAgIF9jbGFzc0NhbGxDaGVjayh0aGlzLCBLZXlib2FyZCk7XG5cbiAgICAgIHRoaXMuX2xvY2FsZSA9IG51bGw7XG4gICAgICB0aGlzLl9jdXJyZW50Q29udGV4dCA9ICcnO1xuICAgICAgdGhpcy5fY29udGV4dHMgPSB7fTtcbiAgICAgIHRoaXMuX2xpc3RlbmVycyA9IFtdO1xuICAgICAgdGhpcy5fYXBwbGllZExpc3RlbmVycyA9IFtdO1xuICAgICAgdGhpcy5fbG9jYWxlcyA9IHt9O1xuICAgICAgdGhpcy5fdGFyZ2V0RWxlbWVudCA9IG51bGw7XG4gICAgICB0aGlzLl90YXJnZXRXaW5kb3cgPSBudWxsO1xuICAgICAgdGhpcy5fdGFyZ2V0UGxhdGZvcm0gPSAnJztcbiAgICAgIHRoaXMuX3RhcmdldFVzZXJBZ2VudCA9ICcnO1xuICAgICAgdGhpcy5faXNNb2Rlcm5Ccm93c2VyID0gZmFsc2U7XG4gICAgICB0aGlzLl90YXJnZXRLZXlEb3duQmluZGluZyA9IG51bGw7XG4gICAgICB0aGlzLl90YXJnZXRLZXlVcEJpbmRpbmcgPSBudWxsO1xuICAgICAgdGhpcy5fdGFyZ2V0UmVzZXRCaW5kaW5nID0gbnVsbDtcbiAgICAgIHRoaXMuX3BhdXNlZCA9IGZhbHNlO1xuICAgICAgdGhpcy5fY29udGV4dHMuZ2xvYmFsID0ge1xuICAgICAgICBsaXN0ZW5lcnM6IHRoaXMuX2xpc3RlbmVycyxcbiAgICAgICAgdGFyZ2V0V2luZG93OiB0YXJnZXRXaW5kb3csXG4gICAgICAgIHRhcmdldEVsZW1lbnQ6IHRhcmdldEVsZW1lbnQsXG4gICAgICAgIHRhcmdldFBsYXRmb3JtOiB0YXJnZXRQbGF0Zm9ybSxcbiAgICAgICAgdGFyZ2V0VXNlckFnZW50OiB0YXJnZXRVc2VyQWdlbnRcbiAgICAgIH07XG4gICAgICB0aGlzLnNldENvbnRleHQoJ2dsb2JhbCcpO1xuICAgIH1cblxuICAgIF9jcmVhdGVDbGFzcyhLZXlib2FyZCwgW3tcbiAgICAgIGtleTogXCJzZXRMb2NhbGVcIixcbiAgICAgIHZhbHVlOiBmdW5jdGlvbiBzZXRMb2NhbGUobG9jYWxlTmFtZSwgbG9jYWxlQnVpbGRlcikge1xuICAgICAgICB2YXIgbG9jYWxlID0gbnVsbDtcblxuICAgICAgICBpZiAodHlwZW9mIGxvY2FsZU5hbWUgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgaWYgKGxvY2FsZUJ1aWxkZXIpIHtcbiAgICAgICAgICAgIGxvY2FsZSA9IG5ldyBMb2NhbGUobG9jYWxlTmFtZSk7XG4gICAgICAgICAgICBsb2NhbGVCdWlsZGVyKGxvY2FsZSwgdGhpcy5fdGFyZ2V0UGxhdGZvcm0sIHRoaXMuX3RhcmdldFVzZXJBZ2VudCk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGxvY2FsZSA9IHRoaXMuX2xvY2FsZXNbbG9jYWxlTmFtZV0gfHwgbnVsbDtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgbG9jYWxlID0gbG9jYWxlTmFtZTtcbiAgICAgICAgICBsb2NhbGVOYW1lID0gbG9jYWxlLl9sb2NhbGVOYW1lO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5fbG9jYWxlID0gbG9jYWxlO1xuICAgICAgICB0aGlzLl9sb2NhbGVzW2xvY2FsZU5hbWVdID0gbG9jYWxlO1xuXG4gICAgICAgIGlmIChsb2NhbGUpIHtcbiAgICAgICAgICB0aGlzLl9sb2NhbGUucHJlc3NlZEtleXMgPSBsb2NhbGUucHJlc3NlZEtleXM7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgIH1cbiAgICB9LCB7XG4gICAgICBrZXk6IFwiZ2V0TG9jYWxlXCIsXG4gICAgICB2YWx1ZTogZnVuY3Rpb24gZ2V0TG9jYWxlKGxvY2FsTmFtZSkge1xuICAgICAgICBsb2NhbE5hbWUgfHwgKGxvY2FsTmFtZSA9IHRoaXMuX2xvY2FsZS5sb2NhbGVOYW1lKTtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2xvY2FsZXNbbG9jYWxOYW1lXSB8fCBudWxsO1xuICAgICAgfVxuICAgIH0sIHtcbiAgICAgIGtleTogXCJiaW5kXCIsXG4gICAgICB2YWx1ZTogZnVuY3Rpb24gYmluZChrZXlDb21ib1N0ciwgcHJlc3NIYW5kbGVyLCByZWxlYXNlSGFuZGxlciwgcHJldmVudFJlcGVhdEJ5RGVmYXVsdCkge1xuICAgICAgICBpZiAoa2V5Q29tYm9TdHIgPT09IG51bGwgfHwgdHlwZW9mIGtleUNvbWJvU3RyID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgcHJldmVudFJlcGVhdEJ5RGVmYXVsdCA9IHJlbGVhc2VIYW5kbGVyO1xuICAgICAgICAgIHJlbGVhc2VIYW5kbGVyID0gcHJlc3NIYW5kbGVyO1xuICAgICAgICAgIHByZXNzSGFuZGxlciA9IGtleUNvbWJvU3RyO1xuICAgICAgICAgIGtleUNvbWJvU3RyID0gbnVsbDtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChrZXlDb21ib1N0ciAmJiBfdHlwZW9mKGtleUNvbWJvU3RyKSA9PT0gJ29iamVjdCcgJiYgdHlwZW9mIGtleUNvbWJvU3RyLmxlbmd0aCA9PT0gJ251bWJlcicpIHtcbiAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGtleUNvbWJvU3RyLmxlbmd0aDsgaSArPSAxKSB7XG4gICAgICAgICAgICB0aGlzLmJpbmQoa2V5Q29tYm9TdHJbaV0sIHByZXNzSGFuZGxlciwgcmVsZWFzZUhhbmRsZXIpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5fbGlzdGVuZXJzLnB1c2goe1xuICAgICAgICAgIGtleUNvbWJvOiBrZXlDb21ib1N0ciA/IG5ldyBLZXlDb21ibyhrZXlDb21ib1N0cikgOiBudWxsLFxuICAgICAgICAgIHByZXNzSGFuZGxlcjogcHJlc3NIYW5kbGVyIHx8IG51bGwsXG4gICAgICAgICAgcmVsZWFzZUhhbmRsZXI6IHJlbGVhc2VIYW5kbGVyIHx8IG51bGwsXG4gICAgICAgICAgcHJldmVudFJlcGVhdDogZmFsc2UsXG4gICAgICAgICAgcHJldmVudFJlcGVhdEJ5RGVmYXVsdDogcHJldmVudFJlcGVhdEJ5RGVmYXVsdCB8fCBmYWxzZSxcbiAgICAgICAgICBleGVjdXRpbmdIYW5kbGVyOiBmYWxzZVxuICAgICAgICB9KTtcblxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgIH1cbiAgICB9LCB7XG4gICAgICBrZXk6IFwiYWRkTGlzdGVuZXJcIixcbiAgICAgIHZhbHVlOiBmdW5jdGlvbiBhZGRMaXN0ZW5lcihrZXlDb21ib1N0ciwgcHJlc3NIYW5kbGVyLCByZWxlYXNlSGFuZGxlciwgcHJldmVudFJlcGVhdEJ5RGVmYXVsdCkge1xuICAgICAgICByZXR1cm4gdGhpcy5iaW5kKGtleUNvbWJvU3RyLCBwcmVzc0hhbmRsZXIsIHJlbGVhc2VIYW5kbGVyLCBwcmV2ZW50UmVwZWF0QnlEZWZhdWx0KTtcbiAgICAgIH1cbiAgICB9LCB7XG4gICAgICBrZXk6IFwib25cIixcbiAgICAgIHZhbHVlOiBmdW5jdGlvbiBvbihrZXlDb21ib1N0ciwgcHJlc3NIYW5kbGVyLCByZWxlYXNlSGFuZGxlciwgcHJldmVudFJlcGVhdEJ5RGVmYXVsdCkge1xuICAgICAgICByZXR1cm4gdGhpcy5iaW5kKGtleUNvbWJvU3RyLCBwcmVzc0hhbmRsZXIsIHJlbGVhc2VIYW5kbGVyLCBwcmV2ZW50UmVwZWF0QnlEZWZhdWx0KTtcbiAgICAgIH1cbiAgICB9LCB7XG4gICAgICBrZXk6IFwiYmluZFByZXNzXCIsXG4gICAgICB2YWx1ZTogZnVuY3Rpb24gYmluZFByZXNzKGtleUNvbWJvU3RyLCBwcmVzc0hhbmRsZXIsIHByZXZlbnRSZXBlYXRCeURlZmF1bHQpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuYmluZChrZXlDb21ib1N0ciwgcHJlc3NIYW5kbGVyLCBudWxsLCBwcmV2ZW50UmVwZWF0QnlEZWZhdWx0KTtcbiAgICAgIH1cbiAgICB9LCB7XG4gICAgICBrZXk6IFwiYmluZFJlbGVhc2VcIixcbiAgICAgIHZhbHVlOiBmdW5jdGlvbiBiaW5kUmVsZWFzZShrZXlDb21ib1N0ciwgcmVsZWFzZUhhbmRsZXIpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuYmluZChrZXlDb21ib1N0ciwgbnVsbCwgcmVsZWFzZUhhbmRsZXIsIHByZXZlbnRSZXBlYXRCeURlZmF1bHQpO1xuICAgICAgfVxuICAgIH0sIHtcbiAgICAgIGtleTogXCJ1bmJpbmRcIixcbiAgICAgIHZhbHVlOiBmdW5jdGlvbiB1bmJpbmQoa2V5Q29tYm9TdHIsIHByZXNzSGFuZGxlciwgcmVsZWFzZUhhbmRsZXIpIHtcbiAgICAgICAgaWYgKGtleUNvbWJvU3RyID09PSBudWxsIHx8IHR5cGVvZiBrZXlDb21ib1N0ciA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgIHJlbGVhc2VIYW5kbGVyID0gcHJlc3NIYW5kbGVyO1xuICAgICAgICAgIHByZXNzSGFuZGxlciA9IGtleUNvbWJvU3RyO1xuICAgICAgICAgIGtleUNvbWJvU3RyID0gbnVsbDtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChrZXlDb21ib1N0ciAmJiBfdHlwZW9mKGtleUNvbWJvU3RyKSA9PT0gJ29iamVjdCcgJiYgdHlwZW9mIGtleUNvbWJvU3RyLmxlbmd0aCA9PT0gJ251bWJlcicpIHtcbiAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGtleUNvbWJvU3RyLmxlbmd0aDsgaSArPSAxKSB7XG4gICAgICAgICAgICB0aGlzLnVuYmluZChrZXlDb21ib1N0cltpXSwgcHJlc3NIYW5kbGVyLCByZWxlYXNlSGFuZGxlcik7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgIH1cblxuICAgICAgICBmb3IgKHZhciBfaSA9IDA7IF9pIDwgdGhpcy5fbGlzdGVuZXJzLmxlbmd0aDsgX2kgKz0gMSkge1xuICAgICAgICAgIHZhciBsaXN0ZW5lciA9IHRoaXMuX2xpc3RlbmVyc1tfaV07XG4gICAgICAgICAgdmFyIGNvbWJvTWF0Y2hlcyA9ICFrZXlDb21ib1N0ciAmJiAhbGlzdGVuZXIua2V5Q29tYm8gfHwgbGlzdGVuZXIua2V5Q29tYm8gJiYgbGlzdGVuZXIua2V5Q29tYm8uaXNFcXVhbChrZXlDb21ib1N0cik7XG4gICAgICAgICAgdmFyIHByZXNzSGFuZGxlck1hdGNoZXMgPSAhcHJlc3NIYW5kbGVyICYmICFyZWxlYXNlSGFuZGxlciB8fCAhcHJlc3NIYW5kbGVyICYmICFsaXN0ZW5lci5wcmVzc0hhbmRsZXIgfHwgcHJlc3NIYW5kbGVyID09PSBsaXN0ZW5lci5wcmVzc0hhbmRsZXI7XG4gICAgICAgICAgdmFyIHJlbGVhc2VIYW5kbGVyTWF0Y2hlcyA9ICFwcmVzc0hhbmRsZXIgJiYgIXJlbGVhc2VIYW5kbGVyIHx8ICFyZWxlYXNlSGFuZGxlciAmJiAhbGlzdGVuZXIucmVsZWFzZUhhbmRsZXIgfHwgcmVsZWFzZUhhbmRsZXIgPT09IGxpc3RlbmVyLnJlbGVhc2VIYW5kbGVyO1xuXG4gICAgICAgICAgaWYgKGNvbWJvTWF0Y2hlcyAmJiBwcmVzc0hhbmRsZXJNYXRjaGVzICYmIHJlbGVhc2VIYW5kbGVyTWF0Y2hlcykge1xuICAgICAgICAgICAgdGhpcy5fbGlzdGVuZXJzLnNwbGljZShfaSwgMSk7XG5cbiAgICAgICAgICAgIF9pIC09IDE7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICB9XG4gICAgfSwge1xuICAgICAga2V5OiBcInJlbW92ZUxpc3RlbmVyXCIsXG4gICAgICB2YWx1ZTogZnVuY3Rpb24gcmVtb3ZlTGlzdGVuZXIoa2V5Q29tYm9TdHIsIHByZXNzSGFuZGxlciwgcmVsZWFzZUhhbmRsZXIpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMudW5iaW5kKGtleUNvbWJvU3RyLCBwcmVzc0hhbmRsZXIsIHJlbGVhc2VIYW5kbGVyKTtcbiAgICAgIH1cbiAgICB9LCB7XG4gICAgICBrZXk6IFwib2ZmXCIsXG4gICAgICB2YWx1ZTogZnVuY3Rpb24gb2ZmKGtleUNvbWJvU3RyLCBwcmVzc0hhbmRsZXIsIHJlbGVhc2VIYW5kbGVyKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnVuYmluZChrZXlDb21ib1N0ciwgcHJlc3NIYW5kbGVyLCByZWxlYXNlSGFuZGxlcik7XG4gICAgICB9XG4gICAgfSwge1xuICAgICAga2V5OiBcInNldENvbnRleHRcIixcbiAgICAgIHZhbHVlOiBmdW5jdGlvbiBzZXRDb250ZXh0KGNvbnRleHROYW1lKSB7XG4gICAgICAgIGlmICh0aGlzLl9sb2NhbGUpIHtcbiAgICAgICAgICB0aGlzLnJlbGVhc2VBbGxLZXlzKCk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoIXRoaXMuX2NvbnRleHRzW2NvbnRleHROYW1lXSkge1xuICAgICAgICAgIHZhciBnbG9iYWxDb250ZXh0ID0gdGhpcy5fY29udGV4dHMuZ2xvYmFsO1xuICAgICAgICAgIHRoaXMuX2NvbnRleHRzW2NvbnRleHROYW1lXSA9IHtcbiAgICAgICAgICAgIGxpc3RlbmVyczogW10sXG4gICAgICAgICAgICB0YXJnZXRXaW5kb3c6IGdsb2JhbENvbnRleHQudGFyZ2V0V2luZG93LFxuICAgICAgICAgICAgdGFyZ2V0RWxlbWVudDogZ2xvYmFsQ29udGV4dC50YXJnZXRFbGVtZW50LFxuICAgICAgICAgICAgdGFyZ2V0UGxhdGZvcm06IGdsb2JhbENvbnRleHQudGFyZ2V0UGxhdGZvcm0sXG4gICAgICAgICAgICB0YXJnZXRVc2VyQWdlbnQ6IGdsb2JhbENvbnRleHQudGFyZ2V0VXNlckFnZW50XG4gICAgICAgICAgfTtcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBjb250ZXh0ID0gdGhpcy5fY29udGV4dHNbY29udGV4dE5hbWVdO1xuICAgICAgICB0aGlzLl9jdXJyZW50Q29udGV4dCA9IGNvbnRleHROYW1lO1xuICAgICAgICB0aGlzLl9saXN0ZW5lcnMgPSBjb250ZXh0Lmxpc3RlbmVycztcbiAgICAgICAgdGhpcy5zdG9wKCk7XG4gICAgICAgIHRoaXMud2F0Y2goY29udGV4dC50YXJnZXRXaW5kb3csIGNvbnRleHQudGFyZ2V0RWxlbWVudCwgY29udGV4dC50YXJnZXRQbGF0Zm9ybSwgY29udGV4dC50YXJnZXRVc2VyQWdlbnQpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgIH1cbiAgICB9LCB7XG4gICAgICBrZXk6IFwiZ2V0Q29udGV4dFwiLFxuICAgICAgdmFsdWU6IGZ1bmN0aW9uIGdldENvbnRleHQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9jdXJyZW50Q29udGV4dDtcbiAgICAgIH1cbiAgICB9LCB7XG4gICAgICBrZXk6IFwid2l0aENvbnRleHRcIixcbiAgICAgIHZhbHVlOiBmdW5jdGlvbiB3aXRoQ29udGV4dChjb250ZXh0TmFtZSwgY2FsbGJhY2spIHtcbiAgICAgICAgdmFyIHByZXZpb3VzQ29udGV4dE5hbWUgPSB0aGlzLmdldENvbnRleHQoKTtcbiAgICAgICAgdGhpcy5zZXRDb250ZXh0KGNvbnRleHROYW1lKTtcbiAgICAgICAgY2FsbGJhY2soKTtcbiAgICAgICAgdGhpcy5zZXRDb250ZXh0KHByZXZpb3VzQ29udGV4dE5hbWUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgIH1cbiAgICB9LCB7XG4gICAgICBrZXk6IFwid2F0Y2hcIixcbiAgICAgIHZhbHVlOiBmdW5jdGlvbiB3YXRjaCh0YXJnZXRXaW5kb3csIHRhcmdldEVsZW1lbnQsIHRhcmdldFBsYXRmb3JtLCB0YXJnZXRVc2VyQWdlbnQpIHtcbiAgICAgICAgdmFyIF90aGlzID0gdGhpcztcblxuICAgICAgICB0aGlzLnN0b3AoKTtcbiAgICAgICAgdmFyIHdpbiA9IHR5cGVvZiBnbG9iYWxUaGlzICE9PSAndW5kZWZpbmVkJyA/IGdsb2JhbFRoaXMgOiB0eXBlb2YgZ2xvYmFsICE9PSAndW5kZWZpbmVkJyA/IGdsb2JhbCA6IHR5cGVvZiB3aW5kb3cgIT09ICd1bmRlZmluZWQnID8gd2luZG93IDoge307XG5cbiAgICAgICAgaWYgKCF0YXJnZXRXaW5kb3cpIHtcbiAgICAgICAgICBpZiAoIXdpbi5hZGRFdmVudExpc3RlbmVyICYmICF3aW4uYXR0YWNoRXZlbnQpIHtcbiAgICAgICAgICAgIC8vIFRoaXMgd2FzIGFkZGVkIHNvIHdoZW4gdXNpbmcgdGhpbmdzIGxpa2UgSlNET00gd2F0Y2ggY2FuIGJlIHVzZWQgdG8gY29uZmlndXJlIHdhdGNoXG4gICAgICAgICAgICAvLyBmb3IgdGhlIGdsb2JhbCBuYW1lc3BhY2UgbWFudWFsbHkuXG4gICAgICAgICAgICBpZiAodGhpcy5fY3VycmVudENvbnRleHQgPT09ICdnbG9iYWwnKSB7XG4gICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdDYW5ub3QgZmluZCB3aW5kb3cgZnVuY3Rpb25zIGFkZEV2ZW50TGlzdGVuZXIgb3IgYXR0YWNoRXZlbnQuJyk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgdGFyZ2V0V2luZG93ID0gd2luO1xuICAgICAgICB9IC8vIEhhbmRsZSBlbGVtZW50IGJpbmRpbmdzIHdoZXJlIGEgdGFyZ2V0IHdpbmRvdyBpcyBub3QgcGFzc2VkXG5cblxuICAgICAgICBpZiAodHlwZW9mIHRhcmdldFdpbmRvdy5ub2RlVHlwZSA9PT0gJ251bWJlcicpIHtcbiAgICAgICAgICB0YXJnZXRVc2VyQWdlbnQgPSB0YXJnZXRQbGF0Zm9ybTtcbiAgICAgICAgICB0YXJnZXRQbGF0Zm9ybSA9IHRhcmdldEVsZW1lbnQ7XG4gICAgICAgICAgdGFyZ2V0RWxlbWVudCA9IHRhcmdldFdpbmRvdztcbiAgICAgICAgICB0YXJnZXRXaW5kb3cgPSB3aW47XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoIXRhcmdldFdpbmRvdy5hZGRFdmVudExpc3RlbmVyICYmICF0YXJnZXRXaW5kb3cuYXR0YWNoRXZlbnQpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0Nhbm5vdCBmaW5kIGFkZEV2ZW50TGlzdGVuZXIgb3IgYXR0YWNoRXZlbnQgbWV0aG9kcyBvbiB0YXJnZXRXaW5kb3cuJyk7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLl9pc01vZGVybkJyb3dzZXIgPSAhIXRhcmdldFdpbmRvdy5hZGRFdmVudExpc3RlbmVyO1xuICAgICAgICB2YXIgdXNlckFnZW50ID0gdGFyZ2V0V2luZG93Lm5hdmlnYXRvciAmJiB0YXJnZXRXaW5kb3cubmF2aWdhdG9yLnVzZXJBZ2VudCB8fCAnJztcbiAgICAgICAgdmFyIHBsYXRmb3JtID0gdGFyZ2V0V2luZG93Lm5hdmlnYXRvciAmJiB0YXJnZXRXaW5kb3cubmF2aWdhdG9yLnBsYXRmb3JtIHx8ICcnO1xuICAgICAgICB0YXJnZXRFbGVtZW50ICYmIHRhcmdldEVsZW1lbnQgIT09IG51bGwgfHwgKHRhcmdldEVsZW1lbnQgPSB0YXJnZXRXaW5kb3cuZG9jdW1lbnQpO1xuICAgICAgICB0YXJnZXRQbGF0Zm9ybSAmJiB0YXJnZXRQbGF0Zm9ybSAhPT0gbnVsbCB8fCAodGFyZ2V0UGxhdGZvcm0gPSBwbGF0Zm9ybSk7XG4gICAgICAgIHRhcmdldFVzZXJBZ2VudCAmJiB0YXJnZXRVc2VyQWdlbnQgIT09IG51bGwgfHwgKHRhcmdldFVzZXJBZ2VudCA9IHVzZXJBZ2VudCk7XG5cbiAgICAgICAgdGhpcy5fdGFyZ2V0S2V5RG93bkJpbmRpbmcgPSBmdW5jdGlvbiAoZXZlbnQpIHtcbiAgICAgICAgICBfdGhpcy5wcmVzc0tleShldmVudC5rZXlDb2RlLCBldmVudCk7XG5cbiAgICAgICAgICBfdGhpcy5faGFuZGxlQ29tbWFuZEJ1ZyhldmVudCwgcGxhdGZvcm0pO1xuICAgICAgICB9O1xuXG4gICAgICAgIHRoaXMuX3RhcmdldEtleVVwQmluZGluZyA9IGZ1bmN0aW9uIChldmVudCkge1xuICAgICAgICAgIF90aGlzLnJlbGVhc2VLZXkoZXZlbnQua2V5Q29kZSwgZXZlbnQpO1xuICAgICAgICB9O1xuXG4gICAgICAgIHRoaXMuX3RhcmdldFJlc2V0QmluZGluZyA9IGZ1bmN0aW9uIChldmVudCkge1xuICAgICAgICAgIF90aGlzLnJlbGVhc2VBbGxLZXlzKGV2ZW50KTtcbiAgICAgICAgfTtcblxuICAgICAgICB0aGlzLl9iaW5kRXZlbnQodGFyZ2V0RWxlbWVudCwgJ2tleWRvd24nLCB0aGlzLl90YXJnZXRLZXlEb3duQmluZGluZyk7XG5cbiAgICAgICAgdGhpcy5fYmluZEV2ZW50KHRhcmdldEVsZW1lbnQsICdrZXl1cCcsIHRoaXMuX3RhcmdldEtleVVwQmluZGluZyk7XG5cbiAgICAgICAgdGhpcy5fYmluZEV2ZW50KHRhcmdldFdpbmRvdywgJ2ZvY3VzJywgdGhpcy5fdGFyZ2V0UmVzZXRCaW5kaW5nKTtcblxuICAgICAgICB0aGlzLl9iaW5kRXZlbnQodGFyZ2V0V2luZG93LCAnYmx1cicsIHRoaXMuX3RhcmdldFJlc2V0QmluZGluZyk7XG5cbiAgICAgICAgdGhpcy5fdGFyZ2V0RWxlbWVudCA9IHRhcmdldEVsZW1lbnQ7XG4gICAgICAgIHRoaXMuX3RhcmdldFdpbmRvdyA9IHRhcmdldFdpbmRvdztcbiAgICAgICAgdGhpcy5fdGFyZ2V0UGxhdGZvcm0gPSB0YXJnZXRQbGF0Zm9ybTtcbiAgICAgICAgdGhpcy5fdGFyZ2V0VXNlckFnZW50ID0gdGFyZ2V0VXNlckFnZW50O1xuICAgICAgICB2YXIgY3VycmVudENvbnRleHQgPSB0aGlzLl9jb250ZXh0c1t0aGlzLl9jdXJyZW50Q29udGV4dF07XG4gICAgICAgIGN1cnJlbnRDb250ZXh0LnRhcmdldFdpbmRvdyA9IHRoaXMuX3RhcmdldFdpbmRvdztcbiAgICAgICAgY3VycmVudENvbnRleHQudGFyZ2V0RWxlbWVudCA9IHRoaXMuX3RhcmdldEVsZW1lbnQ7XG4gICAgICAgIGN1cnJlbnRDb250ZXh0LnRhcmdldFBsYXRmb3JtID0gdGhpcy5fdGFyZ2V0UGxhdGZvcm07XG4gICAgICAgIGN1cnJlbnRDb250ZXh0LnRhcmdldFVzZXJBZ2VudCA9IHRoaXMuX3RhcmdldFVzZXJBZ2VudDtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICB9XG4gICAgfSwge1xuICAgICAga2V5OiBcInN0b3BcIixcbiAgICAgIHZhbHVlOiBmdW5jdGlvbiBzdG9wKCkge1xuICAgICAgICBpZiAoIXRoaXMuX3RhcmdldEVsZW1lbnQgfHwgIXRoaXMuX3RhcmdldFdpbmRvdykge1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuX3VuYmluZEV2ZW50KHRoaXMuX3RhcmdldEVsZW1lbnQsICdrZXlkb3duJywgdGhpcy5fdGFyZ2V0S2V5RG93bkJpbmRpbmcpO1xuXG4gICAgICAgIHRoaXMuX3VuYmluZEV2ZW50KHRoaXMuX3RhcmdldEVsZW1lbnQsICdrZXl1cCcsIHRoaXMuX3RhcmdldEtleVVwQmluZGluZyk7XG5cbiAgICAgICAgdGhpcy5fdW5iaW5kRXZlbnQodGhpcy5fdGFyZ2V0V2luZG93LCAnZm9jdXMnLCB0aGlzLl90YXJnZXRSZXNldEJpbmRpbmcpO1xuXG4gICAgICAgIHRoaXMuX3VuYmluZEV2ZW50KHRoaXMuX3RhcmdldFdpbmRvdywgJ2JsdXInLCB0aGlzLl90YXJnZXRSZXNldEJpbmRpbmcpO1xuXG4gICAgICAgIHRoaXMuX3RhcmdldFdpbmRvdyA9IG51bGw7XG4gICAgICAgIHRoaXMuX3RhcmdldEVsZW1lbnQgPSBudWxsO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgIH1cbiAgICB9LCB7XG4gICAgICBrZXk6IFwicHJlc3NLZXlcIixcbiAgICAgIHZhbHVlOiBmdW5jdGlvbiBwcmVzc0tleShrZXlDb2RlLCBldmVudCkge1xuICAgICAgICBpZiAodGhpcy5fcGF1c2VkKSB7XG4gICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoIXRoaXMuX2xvY2FsZSkge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcignTG9jYWxlIG5vdCBzZXQnKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuX2xvY2FsZS5wcmVzc0tleShrZXlDb2RlKTtcblxuICAgICAgICB0aGlzLl9hcHBseUJpbmRpbmdzKGV2ZW50KTtcblxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgIH1cbiAgICB9LCB7XG4gICAgICBrZXk6IFwicmVsZWFzZUtleVwiLFxuICAgICAgdmFsdWU6IGZ1bmN0aW9uIHJlbGVhc2VLZXkoa2V5Q29kZSwgZXZlbnQpIHtcbiAgICAgICAgaWYgKHRoaXMuX3BhdXNlZCkge1xuICAgICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCF0aGlzLl9sb2NhbGUpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0xvY2FsZSBub3Qgc2V0Jyk7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLl9sb2NhbGUucmVsZWFzZUtleShrZXlDb2RlKTtcblxuICAgICAgICB0aGlzLl9jbGVhckJpbmRpbmdzKGV2ZW50KTtcblxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgIH1cbiAgICB9LCB7XG4gICAgICBrZXk6IFwicmVsZWFzZUFsbEtleXNcIixcbiAgICAgIHZhbHVlOiBmdW5jdGlvbiByZWxlYXNlQWxsS2V5cyhldmVudCkge1xuICAgICAgICBpZiAodGhpcy5fcGF1c2VkKSB7XG4gICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoIXRoaXMuX2xvY2FsZSkge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcignTG9jYWxlIG5vdCBzZXQnKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuX2xvY2FsZS5wcmVzc2VkS2V5cy5sZW5ndGggPSAwO1xuXG4gICAgICAgIHRoaXMuX2NsZWFyQmluZGluZ3MoZXZlbnQpO1xuXG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgfVxuICAgIH0sIHtcbiAgICAgIGtleTogXCJwYXVzZVwiLFxuICAgICAgdmFsdWU6IGZ1bmN0aW9uIHBhdXNlKCkge1xuICAgICAgICBpZiAodGhpcy5fcGF1c2VkKSB7XG4gICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodGhpcy5fbG9jYWxlKSB7XG4gICAgICAgICAgdGhpcy5yZWxlYXNlQWxsS2V5cygpO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5fcGF1c2VkID0gdHJ1ZTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICB9XG4gICAgfSwge1xuICAgICAga2V5OiBcInJlc3VtZVwiLFxuICAgICAgdmFsdWU6IGZ1bmN0aW9uIHJlc3VtZSgpIHtcbiAgICAgICAgdGhpcy5fcGF1c2VkID0gZmFsc2U7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgfVxuICAgIH0sIHtcbiAgICAgIGtleTogXCJyZXNldFwiLFxuICAgICAgdmFsdWU6IGZ1bmN0aW9uIHJlc2V0KCkge1xuICAgICAgICB0aGlzLnJlbGVhc2VBbGxLZXlzKCk7XG4gICAgICAgIHRoaXMuX2xpc3RlbmVycy5sZW5ndGggPSAwO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgIH1cbiAgICB9LCB7XG4gICAgICBrZXk6IFwiX2JpbmRFdmVudFwiLFxuICAgICAgdmFsdWU6IGZ1bmN0aW9uIF9iaW5kRXZlbnQodGFyZ2V0RWxlbWVudCwgZXZlbnROYW1lLCBoYW5kbGVyKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9pc01vZGVybkJyb3dzZXIgPyB0YXJnZXRFbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoZXZlbnROYW1lLCBoYW5kbGVyLCBmYWxzZSkgOiB0YXJnZXRFbGVtZW50LmF0dGFjaEV2ZW50KCdvbicgKyBldmVudE5hbWUsIGhhbmRsZXIpO1xuICAgICAgfVxuICAgIH0sIHtcbiAgICAgIGtleTogXCJfdW5iaW5kRXZlbnRcIixcbiAgICAgIHZhbHVlOiBmdW5jdGlvbiBfdW5iaW5kRXZlbnQodGFyZ2V0RWxlbWVudCwgZXZlbnROYW1lLCBoYW5kbGVyKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9pc01vZGVybkJyb3dzZXIgPyB0YXJnZXRFbGVtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoZXZlbnROYW1lLCBoYW5kbGVyLCBmYWxzZSkgOiB0YXJnZXRFbGVtZW50LmRldGFjaEV2ZW50KCdvbicgKyBldmVudE5hbWUsIGhhbmRsZXIpO1xuICAgICAgfVxuICAgIH0sIHtcbiAgICAgIGtleTogXCJfZ2V0R3JvdXBlZExpc3RlbmVyc1wiLFxuICAgICAgdmFsdWU6IGZ1bmN0aW9uIF9nZXRHcm91cGVkTGlzdGVuZXJzKCkge1xuICAgICAgICB2YXIgbGlzdGVuZXJHcm91cHMgPSBbXTtcbiAgICAgICAgdmFyIGxpc3RlbmVyR3JvdXBNYXAgPSBbXTtcbiAgICAgICAgdmFyIGxpc3RlbmVycyA9IHRoaXMuX2xpc3RlbmVycztcblxuICAgICAgICBpZiAodGhpcy5fY3VycmVudENvbnRleHQgIT09ICdnbG9iYWwnKSB7XG4gICAgICAgICAgbGlzdGVuZXJzID0gW10uY29uY2F0KF90b0NvbnN1bWFibGVBcnJheShsaXN0ZW5lcnMpLCBfdG9Db25zdW1hYmxlQXJyYXkodGhpcy5fY29udGV4dHMuZ2xvYmFsLmxpc3RlbmVycykpO1xuICAgICAgICB9XG5cbiAgICAgICAgbGlzdGVuZXJzLnNvcnQoZnVuY3Rpb24gKGEsIGIpIHtcbiAgICAgICAgICByZXR1cm4gKGIua2V5Q29tYm8gPyBiLmtleUNvbWJvLmtleU5hbWVzLmxlbmd0aCA6IDApIC0gKGEua2V5Q29tYm8gPyBhLmtleUNvbWJvLmtleU5hbWVzLmxlbmd0aCA6IDApO1xuICAgICAgICB9KS5mb3JFYWNoKGZ1bmN0aW9uIChsKSB7XG4gICAgICAgICAgdmFyIG1hcEluZGV4ID0gLTE7XG5cbiAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxpc3RlbmVyR3JvdXBNYXAubGVuZ3RoOyBpICs9IDEpIHtcbiAgICAgICAgICAgIGlmIChsaXN0ZW5lckdyb3VwTWFwW2ldID09PSBudWxsICYmIGwua2V5Q29tYm8gPT09IG51bGwgfHwgbGlzdGVuZXJHcm91cE1hcFtpXSAhPT0gbnVsbCAmJiBsaXN0ZW5lckdyb3VwTWFwW2ldLmlzRXF1YWwobC5rZXlDb21ibykpIHtcbiAgICAgICAgICAgICAgbWFwSW5kZXggPSBpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cblxuICAgICAgICAgIGlmIChtYXBJbmRleCA9PT0gLTEpIHtcbiAgICAgICAgICAgIG1hcEluZGV4ID0gbGlzdGVuZXJHcm91cE1hcC5sZW5ndGg7XG4gICAgICAgICAgICBsaXN0ZW5lckdyb3VwTWFwLnB1c2gobC5rZXlDb21ibyk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaWYgKCFsaXN0ZW5lckdyb3Vwc1ttYXBJbmRleF0pIHtcbiAgICAgICAgICAgIGxpc3RlbmVyR3JvdXBzW21hcEluZGV4XSA9IFtdO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGxpc3RlbmVyR3JvdXBzW21hcEluZGV4XS5wdXNoKGwpO1xuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIGxpc3RlbmVyR3JvdXBzO1xuICAgICAgfVxuICAgIH0sIHtcbiAgICAgIGtleTogXCJfYXBwbHlCaW5kaW5nc1wiLFxuICAgICAgdmFsdWU6IGZ1bmN0aW9uIF9hcHBseUJpbmRpbmdzKGV2ZW50KSB7XG4gICAgICAgIHZhciBfdGhpczIgPSB0aGlzO1xuXG4gICAgICAgIHZhciBwcmV2ZW50UmVwZWF0ID0gZmFsc2U7XG4gICAgICAgIGV2ZW50IHx8IChldmVudCA9IHt9KTtcblxuICAgICAgICBldmVudC5wcmV2ZW50UmVwZWF0ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgIHByZXZlbnRSZXBlYXQgPSB0cnVlO1xuICAgICAgICB9O1xuXG4gICAgICAgIGV2ZW50LnByZXNzZWRLZXlzID0gdGhpcy5fbG9jYWxlLnByZXNzZWRLZXlzLnNsaWNlKDApO1xuICAgICAgICB2YXIgYWN0aXZlVGFyZ2V0S2V5cyA9IHRoaXMuX2xvY2FsZS5hY3RpdmVUYXJnZXRLZXlzO1xuXG4gICAgICAgIHZhciBwcmVzc2VkS2V5cyA9IHRoaXMuX2xvY2FsZS5wcmVzc2VkS2V5cy5zbGljZSgwKTtcblxuICAgICAgICB2YXIgbGlzdGVuZXJHcm91cHMgPSB0aGlzLl9nZXRHcm91cGVkTGlzdGVuZXJzKCk7XG5cbiAgICAgICAgdmFyIF9sb29wID0gZnVuY3Rpb24gX2xvb3AoaSkge1xuICAgICAgICAgIHZhciBsaXN0ZW5lcnMgPSBsaXN0ZW5lckdyb3Vwc1tpXTtcbiAgICAgICAgICB2YXIga2V5Q29tYm8gPSBsaXN0ZW5lcnNbMF0ua2V5Q29tYm87XG5cbiAgICAgICAgICBpZiAoa2V5Q29tYm8gPT09IG51bGwgfHwga2V5Q29tYm8uY2hlY2socHJlc3NlZEtleXMpICYmIGFjdGl2ZVRhcmdldEtleXMuc29tZShmdW5jdGlvbiAoaykge1xuICAgICAgICAgICAgcmV0dXJuIGtleUNvbWJvLmtleU5hbWVzLmluY2x1ZGVzKGspO1xuICAgICAgICAgIH0pKSB7XG4gICAgICAgICAgICBmb3IgKHZhciBqID0gMDsgaiA8IGxpc3RlbmVycy5sZW5ndGg7IGogKz0gMSkge1xuICAgICAgICAgICAgICB2YXIgbGlzdGVuZXIgPSBsaXN0ZW5lcnNbal07XG5cbiAgICAgICAgICAgICAgaWYgKCFsaXN0ZW5lci5leGVjdXRpbmdIYW5kbGVyICYmIGxpc3RlbmVyLnByZXNzSGFuZGxlciAmJiAhbGlzdGVuZXIucHJldmVudFJlcGVhdCkge1xuICAgICAgICAgICAgICAgIGxpc3RlbmVyLmV4ZWN1dGluZ0hhbmRsZXIgPSB0cnVlO1xuICAgICAgICAgICAgICAgIGxpc3RlbmVyLnByZXNzSGFuZGxlci5jYWxsKF90aGlzMiwgZXZlbnQpO1xuICAgICAgICAgICAgICAgIGxpc3RlbmVyLmV4ZWN1dGluZ0hhbmRsZXIgPSBmYWxzZTtcblxuICAgICAgICAgICAgICAgIGlmIChwcmV2ZW50UmVwZWF0IHx8IGxpc3RlbmVyLnByZXZlbnRSZXBlYXRCeURlZmF1bHQpIHtcbiAgICAgICAgICAgICAgICAgIGxpc3RlbmVyLnByZXZlbnRSZXBlYXQgPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgcHJldmVudFJlcGVhdCA9IGZhbHNlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgIGlmIChfdGhpczIuX2FwcGxpZWRMaXN0ZW5lcnMuaW5kZXhPZihsaXN0ZW5lcikgPT09IC0xKSB7XG4gICAgICAgICAgICAgICAgX3RoaXMyLl9hcHBsaWVkTGlzdGVuZXJzLnB1c2gobGlzdGVuZXIpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChrZXlDb21ibykge1xuICAgICAgICAgICAgICBmb3IgKHZhciBfaiA9IDA7IF9qIDwga2V5Q29tYm8ua2V5TmFtZXMubGVuZ3RoOyBfaiArPSAxKSB7XG4gICAgICAgICAgICAgICAgdmFyIGluZGV4ID0gcHJlc3NlZEtleXMuaW5kZXhPZihrZXlDb21iby5rZXlOYW1lc1tfal0pO1xuXG4gICAgICAgICAgICAgICAgaWYgKGluZGV4ICE9PSAtMSkge1xuICAgICAgICAgICAgICAgICAgcHJlc3NlZEtleXMuc3BsaWNlKGluZGV4LCAxKTtcbiAgICAgICAgICAgICAgICAgIF9qIC09IDE7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9O1xuXG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGlzdGVuZXJHcm91cHMubGVuZ3RoOyBpICs9IDEpIHtcbiAgICAgICAgICBfbG9vcChpKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0sIHtcbiAgICAgIGtleTogXCJfY2xlYXJCaW5kaW5nc1wiLFxuICAgICAgdmFsdWU6IGZ1bmN0aW9uIF9jbGVhckJpbmRpbmdzKGV2ZW50KSB7XG4gICAgICAgIGV2ZW50IHx8IChldmVudCA9IHt9KTtcbiAgICAgICAgZXZlbnQucHJlc3NlZEtleXMgPSB0aGlzLl9sb2NhbGUucHJlc3NlZEtleXMuc2xpY2UoMCk7XG5cbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0aGlzLl9hcHBsaWVkTGlzdGVuZXJzLmxlbmd0aDsgaSArPSAxKSB7XG4gICAgICAgICAgdmFyIGxpc3RlbmVyID0gdGhpcy5fYXBwbGllZExpc3RlbmVyc1tpXTtcbiAgICAgICAgICB2YXIga2V5Q29tYm8gPSBsaXN0ZW5lci5rZXlDb21ibztcblxuICAgICAgICAgIGlmIChrZXlDb21ibyA9PT0gbnVsbCB8fCAha2V5Q29tYm8uY2hlY2sodGhpcy5fbG9jYWxlLnByZXNzZWRLZXlzKSkge1xuICAgICAgICAgICAgbGlzdGVuZXIucHJldmVudFJlcGVhdCA9IGZhbHNlO1xuXG4gICAgICAgICAgICBpZiAoa2V5Q29tYm8gIT09IG51bGwgfHwgZXZlbnQucHJlc3NlZEtleXMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICAgIHRoaXMuX2FwcGxpZWRMaXN0ZW5lcnMuc3BsaWNlKGksIDEpO1xuXG4gICAgICAgICAgICAgIGkgLT0gMTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKCFsaXN0ZW5lci5leGVjdXRpbmdIYW5kbGVyICYmIGxpc3RlbmVyLnJlbGVhc2VIYW5kbGVyKSB7XG4gICAgICAgICAgICAgIGxpc3RlbmVyLmV4ZWN1dGluZ0hhbmRsZXIgPSB0cnVlO1xuICAgICAgICAgICAgICBsaXN0ZW5lci5yZWxlYXNlSGFuZGxlci5jYWxsKHRoaXMsIGV2ZW50KTtcbiAgICAgICAgICAgICAgbGlzdGVuZXIuZXhlY3V0aW5nSGFuZGxlciA9IGZhbHNlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0sIHtcbiAgICAgIGtleTogXCJfaGFuZGxlQ29tbWFuZEJ1Z1wiLFxuICAgICAgdmFsdWU6IGZ1bmN0aW9uIF9oYW5kbGVDb21tYW5kQnVnKGV2ZW50LCBwbGF0Zm9ybSkge1xuICAgICAgICAvLyBPbiBNYWMgd2hlbiB0aGUgY29tbWFuZCBrZXkgaXMga2VwdCBwcmVzc2VkLCBrZXl1cCBpcyBub3QgdHJpZ2dlcmVkIGZvciBhbnkgb3RoZXIga2V5LlxuICAgICAgICAvLyBJbiB0aGlzIGNhc2UgZm9yY2UgYSBrZXl1cCBmb3Igbm9uLW1vZGlmaWVyIGtleXMgZGlyZWN0bHkgYWZ0ZXIgdGhlIGtleXByZXNzLlxuICAgICAgICB2YXIgbW9kaWZpZXJLZXlzID0gW1wic2hpZnRcIiwgXCJjdHJsXCIsIFwiYWx0XCIsIFwiY2Fwc2xvY2tcIiwgXCJ0YWJcIiwgXCJjb21tYW5kXCJdO1xuXG4gICAgICAgIGlmIChwbGF0Zm9ybS5tYXRjaChcIk1hY1wiKSAmJiB0aGlzLl9sb2NhbGUucHJlc3NlZEtleXMuaW5jbHVkZXMoXCJjb21tYW5kXCIpICYmICFtb2RpZmllcktleXMuaW5jbHVkZXModGhpcy5fbG9jYWxlLmdldEtleU5hbWVzKGV2ZW50LmtleUNvZGUpWzBdKSkge1xuICAgICAgICAgIHRoaXMuX3RhcmdldEtleVVwQmluZGluZyhldmVudCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XSk7XG5cbiAgICByZXR1cm4gS2V5Ym9hcmQ7XG4gIH0oKTtcblxuICBmdW5jdGlvbiB1cyhsb2NhbGUsIHBsYXRmb3JtLCB1c2VyQWdlbnQpIHtcbiAgICAvLyBnZW5lcmFsXG4gICAgbG9jYWxlLmJpbmRLZXlDb2RlKDMsIFsnY2FuY2VsJ10pO1xuICAgIGxvY2FsZS5iaW5kS2V5Q29kZSg4LCBbJ2JhY2tzcGFjZSddKTtcbiAgICBsb2NhbGUuYmluZEtleUNvZGUoOSwgWyd0YWInXSk7XG4gICAgbG9jYWxlLmJpbmRLZXlDb2RlKDEyLCBbJ2NsZWFyJ10pO1xuICAgIGxvY2FsZS5iaW5kS2V5Q29kZSgxMywgWydlbnRlciddKTtcbiAgICBsb2NhbGUuYmluZEtleUNvZGUoMTYsIFsnc2hpZnQnXSk7XG4gICAgbG9jYWxlLmJpbmRLZXlDb2RlKDE3LCBbJ2N0cmwnXSk7XG4gICAgbG9jYWxlLmJpbmRLZXlDb2RlKDE4LCBbJ2FsdCcsICdtZW51J10pO1xuICAgIGxvY2FsZS5iaW5kS2V5Q29kZSgxOSwgWydwYXVzZScsICdicmVhayddKTtcbiAgICBsb2NhbGUuYmluZEtleUNvZGUoMjAsIFsnY2Fwc2xvY2snXSk7XG4gICAgbG9jYWxlLmJpbmRLZXlDb2RlKDI3LCBbJ2VzY2FwZScsICdlc2MnXSk7XG4gICAgbG9jYWxlLmJpbmRLZXlDb2RlKDMyLCBbJ3NwYWNlJywgJ3NwYWNlYmFyJ10pO1xuICAgIGxvY2FsZS5iaW5kS2V5Q29kZSgzMywgWydwYWdldXAnXSk7XG4gICAgbG9jYWxlLmJpbmRLZXlDb2RlKDM0LCBbJ3BhZ2Vkb3duJ10pO1xuICAgIGxvY2FsZS5iaW5kS2V5Q29kZSgzNSwgWydlbmQnXSk7XG4gICAgbG9jYWxlLmJpbmRLZXlDb2RlKDM2LCBbJ2hvbWUnXSk7XG4gICAgbG9jYWxlLmJpbmRLZXlDb2RlKDM3LCBbJ2xlZnQnXSk7XG4gICAgbG9jYWxlLmJpbmRLZXlDb2RlKDM4LCBbJ3VwJ10pO1xuICAgIGxvY2FsZS5iaW5kS2V5Q29kZSgzOSwgWydyaWdodCddKTtcbiAgICBsb2NhbGUuYmluZEtleUNvZGUoNDAsIFsnZG93biddKTtcbiAgICBsb2NhbGUuYmluZEtleUNvZGUoNDEsIFsnc2VsZWN0J10pO1xuICAgIGxvY2FsZS5iaW5kS2V5Q29kZSg0MiwgWydwcmludHNjcmVlbiddKTtcbiAgICBsb2NhbGUuYmluZEtleUNvZGUoNDMsIFsnZXhlY3V0ZSddKTtcbiAgICBsb2NhbGUuYmluZEtleUNvZGUoNDQsIFsnc25hcHNob3QnXSk7XG4gICAgbG9jYWxlLmJpbmRLZXlDb2RlKDQ1LCBbJ2luc2VydCcsICdpbnMnXSk7XG4gICAgbG9jYWxlLmJpbmRLZXlDb2RlKDQ2LCBbJ2RlbGV0ZScsICdkZWwnXSk7XG4gICAgbG9jYWxlLmJpbmRLZXlDb2RlKDQ3LCBbJ2hlbHAnXSk7XG4gICAgbG9jYWxlLmJpbmRLZXlDb2RlKDE0NSwgWydzY3JvbGxsb2NrJywgJ3Njcm9sbCddKTtcbiAgICBsb2NhbGUuYmluZEtleUNvZGUoMTg4LCBbJ2NvbW1hJywgJywnXSk7XG4gICAgbG9jYWxlLmJpbmRLZXlDb2RlKDE5MCwgWydwZXJpb2QnLCAnLiddKTtcbiAgICBsb2NhbGUuYmluZEtleUNvZGUoMTkxLCBbJ3NsYXNoJywgJ2ZvcndhcmRzbGFzaCcsICcvJ10pO1xuICAgIGxvY2FsZS5iaW5kS2V5Q29kZSgxOTIsIFsnZ3JhdmVhY2NlbnQnLCAnYCddKTtcbiAgICBsb2NhbGUuYmluZEtleUNvZGUoMjE5LCBbJ29wZW5icmFja2V0JywgJ1snXSk7XG4gICAgbG9jYWxlLmJpbmRLZXlDb2RlKDIyMCwgWydiYWNrc2xhc2gnLCAnXFxcXCddKTtcbiAgICBsb2NhbGUuYmluZEtleUNvZGUoMjIxLCBbJ2Nsb3NlYnJhY2tldCcsICddJ10pO1xuICAgIGxvY2FsZS5iaW5kS2V5Q29kZSgyMjIsIFsnYXBvc3Ryb3BoZScsICdcXCcnXSk7IC8vIDAtOVxuXG4gICAgbG9jYWxlLmJpbmRLZXlDb2RlKDQ4LCBbJ3plcm8nLCAnMCddKTtcbiAgICBsb2NhbGUuYmluZEtleUNvZGUoNDksIFsnb25lJywgJzEnXSk7XG4gICAgbG9jYWxlLmJpbmRLZXlDb2RlKDUwLCBbJ3R3bycsICcyJ10pO1xuICAgIGxvY2FsZS5iaW5kS2V5Q29kZSg1MSwgWyd0aHJlZScsICczJ10pO1xuICAgIGxvY2FsZS5iaW5kS2V5Q29kZSg1MiwgWydmb3VyJywgJzQnXSk7XG4gICAgbG9jYWxlLmJpbmRLZXlDb2RlKDUzLCBbJ2ZpdmUnLCAnNSddKTtcbiAgICBsb2NhbGUuYmluZEtleUNvZGUoNTQsIFsnc2l4JywgJzYnXSk7XG4gICAgbG9jYWxlLmJpbmRLZXlDb2RlKDU1LCBbJ3NldmVuJywgJzcnXSk7XG4gICAgbG9jYWxlLmJpbmRLZXlDb2RlKDU2LCBbJ2VpZ2h0JywgJzgnXSk7XG4gICAgbG9jYWxlLmJpbmRLZXlDb2RlKDU3LCBbJ25pbmUnLCAnOSddKTsgLy8gbnVtcGFkXG5cbiAgICBsb2NhbGUuYmluZEtleUNvZGUoOTYsIFsnbnVtemVybycsICdudW0wJ10pO1xuICAgIGxvY2FsZS5iaW5kS2V5Q29kZSg5NywgWydudW1vbmUnLCAnbnVtMSddKTtcbiAgICBsb2NhbGUuYmluZEtleUNvZGUoOTgsIFsnbnVtdHdvJywgJ251bTInXSk7XG4gICAgbG9jYWxlLmJpbmRLZXlDb2RlKDk5LCBbJ251bXRocmVlJywgJ251bTMnXSk7XG4gICAgbG9jYWxlLmJpbmRLZXlDb2RlKDEwMCwgWydudW1mb3VyJywgJ251bTQnXSk7XG4gICAgbG9jYWxlLmJpbmRLZXlDb2RlKDEwMSwgWydudW1maXZlJywgJ251bTUnXSk7XG4gICAgbG9jYWxlLmJpbmRLZXlDb2RlKDEwMiwgWydudW1zaXgnLCAnbnVtNiddKTtcbiAgICBsb2NhbGUuYmluZEtleUNvZGUoMTAzLCBbJ251bXNldmVuJywgJ251bTcnXSk7XG4gICAgbG9jYWxlLmJpbmRLZXlDb2RlKDEwNCwgWydudW1laWdodCcsICdudW04J10pO1xuICAgIGxvY2FsZS5iaW5kS2V5Q29kZSgxMDUsIFsnbnVtbmluZScsICdudW05J10pO1xuICAgIGxvY2FsZS5iaW5kS2V5Q29kZSgxMDYsIFsnbnVtbXVsdGlwbHknLCAnbnVtKiddKTtcbiAgICBsb2NhbGUuYmluZEtleUNvZGUoMTA3LCBbJ251bWFkZCcsICdudW0rJ10pO1xuICAgIGxvY2FsZS5iaW5kS2V5Q29kZSgxMDgsIFsnbnVtZW50ZXInXSk7XG4gICAgbG9jYWxlLmJpbmRLZXlDb2RlKDEwOSwgWydudW1zdWJ0cmFjdCcsICdudW0tJ10pO1xuICAgIGxvY2FsZS5iaW5kS2V5Q29kZSgxMTAsIFsnbnVtZGVjaW1hbCcsICdudW0uJ10pO1xuICAgIGxvY2FsZS5iaW5kS2V5Q29kZSgxMTEsIFsnbnVtZGl2aWRlJywgJ251bS8nXSk7XG4gICAgbG9jYWxlLmJpbmRLZXlDb2RlKDE0NCwgWydudW1sb2NrJywgJ251bSddKTsgLy8gZnVuY3Rpb24ga2V5c1xuXG4gICAgbG9jYWxlLmJpbmRLZXlDb2RlKDExMiwgWydmMSddKTtcbiAgICBsb2NhbGUuYmluZEtleUNvZGUoMTEzLCBbJ2YyJ10pO1xuICAgIGxvY2FsZS5iaW5kS2V5Q29kZSgxMTQsIFsnZjMnXSk7XG4gICAgbG9jYWxlLmJpbmRLZXlDb2RlKDExNSwgWydmNCddKTtcbiAgICBsb2NhbGUuYmluZEtleUNvZGUoMTE2LCBbJ2Y1J10pO1xuICAgIGxvY2FsZS5iaW5kS2V5Q29kZSgxMTcsIFsnZjYnXSk7XG4gICAgbG9jYWxlLmJpbmRLZXlDb2RlKDExOCwgWydmNyddKTtcbiAgICBsb2NhbGUuYmluZEtleUNvZGUoMTE5LCBbJ2Y4J10pO1xuICAgIGxvY2FsZS5iaW5kS2V5Q29kZSgxMjAsIFsnZjknXSk7XG4gICAgbG9jYWxlLmJpbmRLZXlDb2RlKDEyMSwgWydmMTAnXSk7XG4gICAgbG9jYWxlLmJpbmRLZXlDb2RlKDEyMiwgWydmMTEnXSk7XG4gICAgbG9jYWxlLmJpbmRLZXlDb2RlKDEyMywgWydmMTInXSk7XG4gICAgbG9jYWxlLmJpbmRLZXlDb2RlKDEyNCwgWydmMTMnXSk7XG4gICAgbG9jYWxlLmJpbmRLZXlDb2RlKDEyNSwgWydmMTQnXSk7XG4gICAgbG9jYWxlLmJpbmRLZXlDb2RlKDEyNiwgWydmMTUnXSk7XG4gICAgbG9jYWxlLmJpbmRLZXlDb2RlKDEyNywgWydmMTYnXSk7XG4gICAgbG9jYWxlLmJpbmRLZXlDb2RlKDEyOCwgWydmMTcnXSk7XG4gICAgbG9jYWxlLmJpbmRLZXlDb2RlKDEyOSwgWydmMTgnXSk7XG4gICAgbG9jYWxlLmJpbmRLZXlDb2RlKDEzMCwgWydmMTknXSk7XG4gICAgbG9jYWxlLmJpbmRLZXlDb2RlKDEzMSwgWydmMjAnXSk7XG4gICAgbG9jYWxlLmJpbmRLZXlDb2RlKDEzMiwgWydmMjEnXSk7XG4gICAgbG9jYWxlLmJpbmRLZXlDb2RlKDEzMywgWydmMjInXSk7XG4gICAgbG9jYWxlLmJpbmRLZXlDb2RlKDEzNCwgWydmMjMnXSk7XG4gICAgbG9jYWxlLmJpbmRLZXlDb2RlKDEzNSwgWydmMjQnXSk7IC8vIHNlY29uZGFyeSBrZXkgc3ltYm9sc1xuXG4gICAgbG9jYWxlLmJpbmRNYWNybygnc2hpZnQgKyBgJywgWyd0aWxkZScsICd+J10pO1xuICAgIGxvY2FsZS5iaW5kTWFjcm8oJ3NoaWZ0ICsgMScsIFsnZXhjbGFtYXRpb24nLCAnZXhjbGFtYXRpb25wb2ludCcsICchJ10pO1xuICAgIGxvY2FsZS5iaW5kTWFjcm8oJ3NoaWZ0ICsgMicsIFsnYXQnLCAnQCddKTtcbiAgICBsb2NhbGUuYmluZE1hY3JvKCdzaGlmdCArIDMnLCBbJ251bWJlcicsICcjJ10pO1xuICAgIGxvY2FsZS5iaW5kTWFjcm8oJ3NoaWZ0ICsgNCcsIFsnZG9sbGFyJywgJ2RvbGxhcnMnLCAnZG9sbGFyc2lnbicsICckJ10pO1xuICAgIGxvY2FsZS5iaW5kTWFjcm8oJ3NoaWZ0ICsgNScsIFsncGVyY2VudCcsICclJ10pO1xuICAgIGxvY2FsZS5iaW5kTWFjcm8oJ3NoaWZ0ICsgNicsIFsnY2FyZXQnLCAnXiddKTtcbiAgICBsb2NhbGUuYmluZE1hY3JvKCdzaGlmdCArIDcnLCBbJ2FtcGVyc2FuZCcsICdhbmQnLCAnJiddKTtcbiAgICBsb2NhbGUuYmluZE1hY3JvKCdzaGlmdCArIDgnLCBbJ2FzdGVyaXNrJywgJyonXSk7XG4gICAgbG9jYWxlLmJpbmRNYWNybygnc2hpZnQgKyA5JywgWydvcGVucGFyZW4nLCAnKCddKTtcbiAgICBsb2NhbGUuYmluZE1hY3JvKCdzaGlmdCArIDAnLCBbJ2Nsb3NlcGFyZW4nLCAnKSddKTtcbiAgICBsb2NhbGUuYmluZE1hY3JvKCdzaGlmdCArIC0nLCBbJ3VuZGVyc2NvcmUnLCAnXyddKTtcbiAgICBsb2NhbGUuYmluZE1hY3JvKCdzaGlmdCArID0nLCBbJ3BsdXMnLCAnKyddKTtcbiAgICBsb2NhbGUuYmluZE1hY3JvKCdzaGlmdCArIFsnLCBbJ29wZW5jdXJseWJyYWNlJywgJ29wZW5jdXJseWJyYWNrZXQnLCAneyddKTtcbiAgICBsb2NhbGUuYmluZE1hY3JvKCdzaGlmdCArIF0nLCBbJ2Nsb3NlY3VybHlicmFjZScsICdjbG9zZWN1cmx5YnJhY2tldCcsICd9J10pO1xuICAgIGxvY2FsZS5iaW5kTWFjcm8oJ3NoaWZ0ICsgXFxcXCcsIFsndmVydGljYWxiYXInLCAnfCddKTtcbiAgICBsb2NhbGUuYmluZE1hY3JvKCdzaGlmdCArIDsnLCBbJ2NvbG9uJywgJzonXSk7XG4gICAgbG9jYWxlLmJpbmRNYWNybygnc2hpZnQgKyBcXCcnLCBbJ3F1b3RhdGlvbm1hcmsnLCAnXFwnJ10pO1xuICAgIGxvY2FsZS5iaW5kTWFjcm8oJ3NoaWZ0ICsgISwnLCBbJ29wZW5hbmdsZWJyYWNrZXQnLCAnPCddKTtcbiAgICBsb2NhbGUuYmluZE1hY3JvKCdzaGlmdCArIC4nLCBbJ2Nsb3NlYW5nbGVicmFja2V0JywgJz4nXSk7XG4gICAgbG9jYWxlLmJpbmRNYWNybygnc2hpZnQgKyAvJywgWydxdWVzdGlvbm1hcmsnLCAnPyddKTtcblxuICAgIGlmIChwbGF0Zm9ybS5tYXRjaCgnTWFjJykpIHtcbiAgICAgIGxvY2FsZS5iaW5kTWFjcm8oJ2NvbW1hbmQnLCBbJ21vZCcsICdtb2RpZmllciddKTtcbiAgICB9IGVsc2Uge1xuICAgICAgbG9jYWxlLmJpbmRNYWNybygnY3RybCcsIFsnbW9kJywgJ21vZGlmaWVyJ10pO1xuICAgIH0gLy9hLXogYW5kIEEtWlxuXG5cbiAgICBmb3IgKHZhciBrZXlDb2RlID0gNjU7IGtleUNvZGUgPD0gOTA7IGtleUNvZGUgKz0gMSkge1xuICAgICAgdmFyIGtleU5hbWUgPSBTdHJpbmcuZnJvbUNoYXJDb2RlKGtleUNvZGUgKyAzMik7XG4gICAgICB2YXIgY2FwaXRhbEtleU5hbWUgPSBTdHJpbmcuZnJvbUNoYXJDb2RlKGtleUNvZGUpO1xuICAgICAgbG9jYWxlLmJpbmRLZXlDb2RlKGtleUNvZGUsIGtleU5hbWUpO1xuICAgICAgbG9jYWxlLmJpbmRNYWNybygnc2hpZnQgKyAnICsga2V5TmFtZSwgY2FwaXRhbEtleU5hbWUpO1xuICAgICAgbG9jYWxlLmJpbmRNYWNybygnY2Fwc2xvY2sgKyAnICsga2V5TmFtZSwgY2FwaXRhbEtleU5hbWUpO1xuICAgIH0gLy8gYnJvd3NlciBjYXZlYXRzXG5cblxuICAgIHZhciBzZW1pY29sb25LZXlDb2RlID0gdXNlckFnZW50Lm1hdGNoKCdGaXJlZm94JykgPyA1OSA6IDE4NjtcbiAgICB2YXIgZGFzaEtleUNvZGUgPSB1c2VyQWdlbnQubWF0Y2goJ0ZpcmVmb3gnKSA/IDE3MyA6IDE4OTtcbiAgICB2YXIgZXF1YWxLZXlDb2RlID0gdXNlckFnZW50Lm1hdGNoKCdGaXJlZm94JykgPyA2MSA6IDE4NztcbiAgICB2YXIgbGVmdENvbW1hbmRLZXlDb2RlO1xuICAgIHZhciByaWdodENvbW1hbmRLZXlDb2RlO1xuXG4gICAgaWYgKHBsYXRmb3JtLm1hdGNoKCdNYWMnKSAmJiAodXNlckFnZW50Lm1hdGNoKCdTYWZhcmknKSB8fCB1c2VyQWdlbnQubWF0Y2goJ0Nocm9tZScpKSkge1xuICAgICAgbGVmdENvbW1hbmRLZXlDb2RlID0gOTE7XG4gICAgICByaWdodENvbW1hbmRLZXlDb2RlID0gOTM7XG4gICAgfSBlbHNlIGlmIChwbGF0Zm9ybS5tYXRjaCgnTWFjJykgJiYgdXNlckFnZW50Lm1hdGNoKCdPcGVyYScpKSB7XG4gICAgICBsZWZ0Q29tbWFuZEtleUNvZGUgPSAxNztcbiAgICAgIHJpZ2h0Q29tbWFuZEtleUNvZGUgPSAxNztcbiAgICB9IGVsc2UgaWYgKHBsYXRmb3JtLm1hdGNoKCdNYWMnKSAmJiB1c2VyQWdlbnQubWF0Y2goJ0ZpcmVmb3gnKSkge1xuICAgICAgbGVmdENvbW1hbmRLZXlDb2RlID0gMjI0O1xuICAgICAgcmlnaHRDb21tYW5kS2V5Q29kZSA9IDIyNDtcbiAgICB9XG5cbiAgICBsb2NhbGUuYmluZEtleUNvZGUoc2VtaWNvbG9uS2V5Q29kZSwgWydzZW1pY29sb24nLCAnOyddKTtcbiAgICBsb2NhbGUuYmluZEtleUNvZGUoZGFzaEtleUNvZGUsIFsnZGFzaCcsICctJ10pO1xuICAgIGxvY2FsZS5iaW5kS2V5Q29kZShlcXVhbEtleUNvZGUsIFsnZXF1YWwnLCAnZXF1YWxzaWduJywgJz0nXSk7XG4gICAgbG9jYWxlLmJpbmRLZXlDb2RlKGxlZnRDb21tYW5kS2V5Q29kZSwgWydjb21tYW5kJywgJ3dpbmRvd3MnLCAnd2luJywgJ3N1cGVyJywgJ2xlZnRjb21tYW5kJywgJ2xlZnR3aW5kb3dzJywgJ2xlZnR3aW4nLCAnbGVmdHN1cGVyJ10pO1xuICAgIGxvY2FsZS5iaW5kS2V5Q29kZShyaWdodENvbW1hbmRLZXlDb2RlLCBbJ2NvbW1hbmQnLCAnd2luZG93cycsICd3aW4nLCAnc3VwZXInLCAncmlnaHRjb21tYW5kJywgJ3JpZ2h0d2luZG93cycsICdyaWdodHdpbicsICdyaWdodHN1cGVyJ10pOyAvLyBraWxsIGtleXNcblxuICAgIGxvY2FsZS5zZXRLaWxsS2V5KCdjb21tYW5kJyk7XG4gIH1cblxuICB2YXIga2V5Ym9hcmQgPSBuZXcgS2V5Ym9hcmQoKTtcbiAga2V5Ym9hcmQuc2V0TG9jYWxlKCd1cycsIHVzKTtcbiAga2V5Ym9hcmQuS2V5Ym9hcmQgPSBLZXlib2FyZDtcbiAga2V5Ym9hcmQuTG9jYWxlID0gTG9jYWxlO1xuICBrZXlib2FyZC5LZXlDb21ibyA9IEtleUNvbWJvO1xuXG4gIHJldHVybiBrZXlib2FyZDtcblxufSkpKTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWRhdGE6YXBwbGljYXRpb24vanNvbjtjaGFyc2V0PXV0Zi04O2Jhc2U2NCxleUoyWlhKemFXOXVJam96TENKbWFXeGxJam9pYTJWNVltOWhjbVF1YW5NaUxDSnpiM1Z5WTJWeklqcGJJaTR1TDJ4cFlpOXJaWGt0WTI5dFltOHVhbk1pTENJdUxpOXNhV0l2Ykc5allXeGxMbXB6SWl3aUxpNHZiR2xpTDJ0bGVXSnZZWEprTG1weklpd2lMaTR2Ykc5allXeGxjeTkxY3k1cWN5SXNJaTR1TDJsdVpHVjRMbXB6SWwwc0luTnZkWEpqWlhORGIyNTBaVzUwSWpwYklseHVaWGh3YjNKMElHTnNZWE56SUV0bGVVTnZiV0p2SUh0Y2JpQWdZMjl1YzNSeWRXTjBiM0lvYTJWNVEyOXRZbTlUZEhJcElIdGNiaUFnSUNCMGFHbHpMbk52ZFhKalpWTjBjaUE5SUd0bGVVTnZiV0p2VTNSeU8xeHVJQ0FnSUhSb2FYTXVjM1ZpUTI5dFltOXpJRDBnUzJWNVEyOXRZbTh1Y0dGeWMyVkRiMjFpYjFOMGNpaHJaWGxEYjIxaWIxTjBjaWs3WEc0Z0lDQWdkR2hwY3k1clpYbE9ZVzFsY3lBZ1BTQjBhR2x6TG5OMVlrTnZiV0p2Y3k1eVpXUjFZMlVvS0cxbGJXOHNJRzVsZUhSVGRXSkRiMjFpYnlrZ1BUNWNiaUFnSUNBZ0lHMWxiVzh1WTI5dVkyRjBLRzVsZUhSVGRXSkRiMjFpYnlrc0lGdGRLVHRjYmlBZ2ZWeHVYRzRnSUdOb1pXTnJLSEJ5WlhOelpXUkxaWGxPWVcxbGN5a2dlMXh1SUNBZ0lHeGxkQ0J6ZEdGeWRHbHVaMHRsZVU1aGJXVkpibVJsZUNBOUlEQTdYRzRnSUNBZ1ptOXlJQ2hzWlhRZ2FTQTlJREE3SUdrZ1BDQjBhR2x6TG5OMVlrTnZiV0p2Y3k1c1pXNW5kR2c3SUdrZ0t6MGdNU2tnZTF4dUlDQWdJQ0FnYzNSaGNuUnBibWRMWlhsT1lXMWxTVzVrWlhnZ1BTQjBhR2x6TGw5amFHVmphMU4xWWtOdmJXSnZLRnh1SUNBZ0lDQWdJQ0IwYUdsekxuTjFZa052YldKdmMxdHBYU3hjYmlBZ0lDQWdJQ0FnYzNSaGNuUnBibWRMWlhsT1lXMWxTVzVrWlhnc1hHNGdJQ0FnSUNBZ0lIQnlaWE56WldSTFpYbE9ZVzFsYzF4dUlDQWdJQ0FnS1R0Y2JpQWdJQ0FnSUdsbUlDaHpkR0Z5ZEdsdVowdGxlVTVoYldWSmJtUmxlQ0E5UFQwZ0xURXBJSHNnY21WMGRYSnVJR1poYkhObE95QjlYRzRnSUNBZ2ZWeHVJQ0FnSUhKbGRIVnliaUIwY25WbE8xeHVJQ0I5TzF4dVhHNGdJR2x6UlhGMVlXd29iM1JvWlhKTFpYbERiMjFpYnlrZ2UxeHVJQ0FnSUdsbUlDaGNiaUFnSUNBZ0lDRnZkR2hsY2t0bGVVTnZiV0p2SUh4OFhHNGdJQ0FnSUNCMGVYQmxiMllnYjNSb1pYSkxaWGxEYjIxaWJ5QWhQVDBnSjNOMGNtbHVaeWNnSmlaY2JpQWdJQ0FnSUhSNWNHVnZaaUJ2ZEdobGNrdGxlVU52YldKdklDRTlQU0FuYjJKcVpXTjBKMXh1SUNBZ0lDa2dleUJ5WlhSMWNtNGdabUZzYzJVN0lIMWNibHh1SUNBZ0lHbG1JQ2gwZVhCbGIyWWdiM1JvWlhKTFpYbERiMjFpYnlBOVBUMGdKM04wY21sdVp5Y3BJSHRjYmlBZ0lDQWdJRzkwYUdWeVMyVjVRMjl0WW04Z1BTQnVaWGNnUzJWNVEyOXRZbThvYjNSb1pYSkxaWGxEYjIxaWJ5azdYRzRnSUNBZ2ZWeHVYRzRnSUNBZ2FXWWdLSFJvYVhNdWMzVmlRMjl0WW05ekxteGxibWQwYUNBaFBUMGdiM1JvWlhKTFpYbERiMjFpYnk1emRXSkRiMjFpYjNNdWJHVnVaM1JvS1NCN1hHNGdJQ0FnSUNCeVpYUjFjbTRnWm1Gc2MyVTdYRzRnSUNBZ2ZWeHVJQ0FnSUdadmNpQW9iR1YwSUdrZ1BTQXdPeUJwSUR3Z2RHaHBjeTV6ZFdKRGIyMWliM011YkdWdVozUm9PeUJwSUNzOUlERXBJSHRjYmlBZ0lDQWdJR2xtSUNoMGFHbHpMbk4xWWtOdmJXSnZjMXRwWFM1c1pXNW5kR2dnSVQwOUlHOTBhR1Z5UzJWNVEyOXRZbTh1YzNWaVEyOXRZbTl6VzJsZExteGxibWQwYUNrZ2UxeHVJQ0FnSUNBZ0lDQnlaWFIxY200Z1ptRnNjMlU3WEc0Z0lDQWdJQ0I5WEc0Z0lDQWdmVnh1WEc0Z0lDQWdabTl5SUNoc1pYUWdhU0E5SURBN0lHa2dQQ0IwYUdsekxuTjFZa052YldKdmN5NXNaVzVuZEdnN0lHa2dLejBnTVNrZ2UxeHVJQ0FnSUNBZ1kyOXVjM1FnYzNWaVEyOXRZbThnSUNBZ0lDQTlJSFJvYVhNdWMzVmlRMjl0WW05elcybGRPMXh1SUNBZ0lDQWdZMjl1YzNRZ2IzUm9aWEpUZFdKRGIyMWlieUE5SUc5MGFHVnlTMlY1UTI5dFltOHVjM1ZpUTI5dFltOXpXMmxkTG5Oc2FXTmxLREFwTzF4dVhHNGdJQ0FnSUNCbWIzSWdLR3hsZENCcUlEMGdNRHNnYWlBOElITjFZa052YldKdkxteGxibWQwYURzZ2FpQXJQU0F4S1NCN1hHNGdJQ0FnSUNBZ0lHTnZibk4wSUd0bGVVNWhiV1VnUFNCemRXSkRiMjFpYjF0cVhUdGNiaUFnSUNBZ0lDQWdZMjl1YzNRZ2FXNWtaWGdnSUNBOUlHOTBhR1Z5VTNWaVEyOXRZbTh1YVc1a1pYaFBaaWhyWlhsT1lXMWxLVHRjYmx4dUlDQWdJQ0FnSUNCcFppQW9hVzVrWlhnZ1BpQXRNU2tnZTF4dUlDQWdJQ0FnSUNBZ0lHOTBhR1Z5VTNWaVEyOXRZbTh1YzNCc2FXTmxLR2x1WkdWNExDQXhLVHRjYmlBZ0lDQWdJQ0FnZlZ4dUlDQWdJQ0FnZlZ4dUlDQWdJQ0FnYVdZZ0tHOTBhR1Z5VTNWaVEyOXRZbTh1YkdWdVozUm9JQ0U5UFNBd0tTQjdYRzRnSUNBZ0lDQWdJSEpsZEhWeWJpQm1ZV3h6WlR0Y2JpQWdJQ0FnSUgxY2JpQWdJQ0I5WEc1Y2JpQWdJQ0J5WlhSMWNtNGdkSEoxWlR0Y2JpQWdmVHRjYmx4dUlDQmZZMmhsWTJ0VGRXSkRiMjFpYnloemRXSkRiMjFpYnl3Z2MzUmhjblJwYm1kTFpYbE9ZVzFsU1c1a1pYZ3NJSEJ5WlhOelpXUkxaWGxPWVcxbGN5a2dlMXh1SUNBZ0lITjFZa052YldKdklEMGdjM1ZpUTI5dFltOHVjMnhwWTJVb01DazdYRzRnSUNBZ2NISmxjM05sWkV0bGVVNWhiV1Z6SUQwZ2NISmxjM05sWkV0bGVVNWhiV1Z6TG5Oc2FXTmxLSE4wWVhKMGFXNW5TMlY1VG1GdFpVbHVaR1Y0S1R0Y2JseHVJQ0FnSUd4bGRDQmxibVJKYm1SbGVDQTlJSE4wWVhKMGFXNW5TMlY1VG1GdFpVbHVaR1Y0TzF4dUlDQWdJR1p2Y2lBb2JHVjBJR2tnUFNBd095QnBJRHdnYzNWaVEyOXRZbTh1YkdWdVozUm9PeUJwSUNzOUlERXBJSHRjYmx4dUlDQWdJQ0FnYkdWMElHdGxlVTVoYldVZ1BTQnpkV0pEYjIxaWIxdHBYVHRjYmlBZ0lDQWdJR2xtSUNoclpYbE9ZVzFsV3pCZElEMDlQU0FuWEZ4Y1hDY3BJSHRjYmlBZ0lDQWdJQ0FnWTI5dWMzUWdaWE5qWVhCbFpFdGxlVTVoYldVZ1BTQnJaWGxPWVcxbExuTnNhV05sS0RFcE8xeHVJQ0FnSUNBZ0lDQnBaaUFvWEc0Z0lDQWdJQ0FnSUNBZ1pYTmpZWEJsWkV0bGVVNWhiV1VnUFQwOUlFdGxlVU52YldKdkxtTnZiV0p2UkdWc2FXMXBibUYwYjNJZ2ZIeGNiaUFnSUNBZ0lDQWdJQ0JsYzJOaGNHVmtTMlY1VG1GdFpTQTlQVDBnUzJWNVEyOXRZbTh1YTJWNVJHVnNhVzFwYm1GMGIzSmNiaUFnSUNBZ0lDQWdLU0I3WEc0Z0lDQWdJQ0FnSUNBZ2EyVjVUbUZ0WlNBOUlHVnpZMkZ3WldSTFpYbE9ZVzFsTzF4dUlDQWdJQ0FnSUNCOVhHNGdJQ0FnSUNCOVhHNWNiaUFnSUNBZ0lHTnZibk4wSUdsdVpHVjRJRDBnY0hKbGMzTmxaRXRsZVU1aGJXVnpMbWx1WkdWNFQyWW9hMlY1VG1GdFpTazdYRzRnSUNBZ0lDQnBaaUFvYVc1a1pYZ2dQaUF0TVNrZ2UxeHVJQ0FnSUNBZ0lDQnpkV0pEYjIxaWJ5NXpjR3hwWTJVb2FTd2dNU2s3WEc0Z0lDQWdJQ0FnSUdrZ0xUMGdNVHRjYmlBZ0lDQWdJQ0FnYVdZZ0tHbHVaR1Y0SUQ0Z1pXNWtTVzVrWlhncElIdGNiaUFnSUNBZ0lDQWdJQ0JsYm1SSmJtUmxlQ0E5SUdsdVpHVjRPMXh1SUNBZ0lDQWdJQ0I5WEc0Z0lDQWdJQ0FnSUdsbUlDaHpkV0pEYjIxaWJ5NXNaVzVuZEdnZ1BUMDlJREFwSUh0Y2JpQWdJQ0FnSUNBZ0lDQnlaWFIxY200Z1pXNWtTVzVrWlhnN1hHNGdJQ0FnSUNBZ0lIMWNiaUFnSUNBZ0lIMWNiaUFnSUNCOVhHNGdJQ0FnY21WMGRYSnVJQzB4TzF4dUlDQjlPMXh1ZlZ4dVhHNUxaWGxEYjIxaWJ5NWpiMjFpYjBSbGJHbHRhVzVoZEc5eUlEMGdKejRuTzF4dVMyVjVRMjl0WW04dWEyVjVSR1ZzYVcxcGJtRjBiM0lnSUNBOUlDY3JKenRjYmx4dVMyVjVRMjl0WW04dWNHRnljMlZEYjIxaWIxTjBjaUE5SUdaMWJtTjBhVzl1S0d0bGVVTnZiV0p2VTNSeUtTQjdYRzRnSUdOdmJuTjBJSE4xWWtOdmJXSnZVM1J5Y3lBOUlFdGxlVU52YldKdkxsOXpjR3hwZEZOMGNpaHJaWGxEYjIxaWIxTjBjaXdnUzJWNVEyOXRZbTh1WTI5dFltOUVaV3hwYldsdVlYUnZjaWs3WEc0Z0lHTnZibk4wSUdOdmJXSnZJQ0FnSUNBZ0lDQTlJRnRkTzF4dVhHNGdJR1p2Y2lBb2JHVjBJR2tnUFNBd0lEc2dhU0E4SUhOMVlrTnZiV0p2VTNSeWN5NXNaVzVuZEdnN0lHa2dLejBnTVNrZ2UxeHVJQ0FnSUdOdmJXSnZMbkIxYzJnb1MyVjVRMjl0WW04dVgzTndiR2wwVTNSeUtITjFZa052YldKdlUzUnljMXRwWFN3Z1MyVjVRMjl0WW04dWEyVjVSR1ZzYVcxcGJtRjBiM0lwS1R0Y2JpQWdmVnh1SUNCeVpYUjFjbTRnWTI5dFltODdYRzU5WEc1Y2JrdGxlVU52YldKdkxsOXpjR3hwZEZOMGNpQTlJR1oxYm1OMGFXOXVLSE4wY2l3Z1pHVnNhVzFwYm1GMGIzSXBJSHRjYmlBZ1kyOXVjM1FnY3lBZ1BTQnpkSEk3WEc0Z0lHTnZibk4wSUdRZ0lEMGdaR1ZzYVcxcGJtRjBiM0k3WEc0Z0lHeGxkQ0JqSUNBOUlDY25PMXh1SUNCamIyNXpkQ0JqWVNBOUlGdGRPMXh1WEc0Z0lHWnZjaUFvYkdWMElHTnBJRDBnTURzZ1kya2dQQ0J6TG14bGJtZDBhRHNnWTJrZ0t6MGdNU2tnZTF4dUlDQWdJR2xtSUNoamFTQStJREFnSmlZZ2MxdGphVjBnUFQwOUlHUWdKaVlnYzF0amFTQXRJREZkSUNFOVBTQW5YRnhjWENjcElIdGNiaUFnSUNBZ0lHTmhMbkIxYzJnb1l5NTBjbWx0S0NrcE8xeHVJQ0FnSUNBZ1l5QTlJQ2NuTzF4dUlDQWdJQ0FnWTJrZ0t6MGdNVHRjYmlBZ0lDQjlYRzRnSUNBZ1l5QXJQU0J6VzJOcFhUdGNiaUFnZlZ4dUlDQnBaaUFvWXlrZ2V5QmpZUzV3ZFhOb0tHTXVkSEpwYlNncEtUc2dmVnh1WEc0Z0lISmxkSFZ5YmlCallUdGNibjA3WEc0aUxDSnBiWEJ2Y25RZ2V5QkxaWGxEYjIxaWJ5QjlJR1p5YjIwZ0p5NHZhMlY1TFdOdmJXSnZKenRjYmx4dVhHNWxlSEJ2Y25RZ1kyeGhjM01nVEc5allXeGxJSHRjYmlBZ1kyOXVjM1J5ZFdOMGIzSW9ibUZ0WlNrZ2UxeHVJQ0FnSUhSb2FYTXViRzlqWVd4bFRtRnRaU0FnSUNBZ0lDQWdJQ0E5SUc1aGJXVTdYRzRnSUNBZ2RHaHBjeTVoWTNScGRtVlVZWEpuWlhSTFpYbHpJRDBnVzEwN1hHNGdJQ0FnZEdocGN5NXdjbVZ6YzJWa1MyVjVjeUFnSUNBZ0lDQWdJRDBnVzEwN1hHNGdJQ0FnZEdocGN5NWZZWEJ3YkdsbFpFMWhZM0p2Y3lBZ0lDQWdJRDBnVzEwN1hHNGdJQ0FnZEdocGN5NWZhMlY1VFdGd0lDQWdJQ0FnSUNBZ0lDQWdJRDBnZTMwN1hHNGdJQ0FnZEdocGN5NWZhMmxzYkV0bGVVTnZaR1Z6SUNBZ0lDQWdJRDBnVzEwN1hHNGdJQ0FnZEdocGN5NWZiV0ZqY205eklDQWdJQ0FnSUNBZ0lDQWdJRDBnVzEwN1hHNGdJSDFjYmx4dUlDQmlhVzVrUzJWNVEyOWtaU2hyWlhsRGIyUmxMQ0JyWlhsT1lXMWxjeWtnZTF4dUlDQWdJR2xtSUNoMGVYQmxiMllnYTJWNVRtRnRaWE1nUFQwOUlDZHpkSEpwYm1jbktTQjdYRzRnSUNBZ0lDQnJaWGxPWVcxbGN5QTlJRnRyWlhsT1lXMWxjMTA3WEc0Z0lDQWdmVnh1WEc0Z0lDQWdkR2hwY3k1ZmEyVjVUV0Z3VzJ0bGVVTnZaR1ZkSUQwZ2EyVjVUbUZ0WlhNN1hHNGdJSDA3WEc1Y2JpQWdZbWx1WkUxaFkzSnZLR3RsZVVOdmJXSnZVM1J5TENCclpYbE9ZVzFsY3lrZ2UxeHVJQ0FnSUdsbUlDaDBlWEJsYjJZZ2EyVjVUbUZ0WlhNZ1BUMDlJQ2R6ZEhKcGJtY25LU0I3WEc0Z0lDQWdJQ0JyWlhsT1lXMWxjeUE5SUZzZ2EyVjVUbUZ0WlhNZ1hUdGNiaUFnSUNCOVhHNWNiaUFnSUNCc1pYUWdhR0Z1Wkd4bGNpQTlJRzUxYkd3N1hHNGdJQ0FnYVdZZ0tIUjVjR1Z2WmlCclpYbE9ZVzFsY3lBOVBUMGdKMloxYm1OMGFXOXVKeWtnZTF4dUlDQWdJQ0FnYUdGdVpHeGxjaUE5SUd0bGVVNWhiV1Z6TzF4dUlDQWdJQ0FnYTJWNVRtRnRaWE1nUFNCdWRXeHNPMXh1SUNBZ0lIMWNibHh1SUNBZ0lHTnZibk4wSUcxaFkzSnZJRDBnZTF4dUlDQWdJQ0FnYTJWNVEyOXRZbThnT2lCdVpYY2dTMlY1UTI5dFltOG9hMlY1UTI5dFltOVRkSElwTEZ4dUlDQWdJQ0FnYTJWNVRtRnRaWE1nT2lCclpYbE9ZVzFsY3l4Y2JpQWdJQ0FnSUdoaGJtUnNaWElnSURvZ2FHRnVaR3hsY2x4dUlDQWdJSDA3WEc1Y2JpQWdJQ0IwYUdsekxsOXRZV055YjNNdWNIVnphQ2h0WVdOeWJ5azdYRzRnSUgwN1hHNWNiaUFnWjJWMFMyVjVRMjlrWlhNb2EyVjVUbUZ0WlNrZ2UxeHVJQ0FnSUdOdmJuTjBJR3RsZVVOdlpHVnpJRDBnVzEwN1hHNGdJQ0FnWm05eUlDaGpiMjV6ZENCclpYbERiMlJsSUdsdUlIUm9hWE11WDJ0bGVVMWhjQ2tnZTF4dUlDQWdJQ0FnWTI5dWMzUWdhVzVrWlhnZ1BTQjBhR2x6TGw5clpYbE5ZWEJiYTJWNVEyOWtaVjB1YVc1a1pYaFBaaWhyWlhsT1lXMWxLVHRjYmlBZ0lDQWdJR2xtSUNocGJtUmxlQ0ErSUMweEtTQjdJR3RsZVVOdlpHVnpMbkIxYzJnb2EyVjVRMjlrWlh3d0tUc2dmVnh1SUNBZ0lIMWNiaUFnSUNCeVpYUjFjbTRnYTJWNVEyOWtaWE03WEc0Z0lIMDdYRzVjYmlBZ1oyVjBTMlY1VG1GdFpYTW9hMlY1UTI5a1pTa2dlMXh1SUNBZ0lISmxkSFZ5YmlCMGFHbHpMbDlyWlhsTllYQmJhMlY1UTI5a1pWMGdmSHdnVzEwN1hHNGdJSDA3WEc1Y2JpQWdjMlYwUzJsc2JFdGxlU2hyWlhsRGIyUmxLU0I3WEc0Z0lDQWdhV1lnS0hSNWNHVnZaaUJyWlhsRGIyUmxJRDA5UFNBbmMzUnlhVzVuSnlrZ2UxeHVJQ0FnSUNBZ1kyOXVjM1FnYTJWNVEyOWtaWE1nUFNCMGFHbHpMbWRsZEV0bGVVTnZaR1Z6S0d0bGVVTnZaR1VwTzF4dUlDQWdJQ0FnWm05eUlDaHNaWFFnYVNBOUlEQTdJR2tnUENCclpYbERiMlJsY3k1c1pXNW5kR2c3SUdrZ0t6MGdNU2tnZTF4dUlDQWdJQ0FnSUNCMGFHbHpMbk5sZEV0cGJHeExaWGtvYTJWNVEyOWtaWE5iYVYwcE8xeHVJQ0FnSUNBZ2ZWeHVJQ0FnSUNBZ2NtVjBkWEp1TzF4dUlDQWdJSDFjYmx4dUlDQWdJSFJvYVhNdVgydHBiR3hMWlhsRGIyUmxjeTV3ZFhOb0tHdGxlVU52WkdVcE8xeHVJQ0I5TzF4dVhHNGdJSEJ5WlhOelMyVjVLR3RsZVVOdlpHVXBJSHRjYmlBZ0lDQnBaaUFvZEhsd1pXOW1JR3RsZVVOdlpHVWdQVDA5SUNkemRISnBibWNuS1NCN1hHNGdJQ0FnSUNCamIyNXpkQ0JyWlhsRGIyUmxjeUE5SUhSb2FYTXVaMlYwUzJWNVEyOWtaWE1vYTJWNVEyOWtaU2s3WEc0Z0lDQWdJQ0JtYjNJZ0tHeGxkQ0JwSUQwZ01Ec2dhU0E4SUd0bGVVTnZaR1Z6TG14bGJtZDBhRHNnYVNBclBTQXhLU0I3WEc0Z0lDQWdJQ0FnSUhSb2FYTXVjSEpsYzNOTFpYa29hMlY1UTI5a1pYTmJhVjBwTzF4dUlDQWdJQ0FnZlZ4dUlDQWdJQ0FnY21WMGRYSnVPMXh1SUNBZ0lIMWNibHh1SUNBZ0lIUm9hWE11WVdOMGFYWmxWR0Z5WjJWMFMyVjVjeTVzWlc1bmRHZ2dQU0F3TzF4dUlDQWdJR052Ym5OMElHdGxlVTVoYldWeklEMGdkR2hwY3k1blpYUkxaWGxPWVcxbGN5aHJaWGxEYjJSbEtUdGNiaUFnSUNCbWIzSWdLR3hsZENCcElEMGdNRHNnYVNBOElHdGxlVTVoYldWekxteGxibWQwYURzZ2FTQXJQU0F4S1NCN1hHNGdJQ0FnSUNCMGFHbHpMbUZqZEdsMlpWUmhjbWRsZEV0bGVYTXVjSFZ6YUNoclpYbE9ZVzFsYzF0cFhTazdYRzRnSUNBZ0lDQnBaaUFvZEdocGN5NXdjbVZ6YzJWa1MyVjVjeTVwYm1SbGVFOW1LR3RsZVU1aGJXVnpXMmxkS1NBOVBUMGdMVEVwSUh0Y2JpQWdJQ0FnSUNBZ2RHaHBjeTV3Y21WemMyVmtTMlY1Y3k1d2RYTm9LR3RsZVU1aGJXVnpXMmxkS1R0Y2JpQWdJQ0FnSUgxY2JpQWdJQ0I5WEc1Y2JpQWdJQ0IwYUdsekxsOWhjSEJzZVUxaFkzSnZjeWdwTzF4dUlDQjlPMXh1WEc0Z0lISmxiR1ZoYzJWTFpYa29hMlY1UTI5a1pTa2dlMXh1SUNBZ0lHbG1JQ2gwZVhCbGIyWWdhMlY1UTI5a1pTQTlQVDBnSjNOMGNtbHVaeWNwSUh0Y2JpQWdJQ0FnSUdOdmJuTjBJR3RsZVVOdlpHVnpJRDBnZEdocGN5NW5aWFJMWlhsRGIyUmxjeWhyWlhsRGIyUmxLVHRjYmlBZ0lDQWdJR1p2Y2lBb2JHVjBJR2tnUFNBd095QnBJRHdnYTJWNVEyOWtaWE11YkdWdVozUm9PeUJwSUNzOUlERXBJSHRjYmlBZ0lDQWdJQ0FnZEdocGN5NXlaV3hsWVhObFMyVjVLR3RsZVVOdlpHVnpXMmxkS1R0Y2JpQWdJQ0FnSUgxY2JseHVJQ0FnSUgwZ1pXeHpaU0I3WEc0Z0lDQWdJQ0JqYjI1emRDQnJaWGxPWVcxbGN5QWdJQ0FnSUNBZ0lEMGdkR2hwY3k1blpYUkxaWGxPWVcxbGN5aHJaWGxEYjJSbEtUdGNiaUFnSUNBZ0lHTnZibk4wSUd0cGJHeExaWGxEYjJSbFNXNWtaWGdnUFNCMGFHbHpMbDlyYVd4c1MyVjVRMjlrWlhNdWFXNWtaWGhQWmloclpYbERiMlJsS1R0Y2JseHVJQ0FnSUNBZ2FXWWdLR3RwYkd4TFpYbERiMlJsU1c1a1pYZ2dJVDA5SUMweEtTQjdYRzRnSUNBZ0lDQWdJSFJvYVhNdWNISmxjM05sWkV0bGVYTXViR1Z1WjNSb0lEMGdNRHRjYmlBZ0lDQWdJSDBnWld4elpTQjdYRzRnSUNBZ0lDQWdJR1p2Y2lBb2JHVjBJR2tnUFNBd095QnBJRHdnYTJWNVRtRnRaWE11YkdWdVozUm9PeUJwSUNzOUlERXBJSHRjYmlBZ0lDQWdJQ0FnSUNCamIyNXpkQ0JwYm1SbGVDQTlJSFJvYVhNdWNISmxjM05sWkV0bGVYTXVhVzVrWlhoUFppaHJaWGxPWVcxbGMxdHBYU2s3WEc0Z0lDQWdJQ0FnSUNBZ2FXWWdLR2x1WkdWNElENGdMVEVwSUh0Y2JpQWdJQ0FnSUNBZ0lDQWdJSFJvYVhNdWNISmxjM05sWkV0bGVYTXVjM0JzYVdObEtHbHVaR1Y0TENBeEtUdGNiaUFnSUNBZ0lDQWdJQ0I5WEc0Z0lDQWdJQ0FnSUgxY2JpQWdJQ0FnSUgxY2JseHVJQ0FnSUNBZ2RHaHBjeTVoWTNScGRtVlVZWEpuWlhSTFpYbHpMbXhsYm1kMGFDQTlJREE3WEc0Z0lDQWdJQ0IwYUdsekxsOWpiR1ZoY2sxaFkzSnZjeWdwTzF4dUlDQWdJSDFjYmlBZ2ZUdGNibHh1SUNCZllYQndiSGxOWVdOeWIzTW9LU0I3WEc0Z0lDQWdZMjl1YzNRZ2JXRmpjbTl6SUQwZ2RHaHBjeTVmYldGamNtOXpMbk5zYVdObEtEQXBPMXh1SUNBZ0lHWnZjaUFvYkdWMElHa2dQU0F3T3lCcElEd2diV0ZqY205ekxteGxibWQwYURzZ2FTQXJQU0F4S1NCN1hHNGdJQ0FnSUNCamIyNXpkQ0J0WVdOeWJ5QTlJRzFoWTNKdmMxdHBYVHRjYmlBZ0lDQWdJR2xtSUNodFlXTnlieTVyWlhsRGIyMWlieTVqYUdWamF5aDBhR2x6TG5CeVpYTnpaV1JMWlhsektTa2dlMXh1SUNBZ0lDQWdJQ0JwWmlBb2JXRmpjbTh1YUdGdVpHeGxjaWtnZTF4dUlDQWdJQ0FnSUNBZ0lHMWhZM0p2TG10bGVVNWhiV1Z6SUQwZ2JXRmpjbTh1YUdGdVpHeGxjaWgwYUdsekxuQnlaWE56WldSTFpYbHpLVHRjYmlBZ0lDQWdJQ0FnZlZ4dUlDQWdJQ0FnSUNCbWIzSWdLR3hsZENCcUlEMGdNRHNnYWlBOElHMWhZM0p2TG10bGVVNWhiV1Z6TG14bGJtZDBhRHNnYWlBclBTQXhLU0I3WEc0Z0lDQWdJQ0FnSUNBZ2FXWWdLSFJvYVhNdWNISmxjM05sWkV0bGVYTXVhVzVrWlhoUFppaHRZV055Ynk1clpYbE9ZVzFsYzF0cVhTa2dQVDA5SUMweEtTQjdYRzRnSUNBZ0lDQWdJQ0FnSUNCMGFHbHpMbkJ5WlhOelpXUkxaWGx6TG5CMWMyZ29iV0ZqY204dWEyVjVUbUZ0WlhOYmFsMHBPMXh1SUNBZ0lDQWdJQ0FnSUgxY2JpQWdJQ0FnSUNBZ2ZWeHVJQ0FnSUNBZ0lDQjBhR2x6TGw5aGNIQnNhV1ZrVFdGamNtOXpMbkIxYzJnb2JXRmpjbThwTzF4dUlDQWdJQ0FnZlZ4dUlDQWdJSDFjYmlBZ2ZUdGNibHh1SUNCZlkyeGxZWEpOWVdOeWIzTW9LU0I3WEc0Z0lDQWdabTl5SUNoc1pYUWdhU0E5SURBN0lHa2dQQ0IwYUdsekxsOWhjSEJzYVdWa1RXRmpjbTl6TG14bGJtZDBhRHNnYVNBclBTQXhLU0I3WEc0Z0lDQWdJQ0JqYjI1emRDQnRZV055YnlBOUlIUm9hWE11WDJGd2NHeHBaV1JOWVdOeWIzTmJhVjA3WEc0Z0lDQWdJQ0JwWmlBb0lXMWhZM0p2TG10bGVVTnZiV0p2TG1Ob1pXTnJLSFJvYVhNdWNISmxjM05sWkV0bGVYTXBLU0I3WEc0Z0lDQWdJQ0FnSUdadmNpQW9iR1YwSUdvZ1BTQXdPeUJxSUR3Z2JXRmpjbTh1YTJWNVRtRnRaWE11YkdWdVozUm9PeUJxSUNzOUlERXBJSHRjYmlBZ0lDQWdJQ0FnSUNCamIyNXpkQ0JwYm1SbGVDQTlJSFJvYVhNdWNISmxjM05sWkV0bGVYTXVhVzVrWlhoUFppaHRZV055Ynk1clpYbE9ZVzFsYzF0cVhTazdYRzRnSUNBZ0lDQWdJQ0FnYVdZZ0tHbHVaR1Y0SUQ0Z0xURXBJSHRjYmlBZ0lDQWdJQ0FnSUNBZ0lIUm9hWE11Y0hKbGMzTmxaRXRsZVhNdWMzQnNhV05sS0dsdVpHVjRMQ0F4S1R0Y2JpQWdJQ0FnSUNBZ0lDQjlYRzRnSUNBZ0lDQWdJSDFjYmlBZ0lDQWdJQ0FnYVdZZ0tHMWhZM0p2TG1oaGJtUnNaWElwSUh0Y2JpQWdJQ0FnSUNBZ0lDQnRZV055Ynk1clpYbE9ZVzFsY3lBOUlHNTFiR3c3WEc0Z0lDQWdJQ0FnSUgxY2JpQWdJQ0FnSUNBZ2RHaHBjeTVmWVhCd2JHbGxaRTFoWTNKdmN5NXpjR3hwWTJVb2FTd2dNU2s3WEc0Z0lDQWdJQ0FnSUdrZ0xUMGdNVHRjYmlBZ0lDQWdJSDFjYmlBZ0lDQjlYRzRnSUgxY2JuMWNiaUlzSW1sdGNHOXlkQ0I3SUV4dlkyRnNaU0I5SUdaeWIyMGdKeTR2Ykc5allXeGxKenRjYm1sdGNHOXlkQ0I3SUV0bGVVTnZiV0p2SUgwZ1puSnZiU0FuTGk5clpYa3RZMjl0WW04bk8xeHVYRzVjYm1WNGNHOXlkQ0JqYkdGemN5QkxaWGxpYjJGeVpDQjdYRzRnSUdOdmJuTjBjblZqZEc5eUtIUmhjbWRsZEZkcGJtUnZkeXdnZEdGeVoyVjBSV3hsYldWdWRDd2dkR0Z5WjJWMFVHeGhkR1p2Y20wc0lIUmhjbWRsZEZWelpYSkJaMlZ1ZENrZ2UxeHVJQ0FnSUhSb2FYTXVYMnh2WTJGc1pTQWdJQ0FnSUNBZ0lDQWdJQ0FnSUQwZ2JuVnNiRHRjYmlBZ0lDQjBhR2x6TGw5amRYSnlaVzUwUTI5dWRHVjRkQ0FnSUNBZ0lDQTlJQ2NuTzF4dUlDQWdJSFJvYVhNdVgyTnZiblJsZUhSeklDQWdJQ0FnSUNBZ0lDQWdJRDBnZTMwN1hHNGdJQ0FnZEdocGN5NWZiR2x6ZEdWdVpYSnpJQ0FnSUNBZ0lDQWdJQ0FnUFNCYlhUdGNiaUFnSUNCMGFHbHpMbDloY0hCc2FXVmtUR2x6ZEdWdVpYSnpJQ0FnSUNBOUlGdGRPMXh1SUNBZ0lIUm9hWE11WDJ4dlkyRnNaWE1nSUNBZ0lDQWdJQ0FnSUNBZ0lEMGdlMzA3WEc0Z0lDQWdkR2hwY3k1ZmRHRnlaMlYwUld4bGJXVnVkQ0FnSUNBZ0lDQWdQU0J1ZFd4c08xeHVJQ0FnSUhSb2FYTXVYM1JoY21kbGRGZHBibVJ2ZHlBZ0lDQWdJQ0FnSUQwZ2JuVnNiRHRjYmlBZ0lDQjBhR2x6TGw5MFlYSm5aWFJRYkdGMFptOXliU0FnSUNBZ0lDQTlJQ2NuTzF4dUlDQWdJSFJvYVhNdVgzUmhjbWRsZEZWelpYSkJaMlZ1ZENBZ0lDQWdJRDBnSnljN1hHNGdJQ0FnZEdocGN5NWZhWE5OYjJSbGNtNUNjbTkzYzJWeUlDQWdJQ0FnUFNCbVlXeHpaVHRjYmlBZ0lDQjBhR2x6TGw5MFlYSm5aWFJMWlhsRWIzZHVRbWx1WkdsdVp5QTlJRzUxYkd3N1hHNGdJQ0FnZEdocGN5NWZkR0Z5WjJWMFMyVjVWWEJDYVc1a2FXNW5JQ0FnUFNCdWRXeHNPMXh1SUNBZ0lIUm9hWE11WDNSaGNtZGxkRkpsYzJWMFFtbHVaR2x1WnlBZ0lEMGdiblZzYkR0Y2JpQWdJQ0IwYUdsekxsOXdZWFZ6WldRZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0E5SUdaaGJITmxPMXh1WEc0Z0lDQWdkR2hwY3k1ZlkyOXVkR1Y0ZEhNdVoyeHZZbUZzSUQwZ2UxeHVJQ0FnSUNBZ2JHbHpkR1Z1WlhKek9pQjBhR2x6TGw5c2FYTjBaVzVsY25Nc1hHNGdJQ0FnSUNCMFlYSm5aWFJYYVc1a2IzY3NYRzRnSUNBZ0lDQjBZWEpuWlhSRmJHVnRaVzUwTEZ4dUlDQWdJQ0FnZEdGeVoyVjBVR3hoZEdadmNtMHNYRzRnSUNBZ0lDQjBZWEpuWlhSVmMyVnlRV2RsYm5SY2JpQWdJQ0I5TzF4dVhHNGdJQ0FnZEdocGN5NXpaWFJEYjI1MFpYaDBLQ2RuYkc5aVlXd25LVHRjYmlBZ2ZWeHVYRzRnSUhObGRFeHZZMkZzWlNoc2IyTmhiR1ZPWVcxbExDQnNiMk5oYkdWQ2RXbHNaR1Z5S1NCN1hHNGdJQ0FnYkdWMElHeHZZMkZzWlNBOUlHNTFiR3c3WEc0Z0lDQWdhV1lnS0hSNWNHVnZaaUJzYjJOaGJHVk9ZVzFsSUQwOVBTQW5jM1J5YVc1bkp5a2dlMXh1WEc0Z0lDQWdJQ0JwWmlBb2JHOWpZV3hsUW5WcGJHUmxjaWtnZTF4dUlDQWdJQ0FnSUNCc2IyTmhiR1VnUFNCdVpYY2dURzlqWVd4bEtHeHZZMkZzWlU1aGJXVXBPMXh1SUNBZ0lDQWdJQ0JzYjJOaGJHVkNkV2xzWkdWeUtHeHZZMkZzWlN3Z2RHaHBjeTVmZEdGeVoyVjBVR3hoZEdadmNtMHNJSFJvYVhNdVgzUmhjbWRsZEZWelpYSkJaMlZ1ZENrN1hHNGdJQ0FnSUNCOUlHVnNjMlVnZTF4dUlDQWdJQ0FnSUNCc2IyTmhiR1VnUFNCMGFHbHpMbDlzYjJOaGJHVnpXMnh2WTJGc1pVNWhiV1ZkSUh4OElHNTFiR3c3WEc0Z0lDQWdJQ0I5WEc0Z0lDQWdmU0JsYkhObElIdGNiaUFnSUNBZ0lHeHZZMkZzWlNBZ0lDQWdQU0JzYjJOaGJHVk9ZVzFsTzF4dUlDQWdJQ0FnYkc5allXeGxUbUZ0WlNBOUlHeHZZMkZzWlM1ZmJHOWpZV3hsVG1GdFpUdGNiaUFnSUNCOVhHNWNiaUFnSUNCMGFHbHpMbDlzYjJOaGJHVWdJQ0FnSUNBZ0lDQWdJQ0FnSUQwZ2JHOWpZV3hsTzF4dUlDQWdJSFJvYVhNdVgyeHZZMkZzWlhOYmJHOWpZV3hsVG1GdFpWMGdQU0JzYjJOaGJHVTdYRzRnSUNBZ2FXWWdLR3h2WTJGc1pTa2dlMXh1SUNBZ0lDQWdkR2hwY3k1ZmJHOWpZV3hsTG5CeVpYTnpaV1JMWlhseklEMGdiRzlqWVd4bExuQnlaWE56WldSTFpYbHpPMXh1SUNBZ0lIMWNibHh1SUNBZ0lISmxkSFZ5YmlCMGFHbHpPMXh1SUNCOVhHNWNiaUFnWjJWMFRHOWpZV3hsS0d4dlkyRnNUbUZ0WlNrZ2UxeHVJQ0FnSUd4dlkyRnNUbUZ0WlNCOGZDQW9iRzlqWVd4T1lXMWxJRDBnZEdocGN5NWZiRzlqWVd4bExteHZZMkZzWlU1aGJXVXBPMXh1SUNBZ0lISmxkSFZ5YmlCMGFHbHpMbDlzYjJOaGJHVnpXMnh2WTJGc1RtRnRaVjBnZkh3Z2JuVnNiRHRjYmlBZ2ZWeHVYRzRnSUdKcGJtUW9hMlY1UTI5dFltOVRkSElzSUhCeVpYTnpTR0Z1Wkd4bGNpd2djbVZzWldGelpVaGhibVJzWlhJc0lIQnlaWFpsYm5SU1pYQmxZWFJDZVVSbFptRjFiSFFwSUh0Y2JpQWdJQ0JwWmlBb2EyVjVRMjl0WW05VGRISWdQVDA5SUc1MWJHd2dmSHdnZEhsd1pXOW1JR3RsZVVOdmJXSnZVM1J5SUQwOVBTQW5ablZ1WTNScGIyNG5LU0I3WEc0Z0lDQWdJQ0J3Y21WMlpXNTBVbVZ3WldGMFFubEVaV1poZFd4MElEMGdjbVZzWldGelpVaGhibVJzWlhJN1hHNGdJQ0FnSUNCeVpXeGxZWE5sU0dGdVpHeGxjaUFnSUNBZ0lDQWdJRDBnY0hKbGMzTklZVzVrYkdWeU8xeHVJQ0FnSUNBZ2NISmxjM05JWVc1a2JHVnlJQ0FnSUNBZ0lDQWdJQ0E5SUd0bGVVTnZiV0p2VTNSeU8xeHVJQ0FnSUNBZ2EyVjVRMjl0WW05VGRISWdJQ0FnSUNBZ0lDQWdJQ0E5SUc1MWJHdzdYRzRnSUNBZ2ZWeHVYRzRnSUNBZ2FXWWdLRnh1SUNBZ0lDQWdhMlY1UTI5dFltOVRkSElnSmlaY2JpQWdJQ0FnSUhSNWNHVnZaaUJyWlhsRGIyMWliMU4wY2lBOVBUMGdKMjlpYW1WamRDY2dKaVpjYmlBZ0lDQWdJSFI1Y0dWdlppQnJaWGxEYjIxaWIxTjBjaTVzWlc1bmRHZ2dQVDA5SUNkdWRXMWlaWEluWEc0Z0lDQWdLU0I3WEc0Z0lDQWdJQ0JtYjNJZ0tHeGxkQ0JwSUQwZ01Ec2dhU0E4SUd0bGVVTnZiV0p2VTNSeUxteGxibWQwYURzZ2FTQXJQU0F4S1NCN1hHNGdJQ0FnSUNBZ0lIUm9hWE11WW1sdVpDaHJaWGxEYjIxaWIxTjBjbHRwWFN3Z2NISmxjM05JWVc1a2JHVnlMQ0J5Wld4bFlYTmxTR0Z1Wkd4bGNpazdYRzRnSUNBZ0lDQjlYRzRnSUNBZ0lDQnlaWFIxY200Z2RHaHBjenRjYmlBZ0lDQjlYRzVjYmlBZ0lDQjBhR2x6TGw5c2FYTjBaVzVsY25NdWNIVnphQ2g3WEc0Z0lDQWdJQ0JyWlhsRGIyMWlieUFnSUNBZ0lDQWdJQ0FnSUNBZ09pQnJaWGxEYjIxaWIxTjBjaUEvSUc1bGR5QkxaWGxEYjIxaWJ5aHJaWGxEYjIxaWIxTjBjaWtnT2lCdWRXeHNMRnh1SUNBZ0lDQWdjSEpsYzNOSVlXNWtiR1Z5SUNBZ0lDQWdJQ0FnSURvZ2NISmxjM05JWVc1a2JHVnlJQ0FnSUNBZ0lDQWdJQ0I4ZkNCdWRXeHNMRnh1SUNBZ0lDQWdjbVZzWldGelpVaGhibVJzWlhJZ0lDQWdJQ0FnSURvZ2NtVnNaV0Z6WlVoaGJtUnNaWElnSUNBZ0lDQWdJQ0I4ZkNCdWRXeHNMRnh1SUNBZ0lDQWdjSEpsZG1WdWRGSmxjR1ZoZENBZ0lDQWdJQ0FnSURvZ1ptRnNjMlVzWEc0Z0lDQWdJQ0J3Y21WMlpXNTBVbVZ3WldGMFFubEVaV1poZFd4ME9pQndjbVYyWlc1MFVtVndaV0YwUW5sRVpXWmhkV3gwSUh4OElHWmhiSE5sTEZ4dUlDQWdJQ0FnWlhobFkzVjBhVzVuU0dGdVpHeGxjaUFnSUNBZ0lEb2dabUZzYzJWY2JpQWdJQ0I5S1R0Y2JseHVJQ0FnSUhKbGRIVnliaUIwYUdsek8xeHVJQ0I5WEc1Y2JpQWdZV1JrVEdsemRHVnVaWElvYTJWNVEyOXRZbTlUZEhJc0lIQnlaWE56U0dGdVpHeGxjaXdnY21Wc1pXRnpaVWhoYm1Sc1pYSXNJSEJ5WlhabGJuUlNaWEJsWVhSQ2VVUmxabUYxYkhRcElIdGNiaUFnSUNCeVpYUjFjbTRnZEdocGN5NWlhVzVrS0d0bGVVTnZiV0p2VTNSeUxDQndjbVZ6YzBoaGJtUnNaWElzSUhKbGJHVmhjMlZJWVc1a2JHVnlMQ0J3Y21WMlpXNTBVbVZ3WldGMFFubEVaV1poZFd4MEtUdGNiaUFnZlZ4dVhHNGdJRzl1S0d0bGVVTnZiV0p2VTNSeUxDQndjbVZ6YzBoaGJtUnNaWElzSUhKbGJHVmhjMlZJWVc1a2JHVnlMQ0J3Y21WMlpXNTBVbVZ3WldGMFFubEVaV1poZFd4MEtTQjdYRzRnSUNBZ2NtVjBkWEp1SUhSb2FYTXVZbWx1WkNoclpYbERiMjFpYjFOMGNpd2djSEpsYzNOSVlXNWtiR1Z5TENCeVpXeGxZWE5sU0dGdVpHeGxjaXdnY0hKbGRtVnVkRkpsY0dWaGRFSjVSR1ZtWVhWc2RDazdYRzRnSUgxY2JseHVJQ0JpYVc1a1VISmxjM01vYTJWNVEyOXRZbTlUZEhJc0lIQnlaWE56U0dGdVpHeGxjaXdnY0hKbGRtVnVkRkpsY0dWaGRFSjVSR1ZtWVhWc2RDa2dlMXh1SUNBZ0lISmxkSFZ5YmlCMGFHbHpMbUpwYm1Rb2EyVjVRMjl0WW05VGRISXNJSEJ5WlhOelNHRnVaR3hsY2l3Z2JuVnNiQ3dnY0hKbGRtVnVkRkpsY0dWaGRFSjVSR1ZtWVhWc2RDazdYRzRnSUgxY2JseHVJQ0JpYVc1a1VtVnNaV0Z6WlNoclpYbERiMjFpYjFOMGNpd2djbVZzWldGelpVaGhibVJzWlhJcElIdGNiaUFnSUNCeVpYUjFjbTRnZEdocGN5NWlhVzVrS0d0bGVVTnZiV0p2VTNSeUxDQnVkV3hzTENCeVpXeGxZWE5sU0dGdVpHeGxjaXdnY0hKbGRtVnVkRkpsY0dWaGRFSjVSR1ZtWVhWc2RDazdYRzRnSUgxY2JseHVJQ0IxYm1KcGJtUW9hMlY1UTI5dFltOVRkSElzSUhCeVpYTnpTR0Z1Wkd4bGNpd2djbVZzWldGelpVaGhibVJzWlhJcElIdGNiaUFnSUNCcFppQW9hMlY1UTI5dFltOVRkSElnUFQwOUlHNTFiR3dnZkh3Z2RIbHdaVzltSUd0bGVVTnZiV0p2VTNSeUlEMDlQU0FuWm5WdVkzUnBiMjRuS1NCN1hHNGdJQ0FnSUNCeVpXeGxZWE5sU0dGdVpHeGxjaUE5SUhCeVpYTnpTR0Z1Wkd4bGNqdGNiaUFnSUNBZ0lIQnlaWE56U0dGdVpHeGxjaUFnSUQwZ2EyVjVRMjl0WW05VGRISTdYRzRnSUNBZ0lDQnJaWGxEYjIxaWIxTjBjaUE5SUc1MWJHdzdYRzRnSUNBZ2ZWeHVYRzRnSUNBZ2FXWWdLRnh1SUNBZ0lDQWdhMlY1UTI5dFltOVRkSElnSmlaY2JpQWdJQ0FnSUhSNWNHVnZaaUJyWlhsRGIyMWliMU4wY2lBOVBUMGdKMjlpYW1WamRDY2dKaVpjYmlBZ0lDQWdJSFI1Y0dWdlppQnJaWGxEYjIxaWIxTjBjaTVzWlc1bmRHZ2dQVDA5SUNkdWRXMWlaWEluWEc0Z0lDQWdLU0I3WEc0Z0lDQWdJQ0JtYjNJZ0tHeGxkQ0JwSUQwZ01Ec2dhU0E4SUd0bGVVTnZiV0p2VTNSeUxteGxibWQwYURzZ2FTQXJQU0F4S1NCN1hHNGdJQ0FnSUNBZ0lIUm9hWE11ZFc1aWFXNWtLR3RsZVVOdmJXSnZVM1J5VzJsZExDQndjbVZ6YzBoaGJtUnNaWElzSUhKbGJHVmhjMlZJWVc1a2JHVnlLVHRjYmlBZ0lDQWdJSDFjYmlBZ0lDQWdJSEpsZEhWeWJpQjBhR2x6TzF4dUlDQWdJSDFjYmx4dUlDQWdJR1p2Y2lBb2JHVjBJR2tnUFNBd095QnBJRHdnZEdocGN5NWZiR2x6ZEdWdVpYSnpMbXhsYm1kMGFEc2dhU0FyUFNBeEtTQjdYRzRnSUNBZ0lDQmpiMjV6ZENCc2FYTjBaVzVsY2lBOUlIUm9hWE11WDJ4cGMzUmxibVZ5YzF0cFhUdGNibHh1SUNBZ0lDQWdZMjl1YzNRZ1kyOXRZbTlOWVhSamFHVnpJQ0FnSUNBZ0lDQWdJRDBnSVd0bGVVTnZiV0p2VTNSeUlDWW1JQ0ZzYVhOMFpXNWxjaTVyWlhsRGIyMWlieUI4ZkZ4dUlDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUd4cGMzUmxibVZ5TG10bGVVTnZiV0p2SUNZbUlHeHBjM1JsYm1WeUxtdGxlVU52YldKdkxtbHpSWEYxWVd3b2EyVjVRMjl0WW05VGRISXBPMXh1SUNBZ0lDQWdZMjl1YzNRZ2NISmxjM05JWVc1a2JHVnlUV0YwWTJobGN5QWdJRDBnSVhCeVpYTnpTR0Z1Wkd4bGNpQW1KaUFoY21Wc1pXRnpaVWhoYm1Sc1pYSWdmSHhjYmlBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FoY0hKbGMzTklZVzVrYkdWeUlDWW1JQ0ZzYVhOMFpXNWxjaTV3Y21WemMwaGhibVJzWlhJZ2ZIeGNiaUFnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQndjbVZ6YzBoaGJtUnNaWElnUFQwOUlHeHBjM1JsYm1WeUxuQnlaWE56U0dGdVpHeGxjanRjYmlBZ0lDQWdJR052Ym5OMElISmxiR1ZoYzJWSVlXNWtiR1Z5VFdGMFkyaGxjeUE5SUNGd2NtVnpjMGhoYm1Sc1pYSWdKaVlnSVhKbGJHVmhjMlZJWVc1a2JHVnlJSHg4WEc0Z0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSVhKbGJHVmhjMlZJWVc1a2JHVnlJQ1ltSUNGc2FYTjBaVzVsY2k1eVpXeGxZWE5sU0dGdVpHeGxjaUI4ZkZ4dUlDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUhKbGJHVmhjMlZJWVc1a2JHVnlJRDA5UFNCc2FYTjBaVzVsY2k1eVpXeGxZWE5sU0dGdVpHeGxjanRjYmx4dUlDQWdJQ0FnYVdZZ0tHTnZiV0p2VFdGMFkyaGxjeUFtSmlCd2NtVnpjMGhoYm1Sc1pYSk5ZWFJqYUdWeklDWW1JSEpsYkdWaGMyVklZVzVrYkdWeVRXRjBZMmhsY3lrZ2UxeHVJQ0FnSUNBZ0lDQjBhR2x6TGw5c2FYTjBaVzVsY25NdWMzQnNhV05sS0drc0lERXBPMXh1SUNBZ0lDQWdJQ0JwSUMwOUlERTdYRzRnSUNBZ0lDQjlYRzRnSUNBZ2ZWeHVYRzRnSUNBZ2NtVjBkWEp1SUhSb2FYTTdYRzRnSUgxY2JseHVJQ0J5WlcxdmRtVk1hWE4wWlc1bGNpaHJaWGxEYjIxaWIxTjBjaXdnY0hKbGMzTklZVzVrYkdWeUxDQnlaV3hsWVhObFNHRnVaR3hsY2lrZ2UxeHVJQ0FnSUhKbGRIVnliaUIwYUdsekxuVnVZbWx1WkNoclpYbERiMjFpYjFOMGNpd2djSEpsYzNOSVlXNWtiR1Z5TENCeVpXeGxZWE5sU0dGdVpHeGxjaWs3WEc0Z0lIMWNibHh1SUNCdlptWW9hMlY1UTI5dFltOVRkSElzSUhCeVpYTnpTR0Z1Wkd4bGNpd2djbVZzWldGelpVaGhibVJzWlhJcElIdGNiaUFnSUNCeVpYUjFjbTRnZEdocGN5NTFibUpwYm1Rb2EyVjVRMjl0WW05VGRISXNJSEJ5WlhOelNHRnVaR3hsY2l3Z2NtVnNaV0Z6WlVoaGJtUnNaWElwTzF4dUlDQjlYRzVjYmlBZ2MyVjBRMjl1ZEdWNGRDaGpiMjUwWlhoMFRtRnRaU2tnZTF4dUlDQWdJR2xtS0hSb2FYTXVYMnh2WTJGc1pTa2dleUIwYUdsekxuSmxiR1ZoYzJWQmJHeExaWGx6S0NrN0lIMWNibHh1SUNBZ0lHbG1JQ2doZEdocGN5NWZZMjl1ZEdWNGRITmJZMjl1ZEdWNGRFNWhiV1ZkS1NCN1hHNGdJQ0FnSUNCamIyNXpkQ0JuYkc5aVlXeERiMjUwWlhoMElEMGdkR2hwY3k1ZlkyOXVkR1Y0ZEhNdVoyeHZZbUZzTzF4dUlDQWdJQ0FnZEdocGN5NWZZMjl1ZEdWNGRITmJZMjl1ZEdWNGRFNWhiV1ZkSUQwZ2UxeHVJQ0FnSUNBZ0lDQnNhWE4wWlc1bGNuTWdJQ0FnSUNBNklGdGRMRnh1SUNBZ0lDQWdJQ0IwWVhKblpYUlhhVzVrYjNjZ0lDQTZJR2RzYjJKaGJFTnZiblJsZUhRdWRHRnlaMlYwVjJsdVpHOTNMRnh1SUNBZ0lDQWdJQ0IwWVhKblpYUkZiR1Z0Wlc1MElDQTZJR2RzYjJKaGJFTnZiblJsZUhRdWRHRnlaMlYwUld4bGJXVnVkQ3hjYmlBZ0lDQWdJQ0FnZEdGeVoyVjBVR3hoZEdadmNtMGdPaUJuYkc5aVlXeERiMjUwWlhoMExuUmhjbWRsZEZCc1lYUm1iM0p0TEZ4dUlDQWdJQ0FnSUNCMFlYSm5aWFJWYzJWeVFXZGxiblE2SUdkc2IySmhiRU52Ym5SbGVIUXVkR0Z5WjJWMFZYTmxja0ZuWlc1MFhHNGdJQ0FnSUNCOU8xeHVJQ0FnSUgxY2JseHVJQ0FnSUdOdmJuTjBJR052Ym5SbGVIUWdJQ0FnSUNBZ0lEMGdkR2hwY3k1ZlkyOXVkR1Y0ZEhOYlkyOXVkR1Y0ZEU1aGJXVmRPMXh1SUNBZ0lIUm9hWE11WDJOMWNuSmxiblJEYjI1MFpYaDBJRDBnWTI5dWRHVjRkRTVoYldVN1hHNGdJQ0FnZEdocGN5NWZiR2x6ZEdWdVpYSnpJQ0FnSUNBZ1BTQmpiMjUwWlhoMExteHBjM1JsYm1WeWN6dGNibHh1SUNBZ0lIUm9hWE11YzNSdmNDZ3BPMXh1SUNBZ0lIUm9hWE11ZDJGMFkyZ29YRzRnSUNBZ0lDQmpiMjUwWlhoMExuUmhjbWRsZEZkcGJtUnZkeXhjYmlBZ0lDQWdJR052Ym5SbGVIUXVkR0Z5WjJWMFJXeGxiV1Z1ZEN4Y2JpQWdJQ0FnSUdOdmJuUmxlSFF1ZEdGeVoyVjBVR3hoZEdadmNtMHNYRzRnSUNBZ0lDQmpiMjUwWlhoMExuUmhjbWRsZEZWelpYSkJaMlZ1ZEZ4dUlDQWdJQ2s3WEc1Y2JpQWdJQ0J5WlhSMWNtNGdkR2hwY3p0Y2JpQWdmVnh1WEc0Z0lHZGxkRU52Ym5SbGVIUW9LU0I3WEc0Z0lDQWdjbVYwZFhKdUlIUm9hWE11WDJOMWNuSmxiblJEYjI1MFpYaDBPMXh1SUNCOVhHNWNiaUFnZDJsMGFFTnZiblJsZUhRb1kyOXVkR1Y0ZEU1aGJXVXNJR05oYkd4aVlXTnJLU0I3WEc0Z0lDQWdZMjl1YzNRZ2NISmxkbWx2ZFhORGIyNTBaWGgwVG1GdFpTQTlJSFJvYVhNdVoyVjBRMjl1ZEdWNGRDZ3BPMXh1SUNBZ0lIUm9hWE11YzJWMFEyOXVkR1Y0ZENoamIyNTBaWGgwVG1GdFpTazdYRzVjYmlBZ0lDQmpZV3hzWW1GamF5Z3BPMXh1WEc0Z0lDQWdkR2hwY3k1elpYUkRiMjUwWlhoMEtIQnlaWFpwYjNWelEyOXVkR1Y0ZEU1aGJXVXBPMXh1WEc0Z0lDQWdjbVYwZFhKdUlIUm9hWE03WEc0Z0lIMWNibHh1SUNCM1lYUmphQ2gwWVhKblpYUlhhVzVrYjNjc0lIUmhjbWRsZEVWc1pXMWxiblFzSUhSaGNtZGxkRkJzWVhSbWIzSnRMQ0IwWVhKblpYUlZjMlZ5UVdkbGJuUXBJSHRjYmlBZ0lDQjBhR2x6TG5OMGIzQW9LVHRjYmx4dUlDQWdJR052Ym5OMElIZHBiaUE5SUhSNWNHVnZaaUJuYkc5aVlXeFVhR2x6SUNFOVBTQW5kVzVrWldacGJtVmtKeUEvSUdkc2IySmhiRlJvYVhNZ09seHVJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lIUjVjR1Z2WmlCbmJHOWlZV3dnSVQwOUlDZDFibVJsWm1sdVpXUW5JRDhnWjJ4dlltRnNJRHBjYmlBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0IwZVhCbGIyWWdkMmx1Wkc5M0lDRTlQU0FuZFc1a1pXWnBibVZrSnlBL0lIZHBibVJ2ZHlBNlhHNGdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ2UzMDdYRzVjYmlBZ0lDQnBaaUFvSVhSaGNtZGxkRmRwYm1SdmR5a2dlMXh1SUNBZ0lDQWdhV1lnS0NGM2FXNHVZV1JrUlhabGJuUk1hWE4wWlc1bGNpQW1KaUFoZDJsdUxtRjBkR0ZqYUVWMlpXNTBLU0I3WEc0Z0lDQWdJQ0FnSUM4dklGUm9hWE1nZDJGeklHRmtaR1ZrSUhOdklIZG9aVzRnZFhOcGJtY2dkR2hwYm1keklHeHBhMlVnU2xORVQwMGdkMkYwWTJnZ1kyRnVJR0psSUhWelpXUWdkRzhnWTI5dVptbG5kWEpsSUhkaGRHTm9YRzRnSUNBZ0lDQWdJQzh2SUdadmNpQjBhR1VnWjJ4dlltRnNJRzVoYldWemNHRmpaU0J0WVc1MVlXeHNlUzVjYmlBZ0lDQWdJQ0FnYVdZZ0tIUm9hWE11WDJOMWNuSmxiblJEYjI1MFpYaDBJRDA5UFNBbloyeHZZbUZzSnlrZ2UxeHVJQ0FnSUNBZ0lDQWdJSEpsZEhWeWJseHVJQ0FnSUNBZ0lDQjlYRzRnSUNBZ0lDQWdJSFJvY205M0lHNWxkeUJGY25KdmNpZ25RMkZ1Ym05MElHWnBibVFnZDJsdVpHOTNJR1oxYm1OMGFXOXVjeUJoWkdSRmRtVnVkRXhwYzNSbGJtVnlJRzl5SUdGMGRHRmphRVYyWlc1MExpY3BPMXh1SUNBZ0lDQWdmVnh1SUNBZ0lDQWdkR0Z5WjJWMFYybHVaRzkzSUQwZ2QybHVPMXh1SUNBZ0lIMWNibHh1SUNBZ0lDOHZJRWhoYm1Sc1pTQmxiR1Z0Wlc1MElHSnBibVJwYm1keklIZG9aWEpsSUdFZ2RHRnlaMlYwSUhkcGJtUnZkeUJwY3lCdWIzUWdjR0Z6YzJWa1hHNGdJQ0FnYVdZZ0tIUjVjR1Z2WmlCMFlYSm5aWFJYYVc1a2IzY3VibTlrWlZSNWNHVWdQVDA5SUNkdWRXMWlaWEluS1NCN1hHNGdJQ0FnSUNCMFlYSm5aWFJWYzJWeVFXZGxiblFnUFNCMFlYSm5aWFJRYkdGMFptOXliVHRjYmlBZ0lDQWdJSFJoY21kbGRGQnNZWFJtYjNKdElDQTlJSFJoY21kbGRFVnNaVzFsYm5RN1hHNGdJQ0FnSUNCMFlYSm5aWFJGYkdWdFpXNTBJQ0FnUFNCMFlYSm5aWFJYYVc1a2IzYzdYRzRnSUNBZ0lDQjBZWEpuWlhSWGFXNWtiM2NnSUNBZ1BTQjNhVzQ3WEc0Z0lDQWdmVnh1WEc0Z0lDQWdhV1lnS0NGMFlYSm5aWFJYYVc1a2IzY3VZV1JrUlhabGJuUk1hWE4wWlc1bGNpQW1KaUFoZEdGeVoyVjBWMmx1Wkc5M0xtRjBkR0ZqYUVWMlpXNTBLU0I3WEc0Z0lDQWdJQ0IwYUhKdmR5QnVaWGNnUlhKeWIzSW9KME5oYm01dmRDQm1hVzVrSUdGa1pFVjJaVzUwVEdsemRHVnVaWElnYjNJZ1lYUjBZV05vUlhabGJuUWdiV1YwYUc5a2N5QnZiaUIwWVhKblpYUlhhVzVrYjNjdUp5azdYRzRnSUNBZ2ZWeHVYRzRnSUNBZ2RHaHBjeTVmYVhOTmIyUmxjbTVDY205M2MyVnlJRDBnSVNGMFlYSm5aWFJYYVc1a2IzY3VZV1JrUlhabGJuUk1hWE4wWlc1bGNqdGNibHh1SUNBZ0lHTnZibk4wSUhWelpYSkJaMlZ1ZENBOUlIUmhjbWRsZEZkcGJtUnZkeTV1WVhacFoyRjBiM0lnSmlZZ2RHRnlaMlYwVjJsdVpHOTNMbTVoZG1sbllYUnZjaTUxYzJWeVFXZGxiblFnZkh3Z0p5YzdYRzRnSUNBZ1kyOXVjM1FnY0d4aGRHWnZjbTBnSUQwZ2RHRnlaMlYwVjJsdVpHOTNMbTVoZG1sbllYUnZjaUFtSmlCMFlYSm5aWFJYYVc1a2IzY3VibUYyYVdkaGRHOXlMbkJzWVhSbWIzSnRJQ0I4ZkNBbkp6dGNibHh1SUNBZ0lIUmhjbWRsZEVWc1pXMWxiblFnSUNBbUppQjBZWEpuWlhSRmJHVnRaVzUwSUNBZ0lUMDlJRzUxYkd3Z2ZId2dLSFJoY21kbGRFVnNaVzFsYm5RZ0lDQTlJSFJoY21kbGRGZHBibVJ2ZHk1a2IyTjFiV1Z1ZENrN1hHNGdJQ0FnZEdGeVoyVjBVR3hoZEdadmNtMGdJQ1ltSUhSaGNtZGxkRkJzWVhSbWIzSnRJQ0FoUFQwZ2JuVnNiQ0I4ZkNBb2RHRnlaMlYwVUd4aGRHWnZjbTBnSUQwZ2NHeGhkR1p2Y20wcE8xeHVJQ0FnSUhSaGNtZGxkRlZ6WlhKQloyVnVkQ0FtSmlCMFlYSm5aWFJWYzJWeVFXZGxiblFnSVQwOUlHNTFiR3dnZkh3Z0tIUmhjbWRsZEZWelpYSkJaMlZ1ZENBOUlIVnpaWEpCWjJWdWRDazdYRzVjYmlBZ0lDQjBhR2x6TGw5MFlYSm5aWFJMWlhsRWIzZHVRbWx1WkdsdVp5QTlJQ2hsZG1WdWRDa2dQVDRnZTF4dUlDQWdJQ0FnZEdocGN5NXdjbVZ6YzB0bGVTaGxkbVZ1ZEM1clpYbERiMlJsTENCbGRtVnVkQ2s3WEc0Z0lDQWdJQ0IwYUdsekxsOW9ZVzVrYkdWRGIyMXRZVzVrUW5WbktHVjJaVzUwTENCd2JHRjBabTl5YlNrN1hHNGdJQ0FnZlR0Y2JpQWdJQ0IwYUdsekxsOTBZWEpuWlhSTFpYbFZjRUpwYm1ScGJtY2dQU0FvWlhabGJuUXBJRDArSUh0Y2JpQWdJQ0FnSUhSb2FYTXVjbVZzWldGelpVdGxlU2hsZG1WdWRDNXJaWGxEYjJSbExDQmxkbVZ1ZENrN1hHNGdJQ0FnZlR0Y2JpQWdJQ0IwYUdsekxsOTBZWEpuWlhSU1pYTmxkRUpwYm1ScGJtY2dQU0FvWlhabGJuUXBJRDArSUh0Y2JpQWdJQ0FnSUhSb2FYTXVjbVZzWldGelpVRnNiRXRsZVhNb1pYWmxiblFwTzF4dUlDQWdJSDA3WEc1Y2JpQWdJQ0IwYUdsekxsOWlhVzVrUlhabGJuUW9kR0Z5WjJWMFJXeGxiV1Z1ZEN3Z0oydGxlV1J2ZDI0bkxDQjBhR2x6TGw5MFlYSm5aWFJMWlhsRWIzZHVRbWx1WkdsdVp5azdYRzRnSUNBZ2RHaHBjeTVmWW1sdVpFVjJaVzUwS0hSaGNtZGxkRVZzWlcxbGJuUXNJQ2RyWlhsMWNDY3NJQ0FnZEdocGN5NWZkR0Z5WjJWMFMyVjVWWEJDYVc1a2FXNW5LVHRjYmlBZ0lDQjBhR2x6TGw5aWFXNWtSWFpsYm5Rb2RHRnlaMlYwVjJsdVpHOTNMQ0FnSjJadlkzVnpKeXdnSUNCMGFHbHpMbDkwWVhKblpYUlNaWE5sZEVKcGJtUnBibWNwTzF4dUlDQWdJSFJvYVhNdVgySnBibVJGZG1WdWRDaDBZWEpuWlhSWGFXNWtiM2NzSUNBbllteDFjaWNzSUNBZ0lIUm9hWE11WDNSaGNtZGxkRkpsYzJWMFFtbHVaR2x1WnlrN1hHNWNiaUFnSUNCMGFHbHpMbDkwWVhKblpYUkZiR1Z0Wlc1MElDQWdQU0IwWVhKblpYUkZiR1Z0Wlc1ME8xeHVJQ0FnSUhSb2FYTXVYM1JoY21kbGRGZHBibVJ2ZHlBZ0lDQTlJSFJoY21kbGRGZHBibVJ2ZHp0Y2JpQWdJQ0IwYUdsekxsOTBZWEpuWlhSUWJHRjBabTl5YlNBZ1BTQjBZWEpuWlhSUWJHRjBabTl5YlR0Y2JpQWdJQ0IwYUdsekxsOTBZWEpuWlhSVmMyVnlRV2RsYm5RZ1BTQjBZWEpuWlhSVmMyVnlRV2RsYm5RN1hHNWNiaUFnSUNCamIyNXpkQ0JqZFhKeVpXNTBRMjl1ZEdWNGRDQWdJQ0FnSUNBZ0lDQWdQU0IwYUdsekxsOWpiMjUwWlhoMGMxdDBhR2x6TGw5amRYSnlaVzUwUTI5dWRHVjRkRjA3WEc0Z0lDQWdZM1Z5Y21WdWRFTnZiblJsZUhRdWRHRnlaMlYwVjJsdVpHOTNJQ0FnSUQwZ2RHaHBjeTVmZEdGeVoyVjBWMmx1Wkc5M08xeHVJQ0FnSUdOMWNuSmxiblJEYjI1MFpYaDBMblJoY21kbGRFVnNaVzFsYm5RZ0lDQTlJSFJvYVhNdVgzUmhjbWRsZEVWc1pXMWxiblE3WEc0Z0lDQWdZM1Z5Y21WdWRFTnZiblJsZUhRdWRHRnlaMlYwVUd4aGRHWnZjbTBnSUQwZ2RHaHBjeTVmZEdGeVoyVjBVR3hoZEdadmNtMDdYRzRnSUNBZ1kzVnljbVZ1ZEVOdmJuUmxlSFF1ZEdGeVoyVjBWWE5sY2tGblpXNTBJRDBnZEdocGN5NWZkR0Z5WjJWMFZYTmxja0ZuWlc1ME8xeHVYRzRnSUNBZ2NtVjBkWEp1SUhSb2FYTTdYRzRnSUgxY2JseHVJQ0J6ZEc5d0tDa2dlMXh1SUNBZ0lHbG1JQ2doZEdocGN5NWZkR0Z5WjJWMFJXeGxiV1Z1ZENCOGZDQWhkR2hwY3k1ZmRHRnlaMlYwVjJsdVpHOTNLU0I3SUhKbGRIVnlianNnZlZ4dVhHNGdJQ0FnZEdocGN5NWZkVzVpYVc1a1JYWmxiblFvZEdocGN5NWZkR0Z5WjJWMFJXeGxiV1Z1ZEN3Z0oydGxlV1J2ZDI0bkxDQjBhR2x6TGw5MFlYSm5aWFJMWlhsRWIzZHVRbWx1WkdsdVp5azdYRzRnSUNBZ2RHaHBjeTVmZFc1aWFXNWtSWFpsYm5Rb2RHaHBjeTVmZEdGeVoyVjBSV3hsYldWdWRDd2dKMnRsZVhWd0p5d2dJQ0IwYUdsekxsOTBZWEpuWlhSTFpYbFZjRUpwYm1ScGJtY3BPMXh1SUNBZ0lIUm9hWE11WDNWdVltbHVaRVYyWlc1MEtIUm9hWE11WDNSaGNtZGxkRmRwYm1SdmR5d2dJQ2RtYjJOMWN5Y3NJQ0FnZEdocGN5NWZkR0Z5WjJWMFVtVnpaWFJDYVc1a2FXNW5LVHRjYmlBZ0lDQjBhR2x6TGw5MWJtSnBibVJGZG1WdWRDaDBhR2x6TGw5MFlYSm5aWFJYYVc1a2IzY3NJQ0FuWW14MWNpY3NJQ0FnSUhSb2FYTXVYM1JoY21kbGRGSmxjMlYwUW1sdVpHbHVaeWs3WEc1Y2JpQWdJQ0IwYUdsekxsOTBZWEpuWlhSWGFXNWtiM2NnSUQwZ2JuVnNiRHRjYmlBZ0lDQjBhR2x6TGw5MFlYSm5aWFJGYkdWdFpXNTBJRDBnYm5Wc2JEdGNibHh1SUNBZ0lISmxkSFZ5YmlCMGFHbHpPMXh1SUNCOVhHNWNiaUFnY0hKbGMzTkxaWGtvYTJWNVEyOWtaU3dnWlhabGJuUXBJSHRjYmlBZ0lDQnBaaUFvZEdocGN5NWZjR0YxYzJWa0tTQjdJSEpsZEhWeWJpQjBhR2x6T3lCOVhHNGdJQ0FnYVdZZ0tDRjBhR2x6TGw5c2IyTmhiR1VwSUhzZ2RHaHliM2NnYm1WM0lFVnljbTl5S0NkTWIyTmhiR1VnYm05MElITmxkQ2NwT3lCOVhHNWNiaUFnSUNCMGFHbHpMbDlzYjJOaGJHVXVjSEpsYzNOTFpYa29hMlY1UTI5a1pTazdYRzRnSUNBZ2RHaHBjeTVmWVhCd2JIbENhVzVrYVc1bmN5aGxkbVZ1ZENrN1hHNWNiaUFnSUNCeVpYUjFjbTRnZEdocGN6dGNiaUFnZlZ4dVhHNGdJSEpsYkdWaGMyVkxaWGtvYTJWNVEyOWtaU3dnWlhabGJuUXBJSHRjYmlBZ0lDQnBaaUFvZEdocGN5NWZjR0YxYzJWa0tTQjdJSEpsZEhWeWJpQjBhR2x6T3lCOVhHNGdJQ0FnYVdZZ0tDRjBhR2x6TGw5c2IyTmhiR1VwSUhzZ2RHaHliM2NnYm1WM0lFVnljbTl5S0NkTWIyTmhiR1VnYm05MElITmxkQ2NwT3lCOVhHNWNiaUFnSUNCMGFHbHpMbDlzYjJOaGJHVXVjbVZzWldGelpVdGxlU2hyWlhsRGIyUmxLVHRjYmlBZ0lDQjBhR2x6TGw5amJHVmhja0pwYm1ScGJtZHpLR1YyWlc1MEtUdGNibHh1SUNBZ0lISmxkSFZ5YmlCMGFHbHpPMXh1SUNCOVhHNWNiaUFnY21Wc1pXRnpaVUZzYkV0bGVYTW9aWFpsYm5RcElIdGNiaUFnSUNCcFppQW9kR2hwY3k1ZmNHRjFjMlZrS1NCN0lISmxkSFZ5YmlCMGFHbHpPeUI5WEc0Z0lDQWdhV1lnS0NGMGFHbHpMbDlzYjJOaGJHVXBJSHNnZEdoeWIzY2dibVYzSUVWeWNtOXlLQ2RNYjJOaGJHVWdibTkwSUhObGRDY3BPeUI5WEc1Y2JpQWdJQ0IwYUdsekxsOXNiMk5oYkdVdWNISmxjM05sWkV0bGVYTXViR1Z1WjNSb0lEMGdNRHRjYmlBZ0lDQjBhR2x6TGw5amJHVmhja0pwYm1ScGJtZHpLR1YyWlc1MEtUdGNibHh1SUNBZ0lISmxkSFZ5YmlCMGFHbHpPMXh1SUNCOVhHNWNiaUFnY0dGMWMyVW9LU0I3WEc0Z0lDQWdhV1lnS0hSb2FYTXVYM0JoZFhObFpDa2dleUJ5WlhSMWNtNGdkR2hwY3pzZ2ZWeHVJQ0FnSUdsbUlDaDBhR2x6TGw5c2IyTmhiR1VwSUhzZ2RHaHBjeTV5Wld4bFlYTmxRV3hzUzJWNWN5Z3BPeUI5WEc0Z0lDQWdkR2hwY3k1ZmNHRjFjMlZrSUQwZ2RISjFaVHRjYmx4dUlDQWdJSEpsZEhWeWJpQjBhR2x6TzF4dUlDQjlYRzVjYmlBZ2NtVnpkVzFsS0NrZ2UxeHVJQ0FnSUhSb2FYTXVYM0JoZFhObFpDQTlJR1poYkhObE8xeHVYRzRnSUNBZ2NtVjBkWEp1SUhSb2FYTTdYRzRnSUgxY2JseHVJQ0J5WlhObGRDZ3BJSHRjYmlBZ0lDQjBhR2x6TG5KbGJHVmhjMlZCYkd4TFpYbHpLQ2s3WEc0Z0lDQWdkR2hwY3k1ZmJHbHpkR1Z1WlhKekxteGxibWQwYUNBOUlEQTdYRzVjYmlBZ0lDQnlaWFIxY200Z2RHaHBjenRjYmlBZ2ZWeHVYRzRnSUY5aWFXNWtSWFpsYm5Rb2RHRnlaMlYwUld4bGJXVnVkQ3dnWlhabGJuUk9ZVzFsTENCb1lXNWtiR1Z5S1NCN1hHNGdJQ0FnY21WMGRYSnVJSFJvYVhNdVgybHpUVzlrWlhKdVFuSnZkM05sY2lBL1hHNGdJQ0FnSUNCMFlYSm5aWFJGYkdWdFpXNTBMbUZrWkVWMlpXNTBUR2x6ZEdWdVpYSW9aWFpsYm5ST1lXMWxMQ0JvWVc1a2JHVnlMQ0JtWVd4elpTa2dPbHh1SUNBZ0lDQWdkR0Z5WjJWMFJXeGxiV1Z1ZEM1aGRIUmhZMmhGZG1WdWRDZ25iMjRuSUNzZ1pYWmxiblJPWVcxbExDQm9ZVzVrYkdWeUtUdGNiaUFnZlZ4dVhHNGdJRjkxYm1KcGJtUkZkbVZ1ZENoMFlYSm5aWFJGYkdWdFpXNTBMQ0JsZG1WdWRFNWhiV1VzSUdoaGJtUnNaWElwSUh0Y2JpQWdJQ0J5WlhSMWNtNGdkR2hwY3k1ZmFYTk5iMlJsY201Q2NtOTNjMlZ5SUQ5Y2JpQWdJQ0FnSUhSaGNtZGxkRVZzWlcxbGJuUXVjbVZ0YjNabFJYWmxiblJNYVhOMFpXNWxjaWhsZG1WdWRFNWhiV1VzSUdoaGJtUnNaWElzSUdaaGJITmxLU0E2WEc0Z0lDQWdJQ0IwWVhKblpYUkZiR1Z0Wlc1MExtUmxkR0ZqYUVWMlpXNTBLQ2R2YmljZ0t5QmxkbVZ1ZEU1aGJXVXNJR2hoYm1Sc1pYSXBPMXh1SUNCOVhHNWNiaUFnWDJkbGRFZHliM1Z3WldSTWFYTjBaVzVsY25Nb0tTQjdYRzRnSUNBZ1kyOXVjM1FnYkdsemRHVnVaWEpIY205MWNITWdJQ0E5SUZ0ZE8xeHVJQ0FnSUdOdmJuTjBJR3hwYzNSbGJtVnlSM0p2ZFhCTllYQWdQU0JiWFR0Y2JseHVJQ0FnSUd4bGRDQnNhWE4wWlc1bGNuTWdQU0IwYUdsekxsOXNhWE4wWlc1bGNuTTdYRzRnSUNBZ2FXWWdLSFJvYVhNdVgyTjFjbkpsYm5SRGIyNTBaWGgwSUNFOVBTQW5aMnh2WW1Gc0p5a2dlMXh1SUNBZ0lDQWdiR2x6ZEdWdVpYSnpJRDBnV3k0dUxteHBjM1JsYm1WeWN5d2dMaTR1ZEdocGN5NWZZMjl1ZEdWNGRITXVaMnh2WW1Gc0xteHBjM1JsYm1WeWMxMDdYRzRnSUNBZ2ZWeHVYRzRnSUNBZ2JHbHpkR1Z1WlhKekxuTnZjblFvWEc0Z0lDQWdJQ0FvWVN3Z1lpa2dQVDVjYmlBZ0lDQWdJQ0FnS0dJdWEyVjVRMjl0WW04Z1B5QmlMbXRsZVVOdmJXSnZMbXRsZVU1aGJXVnpMbXhsYm1kMGFDQTZJREFwSUMxY2JpQWdJQ0FnSUNBZ0tHRXVhMlY1UTI5dFltOGdQeUJoTG10bGVVTnZiV0p2TG10bGVVNWhiV1Z6TG14bGJtZDBhQ0E2SURBcFhHNGdJQ0FnS1M1bWIzSkZZV05vS0Noc0tTQTlQaUI3WEc0Z0lDQWdJQ0JzWlhRZ2JXRndTVzVrWlhnZ1BTQXRNVHRjYmlBZ0lDQWdJR1p2Y2lBb2JHVjBJR2tnUFNBd095QnBJRHdnYkdsemRHVnVaWEpIY205MWNFMWhjQzVzWlc1bmRHZzdJR2tnS3owZ01Ta2dlMXh1SUNBZ0lDQWdJQ0JwWmlBb2JHbHpkR1Z1WlhKSGNtOTFjRTFoY0Z0cFhTQTlQVDBnYm5Wc2JDQW1KaUJzTG10bGVVTnZiV0p2SUQwOVBTQnVkV3hzSUh4OFhHNGdJQ0FnSUNBZ0lDQWdJQ0JzYVhOMFpXNWxja2R5YjNWd1RXRndXMmxkSUNFOVBTQnVkV3hzSUNZbUlHeHBjM1JsYm1WeVIzSnZkWEJOWVhCYmFWMHVhWE5GY1hWaGJDaHNMbXRsZVVOdmJXSnZLU2tnZTF4dUlDQWdJQ0FnSUNBZ0lHMWhjRWx1WkdWNElEMGdhVHRjYmlBZ0lDQWdJQ0FnZlZ4dUlDQWdJQ0FnZlZ4dUlDQWdJQ0FnYVdZZ0tHMWhjRWx1WkdWNElEMDlQU0F0TVNrZ2UxeHVJQ0FnSUNBZ0lDQnRZWEJKYm1SbGVDQTlJR3hwYzNSbGJtVnlSM0p2ZFhCTllYQXViR1Z1WjNSb08xeHVJQ0FnSUNBZ0lDQnNhWE4wWlc1bGNrZHliM1Z3VFdGd0xuQjFjMmdvYkM1clpYbERiMjFpYnlrN1hHNGdJQ0FnSUNCOVhHNGdJQ0FnSUNCcFppQW9JV3hwYzNSbGJtVnlSM0p2ZFhCelcyMWhjRWx1WkdWNFhTa2dlMXh1SUNBZ0lDQWdJQ0JzYVhOMFpXNWxja2R5YjNWd2MxdHRZWEJKYm1SbGVGMGdQU0JiWFR0Y2JpQWdJQ0FnSUgxY2JpQWdJQ0FnSUd4cGMzUmxibVZ5UjNKdmRYQnpXMjFoY0VsdVpHVjRYUzV3ZFhOb0tHd3BPMXh1SUNBZ0lIMHBPMXh1WEc0Z0lDQWdjbVYwZFhKdUlHeHBjM1JsYm1WeVIzSnZkWEJ6TzF4dUlDQjlYRzVjYmlBZ1gyRndjR3g1UW1sdVpHbHVaM01vWlhabGJuUXBJSHRjYmlBZ0lDQnNaWFFnY0hKbGRtVnVkRkpsY0dWaGRDQTlJR1poYkhObE8xeHVYRzRnSUNBZ1pYWmxiblFnZkh3Z0tHVjJaVzUwSUQwZ2UzMHBPMXh1SUNBZ0lHVjJaVzUwTG5CeVpYWmxiblJTWlhCbFlYUWdQU0FvS1NBOVBpQjdJSEJ5WlhabGJuUlNaWEJsWVhRZ1BTQjBjblZsT3lCOU8xeHVJQ0FnSUdWMlpXNTBMbkJ5WlhOelpXUkxaWGx6SUNBZ1BTQjBhR2x6TGw5c2IyTmhiR1V1Y0hKbGMzTmxaRXRsZVhNdWMyeHBZMlVvTUNrN1hHNWNiaUFnSUNCamIyNXpkQ0JoWTNScGRtVlVZWEpuWlhSTFpYbHpJRDBnZEdocGN5NWZiRzlqWVd4bExtRmpkR2wyWlZSaGNtZGxkRXRsZVhNN1hHNGdJQ0FnWTI5dWMzUWdjSEpsYzNObFpFdGxlWE1nSUNBZ0lDQTlJSFJvYVhNdVgyeHZZMkZzWlM1d2NtVnpjMlZrUzJWNWN5NXpiR2xqWlNnd0tUdGNiaUFnSUNCamIyNXpkQ0JzYVhOMFpXNWxja2R5YjNWd2N5QWdJRDBnZEdocGN5NWZaMlYwUjNKdmRYQmxaRXhwYzNSbGJtVnljeWdwTzF4dVhHNGdJQ0FnWm05eUlDaHNaWFFnYVNBOUlEQTdJR2tnUENCc2FYTjBaVzVsY2tkeWIzVndjeTVzWlc1bmRHZzdJR2tnS3owZ01Ta2dlMXh1SUNBZ0lDQWdZMjl1YzNRZ2JHbHpkR1Z1WlhKeklEMGdiR2x6ZEdWdVpYSkhjbTkxY0hOYmFWMDdYRzRnSUNBZ0lDQmpiMjV6ZENCclpYbERiMjFpYnlBZ1BTQnNhWE4wWlc1bGNuTmJNRjB1YTJWNVEyOXRZbTg3WEc1Y2JpQWdJQ0FnSUdsbUlDaGNiaUFnSUNBZ0lDQWdhMlY1UTI5dFltOGdQVDA5SUc1MWJHd2dmSHhjYmlBZ0lDQWdJQ0FnYTJWNVEyOXRZbTh1WTJobFkyc29jSEpsYzNObFpFdGxlWE1wSUNZbVhHNGdJQ0FnSUNBZ0lHRmpkR2wyWlZSaGNtZGxkRXRsZVhNdWMyOXRaU2hySUQwK0lHdGxlVU52YldKdkxtdGxlVTVoYldWekxtbHVZMngxWkdWektHc3BLVnh1SUNBZ0lDQWdLU0I3WEc0Z0lDQWdJQ0FnSUdadmNpQW9iR1YwSUdvZ1BTQXdPeUJxSUR3Z2JHbHpkR1Z1WlhKekxteGxibWQwYURzZ2FpQXJQU0F4S1NCN1hHNGdJQ0FnSUNBZ0lDQWdiR1YwSUd4cGMzUmxibVZ5SUQwZ2JHbHpkR1Z1WlhKelcycGRPMXh1WEc0Z0lDQWdJQ0FnSUNBZ2FXWWdLQ0ZzYVhOMFpXNWxjaTVsZUdWamRYUnBibWRJWVc1a2JHVnlJQ1ltSUd4cGMzUmxibVZ5TG5CeVpYTnpTR0Z1Wkd4bGNpQW1KaUFoYkdsemRHVnVaWEl1Y0hKbGRtVnVkRkpsY0dWaGRDa2dlMXh1SUNBZ0lDQWdJQ0FnSUNBZ2JHbHpkR1Z1WlhJdVpYaGxZM1YwYVc1blNHRnVaR3hsY2lBOUlIUnlkV1U3WEc0Z0lDQWdJQ0FnSUNBZ0lDQnNhWE4wWlc1bGNpNXdjbVZ6YzBoaGJtUnNaWEl1WTJGc2JDaDBhR2x6TENCbGRtVnVkQ2s3WEc0Z0lDQWdJQ0FnSUNBZ0lDQnNhWE4wWlc1bGNpNWxlR1ZqZFhScGJtZElZVzVrYkdWeUlEMGdabUZzYzJVN1hHNWNiaUFnSUNBZ0lDQWdJQ0FnSUdsbUlDaHdjbVYyWlc1MFVtVndaV0YwSUh4OElHeHBjM1JsYm1WeUxuQnlaWFpsYm5SU1pYQmxZWFJDZVVSbFptRjFiSFFwSUh0Y2JpQWdJQ0FnSUNBZ0lDQWdJQ0FnYkdsemRHVnVaWEl1Y0hKbGRtVnVkRkpsY0dWaGRDQTlJSFJ5ZFdVN1hHNGdJQ0FnSUNBZ0lDQWdJQ0FnSUhCeVpYWmxiblJTWlhCbFlYUWdJQ0FnSUNBZ0lDQWdQU0JtWVd4elpUdGNiaUFnSUNBZ0lDQWdJQ0FnSUgxY2JpQWdJQ0FnSUNBZ0lDQjlYRzVjYmlBZ0lDQWdJQ0FnSUNCcFppQW9kR2hwY3k1ZllYQndiR2xsWkV4cGMzUmxibVZ5Y3k1cGJtUmxlRTltS0d4cGMzUmxibVZ5S1NBOVBUMGdMVEVwSUh0Y2JpQWdJQ0FnSUNBZ0lDQWdJSFJvYVhNdVgyRndjR3hwWldSTWFYTjBaVzVsY25NdWNIVnphQ2hzYVhOMFpXNWxjaWs3WEc0Z0lDQWdJQ0FnSUNBZ2ZWeHVJQ0FnSUNBZ0lDQjlYRzVjYmlBZ0lDQWdJQ0FnYVdZZ0tHdGxlVU52YldKdktTQjdYRzRnSUNBZ0lDQWdJQ0FnWm05eUlDaHNaWFFnYWlBOUlEQTdJR29nUENCclpYbERiMjFpYnk1clpYbE9ZVzFsY3k1c1pXNW5kR2c3SUdvZ0t6MGdNU2tnZTF4dUlDQWdJQ0FnSUNBZ0lDQWdZMjl1YzNRZ2FXNWtaWGdnUFNCd2NtVnpjMlZrUzJWNWN5NXBibVJsZUU5bUtHdGxlVU52YldKdkxtdGxlVTVoYldWelcycGRLVHRjYmlBZ0lDQWdJQ0FnSUNBZ0lHbG1JQ2hwYm1SbGVDQWhQVDBnTFRFcElIdGNiaUFnSUNBZ0lDQWdJQ0FnSUNBZ2NISmxjM05sWkV0bGVYTXVjM0JzYVdObEtHbHVaR1Y0TENBeEtUdGNiaUFnSUNBZ0lDQWdJQ0FnSUNBZ2FpQXRQU0F4TzF4dUlDQWdJQ0FnSUNBZ0lDQWdmVnh1SUNBZ0lDQWdJQ0FnSUgxY2JpQWdJQ0FnSUNBZ2ZWeHVJQ0FnSUNBZ2ZWeHVJQ0FnSUgxY2JpQWdmVnh1WEc0Z0lGOWpiR1ZoY2tKcGJtUnBibWR6S0dWMlpXNTBLU0I3WEc0Z0lDQWdaWFpsYm5RZ2ZId2dLR1YyWlc1MElEMGdlMzBwTzF4dUlDQWdJR1YyWlc1MExuQnlaWE56WldSTFpYbHpJRDBnZEdocGN5NWZiRzlqWVd4bExuQnlaWE56WldSTFpYbHpMbk5zYVdObEtEQXBPMXh1WEc0Z0lDQWdabTl5SUNoc1pYUWdhU0E5SURBN0lHa2dQQ0IwYUdsekxsOWhjSEJzYVdWa1RHbHpkR1Z1WlhKekxteGxibWQwYURzZ2FTQXJQU0F4S1NCN1hHNGdJQ0FnSUNCamIyNXpkQ0JzYVhOMFpXNWxjaUE5SUhSb2FYTXVYMkZ3Y0d4cFpXUk1hWE4wWlc1bGNuTmJhVjA3WEc0Z0lDQWdJQ0JqYjI1emRDQnJaWGxEYjIxaWJ5QTlJR3hwYzNSbGJtVnlMbXRsZVVOdmJXSnZPMXh1SUNBZ0lDQWdhV1lnS0d0bGVVTnZiV0p2SUQwOVBTQnVkV3hzSUh4OElDRnJaWGxEYjIxaWJ5NWphR1ZqYXloMGFHbHpMbDlzYjJOaGJHVXVjSEpsYzNObFpFdGxlWE1wS1NCN1hHNGdJQ0FnSUNBZ0lHeHBjM1JsYm1WeUxuQnlaWFpsYm5SU1pYQmxZWFFnUFNCbVlXeHpaVHRjYmlBZ0lDQWdJQ0FnYVdZZ0tHdGxlVU52YldKdklDRTlQU0J1ZFd4c0lIeDhJR1YyWlc1MExuQnlaWE56WldSTFpYbHpMbXhsYm1kMGFDQTlQVDBnTUNrZ2UxeHVJQ0FnSUNBZ0lDQWdJSFJvYVhNdVgyRndjR3hwWldSTWFYTjBaVzVsY25NdWMzQnNhV05sS0drc0lERXBPMXh1SUNBZ0lDQWdJQ0FnSUdrZ0xUMGdNVHRjYmlBZ0lDQWdJQ0FnZlZ4dUlDQWdJQ0FnSUNCcFppQW9JV3hwYzNSbGJtVnlMbVY0WldOMWRHbHVaMGhoYm1Sc1pYSWdKaVlnYkdsemRHVnVaWEl1Y21Wc1pXRnpaVWhoYm1Sc1pYSXBJSHRjYmlBZ0lDQWdJQ0FnSUNCc2FYTjBaVzVsY2k1bGVHVmpkWFJwYm1kSVlXNWtiR1Z5SUQwZ2RISjFaVHRjYmlBZ0lDQWdJQ0FnSUNCc2FYTjBaVzVsY2k1eVpXeGxZWE5sU0dGdVpHeGxjaTVqWVd4c0tIUm9hWE1zSUdWMlpXNTBLVHRjYmlBZ0lDQWdJQ0FnSUNCc2FYTjBaVzVsY2k1bGVHVmpkWFJwYm1kSVlXNWtiR1Z5SUQwZ1ptRnNjMlU3WEc0Z0lDQWdJQ0FnSUgxY2JpQWdJQ0FnSUgxY2JpQWdJQ0I5WEc0Z0lIMWNibHh1SUNCZmFHRnVaR3hsUTI5dGJXRnVaRUoxWnlobGRtVnVkQ3dnY0d4aGRHWnZjbTBwSUh0Y2JpQWdJQ0F2THlCUGJpQk5ZV01nZDJobGJpQjBhR1VnWTI5dGJXRnVaQ0JyWlhrZ2FYTWdhMlZ3ZENCd2NtVnpjMlZrTENCclpYbDFjQ0JwY3lCdWIzUWdkSEpwWjJkbGNtVmtJR1p2Y2lCaGJua2diM1JvWlhJZ2EyVjVMbHh1SUNBZ0lDOHZJRWx1SUhSb2FYTWdZMkZ6WlNCbWIzSmpaU0JoSUd0bGVYVndJR1p2Y2lCdWIyNHRiVzlrYVdacFpYSWdhMlY1Y3lCa2FYSmxZM1JzZVNCaFpuUmxjaUIwYUdVZ2EyVjVjSEpsYzNNdVhHNGdJQ0FnWTI5dWMzUWdiVzlrYVdacFpYSkxaWGx6SUQwZ1cxd2ljMmhwWm5SY0lpd2dYQ0pqZEhKc1hDSXNJRndpWVd4MFhDSXNJRndpWTJGd2MyeHZZMnRjSWl3Z1hDSjBZV0pjSWl3Z1hDSmpiMjF0WVc1a1hDSmRPMXh1SUNBZ0lHbG1JQ2h3YkdGMFptOXliUzV0WVhSamFDaGNJazFoWTF3aUtTQW1KaUIwYUdsekxsOXNiMk5oYkdVdWNISmxjM05sWkV0bGVYTXVhVzVqYkhWa1pYTW9YQ0pqYjIxdFlXNWtYQ0lwSUNZbVhHNGdJQ0FnSUNBZ0lDRnRiMlJwWm1sbGNrdGxlWE11YVc1amJIVmtaWE1vZEdocGN5NWZiRzlqWVd4bExtZGxkRXRsZVU1aGJXVnpLR1YyWlc1MExtdGxlVU52WkdVcFd6QmRLU2tnZTF4dUlDQWdJQ0FnZEdocGN5NWZkR0Z5WjJWMFMyVjVWWEJDYVc1a2FXNW5LR1YyWlc1MEtUdGNiaUFnSUNCOVhHNGdJSDFjYm4xY2JpSXNJbHh1Wlhod2IzSjBJR1oxYm1OMGFXOXVJSFZ6S0d4dlkyRnNaU3dnY0d4aGRHWnZjbTBzSUhWelpYSkJaMlZ1ZENrZ2UxeHVYRzRnSUM4dklHZGxibVZ5WVd4Y2JpQWdiRzlqWVd4bExtSnBibVJMWlhsRGIyUmxLRE1zSUNBZ1d5ZGpZVzVqWld3blhTazdYRzRnSUd4dlkyRnNaUzVpYVc1a1MyVjVRMjlrWlNnNExDQWdJRnNuWW1GamEzTndZV05sSjEwcE8xeHVJQ0JzYjJOaGJHVXVZbWx1WkV0bGVVTnZaR1VvT1N3Z0lDQmJKM1JoWWlkZEtUdGNiaUFnYkc5allXeGxMbUpwYm1STFpYbERiMlJsS0RFeUxDQWdXeWRqYkdWaGNpZGRLVHRjYmlBZ2JHOWpZV3hsTG1KcGJtUkxaWGxEYjJSbEtERXpMQ0FnV3lkbGJuUmxjaWRkS1R0Y2JpQWdiRzlqWVd4bExtSnBibVJMWlhsRGIyUmxLREUyTENBZ1d5ZHphR2xtZENkZEtUdGNiaUFnYkc5allXeGxMbUpwYm1STFpYbERiMlJsS0RFM0xDQWdXeWRqZEhKc0oxMHBPMXh1SUNCc2IyTmhiR1V1WW1sdVpFdGxlVU52WkdVb01UZ3NJQ0JiSjJGc2RDY3NJQ2R0Wlc1MUoxMHBPMXh1SUNCc2IyTmhiR1V1WW1sdVpFdGxlVU52WkdVb01Ua3NJQ0JiSjNCaGRYTmxKeXdnSjJKeVpXRnJKMTBwTzF4dUlDQnNiMk5oYkdVdVltbHVaRXRsZVVOdlpHVW9NakFzSUNCYkoyTmhjSE5zYjJOckoxMHBPMXh1SUNCc2IyTmhiR1V1WW1sdVpFdGxlVU52WkdVb01qY3NJQ0JiSjJWelkyRndaU2NzSUNkbGMyTW5YU2s3WEc0Z0lHeHZZMkZzWlM1aWFXNWtTMlY1UTI5a1pTZ3pNaXdnSUZzbmMzQmhZMlVuTENBbmMzQmhZMlZpWVhJblhTazdYRzRnSUd4dlkyRnNaUzVpYVc1a1MyVjVRMjlrWlNnek15d2dJRnNuY0dGblpYVndKMTBwTzF4dUlDQnNiMk5oYkdVdVltbHVaRXRsZVVOdlpHVW9NelFzSUNCYkozQmhaMlZrYjNkdUoxMHBPMXh1SUNCc2IyTmhiR1V1WW1sdVpFdGxlVU52WkdVb016VXNJQ0JiSjJWdVpDZGRLVHRjYmlBZ2JHOWpZV3hsTG1KcGJtUkxaWGxEYjJSbEtETTJMQ0FnV3lkb2IyMWxKMTBwTzF4dUlDQnNiMk5oYkdVdVltbHVaRXRsZVVOdlpHVW9NemNzSUNCYkoyeGxablFuWFNrN1hHNGdJR3h2WTJGc1pTNWlhVzVrUzJWNVEyOWtaU2d6T0N3Z0lGc25kWEFuWFNrN1hHNGdJR3h2WTJGc1pTNWlhVzVrUzJWNVEyOWtaU2d6T1N3Z0lGc25jbWxuYUhRblhTazdYRzRnSUd4dlkyRnNaUzVpYVc1a1MyVjVRMjlrWlNnME1Dd2dJRnNuWkc5M2JpZGRLVHRjYmlBZ2JHOWpZV3hsTG1KcGJtUkxaWGxEYjJSbEtEUXhMQ0FnV3lkelpXeGxZM1FuWFNrN1hHNGdJR3h2WTJGc1pTNWlhVzVrUzJWNVEyOWtaU2cwTWl3Z0lGc25jSEpwYm5SelkzSmxaVzRuWFNrN1hHNGdJR3h2WTJGc1pTNWlhVzVrUzJWNVEyOWtaU2cwTXl3Z0lGc25aWGhsWTNWMFpTZGRLVHRjYmlBZ2JHOWpZV3hsTG1KcGJtUkxaWGxEYjJSbEtEUTBMQ0FnV3lkemJtRndjMmh2ZENkZEtUdGNiaUFnYkc5allXeGxMbUpwYm1STFpYbERiMlJsS0RRMUxDQWdXeWRwYm5ObGNuUW5MQ0FuYVc1ekoxMHBPMXh1SUNCc2IyTmhiR1V1WW1sdVpFdGxlVU52WkdVb05EWXNJQ0JiSjJSbGJHVjBaU2NzSUNka1pXd25YU2s3WEc0Z0lHeHZZMkZzWlM1aWFXNWtTMlY1UTI5a1pTZzBOeXdnSUZzbmFHVnNjQ2RkS1R0Y2JpQWdiRzlqWVd4bExtSnBibVJMWlhsRGIyUmxLREUwTlN3Z1d5ZHpZM0p2Ykd4c2IyTnJKeXdnSjNOamNtOXNiQ2RkS1R0Y2JpQWdiRzlqWVd4bExtSnBibVJMWlhsRGIyUmxLREU0T0N3Z1d5ZGpiMjF0WVNjc0lDY3NKMTBwTzF4dUlDQnNiMk5oYkdVdVltbHVaRXRsZVVOdlpHVW9NVGt3TENCYkozQmxjbWx2WkNjc0lDY3VKMTBwTzF4dUlDQnNiMk5oYkdVdVltbHVaRXRsZVVOdlpHVW9NVGt4TENCYkozTnNZWE5vSnl3Z0oyWnZjbmRoY21SemJHRnphQ2NzSUNjdkoxMHBPMXh1SUNCc2IyTmhiR1V1WW1sdVpFdGxlVU52WkdVb01Ua3lMQ0JiSjJkeVlYWmxZV05qWlc1MEp5d2dKMkFuWFNrN1hHNGdJR3h2WTJGc1pTNWlhVzVrUzJWNVEyOWtaU2d5TVRrc0lGc25iM0JsYm1KeVlXTnJaWFFuTENBbld5ZGRLVHRjYmlBZ2JHOWpZV3hsTG1KcGJtUkxaWGxEYjJSbEtESXlNQ3dnV3lkaVlXTnJjMnhoYzJnbkxDQW5YRnhjWENkZEtUdGNiaUFnYkc5allXeGxMbUpwYm1STFpYbERiMlJsS0RJeU1Td2dXeWRqYkc5elpXSnlZV05yWlhRbkxDQW5YU2RkS1R0Y2JpQWdiRzlqWVd4bExtSnBibVJMWlhsRGIyUmxLREl5TWl3Z1d5ZGhjRzl6ZEhKdmNHaGxKeXdnSjF4Y0p5ZGRLVHRjYmx4dUlDQXZMeUF3TFRsY2JpQWdiRzlqWVd4bExtSnBibVJMWlhsRGIyUmxLRFE0TENCYkozcGxjbThuTENBbk1DZGRLVHRjYmlBZ2JHOWpZV3hsTG1KcGJtUkxaWGxEYjJSbEtEUTVMQ0JiSjI5dVpTY3NJQ2N4SjEwcE8xeHVJQ0JzYjJOaGJHVXVZbWx1WkV0bGVVTnZaR1VvTlRBc0lGc25kSGR2Snl3Z0p6SW5YU2s3WEc0Z0lHeHZZMkZzWlM1aWFXNWtTMlY1UTI5a1pTZzFNU3dnV3lkMGFISmxaU2NzSUNjekoxMHBPMXh1SUNCc2IyTmhiR1V1WW1sdVpFdGxlVU52WkdVb05USXNJRnNuWm05MWNpY3NJQ2MwSjEwcE8xeHVJQ0JzYjJOaGJHVXVZbWx1WkV0bGVVTnZaR1VvTlRNc0lGc25abWwyWlNjc0lDYzFKMTBwTzF4dUlDQnNiMk5oYkdVdVltbHVaRXRsZVVOdlpHVW9OVFFzSUZzbmMybDRKeXdnSnpZblhTazdYRzRnSUd4dlkyRnNaUzVpYVc1a1MyVjVRMjlrWlNnMU5Td2dXeWR6WlhabGJpY3NJQ2MzSjEwcE8xeHVJQ0JzYjJOaGJHVXVZbWx1WkV0bGVVTnZaR1VvTlRZc0lGc25aV2xuYUhRbkxDQW5PQ2RkS1R0Y2JpQWdiRzlqWVd4bExtSnBibVJMWlhsRGIyUmxLRFUzTENCYkoyNXBibVVuTENBbk9TZGRLVHRjYmx4dUlDQXZMeUJ1ZFcxd1lXUmNiaUFnYkc5allXeGxMbUpwYm1STFpYbERiMlJsS0RrMkxDQmJKMjUxYlhwbGNtOG5MQ0FuYm5WdE1DZGRLVHRjYmlBZ2JHOWpZV3hsTG1KcGJtUkxaWGxEYjJSbEtEazNMQ0JiSjI1MWJXOXVaU2NzSUNkdWRXMHhKMTBwTzF4dUlDQnNiMk5oYkdVdVltbHVaRXRsZVVOdlpHVW9PVGdzSUZzbmJuVnRkSGR2Snl3Z0oyNTFiVEluWFNrN1hHNGdJR3h2WTJGc1pTNWlhVzVrUzJWNVEyOWtaU2c1T1N3Z1d5ZHVkVzEwYUhKbFpTY3NJQ2R1ZFcwekoxMHBPMXh1SUNCc2IyTmhiR1V1WW1sdVpFdGxlVU52WkdVb01UQXdMQ0JiSjI1MWJXWnZkWEluTENBbmJuVnROQ2RkS1R0Y2JpQWdiRzlqWVd4bExtSnBibVJMWlhsRGIyUmxLREV3TVN3Z1d5ZHVkVzFtYVhabEp5d2dKMjUxYlRVblhTazdYRzRnSUd4dlkyRnNaUzVpYVc1a1MyVjVRMjlrWlNneE1ESXNJRnNuYm5WdGMybDRKeXdnSjI1MWJUWW5YU2s3WEc0Z0lHeHZZMkZzWlM1aWFXNWtTMlY1UTI5a1pTZ3hNRE1zSUZzbmJuVnRjMlYyWlc0bkxDQW5iblZ0TnlkZEtUdGNiaUFnYkc5allXeGxMbUpwYm1STFpYbERiMlJsS0RFd05Dd2dXeWR1ZFcxbGFXZG9kQ2NzSUNkdWRXMDRKMTBwTzF4dUlDQnNiMk5oYkdVdVltbHVaRXRsZVVOdlpHVW9NVEExTENCYkoyNTFiVzVwYm1VbkxDQW5iblZ0T1NkZEtUdGNiaUFnYkc5allXeGxMbUpwYm1STFpYbERiMlJsS0RFd05pd2dXeWR1ZFcxdGRXeDBhWEJzZVNjc0lDZHVkVzBxSjEwcE8xeHVJQ0JzYjJOaGJHVXVZbWx1WkV0bGVVTnZaR1VvTVRBM0xDQmJKMjUxYldGa1pDY3NJQ2R1ZFcwckoxMHBPMXh1SUNCc2IyTmhiR1V1WW1sdVpFdGxlVU52WkdVb01UQTRMQ0JiSjI1MWJXVnVkR1Z5SjEwcE8xeHVJQ0JzYjJOaGJHVXVZbWx1WkV0bGVVTnZaR1VvTVRBNUxDQmJKMjUxYlhOMVluUnlZV04wSnl3Z0oyNTFiUzBuWFNrN1hHNGdJR3h2WTJGc1pTNWlhVzVrUzJWNVEyOWtaU2d4TVRBc0lGc25iblZ0WkdWamFXMWhiQ2NzSUNkdWRXMHVKMTBwTzF4dUlDQnNiMk5oYkdVdVltbHVaRXRsZVVOdlpHVW9NVEV4TENCYkoyNTFiV1JwZG1sa1pTY3NJQ2R1ZFcwdkoxMHBPMXh1SUNCc2IyTmhiR1V1WW1sdVpFdGxlVU52WkdVb01UUTBMQ0JiSjI1MWJXeHZZMnNuTENBbmJuVnRKMTBwTzF4dVhHNGdJQzh2SUdaMWJtTjBhVzl1SUd0bGVYTmNiaUFnYkc5allXeGxMbUpwYm1STFpYbERiMlJsS0RFeE1pd2dXeWRtTVNkZEtUdGNiaUFnYkc5allXeGxMbUpwYm1STFpYbERiMlJsS0RFeE15d2dXeWRtTWlkZEtUdGNiaUFnYkc5allXeGxMbUpwYm1STFpYbERiMlJsS0RFeE5Dd2dXeWRtTXlkZEtUdGNiaUFnYkc5allXeGxMbUpwYm1STFpYbERiMlJsS0RFeE5Td2dXeWRtTkNkZEtUdGNiaUFnYkc5allXeGxMbUpwYm1STFpYbERiMlJsS0RFeE5pd2dXeWRtTlNkZEtUdGNiaUFnYkc5allXeGxMbUpwYm1STFpYbERiMlJsS0RFeE55d2dXeWRtTmlkZEtUdGNiaUFnYkc5allXeGxMbUpwYm1STFpYbERiMlJsS0RFeE9Dd2dXeWRtTnlkZEtUdGNiaUFnYkc5allXeGxMbUpwYm1STFpYbERiMlJsS0RFeE9Td2dXeWRtT0NkZEtUdGNiaUFnYkc5allXeGxMbUpwYm1STFpYbERiMlJsS0RFeU1Dd2dXeWRtT1NkZEtUdGNiaUFnYkc5allXeGxMbUpwYm1STFpYbERiMlJsS0RFeU1Td2dXeWRtTVRBblhTazdYRzRnSUd4dlkyRnNaUzVpYVc1a1MyVjVRMjlrWlNneE1qSXNJRnNuWmpFeEoxMHBPMXh1SUNCc2IyTmhiR1V1WW1sdVpFdGxlVU52WkdVb01USXpMQ0JiSjJZeE1pZGRLVHRjYmlBZ2JHOWpZV3hsTG1KcGJtUkxaWGxEYjJSbEtERXlOQ3dnV3lkbU1UTW5YU2s3WEc0Z0lHeHZZMkZzWlM1aWFXNWtTMlY1UTI5a1pTZ3hNalVzSUZzblpqRTBKMTBwTzF4dUlDQnNiMk5oYkdVdVltbHVaRXRsZVVOdlpHVW9NVEkyTENCYkoyWXhOU2RkS1R0Y2JpQWdiRzlqWVd4bExtSnBibVJMWlhsRGIyUmxLREV5Tnl3Z1d5ZG1NVFluWFNrN1hHNGdJR3h2WTJGc1pTNWlhVzVrUzJWNVEyOWtaU2d4TWpnc0lGc25aakUzSjEwcE8xeHVJQ0JzYjJOaGJHVXVZbWx1WkV0bGVVTnZaR1VvTVRJNUxDQmJKMll4T0NkZEtUdGNiaUFnYkc5allXeGxMbUpwYm1STFpYbERiMlJsS0RFek1Dd2dXeWRtTVRrblhTazdYRzRnSUd4dlkyRnNaUzVpYVc1a1MyVjVRMjlrWlNneE16RXNJRnNuWmpJd0oxMHBPMXh1SUNCc2IyTmhiR1V1WW1sdVpFdGxlVU52WkdVb01UTXlMQ0JiSjJZeU1TZGRLVHRjYmlBZ2JHOWpZV3hsTG1KcGJtUkxaWGxEYjJSbEtERXpNeXdnV3lkbU1qSW5YU2s3WEc0Z0lHeHZZMkZzWlM1aWFXNWtTMlY1UTI5a1pTZ3hNelFzSUZzblpqSXpKMTBwTzF4dUlDQnNiMk5oYkdVdVltbHVaRXRsZVVOdlpHVW9NVE0xTENCYkoyWXlOQ2RkS1R0Y2JseHVJQ0F2THlCelpXTnZibVJoY25rZ2EyVjVJSE41YldKdmJITmNiaUFnYkc5allXeGxMbUpwYm1STllXTnlieWduYzJocFpuUWdLeUJnSnl3Z1d5ZDBhV3hrWlNjc0lDZCtKMTBwTzF4dUlDQnNiMk5oYkdVdVltbHVaRTFoWTNKdktDZHphR2xtZENBcklERW5MQ0JiSjJWNFkyeGhiV0YwYVc5dUp5d2dKMlY0WTJ4aGJXRjBhVzl1Y0c5cGJuUW5MQ0FuSVNkZEtUdGNiaUFnYkc5allXeGxMbUpwYm1STllXTnlieWduYzJocFpuUWdLeUF5Snl3Z1d5ZGhkQ2NzSUNkQUoxMHBPMXh1SUNCc2IyTmhiR1V1WW1sdVpFMWhZM0p2S0NkemFHbG1kQ0FySURNbkxDQmJKMjUxYldKbGNpY3NJQ2NqSjEwcE8xeHVJQ0JzYjJOaGJHVXVZbWx1WkUxaFkzSnZLQ2R6YUdsbWRDQXJJRFFuTENCYkoyUnZiR3hoY2ljc0lDZGtiMnhzWVhKekp5d2dKMlJ2Ykd4aGNuTnBaMjRuTENBbkpDZGRLVHRjYmlBZ2JHOWpZV3hsTG1KcGJtUk5ZV055YnlnbmMyaHBablFnS3lBMUp5d2dXeWR3WlhKalpXNTBKeXdnSnlVblhTazdYRzRnSUd4dlkyRnNaUzVpYVc1a1RXRmpjbThvSjNOb2FXWjBJQ3NnTmljc0lGc25ZMkZ5WlhRbkxDQW5YaWRkS1R0Y2JpQWdiRzlqWVd4bExtSnBibVJOWVdOeWJ5Z25jMmhwWm5RZ0t5QTNKeXdnV3lkaGJYQmxjbk5oYm1RbkxDQW5ZVzVrSnl3Z0p5WW5YU2s3WEc0Z0lHeHZZMkZzWlM1aWFXNWtUV0ZqY204b0ozTm9hV1owSUNzZ09DY3NJRnNuWVhOMFpYSnBjMnNuTENBbktpZGRLVHRjYmlBZ2JHOWpZV3hsTG1KcGJtUk5ZV055YnlnbmMyaHBablFnS3lBNUp5d2dXeWR2Y0dWdWNHRnlaVzRuTENBbktDZGRLVHRjYmlBZ2JHOWpZV3hsTG1KcGJtUk5ZV055YnlnbmMyaHBablFnS3lBd0p5d2dXeWRqYkc5elpYQmhjbVZ1Snl3Z0p5a25YU2s3WEc0Z0lHeHZZMkZzWlM1aWFXNWtUV0ZqY204b0ozTm9hV1owSUNzZ0xTY3NJRnNuZFc1a1pYSnpZMjl5WlNjc0lDZGZKMTBwTzF4dUlDQnNiMk5oYkdVdVltbHVaRTFoWTNKdktDZHphR2xtZENBcklEMG5MQ0JiSjNCc2RYTW5MQ0FuS3lkZEtUdGNiaUFnYkc5allXeGxMbUpwYm1STllXTnlieWduYzJocFpuUWdLeUJiSnl3Z1d5ZHZjR1Z1WTNWeWJIbGljbUZqWlNjc0lDZHZjR1Z1WTNWeWJIbGljbUZqYTJWMEp5d2dKM3NuWFNrN1hHNGdJR3h2WTJGc1pTNWlhVzVrVFdGamNtOG9KM05vYVdaMElDc2dYU2NzSUZzblkyeHZjMlZqZFhKc2VXSnlZV05sSnl3Z0oyTnNiM05sWTNWeWJIbGljbUZqYTJWMEp5d2dKMzBuWFNrN1hHNGdJR3h2WTJGc1pTNWlhVzVrVFdGamNtOG9KM05vYVdaMElDc2dYRnhjWENjc0lGc25kbVZ5ZEdsallXeGlZWEluTENBbmZDZGRLVHRjYmlBZ2JHOWpZV3hsTG1KcGJtUk5ZV055YnlnbmMyaHBablFnS3lBN0p5d2dXeWRqYjJ4dmJpY3NJQ2M2SjEwcE8xeHVJQ0JzYjJOaGJHVXVZbWx1WkUxaFkzSnZLQ2R6YUdsbWRDQXJJRnhjSnljc0lGc25jWFZ2ZEdGMGFXOXViV0Z5YXljc0lDZGNYQ2NuWFNrN1hHNGdJR3h2WTJGc1pTNWlhVzVrVFdGamNtOG9KM05vYVdaMElDc2dJU3duTENCYkoyOXdaVzVoYm1kc1pXSnlZV05yWlhRbkxDQW5QQ2RkS1R0Y2JpQWdiRzlqWVd4bExtSnBibVJOWVdOeWJ5Z25jMmhwWm5RZ0t5QXVKeXdnV3lkamJHOXpaV0Z1WjJ4bFluSmhZMnRsZENjc0lDYytKMTBwTzF4dUlDQnNiMk5oYkdVdVltbHVaRTFoWTNKdktDZHphR2xtZENBcklDOG5MQ0JiSjNGMVpYTjBhVzl1YldGeWF5Y3NJQ2MvSjEwcE8xeHVYRzRnSUdsbUlDaHdiR0YwWm05eWJTNXRZWFJqYUNnblRXRmpKeWtwSUh0Y2JpQWdJQ0JzYjJOaGJHVXVZbWx1WkUxaFkzSnZLQ2RqYjIxdFlXNWtKeXdnV3lkdGIyUW5MQ0FuYlc5a2FXWnBaWEluWFNrN1hHNGdJSDBnWld4elpTQjdYRzRnSUNBZ2JHOWpZV3hsTG1KcGJtUk5ZV055YnlnblkzUnliQ2NzSUZzbmJXOWtKeXdnSjIxdlpHbG1hV1Z5SjEwcE8xeHVJQ0I5WEc1Y2JpQWdMeTloTFhvZ1lXNWtJRUV0V2x4dUlDQm1iM0lnS0d4bGRDQnJaWGxEYjJSbElEMGdOalU3SUd0bGVVTnZaR1VnUEQwZ09UQTdJR3RsZVVOdlpHVWdLejBnTVNrZ2UxeHVJQ0FnSUhaaGNpQnJaWGxPWVcxbElEMGdVM1J5YVc1bkxtWnliMjFEYUdGeVEyOWtaU2hyWlhsRGIyUmxJQ3NnTXpJcE8xeHVJQ0FnSUhaaGNpQmpZWEJwZEdGc1MyVjVUbUZ0WlNBOUlGTjBjbWx1Wnk1bWNtOXRRMmhoY2tOdlpHVW9hMlY1UTI5a1pTazdYRzRnSUZ4MGJHOWpZV3hsTG1KcGJtUkxaWGxEYjJSbEtHdGxlVU52WkdVc0lHdGxlVTVoYldVcE8xeHVJQ0JjZEd4dlkyRnNaUzVpYVc1a1RXRmpjbThvSjNOb2FXWjBJQ3NnSnlBcklHdGxlVTVoYldVc0lHTmhjR2wwWVd4TFpYbE9ZVzFsS1R0Y2JpQWdYSFJzYjJOaGJHVXVZbWx1WkUxaFkzSnZLQ2RqWVhCemJHOWpheUFySUNjZ0t5QnJaWGxPWVcxbExDQmpZWEJwZEdGc1MyVjVUbUZ0WlNrN1hHNGdJSDFjYmx4dUlDQXZMeUJpY205M2MyVnlJR05oZG1WaGRITmNiaUFnWTI5dWMzUWdjMlZ0YVdOdmJHOXVTMlY1UTI5a1pTQTlJSFZ6WlhKQloyVnVkQzV0WVhSamFDZ25SbWx5WldadmVDY3BJRDhnTlRrZ0lEb2dNVGcyTzF4dUlDQmpiMjV6ZENCa1lYTm9TMlY1UTI5a1pTQWdJQ0FnSUQwZ2RYTmxja0ZuWlc1MExtMWhkR05vS0NkR2FYSmxabTk0SnlrZ1B5QXhOek1nT2lBeE9EazdYRzRnSUdOdmJuTjBJR1Z4ZFdGc1MyVjVRMjlrWlNBZ0lDQWdQU0IxYzJWeVFXZGxiblF1YldGMFkyZ29KMFpwY21WbWIzZ25LU0EvSURZeElDQTZJREU0Tnp0Y2JpQWdiR1YwSUd4bFpuUkRiMjF0WVc1a1MyVjVRMjlrWlR0Y2JpQWdiR1YwSUhKcFoyaDBRMjl0YldGdVpFdGxlVU52WkdVN1hHNGdJR2xtSUNod2JHRjBabTl5YlM1dFlYUmphQ2duVFdGakp5a2dKaVlnS0hWelpYSkJaMlZ1ZEM1dFlYUmphQ2duVTJGbVlYSnBKeWtnZkh3Z2RYTmxja0ZuWlc1MExtMWhkR05vS0NkRGFISnZiV1VuS1NrcElIdGNiaUFnSUNCc1pXWjBRMjl0YldGdVpFdGxlVU52WkdVZ0lEMGdPVEU3WEc0Z0lDQWdjbWxuYUhSRGIyMXRZVzVrUzJWNVEyOWtaU0E5SURrek8xeHVJQ0I5SUdWc2MyVWdhV1lvY0d4aGRHWnZjbTB1YldGMFkyZ29KMDFoWXljcElDWW1JSFZ6WlhKQloyVnVkQzV0WVhSamFDZ25UM0JsY21FbktTa2dlMXh1SUNBZ0lHeGxablJEYjIxdFlXNWtTMlY1UTI5a1pTQWdQU0F4Tnp0Y2JpQWdJQ0J5YVdkb2RFTnZiVzFoYm1STFpYbERiMlJsSUQwZ01UYzdYRzRnSUgwZ1pXeHpaU0JwWmlod2JHRjBabTl5YlM1dFlYUmphQ2duVFdGakp5a2dKaVlnZFhObGNrRm5aVzUwTG0xaGRHTm9LQ2RHYVhKbFptOTRKeWtwSUh0Y2JpQWdJQ0JzWldaMFEyOXRiV0Z1WkV0bGVVTnZaR1VnSUQwZ01qSTBPMXh1SUNBZ0lISnBaMmgwUTI5dGJXRnVaRXRsZVVOdlpHVWdQU0F5TWpRN1hHNGdJSDFjYmlBZ2JHOWpZV3hsTG1KcGJtUkxaWGxEYjJSbEtITmxiV2xqYjJ4dmJrdGxlVU52WkdVc0lDQWdJRnNuYzJWdGFXTnZiRzl1Snl3Z0p6c25YU2s3WEc0Z0lHeHZZMkZzWlM1aWFXNWtTMlY1UTI5a1pTaGtZWE5vUzJWNVEyOWtaU3dnSUNBZ0lDQWdJQ0JiSjJSaGMyZ25MQ0FuTFNkZEtUdGNiaUFnYkc5allXeGxMbUpwYm1STFpYbERiMlJsS0dWeGRXRnNTMlY1UTI5a1pTd2dJQ0FnSUNBZ0lGc25aWEYxWVd3bkxDQW5aWEYxWVd4emFXZHVKeXdnSnowblhTazdYRzRnSUd4dlkyRnNaUzVpYVc1a1MyVjVRMjlrWlNoc1pXWjBRMjl0YldGdVpFdGxlVU52WkdVc0lDQmJKMk52YlcxaGJtUW5MQ0FuZDJsdVpHOTNjeWNzSUNkM2FXNG5MQ0FuYzNWd1pYSW5MQ0FuYkdWbWRHTnZiVzFoYm1RbkxDQW5iR1ZtZEhkcGJtUnZkM01uTENBbmJHVm1kSGRwYmljc0lDZHNaV1owYzNWd1pYSW5YU2s3WEc0Z0lHeHZZMkZzWlM1aWFXNWtTMlY1UTI5a1pTaHlhV2RvZEVOdmJXMWhibVJMWlhsRGIyUmxMQ0JiSjJOdmJXMWhibVFuTENBbmQybHVaRzkzY3ljc0lDZDNhVzRuTENBbmMzVndaWEluTENBbmNtbG5hSFJqYjIxdFlXNWtKeXdnSjNKcFoyaDBkMmx1Wkc5M2N5Y3NJQ2R5YVdkb2RIZHBiaWNzSUNkeWFXZG9kSE4xY0dWeUoxMHBPMXh1WEc0Z0lDOHZJR3RwYkd3Z2EyVjVjMXh1SUNCc2IyTmhiR1V1YzJWMFMybHNiRXRsZVNnblkyOXRiV0Z1WkNjcE8xeHVmVHRjYmlJc0ltbHRjRzl5ZENCN0lFdGxlV0p2WVhKa0lIMGdabkp2YlNBbkxpOXNhV0l2YTJWNVltOWhjbVFuTzF4dWFXMXdiM0owSUhzZ1RHOWpZV3hsSUgwZ1puSnZiU0FuTGk5c2FXSXZiRzlqWVd4bEp6dGNibWx0Y0c5eWRDQjdJRXRsZVVOdmJXSnZJSDBnWm5KdmJTQW5MaTlzYVdJdmEyVjVMV052YldKdkp6dGNibWx0Y0c5eWRDQjdJSFZ6SUgwZ1puSnZiU0FuTGk5c2IyTmhiR1Z6TDNWekp6dGNibHh1WTI5dWMzUWdhMlY1WW05aGNtUWdQU0J1WlhjZ1MyVjVZbTloY21Rb0tUdGNibHh1YTJWNVltOWhjbVF1YzJWMFRHOWpZV3hsS0NkMWN5Y3NJSFZ6S1R0Y2JseHVhMlY1WW05aGNtUXVTMlY1WW05aGNtUWdQU0JMWlhsaWIyRnlaRHRjYm10bGVXSnZZWEprTGt4dlkyRnNaU0E5SUV4dlkyRnNaVHRjYm10bGVXSnZZWEprTGt0bGVVTnZiV0p2SUQwZ1MyVjVRMjl0WW04N1hHNWNibVY0Y0c5eWRDQmtaV1poZFd4MElHdGxlV0p2WVhKa08xeHVJbDBzSW01aGJXVnpJanBiSWt0bGVVTnZiV0p2SWl3aWEyVjVRMjl0WW05VGRISWlMQ0p6YjNWeVkyVlRkSElpTENKemRXSkRiMjFpYjNNaUxDSndZWEp6WlVOdmJXSnZVM1J5SWl3aWEyVjVUbUZ0WlhNaUxDSnlaV1IxWTJVaUxDSnRaVzF2SWl3aWJtVjRkRk4xWWtOdmJXSnZJaXdpWTI5dVkyRjBJaXdpY0hKbGMzTmxaRXRsZVU1aGJXVnpJaXdpYzNSaGNuUnBibWRMWlhsT1lXMWxTVzVrWlhnaUxDSnBJaXdpYkdWdVozUm9JaXdpWDJOb1pXTnJVM1ZpUTI5dFltOGlMQ0p2ZEdobGNrdGxlVU52YldKdklpd2ljM1ZpUTI5dFltOGlMQ0p2ZEdobGNsTjFZa052YldKdklpd2ljMnhwWTJVaUxDSnFJaXdpYTJWNVRtRnRaU0lzSW1sdVpHVjRJaXdpYVc1a1pYaFBaaUlzSW5Od2JHbGpaU0lzSW1WdVpFbHVaR1Y0SWl3aVpYTmpZWEJsWkV0bGVVNWhiV1VpTENKamIyMWliMFJsYkdsdGFXNWhkRzl5SWl3aWEyVjVSR1ZzYVcxcGJtRjBiM0lpTENKemRXSkRiMjFpYjFOMGNuTWlMQ0pmYzNCc2FYUlRkSElpTENKamIyMWlieUlzSW5CMWMyZ2lMQ0p6ZEhJaUxDSmtaV3hwYldsdVlYUnZjaUlzSW5NaUxDSmtJaXdpWXlJc0ltTmhJaXdpWTJraUxDSjBjbWx0SWl3aVRHOWpZV3hsSWl3aWJtRnRaU0lzSW14dlkyRnNaVTVoYldVaUxDSmhZM1JwZG1WVVlYSm5aWFJMWlhseklpd2ljSEpsYzNObFpFdGxlWE1pTENKZllYQndiR2xsWkUxaFkzSnZjeUlzSWw5clpYbE5ZWEFpTENKZmEybHNiRXRsZVVOdlpHVnpJaXdpWDIxaFkzSnZjeUlzSW10bGVVTnZaR1VpTENKb1lXNWtiR1Z5SWl3aWJXRmpjbThpTENKclpYbERiMjFpYnlJc0ltdGxlVU52WkdWeklpd2laMlYwUzJWNVEyOWtaWE1pTENKelpYUkxhV3hzUzJWNUlpd2ljSEpsYzNOTFpYa2lMQ0puWlhSTFpYbE9ZVzFsY3lJc0lsOWhjSEJzZVUxaFkzSnZjeUlzSW5KbGJHVmhjMlZMWlhraUxDSnJhV3hzUzJWNVEyOWtaVWx1WkdWNElpd2lYMk5zWldGeVRXRmpjbTl6SWl3aWJXRmpjbTl6SWl3aVkyaGxZMnNpTENKTFpYbGliMkZ5WkNJc0luUmhjbWRsZEZkcGJtUnZkeUlzSW5SaGNtZGxkRVZzWlcxbGJuUWlMQ0owWVhKblpYUlFiR0YwWm05eWJTSXNJblJoY21kbGRGVnpaWEpCWjJWdWRDSXNJbDlzYjJOaGJHVWlMQ0pmWTNWeWNtVnVkRU52Ym5SbGVIUWlMQ0pmWTI5dWRHVjRkSE1pTENKZmJHbHpkR1Z1WlhKeklpd2lYMkZ3Y0d4cFpXUk1hWE4wWlc1bGNuTWlMQ0pmYkc5allXeGxjeUlzSWw5MFlYSm5aWFJGYkdWdFpXNTBJaXdpWDNSaGNtZGxkRmRwYm1SdmR5SXNJbDkwWVhKblpYUlFiR0YwWm05eWJTSXNJbDkwWVhKblpYUlZjMlZ5UVdkbGJuUWlMQ0pmYVhOTmIyUmxjbTVDY205M2MyVnlJaXdpWDNSaGNtZGxkRXRsZVVSdmQyNUNhVzVrYVc1bklpd2lYM1JoY21kbGRFdGxlVlZ3UW1sdVpHbHVaeUlzSWw5MFlYSm5aWFJTWlhObGRFSnBibVJwYm1jaUxDSmZjR0YxYzJWa0lpd2laMnh2WW1Gc0lpd2liR2x6ZEdWdVpYSnpJaXdpYzJWMFEyOXVkR1Y0ZENJc0lteHZZMkZzWlVKMWFXeGtaWElpTENKc2IyTmhiR1VpTENKZmJHOWpZV3hsVG1GdFpTSXNJbXh2WTJGc1RtRnRaU0lzSW5CeVpYTnpTR0Z1Wkd4bGNpSXNJbkpsYkdWaGMyVklZVzVrYkdWeUlpd2ljSEpsZG1WdWRGSmxjR1ZoZEVKNVJHVm1ZWFZzZENJc0ltSnBibVFpTENKd2NtVjJaVzUwVW1Wd1pXRjBJaXdpWlhobFkzVjBhVzVuU0dGdVpHeGxjaUlzSW5WdVltbHVaQ0lzSW14cGMzUmxibVZ5SWl3aVkyOXRZbTlOWVhSamFHVnpJaXdpYVhORmNYVmhiQ0lzSW5CeVpYTnpTR0Z1Wkd4bGNrMWhkR05vWlhNaUxDSnlaV3hsWVhObFNHRnVaR3hsY2sxaGRHTm9aWE1pTENKamIyNTBaWGgwVG1GdFpTSXNJbkpsYkdWaGMyVkJiR3hMWlhseklpd2laMnh2WW1Gc1EyOXVkR1Y0ZENJc0ltTnZiblJsZUhRaUxDSnpkRzl3SWl3aWQyRjBZMmdpTENKallXeHNZbUZqYXlJc0luQnlaWFpwYjNWelEyOXVkR1Y0ZEU1aGJXVWlMQ0puWlhSRGIyNTBaWGgwSWl3aWQybHVJaXdpWjJ4dlltRnNWR2hwY3lJc0luZHBibVJ2ZHlJc0ltRmtaRVYyWlc1MFRHbHpkR1Z1WlhJaUxDSmhkSFJoWTJoRmRtVnVkQ0lzSWtWeWNtOXlJaXdpYm05a1pWUjVjR1VpTENKMWMyVnlRV2RsYm5RaUxDSnVZWFpwWjJGMGIzSWlMQ0p3YkdGMFptOXliU0lzSW1SdlkzVnRaVzUwSWl3aVpYWmxiblFpTENKZmFHRnVaR3hsUTI5dGJXRnVaRUoxWnlJc0lsOWlhVzVrUlhabGJuUWlMQ0pqZFhKeVpXNTBRMjl1ZEdWNGRDSXNJbDkxYm1KcGJtUkZkbVZ1ZENJc0lsOWhjSEJzZVVKcGJtUnBibWR6SWl3aVgyTnNaV0Z5UW1sdVpHbHVaM01pTENKbGRtVnVkRTVoYldVaUxDSnlaVzF2ZG1WRmRtVnVkRXhwYzNSbGJtVnlJaXdpWkdWMFlXTm9SWFpsYm5RaUxDSnNhWE4wWlc1bGNrZHliM1Z3Y3lJc0lteHBjM1JsYm1WeVIzSnZkWEJOWVhBaUxDSnpiM0owSWl3aVlTSXNJbUlpTENKbWIzSkZZV05vSWl3aWJDSXNJbTFoY0VsdVpHVjRJaXdpWDJkbGRFZHliM1Z3WldSTWFYTjBaVzVsY25NaUxDSnpiMjFsSWl3aWF5SXNJbWx1WTJ4MVpHVnpJaXdpWTJGc2JDSXNJbTF2WkdsbWFXVnlTMlY1Y3lJc0ltMWhkR05vSWl3aWRYTWlMQ0ppYVc1a1MyVjVRMjlrWlNJc0ltSnBibVJOWVdOeWJ5SXNJbE4wY21sdVp5SXNJbVp5YjIxRGFHRnlRMjlrWlNJc0ltTmhjR2wwWVd4TFpYbE9ZVzFsSWl3aWMyVnRhV052Ykc5dVMyVjVRMjlrWlNJc0ltUmhjMmhMWlhsRGIyUmxJaXdpWlhGMVlXeExaWGxEYjJSbElpd2liR1ZtZEVOdmJXMWhibVJMWlhsRGIyUmxJaXdpY21sbmFIUkRiMjF0WVc1a1MyVjVRMjlrWlNJc0ltdGxlV0p2WVhKa0lpd2ljMlYwVEc5allXeGxJbDBzSW0xaGNIQnBibWR6SWpvaU96czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenM3T3pzN096czdPenROUVVOaFFTeFJRVUZpTzBWQlEwVXNiMEpCUVZsRExGZEJRVm9zUlVGQmVVSTdSVUZCUVRzN1JVRkRka0lzVTBGQlMwTXNVMEZCVEN4SFFVRnBRa1FzVjBGQmFrSTdSVUZEUVN4VFFVRkxSU3hUUVVGTUxFZEJRV2xDU0N4UlFVRlJMRU5CUVVOSkxHRkJRVlFzUTBGQmRVSklMRmRCUVhaQ0xFTkJRV3BDTzBWQlEwRXNVMEZCUzBrc1VVRkJUQ3hIUVVGcFFpeExRVUZMUml4VFFVRk1MRU5CUVdWSExFMUJRV1lzUTBGQmMwSXNWVUZCUTBNc1NVRkJSQ3hGUVVGUFF5eFpRVUZRTzBWQlFVRXNZVUZEY2tORUxFbEJRVWtzUTBGQlEwVXNUVUZCVEN4RFFVRlpSQ3haUVVGYUxFTkJSSEZETzBWQlFVRXNTMEZCZEVJc1JVRkRXU3hGUVVSYUxFTkJRV3BDTzBWQlJVUTdPMFZCVGtnN1JVRkJRVHRGUVVGQkxEQkNRVkZSUlN4bFFWSlNMRVZCVVhsQ08wVkJRM0pDTEZWQlFVbERMRzlDUVVGdlFpeEhRVUZITEVOQlFUTkNPenRGUVVOQkxGZEJRVXNzU1VGQlNVTXNRMEZCUXl4SFFVRkhMRU5CUVdJc1JVRkJaMEpCTEVOQlFVTXNSMEZCUnl4TFFVRkxWQ3hUUVVGTUxFTkJRV1ZWTEUxQlFXNURMRVZCUVRKRFJDeERRVUZETEVsQlFVa3NRMEZCYUVRc1JVRkJiVVE3UlVGRGFrUkVMRkZCUVVGQkxHOUNRVUZ2UWl4SFFVRkhMRXRCUVV0SExHTkJRVXdzUTBGRGNrSXNTMEZCUzFnc1UwRkJUQ3hEUVVGbFV5eERRVUZtTEVOQlJIRkNMRVZCUlhKQ1JDeHZRa0ZHY1VJc1JVRkhja0pFTEdWQlNIRkNMRU5CUVhaQ096dEZRVXRCTEZsQlFVbERMRzlDUVVGdlFpeExRVUZMTEVOQlFVTXNRMEZCT1VJc1JVRkJhVU03UlVGQlJTeHBRa0ZCVHl4TFFVRlFPMFZCUVdVN1JVRkRia1E3TzBWQlEwUXNZVUZCVHl4SlFVRlFPMFZCUTBRN1JVRnVRa2c3UlVGQlFUdEZRVUZCTERSQ1FYRkNWVWtzWVVGeVFsWXNSVUZ4UW5sQ08wVkJRM0pDTEZWQlEwVXNRMEZCUTBFc1lVRkJSQ3hKUVVOQkxFOUJRVTlCTEdGQlFWQXNTMEZCZVVJc1VVRkJla0lzU1VGRFFTeFJRVUZQUVN4aFFVRlFMRTFCUVhsQ0xGRkJTRE5DTEVWQlNVVTdSVUZCUlN4bFFVRlBMRXRCUVZBN1JVRkJaVHM3UlVGRmJrSXNWVUZCU1N4UFFVRlBRU3hoUVVGUUxFdEJRWGxDTEZGQlFUZENMRVZCUVhWRE8wVkJRM0pEUVN4UlFVRkJRU3hoUVVGaExFZEJRVWNzU1VGQlNXWXNVVUZCU2l4RFFVRmhaU3hoUVVGaUxFTkJRV2hDTzBWQlEwUTdPMFZCUlVRc1ZVRkJTU3hMUVVGTFdpeFRRVUZNTEVOQlFXVlZMRTFCUVdZc1MwRkJNRUpGTEdGQlFXRXNRMEZCUTFvc1UwRkJaQ3hEUVVGM1FsVXNUVUZCZEVRc1JVRkJPRVE3UlVGRE5VUXNaVUZCVHl4TFFVRlFPMFZCUTBRN08wVkJRMFFzVjBGQlN5eEpRVUZKUkN4RFFVRkRMRWRCUVVjc1EwRkJZaXhGUVVGblFrRXNRMEZCUXl4SFFVRkhMRXRCUVV0VUxGTkJRVXdzUTBGQlpWVXNUVUZCYmtNc1JVRkJNa05FTEVOQlFVTXNTVUZCU1N4RFFVRm9SQ3hGUVVGdFJEdEZRVU5xUkN4WlFVRkpMRXRCUVV0VUxGTkJRVXdzUTBGQlpWTXNRMEZCWml4RlFVRnJRa01zVFVGQmJFSXNTMEZCTmtKRkxHRkJRV0VzUTBGQlExb3NVMEZCWkN4RFFVRjNRbE1zUTBGQmVFSXNSVUZCTWtKRExFMUJRVFZFTEVWQlFXOUZPMFZCUTJ4RkxHbENRVUZQTEV0QlFWQTdSVUZEUkR0RlFVTkdPenRGUVVWRUxGZEJRVXNzU1VGQlNVUXNSVUZCUXl4SFFVRkhMRU5CUVdJc1JVRkJaMEpCTEVWQlFVTXNSMEZCUnl4TFFVRkxWQ3hUUVVGTUxFTkJRV1ZWTEUxQlFXNURMRVZCUVRKRFJDeEZRVUZETEVsQlFVa3NRMEZCYUVRc1JVRkJiVVE3UlVGRGFrUXNXVUZCVFVrc1VVRkJVU3hIUVVGUkxFdEJRVXRpTEZOQlFVd3NRMEZCWlZNc1JVRkJaaXhEUVVGMFFqczdSVUZEUVN4WlFVRk5TeXhoUVVGaExFZEJRVWRHTEdGQlFXRXNRMEZCUTFvc1UwRkJaQ3hEUVVGM1FsTXNSVUZCZUVJc1JVRkJNa0pOTEV0QlFUTkNMRU5CUVdsRExFTkJRV3BETEVOQlFYUkNPenRGUVVWQkxHRkJRVXNzU1VGQlNVTXNRMEZCUXl4SFFVRkhMRU5CUVdJc1JVRkJaMEpCTEVOQlFVTXNSMEZCUjBnc1VVRkJVU3hEUVVGRFNDeE5RVUUzUWl4RlFVRnhRMDBzUTBGQlF5eEpRVUZKTEVOQlFURkRMRVZCUVRaRE8wVkJRek5ETEdOQlFVMURMRTlCUVU4c1IwRkJSMG9zVVVGQlVTeERRVUZEUnl4RFFVRkVMRU5CUVhoQ08wVkJRMEVzWTBGQlRVVXNTMEZCU3l4SFFVRkxTaXhoUVVGaExFTkJRVU5MTEU5QlFXUXNRMEZCYzBKR0xFOUJRWFJDTEVOQlFXaENPenRGUVVWQkxHTkJRVWxETEV0QlFVc3NSMEZCUnl4RFFVRkRMRU5CUVdJc1JVRkJaMEk3UlVGRFpFb3NXVUZCUVVFc1lVRkJZU3hEUVVGRFRTeE5RVUZrTEVOQlFYRkNSaXhMUVVGeVFpeEZRVUUwUWl4RFFVRTFRanRGUVVORU8wVkJRMFk3TzBWQlEwUXNXVUZCU1Vvc1lVRkJZU3hEUVVGRFNpeE5RVUZrTEV0QlFYbENMRU5CUVRkQ0xFVkJRV2RETzBWQlF6bENMR2xDUVVGUExFdEJRVkE3UlVGRFJEdEZRVU5HT3p0RlFVVkVMR0ZCUVU4c1NVRkJVRHRGUVVORU8wVkJNMFJJTzBWQlFVRTdSVUZCUVN4dFEwRTJSR2xDUnl4UlFUZEVha0lzUlVFMlJESkNUQ3h2UWtFM1JETkNMRVZCTmtScFJFUXNaVUUzUkdwRUxFVkJOa1JyUlR0RlFVTTVSRTBzVFVGQlFVRXNVVUZCVVN4SFFVRkhRU3hSUVVGUkxFTkJRVU5GTEV0QlFWUXNRMEZCWlN4RFFVRm1MRU5CUVZnN1JVRkRRVklzVFVGQlFVRXNaVUZCWlN4SFFVRkhRU3hsUVVGbExFTkJRVU5STEV0QlFXaENMRU5CUVhOQ1VDeHZRa0ZCZEVJc1EwRkJiRUk3UlVGRlFTeFZRVUZKWVN4UlFVRlJMRWRCUVVkaUxHOUNRVUZtT3p0RlFVTkJMRmRCUVVzc1NVRkJTVU1zUTBGQlF5eEhRVUZITEVOQlFXSXNSVUZCWjBKQkxFTkJRVU1zUjBGQlIwa3NVVUZCVVN4RFFVRkRTQ3hOUVVFM1FpeEZRVUZ4UTBRc1EwRkJReXhKUVVGSkxFTkJRVEZETEVWQlFUWkRPMFZCUlRORExGbEJRVWxSTEU5QlFVOHNSMEZCUjBvc1VVRkJVU3hEUVVGRFNpeERRVUZFTEVOQlFYUkNPenRGUVVOQkxGbEJRVWxSTEU5QlFVOHNRMEZCUXl4RFFVRkVMRU5CUVZBc1MwRkJaU3hKUVVGdVFpeEZRVUY1UWp0RlFVTjJRaXhqUVVGTlN5eGpRVUZqTEVkQlFVZE1MRTlCUVU4c1EwRkJRMFlzUzBGQlVpeERRVUZqTEVOQlFXUXNRMEZCZGtJN08wVkJRMEVzWTBGRFJVOHNZMEZCWXl4TFFVRkxla0lzVVVGQlVTeERRVUZETUVJc1owSkJRVFZDTEVsQlEwRkVMR05CUVdNc1MwRkJTM3BDTEZGQlFWRXNRMEZCUXpKQ0xHTkJSamxDTEVWQlIwVTdSVUZEUVZBc1dVRkJRVUVzVDBGQlR5eEhRVUZIU3l4alFVRldPMFZCUTBRN1JVRkRSanM3UlVGRlJDeFpRVUZOU2l4TFFVRkxMRWRCUVVkWUxHVkJRV1VzUTBGQlExa3NUMEZCYUVJc1EwRkJkMEpHTEU5QlFYaENMRU5CUVdRN08wVkJRMEVzV1VGQlNVTXNTMEZCU3l4SFFVRkhMRU5CUVVNc1EwRkJZaXhGUVVGblFqdEZRVU5rVEN4VlFVRkJRU3hSUVVGUkxFTkJRVU5QTEUxQlFWUXNRMEZCWjBKWUxFTkJRV2hDTEVWQlFXMUNMRU5CUVc1Q08wVkJRMEZCTEZWQlFVRkJMRU5CUVVNc1NVRkJTU3hEUVVGTU96dEZRVU5CTEdOQlFVbFRMRXRCUVVzc1IwRkJSMGNzVVVGQldpeEZRVUZ6UWp0RlFVTndRa0VzV1VGQlFVRXNVVUZCVVN4SFFVRkhTQ3hMUVVGWU8wVkJRMFE3TzBWQlEwUXNZMEZCU1V3c1VVRkJVU3hEUVVGRFNDeE5RVUZVTEV0QlFXOUNMRU5CUVhoQ0xFVkJRVEpDTzBWQlEzcENMRzFDUVVGUFZ5eFJRVUZRTzBWQlEwUTdSVUZEUmp0RlFVTkdPenRGUVVORUxHRkJRVThzUTBGQlF5eERRVUZTTzBWQlEwUTdSVUUxUmtnN08wVkJRVUU3UlVGQlFUdEZRU3RHUVhoQ0xGRkJRVkVzUTBGQlF6QkNMR2RDUVVGVUxFZEJRVFJDTEVkQlFUVkNPMFZCUTBFeFFpeFJRVUZSTEVOQlFVTXlRaXhqUVVGVUxFZEJRVFJDTEVkQlFUVkNPenRGUVVWQk0wSXNVVUZCVVN4RFFVRkRTU3hoUVVGVUxFZEJRWGxDTEZWQlFWTklMRmRCUVZRc1JVRkJjMEk3UlVGRE4wTXNUVUZCVFRKQ0xGbEJRVmtzUjBGQlJ6VkNMRkZCUVZFc1EwRkJRelpDTEZOQlFWUXNRMEZCYlVJMVFpeFhRVUZ1UWl4RlFVRm5RMFFzVVVGQlVTeERRVUZETUVJc1owSkJRWHBETEVOQlFYSkNPenRGUVVOQkxFMUJRVTFKTEV0QlFVc3NSMEZCVlN4RlFVRnlRanM3UlVGRlFTeFBRVUZMTEVsQlFVbHNRaXhEUVVGRExFZEJRVWNzUTBGQllpeEZRVUZwUWtFc1EwRkJReXhIUVVGSFowSXNXVUZCV1N4RFFVRkRaaXhOUVVGc1F5eEZRVUV3UTBRc1EwRkJReXhKUVVGSkxFTkJRUzlETEVWQlFXdEVPMFZCUTJoRWEwSXNTVUZCUVVFc1MwRkJTeXhEUVVGRFF5eEpRVUZPTEVOQlFWY3ZRaXhSUVVGUkxFTkJRVU0yUWl4VFFVRlVMRU5CUVcxQ1JDeFpRVUZaTEVOQlFVTm9RaXhEUVVGRUxFTkJRUzlDTEVWQlFXOURXaXhSUVVGUkxFTkJRVU15UWl4alFVRTNReXhEUVVGWU8wVkJRMFE3TzBWQlEwUXNVMEZCVDBjc1MwRkJVRHRGUVVORUxFTkJVa1E3TzBWQlZVRTVRaXhSUVVGUkxFTkJRVU0yUWl4VFFVRlVMRWRCUVhGQ0xGVkJRVk5ITEVkQlFWUXNSVUZCWTBNc1YwRkJaQ3hGUVVFeVFqdEZRVU01UXl4TlFVRk5ReXhEUVVGRExFZEJRVWxHTEVkQlFWZzdSVUZEUVN4TlFVRk5SeXhEUVVGRExFZEJRVWxHTEZkQlFWZzdSVUZEUVN4TlFVRkpSeXhEUVVGRExFZEJRVWtzUlVGQlZEdEZRVU5CTEUxQlFVMURMRVZCUVVVc1IwRkJSeXhGUVVGWU96dEZRVVZCTEU5QlFVc3NTVUZCU1VNc1JVRkJSU3hIUVVGSExFTkJRV1FzUlVGQmFVSkJMRVZCUVVVc1IwRkJSMG9zUTBGQlF5eERRVUZEY2tJc1RVRkJlRUlzUlVGQlowTjVRaXhGUVVGRkxFbEJRVWtzUTBGQmRFTXNSVUZCZVVNN1JVRkRka01zVVVGQlNVRXNSVUZCUlN4SFFVRkhMRU5CUVV3c1NVRkJWVW9zUTBGQlF5eERRVUZEU1N4RlFVRkVMRU5CUVVRc1MwRkJWVWdzUTBGQmNFSXNTVUZCZVVKRUxFTkJRVU1zUTBGQlEwa3NSVUZCUlN4SFFVRkhMRU5CUVU0c1EwRkJSQ3hMUVVGakxFbEJRVE5ETEVWQlFXbEVPMFZCUXk5RFJDeE5RVUZCUVN4RlFVRkZMRU5CUVVOT0xFbEJRVWdzUTBGQlVVc3NRMEZCUXl4RFFVRkRSeXhKUVVGR0xFVkJRVkk3UlVGRFFVZ3NUVUZCUVVFc1EwRkJReXhIUVVGSExFVkJRVW83UlVGRFFVVXNUVUZCUVVFc1JVRkJSU3hKUVVGSkxFTkJRVTQ3UlVGRFJEczdSVUZEUkVZc1NVRkJRVUVzUTBGQlF5eEpRVUZKUml4RFFVRkRMRU5CUVVOSkxFVkJRVVFzUTBGQlRqdEZRVU5FT3p0RlFVTkVMRTFCUVVsR0xFTkJRVW9zUlVGQlR6dEZRVUZGUXl4SlFVRkJRU3hGUVVGRkxFTkJRVU5PTEVsQlFVZ3NRMEZCVVVzc1EwRkJReXhEUVVGRFJ5eEpRVUZHTEVWQlFWSTdSVUZCYjBJN08wVkJSVGRDTEZOQlFVOUdMRVZCUVZBN1JVRkRSQ3hEUVdwQ1JEczdUVU14UjJGSExFMUJRV0k3UlVGRFJTeHJRa0ZCV1VNc1NVRkJXaXhGUVVGclFqdEZRVUZCT3p0RlFVTm9RaXhUUVVGTFF5eFZRVUZNTEVkQlFUSkNSQ3hKUVVFelFqdEZRVU5CTEZOQlFVdEZMR2RDUVVGTUxFZEJRWGRDTEVWQlFYaENPMFZCUTBFc1UwRkJTME1zVjBGQlRDeEhRVUV5UWl4RlFVRXpRanRGUVVOQkxGTkJRVXRETEdOQlFVd3NSMEZCTWtJc1JVRkJNMEk3UlVGRFFTeFRRVUZMUXl4UFFVRk1MRWRCUVRKQ0xFVkJRVE5DTzBWQlEwRXNVMEZCUzBNc1lVRkJUQ3hIUVVFeVFpeEZRVUV6UWp0RlFVTkJMRk5CUVV0RExFOUJRVXdzUjBGQk1rSXNSVUZCTTBJN1JVRkRSRHM3UlVGVVNEdEZRVUZCTzBWQlFVRXNaME5CVjJORExFOUJXR1FzUlVGWGRVSTFReXhSUVZoMlFpeEZRVmRwUXp0RlFVTTNRaXhWUVVGSkxFOUJRVTlCTEZGQlFWQXNTMEZCYjBJc1VVRkJlRUlzUlVGQmEwTTdSVUZEYUVOQkxGRkJRVUZCTEZGQlFWRXNSMEZCUnl4RFFVRkRRU3hSUVVGRUxFTkJRVmc3UlVGRFJEczdSVUZGUkN4WFFVRkxlVU1zVDBGQlRDeERRVUZoUnl4UFFVRmlMRWxCUVhkQ05VTXNVVUZCZUVJN1JVRkRSRHRGUVdwQ1NEdEZRVUZCTzBWQlFVRXNPRUpCYlVKWlNpeFhRVzVDV2l4RlFXMUNlVUpKTEZGQmJrSjZRaXhGUVcxQ2JVTTdSVUZETDBJc1ZVRkJTU3hQUVVGUFFTeFJRVUZRTEV0QlFXOUNMRkZCUVhoQ0xFVkJRV3RETzBWQlEyaERRU3hSUVVGQlFTeFJRVUZSTEVkQlFVY3NRMEZCUlVFc1VVRkJSaXhEUVVGWU8wVkJRMFE3TzBWQlJVUXNWVUZCU1RaRExFOUJRVThzUjBGQlJ5eEpRVUZrT3p0RlFVTkJMRlZCUVVrc1QwRkJUemRETEZGQlFWQXNTMEZCYjBJc1ZVRkJlRUlzUlVGQmIwTTdSVUZEYkVNMlF5eFJRVUZCUVN4UFFVRlBMRWRCUVVjM1F5eFJRVUZXTzBWQlEwRkJMRkZCUVVGQkxGRkJRVkVzUjBGQlJ5eEpRVUZZTzBWQlEwUTdPMFZCUlVRc1ZVRkJUVGhETEV0QlFVc3NSMEZCUnp0RlFVTmFReXhSUVVGQlFTeFJRVUZSTEVWQlFVY3NTVUZCU1hCRUxGRkJRVW9zUTBGQllVTXNWMEZCWWl4RFFVUkRPMFZCUlZwSkxGRkJRVUZCTEZGQlFWRXNSVUZCUjBFc1VVRkdRenRGUVVkYU5rTXNVVUZCUVVFc1QwRkJUeXhGUVVGSlFUdEZRVWhETEU5QlFXUTdPMFZCVFVFc1YwRkJTMFlzVDBGQlRDeERRVUZoYWtJc1NVRkJZaXhEUVVGclFtOUNMRXRCUVd4Q08wVkJRMFE3UlVGeVEwZzdSVUZCUVR0RlFVRkJMR2REUVhWRFl5OUNMRTlCZGtOa0xFVkJkVU4xUWp0RlFVTnVRaXhWUVVGTmFVTXNVVUZCVVN4SFFVRkhMRVZCUVdwQ096dEZRVU5CTEZkQlFVc3NTVUZCVFVvc1QwRkJXQ3hKUVVGelFpeExRVUZMU0N4UFFVRXpRaXhGUVVGdlF6dEZRVU5zUXl4WlFVRk5la0lzUzBGQlN5eEhRVUZITEV0QlFVdDVRaXhQUVVGTUxFTkJRV0ZITEU5QlFXSXNSVUZCYzBJelFpeFBRVUYwUWl4RFFVRTRRa1lzVDBGQk9VSXNRMEZCWkRzN1JVRkRRU3haUVVGSlF5eExRVUZMTEVkQlFVY3NRMEZCUXl4RFFVRmlMRVZCUVdkQ08wVkJRVVZuUXl4VlFVRkJRU3hSUVVGUkxFTkJRVU4wUWl4SlFVRlVMRU5CUVdOclFpeFBRVUZQTEVkQlFVTXNRMEZCZEVJN1JVRkJNa0k3UlVGRE9VTTdPMFZCUTBRc1lVRkJUMGtzVVVGQlVEdEZRVU5FTzBWQk9VTklPMFZCUVVFN1JVRkJRU3huUTBGblJHTktMRTlCYUVSa0xFVkJaMFIxUWp0RlFVTnVRaXhoUVVGUExFdEJRVXRJTEU5QlFVd3NRMEZCWVVjc1QwRkJZaXhMUVVGNVFpeEZRVUZvUXp0RlFVTkVPMFZCYkVSSU8wVkJRVUU3UlVGQlFTd3JRa0Z2UkdGQkxFOUJjRVJpTEVWQmIwUnpRanRGUVVOc1FpeFZRVUZKTEU5QlFVOUJMRTlCUVZBc1MwRkJiVUlzVVVGQmRrSXNSVUZCYVVNN1JVRkRMMElzV1VGQlRVa3NVVUZCVVN4SFFVRkhMRXRCUVV0RExGZEJRVXdzUTBGQmFVSk1MRTlCUVdwQ0xFTkJRV3BDT3p0RlFVTkJMR0ZCUVVzc1NVRkJTWEpETEVOQlFVTXNSMEZCUnl4RFFVRmlMRVZCUVdkQ1FTeERRVUZETEVkQlFVZDVReXhSUVVGUkxFTkJRVU40UXl4TlFVRTNRaXhGUVVGeFEwUXNRMEZCUXl4SlFVRkpMRU5CUVRGRExFVkJRVFpETzBWQlF6TkRMR1ZCUVVzeVF5eFZRVUZNTEVOQlFXZENSaXhSUVVGUkxFTkJRVU42UXl4RFFVRkVMRU5CUVhoQ08wVkJRMFE3TzBWQlEwUTdSVUZEUkRzN1JVRkZSQ3hYUVVGTGJVTXNZVUZCVEN4RFFVRnRRbWhDTEVsQlFXNUNMRU5CUVhkQ2EwSXNUMEZCZUVJN1JVRkRSRHRGUVRsRVNEdEZRVUZCTzBWQlFVRXNOa0pCWjBWWFFTeFBRV2hGV0N4RlFXZEZiMEk3UlVGRGFFSXNWVUZCU1N4UFFVRlBRU3hQUVVGUUxFdEJRVzFDTEZGQlFYWkNMRVZCUVdsRE8wVkJReTlDTEZsQlFVMUpMRkZCUVZFc1IwRkJSeXhMUVVGTFF5eFhRVUZNTEVOQlFXbENUQ3hQUVVGcVFpeERRVUZxUWpzN1JVRkRRU3hoUVVGTExFbEJRVWx5UXl4RFFVRkRMRWRCUVVjc1EwRkJZaXhGUVVGblFrRXNRMEZCUXl4SFFVRkhlVU1zVVVGQlVTeERRVUZEZUVNc1RVRkJOMElzUlVGQmNVTkVMRU5CUVVNc1NVRkJTU3hEUVVFeFF5eEZRVUUyUXp0RlFVTXpReXhsUVVGTE5FTXNVVUZCVEN4RFFVRmpTQ3hSUVVGUkxFTkJRVU42UXl4RFFVRkVMRU5CUVhSQ08wVkJRMFE3TzBWQlEwUTdSVUZEUkRzN1JVRkZSQ3hYUVVGTEswSXNaMEpCUVV3c1EwRkJjMEk1UWl4TlFVRjBRaXhIUVVFclFpeERRVUV2UWp0RlFVTkJMRlZCUVUxU0xGRkJRVkVzUjBGQlJ5eExRVUZMYjBRc1YwRkJUQ3hEUVVGcFFsSXNUMEZCYWtJc1EwRkJha0k3TzBWQlEwRXNWMEZCU3l4SlFVRkpja01zUlVGQlF5eEhRVUZITEVOQlFXSXNSVUZCWjBKQkxFVkJRVU1zUjBGQlIxQXNVVUZCVVN4RFFVRkRVU3hOUVVFM1FpeEZRVUZ4UTBRc1JVRkJReXhKUVVGSkxFTkJRVEZETEVWQlFUWkRPMFZCUXpORExHRkJRVXNyUWl4blFrRkJUQ3hEUVVGelFsb3NTVUZCZEVJc1EwRkJNa0l4UWl4UlFVRlJMRU5CUVVOUExFVkJRVVFzUTBGQmJrTTdPMFZCUTBFc1dVRkJTU3hMUVVGTFowTXNWMEZCVEN4RFFVRnBRblJDTEU5QlFXcENMRU5CUVhsQ2FrSXNVVUZCVVN4RFFVRkRUeXhGUVVGRUxFTkJRV3BETEUxQlFUQkRMRU5CUVVNc1EwRkJMME1zUlVGQmEwUTdSVUZEYUVRc1pVRkJTMmRETEZkQlFVd3NRMEZCYVVKaUxFbEJRV3BDTEVOQlFYTkNNVUlzVVVGQlVTeERRVUZEVHl4RlFVRkVMRU5CUVRsQ08wVkJRMFE3UlVGRFJqczdSVUZGUkN4WFFVRkxPRU1zV1VGQlREdEZRVU5FTzBWQmJrWklPMFZCUVVFN1JVRkJRU3dyUWtGeFJtRlVMRTlCY2taaUxFVkJjVVp6UWp0RlFVTnNRaXhWUVVGSkxFOUJRVTlCTEU5QlFWQXNTMEZCYlVJc1VVRkJka0lzUlVGQmFVTTdSVUZETDBJc1dVRkJUVWtzVVVGQlVTeEhRVUZITEV0QlFVdERMRmRCUVV3c1EwRkJhVUpNTEU5QlFXcENMRU5CUVdwQ096dEZRVU5CTEdGQlFVc3NTVUZCU1hKRExFTkJRVU1zUjBGQlJ5eERRVUZpTEVWQlFXZENRU3hEUVVGRExFZEJRVWQ1UXl4UlFVRlJMRU5CUVVONFF5eE5RVUUzUWl4RlFVRnhRMFFzUTBGQlF5eEpRVUZKTEVOQlFURkRMRVZCUVRaRE8wVkJRek5ETEdWQlFVc3JReXhWUVVGTUxFTkJRV2RDVGl4UlFVRlJMRU5CUVVONlF5eERRVUZFTEVOQlFYaENPMFZCUTBRN1JVRkZSaXhQUVU1RUxFMUJUVTg3UlVGRFRDeFpRVUZOVUN4UlFVRlJMRWRCUVZjc1MwRkJTMjlFTEZkQlFVd3NRMEZCYVVKU0xFOUJRV3BDTEVOQlFYcENPenRGUVVOQkxGbEJRVTFYTEdkQ1FVRm5RaXhIUVVGSExFdEJRVXRpTEdGQlFVd3NRMEZCYlVKNlFpeFBRVUZ1UWl4RFFVRXlRakpDTEU5QlFUTkNMRU5CUVhwQ096dEZRVVZCTEZsQlFVbFhMR2RDUVVGblFpeExRVUZMTEVOQlFVTXNRMEZCTVVJc1JVRkJOa0k3UlVGRE0wSXNaVUZCUzJoQ0xGZEJRVXdzUTBGQmFVSXZRaXhOUVVGcVFpeEhRVUV3UWl4RFFVRXhRanRGUVVORUxGTkJSa1FzVFVGRlR6dEZRVU5NTEdWQlFVc3NTVUZCU1VRc1IwRkJReXhIUVVGSExFTkJRV0lzUlVGQlowSkJMRWRCUVVNc1IwRkJSMUFzVVVGQlVTeERRVUZEVVN4TlFVRTNRaXhGUVVGeFEwUXNSMEZCUXl4SlFVRkpMRU5CUVRGRExFVkJRVFpETzBWQlF6TkRMR2RDUVVGTlV5eExRVUZMTEVkQlFVY3NTMEZCUzNWQ0xGZEJRVXdzUTBGQmFVSjBRaXhQUVVGcVFpeERRVUY1UW1wQ0xGRkJRVkVzUTBGQlEwOHNSMEZCUkN4RFFVRnFReXhEUVVGa096dEZRVU5CTEdkQ1FVRkpVeXhMUVVGTExFZEJRVWNzUTBGQlF5eERRVUZpTEVWQlFXZENPMFZCUTJRc2JVSkJRVXQxUWl4WFFVRk1MRU5CUVdsQ2NrSXNUVUZCYWtJc1EwRkJkMEpHTEV0QlFYaENMRVZCUVN0Q0xFTkJRUzlDTzBWQlEwUTdSVUZEUmp0RlFVTkdPenRGUVVWRUxHRkJRVXR6UWl4blFrRkJUQ3hEUVVGelFqbENMRTFCUVhSQ0xFZEJRU3RDTEVOQlFTOUNPenRGUVVOQkxHRkJRVXRuUkN4WlFVRk1PMFZCUTBRN1JVRkRSanRGUVRsSFNEdEZRVUZCTzBWQlFVRXNiVU5CWjBocFFqdEZRVU5pTEZWQlFVMURMRTFCUVUwc1IwRkJSeXhMUVVGTFpDeFBRVUZNTEVOQlFXRTVRaXhMUVVGaUxFTkJRVzFDTEVOQlFXNUNMRU5CUVdZN08wVkJRMEVzVjBGQlN5eEpRVUZKVGl4RFFVRkRMRWRCUVVjc1EwRkJZaXhGUVVGblFrRXNRMEZCUXl4SFFVRkhhMFFzVFVGQlRTeERRVUZEYWtRc1RVRkJNMElzUlVGQmJVTkVMRU5CUVVNc1NVRkJTU3hEUVVGNFF5eEZRVUV5UXp0RlFVTjZReXhaUVVGTmRVTXNTMEZCU3l4SFFVRkhWeXhOUVVGTkxFTkJRVU5zUkN4RFFVRkVMRU5CUVhCQ096dEZRVU5CTEZsQlFVbDFReXhMUVVGTExFTkJRVU5ETEZGQlFVNHNRMEZCWlZjc1MwRkJaaXhEUVVGeFFpeExRVUZMYmtJc1YwRkJNVUlzUTBGQlNpeEZRVUUwUXp0RlFVTXhReXhqUVVGSlR5eExRVUZMTEVOQlFVTkVMRTlCUVZZc1JVRkJiVUk3UlVGRGFrSkRMRmxCUVVGQkxFdEJRVXNzUTBGQlF6bERMRkZCUVU0c1IwRkJhVUk0UXl4TFFVRkxMRU5CUVVORUxFOUJRVTRzUTBGQll5eExRVUZMVGl4WFFVRnVRaXhEUVVGcVFqdEZRVU5FT3p0RlFVTkVMR1ZCUVVzc1NVRkJTWHBDTEVOQlFVTXNSMEZCUnl4RFFVRmlMRVZCUVdkQ1FTeERRVUZETEVkQlFVZG5ReXhMUVVGTExFTkJRVU01UXl4UlFVRk9MRU5CUVdWUkxFMUJRVzVETEVWQlFUSkRUU3hEUVVGRExFbEJRVWtzUTBGQmFFUXNSVUZCYlVRN1JVRkRha1FzWjBKQlFVa3NTMEZCUzNsQ0xGZEJRVXdzUTBGQmFVSjBRaXhQUVVGcVFpeERRVUY1UWpaQ0xFdEJRVXNzUTBGQlF6bERMRkZCUVU0c1EwRkJaV01zUTBGQlppeERRVUY2UWl4TlFVRm5SQ3hEUVVGRExFTkJRWEpFTEVWQlFYZEVPMFZCUTNSRUxHMUNRVUZMZVVJc1YwRkJUQ3hEUVVGcFFtSXNTVUZCYWtJc1EwRkJjMEp2UWl4TFFVRkxMRU5CUVVNNVF5eFJRVUZPTEVOQlFXVmpMRU5CUVdZc1EwRkJkRUk3UlVGRFJEdEZRVU5HT3p0RlFVTkVMR1ZCUVVzd1FpeGpRVUZNTEVOQlFXOUNaQ3hKUVVGd1FpeERRVUY1UW05Q0xFdEJRWHBDTzBWQlEwUTdSVUZEUmp0RlFVTkdPMFZCYUVsSU8wVkJRVUU3UlVGQlFTeHRRMEZyU1dsQ08wVkJRMklzVjBGQlN5eEpRVUZKZGtNc1EwRkJReXhIUVVGSExFTkJRV0lzUlVGQlowSkJMRU5CUVVNc1IwRkJSeXhMUVVGTGFVTXNZMEZCVEN4RFFVRnZRbWhETEUxQlFYaERMRVZCUVdkRVJDeERRVUZETEVsQlFVa3NRMEZCY2tRc1JVRkJkMFE3UlVGRGRFUXNXVUZCVFhWRExFdEJRVXNzUjBGQlJ5eExRVUZMVGl4alFVRk1MRU5CUVc5Q2FrTXNRMEZCY0VJc1EwRkJaRHM3UlVGRFFTeFpRVUZKTEVOQlFVTjFReXhMUVVGTExFTkJRVU5ETEZGQlFVNHNRMEZCWlZjc1MwRkJaaXhEUVVGeFFpeExRVUZMYmtJc1YwRkJNVUlzUTBGQlRDeEZRVUUyUXp0RlFVTXpReXhsUVVGTExFbEJRVWw2UWl4RFFVRkRMRWRCUVVjc1EwRkJZaXhGUVVGblFrRXNRMEZCUXl4SFFVRkhaME1zUzBGQlN5eERRVUZET1VNc1VVRkJUaXhEUVVGbFVTeE5RVUZ1UXl4RlFVRXlRMDBzUTBGQlF5eEpRVUZKTEVOQlFXaEVMRVZCUVcxRU8wVkJRMnBFTEdkQ1FVRk5SU3hMUVVGTExFZEJRVWNzUzBGQlMzVkNMRmRCUVV3c1EwRkJhVUowUWl4UFFVRnFRaXhEUVVGNVFqWkNMRXRCUVVzc1EwRkJRemxETEZGQlFVNHNRMEZCWldNc1EwRkJaaXhEUVVGNlFpeERRVUZrT3p0RlFVTkJMR2RDUVVGSlJTeExRVUZMTEVkQlFVY3NRMEZCUXl4RFFVRmlMRVZCUVdkQ08wVkJRMlFzYlVKQlFVdDFRaXhYUVVGTUxFTkJRV2xDY2tJc1RVRkJha0lzUTBGQmQwSkdMRXRCUVhoQ0xFVkJRU3RDTEVOQlFTOUNPMFZCUTBRN1JVRkRSanM3UlVGRFJDeGpRVUZKT0VJc1MwRkJTeXhEUVVGRFJDeFBRVUZXTEVWQlFXMUNPMFZCUTJwQ1F5eFpRVUZCUVN4TFFVRkxMRU5CUVVNNVF5eFJRVUZPTEVkQlFXbENMRWxCUVdwQ08wVkJRMFE3TzBWQlEwUXNaVUZCUzNkRExHTkJRVXdzUTBGQmIwSjBRaXhOUVVGd1FpeERRVUV5UWxnc1EwRkJNMElzUlVGQk9FSXNRMEZCT1VJN08wVkJRMEZCTEZWQlFVRkJMRU5CUVVNc1NVRkJTU3hEUVVGTU8wVkJRMFE3UlVGRFJqdEZRVU5HTzBWQmJrcElPenRGUVVGQk8wVkJRVUU3TzAxRFEyRnZSQ3hSUVVGaU8wVkJRMFVzYjBKQlFWbERMRmxCUVZvc1JVRkJNRUpETEdGQlFURkNMRVZCUVhsRFF5eGpRVUY2UXl4RlFVRjVSRU1zWlVGQmVrUXNSVUZCTUVVN1JVRkJRVHM3UlVGRGVFVXNVMEZCUzBNc1QwRkJUQ3hIUVVFMlFpeEpRVUUzUWp0RlFVTkJMRk5CUVV0RExHVkJRVXdzUjBGQk5rSXNSVUZCTjBJN1JVRkRRU3hUUVVGTFF5eFRRVUZNTEVkQlFUWkNMRVZCUVRkQ08wVkJRMEVzVTBGQlMwTXNWVUZCVEN4SFFVRTJRaXhGUVVFM1FqdEZRVU5CTEZOQlFVdERMR2xDUVVGTUxFZEJRVFpDTEVWQlFUZENPMFZCUTBFc1UwRkJTME1zVVVGQlRDeEhRVUUyUWl4RlFVRTNRanRGUVVOQkxGTkJRVXRETEdOQlFVd3NSMEZCTmtJc1NVRkJOMEk3UlVGRFFTeFRRVUZMUXl4aFFVRk1MRWRCUVRaQ0xFbEJRVGRDTzBWQlEwRXNVMEZCUzBNc1pVRkJUQ3hIUVVFMlFpeEZRVUUzUWp0RlFVTkJMRk5CUVV0RExHZENRVUZNTEVkQlFUWkNMRVZCUVRkQ08wVkJRMEVzVTBGQlMwTXNaMEpCUVV3c1IwRkJOa0lzUzBGQk4wSTdSVUZEUVN4VFFVRkxReXh4UWtGQlRDeEhRVUUyUWl4SlFVRTNRanRGUVVOQkxGTkJRVXRETEcxQ1FVRk1MRWRCUVRaQ0xFbEJRVGRDTzBWQlEwRXNVMEZCUzBNc2JVSkJRVXdzUjBGQk5rSXNTVUZCTjBJN1JVRkRRU3hUUVVGTFF5eFBRVUZNTEVkQlFUWkNMRXRCUVRkQ08wVkJSVUVzVTBGQlMxb3NVMEZCVEN4RFFVRmxZU3hOUVVGbUxFZEJRWGRDTzBWQlEzUkNReXhOUVVGQlFTeFRRVUZUTEVWQlFVVXNTMEZCUzJJc1ZVRkVUVHRGUVVWMFFsQXNUVUZCUVVFc1dVRkJXU3hGUVVGYVFTeFpRVVp6UWp0RlFVZDBRa01zVFVGQlFVRXNZVUZCWVN4RlFVRmlRU3hoUVVoelFqdEZRVWwwUWtNc1RVRkJRVUVzWTBGQll5eEZRVUZrUVN4alFVcHpRanRGUVV0MFFrTXNUVUZCUVVFc1pVRkJaU3hGUVVGbVFUdEZRVXh6UWl4TFFVRjRRanRGUVZGQkxGTkJRVXRyUWl4VlFVRk1MRU5CUVdkQ0xGRkJRV2hDTzBWQlEwUTdPMFZCTTBKSU8wVkJRVUU3UlVGQlFTdzRRa0UyUWxrMVF5eFZRVGRDV2l4RlFUWkNkMEkyUXl4aFFUZENlRUlzUlVFMlFuVkRPMFZCUTI1RExGVkJRVWxETEUxQlFVMHNSMEZCUnl4SlFVRmlPenRGUVVOQkxGVkJRVWtzVDBGQlR6bERMRlZCUVZBc1MwRkJjMElzVVVGQk1VSXNSVUZCYjBNN1JVRkZiRU1zV1VGQlNUWkRMR0ZCUVVvc1JVRkJiVUk3UlVGRGFrSkRMRlZCUVVGQkxFMUJRVTBzUjBGQlJ5eEpRVUZKYUVRc1RVRkJTaXhEUVVGWFJTeFZRVUZZTEVOQlFWUTdSVUZEUVRaRExGVkJRVUZCTEdGQlFXRXNRMEZCUTBNc1RVRkJSQ3hGUVVGVExFdEJRVXRZTEdWQlFXUXNSVUZCSzBJc1MwRkJTME1zWjBKQlFYQkRMRU5CUVdJN1JVRkRSQ3hUUVVoRUxFMUJSMDg3UlVGRFRGVXNWVUZCUVVFc1RVRkJUU3hIUVVGSExFdEJRVXRrTEZGQlFVd3NRMEZCWTJoRExGVkJRV1FzUzBGQk5rSXNTVUZCZEVNN1JVRkRSRHRGUVVOR0xFOUJVa1FzVFVGUlR6dEZRVU5NT0VNc1VVRkJRVUVzVFVGQlRTeEhRVUZQT1VNc1ZVRkJZanRGUVVOQlFTeFJRVUZCUVN4VlFVRlZMRWRCUVVjNFF5eE5RVUZOTEVOQlFVTkRMRmRCUVhCQ08wVkJRMFE3TzBWQlJVUXNWMEZCUzNCQ0xFOUJRVXdzUjBGQk5FSnRRaXhOUVVFMVFqdEZRVU5CTEZkQlFVdGtMRkZCUVV3c1EwRkJZMmhETEZWQlFXUXNTVUZCTkVJNFF5eE5RVUUxUWpzN1JVRkRRU3hWUVVGSlFTeE5RVUZLTEVWQlFWazdSVUZEVml4aFFVRkxia0lzVDBGQlRDeERRVUZoZWtJc1YwRkJZaXhIUVVFeVFqUkRMRTFCUVUwc1EwRkJRelZETEZkQlFXeERPMFZCUTBRN08wVkJSVVFzWVVGQlR5eEpRVUZRTzBWQlEwUTdSVUZ1UkVnN1JVRkJRVHRGUVVGQkxEaENRWEZFV1RoRExGTkJja1JhTEVWQmNVUjFRanRGUVVOdVFrRXNUVUZCUVVFc1UwRkJVeXhMUVVGTFFTeFRRVUZUTEVkQlFVY3NTMEZCUzNKQ0xFOUJRVXdzUTBGQllUTkNMRlZCUVRsQ0xFTkJRVlE3UlVGRFFTeGhRVUZQTEV0QlFVdG5ReXhSUVVGTUxFTkJRV05uUWl4VFFVRmtMRXRCUVRSQ0xFbEJRVzVETzBWQlEwUTdSVUY0UkVnN1JVRkJRVHRGUVVGQkxIbENRVEJFVDNwR0xGZEJNVVJRTEVWQk1FUnZRakJHTEZsQk1VUndRaXhGUVRCRWEwTkRMR05CTVVSc1F5eEZRVEJFYTBSRExITkNRVEZFYkVRc1JVRXdSREJGTzBWQlEzUkZMRlZCUVVrMVJpeFhRVUZYTEV0QlFVc3NTVUZCYUVJc1NVRkJkMElzVDBGQlQwRXNWMEZCVUN4TFFVRjFRaXhWUVVGdVJDeEZRVUVyUkR0RlFVTTNSRFJHTEZGQlFVRkJMSE5DUVVGelFpeEhRVUZIUkN4alFVRjZRanRGUVVOQlFTeFJRVUZCUVN4alFVRmpMRWRCUVZkRUxGbEJRWHBDTzBWQlEwRkJMRkZCUVVGQkxGbEJRVmtzUjBGQllURkdMRmRCUVhwQ08wVkJRMEZCTEZGQlFVRkJMRmRCUVZjc1IwRkJZeXhKUVVGNlFqdEZRVU5FT3p0RlFVVkVMRlZCUTBWQkxGZEJRVmNzU1VGRFdDeFJRVUZQUVN4WFFVRlFMRTFCUVhWQ0xGRkJSSFpDTEVsQlJVRXNUMEZCVDBFc1YwRkJWeXhEUVVGRFdTeE5RVUZ1UWl4TFFVRTRRaXhSUVVob1F5eEZRVWxGTzBWQlEwRXNZVUZCU3l4SlFVRkpSQ3hEUVVGRExFZEJRVWNzUTBGQllpeEZRVUZuUWtFc1EwRkJReXhIUVVGSFdDeFhRVUZYTEVOQlFVTlpMRTFCUVdoRExFVkJRWGREUkN4RFFVRkRMRWxCUVVrc1EwRkJOME1zUlVGQlowUTdSVUZET1VNc1pVRkJTMnRHTEVsQlFVd3NRMEZCVlRkR0xGZEJRVmNzUTBGQlExY3NRMEZCUkN4RFFVRnlRaXhGUVVFd1FpdEZMRmxCUVRGQ0xFVkJRWGREUXl4alFVRjRRenRGUVVORU96dEZRVU5FTEdWQlFVOHNTVUZCVUR0RlFVTkVPenRGUVVWRUxGZEJRVXR3UWl4VlFVRk1MRU5CUVdkQ2VrTXNTVUZCYUVJc1EwRkJjVUk3UlVGRGJrSnhRaXhSUVVGQlFTeFJRVUZSTEVWQlFXZENia1FzVjBGQlZ5eEhRVUZITEVsQlFVbEVMRkZCUVVvc1EwRkJZVU1zVjBGQllpeERRVUZJTEVkQlFTdENMRWxCUkM5RE8wVkJSVzVDTUVZc1VVRkJRVUVzV1VGQldTeEZRVUZaUVN4WlFVRlpMRWxCUVdNc1NVRkdMMEk3UlVGSGJrSkRMRkZCUVVGQkxHTkJRV01zUlVGQlZVRXNZMEZCWXl4SlFVRlpMRWxCU0M5Q08wVkJTVzVDUnl4UlFVRkJRU3hoUVVGaExFVkJRVmNzUzBGS1REdEZRVXR1UWtZc1VVRkJRVUVzYzBKQlFYTkNMRVZCUVVWQkxITkNRVUZ6UWl4SlFVRkpMRXRCVEM5Q08wVkJUVzVDUnl4UlFVRkJRU3huUWtGQlowSXNSVUZCVVR0RlFVNU1MRTlCUVhKQ096dEZRVk5CTEdGQlFVOHNTVUZCVUR0RlFVTkVPMFZCZGtaSU8wVkJRVUU3UlVGQlFTeG5RMEY1Um1NdlJpeFhRWHBHWkN4RlFYbEdNa0l3Uml4WlFYcEdNMElzUlVGNVJubERReXhqUVhwR2VrTXNSVUY1Um5sRVF5eHpRa0Y2Um5wRUxFVkJlVVpwUmp0RlFVTTNSU3hoUVVGUExFdEJRVXRETEVsQlFVd3NRMEZCVlRkR0xGZEJRVllzUlVGQmRVSXdSaXhaUVVGMlFpeEZRVUZ4UTBNc1kwRkJja01zUlVGQmNVUkRMSE5DUVVGeVJDeERRVUZRTzBWQlEwUTdSVUV6UmtnN1JVRkJRVHRGUVVGQkxIVkNRVFpHU3pWR0xGZEJOMFpNTEVWQk5rWnJRakJHTEZsQk4wWnNRaXhGUVRaR1owTkRMR05CTjBab1F5eEZRVFpHWjBSRExITkNRVGRHYUVRc1JVRTJSbmRGTzBWQlEzQkZMR0ZCUVU4c1MwRkJTME1zU1VGQlRDeERRVUZWTjBZc1YwRkJWaXhGUVVGMVFqQkdMRmxCUVhaQ0xFVkJRWEZEUXl4alFVRnlReXhGUVVGeFJFTXNjMEpCUVhKRUxFTkJRVkE3UlVGRFJEdEZRUzlHU0R0RlFVRkJPMFZCUVVFc09FSkJhVWRaTlVZc1YwRnFSMW9zUlVGcFIzbENNRVlzV1VGcVIzcENMRVZCYVVkMVEwVXNjMEpCYWtkMlF5eEZRV2xISzBRN1JVRkRNMFFzWVVGQlR5eExRVUZMUXl4SlFVRk1MRU5CUVZVM1JpeFhRVUZXTEVWQlFYVkNNRVlzV1VGQmRrSXNSVUZCY1VNc1NVRkJja01zUlVGQk1rTkZMSE5DUVVFelF5eERRVUZRTzBWQlEwUTdSVUZ1UjBnN1JVRkJRVHRGUVVGQkxHZERRWEZIWXpWR0xGZEJja2RrTEVWQmNVY3lRakpHTEdOQmNrY3pRaXhGUVhGSE1rTTdSVUZEZGtNc1lVRkJUeXhMUVVGTFJTeEpRVUZNTEVOQlFWVTNSaXhYUVVGV0xFVkJRWFZDTEVsQlFYWkNMRVZCUVRaQ01rWXNZMEZCTjBJc1JVRkJOa05ETEhOQ1FVRTNReXhEUVVGUU8wVkJRMFE3UlVGMlIwZzdSVUZCUVR0RlFVRkJMREpDUVhsSFV6VkdMRmRCZWtkVUxFVkJlVWR6UWpCR0xGbEJla2QwUWl4RlFYbEhiME5ETEdOQmVrZHdReXhGUVhsSGIwUTdSVUZEYUVRc1ZVRkJTVE5HTEZkQlFWY3NTMEZCU3l4SlFVRm9RaXhKUVVGM1FpeFBRVUZQUVN4WFFVRlFMRXRCUVhWQ0xGVkJRVzVFTEVWQlFTdEVPMFZCUXpkRU1rWXNVVUZCUVVFc1kwRkJZeXhIUVVGSFJDeFpRVUZxUWp0RlFVTkJRU3hSUVVGQlFTeFpRVUZaTEVkQlFVc3hSaXhYUVVGcVFqdEZRVU5CUVN4UlFVRkJRU3hYUVVGWExFZEJRVWNzU1VGQlpEdEZRVU5FT3p0RlFVVkVMRlZCUTBWQkxGZEJRVmNzU1VGRFdDeFJRVUZQUVN4WFFVRlFMRTFCUVhWQ0xGRkJSSFpDTEVsQlJVRXNUMEZCVDBFc1YwRkJWeXhEUVVGRFdTeE5RVUZ1UWl4TFFVRTRRaXhSUVVob1F5eEZRVWxGTzBWQlEwRXNZVUZCU3l4SlFVRkpSQ3hEUVVGRExFZEJRVWNzUTBGQllpeEZRVUZuUWtFc1EwRkJReXhIUVVGSFdDeFhRVUZYTEVOQlFVTlpMRTFCUVdoRExFVkJRWGREUkN4RFFVRkRMRWxCUVVrc1EwRkJOME1zUlVGQlowUTdSVUZET1VNc1pVRkJTM0ZHTEUxQlFVd3NRMEZCV1doSExGZEJRVmNzUTBGQlExY3NRMEZCUkN4RFFVRjJRaXhGUVVFMFFpdEZMRmxCUVRWQ0xFVkJRVEJEUXl4alFVRXhRenRGUVVORU96dEZRVU5FTEdWQlFVOHNTVUZCVUR0RlFVTkVPenRGUVVWRUxGZEJRVXNzU1VGQlNXaEdMRVZCUVVNc1IwRkJSeXhEUVVGaUxFVkJRV2RDUVN4RlFVRkRMRWRCUVVjc1MwRkJTelJFTEZWQlFVd3NRMEZCWjBJelJDeE5RVUZ3UXl4RlFVRTBRMFFzUlVGQlF5eEpRVUZKTEVOQlFXcEVMRVZCUVc5RU8wVkJRMnhFTEZsQlFVMXpSaXhSUVVGUkxFZEJRVWNzUzBGQlN6RkNMRlZCUVV3c1EwRkJaMEkxUkN4RlFVRm9RaXhEUVVGcVFqdEZRVVZCTEZsQlFVMTFSaXhaUVVGWkxFZEJRVmtzUTBGQlEyeEhMRmRCUVVRc1NVRkJaMElzUTBGQlEybEhMRkZCUVZFc1EwRkJRemxETEZGQlFURkNMRWxCUTBZNFF5eFJRVUZSTEVOQlFVTTVReXhSUVVGVUxFbEJRWEZDT0VNc1VVRkJVU3hEUVVGRE9VTXNVVUZCVkN4RFFVRnJRbWRFTEU5QlFXeENMRU5CUVRCQ2JrY3NWMEZCTVVJc1EwRkVha1E3UlVGRlFTeFpRVUZOYjBjc2JVSkJRVzFDTEVkQlFVc3NRMEZCUTFZc1dVRkJSQ3hKUVVGcFFpeERRVUZEUXl4alFVRnNRaXhKUVVOR0xFTkJRVU5FTEZsQlFVUXNTVUZCYVVJc1EwRkJRMDhzVVVGQlVTeERRVUZEVUN4WlFVUjZRaXhKUVVWR1FTeFpRVUZaTEV0QlFVdFBMRkZCUVZFc1EwRkJRMUFzV1VGR2RFUTdSVUZIUVN4WlFVRk5WeXh4UWtGQmNVSXNSMEZCUnl4RFFVRkRXQ3haUVVGRUxFbEJRV2xDTEVOQlFVTkRMR05CUVd4Q0xFbEJRMFlzUTBGQlEwRXNZMEZCUkN4SlFVRnRRaXhEUVVGRFRTeFJRVUZSTEVOQlFVTk9MR05CUkROQ0xFbEJSVVpCTEdOQlFXTXNTMEZCUzAwc1VVRkJVU3hEUVVGRFRpeGpRVVo0UkRzN1JVRkpRU3haUVVGSlR5eFpRVUZaTEVsQlFVbEZMRzFDUVVGb1FpeEpRVUYxUTBNc2NVSkJRVE5ETEVWQlFXdEZPMFZCUTJoRkxHVkJRVXM1UWl4VlFVRk1MRU5CUVdkQ2FrUXNUVUZCYUVJc1EwRkJkVUpZTEVWQlFYWkNMRVZCUVRCQ0xFTkJRVEZDT3p0RlFVTkJRU3hWUVVGQlFTeEZRVUZETEVsQlFVa3NRMEZCVER0RlFVTkVPMFZCUTBZN08wVkJSVVFzWVVGQlR5eEpRVUZRTzBWQlEwUTdSVUU1U1VnN1JVRkJRVHRGUVVGQkxHMURRV2RLYVVKWUxGZEJhRXBxUWl4RlFXZEtPRUl3Uml4WlFXaEtPVUlzUlVGblNqUkRReXhqUVdoS05VTXNSVUZuU2pSRU8wVkJRM2hFTEdGQlFVOHNTMEZCUzBzc1RVRkJUQ3hEUVVGWmFFY3NWMEZCV2l4RlFVRjVRakJHTEZsQlFYcENMRVZCUVhWRFF5eGpRVUYyUXl4RFFVRlFPMFZCUTBRN1JVRnNTa2c3UlVGQlFUdEZRVUZCTEhkQ1FXOUtUVE5HTEZkQmNFcE9MRVZCYjBwdFFqQkdMRmxCY0VwdVFpeEZRVzlLYVVORExHTkJjRXBxUXl4RlFXOUthVVE3UlVGRE4wTXNZVUZCVHl4TFFVRkxTeXhOUVVGTUxFTkJRVmxvUnl4WFFVRmFMRVZCUVhsQ01FWXNXVUZCZWtJc1JVRkJkVU5ETEdOQlFYWkRMRU5CUVZBN1JVRkRSRHRGUVhSS1NEdEZRVUZCTzBWQlFVRXNLMEpCZDBwaFZ5eFhRWGhLWWl4RlFYZEtNRUk3UlVGRGRFSXNWVUZCUnl4TFFVRkxiRU1zVDBGQlVpeEZRVUZwUWp0RlFVRkZMR0ZCUVV0dFF5eGpRVUZNTzBWQlFYZENPenRGUVVVelF5eFZRVUZKTEVOQlFVTXNTMEZCUzJwRExGTkJRVXdzUTBGQlpXZERMRmRCUVdZc1EwRkJUQ3hGUVVGclF6dEZRVU5vUXl4WlFVRk5SU3hoUVVGaExFZEJRVWNzUzBGQlMyeERMRk5CUVV3c1EwRkJaV0VzVFVGQmNrTTdSVUZEUVN4aFFVRkxZaXhUUVVGTUxFTkJRV1ZuUXl4WFFVRm1MRWxCUVRoQ08wVkJRelZDYkVJc1ZVRkJRVUVzVTBGQlV5eEZRVUZSTEVWQlJGYzdSVUZGTlVKd1FpeFZRVUZCUVN4WlFVRlpMRVZCUVV0M1F5eGhRVUZoTEVOQlFVTjRReXhaUVVaSU8wVkJSelZDUXl4VlFVRkJRU3hoUVVGaExFVkJRVWwxUXl4aFFVRmhMRU5CUVVOMlF5eGhRVWhJTzBWQlNUVkNReXhWUVVGQlFTeGpRVUZqTEVWQlFVZHpReXhoUVVGaExFTkJRVU4wUXl4alFVcElPMFZCU3pWQ1F5eFZRVUZCUVN4bFFVRmxMRVZCUVVWeFF5eGhRVUZoTEVOQlFVTnlRenRGUVV4SUxGTkJRVGxDTzBWQlQwUTdPMFZCUlVRc1ZVRkJUWE5ETEU5QlFVOHNSMEZCVlN4TFFVRkxia01zVTBGQlRDeERRVUZsWjBNc1YwRkJaaXhEUVVGMlFqdEZRVU5CTEZkQlFVdHFReXhsUVVGTUxFZEJRWFZDYVVNc1YwRkJka0k3UlVGRFFTeFhRVUZMTDBJc1ZVRkJUQ3hIUVVGMVFtdERMRTlCUVU4c1EwRkJRM0pDTEZOQlFTOUNPMFZCUlVFc1YwRkJTM05DTEVsQlFVdzdSVUZEUVN4WFFVRkxReXhMUVVGTUxFTkJRMFZHTEU5QlFVOHNRMEZCUTNwRExGbEJSRllzUlVGRlJYbERMRTlCUVU4c1EwRkJRM2hETEdGQlJsWXNSVUZIUlhkRExFOUJRVThzUTBGQlEzWkRMR05CU0ZZc1JVRkpSWFZETEU5QlFVOHNRMEZCUTNSRExHVkJTbFk3UlVGUFFTeGhRVUZQTEVsQlFWQTdSVUZEUkR0RlFXNU1TRHRGUVVGQk8wVkJRVUVzYVVOQmNVeGxPMFZCUTFnc1lVRkJUeXhMUVVGTFJTeGxRVUZhTzBWQlEwUTdSVUYyVEVnN1JVRkJRVHRGUVVGQkxHZERRWGxNWTJsRExGZEJla3hrTEVWQmVVd3lRazBzVVVGNlRETkNMRVZCZVV4eFF6dEZRVU5xUXl4VlFVRk5ReXh0UWtGQmJVSXNSMEZCUnl4TFFVRkxReXhWUVVGTUxFVkJRVFZDTzBWQlEwRXNWMEZCUzNwQ0xGVkJRVXdzUTBGQlowSnBRaXhYUVVGb1FqdEZRVVZCVFN4TlFVRkJRU3hSUVVGUk8wVkJSVklzVjBGQlMzWkNMRlZCUVV3c1EwRkJaMEozUWl4dFFrRkJhRUk3UlVGRlFTeGhRVUZQTEVsQlFWQTdSVUZEUkR0RlFXeE5TRHRGUVVGQk8wVkJRVUVzTUVKQmIwMVJOME1zV1VGd1RWSXNSVUZ2VFhOQ1F5eGhRWEJOZEVJc1JVRnZUWEZEUXl4alFYQk5ja01zUlVGdlRYRkVReXhsUVhCTmNrUXNSVUZ2VFhORk8wVkJRVUU3TzBWQlEyeEZMRmRCUVV0MVF5eEpRVUZNTzBWQlJVRXNWVUZCVFVzc1IwRkJSeXhIUVVGSExFOUJRVTlETEZWQlFWQXNTMEZCYzBJc1YwRkJkRUlzUjBGQmIwTkJMRlZCUVhCRExFZEJRMEVzVDBGQlR6ZENMRTFCUVZBc1MwRkJhMElzVjBGQmJFSXNSMEZCWjBOQkxFMUJRV2hETEVkQlEwRXNUMEZCVHpoQ0xFMUJRVkFzUzBGQmEwSXNWMEZCYkVJc1IwRkJaME5CTEUxQlFXaERMRWRCUTBFc1JVRklXanM3UlVGTFFTeFZRVUZKTEVOQlFVTnFSQ3haUVVGTUxFVkJRVzFDTzBWQlEycENMRmxCUVVrc1EwRkJReXRETEVkQlFVY3NRMEZCUTBjc1owSkJRVXdzU1VGQmVVSXNRMEZCUTBnc1IwRkJSeXhEUVVGRFNTeFhRVUZzUXl4RlFVRXJRenRGUVVNM1F6dEZRVU5CTzBWQlEwRXNZMEZCU1N4TFFVRkxPVU1zWlVGQlRDeExRVUY1UWl4UlFVRTNRaXhGUVVGMVF6dEZRVU55UXp0RlFVTkVPenRGUVVORUxHZENRVUZOTEVsQlFVa3JReXhMUVVGS0xFTkJRVlVzSzBSQlFWWXNRMEZCVGp0RlFVTkVPenRGUVVORWNFUXNVVUZCUVVFc1dVRkJXU3hIUVVGSEswTXNSMEZCWmp0RlFVTkVMRTlCYkVKcFJUczdPMFZCY1VKc1JTeFZRVUZKTEU5QlFVOHZReXhaUVVGWkxFTkJRVU54UkN4UlFVRndRaXhMUVVGcFF5eFJRVUZ5UXl4RlFVRXJRenRGUVVNM1EyeEVMRkZCUVVGQkxHVkJRV1VzUjBGQlIwUXNZMEZCYkVJN1JVRkRRVUVzVVVGQlFVRXNZMEZCWXl4SFFVRkpSQ3hoUVVGc1FqdEZRVU5CUVN4UlFVRkJRU3hoUVVGaExFZEJRVXRFTEZsQlFXeENPMFZCUTBGQkxGRkJRVUZCTEZsQlFWa3NSMEZCVFN0RExFZEJRV3hDTzBWQlEwUTdPMFZCUlVRc1ZVRkJTU3hEUVVGREwwTXNXVUZCV1N4RFFVRkRhMFFzWjBKQlFXUXNTVUZCYTBNc1EwRkJRMnhFTEZsQlFWa3NRMEZCUTIxRUxGZEJRWEJFTEVWQlFXbEZPMFZCUXk5RUxHTkJRVTBzU1VGQlNVTXNTMEZCU2l4RFFVRlZMSE5GUVVGV0xFTkJRVTQ3UlVGRFJEczdSVUZGUkN4WFFVRkxkRU1zWjBKQlFVd3NSMEZCZDBJc1EwRkJReXhEUVVGRFpDeFpRVUZaTEVOQlFVTnJSQ3huUWtGQmRrTTdSVUZGUVN4VlFVRk5TU3hUUVVGVExFZEJRVWQwUkN4WlFVRlpMRU5CUVVOMVJDeFRRVUZpTEVsQlFUQkNka1FzV1VGQldTeERRVUZEZFVRc1UwRkJZaXhEUVVGMVFrUXNVMEZCYWtRc1NVRkJPRVFzUlVGQmFFWTdSVUZEUVN4VlFVRk5SU3hSUVVGUkxFZEJRVWw0UkN4WlFVRlpMRU5CUVVOMVJDeFRRVUZpTEVsQlFUQkNka1FzV1VGQldTeERRVUZEZFVRc1UwRkJZaXhEUVVGMVFrTXNVVUZCYWtRc1NVRkJPRVFzUlVGQmFFWTdSVUZGUVhaRUxFMUJRVUZCTEdGQlFXRXNTVUZCVFVFc1lVRkJZU3hMUVVGUExFbEJRWFpETEV0QlFXZEVRU3hoUVVGaExFZEJRVXRFTEZsQlFWa3NRMEZCUTNsRUxGRkJRUzlGTzBWQlEwRjJSQ3hOUVVGQlFTeGpRVUZqTEVsQlFVdEJMR05CUVdNc1MwRkJUU3hKUVVGMlF5eExRVUZuUkVFc1kwRkJZeXhIUVVGSmMwUXNVVUZCYkVVN1JVRkRRWEpFTEUxQlFVRkJMR1ZCUVdVc1NVRkJTVUVzWlVGQlpTeExRVUZMTEVsQlFYWkRMRXRCUVdkRVFTeGxRVUZsTEVkQlFVZHRSQ3hUUVVGc1JUczdSVUZGUVN4WFFVRkxka01zY1VKQlFVd3NSMEZCTmtJc1ZVRkJRekpETEV0QlFVUXNSVUZCVnp0RlFVTjBReXhSUVVGQkxFdEJRVWtzUTBGQlEyNUZMRkZCUVV3c1EwRkJZMjFGTEV0QlFVc3NRMEZCUXpGRkxFOUJRWEJDTEVWQlFUWkNNRVVzUzBGQk4wSTdPMFZCUTBFc1VVRkJRU3hMUVVGSkxFTkJRVU5ETEdsQ1FVRk1MRU5CUVhWQ1JDeExRVUYyUWl4RlFVRTRRa1lzVVVGQk9VSTdSVUZEUkN4UFFVaEVPenRGUVVsQkxGZEJRVXQ0UXl4dFFrRkJUQ3hIUVVFeVFpeFZRVUZETUVNc1MwRkJSQ3hGUVVGWE8wVkJRM0JETEZGQlFVRXNTMEZCU1N4RFFVRkRhRVVzVlVGQlRDeERRVUZuUW1kRkxFdEJRVXNzUTBGQlF6RkZMRTlCUVhSQ0xFVkJRU3RDTUVVc1MwRkJMMEk3UlVGRFJDeFBRVVpFT3p0RlFVZEJMRmRCUVV0NlF5eHRRa0ZCVEN4SFFVRXlRaXhWUVVGRGVVTXNTMEZCUkN4RlFVRlhPMFZCUTNCRExGRkJRVUVzUzBGQlNTeERRVUZEYmtJc1kwRkJUQ3hEUVVGdlFtMUNMRXRCUVhCQ08wVkJRMFFzVDBGR1JEczdSVUZKUVN4WFFVRkxSU3hWUVVGTUxFTkJRV2RDTTBRc1lVRkJhRUlzUlVGQkswSXNVMEZCTDBJc1JVRkJNRU1zUzBGQlMyTXNjVUpCUVM5RE96dEZRVU5CTEZkQlFVczJReXhWUVVGTUxFTkJRV2RDTTBRc1lVRkJhRUlzUlVGQkswSXNUMEZCTDBJc1JVRkJNRU1zUzBGQlMyVXNiVUpCUVM5RE96dEZRVU5CTEZkQlFVczBReXhWUVVGTUxFTkJRV2RDTlVRc1dVRkJhRUlzUlVGQkswSXNUMEZCTDBJc1JVRkJNRU1zUzBGQlMybENMRzFDUVVFdlF6czdSVUZEUVN4WFFVRkxNa01zVlVGQlRDeERRVUZuUWpWRUxGbEJRV2hDTEVWQlFTdENMRTFCUVM5Q0xFVkJRVEJETEV0QlFVdHBRaXh0UWtGQkwwTTdPMFZCUlVFc1YwRkJTMUFzWTBGQlRDeEhRVUYzUWxRc1lVRkJlRUk3UlVGRFFTeFhRVUZMVlN4aFFVRk1MRWRCUVhkQ1dDeFpRVUY0UWp0RlFVTkJMRmRCUVV0WkxHVkJRVXdzUjBGQmQwSldMR05CUVhoQ08wVkJRMEVzVjBGQlMxY3NaMEpCUVV3c1IwRkJkMEpXTEdWQlFYaENPMFZCUlVFc1ZVRkJUVEJFTEdOQlFXTXNSMEZCWVN4TFFVRkxka1FzVTBGQlRDeERRVUZsTEV0QlFVdEVMR1ZCUVhCQ0xFTkJRV3BETzBWQlEwRjNSQ3hOUVVGQlFTeGpRVUZqTEVOQlFVTTNSQ3haUVVGbUxFZEJRV2xETEV0QlFVdFhMR0ZCUVhSRE8wVkJRMEZyUkN4TlFVRkJRU3hqUVVGakxFTkJRVU0xUkN4aFFVRm1MRWRCUVdsRExFdEJRVXRUTEdOQlFYUkRPMFZCUTBGdFJDeE5RVUZCUVN4alFVRmpMRU5CUVVNelJDeGpRVUZtTEVkQlFXbERMRXRCUVV0VkxHVkJRWFJETzBWQlEwRnBSQ3hOUVVGQlFTeGpRVUZqTEVOQlFVTXhSQ3hsUVVGbUxFZEJRV2xETEV0QlFVdFZMR2RDUVVGMFF6dEZRVVZCTEdGQlFVOHNTVUZCVUR0RlFVTkVPMFZCZWxGSU8wVkJRVUU3UlVGQlFTd3lRa0V5VVZNN1JVRkRUQ3hWUVVGSkxFTkJRVU1zUzBGQlMwZ3NZMEZCVGl4SlFVRjNRaXhEUVVGRExFdEJRVXRETEdGQlFXeERMRVZCUVdsRU8wVkJRVVU3UlVGQlV6czdSVUZGTlVRc1YwRkJTMjFFTEZsQlFVd3NRMEZCYTBJc1MwRkJTM0JFTEdOQlFYWkNMRVZCUVhWRExGTkJRWFpETEVWQlFXdEVMRXRCUVV0TExIRkNRVUYyUkRzN1JVRkRRU3hYUVVGTEswTXNXVUZCVEN4RFFVRnJRaXhMUVVGTGNFUXNZMEZCZGtJc1JVRkJkVU1zVDBGQmRrTXNSVUZCYTBRc1MwRkJTMDBzYlVKQlFYWkVPenRGUVVOQkxGZEJRVXM0UXl4WlFVRk1MRU5CUVd0Q0xFdEJRVXR1UkN4aFFVRjJRaXhGUVVGMVF5eFBRVUYyUXl4RlFVRnJSQ3hMUVVGTFRTeHRRa0ZCZGtRN08wVkJRMEVzVjBGQlN6WkRMRmxCUVV3c1EwRkJhMElzUzBGQlMyNUVMR0ZCUVhaQ0xFVkJRWFZETEUxQlFYWkRMRVZCUVd0RUxFdEJRVXROTEcxQ1FVRjJSRHM3UlVGRlFTeFhRVUZMVGl4aFFVRk1MRWRCUVhOQ0xFbEJRWFJDTzBWQlEwRXNWMEZCUzBRc1kwRkJUQ3hIUVVGelFpeEpRVUYwUWp0RlFVVkJMR0ZCUVU4c1NVRkJVRHRGUVVORU8wVkJkbEpJTzBWQlFVRTdSVUZCUVN3MlFrRjVVbGN4UWl4UFFYcFNXQ3hGUVhsU2IwSXdSU3hMUVhwU2NFSXNSVUY1VWpKQ08wVkJRM1pDTEZWQlFVa3NTMEZCUzNoRExFOUJRVlFzUlVGQmEwSTdSVUZCUlN4bFFVRlBMRWxCUVZBN1JVRkJZenM3UlVGRGJFTXNWVUZCU1N4RFFVRkRMRXRCUVV0a0xFOUJRVllzUlVGQmJVSTdSVUZCUlN4alFVRk5MRWxCUVVsblJDeExRVUZLTEVOQlFWVXNaMEpCUVZZc1EwRkJUanRGUVVGdlF6czdSVUZGZWtRc1YwRkJTMmhFTEU5QlFVd3NRMEZCWVdJc1VVRkJZaXhEUVVGelFsQXNUMEZCZEVJN08wVkJRMEVzVjBGQlN5dEZMR05CUVV3c1EwRkJiMEpNTEV0QlFYQkNPenRGUVVWQkxHRkJRVThzU1VGQlVEdEZRVU5FTzBWQmFsTklPMFZCUVVFN1JVRkJRU3dyUWtGdFUyRXhSU3hQUVc1VFlpeEZRVzFUYzBJd1JTeExRVzVUZEVJc1JVRnRVelpDTzBWQlEzcENMRlZCUVVrc1MwRkJTM2hETEU5QlFWUXNSVUZCYTBJN1JVRkJSU3hsUVVGUExFbEJRVkE3UlVGQll6czdSVUZEYkVNc1ZVRkJTU3hEUVVGRExFdEJRVXRrTEU5QlFWWXNSVUZCYlVJN1JVRkJSU3hqUVVGTkxFbEJRVWxuUkN4TFFVRktMRU5CUVZVc1owSkJRVllzUTBGQlRqdEZRVUZ2UXpzN1JVRkZla1FzVjBGQlMyaEVMRTlCUVV3c1EwRkJZVllzVlVGQllpeERRVUYzUWxZc1QwRkJlRUk3TzBWQlEwRXNWMEZCUzJkR0xHTkJRVXdzUTBGQmIwSk9MRXRCUVhCQ096dEZRVVZCTEdGQlFVOHNTVUZCVUR0RlFVTkVPMFZCTTFOSU8wVkJRVUU3UlVGQlFTeHRRMEUyVTJsQ1FTeExRVGRUYWtJc1JVRTJVM2RDTzBWQlEzQkNMRlZCUVVrc1MwRkJTM2hETEU5QlFWUXNSVUZCYTBJN1JVRkJSU3hsUVVGUExFbEJRVkE3UlVGQll6czdSVUZEYkVNc1ZVRkJTU3hEUVVGRExFdEJRVXRrTEU5QlFWWXNSVUZCYlVJN1JVRkJSU3hqUVVGTkxFbEJRVWxuUkN4TFFVRktMRU5CUVZVc1owSkJRVllzUTBGQlRqdEZRVUZ2UXpzN1JVRkZla1FzVjBGQlMyaEVMRTlCUVV3c1EwRkJZWHBDTEZkQlFXSXNRMEZCZVVJdlFpeE5RVUY2UWl4SFFVRnJReXhEUVVGc1F6czdSVUZEUVN4WFFVRkxiMGdzWTBGQlRDeERRVUZ2UWs0c1MwRkJjRUk3TzBWQlJVRXNZVUZCVHl4SlFVRlFPMFZCUTBRN1JVRnlWRWc3UlVGQlFUdEZRVUZCTERSQ1FYVlVWVHRGUVVOT0xGVkJRVWtzUzBGQlMzaERMRTlCUVZRc1JVRkJhMEk3UlVGQlJTeGxRVUZQTEVsQlFWQTdSVUZCWXpzN1JVRkRiRU1zVlVGQlNTeExRVUZMWkN4UFFVRlVMRVZCUVd0Q08wVkJRVVVzWVVGQlMyMURMR05CUVV3N1JVRkJkMEk3TzBWQlF6VkRMRmRCUVV0eVFpeFBRVUZNTEVkQlFXVXNTVUZCWmp0RlFVVkJMR0ZCUVU4c1NVRkJVRHRGUVVORU8wVkJOMVJJTzBWQlFVRTdSVUZCUVN3MlFrRXJWRmM3UlVGRFVDeFhRVUZMUVN4UFFVRk1MRWRCUVdVc1MwRkJaanRGUVVWQkxHRkJRVThzU1VGQlVEdEZRVU5FTzBWQmJsVklPMFZCUVVFN1JVRkJRU3cwUWtGeFZWVTdSVUZEVGl4WFFVRkxjVUlzWTBGQlREdEZRVU5CTEZkQlFVdG9ReXhWUVVGTUxFTkJRV2RDTTBRc1RVRkJhRUlzUjBGQmVVSXNRMEZCZWtJN1JVRkZRU3hoUVVGUExFbEJRVkE3UlVGRFJEdEZRVEZWU0R0RlFVRkJPMFZCUVVFc0swSkJORlZoY1VRc1lVRTFWV0lzUlVFMFZUUkNaMFVzVTBFMVZUVkNMRVZCTkZWMVEyaEdMRTlCTlZWMlF5eEZRVFJWWjBRN1JVRkROVU1zWVVGQlR5eExRVUZMTmtJc1owSkJRVXdzUjBGRFRHSXNZVUZCWVN4RFFVRkRhVVFzWjBKQlFXUXNRMEZCSzBKbExGTkJRUzlDTEVWQlFUQkRhRVlzVDBGQk1VTXNSVUZCYlVRc1MwRkJia1FzUTBGRVN5eEhRVVZNWjBJc1lVRkJZU3hEUVVGRGEwUXNWMEZCWkN4RFFVRXdRaXhQUVVGUFl5eFRRVUZxUXl4RlFVRTBRMmhHTEU5QlFUVkRMRU5CUmtZN1JVRkhSRHRGUVdoV1NEdEZRVUZCTzBWQlFVRXNhVU5CYTFabFowSXNZVUZzVm1Zc1JVRnJWamhDWjBVc1UwRnNWamxDTEVWQmExWjVRMmhHTEU5QmJGWjZReXhGUVd0V2EwUTdSVUZET1VNc1lVRkJUeXhMUVVGTE5rSXNaMEpCUVV3c1IwRkRUR0lzWVVGQllTeERRVUZEYVVVc2JVSkJRV1FzUTBGQmEwTkVMRk5CUVd4RExFVkJRVFpEYUVZc1QwRkJOME1zUlVGQmMwUXNTMEZCZEVRc1EwRkVTeXhIUVVWTVowSXNZVUZCWVN4RFFVRkRhMFVzVjBGQlpDeERRVUV3UWl4UFFVRlBSaXhUUVVGcVF5eEZRVUUwUTJoR0xFOUJRVFZETEVOQlJrWTdSVUZIUkR0RlFYUldTRHRGUVVGQk8wVkJRVUVzTWtOQmQxWjVRanRGUVVOeVFpeFZRVUZOYlVZc1kwRkJZeXhIUVVGTExFVkJRWHBDTzBWQlEwRXNWVUZCVFVNc1owSkJRV2RDTEVkQlFVY3NSVUZCZWtJN1JVRkZRU3hWUVVGSmFrUXNVMEZCVXl4SFFVRkhMRXRCUVV0aUxGVkJRWEpDT3p0RlFVTkJMRlZCUVVrc1MwRkJTMFlzWlVGQlRDeExRVUY1UWl4UlFVRTNRaXhGUVVGMVF6dEZRVU55UTJVc1VVRkJRVUVzVTBGQlV5eG5RMEZCVDBFc1UwRkJVQ3h6UWtGQmNVSXNTMEZCUzJRc1UwRkJUQ3hEUVVGbFlTeE5RVUZtTEVOQlFYTkNReXhUUVVFelF5eEZRVUZVTzBWQlEwUTdPMFZCUlVSQkxFMUJRVUZCTEZOQlFWTXNRMEZCUTJ0RUxFbEJRVllzUTBGRFJTeFZRVUZEUXl4RFFVRkVMRVZCUVVsRExFTkJRVW83UlVGQlFTeGxRVU5GTEVOQlFVTkJMRU5CUVVNc1EwRkJRM0pHTEZGQlFVWXNSMEZCWVhGR0xFTkJRVU1zUTBGQlEzSkdMRkZCUVVZc1EwRkJWeTlETEZGQlFWZ3NRMEZCYjBKUkxFMUJRV3BETEVkQlFUQkRMRU5CUVRORExFdEJRME15U0N4RFFVRkRMRU5CUVVOd1JpeFJRVUZHTEVkQlFXRnZSaXhEUVVGRExFTkJRVU53Uml4UlFVRkdMRU5CUVZjdlF5eFJRVUZZTEVOQlFXOUNVU3hOUVVGcVF5eEhRVUV3UXl4RFFVUXpReXhEUVVSR08wVkJRVUVzVDBGRVJpeEZRVWxGTmtnc1QwRktSaXhEUVVsVkxGVkJRVU5ETEVOQlFVUXNSVUZCVHp0RlFVTm1MRmxCUVVsRExGRkJRVkVzUjBGQlJ5eERRVUZETEVOQlFXaENPenRGUVVOQkxHRkJRVXNzU1VGQlNXaEpMRU5CUVVNc1IwRkJSeXhEUVVGaUxFVkJRV2RDUVN4RFFVRkRMRWRCUVVjd1NDeG5Ra0ZCWjBJc1EwRkJRM3BJTEUxQlFYSkRMRVZCUVRaRFJDeERRVUZETEVsQlFVa3NRMEZCYkVRc1JVRkJjVVE3UlVGRGJrUXNZMEZCU1RCSUxHZENRVUZuUWl4RFFVRkRNVWdzUTBGQlJDeERRVUZvUWl4TFFVRjNRaXhKUVVGNFFpeEpRVUZuUXl0SUxFTkJRVU1zUTBGQlEzWkdMRkZCUVVZc1MwRkJaU3hKUVVFdlF5eEpRVU5CYTBZc1owSkJRV2RDTEVOQlFVTXhTQ3hEUVVGRUxFTkJRV2hDTEV0QlFYZENMRWxCUVhoQ0xFbEJRV2RETUVnc1owSkJRV2RDTEVOQlFVTXhTQ3hEUVVGRUxFTkJRV2hDTEVOQlFXOUNkMFlzVDBGQmNFSXNRMEZCTkVKMVF5eERRVUZETEVOQlFVTjJSaXhSUVVFNVFpeERRVVJ3UXl4RlFVTTJSVHRGUVVNelJYZEdMRmxCUVVGQkxGRkJRVkVzUjBGQlIyaEpMRU5CUVZnN1JVRkRSRHRGUVVOR096dEZRVU5FTEZsQlFVbG5TU3hSUVVGUkxFdEJRVXNzUTBGQlF5eERRVUZzUWl4RlFVRnhRanRGUVVOdVFrRXNWVUZCUVVFc1VVRkJVU3hIUVVGSFRpeG5Ra0ZCWjBJc1EwRkJRM3BJTEUxQlFUVkNPMFZCUTBGNVNDeFZRVUZCUVN4blFrRkJaMElzUTBGQlEzWkhMRWxCUVdwQ0xFTkJRWE5DTkVjc1EwRkJReXhEUVVGRGRrWXNVVUZCZUVJN1JVRkRSRHM3UlVGRFJDeFpRVUZKTEVOQlFVTnBSaXhqUVVGakxFTkJRVU5QTEZGQlFVUXNRMEZCYmtJc1JVRkJLMEk3UlVGRE4wSlFMRlZCUVVGQkxHTkJRV01zUTBGQlEwOHNVVUZCUkN4RFFVRmtMRWRCUVRKQ0xFVkJRVE5DTzBWQlEwUTdPMFZCUTBSUUxGRkJRVUZCTEdOQlFXTXNRMEZCUTA4c1VVRkJSQ3hEUVVGa0xFTkJRWGxDTjBjc1NVRkJla0lzUTBGQk9FSTBSeXhEUVVFNVFqdEZRVU5FTEU5QmNFSkVPMFZCYzBKQkxHRkJRVTlPTEdOQlFWQTdSVUZEUkR0RlFYaFlTRHRGUVVGQk8wVkJRVUVzYlVOQk1GaHBRbFlzUzBFeFdHcENMRVZCTUZoM1FqdEZRVUZCT3p0RlFVTndRaXhWUVVGSk5VSXNZVUZCWVN4SFFVRkhMRXRCUVhCQ08wVkJSVUUwUWl4TlFVRkJRU3hMUVVGTExFdEJRVXRCTEV0QlFVc3NSMEZCUnl4RlFVRmlMRU5CUVV3N08wVkJRMEZCTEUxQlFVRkJMRXRCUVVzc1EwRkJRelZDTEdGQlFVNHNSMEZCYzBJc1dVRkJUVHRGUVVGRlFTeFJRVUZCUVN4aFFVRmhMRWRCUVVjc1NVRkJhRUk3UlVGQmRVSXNUMEZCY2tRN08wVkJRMEUwUWl4TlFVRkJRU3hMUVVGTExFTkJRVU12UlN4WFFVRk9MRWRCUVhOQ0xFdEJRVXQ1UWl4UFFVRk1MRU5CUVdGNlFpeFhRVUZpTEVOQlFYbENNVUlzUzBGQmVrSXNRMEZCSzBJc1EwRkJMMElzUTBGQmRFSTdSVUZGUVN4VlFVRk5lVUlzWjBKQlFXZENMRWRCUVVjc1MwRkJTekJDTEU5QlFVd3NRMEZCWVRGQ0xHZENRVUYwUXpzN1JVRkRRU3hWUVVGTlF5eFhRVUZYTEVkQlFWRXNTMEZCUzNsQ0xFOUJRVXdzUTBGQllYcENMRmRCUVdJc1EwRkJlVUl4UWl4TFFVRjZRaXhEUVVFclFpeERRVUV2UWl4RFFVRjZRanM3UlVGRFFTeFZRVUZOYlVnc1kwRkJZeXhIUVVGTExFdEJRVXRSTEc5Q1FVRk1MRVZCUVhwQ096dEZRVlJ2UWl4cFEwRlhXR3BKTEVOQldGYzdSVUZaYkVJc1dVRkJUWGxGTEZOQlFWTXNSMEZCUjJkRUxHTkJRV01zUTBGQlEzcElMRU5CUVVRc1EwRkJhRU03UlVGRFFTeFpRVUZOZDBNc1VVRkJVU3hIUVVGSmFVTXNVMEZCVXl4RFFVRkRMRU5CUVVRc1EwRkJWQ3hEUVVGaGFrTXNVVUZCTDBJN08wVkJSVUVzV1VGRFJVRXNVVUZCVVN4TFFVRkxMRWxCUVdJc1NVRkRRVUVzVVVGQlVTeERRVUZEVnl4TFFVRlVMRU5CUVdWdVFpeFhRVUZtTEV0QlEwRkVMR2RDUVVGblFpeERRVUZEYlVjc1NVRkJha0lzUTBGQmMwSXNWVUZCUVVNc1EwRkJRenRGUVVGQkxHbENRVUZKTTBZc1VVRkJVU3hEUVVGREwwTXNVVUZCVkN4RFFVRnJRakpKTEZGQlFXeENMRU5CUVRKQ1JDeERRVUV6UWl4RFFVRktPMFZCUVVFc1UwRkJka0lzUTBGSVJpeEZRVWxGTzBWQlEwRXNaVUZCU3l4SlFVRkpOVWdzUTBGQlF5eEhRVUZITEVOQlFXSXNSVUZCWjBKQkxFTkJRVU1zUjBGQlIydEZMRk5CUVZNc1EwRkJRM2hGTEUxQlFUbENMRVZCUVhORFRTeERRVUZETEVsQlFVa3NRMEZCTTBNc1JVRkJPRU03UlVGRE5VTXNaMEpCUVVrclJTeFJRVUZSTEVkQlFVZGlMRk5CUVZNc1EwRkJRMnhGTEVOQlFVUXNRMEZCZUVJN08wVkJSVUVzWjBKQlFVa3NRMEZCUXl0RkxGRkJRVkVzUTBGQlEwWXNaMEpCUVZZc1NVRkJPRUpGTEZGQlFWRXNRMEZCUTFBc1dVRkJka01zU1VGQmRVUXNRMEZCUTA4c1VVRkJVU3hEUVVGRFNDeGhRVUZ5UlN4RlFVRnZSanRGUVVOc1JrY3NZMEZCUVVFc1VVRkJVU3hEUVVGRFJpeG5Ra0ZCVkN4SFFVRTBRaXhKUVVFMVFqdEZRVU5CUlN4alFVRkJRU3hSUVVGUkxFTkJRVU5RTEZsQlFWUXNRMEZCYzBKelJDeEpRVUYwUWl4RFFVRXlRaXhOUVVFelFpeEZRVUZwUTNSQ0xFdEJRV3BETzBWQlEwRjZRaXhqUVVGQlFTeFJRVUZSTEVOQlFVTkdMR2RDUVVGVUxFZEJRVFJDTEV0QlFUVkNPenRGUVVWQkxHdENRVUZKUkN4aFFVRmhMRWxCUVVsSExGRkJRVkVzUTBGQlEwd3NjMEpCUVRsQ0xFVkJRWE5FTzBWQlEzQkVTeXhuUWtGQlFVRXNVVUZCVVN4RFFVRkRTQ3hoUVVGVUxFZEJRWGxDTEVsQlFYcENPMFZCUTBGQkxHZENRVUZCUVN4aFFVRmhMRWRCUVZrc1MwRkJla0k3UlVGRFJEdEZRVU5HT3p0RlFVVkVMR2RDUVVGSkxFMUJRVWtzUTBGQlEzUkNMR2xDUVVGTUxFTkJRWFZDYmtRc1QwRkJka0lzUTBGQkswSTBSU3hSUVVFdlFpeE5RVUUyUXl4RFFVRkRMRU5CUVd4RUxFVkJRWEZFTzBWQlEyNUVMR05CUVVFc1RVRkJTU3hEUVVGRGVrSXNhVUpCUVV3c1EwRkJkVUl4UXl4SlFVRjJRaXhEUVVFMFFtMUZMRkZCUVRWQ08wVkJRMFE3UlVGRFJqczdSVUZGUkN4alFVRkpPVU1zVVVGQlNpeEZRVUZqTzBWQlExb3NhVUpCUVVzc1NVRkJTV3BETEVWQlFVTXNSMEZCUnl4RFFVRmlMRVZCUVdkQ1FTeEZRVUZETEVkQlFVZHBReXhSUVVGUkxFTkJRVU12UXl4UlFVRlVMRU5CUVd0Q1VTeE5RVUYwUXl4RlFVRTRRMDBzUlVGQlF5eEpRVUZKTEVOQlFXNUVMRVZCUVhORU8wVkJRM0JFTEd0Q1FVRk5SU3hMUVVGTExFZEJRVWQxUWl4WFFVRlhMRU5CUVVOMFFpeFBRVUZhTEVOQlFXOUNPRUlzVVVGQlVTeERRVUZETDBNc1VVRkJWQ3hEUVVGclFtTXNSVUZCYkVJc1EwRkJjRUlzUTBGQlpEczdSVUZEUVN4clFrRkJTVVVzUzBGQlN5eExRVUZMTEVOQlFVTXNRMEZCWml4RlFVRnJRanRGUVVOb1FuVkNMR2RDUVVGQlFTeFhRVUZYTEVOQlFVTnlRaXhOUVVGYUxFTkJRVzFDUml4TFFVRnVRaXhGUVVFd1FpeERRVUV4UWp0RlFVTkJSaXhuUWtGQlFVRXNSVUZCUXl4SlFVRkpMRU5CUVV3N1JVRkRSRHRGUVVOR08wVkJRMFk3UlVGRFJqdEZRV2hFYVVJN08wVkJWM0JDTEZkQlFVc3NTVUZCU1ZBc1EwRkJReXhIUVVGSExFTkJRV0lzUlVGQlowSkJMRU5CUVVNc1IwRkJSM2xJTEdOQlFXTXNRMEZCUTNoSUxFMUJRVzVETEVWQlFUSkRSQ3hEUVVGRExFbEJRVWtzUTBGQmFFUXNSVUZCYlVRN1JVRkJRU3hqUVVFeFEwRXNRMEZCTUVNN1JVRnpRMnhFTzBWQlEwWTdSVUUxWVVnN1JVRkJRVHRGUVVGQkxHMURRVGhoYVVJclJ5eExRVGxoYWtJc1JVRTRZWGRDTzBWQlEzQkNRU3hOUVVGQlFTeExRVUZMTEV0QlFVdEJMRXRCUVVzc1IwRkJSeXhGUVVGaUxFTkJRVXc3UlVGRFFVRXNUVUZCUVVFc1MwRkJTeXhEUVVGREwwVXNWMEZCVGl4SFFVRnZRaXhMUVVGTGVVSXNUMEZCVEN4RFFVRmhla0lzVjBGQllpeERRVUY1UWpGQ0xFdEJRWHBDTEVOQlFTdENMRU5CUVM5Q0xFTkJRWEJDT3p0RlFVVkJMRmRCUVVzc1NVRkJTVTRzUTBGQlF5eEhRVUZITEVOQlFXSXNSVUZCWjBKQkxFTkJRVU1zUjBGQlJ5eExRVUZMTmtRc2FVSkJRVXdzUTBGQmRVSTFSQ3hOUVVFelF5eEZRVUZ0UkVRc1EwRkJReXhKUVVGSkxFTkJRWGhFTEVWQlFUSkVPMFZCUTNwRUxGbEJRVTF6Uml4UlFVRlJMRWRCUVVjc1MwRkJTM3BDTEdsQ1FVRk1MRU5CUVhWQ04wUXNRMEZCZGtJc1EwRkJha0k3UlVGRFFTeFpRVUZOZDBNc1VVRkJVU3hIUVVGSE9FTXNVVUZCVVN4RFFVRkRPVU1zVVVGQk1VSTdPMFZCUTBFc1dVRkJTVUVzVVVGQlVTeExRVUZMTEVsQlFXSXNTVUZCY1VJc1EwRkJRMEVzVVVGQlVTeERRVUZEVnl4TFFVRlVMRU5CUVdVc1MwRkJTMDBzVDBGQlRDeERRVUZoZWtJc1YwRkJOVUlzUTBGQk1VSXNSVUZCYjBVN1JVRkRiRVZ6UkN4VlFVRkJRU3hSUVVGUkxFTkJRVU5JTEdGQlFWUXNSMEZCZVVJc1MwRkJla0k3TzBWQlEwRXNZMEZCU1RORExGRkJRVkVzUzBGQlN5eEpRVUZpTEVsQlFYRkNkVVVzUzBGQlN5eERRVUZETDBVc1YwRkJUaXhEUVVGclFpOUNMRTFCUVd4Q0xFdEJRVFpDTEVOQlFYUkVMRVZCUVhsRU8wVkJRM1pFTEdsQ1FVRkxORVFzYVVKQlFVd3NRMEZCZFVKc1JDeE5RVUYyUWl4RFFVRTRRbGdzUTBGQk9VSXNSVUZCYVVNc1EwRkJha003TzBWQlEwRkJMRmxCUVVGQkxFTkJRVU1zU1VGQlNTeERRVUZNTzBWQlEwUTdPMFZCUTBRc1kwRkJTU3hEUVVGRGMwWXNVVUZCVVN4RFFVRkRSaXhuUWtGQlZpeEpRVUU0UWtVc1VVRkJVU3hEUVVGRFRpeGpRVUV6UXl4RlFVRXlSRHRGUVVONlJFMHNXVUZCUVVFc1VVRkJVU3hEUVVGRFJpeG5Ra0ZCVkN4SFFVRTBRaXhKUVVFMVFqdEZRVU5CUlN4WlFVRkJRU3hSUVVGUkxFTkJRVU5PTEdOQlFWUXNRMEZCZDBKeFJDeEpRVUY0UWl4RFFVRTJRaXhKUVVFM1FpeEZRVUZ0UTNSQ0xFdEJRVzVETzBWQlEwRjZRaXhaUVVGQlFTeFJRVUZSTEVOQlFVTkdMR2RDUVVGVUxFZEJRVFJDTEV0QlFUVkNPMFZCUTBRN1JVRkRSanRGUVVOR08wVkJRMFk3UlVGc1kwZzdSVUZCUVR0RlFVRkJMSE5EUVc5amIwSXlRaXhMUVhCamNFSXNSVUZ2WXpKQ1JpeFJRWEJqTTBJc1JVRnZZM0ZETzBWQlEycERPMFZCUTBFN1JVRkRRU3hWUVVGTmVVSXNXVUZCV1N4SFFVRkhMRU5CUVVNc1QwRkJSQ3hGUVVGVkxFMUJRVllzUlVGQmEwSXNTMEZCYkVJc1JVRkJlVUlzVlVGQmVrSXNSVUZCY1VNc1MwRkJja01zUlVGQk5FTXNVMEZCTlVNc1EwRkJja0k3TzBWQlEwRXNWVUZCU1hwQ0xGRkJRVkVzUTBGQlF6QkNMRXRCUVZRc1EwRkJaU3hMUVVGbUxFdEJRWGxDTEV0QlFVczVSU3hQUVVGTUxFTkJRV0Y2UWl4WFFVRmlMRU5CUVhsQ2IwY3NVVUZCZWtJc1EwRkJhME1zVTBGQmJFTXNRMEZCZWtJc1NVRkRRU3hEUVVGRFJTeFpRVUZaTEVOQlFVTkdMRkZCUVdJc1EwRkJjMElzUzBGQlN6TkZMRTlCUVV3c1EwRkJZVm9zVjBGQllpeERRVUY1UW10RkxFdEJRVXNzUTBGQlF6RkZMRTlCUVM5Q0xFVkJRWGRETEVOQlFYaERMRU5CUVhSQ0xFTkJSRXdzUlVGRGQwVTdSVUZEZEVVc1lVRkJTMmRETEcxQ1FVRk1MRU5CUVhsQ01FTXNTMEZCZWtJN1JVRkRSRHRGUVVOR08wVkJOV05JT3p0RlFVRkJPMFZCUVVFN08wVkRTRThzVTBGQlUzbENMRVZCUVZRc1EwRkJXVFZFTEUxQlFWb3NSVUZCYjBKcFF5eFJRVUZ3UWl4RlFVRTRRa1lzVTBGQk9VSXNSVUZCZVVNN1JVRkZPVU03UlVGRFFTOUNMRVZCUVVGQkxFMUJRVTBzUTBGQlF6WkVMRmRCUVZBc1EwRkJiVUlzUTBGQmJrSXNSVUZCZDBJc1EwRkJReXhSUVVGRUxFTkJRWGhDTzBWQlEwRTNSQ3hGUVVGQlFTeE5RVUZOTEVOQlFVTTJSQ3hYUVVGUUxFTkJRVzFDTEVOQlFXNUNMRVZCUVhkQ0xFTkJRVU1zVjBGQlJDeERRVUY0UWp0RlFVTkJOMFFzUlVGQlFVRXNUVUZCVFN4RFFVRkROa1FzVjBGQlVDeERRVUZ0UWl4RFFVRnVRaXhGUVVGM1FpeERRVUZETEV0QlFVUXNRMEZCZUVJN1JVRkRRVGRFTEVWQlFVRkJMRTFCUVUwc1EwRkJRelpFTEZkQlFWQXNRMEZCYlVJc1JVRkJia0lzUlVGQmQwSXNRMEZCUXl4UFFVRkVMRU5CUVhoQ08wVkJRMEUzUkN4RlFVRkJRU3hOUVVGTkxFTkJRVU0yUkN4WFFVRlFMRU5CUVcxQ0xFVkJRVzVDTEVWQlFYZENMRU5CUVVNc1QwRkJSQ3hEUVVGNFFqdEZRVU5CTjBRc1JVRkJRVUVzVFVGQlRTeERRVUZETmtRc1YwRkJVQ3hEUVVGdFFpeEZRVUZ1UWl4RlFVRjNRaXhEUVVGRExFOUJRVVFzUTBGQmVFSTdSVUZEUVRkRUxFVkJRVUZCTEUxQlFVMHNRMEZCUXpaRUxGZEJRVkFzUTBGQmJVSXNSVUZCYmtJc1JVRkJkMElzUTBGQlF5eE5RVUZFTEVOQlFYaENPMFZCUTBFM1JDeEZRVUZCUVN4TlFVRk5MRU5CUVVNMlJDeFhRVUZRTEVOQlFXMUNMRVZCUVc1Q0xFVkJRWGRDTEVOQlFVTXNTMEZCUkN4RlFVRlJMRTFCUVZJc1EwRkJlRUk3UlVGRFFUZEVMRVZCUVVGQkxFMUJRVTBzUTBGQlF6WkVMRmRCUVZBc1EwRkJiVUlzUlVGQmJrSXNSVUZCZDBJc1EwRkJReXhQUVVGRUxFVkJRVlVzVDBGQlZpeERRVUY0UWp0RlFVTkJOMFFzUlVGQlFVRXNUVUZCVFN4RFFVRkROa1FzVjBGQlVDeERRVUZ0UWl4RlFVRnVRaXhGUVVGM1FpeERRVUZETEZWQlFVUXNRMEZCZUVJN1JVRkRRVGRFTEVWQlFVRkJMRTFCUVUwc1EwRkJRelpFTEZkQlFWQXNRMEZCYlVJc1JVRkJia0lzUlVGQmQwSXNRMEZCUXl4UlFVRkVMRVZCUVZjc1MwRkJXQ3hEUVVGNFFqdEZRVU5CTjBRc1JVRkJRVUVzVFVGQlRTeERRVUZETmtRc1YwRkJVQ3hEUVVGdFFpeEZRVUZ1UWl4RlFVRjNRaXhEUVVGRExFOUJRVVFzUlVGQlZTeFZRVUZXTEVOQlFYaENPMFZCUTBFM1JDeEZRVUZCUVN4TlFVRk5MRU5CUVVNMlJDeFhRVUZRTEVOQlFXMUNMRVZCUVc1Q0xFVkJRWGRDTEVOQlFVTXNVVUZCUkN4RFFVRjRRanRGUVVOQk4wUXNSVUZCUVVFc1RVRkJUU3hEUVVGRE5rUXNWMEZCVUN4RFFVRnRRaXhGUVVGdVFpeEZRVUYzUWl4RFFVRkRMRlZCUVVRc1EwRkJlRUk3UlVGRFFUZEVMRVZCUVVGQkxFMUJRVTBzUTBGQlF6WkVMRmRCUVZBc1EwRkJiVUlzUlVGQmJrSXNSVUZCZDBJc1EwRkJReXhMUVVGRUxFTkJRWGhDTzBWQlEwRTNSQ3hGUVVGQlFTeE5RVUZOTEVOQlFVTTJSQ3hYUVVGUUxFTkJRVzFDTEVWQlFXNUNMRVZCUVhkQ0xFTkJRVU1zVFVGQlJDeERRVUY0UWp0RlFVTkJOMFFzUlVGQlFVRXNUVUZCVFN4RFFVRkROa1FzVjBGQlVDeERRVUZ0UWl4RlFVRnVRaXhGUVVGM1FpeERRVUZETEUxQlFVUXNRMEZCZUVJN1JVRkRRVGRFTEVWQlFVRkJMRTFCUVUwc1EwRkJRelpFTEZkQlFWQXNRMEZCYlVJc1JVRkJia0lzUlVGQmQwSXNRMEZCUXl4SlFVRkVMRU5CUVhoQ08wVkJRMEUzUkN4RlFVRkJRU3hOUVVGTkxFTkJRVU0yUkN4WFFVRlFMRU5CUVcxQ0xFVkJRVzVDTEVWQlFYZENMRU5CUVVNc1QwRkJSQ3hEUVVGNFFqdEZRVU5CTjBRc1JVRkJRVUVzVFVGQlRTeERRVUZETmtRc1YwRkJVQ3hEUVVGdFFpeEZRVUZ1UWl4RlFVRjNRaXhEUVVGRExFMUJRVVFzUTBGQmVFSTdSVUZEUVRkRUxFVkJRVUZCTEUxQlFVMHNRMEZCUXpaRUxGZEJRVkFzUTBGQmJVSXNSVUZCYmtJc1JVRkJkMElzUTBGQlF5eFJRVUZFTEVOQlFYaENPMFZCUTBFM1JDeEZRVUZCUVN4TlFVRk5MRU5CUVVNMlJDeFhRVUZRTEVOQlFXMUNMRVZCUVc1Q0xFVkJRWGRDTEVOQlFVTXNZVUZCUkN4RFFVRjRRanRGUVVOQk4wUXNSVUZCUVVFc1RVRkJUU3hEUVVGRE5rUXNWMEZCVUN4RFFVRnRRaXhGUVVGdVFpeEZRVUYzUWl4RFFVRkRMRk5CUVVRc1EwRkJlRUk3UlVGRFFUZEVMRVZCUVVGQkxFMUJRVTBzUTBGQlF6WkVMRmRCUVZBc1EwRkJiVUlzUlVGQmJrSXNSVUZCZDBJc1EwRkJReXhWUVVGRUxFTkJRWGhDTzBWQlEwRTNSQ3hGUVVGQlFTeE5RVUZOTEVOQlFVTTJSQ3hYUVVGUUxFTkJRVzFDTEVWQlFXNUNMRVZCUVhkQ0xFTkJRVU1zVVVGQlJDeEZRVUZYTEV0QlFWZ3NRMEZCZUVJN1JVRkRRVGRFTEVWQlFVRkJMRTFCUVUwc1EwRkJRelpFTEZkQlFWQXNRMEZCYlVJc1JVRkJia0lzUlVGQmQwSXNRMEZCUXl4UlFVRkVMRVZCUVZjc1MwRkJXQ3hEUVVGNFFqdEZRVU5CTjBRc1JVRkJRVUVzVFVGQlRTeERRVUZETmtRc1YwRkJVQ3hEUVVGdFFpeEZRVUZ1UWl4RlFVRjNRaXhEUVVGRExFMUJRVVFzUTBGQmVFSTdSVUZEUVRkRUxFVkJRVUZCTEUxQlFVMHNRMEZCUXpaRUxGZEJRVkFzUTBGQmJVSXNSMEZCYmtJc1JVRkJkMElzUTBGQlF5eFpRVUZFTEVWQlFXVXNVVUZCWml4RFFVRjRRanRGUVVOQk4wUXNSVUZCUVVFc1RVRkJUU3hEUVVGRE5rUXNWMEZCVUN4RFFVRnRRaXhIUVVGdVFpeEZRVUYzUWl4RFFVRkRMRTlCUVVRc1JVRkJWU3hIUVVGV0xFTkJRWGhDTzBWQlEwRTNSQ3hGUVVGQlFTeE5RVUZOTEVOQlFVTTJSQ3hYUVVGUUxFTkJRVzFDTEVkQlFXNUNMRVZCUVhkQ0xFTkJRVU1zVVVGQlJDeEZRVUZYTEVkQlFWZ3NRMEZCZUVJN1JVRkRRVGRFTEVWQlFVRkJMRTFCUVUwc1EwRkJRelpFTEZkQlFWQXNRMEZCYlVJc1IwRkJia0lzUlVGQmQwSXNRMEZCUXl4UFFVRkVMRVZCUVZVc1kwRkJWaXhGUVVFd1FpeEhRVUV4UWl4RFFVRjRRanRGUVVOQk4wUXNSVUZCUVVFc1RVRkJUU3hEUVVGRE5rUXNWMEZCVUN4RFFVRnRRaXhIUVVGdVFpeEZRVUYzUWl4RFFVRkRMR0ZCUVVRc1JVRkJaMElzUjBGQmFFSXNRMEZCZUVJN1JVRkRRVGRFTEVWQlFVRkJMRTFCUVUwc1EwRkJRelpFTEZkQlFWQXNRMEZCYlVJc1IwRkJia0lzUlVGQmQwSXNRMEZCUXl4aFFVRkVMRVZCUVdkQ0xFZEJRV2hDTEVOQlFYaENPMFZCUTBFM1JDeEZRVUZCUVN4TlFVRk5MRU5CUVVNMlJDeFhRVUZRTEVOQlFXMUNMRWRCUVc1Q0xFVkJRWGRDTEVOQlFVTXNWMEZCUkN4RlFVRmpMRWxCUVdRc1EwRkJlRUk3UlVGRFFUZEVMRVZCUVVGQkxFMUJRVTBzUTBGQlF6WkVMRmRCUVZBc1EwRkJiVUlzUjBGQmJrSXNSVUZCZDBJc1EwRkJReXhqUVVGRUxFVkJRV2xDTEVkQlFXcENMRU5CUVhoQ08wVkJRMEUzUkN4RlFVRkJRU3hOUVVGTkxFTkJRVU0yUkN4WFFVRlFMRU5CUVcxQ0xFZEJRVzVDTEVWQlFYZENMRU5CUVVNc1dVRkJSQ3hGUVVGbExFbEJRV1lzUTBGQmVFSXNSVUYwUXpoRE96dEZRWGxET1VNM1JDeEZRVUZCUVN4TlFVRk5MRU5CUVVNMlJDeFhRVUZRTEVOQlFXMUNMRVZCUVc1Q0xFVkJRWFZDTEVOQlFVTXNUVUZCUkN4RlFVRlRMRWRCUVZRc1EwRkJka0k3UlVGRFFUZEVMRVZCUVVGQkxFMUJRVTBzUTBGQlF6WkVMRmRCUVZBc1EwRkJiVUlzUlVGQmJrSXNSVUZCZFVJc1EwRkJReXhMUVVGRUxFVkJRVkVzUjBGQlVpeERRVUYyUWp0RlFVTkJOMFFzUlVGQlFVRXNUVUZCVFN4RFFVRkROa1FzVjBGQlVDeERRVUZ0UWl4RlFVRnVRaXhGUVVGMVFpeERRVUZETEV0QlFVUXNSVUZCVVN4SFFVRlNMRU5CUVhaQ08wVkJRMEUzUkN4RlFVRkJRU3hOUVVGTkxFTkJRVU0yUkN4WFFVRlFMRU5CUVcxQ0xFVkJRVzVDTEVWQlFYVkNMRU5CUVVNc1QwRkJSQ3hGUVVGVkxFZEJRVllzUTBGQmRrSTdSVUZEUVRkRUxFVkJRVUZCTEUxQlFVMHNRMEZCUXpaRUxGZEJRVkFzUTBGQmJVSXNSVUZCYmtJc1JVRkJkVUlzUTBGQlF5eE5RVUZFTEVWQlFWTXNSMEZCVkN4RFFVRjJRanRGUVVOQk4wUXNSVUZCUVVFc1RVRkJUU3hEUVVGRE5rUXNWMEZCVUN4RFFVRnRRaXhGUVVGdVFpeEZRVUYxUWl4RFFVRkRMRTFCUVVRc1JVRkJVeXhIUVVGVUxFTkJRWFpDTzBWQlEwRTNSQ3hGUVVGQlFTeE5RVUZOTEVOQlFVTTJSQ3hYUVVGUUxFTkJRVzFDTEVWQlFXNUNMRVZCUVhWQ0xFTkJRVU1zUzBGQlJDeEZRVUZSTEVkQlFWSXNRMEZCZGtJN1JVRkRRVGRFTEVWQlFVRkJMRTFCUVUwc1EwRkJRelpFTEZkQlFWQXNRMEZCYlVJc1JVRkJia0lzUlVGQmRVSXNRMEZCUXl4UFFVRkVMRVZCUVZVc1IwRkJWaXhEUVVGMlFqdEZRVU5CTjBRc1JVRkJRVUVzVFVGQlRTeERRVUZETmtRc1YwRkJVQ3hEUVVGdFFpeEZRVUZ1UWl4RlFVRjFRaXhEUVVGRExFOUJRVVFzUlVGQlZTeEhRVUZXTEVOQlFYWkNPMFZCUTBFM1JDeEZRVUZCUVN4TlFVRk5MRU5CUVVNMlJDeFhRVUZRTEVOQlFXMUNMRVZCUVc1Q0xFVkJRWFZDTEVOQlFVTXNUVUZCUkN4RlFVRlRMRWRCUVZRc1EwRkJka0lzUlVGc1JEaERPenRGUVhGRU9VTTNSQ3hGUVVGQlFTeE5RVUZOTEVOQlFVTTJSQ3hYUVVGUUxFTkJRVzFDTEVWQlFXNUNMRVZCUVhWQ0xFTkJRVU1zVTBGQlJDeEZRVUZaTEUxQlFWb3NRMEZCZGtJN1JVRkRRVGRFTEVWQlFVRkJMRTFCUVUwc1EwRkJRelpFTEZkQlFWQXNRMEZCYlVJc1JVRkJia0lzUlVGQmRVSXNRMEZCUXl4UlFVRkVMRVZCUVZjc1RVRkJXQ3hEUVVGMlFqdEZRVU5CTjBRc1JVRkJRVUVzVFVGQlRTeERRVUZETmtRc1YwRkJVQ3hEUVVGdFFpeEZRVUZ1UWl4RlFVRjFRaXhEUVVGRExGRkJRVVFzUlVGQlZ5eE5RVUZZTEVOQlFYWkNPMFZCUTBFM1JDeEZRVUZCUVN4TlFVRk5MRU5CUVVNMlJDeFhRVUZRTEVOQlFXMUNMRVZCUVc1Q0xFVkJRWFZDTEVOQlFVTXNWVUZCUkN4RlFVRmhMRTFCUVdJc1EwRkJka0k3UlVGRFFUZEVMRVZCUVVGQkxFMUJRVTBzUTBGQlF6WkVMRmRCUVZBc1EwRkJiVUlzUjBGQmJrSXNSVUZCZDBJc1EwRkJReXhUUVVGRUxFVkJRVmtzVFVGQldpeERRVUY0UWp0RlFVTkJOMFFzUlVGQlFVRXNUVUZCVFN4RFFVRkROa1FzVjBGQlVDeERRVUZ0UWl4SFFVRnVRaXhGUVVGM1FpeERRVUZETEZOQlFVUXNSVUZCV1N4TlFVRmFMRU5CUVhoQ08wVkJRMEUzUkN4RlFVRkJRU3hOUVVGTkxFTkJRVU0yUkN4WFFVRlFMRU5CUVcxQ0xFZEJRVzVDTEVWQlFYZENMRU5CUVVNc1VVRkJSQ3hGUVVGWExFMUJRVmdzUTBGQmVFSTdSVUZEUVRkRUxFVkJRVUZCTEUxQlFVMHNRMEZCUXpaRUxGZEJRVkFzUTBGQmJVSXNSMEZCYmtJc1JVRkJkMElzUTBGQlF5eFZRVUZFTEVWQlFXRXNUVUZCWWl4RFFVRjRRanRGUVVOQk4wUXNSVUZCUVVFc1RVRkJUU3hEUVVGRE5rUXNWMEZCVUN4RFFVRnRRaXhIUVVGdVFpeEZRVUYzUWl4RFFVRkRMRlZCUVVRc1JVRkJZU3hOUVVGaUxFTkJRWGhDTzBWQlEwRTNSQ3hGUVVGQlFTeE5RVUZOTEVOQlFVTTJSQ3hYUVVGUUxFTkJRVzFDTEVkQlFXNUNMRVZCUVhkQ0xFTkJRVU1zVTBGQlJDeEZRVUZaTEUxQlFWb3NRMEZCZUVJN1JVRkRRVGRFTEVWQlFVRkJMRTFCUVUwc1EwRkJRelpFTEZkQlFWQXNRMEZCYlVJc1IwRkJia0lzUlVGQmQwSXNRMEZCUXl4aFFVRkVMRVZCUVdkQ0xFMUJRV2hDTEVOQlFYaENPMFZCUTBFM1JDeEZRVUZCUVN4TlFVRk5MRU5CUVVNMlJDeFhRVUZRTEVOQlFXMUNMRWRCUVc1Q0xFVkJRWGRDTEVOQlFVTXNVVUZCUkN4RlFVRlhMRTFCUVZnc1EwRkJlRUk3UlVGRFFUZEVMRVZCUVVGQkxFMUJRVTBzUTBGQlF6WkVMRmRCUVZBc1EwRkJiVUlzUjBGQmJrSXNSVUZCZDBJc1EwRkJReXhWUVVGRUxFTkJRWGhDTzBWQlEwRTNSQ3hGUVVGQlFTeE5RVUZOTEVOQlFVTTJSQ3hYUVVGUUxFTkJRVzFDTEVkQlFXNUNMRVZCUVhkQ0xFTkJRVU1zWVVGQlJDeEZRVUZuUWl4TlFVRm9RaXhEUVVGNFFqdEZRVU5CTjBRc1JVRkJRVUVzVFVGQlRTeERRVUZETmtRc1YwRkJVQ3hEUVVGdFFpeEhRVUZ1UWl4RlFVRjNRaXhEUVVGRExGbEJRVVFzUlVGQlpTeE5RVUZtTEVOQlFYaENPMFZCUTBFM1JDeEZRVUZCUVN4TlFVRk5MRU5CUVVNMlJDeFhRVUZRTEVOQlFXMUNMRWRCUVc1Q0xFVkJRWGRDTEVOQlFVTXNWMEZCUkN4RlFVRmpMRTFCUVdRc1EwRkJlRUk3UlVGRFFUZEVMRVZCUVVGQkxFMUJRVTBzUTBGQlF6WkVMRmRCUVZBc1EwRkJiVUlzUjBGQmJrSXNSVUZCZDBJc1EwRkJReXhUUVVGRUxFVkJRVmtzUzBGQldpeERRVUY0UWl4RlFYSkZPRU03TzBWQmQwVTVRemRFTEVWQlFVRkJMRTFCUVUwc1EwRkJRelpFTEZkQlFWQXNRMEZCYlVJc1IwRkJia0lzUlVGQmQwSXNRMEZCUXl4SlFVRkVMRU5CUVhoQ08wVkJRMEUzUkN4RlFVRkJRU3hOUVVGTkxFTkJRVU0yUkN4WFFVRlFMRU5CUVcxQ0xFZEJRVzVDTEVWQlFYZENMRU5CUVVNc1NVRkJSQ3hEUVVGNFFqdEZRVU5CTjBRc1JVRkJRVUVzVFVGQlRTeERRVUZETmtRc1YwRkJVQ3hEUVVGdFFpeEhRVUZ1UWl4RlFVRjNRaXhEUVVGRExFbEJRVVFzUTBGQmVFSTdSVUZEUVRkRUxFVkJRVUZCTEUxQlFVMHNRMEZCUXpaRUxGZEJRVkFzUTBGQmJVSXNSMEZCYmtJc1JVRkJkMElzUTBGQlF5eEpRVUZFTEVOQlFYaENPMFZCUTBFM1JDeEZRVUZCUVN4TlFVRk5MRU5CUVVNMlJDeFhRVUZRTEVOQlFXMUNMRWRCUVc1Q0xFVkJRWGRDTEVOQlFVTXNTVUZCUkN4RFFVRjRRanRGUVVOQk4wUXNSVUZCUVVFc1RVRkJUU3hEUVVGRE5rUXNWMEZCVUN4RFFVRnRRaXhIUVVGdVFpeEZRVUYzUWl4RFFVRkRMRWxCUVVRc1EwRkJlRUk3UlVGRFFUZEVMRVZCUVVGQkxFMUJRVTBzUTBGQlF6WkVMRmRCUVZBc1EwRkJiVUlzUjBGQmJrSXNSVUZCZDBJc1EwRkJReXhKUVVGRUxFTkJRWGhDTzBWQlEwRTNSQ3hGUVVGQlFTeE5RVUZOTEVOQlFVTTJSQ3hYUVVGUUxFTkJRVzFDTEVkQlFXNUNMRVZCUVhkQ0xFTkJRVU1zU1VGQlJDeERRVUY0UWp0RlFVTkJOMFFzUlVGQlFVRXNUVUZCVFN4RFFVRkROa1FzVjBGQlVDeERRVUZ0UWl4SFFVRnVRaXhGUVVGM1FpeERRVUZETEVsQlFVUXNRMEZCZUVJN1JVRkRRVGRFTEVWQlFVRkJMRTFCUVUwc1EwRkJRelpFTEZkQlFWQXNRMEZCYlVJc1IwRkJia0lzUlVGQmQwSXNRMEZCUXl4TFFVRkVMRU5CUVhoQ08wVkJRMEUzUkN4RlFVRkJRU3hOUVVGTkxFTkJRVU0yUkN4WFFVRlFMRU5CUVcxQ0xFZEJRVzVDTEVWQlFYZENMRU5CUVVNc1MwRkJSQ3hEUVVGNFFqdEZRVU5CTjBRc1JVRkJRVUVzVFVGQlRTeERRVUZETmtRc1YwRkJVQ3hEUVVGdFFpeEhRVUZ1UWl4RlFVRjNRaXhEUVVGRExFdEJRVVFzUTBGQmVFSTdSVUZEUVRkRUxFVkJRVUZCTEUxQlFVMHNRMEZCUXpaRUxGZEJRVkFzUTBGQmJVSXNSMEZCYmtJc1JVRkJkMElzUTBGQlF5eExRVUZFTEVOQlFYaENPMFZCUTBFM1JDeEZRVUZCUVN4TlFVRk5MRU5CUVVNMlJDeFhRVUZRTEVOQlFXMUNMRWRCUVc1Q0xFVkJRWGRDTEVOQlFVTXNTMEZCUkN4RFFVRjRRanRGUVVOQk4wUXNSVUZCUVVFc1RVRkJUU3hEUVVGRE5rUXNWMEZCVUN4RFFVRnRRaXhIUVVGdVFpeEZRVUYzUWl4RFFVRkRMRXRCUVVRc1EwRkJlRUk3UlVGRFFUZEVMRVZCUVVGQkxFMUJRVTBzUTBGQlF6WkVMRmRCUVZBc1EwRkJiVUlzUjBGQmJrSXNSVUZCZDBJc1EwRkJReXhMUVVGRUxFTkJRWGhDTzBWQlEwRTNSQ3hGUVVGQlFTeE5RVUZOTEVOQlFVTTJSQ3hYUVVGUUxFTkJRVzFDTEVkQlFXNUNMRVZCUVhkQ0xFTkJRVU1zUzBGQlJDeERRVUY0UWp0RlFVTkJOMFFzUlVGQlFVRXNUVUZCVFN4RFFVRkROa1FzVjBGQlVDeERRVUZ0UWl4SFFVRnVRaXhGUVVGM1FpeERRVUZETEV0QlFVUXNRMEZCZUVJN1JVRkRRVGRFTEVWQlFVRkJMRTFCUVUwc1EwRkJRelpFTEZkQlFWQXNRMEZCYlVJc1IwRkJia0lzUlVGQmQwSXNRMEZCUXl4TFFVRkVMRU5CUVhoQ08wVkJRMEUzUkN4RlFVRkJRU3hOUVVGTkxFTkJRVU0yUkN4WFFVRlFMRU5CUVcxQ0xFZEJRVzVDTEVWQlFYZENMRU5CUVVNc1MwRkJSQ3hEUVVGNFFqdEZRVU5CTjBRc1JVRkJRVUVzVFVGQlRTeERRVUZETmtRc1YwRkJVQ3hEUVVGdFFpeEhRVUZ1UWl4RlFVRjNRaXhEUVVGRExFdEJRVVFzUTBGQmVFSTdSVUZEUVRkRUxFVkJRVUZCTEUxQlFVMHNRMEZCUXpaRUxGZEJRVkFzUTBGQmJVSXNSMEZCYmtJc1JVRkJkMElzUTBGQlF5eExRVUZFTEVOQlFYaENPMFZCUTBFM1JDeEZRVUZCUVN4TlFVRk5MRU5CUVVNMlJDeFhRVUZRTEVOQlFXMUNMRWRCUVc1Q0xFVkJRWGRDTEVOQlFVTXNTMEZCUkN4RFFVRjRRanRGUVVOQk4wUXNSVUZCUVVFc1RVRkJUU3hEUVVGRE5rUXNWMEZCVUN4RFFVRnRRaXhIUVVGdVFpeEZRVUYzUWl4RFFVRkRMRXRCUVVRc1EwRkJlRUlzUlVFdlJqaERPenRGUVd0SE9VTTNSQ3hGUVVGQlFTeE5RVUZOTEVOQlFVTTRSQ3hUUVVGUUxFTkJRV2xDTEZkQlFXcENMRVZCUVRoQ0xFTkJRVU1zVDBGQlJDeEZRVUZWTEVkQlFWWXNRMEZCT1VJN1JVRkRRVGxFTEVWQlFVRkJMRTFCUVUwc1EwRkJRemhFTEZOQlFWQXNRMEZCYVVJc1YwRkJha0lzUlVGQk9FSXNRMEZCUXl4aFFVRkVMRVZCUVdkQ0xHdENRVUZvUWl4RlFVRnZReXhIUVVGd1F5eERRVUU1UWp0RlFVTkJPVVFzUlVGQlFVRXNUVUZCVFN4RFFVRkRPRVFzVTBGQlVDeERRVUZwUWl4WFFVRnFRaXhGUVVFNFFpeERRVUZETEVsQlFVUXNSVUZCVHl4SFFVRlFMRU5CUVRsQ08wVkJRMEU1UkN4RlFVRkJRU3hOUVVGTkxFTkJRVU00UkN4VFFVRlFMRU5CUVdsQ0xGZEJRV3BDTEVWQlFUaENMRU5CUVVNc1VVRkJSQ3hGUVVGWExFZEJRVmdzUTBGQk9VSTdSVUZEUVRsRUxFVkJRVUZCTEUxQlFVMHNRMEZCUXpoRUxGTkJRVkFzUTBGQmFVSXNWMEZCYWtJc1JVRkJPRUlzUTBGQlF5eFJRVUZFTEVWQlFWY3NVMEZCV0N4RlFVRnpRaXhaUVVGMFFpeEZRVUZ2UXl4SFFVRndReXhEUVVFNVFqdEZRVU5CT1VRc1JVRkJRVUVzVFVGQlRTeERRVUZET0VRc1UwRkJVQ3hEUVVGcFFpeFhRVUZxUWl4RlFVRTRRaXhEUVVGRExGTkJRVVFzUlVGQldTeEhRVUZhTEVOQlFUbENPMFZCUTBFNVJDeEZRVUZCUVN4TlFVRk5MRU5CUVVNNFJDeFRRVUZRTEVOQlFXbENMRmRCUVdwQ0xFVkJRVGhDTEVOQlFVTXNUMEZCUkN4RlFVRlZMRWRCUVZZc1EwRkJPVUk3UlVGRFFUbEVMRVZCUVVGQkxFMUJRVTBzUTBGQlF6aEVMRk5CUVZBc1EwRkJhVUlzVjBGQmFrSXNSVUZCT0VJc1EwRkJReXhYUVVGRUxFVkJRV01zUzBGQlpDeEZRVUZ4UWl4SFFVRnlRaXhEUVVFNVFqdEZRVU5CT1VRc1JVRkJRVUVzVFVGQlRTeERRVUZET0VRc1UwRkJVQ3hEUVVGcFFpeFhRVUZxUWl4RlFVRTRRaXhEUVVGRExGVkJRVVFzUlVGQllTeEhRVUZpTEVOQlFUbENPMFZCUTBFNVJDeEZRVUZCUVN4TlFVRk5MRU5CUVVNNFJDeFRRVUZRTEVOQlFXbENMRmRCUVdwQ0xFVkJRVGhDTEVOQlFVTXNWMEZCUkN4RlFVRmpMRWRCUVdRc1EwRkJPVUk3UlVGRFFUbEVMRVZCUVVGQkxFMUJRVTBzUTBGQlF6aEVMRk5CUVZBc1EwRkJhVUlzVjBGQmFrSXNSVUZCT0VJc1EwRkJReXhaUVVGRUxFVkJRV1VzUjBGQlppeERRVUU1UWp0RlFVTkJPVVFzUlVGQlFVRXNUVUZCVFN4RFFVRkRPRVFzVTBGQlVDeERRVUZwUWl4WFFVRnFRaXhGUVVFNFFpeERRVUZETEZsQlFVUXNSVUZCWlN4SFFVRm1MRU5CUVRsQ08wVkJRMEU1UkN4RlFVRkJRU3hOUVVGTkxFTkJRVU00UkN4VFFVRlFMRU5CUVdsQ0xGZEJRV3BDTEVWQlFUaENMRU5CUVVNc1RVRkJSQ3hGUVVGVExFZEJRVlFzUTBGQk9VSTdSVUZEUVRsRUxFVkJRVUZCTEUxQlFVMHNRMEZCUXpoRUxGTkJRVkFzUTBGQmFVSXNWMEZCYWtJc1JVRkJPRUlzUTBGQlF5eG5Ra0ZCUkN4RlFVRnRRaXhyUWtGQmJrSXNSVUZCZFVNc1IwRkJka01zUTBGQk9VSTdSVUZEUVRsRUxFVkJRVUZCTEUxQlFVMHNRMEZCUXpoRUxGTkJRVkFzUTBGQmFVSXNWMEZCYWtJc1JVRkJPRUlzUTBGQlF5eHBRa0ZCUkN4RlFVRnZRaXh0UWtGQmNFSXNSVUZCZVVNc1IwRkJla01zUTBGQk9VSTdSVUZEUVRsRUxFVkJRVUZCTEUxQlFVMHNRMEZCUXpoRUxGTkJRVkFzUTBGQmFVSXNXVUZCYWtJc1JVRkJLMElzUTBGQlF5eGhRVUZFTEVWQlFXZENMRWRCUVdoQ0xFTkJRUzlDTzBWQlEwRTVSQ3hGUVVGQlFTeE5RVUZOTEVOQlFVTTRSQ3hUUVVGUUxFTkJRV2xDTEZkQlFXcENMRVZCUVRoQ0xFTkJRVU1zVDBGQlJDeEZRVUZWTEVkQlFWWXNRMEZCT1VJN1JVRkRRVGxFTEVWQlFVRkJMRTFCUVUwc1EwRkJRemhFTEZOQlFWQXNRMEZCYVVJc1dVRkJha0lzUlVGQkswSXNRMEZCUXl4bFFVRkVMRVZCUVd0Q0xFbEJRV3hDTEVOQlFTOUNPMFZCUTBFNVJDeEZRVUZCUVN4TlFVRk5MRU5CUVVNNFJDeFRRVUZRTEVOQlFXbENMRmxCUVdwQ0xFVkJRU3RDTEVOQlFVTXNhMEpCUVVRc1JVRkJjVUlzUjBGQmNrSXNRMEZCTDBJN1JVRkRRVGxFTEVWQlFVRkJMRTFCUVUwc1EwRkJRemhFTEZOQlFWQXNRMEZCYVVJc1YwRkJha0lzUlVGQk9FSXNRMEZCUXl4dFFrRkJSQ3hGUVVGelFpeEhRVUYwUWl4RFFVRTVRanRGUVVOQk9VUXNSVUZCUVVFc1RVRkJUU3hEUVVGRE9FUXNVMEZCVUN4RFFVRnBRaXhYUVVGcVFpeEZRVUU0UWl4RFFVRkRMR05CUVVRc1JVRkJhVUlzUjBGQmFrSXNRMEZCT1VJN08wVkJSVUVzVFVGQlNUZENMRkZCUVZFc1EwRkJRekJDTEV0QlFWUXNRMEZCWlN4TFFVRm1MRU5CUVVvc1JVRkJNa0k3UlVGRGVrSXpSQ3hKUVVGQlFTeE5RVUZOTEVOQlFVTTRSQ3hUUVVGUUxFTkJRV2xDTEZOQlFXcENMRVZCUVRSQ0xFTkJRVU1zUzBGQlJDeEZRVUZSTEZWQlFWSXNRMEZCTlVJN1JVRkRSQ3hIUVVaRUxFMUJSVTg3UlVGRFREbEVMRWxCUVVGQkxFMUJRVTBzUTBGQlF6aEVMRk5CUVZBc1EwRkJhVUlzVFVGQmFrSXNSVUZCZVVJc1EwRkJReXhMUVVGRUxFVkJRVkVzVlVGQlVpeERRVUY2UWp0RlFVTkVMRWRCTlVnMlF6czdPMFZCSzBnNVF5eFBRVUZMTEVsQlFVbHlSeXhQUVVGUExFZEJRVWNzUlVGQmJrSXNSVUZCZFVKQkxFOUJRVThzU1VGQlNTeEZRVUZzUXl4RlFVRnpRMEVzVDBGQlR5eEpRVUZKTEVOQlFXcEVMRVZCUVc5RU8wVkJRMnhFTEZGQlFVazNRaXhQUVVGUExFZEJRVWR0U1N4TlFVRk5MRU5CUVVORExGbEJRVkFzUTBGQmIwSjJSeXhQUVVGUExFZEJRVWNzUlVGQk9VSXNRMEZCWkR0RlFVTkJMRkZCUVVsM1J5eGpRVUZqTEVkQlFVZEdMRTFCUVUwc1EwRkJRME1zV1VGQlVDeERRVUZ2UW5aSExFOUJRWEJDTEVOQlFYSkNPMFZCUTBSMVF5eEpRVUZCUVN4TlFVRk5MRU5CUVVNMlJDeFhRVUZRTEVOQlFXMUNjRWNzVDBGQmJrSXNSVUZCTkVJM1FpeFBRVUUxUWp0RlFVTkJiMFVzU1VGQlFVRXNUVUZCVFN4RFFVRkRPRVFzVTBGQlVDeERRVUZwUWl4aFFVRmhiRWtzVDBGQk9VSXNSVUZCZFVOeFNTeGpRVUYyUXp0RlFVTkJha1VzU1VGQlFVRXNUVUZCVFN4RFFVRkRPRVFzVTBGQlVDeERRVUZwUWl4blFrRkJaMEpzU1N4UFFVRnFReXhGUVVFd1EzRkpMR05CUVRGRE8wVkJRMEVzUjBGeVNUWkRPenM3UlVGM1NUbERMRTFCUVUxRExHZENRVUZuUWl4SFFVRkhia01zVTBGQlV5eERRVUZETkVJc1MwRkJWaXhEUVVGblFpeFRRVUZvUWl4SlFVRTJRaXhGUVVFM1FpeEhRVUZ0UXl4SFFVRTFSRHRGUVVOQkxFMUJRVTFSTEZkQlFWY3NSMEZCVVhCRExGTkJRVk1zUTBGQlF6UkNMRXRCUVZZc1EwRkJaMElzVTBGQmFFSXNTVUZCTmtJc1IwRkJOMElzUjBGQmJVTXNSMEZCTlVRN1JVRkRRU3hOUVVGTlV5eFpRVUZaTEVkQlFVOXlReXhUUVVGVExFTkJRVU0wUWl4TFFVRldMRU5CUVdkQ0xGTkJRV2hDTEVsQlFUWkNMRVZCUVRkQ0xFZEJRVzFETEVkQlFUVkVPMFZCUTBFc1RVRkJTVlVzYTBKQlFVbzdSVUZEUVN4TlFVRkpReXh0UWtGQlNqczdSVUZEUVN4TlFVRkpja01zVVVGQlVTeERRVUZETUVJc1MwRkJWQ3hEUVVGbExFdEJRV1lzVFVGQk1FSTFRaXhUUVVGVExFTkJRVU0wUWl4TFFVRldMRU5CUVdkQ0xGRkJRV2hDTEV0QlFUWkNOVUlzVTBGQlV5eERRVUZETkVJc1MwRkJWaXhEUVVGblFpeFJRVUZvUWl4RFFVRjJSQ3hEUVVGS0xFVkJRWFZHTzBWQlEzSkdWU3hKUVVGQlFTeHJRa0ZCYTBJc1IwRkJTU3hGUVVGMFFqdEZRVU5CUXl4SlFVRkJRU3h0UWtGQmJVSXNSMEZCUnl4RlFVRjBRanRGUVVORUxFZEJTRVFzVFVGSFR5eEpRVUZIY2tNc1VVRkJVU3hEUVVGRE1FSXNTMEZCVkN4RFFVRmxMRXRCUVdZc1MwRkJlVUkxUWl4VFFVRlRMRU5CUVVNMFFpeExRVUZXTEVOQlFXZENMRTlCUVdoQ0xFTkJRVFZDTEVWQlFYTkVPMFZCUXpORVZTeEpRVUZCUVN4clFrRkJhMElzUjBGQlNTeEZRVUYwUWp0RlFVTkJReXhKUVVGQlFTeHRRa0ZCYlVJc1IwRkJSeXhGUVVGMFFqdEZRVU5FTEVkQlNFMHNUVUZIUVN4SlFVRkhja01zVVVGQlVTeERRVUZETUVJc1MwRkJWQ3hEUVVGbExFdEJRV1lzUzBGQmVVSTFRaXhUUVVGVExFTkJRVU0wUWl4TFFVRldMRU5CUVdkQ0xGTkJRV2hDTEVOQlFUVkNMRVZCUVhkRU8wVkJRemRFVlN4SlFVRkJRU3hyUWtGQmEwSXNSMEZCU1N4SFFVRjBRanRGUVVOQlF5eEpRVUZCUVN4dFFrRkJiVUlzUjBGQlJ5eEhRVUYwUWp0RlFVTkVPenRGUVVORWRFVXNSVUZCUVVFc1RVRkJUU3hEUVVGRE5rUXNWMEZCVUN4RFFVRnRRa3NzWjBKQlFXNUNMRVZCUVhkRExFTkJRVU1zVjBGQlJDeEZRVUZqTEVkQlFXUXNRMEZCZUVNN1JVRkRRV3hGTEVWQlFVRkJMRTFCUVUwc1EwRkJRelpFTEZkQlFWQXNRMEZCYlVKTkxGZEJRVzVDTEVWQlFYZERMRU5CUVVNc1RVRkJSQ3hGUVVGVExFZEJRVlFzUTBGQmVFTTdSVUZEUVc1RkxFVkJRVUZCTEUxQlFVMHNRMEZCUXpaRUxGZEJRVkFzUTBGQmJVSlBMRmxCUVc1Q0xFVkJRWGRETEVOQlFVTXNUMEZCUkN4RlFVRlZMRmRCUVZZc1JVRkJkVUlzUjBGQmRrSXNRMEZCZUVNN1JVRkRRWEJGTEVWQlFVRkJMRTFCUVUwc1EwRkJRelpFTEZkQlFWQXNRMEZCYlVKUkxHdENRVUZ1UWl4RlFVRjNReXhEUVVGRExGTkJRVVFzUlVGQldTeFRRVUZhTEVWQlFYVkNMRXRCUVhaQ0xFVkJRVGhDTEU5QlFUbENMRVZCUVhWRExHRkJRWFpETEVWQlFYTkVMR0ZCUVhSRUxFVkJRWEZGTEZOQlFYSkZMRVZCUVdkR0xGZEJRV2hHTEVOQlFYaERPMFZCUTBGeVJTeEZRVUZCUVN4TlFVRk5MRU5CUVVNMlJDeFhRVUZRTEVOQlFXMUNVeXh0UWtGQmJrSXNSVUZCZDBNc1EwRkJReXhUUVVGRUxFVkJRVmtzVTBGQldpeEZRVUYxUWl4TFFVRjJRaXhGUVVFNFFpeFBRVUU1UWl4RlFVRjFReXhqUVVGMlF5eEZRVUYxUkN4alFVRjJSQ3hGUVVGMVJTeFZRVUYyUlN4RlFVRnRSaXhaUVVGdVJpeERRVUY0UXl4RlFUTktPRU03TzBWQk9FbzVRM1JGTEVWQlFVRkJMRTFCUVUwc1EwRkJRMnBETEZWQlFWQXNRMEZCYTBJc1UwRkJiRUk3UlVGRFJEczdUVU16U2t0M1J5eFJRVUZSTEVkQlFVY3NTVUZCU1M5R0xGRkJRVW83UlVGRmFrSXJSaXhSUVVGUkxFTkJRVU5ETEZOQlFWUXNRMEZCYlVJc1NVRkJia0lzUlVGQmVVSmFMRVZCUVhwQ08wVkJSVUZYTEZGQlFWRXNRMEZCUXk5R0xGRkJRVlFzUjBGQmIwSkJMRkZCUVhCQ08wVkJRMEVyUml4UlFVRlJMRU5CUVVOMlNDeE5RVUZVTEVkQlFXdENRU3hOUVVGc1FqdEZRVU5CZFVnc1VVRkJVU3hEUVVGREwwb3NVVUZCVkN4SFFVRnZRa0VzVVVGQmNFSTdPenM3T3pzN095SjlcbiIsIi8qKlxuICogQGxpY2Vuc2VcbiAqIExvZGFzaCA8aHR0cHM6Ly9sb2Rhc2guY29tLz5cbiAqIENvcHlyaWdodCBPcGVuSlMgRm91bmRhdGlvbiBhbmQgb3RoZXIgY29udHJpYnV0b3JzIDxodHRwczovL29wZW5qc2Yub3JnLz5cbiAqIFJlbGVhc2VkIHVuZGVyIE1JVCBsaWNlbnNlIDxodHRwczovL2xvZGFzaC5jb20vbGljZW5zZT5cbiAqIEJhc2VkIG9uIFVuZGVyc2NvcmUuanMgMS44LjMgPGh0dHA6Ly91bmRlcnNjb3JlanMub3JnL0xJQ0VOU0U+XG4gKiBDb3B5cmlnaHQgSmVyZW15IEFzaGtlbmFzLCBEb2N1bWVudENsb3VkIGFuZCBJbnZlc3RpZ2F0aXZlIFJlcG9ydGVycyAmIEVkaXRvcnNcbiAqL1xuOyhmdW5jdGlvbigpIHtcblxuICAvKiogVXNlZCBhcyBhIHNhZmUgcmVmZXJlbmNlIGZvciBgdW5kZWZpbmVkYCBpbiBwcmUtRVM1IGVudmlyb25tZW50cy4gKi9cbiAgdmFyIHVuZGVmaW5lZDtcblxuICAvKiogVXNlZCBhcyB0aGUgc2VtYW50aWMgdmVyc2lvbiBudW1iZXIuICovXG4gIHZhciBWRVJTSU9OID0gJzQuMTcuMjEnO1xuXG4gIC8qKiBVc2VkIGFzIHRoZSBzaXplIHRvIGVuYWJsZSBsYXJnZSBhcnJheSBvcHRpbWl6YXRpb25zLiAqL1xuICB2YXIgTEFSR0VfQVJSQVlfU0laRSA9IDIwMDtcblxuICAvKiogRXJyb3IgbWVzc2FnZSBjb25zdGFudHMuICovXG4gIHZhciBDT1JFX0VSUk9SX1RFWFQgPSAnVW5zdXBwb3J0ZWQgY29yZS1qcyB1c2UuIFRyeSBodHRwczovL25wbXMuaW8vc2VhcmNoP3E9cG9ueWZpbGwuJyxcbiAgICAgIEZVTkNfRVJST1JfVEVYVCA9ICdFeHBlY3RlZCBhIGZ1bmN0aW9uJyxcbiAgICAgIElOVkFMSURfVEVNUExfVkFSX0VSUk9SX1RFWFQgPSAnSW52YWxpZCBgdmFyaWFibGVgIG9wdGlvbiBwYXNzZWQgaW50byBgXy50ZW1wbGF0ZWAnO1xuXG4gIC8qKiBVc2VkIHRvIHN0YW5kLWluIGZvciBgdW5kZWZpbmVkYCBoYXNoIHZhbHVlcy4gKi9cbiAgdmFyIEhBU0hfVU5ERUZJTkVEID0gJ19fbG9kYXNoX2hhc2hfdW5kZWZpbmVkX18nO1xuXG4gIC8qKiBVc2VkIGFzIHRoZSBtYXhpbXVtIG1lbW9pemUgY2FjaGUgc2l6ZS4gKi9cbiAgdmFyIE1BWF9NRU1PSVpFX1NJWkUgPSA1MDA7XG5cbiAgLyoqIFVzZWQgYXMgdGhlIGludGVybmFsIGFyZ3VtZW50IHBsYWNlaG9sZGVyLiAqL1xuICB2YXIgUExBQ0VIT0xERVIgPSAnX19sb2Rhc2hfcGxhY2Vob2xkZXJfXyc7XG5cbiAgLyoqIFVzZWQgdG8gY29tcG9zZSBiaXRtYXNrcyBmb3IgY2xvbmluZy4gKi9cbiAgdmFyIENMT05FX0RFRVBfRkxBRyA9IDEsXG4gICAgICBDTE9ORV9GTEFUX0ZMQUcgPSAyLFxuICAgICAgQ0xPTkVfU1lNQk9MU19GTEFHID0gNDtcblxuICAvKiogVXNlZCB0byBjb21wb3NlIGJpdG1hc2tzIGZvciB2YWx1ZSBjb21wYXJpc29ucy4gKi9cbiAgdmFyIENPTVBBUkVfUEFSVElBTF9GTEFHID0gMSxcbiAgICAgIENPTVBBUkVfVU5PUkRFUkVEX0ZMQUcgPSAyO1xuXG4gIC8qKiBVc2VkIHRvIGNvbXBvc2UgYml0bWFza3MgZm9yIGZ1bmN0aW9uIG1ldGFkYXRhLiAqL1xuICB2YXIgV1JBUF9CSU5EX0ZMQUcgPSAxLFxuICAgICAgV1JBUF9CSU5EX0tFWV9GTEFHID0gMixcbiAgICAgIFdSQVBfQ1VSUllfQk9VTkRfRkxBRyA9IDQsXG4gICAgICBXUkFQX0NVUlJZX0ZMQUcgPSA4LFxuICAgICAgV1JBUF9DVVJSWV9SSUdIVF9GTEFHID0gMTYsXG4gICAgICBXUkFQX1BBUlRJQUxfRkxBRyA9IDMyLFxuICAgICAgV1JBUF9QQVJUSUFMX1JJR0hUX0ZMQUcgPSA2NCxcbiAgICAgIFdSQVBfQVJZX0ZMQUcgPSAxMjgsXG4gICAgICBXUkFQX1JFQVJHX0ZMQUcgPSAyNTYsXG4gICAgICBXUkFQX0ZMSVBfRkxBRyA9IDUxMjtcblxuICAvKiogVXNlZCBhcyBkZWZhdWx0IG9wdGlvbnMgZm9yIGBfLnRydW5jYXRlYC4gKi9cbiAgdmFyIERFRkFVTFRfVFJVTkNfTEVOR1RIID0gMzAsXG4gICAgICBERUZBVUxUX1RSVU5DX09NSVNTSU9OID0gJy4uLic7XG5cbiAgLyoqIFVzZWQgdG8gZGV0ZWN0IGhvdCBmdW5jdGlvbnMgYnkgbnVtYmVyIG9mIGNhbGxzIHdpdGhpbiBhIHNwYW4gb2YgbWlsbGlzZWNvbmRzLiAqL1xuICB2YXIgSE9UX0NPVU5UID0gODAwLFxuICAgICAgSE9UX1NQQU4gPSAxNjtcblxuICAvKiogVXNlZCB0byBpbmRpY2F0ZSB0aGUgdHlwZSBvZiBsYXp5IGl0ZXJhdGVlcy4gKi9cbiAgdmFyIExBWllfRklMVEVSX0ZMQUcgPSAxLFxuICAgICAgTEFaWV9NQVBfRkxBRyA9IDIsXG4gICAgICBMQVpZX1dISUxFX0ZMQUcgPSAzO1xuXG4gIC8qKiBVc2VkIGFzIHJlZmVyZW5jZXMgZm9yIHZhcmlvdXMgYE51bWJlcmAgY29uc3RhbnRzLiAqL1xuICB2YXIgSU5GSU5JVFkgPSAxIC8gMCxcbiAgICAgIE1BWF9TQUZFX0lOVEVHRVIgPSA5MDA3MTk5MjU0NzQwOTkxLFxuICAgICAgTUFYX0lOVEVHRVIgPSAxLjc5NzY5MzEzNDg2MjMxNTdlKzMwOCxcbiAgICAgIE5BTiA9IDAgLyAwO1xuXG4gIC8qKiBVc2VkIGFzIHJlZmVyZW5jZXMgZm9yIHRoZSBtYXhpbXVtIGxlbmd0aCBhbmQgaW5kZXggb2YgYW4gYXJyYXkuICovXG4gIHZhciBNQVhfQVJSQVlfTEVOR1RIID0gNDI5NDk2NzI5NSxcbiAgICAgIE1BWF9BUlJBWV9JTkRFWCA9IE1BWF9BUlJBWV9MRU5HVEggLSAxLFxuICAgICAgSEFMRl9NQVhfQVJSQVlfTEVOR1RIID0gTUFYX0FSUkFZX0xFTkdUSCA+Pj4gMTtcblxuICAvKiogVXNlZCB0byBhc3NvY2lhdGUgd3JhcCBtZXRob2RzIHdpdGggdGhlaXIgYml0IGZsYWdzLiAqL1xuICB2YXIgd3JhcEZsYWdzID0gW1xuICAgIFsnYXJ5JywgV1JBUF9BUllfRkxBR10sXG4gICAgWydiaW5kJywgV1JBUF9CSU5EX0ZMQUddLFxuICAgIFsnYmluZEtleScsIFdSQVBfQklORF9LRVlfRkxBR10sXG4gICAgWydjdXJyeScsIFdSQVBfQ1VSUllfRkxBR10sXG4gICAgWydjdXJyeVJpZ2h0JywgV1JBUF9DVVJSWV9SSUdIVF9GTEFHXSxcbiAgICBbJ2ZsaXAnLCBXUkFQX0ZMSVBfRkxBR10sXG4gICAgWydwYXJ0aWFsJywgV1JBUF9QQVJUSUFMX0ZMQUddLFxuICAgIFsncGFydGlhbFJpZ2h0JywgV1JBUF9QQVJUSUFMX1JJR0hUX0ZMQUddLFxuICAgIFsncmVhcmcnLCBXUkFQX1JFQVJHX0ZMQUddXG4gIF07XG5cbiAgLyoqIGBPYmplY3QjdG9TdHJpbmdgIHJlc3VsdCByZWZlcmVuY2VzLiAqL1xuICB2YXIgYXJnc1RhZyA9ICdbb2JqZWN0IEFyZ3VtZW50c10nLFxuICAgICAgYXJyYXlUYWcgPSAnW29iamVjdCBBcnJheV0nLFxuICAgICAgYXN5bmNUYWcgPSAnW29iamVjdCBBc3luY0Z1bmN0aW9uXScsXG4gICAgICBib29sVGFnID0gJ1tvYmplY3QgQm9vbGVhbl0nLFxuICAgICAgZGF0ZVRhZyA9ICdbb2JqZWN0IERhdGVdJyxcbiAgICAgIGRvbUV4Y1RhZyA9ICdbb2JqZWN0IERPTUV4Y2VwdGlvbl0nLFxuICAgICAgZXJyb3JUYWcgPSAnW29iamVjdCBFcnJvcl0nLFxuICAgICAgZnVuY1RhZyA9ICdbb2JqZWN0IEZ1bmN0aW9uXScsXG4gICAgICBnZW5UYWcgPSAnW29iamVjdCBHZW5lcmF0b3JGdW5jdGlvbl0nLFxuICAgICAgbWFwVGFnID0gJ1tvYmplY3QgTWFwXScsXG4gICAgICBudW1iZXJUYWcgPSAnW29iamVjdCBOdW1iZXJdJyxcbiAgICAgIG51bGxUYWcgPSAnW29iamVjdCBOdWxsXScsXG4gICAgICBvYmplY3RUYWcgPSAnW29iamVjdCBPYmplY3RdJyxcbiAgICAgIHByb21pc2VUYWcgPSAnW29iamVjdCBQcm9taXNlXScsXG4gICAgICBwcm94eVRhZyA9ICdbb2JqZWN0IFByb3h5XScsXG4gICAgICByZWdleHBUYWcgPSAnW29iamVjdCBSZWdFeHBdJyxcbiAgICAgIHNldFRhZyA9ICdbb2JqZWN0IFNldF0nLFxuICAgICAgc3RyaW5nVGFnID0gJ1tvYmplY3QgU3RyaW5nXScsXG4gICAgICBzeW1ib2xUYWcgPSAnW29iamVjdCBTeW1ib2xdJyxcbiAgICAgIHVuZGVmaW5lZFRhZyA9ICdbb2JqZWN0IFVuZGVmaW5lZF0nLFxuICAgICAgd2Vha01hcFRhZyA9ICdbb2JqZWN0IFdlYWtNYXBdJyxcbiAgICAgIHdlYWtTZXRUYWcgPSAnW29iamVjdCBXZWFrU2V0XSc7XG5cbiAgdmFyIGFycmF5QnVmZmVyVGFnID0gJ1tvYmplY3QgQXJyYXlCdWZmZXJdJyxcbiAgICAgIGRhdGFWaWV3VGFnID0gJ1tvYmplY3QgRGF0YVZpZXddJyxcbiAgICAgIGZsb2F0MzJUYWcgPSAnW29iamVjdCBGbG9hdDMyQXJyYXldJyxcbiAgICAgIGZsb2F0NjRUYWcgPSAnW29iamVjdCBGbG9hdDY0QXJyYXldJyxcbiAgICAgIGludDhUYWcgPSAnW29iamVjdCBJbnQ4QXJyYXldJyxcbiAgICAgIGludDE2VGFnID0gJ1tvYmplY3QgSW50MTZBcnJheV0nLFxuICAgICAgaW50MzJUYWcgPSAnW29iamVjdCBJbnQzMkFycmF5XScsXG4gICAgICB1aW50OFRhZyA9ICdbb2JqZWN0IFVpbnQ4QXJyYXldJyxcbiAgICAgIHVpbnQ4Q2xhbXBlZFRhZyA9ICdbb2JqZWN0IFVpbnQ4Q2xhbXBlZEFycmF5XScsXG4gICAgICB1aW50MTZUYWcgPSAnW29iamVjdCBVaW50MTZBcnJheV0nLFxuICAgICAgdWludDMyVGFnID0gJ1tvYmplY3QgVWludDMyQXJyYXldJztcblxuICAvKiogVXNlZCB0byBtYXRjaCBlbXB0eSBzdHJpbmcgbGl0ZXJhbHMgaW4gY29tcGlsZWQgdGVtcGxhdGUgc291cmNlLiAqL1xuICB2YXIgcmVFbXB0eVN0cmluZ0xlYWRpbmcgPSAvXFxiX19wIFxcKz0gJyc7L2csXG4gICAgICByZUVtcHR5U3RyaW5nTWlkZGxlID0gL1xcYihfX3AgXFwrPSkgJycgXFwrL2csXG4gICAgICByZUVtcHR5U3RyaW5nVHJhaWxpbmcgPSAvKF9fZVxcKC4qP1xcKXxcXGJfX3RcXCkpIFxcK1xcbicnOy9nO1xuXG4gIC8qKiBVc2VkIHRvIG1hdGNoIEhUTUwgZW50aXRpZXMgYW5kIEhUTUwgY2hhcmFjdGVycy4gKi9cbiAgdmFyIHJlRXNjYXBlZEh0bWwgPSAvJig/OmFtcHxsdHxndHxxdW90fCMzOSk7L2csXG4gICAgICByZVVuZXNjYXBlZEh0bWwgPSAvWyY8PlwiJ10vZyxcbiAgICAgIHJlSGFzRXNjYXBlZEh0bWwgPSBSZWdFeHAocmVFc2NhcGVkSHRtbC5zb3VyY2UpLFxuICAgICAgcmVIYXNVbmVzY2FwZWRIdG1sID0gUmVnRXhwKHJlVW5lc2NhcGVkSHRtbC5zb3VyY2UpO1xuXG4gIC8qKiBVc2VkIHRvIG1hdGNoIHRlbXBsYXRlIGRlbGltaXRlcnMuICovXG4gIHZhciByZUVzY2FwZSA9IC88JS0oW1xcc1xcU10rPyklPi9nLFxuICAgICAgcmVFdmFsdWF0ZSA9IC88JShbXFxzXFxTXSs/KSU+L2csXG4gICAgICByZUludGVycG9sYXRlID0gLzwlPShbXFxzXFxTXSs/KSU+L2c7XG5cbiAgLyoqIFVzZWQgdG8gbWF0Y2ggcHJvcGVydHkgbmFtZXMgd2l0aGluIHByb3BlcnR5IHBhdGhzLiAqL1xuICB2YXIgcmVJc0RlZXBQcm9wID0gL1xcLnxcXFsoPzpbXltcXF1dKnwoW1wiJ10pKD86KD8hXFwxKVteXFxcXF18XFxcXC4pKj9cXDEpXFxdLyxcbiAgICAgIHJlSXNQbGFpblByb3AgPSAvXlxcdyokLyxcbiAgICAgIHJlUHJvcE5hbWUgPSAvW14uW1xcXV0rfFxcWyg/OigtP1xcZCsoPzpcXC5cXGQrKT8pfChbXCInXSkoKD86KD8hXFwyKVteXFxcXF18XFxcXC4pKj8pXFwyKVxcXXwoPz0oPzpcXC58XFxbXFxdKSg/OlxcLnxcXFtcXF18JCkpL2c7XG5cbiAgLyoqXG4gICAqIFVzZWQgdG8gbWF0Y2ggYFJlZ0V4cGBcbiAgICogW3N5bnRheCBjaGFyYWN0ZXJzXShodHRwOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi83LjAvI3NlYy1wYXR0ZXJucykuXG4gICAqL1xuICB2YXIgcmVSZWdFeHBDaGFyID0gL1tcXFxcXiQuKis/KClbXFxde318XS9nLFxuICAgICAgcmVIYXNSZWdFeHBDaGFyID0gUmVnRXhwKHJlUmVnRXhwQ2hhci5zb3VyY2UpO1xuXG4gIC8qKiBVc2VkIHRvIG1hdGNoIGxlYWRpbmcgd2hpdGVzcGFjZS4gKi9cbiAgdmFyIHJlVHJpbVN0YXJ0ID0gL15cXHMrLztcblxuICAvKiogVXNlZCB0byBtYXRjaCBhIHNpbmdsZSB3aGl0ZXNwYWNlIGNoYXJhY3Rlci4gKi9cbiAgdmFyIHJlV2hpdGVzcGFjZSA9IC9cXHMvO1xuXG4gIC8qKiBVc2VkIHRvIG1hdGNoIHdyYXAgZGV0YWlsIGNvbW1lbnRzLiAqL1xuICB2YXIgcmVXcmFwQ29tbWVudCA9IC9cXHsoPzpcXG5cXC9cXCogXFxbd3JhcHBlZCB3aXRoIC4rXFxdIFxcKlxcLyk/XFxuPy8sXG4gICAgICByZVdyYXBEZXRhaWxzID0gL1xce1xcblxcL1xcKiBcXFt3cmFwcGVkIHdpdGggKC4rKVxcXSBcXCovLFxuICAgICAgcmVTcGxpdERldGFpbHMgPSAvLD8gJiAvO1xuXG4gIC8qKiBVc2VkIHRvIG1hdGNoIHdvcmRzIGNvbXBvc2VkIG9mIGFscGhhbnVtZXJpYyBjaGFyYWN0ZXJzLiAqL1xuICB2YXIgcmVBc2NpaVdvcmQgPSAvW15cXHgwMC1cXHgyZlxceDNhLVxceDQwXFx4NWItXFx4NjBcXHg3Yi1cXHg3Zl0rL2c7XG5cbiAgLyoqXG4gICAqIFVzZWQgdG8gdmFsaWRhdGUgdGhlIGB2YWxpZGF0ZWAgb3B0aW9uIGluIGBfLnRlbXBsYXRlYCB2YXJpYWJsZS5cbiAgICpcbiAgICogRm9yYmlkcyBjaGFyYWN0ZXJzIHdoaWNoIGNvdWxkIHBvdGVudGlhbGx5IGNoYW5nZSB0aGUgbWVhbmluZyBvZiB0aGUgZnVuY3Rpb24gYXJndW1lbnQgZGVmaW5pdGlvbjpcbiAgICogLSBcIigpLFwiIChtb2RpZmljYXRpb24gb2YgZnVuY3Rpb24gcGFyYW1ldGVycylcbiAgICogLSBcIj1cIiAoZGVmYXVsdCB2YWx1ZSlcbiAgICogLSBcIltde31cIiAoZGVzdHJ1Y3R1cmluZyBvZiBmdW5jdGlvbiBwYXJhbWV0ZXJzKVxuICAgKiAtIFwiL1wiIChiZWdpbm5pbmcgb2YgYSBjb21tZW50KVxuICAgKiAtIHdoaXRlc3BhY2VcbiAgICovXG4gIHZhciByZUZvcmJpZGRlbklkZW50aWZpZXJDaGFycyA9IC9bKCk9LHt9XFxbXFxdXFwvXFxzXS87XG5cbiAgLyoqIFVzZWQgdG8gbWF0Y2ggYmFja3NsYXNoZXMgaW4gcHJvcGVydHkgcGF0aHMuICovXG4gIHZhciByZUVzY2FwZUNoYXIgPSAvXFxcXChcXFxcKT8vZztcblxuICAvKipcbiAgICogVXNlZCB0byBtYXRjaFxuICAgKiBbRVMgdGVtcGxhdGUgZGVsaW1pdGVyc10oaHR0cDovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNy4wLyNzZWMtdGVtcGxhdGUtbGl0ZXJhbC1sZXhpY2FsLWNvbXBvbmVudHMpLlxuICAgKi9cbiAgdmFyIHJlRXNUZW1wbGF0ZSA9IC9cXCRcXHsoW15cXFxcfV0qKD86XFxcXC5bXlxcXFx9XSopKilcXH0vZztcblxuICAvKiogVXNlZCB0byBtYXRjaCBgUmVnRXhwYCBmbGFncyBmcm9tIHRoZWlyIGNvZXJjZWQgc3RyaW5nIHZhbHVlcy4gKi9cbiAgdmFyIHJlRmxhZ3MgPSAvXFx3KiQvO1xuXG4gIC8qKiBVc2VkIHRvIGRldGVjdCBiYWQgc2lnbmVkIGhleGFkZWNpbWFsIHN0cmluZyB2YWx1ZXMuICovXG4gIHZhciByZUlzQmFkSGV4ID0gL15bLStdMHhbMC05YS1mXSskL2k7XG5cbiAgLyoqIFVzZWQgdG8gZGV0ZWN0IGJpbmFyeSBzdHJpbmcgdmFsdWVzLiAqL1xuICB2YXIgcmVJc0JpbmFyeSA9IC9eMGJbMDFdKyQvaTtcblxuICAvKiogVXNlZCB0byBkZXRlY3QgaG9zdCBjb25zdHJ1Y3RvcnMgKFNhZmFyaSkuICovXG4gIHZhciByZUlzSG9zdEN0b3IgPSAvXlxcW29iamVjdCAuKz9Db25zdHJ1Y3RvclxcXSQvO1xuXG4gIC8qKiBVc2VkIHRvIGRldGVjdCBvY3RhbCBzdHJpbmcgdmFsdWVzLiAqL1xuICB2YXIgcmVJc09jdGFsID0gL14wb1swLTddKyQvaTtcblxuICAvKiogVXNlZCB0byBkZXRlY3QgdW5zaWduZWQgaW50ZWdlciB2YWx1ZXMuICovXG4gIHZhciByZUlzVWludCA9IC9eKD86MHxbMS05XVxcZCopJC87XG5cbiAgLyoqIFVzZWQgdG8gbWF0Y2ggTGF0aW4gVW5pY29kZSBsZXR0ZXJzIChleGNsdWRpbmcgbWF0aGVtYXRpY2FsIG9wZXJhdG9ycykuICovXG4gIHZhciByZUxhdGluID0gL1tcXHhjMC1cXHhkNlxceGQ4LVxceGY2XFx4ZjgtXFx4ZmZcXHUwMTAwLVxcdTAxN2ZdL2c7XG5cbiAgLyoqIFVzZWQgdG8gZW5zdXJlIGNhcHR1cmluZyBvcmRlciBvZiB0ZW1wbGF0ZSBkZWxpbWl0ZXJzLiAqL1xuICB2YXIgcmVOb01hdGNoID0gLygkXikvO1xuXG4gIC8qKiBVc2VkIHRvIG1hdGNoIHVuZXNjYXBlZCBjaGFyYWN0ZXJzIGluIGNvbXBpbGVkIHN0cmluZyBsaXRlcmFscy4gKi9cbiAgdmFyIHJlVW5lc2NhcGVkU3RyaW5nID0gL1snXFxuXFxyXFx1MjAyOFxcdTIwMjlcXFxcXS9nO1xuXG4gIC8qKiBVc2VkIHRvIGNvbXBvc2UgdW5pY29kZSBjaGFyYWN0ZXIgY2xhc3Nlcy4gKi9cbiAgdmFyIHJzQXN0cmFsUmFuZ2UgPSAnXFxcXHVkODAwLVxcXFx1ZGZmZicsXG4gICAgICByc0NvbWJvTWFya3NSYW5nZSA9ICdcXFxcdTAzMDAtXFxcXHUwMzZmJyxcbiAgICAgIHJlQ29tYm9IYWxmTWFya3NSYW5nZSA9ICdcXFxcdWZlMjAtXFxcXHVmZTJmJyxcbiAgICAgIHJzQ29tYm9TeW1ib2xzUmFuZ2UgPSAnXFxcXHUyMGQwLVxcXFx1MjBmZicsXG4gICAgICByc0NvbWJvUmFuZ2UgPSByc0NvbWJvTWFya3NSYW5nZSArIHJlQ29tYm9IYWxmTWFya3NSYW5nZSArIHJzQ29tYm9TeW1ib2xzUmFuZ2UsXG4gICAgICByc0RpbmdiYXRSYW5nZSA9ICdcXFxcdTI3MDAtXFxcXHUyN2JmJyxcbiAgICAgIHJzTG93ZXJSYW5nZSA9ICdhLXpcXFxceGRmLVxcXFx4ZjZcXFxceGY4LVxcXFx4ZmYnLFxuICAgICAgcnNNYXRoT3BSYW5nZSA9ICdcXFxceGFjXFxcXHhiMVxcXFx4ZDdcXFxceGY3JyxcbiAgICAgIHJzTm9uQ2hhclJhbmdlID0gJ1xcXFx4MDAtXFxcXHgyZlxcXFx4M2EtXFxcXHg0MFxcXFx4NWItXFxcXHg2MFxcXFx4N2ItXFxcXHhiZicsXG4gICAgICByc1B1bmN0dWF0aW9uUmFuZ2UgPSAnXFxcXHUyMDAwLVxcXFx1MjA2ZicsXG4gICAgICByc1NwYWNlUmFuZ2UgPSAnIFxcXFx0XFxcXHgwYlxcXFxmXFxcXHhhMFxcXFx1ZmVmZlxcXFxuXFxcXHJcXFxcdTIwMjhcXFxcdTIwMjlcXFxcdTE2ODBcXFxcdTE4MGVcXFxcdTIwMDBcXFxcdTIwMDFcXFxcdTIwMDJcXFxcdTIwMDNcXFxcdTIwMDRcXFxcdTIwMDVcXFxcdTIwMDZcXFxcdTIwMDdcXFxcdTIwMDhcXFxcdTIwMDlcXFxcdTIwMGFcXFxcdTIwMmZcXFxcdTIwNWZcXFxcdTMwMDAnLFxuICAgICAgcnNVcHBlclJhbmdlID0gJ0EtWlxcXFx4YzAtXFxcXHhkNlxcXFx4ZDgtXFxcXHhkZScsXG4gICAgICByc1ZhclJhbmdlID0gJ1xcXFx1ZmUwZVxcXFx1ZmUwZicsXG4gICAgICByc0JyZWFrUmFuZ2UgPSByc01hdGhPcFJhbmdlICsgcnNOb25DaGFyUmFuZ2UgKyByc1B1bmN0dWF0aW9uUmFuZ2UgKyByc1NwYWNlUmFuZ2U7XG5cbiAgLyoqIFVzZWQgdG8gY29tcG9zZSB1bmljb2RlIGNhcHR1cmUgZ3JvdXBzLiAqL1xuICB2YXIgcnNBcG9zID0gXCJbJ1xcdTIwMTldXCIsXG4gICAgICByc0FzdHJhbCA9ICdbJyArIHJzQXN0cmFsUmFuZ2UgKyAnXScsXG4gICAgICByc0JyZWFrID0gJ1snICsgcnNCcmVha1JhbmdlICsgJ10nLFxuICAgICAgcnNDb21ibyA9ICdbJyArIHJzQ29tYm9SYW5nZSArICddJyxcbiAgICAgIHJzRGlnaXRzID0gJ1xcXFxkKycsXG4gICAgICByc0RpbmdiYXQgPSAnWycgKyByc0RpbmdiYXRSYW5nZSArICddJyxcbiAgICAgIHJzTG93ZXIgPSAnWycgKyByc0xvd2VyUmFuZ2UgKyAnXScsXG4gICAgICByc01pc2MgPSAnW14nICsgcnNBc3RyYWxSYW5nZSArIHJzQnJlYWtSYW5nZSArIHJzRGlnaXRzICsgcnNEaW5nYmF0UmFuZ2UgKyByc0xvd2VyUmFuZ2UgKyByc1VwcGVyUmFuZ2UgKyAnXScsXG4gICAgICByc0ZpdHogPSAnXFxcXHVkODNjW1xcXFx1ZGZmYi1cXFxcdWRmZmZdJyxcbiAgICAgIHJzTW9kaWZpZXIgPSAnKD86JyArIHJzQ29tYm8gKyAnfCcgKyByc0ZpdHogKyAnKScsXG4gICAgICByc05vbkFzdHJhbCA9ICdbXicgKyByc0FzdHJhbFJhbmdlICsgJ10nLFxuICAgICAgcnNSZWdpb25hbCA9ICcoPzpcXFxcdWQ4M2NbXFxcXHVkZGU2LVxcXFx1ZGRmZl0pezJ9JyxcbiAgICAgIHJzU3VyclBhaXIgPSAnW1xcXFx1ZDgwMC1cXFxcdWRiZmZdW1xcXFx1ZGMwMC1cXFxcdWRmZmZdJyxcbiAgICAgIHJzVXBwZXIgPSAnWycgKyByc1VwcGVyUmFuZ2UgKyAnXScsXG4gICAgICByc1pXSiA9ICdcXFxcdTIwMGQnO1xuXG4gIC8qKiBVc2VkIHRvIGNvbXBvc2UgdW5pY29kZSByZWdleGVzLiAqL1xuICB2YXIgcnNNaXNjTG93ZXIgPSAnKD86JyArIHJzTG93ZXIgKyAnfCcgKyByc01pc2MgKyAnKScsXG4gICAgICByc01pc2NVcHBlciA9ICcoPzonICsgcnNVcHBlciArICd8JyArIHJzTWlzYyArICcpJyxcbiAgICAgIHJzT3B0Q29udHJMb3dlciA9ICcoPzonICsgcnNBcG9zICsgJyg/OmR8bGx8bXxyZXxzfHR8dmUpKT8nLFxuICAgICAgcnNPcHRDb250clVwcGVyID0gJyg/OicgKyByc0Fwb3MgKyAnKD86RHxMTHxNfFJFfFN8VHxWRSkpPycsXG4gICAgICByZU9wdE1vZCA9IHJzTW9kaWZpZXIgKyAnPycsXG4gICAgICByc09wdFZhciA9ICdbJyArIHJzVmFyUmFuZ2UgKyAnXT8nLFxuICAgICAgcnNPcHRKb2luID0gJyg/OicgKyByc1pXSiArICcoPzonICsgW3JzTm9uQXN0cmFsLCByc1JlZ2lvbmFsLCByc1N1cnJQYWlyXS5qb2luKCd8JykgKyAnKScgKyByc09wdFZhciArIHJlT3B0TW9kICsgJykqJyxcbiAgICAgIHJzT3JkTG93ZXIgPSAnXFxcXGQqKD86MXN0fDJuZHwzcmR8KD8hWzEyM10pXFxcXGR0aCkoPz1cXFxcYnxbQS1aX10pJyxcbiAgICAgIHJzT3JkVXBwZXIgPSAnXFxcXGQqKD86MVNUfDJORHwzUkR8KD8hWzEyM10pXFxcXGRUSCkoPz1cXFxcYnxbYS16X10pJyxcbiAgICAgIHJzU2VxID0gcnNPcHRWYXIgKyByZU9wdE1vZCArIHJzT3B0Sm9pbixcbiAgICAgIHJzRW1vamkgPSAnKD86JyArIFtyc0RpbmdiYXQsIHJzUmVnaW9uYWwsIHJzU3VyclBhaXJdLmpvaW4oJ3wnKSArICcpJyArIHJzU2VxLFxuICAgICAgcnNTeW1ib2wgPSAnKD86JyArIFtyc05vbkFzdHJhbCArIHJzQ29tYm8gKyAnPycsIHJzQ29tYm8sIHJzUmVnaW9uYWwsIHJzU3VyclBhaXIsIHJzQXN0cmFsXS5qb2luKCd8JykgKyAnKSc7XG5cbiAgLyoqIFVzZWQgdG8gbWF0Y2ggYXBvc3Ryb3BoZXMuICovXG4gIHZhciByZUFwb3MgPSBSZWdFeHAocnNBcG9zLCAnZycpO1xuXG4gIC8qKlxuICAgKiBVc2VkIHRvIG1hdGNoIFtjb21iaW5pbmcgZGlhY3JpdGljYWwgbWFya3NdKGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL0NvbWJpbmluZ19EaWFjcml0aWNhbF9NYXJrcykgYW5kXG4gICAqIFtjb21iaW5pbmcgZGlhY3JpdGljYWwgbWFya3MgZm9yIHN5bWJvbHNdKGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL0NvbWJpbmluZ19EaWFjcml0aWNhbF9NYXJrc19mb3JfU3ltYm9scykuXG4gICAqL1xuICB2YXIgcmVDb21ib01hcmsgPSBSZWdFeHAocnNDb21ibywgJ2cnKTtcblxuICAvKiogVXNlZCB0byBtYXRjaCBbc3RyaW5nIHN5bWJvbHNdKGh0dHBzOi8vbWF0aGlhc2J5bmVucy5iZS9ub3Rlcy9qYXZhc2NyaXB0LXVuaWNvZGUpLiAqL1xuICB2YXIgcmVVbmljb2RlID0gUmVnRXhwKHJzRml0eiArICcoPz0nICsgcnNGaXR6ICsgJyl8JyArIHJzU3ltYm9sICsgcnNTZXEsICdnJyk7XG5cbiAgLyoqIFVzZWQgdG8gbWF0Y2ggY29tcGxleCBvciBjb21wb3VuZCB3b3Jkcy4gKi9cbiAgdmFyIHJlVW5pY29kZVdvcmQgPSBSZWdFeHAoW1xuICAgIHJzVXBwZXIgKyAnPycgKyByc0xvd2VyICsgJysnICsgcnNPcHRDb250ckxvd2VyICsgJyg/PScgKyBbcnNCcmVhaywgcnNVcHBlciwgJyQnXS5qb2luKCd8JykgKyAnKScsXG4gICAgcnNNaXNjVXBwZXIgKyAnKycgKyByc09wdENvbnRyVXBwZXIgKyAnKD89JyArIFtyc0JyZWFrLCByc1VwcGVyICsgcnNNaXNjTG93ZXIsICckJ10uam9pbignfCcpICsgJyknLFxuICAgIHJzVXBwZXIgKyAnPycgKyByc01pc2NMb3dlciArICcrJyArIHJzT3B0Q29udHJMb3dlcixcbiAgICByc1VwcGVyICsgJysnICsgcnNPcHRDb250clVwcGVyLFxuICAgIHJzT3JkVXBwZXIsXG4gICAgcnNPcmRMb3dlcixcbiAgICByc0RpZ2l0cyxcbiAgICByc0Vtb2ppXG4gIF0uam9pbignfCcpLCAnZycpO1xuXG4gIC8qKiBVc2VkIHRvIGRldGVjdCBzdHJpbmdzIHdpdGggW3plcm8td2lkdGggam9pbmVycyBvciBjb2RlIHBvaW50cyBmcm9tIHRoZSBhc3RyYWwgcGxhbmVzXShodHRwOi8vZWV2LmVlL2Jsb2cvMjAxNS8wOS8xMi9kYXJrLWNvcm5lcnMtb2YtdW5pY29kZS8pLiAqL1xuICB2YXIgcmVIYXNVbmljb2RlID0gUmVnRXhwKCdbJyArIHJzWldKICsgcnNBc3RyYWxSYW5nZSAgKyByc0NvbWJvUmFuZ2UgKyByc1ZhclJhbmdlICsgJ10nKTtcblxuICAvKiogVXNlZCB0byBkZXRlY3Qgc3RyaW5ncyB0aGF0IG5lZWQgYSBtb3JlIHJvYnVzdCByZWdleHAgdG8gbWF0Y2ggd29yZHMuICovXG4gIHZhciByZUhhc1VuaWNvZGVXb3JkID0gL1thLXpdW0EtWl18W0EtWl17Mn1bYS16XXxbMC05XVthLXpBLVpdfFthLXpBLVpdWzAtOV18W15hLXpBLVowLTkgXS87XG5cbiAgLyoqIFVzZWQgdG8gYXNzaWduIGRlZmF1bHQgYGNvbnRleHRgIG9iamVjdCBwcm9wZXJ0aWVzLiAqL1xuICB2YXIgY29udGV4dFByb3BzID0gW1xuICAgICdBcnJheScsICdCdWZmZXInLCAnRGF0YVZpZXcnLCAnRGF0ZScsICdFcnJvcicsICdGbG9hdDMyQXJyYXknLCAnRmxvYXQ2NEFycmF5JyxcbiAgICAnRnVuY3Rpb24nLCAnSW50OEFycmF5JywgJ0ludDE2QXJyYXknLCAnSW50MzJBcnJheScsICdNYXAnLCAnTWF0aCcsICdPYmplY3QnLFxuICAgICdQcm9taXNlJywgJ1JlZ0V4cCcsICdTZXQnLCAnU3RyaW5nJywgJ1N5bWJvbCcsICdUeXBlRXJyb3InLCAnVWludDhBcnJheScsXG4gICAgJ1VpbnQ4Q2xhbXBlZEFycmF5JywgJ1VpbnQxNkFycmF5JywgJ1VpbnQzMkFycmF5JywgJ1dlYWtNYXAnLFxuICAgICdfJywgJ2NsZWFyVGltZW91dCcsICdpc0Zpbml0ZScsICdwYXJzZUludCcsICdzZXRUaW1lb3V0J1xuICBdO1xuXG4gIC8qKiBVc2VkIHRvIG1ha2UgdGVtcGxhdGUgc291cmNlVVJMcyBlYXNpZXIgdG8gaWRlbnRpZnkuICovXG4gIHZhciB0ZW1wbGF0ZUNvdW50ZXIgPSAtMTtcblxuICAvKiogVXNlZCB0byBpZGVudGlmeSBgdG9TdHJpbmdUYWdgIHZhbHVlcyBvZiB0eXBlZCBhcnJheXMuICovXG4gIHZhciB0eXBlZEFycmF5VGFncyA9IHt9O1xuICB0eXBlZEFycmF5VGFnc1tmbG9hdDMyVGFnXSA9IHR5cGVkQXJyYXlUYWdzW2Zsb2F0NjRUYWddID1cbiAgdHlwZWRBcnJheVRhZ3NbaW50OFRhZ10gPSB0eXBlZEFycmF5VGFnc1tpbnQxNlRhZ10gPVxuICB0eXBlZEFycmF5VGFnc1tpbnQzMlRhZ10gPSB0eXBlZEFycmF5VGFnc1t1aW50OFRhZ10gPVxuICB0eXBlZEFycmF5VGFnc1t1aW50OENsYW1wZWRUYWddID0gdHlwZWRBcnJheVRhZ3NbdWludDE2VGFnXSA9XG4gIHR5cGVkQXJyYXlUYWdzW3VpbnQzMlRhZ10gPSB0cnVlO1xuICB0eXBlZEFycmF5VGFnc1thcmdzVGFnXSA9IHR5cGVkQXJyYXlUYWdzW2FycmF5VGFnXSA9XG4gIHR5cGVkQXJyYXlUYWdzW2FycmF5QnVmZmVyVGFnXSA9IHR5cGVkQXJyYXlUYWdzW2Jvb2xUYWddID1cbiAgdHlwZWRBcnJheVRhZ3NbZGF0YVZpZXdUYWddID0gdHlwZWRBcnJheVRhZ3NbZGF0ZVRhZ10gPVxuICB0eXBlZEFycmF5VGFnc1tlcnJvclRhZ10gPSB0eXBlZEFycmF5VGFnc1tmdW5jVGFnXSA9XG4gIHR5cGVkQXJyYXlUYWdzW21hcFRhZ10gPSB0eXBlZEFycmF5VGFnc1tudW1iZXJUYWddID1cbiAgdHlwZWRBcnJheVRhZ3Nbb2JqZWN0VGFnXSA9IHR5cGVkQXJyYXlUYWdzW3JlZ2V4cFRhZ10gPVxuICB0eXBlZEFycmF5VGFnc1tzZXRUYWddID0gdHlwZWRBcnJheVRhZ3Nbc3RyaW5nVGFnXSA9XG4gIHR5cGVkQXJyYXlUYWdzW3dlYWtNYXBUYWddID0gZmFsc2U7XG5cbiAgLyoqIFVzZWQgdG8gaWRlbnRpZnkgYHRvU3RyaW5nVGFnYCB2YWx1ZXMgc3VwcG9ydGVkIGJ5IGBfLmNsb25lYC4gKi9cbiAgdmFyIGNsb25lYWJsZVRhZ3MgPSB7fTtcbiAgY2xvbmVhYmxlVGFnc1thcmdzVGFnXSA9IGNsb25lYWJsZVRhZ3NbYXJyYXlUYWddID1cbiAgY2xvbmVhYmxlVGFnc1thcnJheUJ1ZmZlclRhZ10gPSBjbG9uZWFibGVUYWdzW2RhdGFWaWV3VGFnXSA9XG4gIGNsb25lYWJsZVRhZ3NbYm9vbFRhZ10gPSBjbG9uZWFibGVUYWdzW2RhdGVUYWddID1cbiAgY2xvbmVhYmxlVGFnc1tmbG9hdDMyVGFnXSA9IGNsb25lYWJsZVRhZ3NbZmxvYXQ2NFRhZ10gPVxuICBjbG9uZWFibGVUYWdzW2ludDhUYWddID0gY2xvbmVhYmxlVGFnc1tpbnQxNlRhZ10gPVxuICBjbG9uZWFibGVUYWdzW2ludDMyVGFnXSA9IGNsb25lYWJsZVRhZ3NbbWFwVGFnXSA9XG4gIGNsb25lYWJsZVRhZ3NbbnVtYmVyVGFnXSA9IGNsb25lYWJsZVRhZ3Nbb2JqZWN0VGFnXSA9XG4gIGNsb25lYWJsZVRhZ3NbcmVnZXhwVGFnXSA9IGNsb25lYWJsZVRhZ3Nbc2V0VGFnXSA9XG4gIGNsb25lYWJsZVRhZ3Nbc3RyaW5nVGFnXSA9IGNsb25lYWJsZVRhZ3Nbc3ltYm9sVGFnXSA9XG4gIGNsb25lYWJsZVRhZ3NbdWludDhUYWddID0gY2xvbmVhYmxlVGFnc1t1aW50OENsYW1wZWRUYWddID1cbiAgY2xvbmVhYmxlVGFnc1t1aW50MTZUYWddID0gY2xvbmVhYmxlVGFnc1t1aW50MzJUYWddID0gdHJ1ZTtcbiAgY2xvbmVhYmxlVGFnc1tlcnJvclRhZ10gPSBjbG9uZWFibGVUYWdzW2Z1bmNUYWddID1cbiAgY2xvbmVhYmxlVGFnc1t3ZWFrTWFwVGFnXSA9IGZhbHNlO1xuXG4gIC8qKiBVc2VkIHRvIG1hcCBMYXRpbiBVbmljb2RlIGxldHRlcnMgdG8gYmFzaWMgTGF0aW4gbGV0dGVycy4gKi9cbiAgdmFyIGRlYnVycmVkTGV0dGVycyA9IHtcbiAgICAvLyBMYXRpbi0xIFN1cHBsZW1lbnQgYmxvY2suXG4gICAgJ1xceGMwJzogJ0EnLCAgJ1xceGMxJzogJ0EnLCAnXFx4YzInOiAnQScsICdcXHhjMyc6ICdBJywgJ1xceGM0JzogJ0EnLCAnXFx4YzUnOiAnQScsXG4gICAgJ1xceGUwJzogJ2EnLCAgJ1xceGUxJzogJ2EnLCAnXFx4ZTInOiAnYScsICdcXHhlMyc6ICdhJywgJ1xceGU0JzogJ2EnLCAnXFx4ZTUnOiAnYScsXG4gICAgJ1xceGM3JzogJ0MnLCAgJ1xceGU3JzogJ2MnLFxuICAgICdcXHhkMCc6ICdEJywgICdcXHhmMCc6ICdkJyxcbiAgICAnXFx4YzgnOiAnRScsICAnXFx4YzknOiAnRScsICdcXHhjYSc6ICdFJywgJ1xceGNiJzogJ0UnLFxuICAgICdcXHhlOCc6ICdlJywgICdcXHhlOSc6ICdlJywgJ1xceGVhJzogJ2UnLCAnXFx4ZWInOiAnZScsXG4gICAgJ1xceGNjJzogJ0knLCAgJ1xceGNkJzogJ0knLCAnXFx4Y2UnOiAnSScsICdcXHhjZic6ICdJJyxcbiAgICAnXFx4ZWMnOiAnaScsICAnXFx4ZWQnOiAnaScsICdcXHhlZSc6ICdpJywgJ1xceGVmJzogJ2knLFxuICAgICdcXHhkMSc6ICdOJywgICdcXHhmMSc6ICduJyxcbiAgICAnXFx4ZDInOiAnTycsICAnXFx4ZDMnOiAnTycsICdcXHhkNCc6ICdPJywgJ1xceGQ1JzogJ08nLCAnXFx4ZDYnOiAnTycsICdcXHhkOCc6ICdPJyxcbiAgICAnXFx4ZjInOiAnbycsICAnXFx4ZjMnOiAnbycsICdcXHhmNCc6ICdvJywgJ1xceGY1JzogJ28nLCAnXFx4ZjYnOiAnbycsICdcXHhmOCc6ICdvJyxcbiAgICAnXFx4ZDknOiAnVScsICAnXFx4ZGEnOiAnVScsICdcXHhkYic6ICdVJywgJ1xceGRjJzogJ1UnLFxuICAgICdcXHhmOSc6ICd1JywgICdcXHhmYSc6ICd1JywgJ1xceGZiJzogJ3UnLCAnXFx4ZmMnOiAndScsXG4gICAgJ1xceGRkJzogJ1knLCAgJ1xceGZkJzogJ3knLCAnXFx4ZmYnOiAneScsXG4gICAgJ1xceGM2JzogJ0FlJywgJ1xceGU2JzogJ2FlJyxcbiAgICAnXFx4ZGUnOiAnVGgnLCAnXFx4ZmUnOiAndGgnLFxuICAgICdcXHhkZic6ICdzcycsXG4gICAgLy8gTGF0aW4gRXh0ZW5kZWQtQSBibG9jay5cbiAgICAnXFx1MDEwMCc6ICdBJywgICdcXHUwMTAyJzogJ0EnLCAnXFx1MDEwNCc6ICdBJyxcbiAgICAnXFx1MDEwMSc6ICdhJywgICdcXHUwMTAzJzogJ2EnLCAnXFx1MDEwNSc6ICdhJyxcbiAgICAnXFx1MDEwNic6ICdDJywgICdcXHUwMTA4JzogJ0MnLCAnXFx1MDEwYSc6ICdDJywgJ1xcdTAxMGMnOiAnQycsXG4gICAgJ1xcdTAxMDcnOiAnYycsICAnXFx1MDEwOSc6ICdjJywgJ1xcdTAxMGInOiAnYycsICdcXHUwMTBkJzogJ2MnLFxuICAgICdcXHUwMTBlJzogJ0QnLCAgJ1xcdTAxMTAnOiAnRCcsICdcXHUwMTBmJzogJ2QnLCAnXFx1MDExMSc6ICdkJyxcbiAgICAnXFx1MDExMic6ICdFJywgICdcXHUwMTE0JzogJ0UnLCAnXFx1MDExNic6ICdFJywgJ1xcdTAxMTgnOiAnRScsICdcXHUwMTFhJzogJ0UnLFxuICAgICdcXHUwMTEzJzogJ2UnLCAgJ1xcdTAxMTUnOiAnZScsICdcXHUwMTE3JzogJ2UnLCAnXFx1MDExOSc6ICdlJywgJ1xcdTAxMWInOiAnZScsXG4gICAgJ1xcdTAxMWMnOiAnRycsICAnXFx1MDExZSc6ICdHJywgJ1xcdTAxMjAnOiAnRycsICdcXHUwMTIyJzogJ0cnLFxuICAgICdcXHUwMTFkJzogJ2cnLCAgJ1xcdTAxMWYnOiAnZycsICdcXHUwMTIxJzogJ2cnLCAnXFx1MDEyMyc6ICdnJyxcbiAgICAnXFx1MDEyNCc6ICdIJywgICdcXHUwMTI2JzogJ0gnLCAnXFx1MDEyNSc6ICdoJywgJ1xcdTAxMjcnOiAnaCcsXG4gICAgJ1xcdTAxMjgnOiAnSScsICAnXFx1MDEyYSc6ICdJJywgJ1xcdTAxMmMnOiAnSScsICdcXHUwMTJlJzogJ0knLCAnXFx1MDEzMCc6ICdJJyxcbiAgICAnXFx1MDEyOSc6ICdpJywgICdcXHUwMTJiJzogJ2knLCAnXFx1MDEyZCc6ICdpJywgJ1xcdTAxMmYnOiAnaScsICdcXHUwMTMxJzogJ2knLFxuICAgICdcXHUwMTM0JzogJ0onLCAgJ1xcdTAxMzUnOiAnaicsXG4gICAgJ1xcdTAxMzYnOiAnSycsICAnXFx1MDEzNyc6ICdrJywgJ1xcdTAxMzgnOiAnaycsXG4gICAgJ1xcdTAxMzknOiAnTCcsICAnXFx1MDEzYic6ICdMJywgJ1xcdTAxM2QnOiAnTCcsICdcXHUwMTNmJzogJ0wnLCAnXFx1MDE0MSc6ICdMJyxcbiAgICAnXFx1MDEzYSc6ICdsJywgICdcXHUwMTNjJzogJ2wnLCAnXFx1MDEzZSc6ICdsJywgJ1xcdTAxNDAnOiAnbCcsICdcXHUwMTQyJzogJ2wnLFxuICAgICdcXHUwMTQzJzogJ04nLCAgJ1xcdTAxNDUnOiAnTicsICdcXHUwMTQ3JzogJ04nLCAnXFx1MDE0YSc6ICdOJyxcbiAgICAnXFx1MDE0NCc6ICduJywgICdcXHUwMTQ2JzogJ24nLCAnXFx1MDE0OCc6ICduJywgJ1xcdTAxNGInOiAnbicsXG4gICAgJ1xcdTAxNGMnOiAnTycsICAnXFx1MDE0ZSc6ICdPJywgJ1xcdTAxNTAnOiAnTycsXG4gICAgJ1xcdTAxNGQnOiAnbycsICAnXFx1MDE0Zic6ICdvJywgJ1xcdTAxNTEnOiAnbycsXG4gICAgJ1xcdTAxNTQnOiAnUicsICAnXFx1MDE1Nic6ICdSJywgJ1xcdTAxNTgnOiAnUicsXG4gICAgJ1xcdTAxNTUnOiAncicsICAnXFx1MDE1Nyc6ICdyJywgJ1xcdTAxNTknOiAncicsXG4gICAgJ1xcdTAxNWEnOiAnUycsICAnXFx1MDE1Yyc6ICdTJywgJ1xcdTAxNWUnOiAnUycsICdcXHUwMTYwJzogJ1MnLFxuICAgICdcXHUwMTViJzogJ3MnLCAgJ1xcdTAxNWQnOiAncycsICdcXHUwMTVmJzogJ3MnLCAnXFx1MDE2MSc6ICdzJyxcbiAgICAnXFx1MDE2Mic6ICdUJywgICdcXHUwMTY0JzogJ1QnLCAnXFx1MDE2Nic6ICdUJyxcbiAgICAnXFx1MDE2Myc6ICd0JywgICdcXHUwMTY1JzogJ3QnLCAnXFx1MDE2Nyc6ICd0JyxcbiAgICAnXFx1MDE2OCc6ICdVJywgICdcXHUwMTZhJzogJ1UnLCAnXFx1MDE2Yyc6ICdVJywgJ1xcdTAxNmUnOiAnVScsICdcXHUwMTcwJzogJ1UnLCAnXFx1MDE3Mic6ICdVJyxcbiAgICAnXFx1MDE2OSc6ICd1JywgICdcXHUwMTZiJzogJ3UnLCAnXFx1MDE2ZCc6ICd1JywgJ1xcdTAxNmYnOiAndScsICdcXHUwMTcxJzogJ3UnLCAnXFx1MDE3Myc6ICd1JyxcbiAgICAnXFx1MDE3NCc6ICdXJywgICdcXHUwMTc1JzogJ3cnLFxuICAgICdcXHUwMTc2JzogJ1knLCAgJ1xcdTAxNzcnOiAneScsICdcXHUwMTc4JzogJ1knLFxuICAgICdcXHUwMTc5JzogJ1onLCAgJ1xcdTAxN2InOiAnWicsICdcXHUwMTdkJzogJ1onLFxuICAgICdcXHUwMTdhJzogJ3onLCAgJ1xcdTAxN2MnOiAneicsICdcXHUwMTdlJzogJ3onLFxuICAgICdcXHUwMTMyJzogJ0lKJywgJ1xcdTAxMzMnOiAnaWonLFxuICAgICdcXHUwMTUyJzogJ09lJywgJ1xcdTAxNTMnOiAnb2UnLFxuICAgICdcXHUwMTQ5JzogXCInblwiLCAnXFx1MDE3Zic6ICdzJ1xuICB9O1xuXG4gIC8qKiBVc2VkIHRvIG1hcCBjaGFyYWN0ZXJzIHRvIEhUTUwgZW50aXRpZXMuICovXG4gIHZhciBodG1sRXNjYXBlcyA9IHtcbiAgICAnJic6ICcmYW1wOycsXG4gICAgJzwnOiAnJmx0OycsXG4gICAgJz4nOiAnJmd0OycsXG4gICAgJ1wiJzogJyZxdW90OycsXG4gICAgXCInXCI6ICcmIzM5OydcbiAgfTtcblxuICAvKiogVXNlZCB0byBtYXAgSFRNTCBlbnRpdGllcyB0byBjaGFyYWN0ZXJzLiAqL1xuICB2YXIgaHRtbFVuZXNjYXBlcyA9IHtcbiAgICAnJmFtcDsnOiAnJicsXG4gICAgJyZsdDsnOiAnPCcsXG4gICAgJyZndDsnOiAnPicsXG4gICAgJyZxdW90Oyc6ICdcIicsXG4gICAgJyYjMzk7JzogXCInXCJcbiAgfTtcblxuICAvKiogVXNlZCB0byBlc2NhcGUgY2hhcmFjdGVycyBmb3IgaW5jbHVzaW9uIGluIGNvbXBpbGVkIHN0cmluZyBsaXRlcmFscy4gKi9cbiAgdmFyIHN0cmluZ0VzY2FwZXMgPSB7XG4gICAgJ1xcXFwnOiAnXFxcXCcsXG4gICAgXCInXCI6IFwiJ1wiLFxuICAgICdcXG4nOiAnbicsXG4gICAgJ1xccic6ICdyJyxcbiAgICAnXFx1MjAyOCc6ICd1MjAyOCcsXG4gICAgJ1xcdTIwMjknOiAndTIwMjknXG4gIH07XG5cbiAgLyoqIEJ1aWx0LWluIG1ldGhvZCByZWZlcmVuY2VzIHdpdGhvdXQgYSBkZXBlbmRlbmN5IG9uIGByb290YC4gKi9cbiAgdmFyIGZyZWVQYXJzZUZsb2F0ID0gcGFyc2VGbG9hdCxcbiAgICAgIGZyZWVQYXJzZUludCA9IHBhcnNlSW50O1xuXG4gIC8qKiBEZXRlY3QgZnJlZSB2YXJpYWJsZSBgZ2xvYmFsYCBmcm9tIE5vZGUuanMuICovXG4gIHZhciBmcmVlR2xvYmFsID0gdHlwZW9mIGdsb2JhbCA9PSAnb2JqZWN0JyAmJiBnbG9iYWwgJiYgZ2xvYmFsLk9iamVjdCA9PT0gT2JqZWN0ICYmIGdsb2JhbDtcblxuICAvKiogRGV0ZWN0IGZyZWUgdmFyaWFibGUgYHNlbGZgLiAqL1xuICB2YXIgZnJlZVNlbGYgPSB0eXBlb2Ygc2VsZiA9PSAnb2JqZWN0JyAmJiBzZWxmICYmIHNlbGYuT2JqZWN0ID09PSBPYmplY3QgJiYgc2VsZjtcblxuICAvKiogVXNlZCBhcyBhIHJlZmVyZW5jZSB0byB0aGUgZ2xvYmFsIG9iamVjdC4gKi9cbiAgdmFyIHJvb3QgPSBmcmVlR2xvYmFsIHx8IGZyZWVTZWxmIHx8IEZ1bmN0aW9uKCdyZXR1cm4gdGhpcycpKCk7XG5cbiAgLyoqIERldGVjdCBmcmVlIHZhcmlhYmxlIGBleHBvcnRzYC4gKi9cbiAgdmFyIGZyZWVFeHBvcnRzID0gdHlwZW9mIGV4cG9ydHMgPT0gJ29iamVjdCcgJiYgZXhwb3J0cyAmJiAhZXhwb3J0cy5ub2RlVHlwZSAmJiBleHBvcnRzO1xuXG4gIC8qKiBEZXRlY3QgZnJlZSB2YXJpYWJsZSBgbW9kdWxlYC4gKi9cbiAgdmFyIGZyZWVNb2R1bGUgPSBmcmVlRXhwb3J0cyAmJiB0eXBlb2YgbW9kdWxlID09ICdvYmplY3QnICYmIG1vZHVsZSAmJiAhbW9kdWxlLm5vZGVUeXBlICYmIG1vZHVsZTtcblxuICAvKiogRGV0ZWN0IHRoZSBwb3B1bGFyIENvbW1vbkpTIGV4dGVuc2lvbiBgbW9kdWxlLmV4cG9ydHNgLiAqL1xuICB2YXIgbW9kdWxlRXhwb3J0cyA9IGZyZWVNb2R1bGUgJiYgZnJlZU1vZHVsZS5leHBvcnRzID09PSBmcmVlRXhwb3J0cztcblxuICAvKiogRGV0ZWN0IGZyZWUgdmFyaWFibGUgYHByb2Nlc3NgIGZyb20gTm9kZS5qcy4gKi9cbiAgdmFyIGZyZWVQcm9jZXNzID0gbW9kdWxlRXhwb3J0cyAmJiBmcmVlR2xvYmFsLnByb2Nlc3M7XG5cbiAgLyoqIFVzZWQgdG8gYWNjZXNzIGZhc3RlciBOb2RlLmpzIGhlbHBlcnMuICovXG4gIHZhciBub2RlVXRpbCA9IChmdW5jdGlvbigpIHtcbiAgICB0cnkge1xuICAgICAgLy8gVXNlIGB1dGlsLnR5cGVzYCBmb3IgTm9kZS5qcyAxMCsuXG4gICAgICB2YXIgdHlwZXMgPSBmcmVlTW9kdWxlICYmIGZyZWVNb2R1bGUucmVxdWlyZSAmJiBmcmVlTW9kdWxlLnJlcXVpcmUoJ3V0aWwnKS50eXBlcztcblxuICAgICAgaWYgKHR5cGVzKSB7XG4gICAgICAgIHJldHVybiB0eXBlcztcbiAgICAgIH1cblxuICAgICAgLy8gTGVnYWN5IGBwcm9jZXNzLmJpbmRpbmcoJ3V0aWwnKWAgZm9yIE5vZGUuanMgPCAxMC5cbiAgICAgIHJldHVybiBmcmVlUHJvY2VzcyAmJiBmcmVlUHJvY2Vzcy5iaW5kaW5nICYmIGZyZWVQcm9jZXNzLmJpbmRpbmcoJ3V0aWwnKTtcbiAgICB9IGNhdGNoIChlKSB7fVxuICB9KCkpO1xuXG4gIC8qIE5vZGUuanMgaGVscGVyIHJlZmVyZW5jZXMuICovXG4gIHZhciBub2RlSXNBcnJheUJ1ZmZlciA9IG5vZGVVdGlsICYmIG5vZGVVdGlsLmlzQXJyYXlCdWZmZXIsXG4gICAgICBub2RlSXNEYXRlID0gbm9kZVV0aWwgJiYgbm9kZVV0aWwuaXNEYXRlLFxuICAgICAgbm9kZUlzTWFwID0gbm9kZVV0aWwgJiYgbm9kZVV0aWwuaXNNYXAsXG4gICAgICBub2RlSXNSZWdFeHAgPSBub2RlVXRpbCAmJiBub2RlVXRpbC5pc1JlZ0V4cCxcbiAgICAgIG5vZGVJc1NldCA9IG5vZGVVdGlsICYmIG5vZGVVdGlsLmlzU2V0LFxuICAgICAgbm9kZUlzVHlwZWRBcnJheSA9IG5vZGVVdGlsICYmIG5vZGVVdGlsLmlzVHlwZWRBcnJheTtcblxuICAvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi9cblxuICAvKipcbiAgICogQSBmYXN0ZXIgYWx0ZXJuYXRpdmUgdG8gYEZ1bmN0aW9uI2FwcGx5YCwgdGhpcyBmdW5jdGlvbiBpbnZva2VzIGBmdW5jYFxuICAgKiB3aXRoIHRoZSBgdGhpc2AgYmluZGluZyBvZiBgdGhpc0FyZ2AgYW5kIHRoZSBhcmd1bWVudHMgb2YgYGFyZ3NgLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byBpbnZva2UuXG4gICAqIEBwYXJhbSB7Kn0gdGhpc0FyZyBUaGUgYHRoaXNgIGJpbmRpbmcgb2YgYGZ1bmNgLlxuICAgKiBAcGFyYW0ge0FycmF5fSBhcmdzIFRoZSBhcmd1bWVudHMgdG8gaW52b2tlIGBmdW5jYCB3aXRoLlxuICAgKiBAcmV0dXJucyB7Kn0gUmV0dXJucyB0aGUgcmVzdWx0IG9mIGBmdW5jYC5cbiAgICovXG4gIGZ1bmN0aW9uIGFwcGx5KGZ1bmMsIHRoaXNBcmcsIGFyZ3MpIHtcbiAgICBzd2l0Y2ggKGFyZ3MubGVuZ3RoKSB7XG4gICAgICBjYXNlIDA6IHJldHVybiBmdW5jLmNhbGwodGhpc0FyZyk7XG4gICAgICBjYXNlIDE6IHJldHVybiBmdW5jLmNhbGwodGhpc0FyZywgYXJnc1swXSk7XG4gICAgICBjYXNlIDI6IHJldHVybiBmdW5jLmNhbGwodGhpc0FyZywgYXJnc1swXSwgYXJnc1sxXSk7XG4gICAgICBjYXNlIDM6IHJldHVybiBmdW5jLmNhbGwodGhpc0FyZywgYXJnc1swXSwgYXJnc1sxXSwgYXJnc1syXSk7XG4gICAgfVxuICAgIHJldHVybiBmdW5jLmFwcGx5KHRoaXNBcmcsIGFyZ3MpO1xuICB9XG5cbiAgLyoqXG4gICAqIEEgc3BlY2lhbGl6ZWQgdmVyc2lvbiBvZiBgYmFzZUFnZ3JlZ2F0b3JgIGZvciBhcnJheXMuXG4gICAqXG4gICAqIEBwcml2YXRlXG4gICAqIEBwYXJhbSB7QXJyYXl9IFthcnJheV0gVGhlIGFycmF5IHRvIGl0ZXJhdGUgb3Zlci5cbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gc2V0dGVyIFRoZSBmdW5jdGlvbiB0byBzZXQgYGFjY3VtdWxhdG9yYCB2YWx1ZXMuXG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IGl0ZXJhdGVlIFRoZSBpdGVyYXRlZSB0byB0cmFuc2Zvcm0ga2V5cy5cbiAgICogQHBhcmFtIHtPYmplY3R9IGFjY3VtdWxhdG9yIFRoZSBpbml0aWFsIGFnZ3JlZ2F0ZWQgb2JqZWN0LlxuICAgKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgYGFjY3VtdWxhdG9yYC5cbiAgICovXG4gIGZ1bmN0aW9uIGFycmF5QWdncmVnYXRvcihhcnJheSwgc2V0dGVyLCBpdGVyYXRlZSwgYWNjdW11bGF0b3IpIHtcbiAgICB2YXIgaW5kZXggPSAtMSxcbiAgICAgICAgbGVuZ3RoID0gYXJyYXkgPT0gbnVsbCA/IDAgOiBhcnJheS5sZW5ndGg7XG5cbiAgICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgICAgdmFyIHZhbHVlID0gYXJyYXlbaW5kZXhdO1xuICAgICAgc2V0dGVyKGFjY3VtdWxhdG9yLCB2YWx1ZSwgaXRlcmF0ZWUodmFsdWUpLCBhcnJheSk7XG4gICAgfVxuICAgIHJldHVybiBhY2N1bXVsYXRvcjtcbiAgfVxuXG4gIC8qKlxuICAgKiBBIHNwZWNpYWxpemVkIHZlcnNpb24gb2YgYF8uZm9yRWFjaGAgZm9yIGFycmF5cyB3aXRob3V0IHN1cHBvcnQgZm9yXG4gICAqIGl0ZXJhdGVlIHNob3J0aGFuZHMuXG4gICAqXG4gICAqIEBwcml2YXRlXG4gICAqIEBwYXJhbSB7QXJyYXl9IFthcnJheV0gVGhlIGFycmF5IHRvIGl0ZXJhdGUgb3Zlci5cbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gaXRlcmF0ZWUgVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIGl0ZXJhdGlvbi5cbiAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIGBhcnJheWAuXG4gICAqL1xuICBmdW5jdGlvbiBhcnJheUVhY2goYXJyYXksIGl0ZXJhdGVlKSB7XG4gICAgdmFyIGluZGV4ID0gLTEsXG4gICAgICAgIGxlbmd0aCA9IGFycmF5ID09IG51bGwgPyAwIDogYXJyYXkubGVuZ3RoO1xuXG4gICAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHtcbiAgICAgIGlmIChpdGVyYXRlZShhcnJheVtpbmRleF0sIGluZGV4LCBhcnJheSkgPT09IGZhbHNlKSB7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gYXJyYXk7XG4gIH1cblxuICAvKipcbiAgICogQSBzcGVjaWFsaXplZCB2ZXJzaW9uIG9mIGBfLmZvckVhY2hSaWdodGAgZm9yIGFycmF5cyB3aXRob3V0IHN1cHBvcnQgZm9yXG4gICAqIGl0ZXJhdGVlIHNob3J0aGFuZHMuXG4gICAqXG4gICAqIEBwcml2YXRlXG4gICAqIEBwYXJhbSB7QXJyYXl9IFthcnJheV0gVGhlIGFycmF5IHRvIGl0ZXJhdGUgb3Zlci5cbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gaXRlcmF0ZWUgVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIGl0ZXJhdGlvbi5cbiAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIGBhcnJheWAuXG4gICAqL1xuICBmdW5jdGlvbiBhcnJheUVhY2hSaWdodChhcnJheSwgaXRlcmF0ZWUpIHtcbiAgICB2YXIgbGVuZ3RoID0gYXJyYXkgPT0gbnVsbCA/IDAgOiBhcnJheS5sZW5ndGg7XG5cbiAgICB3aGlsZSAobGVuZ3RoLS0pIHtcbiAgICAgIGlmIChpdGVyYXRlZShhcnJheVtsZW5ndGhdLCBsZW5ndGgsIGFycmF5KSA9PT0gZmFsc2UpIHtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBhcnJheTtcbiAgfVxuXG4gIC8qKlxuICAgKiBBIHNwZWNpYWxpemVkIHZlcnNpb24gb2YgYF8uZXZlcnlgIGZvciBhcnJheXMgd2l0aG91dCBzdXBwb3J0IGZvclxuICAgKiBpdGVyYXRlZSBzaG9ydGhhbmRzLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge0FycmF5fSBbYXJyYXldIFRoZSBhcnJheSB0byBpdGVyYXRlIG92ZXIuXG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IHByZWRpY2F0ZSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYWxsIGVsZW1lbnRzIHBhc3MgdGhlIHByZWRpY2F0ZSBjaGVjayxcbiAgICogIGVsc2UgYGZhbHNlYC5cbiAgICovXG4gIGZ1bmN0aW9uIGFycmF5RXZlcnkoYXJyYXksIHByZWRpY2F0ZSkge1xuICAgIHZhciBpbmRleCA9IC0xLFxuICAgICAgICBsZW5ndGggPSBhcnJheSA9PSBudWxsID8gMCA6IGFycmF5Lmxlbmd0aDtcblxuICAgIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XG4gICAgICBpZiAoIXByZWRpY2F0ZShhcnJheVtpbmRleF0sIGluZGV4LCBhcnJheSkpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBBIHNwZWNpYWxpemVkIHZlcnNpb24gb2YgYF8uZmlsdGVyYCBmb3IgYXJyYXlzIHdpdGhvdXQgc3VwcG9ydCBmb3JcbiAgICogaXRlcmF0ZWUgc2hvcnRoYW5kcy5cbiAgICpcbiAgICogQHByaXZhdGVcbiAgICogQHBhcmFtIHtBcnJheX0gW2FycmF5XSBUaGUgYXJyYXkgdG8gaXRlcmF0ZSBvdmVyLlxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBwcmVkaWNhdGUgVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIGl0ZXJhdGlvbi5cbiAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBuZXcgZmlsdGVyZWQgYXJyYXkuXG4gICAqL1xuICBmdW5jdGlvbiBhcnJheUZpbHRlcihhcnJheSwgcHJlZGljYXRlKSB7XG4gICAgdmFyIGluZGV4ID0gLTEsXG4gICAgICAgIGxlbmd0aCA9IGFycmF5ID09IG51bGwgPyAwIDogYXJyYXkubGVuZ3RoLFxuICAgICAgICByZXNJbmRleCA9IDAsXG4gICAgICAgIHJlc3VsdCA9IFtdO1xuXG4gICAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHtcbiAgICAgIHZhciB2YWx1ZSA9IGFycmF5W2luZGV4XTtcbiAgICAgIGlmIChwcmVkaWNhdGUodmFsdWUsIGluZGV4LCBhcnJheSkpIHtcbiAgICAgICAgcmVzdWx0W3Jlc0luZGV4KytdID0gdmFsdWU7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICAvKipcbiAgICogQSBzcGVjaWFsaXplZCB2ZXJzaW9uIG9mIGBfLmluY2x1ZGVzYCBmb3IgYXJyYXlzIHdpdGhvdXQgc3VwcG9ydCBmb3JcbiAgICogc3BlY2lmeWluZyBhbiBpbmRleCB0byBzZWFyY2ggZnJvbS5cbiAgICpcbiAgICogQHByaXZhdGVcbiAgICogQHBhcmFtIHtBcnJheX0gW2FycmF5XSBUaGUgYXJyYXkgdG8gaW5zcGVjdC5cbiAgICogQHBhcmFtIHsqfSB0YXJnZXQgVGhlIHZhbHVlIHRvIHNlYXJjaCBmb3IuXG4gICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdGFyZ2V0YCBpcyBmb3VuZCwgZWxzZSBgZmFsc2VgLlxuICAgKi9cbiAgZnVuY3Rpb24gYXJyYXlJbmNsdWRlcyhhcnJheSwgdmFsdWUpIHtcbiAgICB2YXIgbGVuZ3RoID0gYXJyYXkgPT0gbnVsbCA/IDAgOiBhcnJheS5sZW5ndGg7XG4gICAgcmV0dXJuICEhbGVuZ3RoICYmIGJhc2VJbmRleE9mKGFycmF5LCB2YWx1ZSwgMCkgPiAtMTtcbiAgfVxuXG4gIC8qKlxuICAgKiBUaGlzIGZ1bmN0aW9uIGlzIGxpa2UgYGFycmF5SW5jbHVkZXNgIGV4Y2VwdCB0aGF0IGl0IGFjY2VwdHMgYSBjb21wYXJhdG9yLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge0FycmF5fSBbYXJyYXldIFRoZSBhcnJheSB0byBpbnNwZWN0LlxuICAgKiBAcGFyYW0geyp9IHRhcmdldCBUaGUgdmFsdWUgdG8gc2VhcmNoIGZvci5cbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gY29tcGFyYXRvciBUaGUgY29tcGFyYXRvciBpbnZva2VkIHBlciBlbGVtZW50LlxuICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHRhcmdldGAgaXMgZm91bmQsIGVsc2UgYGZhbHNlYC5cbiAgICovXG4gIGZ1bmN0aW9uIGFycmF5SW5jbHVkZXNXaXRoKGFycmF5LCB2YWx1ZSwgY29tcGFyYXRvcikge1xuICAgIHZhciBpbmRleCA9IC0xLFxuICAgICAgICBsZW5ndGggPSBhcnJheSA9PSBudWxsID8gMCA6IGFycmF5Lmxlbmd0aDtcblxuICAgIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XG4gICAgICBpZiAoY29tcGFyYXRvcih2YWx1ZSwgYXJyYXlbaW5kZXhdKSkge1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgLyoqXG4gICAqIEEgc3BlY2lhbGl6ZWQgdmVyc2lvbiBvZiBgXy5tYXBgIGZvciBhcnJheXMgd2l0aG91dCBzdXBwb3J0IGZvciBpdGVyYXRlZVxuICAgKiBzaG9ydGhhbmRzLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge0FycmF5fSBbYXJyYXldIFRoZSBhcnJheSB0byBpdGVyYXRlIG92ZXIuXG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IGl0ZXJhdGVlIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uXG4gICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IG1hcHBlZCBhcnJheS5cbiAgICovXG4gIGZ1bmN0aW9uIGFycmF5TWFwKGFycmF5LCBpdGVyYXRlZSkge1xuICAgIHZhciBpbmRleCA9IC0xLFxuICAgICAgICBsZW5ndGggPSBhcnJheSA9PSBudWxsID8gMCA6IGFycmF5Lmxlbmd0aCxcbiAgICAgICAgcmVzdWx0ID0gQXJyYXkobGVuZ3RoKTtcblxuICAgIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XG4gICAgICByZXN1bHRbaW5kZXhdID0gaXRlcmF0ZWUoYXJyYXlbaW5kZXhdLCBpbmRleCwgYXJyYXkpO1xuICAgIH1cbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgLyoqXG4gICAqIEFwcGVuZHMgdGhlIGVsZW1lbnRzIG9mIGB2YWx1ZXNgIHRvIGBhcnJheWAuXG4gICAqXG4gICAqIEBwcml2YXRlXG4gICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBtb2RpZnkuXG4gICAqIEBwYXJhbSB7QXJyYXl9IHZhbHVlcyBUaGUgdmFsdWVzIHRvIGFwcGVuZC5cbiAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIGBhcnJheWAuXG4gICAqL1xuICBmdW5jdGlvbiBhcnJheVB1c2goYXJyYXksIHZhbHVlcykge1xuICAgIHZhciBpbmRleCA9IC0xLFxuICAgICAgICBsZW5ndGggPSB2YWx1ZXMubGVuZ3RoLFxuICAgICAgICBvZmZzZXQgPSBhcnJheS5sZW5ndGg7XG5cbiAgICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgICAgYXJyYXlbb2Zmc2V0ICsgaW5kZXhdID0gdmFsdWVzW2luZGV4XTtcbiAgICB9XG4gICAgcmV0dXJuIGFycmF5O1xuICB9XG5cbiAgLyoqXG4gICAqIEEgc3BlY2lhbGl6ZWQgdmVyc2lvbiBvZiBgXy5yZWR1Y2VgIGZvciBhcnJheXMgd2l0aG91dCBzdXBwb3J0IGZvclxuICAgKiBpdGVyYXRlZSBzaG9ydGhhbmRzLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge0FycmF5fSBbYXJyYXldIFRoZSBhcnJheSB0byBpdGVyYXRlIG92ZXIuXG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IGl0ZXJhdGVlIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uXG4gICAqIEBwYXJhbSB7Kn0gW2FjY3VtdWxhdG9yXSBUaGUgaW5pdGlhbCB2YWx1ZS5cbiAgICogQHBhcmFtIHtib29sZWFufSBbaW5pdEFjY3VtXSBTcGVjaWZ5IHVzaW5nIHRoZSBmaXJzdCBlbGVtZW50IG9mIGBhcnJheWAgYXNcbiAgICogIHRoZSBpbml0aWFsIHZhbHVlLlxuICAgKiBAcmV0dXJucyB7Kn0gUmV0dXJucyB0aGUgYWNjdW11bGF0ZWQgdmFsdWUuXG4gICAqL1xuICBmdW5jdGlvbiBhcnJheVJlZHVjZShhcnJheSwgaXRlcmF0ZWUsIGFjY3VtdWxhdG9yLCBpbml0QWNjdW0pIHtcbiAgICB2YXIgaW5kZXggPSAtMSxcbiAgICAgICAgbGVuZ3RoID0gYXJyYXkgPT0gbnVsbCA/IDAgOiBhcnJheS5sZW5ndGg7XG5cbiAgICBpZiAoaW5pdEFjY3VtICYmIGxlbmd0aCkge1xuICAgICAgYWNjdW11bGF0b3IgPSBhcnJheVsrK2luZGV4XTtcbiAgICB9XG4gICAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHtcbiAgICAgIGFjY3VtdWxhdG9yID0gaXRlcmF0ZWUoYWNjdW11bGF0b3IsIGFycmF5W2luZGV4XSwgaW5kZXgsIGFycmF5KTtcbiAgICB9XG4gICAgcmV0dXJuIGFjY3VtdWxhdG9yO1xuICB9XG5cbiAgLyoqXG4gICAqIEEgc3BlY2lhbGl6ZWQgdmVyc2lvbiBvZiBgXy5yZWR1Y2VSaWdodGAgZm9yIGFycmF5cyB3aXRob3V0IHN1cHBvcnQgZm9yXG4gICAqIGl0ZXJhdGVlIHNob3J0aGFuZHMuXG4gICAqXG4gICAqIEBwcml2YXRlXG4gICAqIEBwYXJhbSB7QXJyYXl9IFthcnJheV0gVGhlIGFycmF5IHRvIGl0ZXJhdGUgb3Zlci5cbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gaXRlcmF0ZWUgVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIGl0ZXJhdGlvbi5cbiAgICogQHBhcmFtIHsqfSBbYWNjdW11bGF0b3JdIFRoZSBpbml0aWFsIHZhbHVlLlxuICAgKiBAcGFyYW0ge2Jvb2xlYW59IFtpbml0QWNjdW1dIFNwZWNpZnkgdXNpbmcgdGhlIGxhc3QgZWxlbWVudCBvZiBgYXJyYXlgIGFzXG4gICAqICB0aGUgaW5pdGlhbCB2YWx1ZS5cbiAgICogQHJldHVybnMgeyp9IFJldHVybnMgdGhlIGFjY3VtdWxhdGVkIHZhbHVlLlxuICAgKi9cbiAgZnVuY3Rpb24gYXJyYXlSZWR1Y2VSaWdodChhcnJheSwgaXRlcmF0ZWUsIGFjY3VtdWxhdG9yLCBpbml0QWNjdW0pIHtcbiAgICB2YXIgbGVuZ3RoID0gYXJyYXkgPT0gbnVsbCA/IDAgOiBhcnJheS5sZW5ndGg7XG4gICAgaWYgKGluaXRBY2N1bSAmJiBsZW5ndGgpIHtcbiAgICAgIGFjY3VtdWxhdG9yID0gYXJyYXlbLS1sZW5ndGhdO1xuICAgIH1cbiAgICB3aGlsZSAobGVuZ3RoLS0pIHtcbiAgICAgIGFjY3VtdWxhdG9yID0gaXRlcmF0ZWUoYWNjdW11bGF0b3IsIGFycmF5W2xlbmd0aF0sIGxlbmd0aCwgYXJyYXkpO1xuICAgIH1cbiAgICByZXR1cm4gYWNjdW11bGF0b3I7XG4gIH1cblxuICAvKipcbiAgICogQSBzcGVjaWFsaXplZCB2ZXJzaW9uIG9mIGBfLnNvbWVgIGZvciBhcnJheXMgd2l0aG91dCBzdXBwb3J0IGZvciBpdGVyYXRlZVxuICAgKiBzaG9ydGhhbmRzLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge0FycmF5fSBbYXJyYXldIFRoZSBhcnJheSB0byBpdGVyYXRlIG92ZXIuXG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IHByZWRpY2F0ZSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYW55IGVsZW1lbnQgcGFzc2VzIHRoZSBwcmVkaWNhdGUgY2hlY2ssXG4gICAqICBlbHNlIGBmYWxzZWAuXG4gICAqL1xuICBmdW5jdGlvbiBhcnJheVNvbWUoYXJyYXksIHByZWRpY2F0ZSkge1xuICAgIHZhciBpbmRleCA9IC0xLFxuICAgICAgICBsZW5ndGggPSBhcnJheSA9PSBudWxsID8gMCA6IGFycmF5Lmxlbmd0aDtcblxuICAgIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XG4gICAgICBpZiAocHJlZGljYXRlKGFycmF5W2luZGV4XSwgaW5kZXgsIGFycmF5KSkge1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldHMgdGhlIHNpemUgb2YgYW4gQVNDSUkgYHN0cmluZ2AuXG4gICAqXG4gICAqIEBwcml2YXRlXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBzdHJpbmcgVGhlIHN0cmluZyBpbnNwZWN0LlxuICAgKiBAcmV0dXJucyB7bnVtYmVyfSBSZXR1cm5zIHRoZSBzdHJpbmcgc2l6ZS5cbiAgICovXG4gIHZhciBhc2NpaVNpemUgPSBiYXNlUHJvcGVydHkoJ2xlbmd0aCcpO1xuXG4gIC8qKlxuICAgKiBDb252ZXJ0cyBhbiBBU0NJSSBgc3RyaW5nYCB0byBhbiBhcnJheS5cbiAgICpcbiAgICogQHByaXZhdGVcbiAgICogQHBhcmFtIHtzdHJpbmd9IHN0cmluZyBUaGUgc3RyaW5nIHRvIGNvbnZlcnQuXG4gICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgY29udmVydGVkIGFycmF5LlxuICAgKi9cbiAgZnVuY3Rpb24gYXNjaWlUb0FycmF5KHN0cmluZykge1xuICAgIHJldHVybiBzdHJpbmcuc3BsaXQoJycpO1xuICB9XG5cbiAgLyoqXG4gICAqIFNwbGl0cyBhbiBBU0NJSSBgc3RyaW5nYCBpbnRvIGFuIGFycmF5IG9mIGl0cyB3b3Jkcy5cbiAgICpcbiAgICogQHByaXZhdGVcbiAgICogQHBhcmFtIHtzdHJpbmd9IFRoZSBzdHJpbmcgdG8gaW5zcGVjdC5cbiAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSB3b3JkcyBvZiBgc3RyaW5nYC5cbiAgICovXG4gIGZ1bmN0aW9uIGFzY2lpV29yZHMoc3RyaW5nKSB7XG4gICAgcmV0dXJuIHN0cmluZy5tYXRjaChyZUFzY2lpV29yZCkgfHwgW107XG4gIH1cblxuICAvKipcbiAgICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgbWV0aG9kcyBsaWtlIGBfLmZpbmRLZXlgIGFuZCBgXy5maW5kTGFzdEtleWAsXG4gICAqIHdpdGhvdXQgc3VwcG9ydCBmb3IgaXRlcmF0ZWUgc2hvcnRoYW5kcywgd2hpY2ggaXRlcmF0ZXMgb3ZlciBgY29sbGVjdGlvbmBcbiAgICogdXNpbmcgYGVhY2hGdW5jYC5cbiAgICpcbiAgICogQHByaXZhdGVcbiAgICogQHBhcmFtIHtBcnJheXxPYmplY3R9IGNvbGxlY3Rpb24gVGhlIGNvbGxlY3Rpb24gdG8gaW5zcGVjdC5cbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gcHJlZGljYXRlIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uXG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IGVhY2hGdW5jIFRoZSBmdW5jdGlvbiB0byBpdGVyYXRlIG92ZXIgYGNvbGxlY3Rpb25gLlxuICAgKiBAcmV0dXJucyB7Kn0gUmV0dXJucyB0aGUgZm91bmQgZWxlbWVudCBvciBpdHMga2V5LCBlbHNlIGB1bmRlZmluZWRgLlxuICAgKi9cbiAgZnVuY3Rpb24gYmFzZUZpbmRLZXkoY29sbGVjdGlvbiwgcHJlZGljYXRlLCBlYWNoRnVuYykge1xuICAgIHZhciByZXN1bHQ7XG4gICAgZWFjaEZ1bmMoY29sbGVjdGlvbiwgZnVuY3Rpb24odmFsdWUsIGtleSwgY29sbGVjdGlvbikge1xuICAgICAgaWYgKHByZWRpY2F0ZSh2YWx1ZSwga2V5LCBjb2xsZWN0aW9uKSkge1xuICAgICAgICByZXN1bHQgPSBrZXk7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgLyoqXG4gICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLmZpbmRJbmRleGAgYW5kIGBfLmZpbmRMYXN0SW5kZXhgIHdpdGhvdXRcbiAgICogc3VwcG9ydCBmb3IgaXRlcmF0ZWUgc2hvcnRoYW5kcy5cbiAgICpcbiAgICogQHByaXZhdGVcbiAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIGluc3BlY3QuXG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IHByZWRpY2F0ZSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICAgKiBAcGFyYW0ge251bWJlcn0gZnJvbUluZGV4IFRoZSBpbmRleCB0byBzZWFyY2ggZnJvbS5cbiAgICogQHBhcmFtIHtib29sZWFufSBbZnJvbVJpZ2h0XSBTcGVjaWZ5IGl0ZXJhdGluZyBmcm9tIHJpZ2h0IHRvIGxlZnQuXG4gICAqIEByZXR1cm5zIHtudW1iZXJ9IFJldHVybnMgdGhlIGluZGV4IG9mIHRoZSBtYXRjaGVkIHZhbHVlLCBlbHNlIGAtMWAuXG4gICAqL1xuICBmdW5jdGlvbiBiYXNlRmluZEluZGV4KGFycmF5LCBwcmVkaWNhdGUsIGZyb21JbmRleCwgZnJvbVJpZ2h0KSB7XG4gICAgdmFyIGxlbmd0aCA9IGFycmF5Lmxlbmd0aCxcbiAgICAgICAgaW5kZXggPSBmcm9tSW5kZXggKyAoZnJvbVJpZ2h0ID8gMSA6IC0xKTtcblxuICAgIHdoaWxlICgoZnJvbVJpZ2h0ID8gaW5kZXgtLSA6ICsraW5kZXggPCBsZW5ndGgpKSB7XG4gICAgICBpZiAocHJlZGljYXRlKGFycmF5W2luZGV4XSwgaW5kZXgsIGFycmF5KSkge1xuICAgICAgICByZXR1cm4gaW5kZXg7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiAtMTtcbiAgfVxuXG4gIC8qKlxuICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5pbmRleE9mYCB3aXRob3V0IGBmcm9tSW5kZXhgIGJvdW5kcyBjaGVja3MuXG4gICAqXG4gICAqIEBwcml2YXRlXG4gICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBpbnNwZWN0LlxuICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBzZWFyY2ggZm9yLlxuICAgKiBAcGFyYW0ge251bWJlcn0gZnJvbUluZGV4IFRoZSBpbmRleCB0byBzZWFyY2ggZnJvbS5cbiAgICogQHJldHVybnMge251bWJlcn0gUmV0dXJucyB0aGUgaW5kZXggb2YgdGhlIG1hdGNoZWQgdmFsdWUsIGVsc2UgYC0xYC5cbiAgICovXG4gIGZ1bmN0aW9uIGJhc2VJbmRleE9mKGFycmF5LCB2YWx1ZSwgZnJvbUluZGV4KSB7XG4gICAgcmV0dXJuIHZhbHVlID09PSB2YWx1ZVxuICAgICAgPyBzdHJpY3RJbmRleE9mKGFycmF5LCB2YWx1ZSwgZnJvbUluZGV4KVxuICAgICAgOiBiYXNlRmluZEluZGV4KGFycmF5LCBiYXNlSXNOYU4sIGZyb21JbmRleCk7XG4gIH1cblxuICAvKipcbiAgICogVGhpcyBmdW5jdGlvbiBpcyBsaWtlIGBiYXNlSW5kZXhPZmAgZXhjZXB0IHRoYXQgaXQgYWNjZXB0cyBhIGNvbXBhcmF0b3IuXG4gICAqXG4gICAqIEBwcml2YXRlXG4gICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBpbnNwZWN0LlxuICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBzZWFyY2ggZm9yLlxuICAgKiBAcGFyYW0ge251bWJlcn0gZnJvbUluZGV4IFRoZSBpbmRleCB0byBzZWFyY2ggZnJvbS5cbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gY29tcGFyYXRvciBUaGUgY29tcGFyYXRvciBpbnZva2VkIHBlciBlbGVtZW50LlxuICAgKiBAcmV0dXJucyB7bnVtYmVyfSBSZXR1cm5zIHRoZSBpbmRleCBvZiB0aGUgbWF0Y2hlZCB2YWx1ZSwgZWxzZSBgLTFgLlxuICAgKi9cbiAgZnVuY3Rpb24gYmFzZUluZGV4T2ZXaXRoKGFycmF5LCB2YWx1ZSwgZnJvbUluZGV4LCBjb21wYXJhdG9yKSB7XG4gICAgdmFyIGluZGV4ID0gZnJvbUluZGV4IC0gMSxcbiAgICAgICAgbGVuZ3RoID0gYXJyYXkubGVuZ3RoO1xuXG4gICAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHtcbiAgICAgIGlmIChjb21wYXJhdG9yKGFycmF5W2luZGV4XSwgdmFsdWUpKSB7XG4gICAgICAgIHJldHVybiBpbmRleDtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIC0xO1xuICB9XG5cbiAgLyoqXG4gICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLmlzTmFOYCB3aXRob3V0IHN1cHBvcnQgZm9yIG51bWJlciBvYmplY3RzLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgYE5hTmAsIGVsc2UgYGZhbHNlYC5cbiAgICovXG4gIGZ1bmN0aW9uIGJhc2VJc05hTih2YWx1ZSkge1xuICAgIHJldHVybiB2YWx1ZSAhPT0gdmFsdWU7XG4gIH1cblxuICAvKipcbiAgICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8ubWVhbmAgYW5kIGBfLm1lYW5CeWAgd2l0aG91dCBzdXBwb3J0IGZvclxuICAgKiBpdGVyYXRlZSBzaG9ydGhhbmRzLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gaXRlcmF0ZSBvdmVyLlxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBpdGVyYXRlZSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICAgKiBAcmV0dXJucyB7bnVtYmVyfSBSZXR1cm5zIHRoZSBtZWFuLlxuICAgKi9cbiAgZnVuY3Rpb24gYmFzZU1lYW4oYXJyYXksIGl0ZXJhdGVlKSB7XG4gICAgdmFyIGxlbmd0aCA9IGFycmF5ID09IG51bGwgPyAwIDogYXJyYXkubGVuZ3RoO1xuICAgIHJldHVybiBsZW5ndGggPyAoYmFzZVN1bShhcnJheSwgaXRlcmF0ZWUpIC8gbGVuZ3RoKSA6IE5BTjtcbiAgfVxuXG4gIC8qKlxuICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5wcm9wZXJ0eWAgd2l0aG91dCBzdXBwb3J0IGZvciBkZWVwIHBhdGhzLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge3N0cmluZ30ga2V5IFRoZSBrZXkgb2YgdGhlIHByb3BlcnR5IHRvIGdldC5cbiAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgYWNjZXNzb3IgZnVuY3Rpb24uXG4gICAqL1xuICBmdW5jdGlvbiBiYXNlUHJvcGVydHkoa2V5KSB7XG4gICAgcmV0dXJuIGZ1bmN0aW9uKG9iamVjdCkge1xuICAgICAgcmV0dXJuIG9iamVjdCA9PSBudWxsID8gdW5kZWZpbmVkIDogb2JqZWN0W2tleV07XG4gICAgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5wcm9wZXJ0eU9mYCB3aXRob3V0IHN1cHBvcnQgZm9yIGRlZXAgcGF0aHMuXG4gICAqXG4gICAqIEBwcml2YXRlXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBxdWVyeS5cbiAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgYWNjZXNzb3IgZnVuY3Rpb24uXG4gICAqL1xuICBmdW5jdGlvbiBiYXNlUHJvcGVydHlPZihvYmplY3QpIHtcbiAgICByZXR1cm4gZnVuY3Rpb24oa2V5KSB7XG4gICAgICByZXR1cm4gb2JqZWN0ID09IG51bGwgPyB1bmRlZmluZWQgOiBvYmplY3Rba2V5XTtcbiAgICB9O1xuICB9XG5cbiAgLyoqXG4gICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLnJlZHVjZWAgYW5kIGBfLnJlZHVjZVJpZ2h0YCwgd2l0aG91dCBzdXBwb3J0XG4gICAqIGZvciBpdGVyYXRlZSBzaG9ydGhhbmRzLCB3aGljaCBpdGVyYXRlcyBvdmVyIGBjb2xsZWN0aW9uYCB1c2luZyBgZWFjaEZ1bmNgLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge0FycmF5fE9iamVjdH0gY29sbGVjdGlvbiBUaGUgY29sbGVjdGlvbiB0byBpdGVyYXRlIG92ZXIuXG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IGl0ZXJhdGVlIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uXG4gICAqIEBwYXJhbSB7Kn0gYWNjdW11bGF0b3IgVGhlIGluaXRpYWwgdmFsdWUuXG4gICAqIEBwYXJhbSB7Ym9vbGVhbn0gaW5pdEFjY3VtIFNwZWNpZnkgdXNpbmcgdGhlIGZpcnN0IG9yIGxhc3QgZWxlbWVudCBvZlxuICAgKiAgYGNvbGxlY3Rpb25gIGFzIHRoZSBpbml0aWFsIHZhbHVlLlxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBlYWNoRnVuYyBUaGUgZnVuY3Rpb24gdG8gaXRlcmF0ZSBvdmVyIGBjb2xsZWN0aW9uYC5cbiAgICogQHJldHVybnMgeyp9IFJldHVybnMgdGhlIGFjY3VtdWxhdGVkIHZhbHVlLlxuICAgKi9cbiAgZnVuY3Rpb24gYmFzZVJlZHVjZShjb2xsZWN0aW9uLCBpdGVyYXRlZSwgYWNjdW11bGF0b3IsIGluaXRBY2N1bSwgZWFjaEZ1bmMpIHtcbiAgICBlYWNoRnVuYyhjb2xsZWN0aW9uLCBmdW5jdGlvbih2YWx1ZSwgaW5kZXgsIGNvbGxlY3Rpb24pIHtcbiAgICAgIGFjY3VtdWxhdG9yID0gaW5pdEFjY3VtXG4gICAgICAgID8gKGluaXRBY2N1bSA9IGZhbHNlLCB2YWx1ZSlcbiAgICAgICAgOiBpdGVyYXRlZShhY2N1bXVsYXRvciwgdmFsdWUsIGluZGV4LCBjb2xsZWN0aW9uKTtcbiAgICB9KTtcbiAgICByZXR1cm4gYWNjdW11bGF0b3I7XG4gIH1cblxuICAvKipcbiAgICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uc29ydEJ5YCB3aGljaCB1c2VzIGBjb21wYXJlcmAgdG8gZGVmaW5lIHRoZVxuICAgKiBzb3J0IG9yZGVyIG9mIGBhcnJheWAgYW5kIHJlcGxhY2VzIGNyaXRlcmlhIG9iamVjdHMgd2l0aCB0aGVpciBjb3JyZXNwb25kaW5nXG4gICAqIHZhbHVlcy5cbiAgICpcbiAgICogQHByaXZhdGVcbiAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIHNvcnQuXG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IGNvbXBhcmVyIFRoZSBmdW5jdGlvbiB0byBkZWZpbmUgc29ydCBvcmRlci5cbiAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIGBhcnJheWAuXG4gICAqL1xuICBmdW5jdGlvbiBiYXNlU29ydEJ5KGFycmF5LCBjb21wYXJlcikge1xuICAgIHZhciBsZW5ndGggPSBhcnJheS5sZW5ndGg7XG5cbiAgICBhcnJheS5zb3J0KGNvbXBhcmVyKTtcbiAgICB3aGlsZSAobGVuZ3RoLS0pIHtcbiAgICAgIGFycmF5W2xlbmd0aF0gPSBhcnJheVtsZW5ndGhdLnZhbHVlO1xuICAgIH1cbiAgICByZXR1cm4gYXJyYXk7XG4gIH1cblxuICAvKipcbiAgICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uc3VtYCBhbmQgYF8uc3VtQnlgIHdpdGhvdXQgc3VwcG9ydCBmb3JcbiAgICogaXRlcmF0ZWUgc2hvcnRoYW5kcy5cbiAgICpcbiAgICogQHByaXZhdGVcbiAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIGl0ZXJhdGUgb3Zlci5cbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gaXRlcmF0ZWUgVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIGl0ZXJhdGlvbi5cbiAgICogQHJldHVybnMge251bWJlcn0gUmV0dXJucyB0aGUgc3VtLlxuICAgKi9cbiAgZnVuY3Rpb24gYmFzZVN1bShhcnJheSwgaXRlcmF0ZWUpIHtcbiAgICB2YXIgcmVzdWx0LFxuICAgICAgICBpbmRleCA9IC0xLFxuICAgICAgICBsZW5ndGggPSBhcnJheS5sZW5ndGg7XG5cbiAgICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgICAgdmFyIGN1cnJlbnQgPSBpdGVyYXRlZShhcnJheVtpbmRleF0pO1xuICAgICAgaWYgKGN1cnJlbnQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICByZXN1bHQgPSByZXN1bHQgPT09IHVuZGVmaW5lZCA/IGN1cnJlbnQgOiAocmVzdWx0ICsgY3VycmVudCk7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICAvKipcbiAgICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8udGltZXNgIHdpdGhvdXQgc3VwcG9ydCBmb3IgaXRlcmF0ZWUgc2hvcnRoYW5kc1xuICAgKiBvciBtYXggYXJyYXkgbGVuZ3RoIGNoZWNrcy5cbiAgICpcbiAgICogQHByaXZhdGVcbiAgICogQHBhcmFtIHtudW1iZXJ9IG4gVGhlIG51bWJlciBvZiB0aW1lcyB0byBpbnZva2UgYGl0ZXJhdGVlYC5cbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gaXRlcmF0ZWUgVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIGl0ZXJhdGlvbi5cbiAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBhcnJheSBvZiByZXN1bHRzLlxuICAgKi9cbiAgZnVuY3Rpb24gYmFzZVRpbWVzKG4sIGl0ZXJhdGVlKSB7XG4gICAgdmFyIGluZGV4ID0gLTEsXG4gICAgICAgIHJlc3VsdCA9IEFycmF5KG4pO1xuXG4gICAgd2hpbGUgKCsraW5kZXggPCBuKSB7XG4gICAgICByZXN1bHRbaW5kZXhdID0gaXRlcmF0ZWUoaW5kZXgpO1xuICAgIH1cbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgLyoqXG4gICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLnRvUGFpcnNgIGFuZCBgXy50b1BhaXJzSW5gIHdoaWNoIGNyZWF0ZXMgYW4gYXJyYXlcbiAgICogb2Yga2V5LXZhbHVlIHBhaXJzIGZvciBgb2JqZWN0YCBjb3JyZXNwb25kaW5nIHRvIHRoZSBwcm9wZXJ0eSBuYW1lcyBvZiBgcHJvcHNgLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gcXVlcnkuXG4gICAqIEBwYXJhbSB7QXJyYXl9IHByb3BzIFRoZSBwcm9wZXJ0eSBuYW1lcyB0byBnZXQgdmFsdWVzIGZvci5cbiAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyB0aGUga2V5LXZhbHVlIHBhaXJzLlxuICAgKi9cbiAgZnVuY3Rpb24gYmFzZVRvUGFpcnMob2JqZWN0LCBwcm9wcykge1xuICAgIHJldHVybiBhcnJheU1hcChwcm9wcywgZnVuY3Rpb24oa2V5KSB7XG4gICAgICByZXR1cm4gW2tleSwgb2JqZWN0W2tleV1dO1xuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLnRyaW1gLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge3N0cmluZ30gc3RyaW5nIFRoZSBzdHJpbmcgdG8gdHJpbS5cbiAgICogQHJldHVybnMge3N0cmluZ30gUmV0dXJucyB0aGUgdHJpbW1lZCBzdHJpbmcuXG4gICAqL1xuICBmdW5jdGlvbiBiYXNlVHJpbShzdHJpbmcpIHtcbiAgICByZXR1cm4gc3RyaW5nXG4gICAgICA/IHN0cmluZy5zbGljZSgwLCB0cmltbWVkRW5kSW5kZXgoc3RyaW5nKSArIDEpLnJlcGxhY2UocmVUcmltU3RhcnQsICcnKVxuICAgICAgOiBzdHJpbmc7XG4gIH1cblxuICAvKipcbiAgICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8udW5hcnlgIHdpdGhvdXQgc3VwcG9ydCBmb3Igc3RvcmluZyBtZXRhZGF0YS5cbiAgICpcbiAgICogQHByaXZhdGVcbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gZnVuYyBUaGUgZnVuY3Rpb24gdG8gY2FwIGFyZ3VtZW50cyBmb3IuXG4gICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IGNhcHBlZCBmdW5jdGlvbi5cbiAgICovXG4gIGZ1bmN0aW9uIGJhc2VVbmFyeShmdW5jKSB7XG4gICAgcmV0dXJuIGZ1bmN0aW9uKHZhbHVlKSB7XG4gICAgICByZXR1cm4gZnVuYyh2YWx1ZSk7XG4gICAgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy52YWx1ZXNgIGFuZCBgXy52YWx1ZXNJbmAgd2hpY2ggY3JlYXRlcyBhblxuICAgKiBhcnJheSBvZiBgb2JqZWN0YCBwcm9wZXJ0eSB2YWx1ZXMgY29ycmVzcG9uZGluZyB0byB0aGUgcHJvcGVydHkgbmFtZXNcbiAgICogb2YgYHByb3BzYC5cbiAgICpcbiAgICogQHByaXZhdGVcbiAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIHF1ZXJ5LlxuICAgKiBAcGFyYW0ge0FycmF5fSBwcm9wcyBUaGUgcHJvcGVydHkgbmFtZXMgdG8gZ2V0IHZhbHVlcyBmb3IuXG4gICAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgdGhlIGFycmF5IG9mIHByb3BlcnR5IHZhbHVlcy5cbiAgICovXG4gIGZ1bmN0aW9uIGJhc2VWYWx1ZXMob2JqZWN0LCBwcm9wcykge1xuICAgIHJldHVybiBhcnJheU1hcChwcm9wcywgZnVuY3Rpb24oa2V5KSB7XG4gICAgICByZXR1cm4gb2JqZWN0W2tleV07XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogQ2hlY2tzIGlmIGEgYGNhY2hlYCB2YWx1ZSBmb3IgYGtleWAgZXhpc3RzLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge09iamVjdH0gY2FjaGUgVGhlIGNhY2hlIHRvIHF1ZXJ5LlxuICAgKiBAcGFyYW0ge3N0cmluZ30ga2V5IFRoZSBrZXkgb2YgdGhlIGVudHJ5IHRvIGNoZWNrLlxuICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYW4gZW50cnkgZm9yIGBrZXlgIGV4aXN0cywgZWxzZSBgZmFsc2VgLlxuICAgKi9cbiAgZnVuY3Rpb24gY2FjaGVIYXMoY2FjaGUsIGtleSkge1xuICAgIHJldHVybiBjYWNoZS5oYXMoa2V5KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBVc2VkIGJ5IGBfLnRyaW1gIGFuZCBgXy50cmltU3RhcnRgIHRvIGdldCB0aGUgaW5kZXggb2YgdGhlIGZpcnN0IHN0cmluZyBzeW1ib2xcbiAgICogdGhhdCBpcyBub3QgZm91bmQgaW4gdGhlIGNoYXJhY3RlciBzeW1ib2xzLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge0FycmF5fSBzdHJTeW1ib2xzIFRoZSBzdHJpbmcgc3ltYm9scyB0byBpbnNwZWN0LlxuICAgKiBAcGFyYW0ge0FycmF5fSBjaHJTeW1ib2xzIFRoZSBjaGFyYWN0ZXIgc3ltYm9scyB0byBmaW5kLlxuICAgKiBAcmV0dXJucyB7bnVtYmVyfSBSZXR1cm5zIHRoZSBpbmRleCBvZiB0aGUgZmlyc3QgdW5tYXRjaGVkIHN0cmluZyBzeW1ib2wuXG4gICAqL1xuICBmdW5jdGlvbiBjaGFyc1N0YXJ0SW5kZXgoc3RyU3ltYm9scywgY2hyU3ltYm9scykge1xuICAgIHZhciBpbmRleCA9IC0xLFxuICAgICAgICBsZW5ndGggPSBzdHJTeW1ib2xzLmxlbmd0aDtcblxuICAgIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoICYmIGJhc2VJbmRleE9mKGNoclN5bWJvbHMsIHN0clN5bWJvbHNbaW5kZXhdLCAwKSA+IC0xKSB7fVxuICAgIHJldHVybiBpbmRleDtcbiAgfVxuXG4gIC8qKlxuICAgKiBVc2VkIGJ5IGBfLnRyaW1gIGFuZCBgXy50cmltRW5kYCB0byBnZXQgdGhlIGluZGV4IG9mIHRoZSBsYXN0IHN0cmluZyBzeW1ib2xcbiAgICogdGhhdCBpcyBub3QgZm91bmQgaW4gdGhlIGNoYXJhY3RlciBzeW1ib2xzLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge0FycmF5fSBzdHJTeW1ib2xzIFRoZSBzdHJpbmcgc3ltYm9scyB0byBpbnNwZWN0LlxuICAgKiBAcGFyYW0ge0FycmF5fSBjaHJTeW1ib2xzIFRoZSBjaGFyYWN0ZXIgc3ltYm9scyB0byBmaW5kLlxuICAgKiBAcmV0dXJucyB7bnVtYmVyfSBSZXR1cm5zIHRoZSBpbmRleCBvZiB0aGUgbGFzdCB1bm1hdGNoZWQgc3RyaW5nIHN5bWJvbC5cbiAgICovXG4gIGZ1bmN0aW9uIGNoYXJzRW5kSW5kZXgoc3RyU3ltYm9scywgY2hyU3ltYm9scykge1xuICAgIHZhciBpbmRleCA9IHN0clN5bWJvbHMubGVuZ3RoO1xuXG4gICAgd2hpbGUgKGluZGV4LS0gJiYgYmFzZUluZGV4T2YoY2hyU3ltYm9scywgc3RyU3ltYm9sc1tpbmRleF0sIDApID4gLTEpIHt9XG4gICAgcmV0dXJuIGluZGV4O1xuICB9XG5cbiAgLyoqXG4gICAqIEdldHMgdGhlIG51bWJlciBvZiBgcGxhY2Vob2xkZXJgIG9jY3VycmVuY2VzIGluIGBhcnJheWAuXG4gICAqXG4gICAqIEBwcml2YXRlXG4gICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBpbnNwZWN0LlxuICAgKiBAcGFyYW0geyp9IHBsYWNlaG9sZGVyIFRoZSBwbGFjZWhvbGRlciB0byBzZWFyY2ggZm9yLlxuICAgKiBAcmV0dXJucyB7bnVtYmVyfSBSZXR1cm5zIHRoZSBwbGFjZWhvbGRlciBjb3VudC5cbiAgICovXG4gIGZ1bmN0aW9uIGNvdW50SG9sZGVycyhhcnJheSwgcGxhY2Vob2xkZXIpIHtcbiAgICB2YXIgbGVuZ3RoID0gYXJyYXkubGVuZ3RoLFxuICAgICAgICByZXN1bHQgPSAwO1xuXG4gICAgd2hpbGUgKGxlbmd0aC0tKSB7XG4gICAgICBpZiAoYXJyYXlbbGVuZ3RoXSA9PT0gcGxhY2Vob2xkZXIpIHtcbiAgICAgICAgKytyZXN1bHQ7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICAvKipcbiAgICogVXNlZCBieSBgXy5kZWJ1cnJgIHRvIGNvbnZlcnQgTGF0aW4tMSBTdXBwbGVtZW50IGFuZCBMYXRpbiBFeHRlbmRlZC1BXG4gICAqIGxldHRlcnMgdG8gYmFzaWMgTGF0aW4gbGV0dGVycy5cbiAgICpcbiAgICogQHByaXZhdGVcbiAgICogQHBhcmFtIHtzdHJpbmd9IGxldHRlciBUaGUgbWF0Y2hlZCBsZXR0ZXIgdG8gZGVidXJyLlxuICAgKiBAcmV0dXJucyB7c3RyaW5nfSBSZXR1cm5zIHRoZSBkZWJ1cnJlZCBsZXR0ZXIuXG4gICAqL1xuICB2YXIgZGVidXJyTGV0dGVyID0gYmFzZVByb3BlcnR5T2YoZGVidXJyZWRMZXR0ZXJzKTtcblxuICAvKipcbiAgICogVXNlZCBieSBgXy5lc2NhcGVgIHRvIGNvbnZlcnQgY2hhcmFjdGVycyB0byBIVE1MIGVudGl0aWVzLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge3N0cmluZ30gY2hyIFRoZSBtYXRjaGVkIGNoYXJhY3RlciB0byBlc2NhcGUuXG4gICAqIEByZXR1cm5zIHtzdHJpbmd9IFJldHVybnMgdGhlIGVzY2FwZWQgY2hhcmFjdGVyLlxuICAgKi9cbiAgdmFyIGVzY2FwZUh0bWxDaGFyID0gYmFzZVByb3BlcnR5T2YoaHRtbEVzY2FwZXMpO1xuXG4gIC8qKlxuICAgKiBVc2VkIGJ5IGBfLnRlbXBsYXRlYCB0byBlc2NhcGUgY2hhcmFjdGVycyBmb3IgaW5jbHVzaW9uIGluIGNvbXBpbGVkIHN0cmluZyBsaXRlcmFscy5cbiAgICpcbiAgICogQHByaXZhdGVcbiAgICogQHBhcmFtIHtzdHJpbmd9IGNociBUaGUgbWF0Y2hlZCBjaGFyYWN0ZXIgdG8gZXNjYXBlLlxuICAgKiBAcmV0dXJucyB7c3RyaW5nfSBSZXR1cm5zIHRoZSBlc2NhcGVkIGNoYXJhY3Rlci5cbiAgICovXG4gIGZ1bmN0aW9uIGVzY2FwZVN0cmluZ0NoYXIoY2hyKSB7XG4gICAgcmV0dXJuICdcXFxcJyArIHN0cmluZ0VzY2FwZXNbY2hyXTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXRzIHRoZSB2YWx1ZSBhdCBga2V5YCBvZiBgb2JqZWN0YC5cbiAgICpcbiAgICogQHByaXZhdGVcbiAgICogQHBhcmFtIHtPYmplY3R9IFtvYmplY3RdIFRoZSBvYmplY3QgdG8gcXVlcnkuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgVGhlIGtleSBvZiB0aGUgcHJvcGVydHkgdG8gZ2V0LlxuICAgKiBAcmV0dXJucyB7Kn0gUmV0dXJucyB0aGUgcHJvcGVydHkgdmFsdWUuXG4gICAqL1xuICBmdW5jdGlvbiBnZXRWYWx1ZShvYmplY3QsIGtleSkge1xuICAgIHJldHVybiBvYmplY3QgPT0gbnVsbCA/IHVuZGVmaW5lZCA6IG9iamVjdFtrZXldO1xuICB9XG5cbiAgLyoqXG4gICAqIENoZWNrcyBpZiBgc3RyaW5nYCBjb250YWlucyBVbmljb2RlIHN5bWJvbHMuXG4gICAqXG4gICAqIEBwcml2YXRlXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBzdHJpbmcgVGhlIHN0cmluZyB0byBpbnNwZWN0LlxuICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYSBzeW1ib2wgaXMgZm91bmQsIGVsc2UgYGZhbHNlYC5cbiAgICovXG4gIGZ1bmN0aW9uIGhhc1VuaWNvZGUoc3RyaW5nKSB7XG4gICAgcmV0dXJuIHJlSGFzVW5pY29kZS50ZXN0KHN0cmluZyk7XG4gIH1cblxuICAvKipcbiAgICogQ2hlY2tzIGlmIGBzdHJpbmdgIGNvbnRhaW5zIGEgd29yZCBjb21wb3NlZCBvZiBVbmljb2RlIHN5bWJvbHMuXG4gICAqXG4gICAqIEBwcml2YXRlXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBzdHJpbmcgVGhlIHN0cmluZyB0byBpbnNwZWN0LlxuICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYSB3b3JkIGlzIGZvdW5kLCBlbHNlIGBmYWxzZWAuXG4gICAqL1xuICBmdW5jdGlvbiBoYXNVbmljb2RlV29yZChzdHJpbmcpIHtcbiAgICByZXR1cm4gcmVIYXNVbmljb2RlV29yZC50ZXN0KHN0cmluZyk7XG4gIH1cblxuICAvKipcbiAgICogQ29udmVydHMgYGl0ZXJhdG9yYCB0byBhbiBhcnJheS5cbiAgICpcbiAgICogQHByaXZhdGVcbiAgICogQHBhcmFtIHtPYmplY3R9IGl0ZXJhdG9yIFRoZSBpdGVyYXRvciB0byBjb252ZXJ0LlxuICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIGNvbnZlcnRlZCBhcnJheS5cbiAgICovXG4gIGZ1bmN0aW9uIGl0ZXJhdG9yVG9BcnJheShpdGVyYXRvcikge1xuICAgIHZhciBkYXRhLFxuICAgICAgICByZXN1bHQgPSBbXTtcblxuICAgIHdoaWxlICghKGRhdGEgPSBpdGVyYXRvci5uZXh0KCkpLmRvbmUpIHtcbiAgICAgIHJlc3VsdC5wdXNoKGRhdGEudmFsdWUpO1xuICAgIH1cbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgLyoqXG4gICAqIENvbnZlcnRzIGBtYXBgIHRvIGl0cyBrZXktdmFsdWUgcGFpcnMuXG4gICAqXG4gICAqIEBwcml2YXRlXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBtYXAgVGhlIG1hcCB0byBjb252ZXJ0LlxuICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIGtleS12YWx1ZSBwYWlycy5cbiAgICovXG4gIGZ1bmN0aW9uIG1hcFRvQXJyYXkobWFwKSB7XG4gICAgdmFyIGluZGV4ID0gLTEsXG4gICAgICAgIHJlc3VsdCA9IEFycmF5KG1hcC5zaXplKTtcblxuICAgIG1hcC5mb3JFYWNoKGZ1bmN0aW9uKHZhbHVlLCBrZXkpIHtcbiAgICAgIHJlc3VsdFsrK2luZGV4XSA9IFtrZXksIHZhbHVlXTtcbiAgICB9KTtcbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgLyoqXG4gICAqIENyZWF0ZXMgYSB1bmFyeSBmdW5jdGlvbiB0aGF0IGludm9rZXMgYGZ1bmNgIHdpdGggaXRzIGFyZ3VtZW50IHRyYW5zZm9ybWVkLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byB3cmFwLlxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSB0cmFuc2Zvcm0gVGhlIGFyZ3VtZW50IHRyYW5zZm9ybS5cbiAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgZnVuY3Rpb24uXG4gICAqL1xuICBmdW5jdGlvbiBvdmVyQXJnKGZ1bmMsIHRyYW5zZm9ybSkge1xuICAgIHJldHVybiBmdW5jdGlvbihhcmcpIHtcbiAgICAgIHJldHVybiBmdW5jKHRyYW5zZm9ybShhcmcpKTtcbiAgICB9O1xuICB9XG5cbiAgLyoqXG4gICAqIFJlcGxhY2VzIGFsbCBgcGxhY2Vob2xkZXJgIGVsZW1lbnRzIGluIGBhcnJheWAgd2l0aCBhbiBpbnRlcm5hbCBwbGFjZWhvbGRlclxuICAgKiBhbmQgcmV0dXJucyBhbiBhcnJheSBvZiB0aGVpciBpbmRleGVzLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gbW9kaWZ5LlxuICAgKiBAcGFyYW0geyp9IHBsYWNlaG9sZGVyIFRoZSBwbGFjZWhvbGRlciB0byByZXBsYWNlLlxuICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIG5ldyBhcnJheSBvZiBwbGFjZWhvbGRlciBpbmRleGVzLlxuICAgKi9cbiAgZnVuY3Rpb24gcmVwbGFjZUhvbGRlcnMoYXJyYXksIHBsYWNlaG9sZGVyKSB7XG4gICAgdmFyIGluZGV4ID0gLTEsXG4gICAgICAgIGxlbmd0aCA9IGFycmF5Lmxlbmd0aCxcbiAgICAgICAgcmVzSW5kZXggPSAwLFxuICAgICAgICByZXN1bHQgPSBbXTtcblxuICAgIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XG4gICAgICB2YXIgdmFsdWUgPSBhcnJheVtpbmRleF07XG4gICAgICBpZiAodmFsdWUgPT09IHBsYWNlaG9sZGVyIHx8IHZhbHVlID09PSBQTEFDRUhPTERFUikge1xuICAgICAgICBhcnJheVtpbmRleF0gPSBQTEFDRUhPTERFUjtcbiAgICAgICAgcmVzdWx0W3Jlc0luZGV4KytdID0gaW5kZXg7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICAvKipcbiAgICogQ29udmVydHMgYHNldGAgdG8gYW4gYXJyYXkgb2YgaXRzIHZhbHVlcy5cbiAgICpcbiAgICogQHByaXZhdGVcbiAgICogQHBhcmFtIHtPYmplY3R9IHNldCBUaGUgc2V0IHRvIGNvbnZlcnQuXG4gICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgdmFsdWVzLlxuICAgKi9cbiAgZnVuY3Rpb24gc2V0VG9BcnJheShzZXQpIHtcbiAgICB2YXIgaW5kZXggPSAtMSxcbiAgICAgICAgcmVzdWx0ID0gQXJyYXkoc2V0LnNpemUpO1xuXG4gICAgc2V0LmZvckVhY2goZnVuY3Rpb24odmFsdWUpIHtcbiAgICAgIHJlc3VsdFsrK2luZGV4XSA9IHZhbHVlO1xuICAgIH0pO1xuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICAvKipcbiAgICogQ29udmVydHMgYHNldGAgdG8gaXRzIHZhbHVlLXZhbHVlIHBhaXJzLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge09iamVjdH0gc2V0IFRoZSBzZXQgdG8gY29udmVydC5cbiAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSB2YWx1ZS12YWx1ZSBwYWlycy5cbiAgICovXG4gIGZ1bmN0aW9uIHNldFRvUGFpcnMoc2V0KSB7XG4gICAgdmFyIGluZGV4ID0gLTEsXG4gICAgICAgIHJlc3VsdCA9IEFycmF5KHNldC5zaXplKTtcblxuICAgIHNldC5mb3JFYWNoKGZ1bmN0aW9uKHZhbHVlKSB7XG4gICAgICByZXN1bHRbKytpbmRleF0gPSBbdmFsdWUsIHZhbHVlXTtcbiAgICB9KTtcbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgLyoqXG4gICAqIEEgc3BlY2lhbGl6ZWQgdmVyc2lvbiBvZiBgXy5pbmRleE9mYCB3aGljaCBwZXJmb3JtcyBzdHJpY3QgZXF1YWxpdHlcbiAgICogY29tcGFyaXNvbnMgb2YgdmFsdWVzLCBpLmUuIGA9PT1gLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gaW5zcGVjdC5cbiAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gc2VhcmNoIGZvci5cbiAgICogQHBhcmFtIHtudW1iZXJ9IGZyb21JbmRleCBUaGUgaW5kZXggdG8gc2VhcmNoIGZyb20uXG4gICAqIEByZXR1cm5zIHtudW1iZXJ9IFJldHVybnMgdGhlIGluZGV4IG9mIHRoZSBtYXRjaGVkIHZhbHVlLCBlbHNlIGAtMWAuXG4gICAqL1xuICBmdW5jdGlvbiBzdHJpY3RJbmRleE9mKGFycmF5LCB2YWx1ZSwgZnJvbUluZGV4KSB7XG4gICAgdmFyIGluZGV4ID0gZnJvbUluZGV4IC0gMSxcbiAgICAgICAgbGVuZ3RoID0gYXJyYXkubGVuZ3RoO1xuXG4gICAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHtcbiAgICAgIGlmIChhcnJheVtpbmRleF0gPT09IHZhbHVlKSB7XG4gICAgICAgIHJldHVybiBpbmRleDtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIC0xO1xuICB9XG5cbiAgLyoqXG4gICAqIEEgc3BlY2lhbGl6ZWQgdmVyc2lvbiBvZiBgXy5sYXN0SW5kZXhPZmAgd2hpY2ggcGVyZm9ybXMgc3RyaWN0IGVxdWFsaXR5XG4gICAqIGNvbXBhcmlzb25zIG9mIHZhbHVlcywgaS5lLiBgPT09YC5cbiAgICpcbiAgICogQHByaXZhdGVcbiAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIGluc3BlY3QuXG4gICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIHNlYXJjaCBmb3IuXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBmcm9tSW5kZXggVGhlIGluZGV4IHRvIHNlYXJjaCBmcm9tLlxuICAgKiBAcmV0dXJucyB7bnVtYmVyfSBSZXR1cm5zIHRoZSBpbmRleCBvZiB0aGUgbWF0Y2hlZCB2YWx1ZSwgZWxzZSBgLTFgLlxuICAgKi9cbiAgZnVuY3Rpb24gc3RyaWN0TGFzdEluZGV4T2YoYXJyYXksIHZhbHVlLCBmcm9tSW5kZXgpIHtcbiAgICB2YXIgaW5kZXggPSBmcm9tSW5kZXggKyAxO1xuICAgIHdoaWxlIChpbmRleC0tKSB7XG4gICAgICBpZiAoYXJyYXlbaW5kZXhdID09PSB2YWx1ZSkge1xuICAgICAgICByZXR1cm4gaW5kZXg7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBpbmRleDtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXRzIHRoZSBudW1iZXIgb2Ygc3ltYm9scyBpbiBgc3RyaW5nYC5cbiAgICpcbiAgICogQHByaXZhdGVcbiAgICogQHBhcmFtIHtzdHJpbmd9IHN0cmluZyBUaGUgc3RyaW5nIHRvIGluc3BlY3QuXG4gICAqIEByZXR1cm5zIHtudW1iZXJ9IFJldHVybnMgdGhlIHN0cmluZyBzaXplLlxuICAgKi9cbiAgZnVuY3Rpb24gc3RyaW5nU2l6ZShzdHJpbmcpIHtcbiAgICByZXR1cm4gaGFzVW5pY29kZShzdHJpbmcpXG4gICAgICA/IHVuaWNvZGVTaXplKHN0cmluZylcbiAgICAgIDogYXNjaWlTaXplKHN0cmluZyk7XG4gIH1cblxuICAvKipcbiAgICogQ29udmVydHMgYHN0cmluZ2AgdG8gYW4gYXJyYXkuXG4gICAqXG4gICAqIEBwcml2YXRlXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBzdHJpbmcgVGhlIHN0cmluZyB0byBjb252ZXJ0LlxuICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIGNvbnZlcnRlZCBhcnJheS5cbiAgICovXG4gIGZ1bmN0aW9uIHN0cmluZ1RvQXJyYXkoc3RyaW5nKSB7XG4gICAgcmV0dXJuIGhhc1VuaWNvZGUoc3RyaW5nKVxuICAgICAgPyB1bmljb2RlVG9BcnJheShzdHJpbmcpXG4gICAgICA6IGFzY2lpVG9BcnJheShzdHJpbmcpO1xuICB9XG5cbiAgLyoqXG4gICAqIFVzZWQgYnkgYF8udHJpbWAgYW5kIGBfLnRyaW1FbmRgIHRvIGdldCB0aGUgaW5kZXggb2YgdGhlIGxhc3Qgbm9uLXdoaXRlc3BhY2VcbiAgICogY2hhcmFjdGVyIG9mIGBzdHJpbmdgLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge3N0cmluZ30gc3RyaW5nIFRoZSBzdHJpbmcgdG8gaW5zcGVjdC5cbiAgICogQHJldHVybnMge251bWJlcn0gUmV0dXJucyB0aGUgaW5kZXggb2YgdGhlIGxhc3Qgbm9uLXdoaXRlc3BhY2UgY2hhcmFjdGVyLlxuICAgKi9cbiAgZnVuY3Rpb24gdHJpbW1lZEVuZEluZGV4KHN0cmluZykge1xuICAgIHZhciBpbmRleCA9IHN0cmluZy5sZW5ndGg7XG5cbiAgICB3aGlsZSAoaW5kZXgtLSAmJiByZVdoaXRlc3BhY2UudGVzdChzdHJpbmcuY2hhckF0KGluZGV4KSkpIHt9XG4gICAgcmV0dXJuIGluZGV4O1xuICB9XG5cbiAgLyoqXG4gICAqIFVzZWQgYnkgYF8udW5lc2NhcGVgIHRvIGNvbnZlcnQgSFRNTCBlbnRpdGllcyB0byBjaGFyYWN0ZXJzLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge3N0cmluZ30gY2hyIFRoZSBtYXRjaGVkIGNoYXJhY3RlciB0byB1bmVzY2FwZS5cbiAgICogQHJldHVybnMge3N0cmluZ30gUmV0dXJucyB0aGUgdW5lc2NhcGVkIGNoYXJhY3Rlci5cbiAgICovXG4gIHZhciB1bmVzY2FwZUh0bWxDaGFyID0gYmFzZVByb3BlcnR5T2YoaHRtbFVuZXNjYXBlcyk7XG5cbiAgLyoqXG4gICAqIEdldHMgdGhlIHNpemUgb2YgYSBVbmljb2RlIGBzdHJpbmdgLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge3N0cmluZ30gc3RyaW5nIFRoZSBzdHJpbmcgaW5zcGVjdC5cbiAgICogQHJldHVybnMge251bWJlcn0gUmV0dXJucyB0aGUgc3RyaW5nIHNpemUuXG4gICAqL1xuICBmdW5jdGlvbiB1bmljb2RlU2l6ZShzdHJpbmcpIHtcbiAgICB2YXIgcmVzdWx0ID0gcmVVbmljb2RlLmxhc3RJbmRleCA9IDA7XG4gICAgd2hpbGUgKHJlVW5pY29kZS50ZXN0KHN0cmluZykpIHtcbiAgICAgICsrcmVzdWx0O1xuICAgIH1cbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgLyoqXG4gICAqIENvbnZlcnRzIGEgVW5pY29kZSBgc3RyaW5nYCB0byBhbiBhcnJheS5cbiAgICpcbiAgICogQHByaXZhdGVcbiAgICogQHBhcmFtIHtzdHJpbmd9IHN0cmluZyBUaGUgc3RyaW5nIHRvIGNvbnZlcnQuXG4gICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgY29udmVydGVkIGFycmF5LlxuICAgKi9cbiAgZnVuY3Rpb24gdW5pY29kZVRvQXJyYXkoc3RyaW5nKSB7XG4gICAgcmV0dXJuIHN0cmluZy5tYXRjaChyZVVuaWNvZGUpIHx8IFtdO1xuICB9XG5cbiAgLyoqXG4gICAqIFNwbGl0cyBhIFVuaWNvZGUgYHN0cmluZ2AgaW50byBhbiBhcnJheSBvZiBpdHMgd29yZHMuXG4gICAqXG4gICAqIEBwcml2YXRlXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBUaGUgc3RyaW5nIHRvIGluc3BlY3QuXG4gICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgd29yZHMgb2YgYHN0cmluZ2AuXG4gICAqL1xuICBmdW5jdGlvbiB1bmljb2RlV29yZHMoc3RyaW5nKSB7XG4gICAgcmV0dXJuIHN0cmluZy5tYXRjaChyZVVuaWNvZGVXb3JkKSB8fCBbXTtcbiAgfVxuXG4gIC8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuXG4gIC8qKlxuICAgKiBDcmVhdGUgYSBuZXcgcHJpc3RpbmUgYGxvZGFzaGAgZnVuY3Rpb24gdXNpbmcgdGhlIGBjb250ZXh0YCBvYmplY3QuXG4gICAqXG4gICAqIEBzdGF0aWNcbiAgICogQG1lbWJlck9mIF9cbiAgICogQHNpbmNlIDEuMS4wXG4gICAqIEBjYXRlZ29yeSBVdGlsXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBbY29udGV4dD1yb290XSBUaGUgY29udGV4dCBvYmplY3QuXG4gICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyBhIG5ldyBgbG9kYXNoYCBmdW5jdGlvbi5cbiAgICogQGV4YW1wbGVcbiAgICpcbiAgICogXy5taXhpbih7ICdmb28nOiBfLmNvbnN0YW50KCdmb28nKSB9KTtcbiAgICpcbiAgICogdmFyIGxvZGFzaCA9IF8ucnVuSW5Db250ZXh0KCk7XG4gICAqIGxvZGFzaC5taXhpbih7ICdiYXInOiBsb2Rhc2guY29uc3RhbnQoJ2JhcicpIH0pO1xuICAgKlxuICAgKiBfLmlzRnVuY3Rpb24oXy5mb28pO1xuICAgKiAvLyA9PiB0cnVlXG4gICAqIF8uaXNGdW5jdGlvbihfLmJhcik7XG4gICAqIC8vID0+IGZhbHNlXG4gICAqXG4gICAqIGxvZGFzaC5pc0Z1bmN0aW9uKGxvZGFzaC5mb28pO1xuICAgKiAvLyA9PiBmYWxzZVxuICAgKiBsb2Rhc2guaXNGdW5jdGlvbihsb2Rhc2guYmFyKTtcbiAgICogLy8gPT4gdHJ1ZVxuICAgKlxuICAgKiAvLyBDcmVhdGUgYSBzdXBlZC11cCBgZGVmZXJgIGluIE5vZGUuanMuXG4gICAqIHZhciBkZWZlciA9IF8ucnVuSW5Db250ZXh0KHsgJ3NldFRpbWVvdXQnOiBzZXRJbW1lZGlhdGUgfSkuZGVmZXI7XG4gICAqL1xuICB2YXIgcnVuSW5Db250ZXh0ID0gKGZ1bmN0aW9uIHJ1bkluQ29udGV4dChjb250ZXh0KSB7XG4gICAgY29udGV4dCA9IGNvbnRleHQgPT0gbnVsbCA/IHJvb3QgOiBfLmRlZmF1bHRzKHJvb3QuT2JqZWN0KCksIGNvbnRleHQsIF8ucGljayhyb290LCBjb250ZXh0UHJvcHMpKTtcblxuICAgIC8qKiBCdWlsdC1pbiBjb25zdHJ1Y3RvciByZWZlcmVuY2VzLiAqL1xuICAgIHZhciBBcnJheSA9IGNvbnRleHQuQXJyYXksXG4gICAgICAgIERhdGUgPSBjb250ZXh0LkRhdGUsXG4gICAgICAgIEVycm9yID0gY29udGV4dC5FcnJvcixcbiAgICAgICAgRnVuY3Rpb24gPSBjb250ZXh0LkZ1bmN0aW9uLFxuICAgICAgICBNYXRoID0gY29udGV4dC5NYXRoLFxuICAgICAgICBPYmplY3QgPSBjb250ZXh0Lk9iamVjdCxcbiAgICAgICAgUmVnRXhwID0gY29udGV4dC5SZWdFeHAsXG4gICAgICAgIFN0cmluZyA9IGNvbnRleHQuU3RyaW5nLFxuICAgICAgICBUeXBlRXJyb3IgPSBjb250ZXh0LlR5cGVFcnJvcjtcblxuICAgIC8qKiBVc2VkIGZvciBidWlsdC1pbiBtZXRob2QgcmVmZXJlbmNlcy4gKi9cbiAgICB2YXIgYXJyYXlQcm90byA9IEFycmF5LnByb3RvdHlwZSxcbiAgICAgICAgZnVuY1Byb3RvID0gRnVuY3Rpb24ucHJvdG90eXBlLFxuICAgICAgICBvYmplY3RQcm90byA9IE9iamVjdC5wcm90b3R5cGU7XG5cbiAgICAvKiogVXNlZCB0byBkZXRlY3Qgb3ZlcnJlYWNoaW5nIGNvcmUtanMgc2hpbXMuICovXG4gICAgdmFyIGNvcmVKc0RhdGEgPSBjb250ZXh0WydfX2NvcmUtanNfc2hhcmVkX18nXTtcblxuICAgIC8qKiBVc2VkIHRvIHJlc29sdmUgdGhlIGRlY29tcGlsZWQgc291cmNlIG9mIGZ1bmN0aW9ucy4gKi9cbiAgICB2YXIgZnVuY1RvU3RyaW5nID0gZnVuY1Byb3RvLnRvU3RyaW5nO1xuXG4gICAgLyoqIFVzZWQgdG8gY2hlY2sgb2JqZWN0cyBmb3Igb3duIHByb3BlcnRpZXMuICovXG4gICAgdmFyIGhhc093blByb3BlcnR5ID0gb2JqZWN0UHJvdG8uaGFzT3duUHJvcGVydHk7XG5cbiAgICAvKiogVXNlZCB0byBnZW5lcmF0ZSB1bmlxdWUgSURzLiAqL1xuICAgIHZhciBpZENvdW50ZXIgPSAwO1xuXG4gICAgLyoqIFVzZWQgdG8gZGV0ZWN0IG1ldGhvZHMgbWFzcXVlcmFkaW5nIGFzIG5hdGl2ZS4gKi9cbiAgICB2YXIgbWFza1NyY0tleSA9IChmdW5jdGlvbigpIHtcbiAgICAgIHZhciB1aWQgPSAvW14uXSskLy5leGVjKGNvcmVKc0RhdGEgJiYgY29yZUpzRGF0YS5rZXlzICYmIGNvcmVKc0RhdGEua2V5cy5JRV9QUk9UTyB8fCAnJyk7XG4gICAgICByZXR1cm4gdWlkID8gKCdTeW1ib2woc3JjKV8xLicgKyB1aWQpIDogJyc7XG4gICAgfSgpKTtcblxuICAgIC8qKlxuICAgICAqIFVzZWQgdG8gcmVzb2x2ZSB0aGVcbiAgICAgKiBbYHRvU3RyaW5nVGFnYF0oaHR0cDovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNy4wLyNzZWMtb2JqZWN0LnByb3RvdHlwZS50b3N0cmluZylcbiAgICAgKiBvZiB2YWx1ZXMuXG4gICAgICovXG4gICAgdmFyIG5hdGl2ZU9iamVjdFRvU3RyaW5nID0gb2JqZWN0UHJvdG8udG9TdHJpbmc7XG5cbiAgICAvKiogVXNlZCB0byBpbmZlciB0aGUgYE9iamVjdGAgY29uc3RydWN0b3IuICovXG4gICAgdmFyIG9iamVjdEN0b3JTdHJpbmcgPSBmdW5jVG9TdHJpbmcuY2FsbChPYmplY3QpO1xuXG4gICAgLyoqIFVzZWQgdG8gcmVzdG9yZSB0aGUgb3JpZ2luYWwgYF9gIHJlZmVyZW5jZSBpbiBgXy5ub0NvbmZsaWN0YC4gKi9cbiAgICB2YXIgb2xkRGFzaCA9IHJvb3QuXztcblxuICAgIC8qKiBVc2VkIHRvIGRldGVjdCBpZiBhIG1ldGhvZCBpcyBuYXRpdmUuICovXG4gICAgdmFyIHJlSXNOYXRpdmUgPSBSZWdFeHAoJ14nICtcbiAgICAgIGZ1bmNUb1N0cmluZy5jYWxsKGhhc093blByb3BlcnR5KS5yZXBsYWNlKHJlUmVnRXhwQ2hhciwgJ1xcXFwkJicpXG4gICAgICAucmVwbGFjZSgvaGFzT3duUHJvcGVydHl8KGZ1bmN0aW9uKS4qPyg/PVxcXFxcXCgpfCBmb3IgLis/KD89XFxcXFxcXSkvZywgJyQxLio/JykgKyAnJCdcbiAgICApO1xuXG4gICAgLyoqIEJ1aWx0LWluIHZhbHVlIHJlZmVyZW5jZXMuICovXG4gICAgdmFyIEJ1ZmZlciA9IG1vZHVsZUV4cG9ydHMgPyBjb250ZXh0LkJ1ZmZlciA6IHVuZGVmaW5lZCxcbiAgICAgICAgU3ltYm9sID0gY29udGV4dC5TeW1ib2wsXG4gICAgICAgIFVpbnQ4QXJyYXkgPSBjb250ZXh0LlVpbnQ4QXJyYXksXG4gICAgICAgIGFsbG9jVW5zYWZlID0gQnVmZmVyID8gQnVmZmVyLmFsbG9jVW5zYWZlIDogdW5kZWZpbmVkLFxuICAgICAgICBnZXRQcm90b3R5cGUgPSBvdmVyQXJnKE9iamVjdC5nZXRQcm90b3R5cGVPZiwgT2JqZWN0KSxcbiAgICAgICAgb2JqZWN0Q3JlYXRlID0gT2JqZWN0LmNyZWF0ZSxcbiAgICAgICAgcHJvcGVydHlJc0VudW1lcmFibGUgPSBvYmplY3RQcm90by5wcm9wZXJ0eUlzRW51bWVyYWJsZSxcbiAgICAgICAgc3BsaWNlID0gYXJyYXlQcm90by5zcGxpY2UsXG4gICAgICAgIHNwcmVhZGFibGVTeW1ib2wgPSBTeW1ib2wgPyBTeW1ib2wuaXNDb25jYXRTcHJlYWRhYmxlIDogdW5kZWZpbmVkLFxuICAgICAgICBzeW1JdGVyYXRvciA9IFN5bWJvbCA/IFN5bWJvbC5pdGVyYXRvciA6IHVuZGVmaW5lZCxcbiAgICAgICAgc3ltVG9TdHJpbmdUYWcgPSBTeW1ib2wgPyBTeW1ib2wudG9TdHJpbmdUYWcgOiB1bmRlZmluZWQ7XG5cbiAgICB2YXIgZGVmaW5lUHJvcGVydHkgPSAoZnVuY3Rpb24oKSB7XG4gICAgICB0cnkge1xuICAgICAgICB2YXIgZnVuYyA9IGdldE5hdGl2ZShPYmplY3QsICdkZWZpbmVQcm9wZXJ0eScpO1xuICAgICAgICBmdW5jKHt9LCAnJywge30pO1xuICAgICAgICByZXR1cm4gZnVuYztcbiAgICAgIH0gY2F0Y2ggKGUpIHt9XG4gICAgfSgpKTtcblxuICAgIC8qKiBNb2NrZWQgYnVpbHQtaW5zLiAqL1xuICAgIHZhciBjdHhDbGVhclRpbWVvdXQgPSBjb250ZXh0LmNsZWFyVGltZW91dCAhPT0gcm9vdC5jbGVhclRpbWVvdXQgJiYgY29udGV4dC5jbGVhclRpbWVvdXQsXG4gICAgICAgIGN0eE5vdyA9IERhdGUgJiYgRGF0ZS5ub3cgIT09IHJvb3QuRGF0ZS5ub3cgJiYgRGF0ZS5ub3csXG4gICAgICAgIGN0eFNldFRpbWVvdXQgPSBjb250ZXh0LnNldFRpbWVvdXQgIT09IHJvb3Quc2V0VGltZW91dCAmJiBjb250ZXh0LnNldFRpbWVvdXQ7XG5cbiAgICAvKiBCdWlsdC1pbiBtZXRob2QgcmVmZXJlbmNlcyBmb3IgdGhvc2Ugd2l0aCB0aGUgc2FtZSBuYW1lIGFzIG90aGVyIGBsb2Rhc2hgIG1ldGhvZHMuICovXG4gICAgdmFyIG5hdGl2ZUNlaWwgPSBNYXRoLmNlaWwsXG4gICAgICAgIG5hdGl2ZUZsb29yID0gTWF0aC5mbG9vcixcbiAgICAgICAgbmF0aXZlR2V0U3ltYm9scyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eVN5bWJvbHMsXG4gICAgICAgIG5hdGl2ZUlzQnVmZmVyID0gQnVmZmVyID8gQnVmZmVyLmlzQnVmZmVyIDogdW5kZWZpbmVkLFxuICAgICAgICBuYXRpdmVJc0Zpbml0ZSA9IGNvbnRleHQuaXNGaW5pdGUsXG4gICAgICAgIG5hdGl2ZUpvaW4gPSBhcnJheVByb3RvLmpvaW4sXG4gICAgICAgIG5hdGl2ZUtleXMgPSBvdmVyQXJnKE9iamVjdC5rZXlzLCBPYmplY3QpLFxuICAgICAgICBuYXRpdmVNYXggPSBNYXRoLm1heCxcbiAgICAgICAgbmF0aXZlTWluID0gTWF0aC5taW4sXG4gICAgICAgIG5hdGl2ZU5vdyA9IERhdGUubm93LFxuICAgICAgICBuYXRpdmVQYXJzZUludCA9IGNvbnRleHQucGFyc2VJbnQsXG4gICAgICAgIG5hdGl2ZVJhbmRvbSA9IE1hdGgucmFuZG9tLFxuICAgICAgICBuYXRpdmVSZXZlcnNlID0gYXJyYXlQcm90by5yZXZlcnNlO1xuXG4gICAgLyogQnVpbHQtaW4gbWV0aG9kIHJlZmVyZW5jZXMgdGhhdCBhcmUgdmVyaWZpZWQgdG8gYmUgbmF0aXZlLiAqL1xuICAgIHZhciBEYXRhVmlldyA9IGdldE5hdGl2ZShjb250ZXh0LCAnRGF0YVZpZXcnKSxcbiAgICAgICAgTWFwID0gZ2V0TmF0aXZlKGNvbnRleHQsICdNYXAnKSxcbiAgICAgICAgUHJvbWlzZSA9IGdldE5hdGl2ZShjb250ZXh0LCAnUHJvbWlzZScpLFxuICAgICAgICBTZXQgPSBnZXROYXRpdmUoY29udGV4dCwgJ1NldCcpLFxuICAgICAgICBXZWFrTWFwID0gZ2V0TmF0aXZlKGNvbnRleHQsICdXZWFrTWFwJyksXG4gICAgICAgIG5hdGl2ZUNyZWF0ZSA9IGdldE5hdGl2ZShPYmplY3QsICdjcmVhdGUnKTtcblxuICAgIC8qKiBVc2VkIHRvIHN0b3JlIGZ1bmN0aW9uIG1ldGFkYXRhLiAqL1xuICAgIHZhciBtZXRhTWFwID0gV2Vha01hcCAmJiBuZXcgV2Vha01hcDtcblxuICAgIC8qKiBVc2VkIHRvIGxvb2t1cCB1bm1pbmlmaWVkIGZ1bmN0aW9uIG5hbWVzLiAqL1xuICAgIHZhciByZWFsTmFtZXMgPSB7fTtcblxuICAgIC8qKiBVc2VkIHRvIGRldGVjdCBtYXBzLCBzZXRzLCBhbmQgd2Vha21hcHMuICovXG4gICAgdmFyIGRhdGFWaWV3Q3RvclN0cmluZyA9IHRvU291cmNlKERhdGFWaWV3KSxcbiAgICAgICAgbWFwQ3RvclN0cmluZyA9IHRvU291cmNlKE1hcCksXG4gICAgICAgIHByb21pc2VDdG9yU3RyaW5nID0gdG9Tb3VyY2UoUHJvbWlzZSksXG4gICAgICAgIHNldEN0b3JTdHJpbmcgPSB0b1NvdXJjZShTZXQpLFxuICAgICAgICB3ZWFrTWFwQ3RvclN0cmluZyA9IHRvU291cmNlKFdlYWtNYXApO1xuXG4gICAgLyoqIFVzZWQgdG8gY29udmVydCBzeW1ib2xzIHRvIHByaW1pdGl2ZXMgYW5kIHN0cmluZ3MuICovXG4gICAgdmFyIHN5bWJvbFByb3RvID0gU3ltYm9sID8gU3ltYm9sLnByb3RvdHlwZSA6IHVuZGVmaW5lZCxcbiAgICAgICAgc3ltYm9sVmFsdWVPZiA9IHN5bWJvbFByb3RvID8gc3ltYm9sUHJvdG8udmFsdWVPZiA6IHVuZGVmaW5lZCxcbiAgICAgICAgc3ltYm9sVG9TdHJpbmcgPSBzeW1ib2xQcm90byA/IHN5bWJvbFByb3RvLnRvU3RyaW5nIDogdW5kZWZpbmVkO1xuXG4gICAgLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIGBsb2Rhc2hgIG9iamVjdCB3aGljaCB3cmFwcyBgdmFsdWVgIHRvIGVuYWJsZSBpbXBsaWNpdCBtZXRob2RcbiAgICAgKiBjaGFpbiBzZXF1ZW5jZXMuIE1ldGhvZHMgdGhhdCBvcGVyYXRlIG9uIGFuZCByZXR1cm4gYXJyYXlzLCBjb2xsZWN0aW9ucyxcbiAgICAgKiBhbmQgZnVuY3Rpb25zIGNhbiBiZSBjaGFpbmVkIHRvZ2V0aGVyLiBNZXRob2RzIHRoYXQgcmV0cmlldmUgYSBzaW5nbGUgdmFsdWVcbiAgICAgKiBvciBtYXkgcmV0dXJuIGEgcHJpbWl0aXZlIHZhbHVlIHdpbGwgYXV0b21hdGljYWxseSBlbmQgdGhlIGNoYWluIHNlcXVlbmNlXG4gICAgICogYW5kIHJldHVybiB0aGUgdW53cmFwcGVkIHZhbHVlLiBPdGhlcndpc2UsIHRoZSB2YWx1ZSBtdXN0IGJlIHVud3JhcHBlZFxuICAgICAqIHdpdGggYF8jdmFsdWVgLlxuICAgICAqXG4gICAgICogRXhwbGljaXQgY2hhaW4gc2VxdWVuY2VzLCB3aGljaCBtdXN0IGJlIHVud3JhcHBlZCB3aXRoIGBfI3ZhbHVlYCwgbWF5IGJlXG4gICAgICogZW5hYmxlZCB1c2luZyBgXy5jaGFpbmAuXG4gICAgICpcbiAgICAgKiBUaGUgZXhlY3V0aW9uIG9mIGNoYWluZWQgbWV0aG9kcyBpcyBsYXp5LCB0aGF0IGlzLCBpdCdzIGRlZmVycmVkIHVudGlsXG4gICAgICogYF8jdmFsdWVgIGlzIGltcGxpY2l0bHkgb3IgZXhwbGljaXRseSBjYWxsZWQuXG4gICAgICpcbiAgICAgKiBMYXp5IGV2YWx1YXRpb24gYWxsb3dzIHNldmVyYWwgbWV0aG9kcyB0byBzdXBwb3J0IHNob3J0Y3V0IGZ1c2lvbi5cbiAgICAgKiBTaG9ydGN1dCBmdXNpb24gaXMgYW4gb3B0aW1pemF0aW9uIHRvIG1lcmdlIGl0ZXJhdGVlIGNhbGxzOyB0aGlzIGF2b2lkc1xuICAgICAqIHRoZSBjcmVhdGlvbiBvZiBpbnRlcm1lZGlhdGUgYXJyYXlzIGFuZCBjYW4gZ3JlYXRseSByZWR1Y2UgdGhlIG51bWJlciBvZlxuICAgICAqIGl0ZXJhdGVlIGV4ZWN1dGlvbnMuIFNlY3Rpb25zIG9mIGEgY2hhaW4gc2VxdWVuY2UgcXVhbGlmeSBmb3Igc2hvcnRjdXRcbiAgICAgKiBmdXNpb24gaWYgdGhlIHNlY3Rpb24gaXMgYXBwbGllZCB0byBhbiBhcnJheSBhbmQgaXRlcmF0ZWVzIGFjY2VwdCBvbmx5XG4gICAgICogb25lIGFyZ3VtZW50LiBUaGUgaGV1cmlzdGljIGZvciB3aGV0aGVyIGEgc2VjdGlvbiBxdWFsaWZpZXMgZm9yIHNob3J0Y3V0XG4gICAgICogZnVzaW9uIGlzIHN1YmplY3QgdG8gY2hhbmdlLlxuICAgICAqXG4gICAgICogQ2hhaW5pbmcgaXMgc3VwcG9ydGVkIGluIGN1c3RvbSBidWlsZHMgYXMgbG9uZyBhcyB0aGUgYF8jdmFsdWVgIG1ldGhvZCBpc1xuICAgICAqIGRpcmVjdGx5IG9yIGluZGlyZWN0bHkgaW5jbHVkZWQgaW4gdGhlIGJ1aWxkLlxuICAgICAqXG4gICAgICogSW4gYWRkaXRpb24gdG8gbG9kYXNoIG1ldGhvZHMsIHdyYXBwZXJzIGhhdmUgYEFycmF5YCBhbmQgYFN0cmluZ2AgbWV0aG9kcy5cbiAgICAgKlxuICAgICAqIFRoZSB3cmFwcGVyIGBBcnJheWAgbWV0aG9kcyBhcmU6XG4gICAgICogYGNvbmNhdGAsIGBqb2luYCwgYHBvcGAsIGBwdXNoYCwgYHNoaWZ0YCwgYHNvcnRgLCBgc3BsaWNlYCwgYW5kIGB1bnNoaWZ0YFxuICAgICAqXG4gICAgICogVGhlIHdyYXBwZXIgYFN0cmluZ2AgbWV0aG9kcyBhcmU6XG4gICAgICogYHJlcGxhY2VgIGFuZCBgc3BsaXRgXG4gICAgICpcbiAgICAgKiBUaGUgd3JhcHBlciBtZXRob2RzIHRoYXQgc3VwcG9ydCBzaG9ydGN1dCBmdXNpb24gYXJlOlxuICAgICAqIGBhdGAsIGBjb21wYWN0YCwgYGRyb3BgLCBgZHJvcFJpZ2h0YCwgYGRyb3BXaGlsZWAsIGBmaWx0ZXJgLCBgZmluZGAsXG4gICAgICogYGZpbmRMYXN0YCwgYGhlYWRgLCBgaW5pdGlhbGAsIGBsYXN0YCwgYG1hcGAsIGByZWplY3RgLCBgcmV2ZXJzZWAsIGBzbGljZWAsXG4gICAgICogYHRhaWxgLCBgdGFrZWAsIGB0YWtlUmlnaHRgLCBgdGFrZVJpZ2h0V2hpbGVgLCBgdGFrZVdoaWxlYCwgYW5kIGB0b0FycmF5YFxuICAgICAqXG4gICAgICogVGhlIGNoYWluYWJsZSB3cmFwcGVyIG1ldGhvZHMgYXJlOlxuICAgICAqIGBhZnRlcmAsIGBhcnlgLCBgYXNzaWduYCwgYGFzc2lnbkluYCwgYGFzc2lnbkluV2l0aGAsIGBhc3NpZ25XaXRoYCwgYGF0YCxcbiAgICAgKiBgYmVmb3JlYCwgYGJpbmRgLCBgYmluZEFsbGAsIGBiaW5kS2V5YCwgYGNhc3RBcnJheWAsIGBjaGFpbmAsIGBjaHVua2AsXG4gICAgICogYGNvbW1pdGAsIGBjb21wYWN0YCwgYGNvbmNhdGAsIGBjb25mb3Jtc2AsIGBjb25zdGFudGAsIGBjb3VudEJ5YCwgYGNyZWF0ZWAsXG4gICAgICogYGN1cnJ5YCwgYGRlYm91bmNlYCwgYGRlZmF1bHRzYCwgYGRlZmF1bHRzRGVlcGAsIGBkZWZlcmAsIGBkZWxheWAsXG4gICAgICogYGRpZmZlcmVuY2VgLCBgZGlmZmVyZW5jZUJ5YCwgYGRpZmZlcmVuY2VXaXRoYCwgYGRyb3BgLCBgZHJvcFJpZ2h0YCxcbiAgICAgKiBgZHJvcFJpZ2h0V2hpbGVgLCBgZHJvcFdoaWxlYCwgYGV4dGVuZGAsIGBleHRlbmRXaXRoYCwgYGZpbGxgLCBgZmlsdGVyYCxcbiAgICAgKiBgZmxhdE1hcGAsIGBmbGF0TWFwRGVlcGAsIGBmbGF0TWFwRGVwdGhgLCBgZmxhdHRlbmAsIGBmbGF0dGVuRGVlcGAsXG4gICAgICogYGZsYXR0ZW5EZXB0aGAsIGBmbGlwYCwgYGZsb3dgLCBgZmxvd1JpZ2h0YCwgYGZyb21QYWlyc2AsIGBmdW5jdGlvbnNgLFxuICAgICAqIGBmdW5jdGlvbnNJbmAsIGBncm91cEJ5YCwgYGluaXRpYWxgLCBgaW50ZXJzZWN0aW9uYCwgYGludGVyc2VjdGlvbkJ5YCxcbiAgICAgKiBgaW50ZXJzZWN0aW9uV2l0aGAsIGBpbnZlcnRgLCBgaW52ZXJ0QnlgLCBgaW52b2tlTWFwYCwgYGl0ZXJhdGVlYCwgYGtleUJ5YCxcbiAgICAgKiBga2V5c2AsIGBrZXlzSW5gLCBgbWFwYCwgYG1hcEtleXNgLCBgbWFwVmFsdWVzYCwgYG1hdGNoZXNgLCBgbWF0Y2hlc1Byb3BlcnR5YCxcbiAgICAgKiBgbWVtb2l6ZWAsIGBtZXJnZWAsIGBtZXJnZVdpdGhgLCBgbWV0aG9kYCwgYG1ldGhvZE9mYCwgYG1peGluYCwgYG5lZ2F0ZWAsXG4gICAgICogYG50aEFyZ2AsIGBvbWl0YCwgYG9taXRCeWAsIGBvbmNlYCwgYG9yZGVyQnlgLCBgb3ZlcmAsIGBvdmVyQXJnc2AsXG4gICAgICogYG92ZXJFdmVyeWAsIGBvdmVyU29tZWAsIGBwYXJ0aWFsYCwgYHBhcnRpYWxSaWdodGAsIGBwYXJ0aXRpb25gLCBgcGlja2AsXG4gICAgICogYHBpY2tCeWAsIGBwbGFudGAsIGBwcm9wZXJ0eWAsIGBwcm9wZXJ0eU9mYCwgYHB1bGxgLCBgcHVsbEFsbGAsIGBwdWxsQWxsQnlgLFxuICAgICAqIGBwdWxsQWxsV2l0aGAsIGBwdWxsQXRgLCBgcHVzaGAsIGByYW5nZWAsIGByYW5nZVJpZ2h0YCwgYHJlYXJnYCwgYHJlamVjdGAsXG4gICAgICogYHJlbW92ZWAsIGByZXN0YCwgYHJldmVyc2VgLCBgc2FtcGxlU2l6ZWAsIGBzZXRgLCBgc2V0V2l0aGAsIGBzaHVmZmxlYCxcbiAgICAgKiBgc2xpY2VgLCBgc29ydGAsIGBzb3J0QnlgLCBgc3BsaWNlYCwgYHNwcmVhZGAsIGB0YWlsYCwgYHRha2VgLCBgdGFrZVJpZ2h0YCxcbiAgICAgKiBgdGFrZVJpZ2h0V2hpbGVgLCBgdGFrZVdoaWxlYCwgYHRhcGAsIGB0aHJvdHRsZWAsIGB0aHJ1YCwgYHRvQXJyYXlgLFxuICAgICAqIGB0b1BhaXJzYCwgYHRvUGFpcnNJbmAsIGB0b1BhdGhgLCBgdG9QbGFpbk9iamVjdGAsIGB0cmFuc2Zvcm1gLCBgdW5hcnlgLFxuICAgICAqIGB1bmlvbmAsIGB1bmlvbkJ5YCwgYHVuaW9uV2l0aGAsIGB1bmlxYCwgYHVuaXFCeWAsIGB1bmlxV2l0aGAsIGB1bnNldGAsXG4gICAgICogYHVuc2hpZnRgLCBgdW56aXBgLCBgdW56aXBXaXRoYCwgYHVwZGF0ZWAsIGB1cGRhdGVXaXRoYCwgYHZhbHVlc2AsXG4gICAgICogYHZhbHVlc0luYCwgYHdpdGhvdXRgLCBgd3JhcGAsIGB4b3JgLCBgeG9yQnlgLCBgeG9yV2l0aGAsIGB6aXBgLFxuICAgICAqIGB6aXBPYmplY3RgLCBgemlwT2JqZWN0RGVlcGAsIGFuZCBgemlwV2l0aGBcbiAgICAgKlxuICAgICAqIFRoZSB3cmFwcGVyIG1ldGhvZHMgdGhhdCBhcmUgKipub3QqKiBjaGFpbmFibGUgYnkgZGVmYXVsdCBhcmU6XG4gICAgICogYGFkZGAsIGBhdHRlbXB0YCwgYGNhbWVsQ2FzZWAsIGBjYXBpdGFsaXplYCwgYGNlaWxgLCBgY2xhbXBgLCBgY2xvbmVgLFxuICAgICAqIGBjbG9uZURlZXBgLCBgY2xvbmVEZWVwV2l0aGAsIGBjbG9uZVdpdGhgLCBgY29uZm9ybXNUb2AsIGBkZWJ1cnJgLFxuICAgICAqIGBkZWZhdWx0VG9gLCBgZGl2aWRlYCwgYGVhY2hgLCBgZWFjaFJpZ2h0YCwgYGVuZHNXaXRoYCwgYGVxYCwgYGVzY2FwZWAsXG4gICAgICogYGVzY2FwZVJlZ0V4cGAsIGBldmVyeWAsIGBmaW5kYCwgYGZpbmRJbmRleGAsIGBmaW5kS2V5YCwgYGZpbmRMYXN0YCxcbiAgICAgKiBgZmluZExhc3RJbmRleGAsIGBmaW5kTGFzdEtleWAsIGBmaXJzdGAsIGBmbG9vcmAsIGBmb3JFYWNoYCwgYGZvckVhY2hSaWdodGAsXG4gICAgICogYGZvckluYCwgYGZvckluUmlnaHRgLCBgZm9yT3duYCwgYGZvck93blJpZ2h0YCwgYGdldGAsIGBndGAsIGBndGVgLCBgaGFzYCxcbiAgICAgKiBgaGFzSW5gLCBgaGVhZGAsIGBpZGVudGl0eWAsIGBpbmNsdWRlc2AsIGBpbmRleE9mYCwgYGluUmFuZ2VgLCBgaW52b2tlYCxcbiAgICAgKiBgaXNBcmd1bWVudHNgLCBgaXNBcnJheWAsIGBpc0FycmF5QnVmZmVyYCwgYGlzQXJyYXlMaWtlYCwgYGlzQXJyYXlMaWtlT2JqZWN0YCxcbiAgICAgKiBgaXNCb29sZWFuYCwgYGlzQnVmZmVyYCwgYGlzRGF0ZWAsIGBpc0VsZW1lbnRgLCBgaXNFbXB0eWAsIGBpc0VxdWFsYCxcbiAgICAgKiBgaXNFcXVhbFdpdGhgLCBgaXNFcnJvcmAsIGBpc0Zpbml0ZWAsIGBpc0Z1bmN0aW9uYCwgYGlzSW50ZWdlcmAsIGBpc0xlbmd0aGAsXG4gICAgICogYGlzTWFwYCwgYGlzTWF0Y2hgLCBgaXNNYXRjaFdpdGhgLCBgaXNOYU5gLCBgaXNOYXRpdmVgLCBgaXNOaWxgLCBgaXNOdWxsYCxcbiAgICAgKiBgaXNOdW1iZXJgLCBgaXNPYmplY3RgLCBgaXNPYmplY3RMaWtlYCwgYGlzUGxhaW5PYmplY3RgLCBgaXNSZWdFeHBgLFxuICAgICAqIGBpc1NhZmVJbnRlZ2VyYCwgYGlzU2V0YCwgYGlzU3RyaW5nYCwgYGlzVW5kZWZpbmVkYCwgYGlzVHlwZWRBcnJheWAsXG4gICAgICogYGlzV2Vha01hcGAsIGBpc1dlYWtTZXRgLCBgam9pbmAsIGBrZWJhYkNhc2VgLCBgbGFzdGAsIGBsYXN0SW5kZXhPZmAsXG4gICAgICogYGxvd2VyQ2FzZWAsIGBsb3dlckZpcnN0YCwgYGx0YCwgYGx0ZWAsIGBtYXhgLCBgbWF4QnlgLCBgbWVhbmAsIGBtZWFuQnlgLFxuICAgICAqIGBtaW5gLCBgbWluQnlgLCBgbXVsdGlwbHlgLCBgbm9Db25mbGljdGAsIGBub29wYCwgYG5vd2AsIGBudGhgLCBgcGFkYCxcbiAgICAgKiBgcGFkRW5kYCwgYHBhZFN0YXJ0YCwgYHBhcnNlSW50YCwgYHBvcGAsIGByYW5kb21gLCBgcmVkdWNlYCwgYHJlZHVjZVJpZ2h0YCxcbiAgICAgKiBgcmVwZWF0YCwgYHJlc3VsdGAsIGByb3VuZGAsIGBydW5JbkNvbnRleHRgLCBgc2FtcGxlYCwgYHNoaWZ0YCwgYHNpemVgLFxuICAgICAqIGBzbmFrZUNhc2VgLCBgc29tZWAsIGBzb3J0ZWRJbmRleGAsIGBzb3J0ZWRJbmRleEJ5YCwgYHNvcnRlZExhc3RJbmRleGAsXG4gICAgICogYHNvcnRlZExhc3RJbmRleEJ5YCwgYHN0YXJ0Q2FzZWAsIGBzdGFydHNXaXRoYCwgYHN0dWJBcnJheWAsIGBzdHViRmFsc2VgLFxuICAgICAqIGBzdHViT2JqZWN0YCwgYHN0dWJTdHJpbmdgLCBgc3R1YlRydWVgLCBgc3VidHJhY3RgLCBgc3VtYCwgYHN1bUJ5YCxcbiAgICAgKiBgdGVtcGxhdGVgLCBgdGltZXNgLCBgdG9GaW5pdGVgLCBgdG9JbnRlZ2VyYCwgYHRvSlNPTmAsIGB0b0xlbmd0aGAsXG4gICAgICogYHRvTG93ZXJgLCBgdG9OdW1iZXJgLCBgdG9TYWZlSW50ZWdlcmAsIGB0b1N0cmluZ2AsIGB0b1VwcGVyYCwgYHRyaW1gLFxuICAgICAqIGB0cmltRW5kYCwgYHRyaW1TdGFydGAsIGB0cnVuY2F0ZWAsIGB1bmVzY2FwZWAsIGB1bmlxdWVJZGAsIGB1cHBlckNhc2VgLFxuICAgICAqIGB1cHBlckZpcnN0YCwgYHZhbHVlYCwgYW5kIGB3b3Jkc2BcbiAgICAgKlxuICAgICAqIEBuYW1lIF9cbiAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgKiBAY2F0ZWdvcnkgU2VxXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gd3JhcCBpbiBhIGBsb2Rhc2hgIGluc3RhbmNlLlxuICAgICAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgdGhlIG5ldyBgbG9kYXNoYCB3cmFwcGVyIGluc3RhbmNlLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBmdW5jdGlvbiBzcXVhcmUobikge1xuICAgICAqICAgcmV0dXJuIG4gKiBuO1xuICAgICAqIH1cbiAgICAgKlxuICAgICAqIHZhciB3cmFwcGVkID0gXyhbMSwgMiwgM10pO1xuICAgICAqXG4gICAgICogLy8gUmV0dXJucyBhbiB1bndyYXBwZWQgdmFsdWUuXG4gICAgICogd3JhcHBlZC5yZWR1Y2UoXy5hZGQpO1xuICAgICAqIC8vID0+IDZcbiAgICAgKlxuICAgICAqIC8vIFJldHVybnMgYSB3cmFwcGVkIHZhbHVlLlxuICAgICAqIHZhciBzcXVhcmVzID0gd3JhcHBlZC5tYXAoc3F1YXJlKTtcbiAgICAgKlxuICAgICAqIF8uaXNBcnJheShzcXVhcmVzKTtcbiAgICAgKiAvLyA9PiBmYWxzZVxuICAgICAqXG4gICAgICogXy5pc0FycmF5KHNxdWFyZXMudmFsdWUoKSk7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGxvZGFzaCh2YWx1ZSkge1xuICAgICAgaWYgKGlzT2JqZWN0TGlrZSh2YWx1ZSkgJiYgIWlzQXJyYXkodmFsdWUpICYmICEodmFsdWUgaW5zdGFuY2VvZiBMYXp5V3JhcHBlcikpIHtcbiAgICAgICAgaWYgKHZhbHVlIGluc3RhbmNlb2YgTG9kYXNoV3JhcHBlcikge1xuICAgICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoaGFzT3duUHJvcGVydHkuY2FsbCh2YWx1ZSwgJ19fd3JhcHBlZF9fJykpIHtcbiAgICAgICAgICByZXR1cm4gd3JhcHBlckNsb25lKHZhbHVlKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIG5ldyBMb2Rhc2hXcmFwcGVyKHZhbHVlKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5jcmVhdGVgIHdpdGhvdXQgc3VwcG9ydCBmb3IgYXNzaWduaW5nXG4gICAgICogcHJvcGVydGllcyB0byB0aGUgY3JlYXRlZCBvYmplY3QuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBwcm90byBUaGUgb2JqZWN0IHRvIGluaGVyaXQgZnJvbS5cbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIHRoZSBuZXcgb2JqZWN0LlxuICAgICAqL1xuICAgIHZhciBiYXNlQ3JlYXRlID0gKGZ1bmN0aW9uKCkge1xuICAgICAgZnVuY3Rpb24gb2JqZWN0KCkge31cbiAgICAgIHJldHVybiBmdW5jdGlvbihwcm90bykge1xuICAgICAgICBpZiAoIWlzT2JqZWN0KHByb3RvKSkge1xuICAgICAgICAgIHJldHVybiB7fTtcbiAgICAgICAgfVxuICAgICAgICBpZiAob2JqZWN0Q3JlYXRlKSB7XG4gICAgICAgICAgcmV0dXJuIG9iamVjdENyZWF0ZShwcm90byk7XG4gICAgICAgIH1cbiAgICAgICAgb2JqZWN0LnByb3RvdHlwZSA9IHByb3RvO1xuICAgICAgICB2YXIgcmVzdWx0ID0gbmV3IG9iamVjdDtcbiAgICAgICAgb2JqZWN0LnByb3RvdHlwZSA9IHVuZGVmaW5lZDtcbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgIH07XG4gICAgfSgpKTtcblxuICAgIC8qKlxuICAgICAqIFRoZSBmdW5jdGlvbiB3aG9zZSBwcm90b3R5cGUgY2hhaW4gc2VxdWVuY2Ugd3JhcHBlcnMgaW5oZXJpdCBmcm9tLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBiYXNlTG9kYXNoKCkge1xuICAgICAgLy8gTm8gb3BlcmF0aW9uIHBlcmZvcm1lZC5cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYmFzZSBjb25zdHJ1Y3RvciBmb3IgY3JlYXRpbmcgYGxvZGFzaGAgd3JhcHBlciBvYmplY3RzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byB3cmFwLlxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbn0gW2NoYWluQWxsXSBFbmFibGUgZXhwbGljaXQgbWV0aG9kIGNoYWluIHNlcXVlbmNlcy5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBMb2Rhc2hXcmFwcGVyKHZhbHVlLCBjaGFpbkFsbCkge1xuICAgICAgdGhpcy5fX3dyYXBwZWRfXyA9IHZhbHVlO1xuICAgICAgdGhpcy5fX2FjdGlvbnNfXyA9IFtdO1xuICAgICAgdGhpcy5fX2NoYWluX18gPSAhIWNoYWluQWxsO1xuICAgICAgdGhpcy5fX2luZGV4X18gPSAwO1xuICAgICAgdGhpcy5fX3ZhbHVlc19fID0gdW5kZWZpbmVkO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEJ5IGRlZmF1bHQsIHRoZSB0ZW1wbGF0ZSBkZWxpbWl0ZXJzIHVzZWQgYnkgbG9kYXNoIGFyZSBsaWtlIHRob3NlIGluXG4gICAgICogZW1iZWRkZWQgUnVieSAoRVJCKSBhcyB3ZWxsIGFzIEVTMjAxNSB0ZW1wbGF0ZSBzdHJpbmdzLiBDaGFuZ2UgdGhlXG4gICAgICogZm9sbG93aW5nIHRlbXBsYXRlIHNldHRpbmdzIHRvIHVzZSBhbHRlcm5hdGl2ZSBkZWxpbWl0ZXJzLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHR5cGUge09iamVjdH1cbiAgICAgKi9cbiAgICBsb2Rhc2gudGVtcGxhdGVTZXR0aW5ncyA9IHtcblxuICAgICAgLyoqXG4gICAgICAgKiBVc2VkIHRvIGRldGVjdCBgZGF0YWAgcHJvcGVydHkgdmFsdWVzIHRvIGJlIEhUTUwtZXNjYXBlZC5cbiAgICAgICAqXG4gICAgICAgKiBAbWVtYmVyT2YgXy50ZW1wbGF0ZVNldHRpbmdzXG4gICAgICAgKiBAdHlwZSB7UmVnRXhwfVxuICAgICAgICovXG4gICAgICAnZXNjYXBlJzogcmVFc2NhcGUsXG5cbiAgICAgIC8qKlxuICAgICAgICogVXNlZCB0byBkZXRlY3QgY29kZSB0byBiZSBldmFsdWF0ZWQuXG4gICAgICAgKlxuICAgICAgICogQG1lbWJlck9mIF8udGVtcGxhdGVTZXR0aW5nc1xuICAgICAgICogQHR5cGUge1JlZ0V4cH1cbiAgICAgICAqL1xuICAgICAgJ2V2YWx1YXRlJzogcmVFdmFsdWF0ZSxcblxuICAgICAgLyoqXG4gICAgICAgKiBVc2VkIHRvIGRldGVjdCBgZGF0YWAgcHJvcGVydHkgdmFsdWVzIHRvIGluamVjdC5cbiAgICAgICAqXG4gICAgICAgKiBAbWVtYmVyT2YgXy50ZW1wbGF0ZVNldHRpbmdzXG4gICAgICAgKiBAdHlwZSB7UmVnRXhwfVxuICAgICAgICovXG4gICAgICAnaW50ZXJwb2xhdGUnOiByZUludGVycG9sYXRlLFxuXG4gICAgICAvKipcbiAgICAgICAqIFVzZWQgdG8gcmVmZXJlbmNlIHRoZSBkYXRhIG9iamVjdCBpbiB0aGUgdGVtcGxhdGUgdGV4dC5cbiAgICAgICAqXG4gICAgICAgKiBAbWVtYmVyT2YgXy50ZW1wbGF0ZVNldHRpbmdzXG4gICAgICAgKiBAdHlwZSB7c3RyaW5nfVxuICAgICAgICovXG4gICAgICAndmFyaWFibGUnOiAnJyxcblxuICAgICAgLyoqXG4gICAgICAgKiBVc2VkIHRvIGltcG9ydCB2YXJpYWJsZXMgaW50byB0aGUgY29tcGlsZWQgdGVtcGxhdGUuXG4gICAgICAgKlxuICAgICAgICogQG1lbWJlck9mIF8udGVtcGxhdGVTZXR0aW5nc1xuICAgICAgICogQHR5cGUge09iamVjdH1cbiAgICAgICAqL1xuICAgICAgJ2ltcG9ydHMnOiB7XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIEEgcmVmZXJlbmNlIHRvIHRoZSBgbG9kYXNoYCBmdW5jdGlvbi5cbiAgICAgICAgICpcbiAgICAgICAgICogQG1lbWJlck9mIF8udGVtcGxhdGVTZXR0aW5ncy5pbXBvcnRzXG4gICAgICAgICAqIEB0eXBlIHtGdW5jdGlvbn1cbiAgICAgICAgICovXG4gICAgICAgICdfJzogbG9kYXNoXG4gICAgICB9XG4gICAgfTtcblxuICAgIC8vIEVuc3VyZSB3cmFwcGVycyBhcmUgaW5zdGFuY2VzIG9mIGBiYXNlTG9kYXNoYC5cbiAgICBsb2Rhc2gucHJvdG90eXBlID0gYmFzZUxvZGFzaC5wcm90b3R5cGU7XG4gICAgbG9kYXNoLnByb3RvdHlwZS5jb25zdHJ1Y3RvciA9IGxvZGFzaDtcblxuICAgIExvZGFzaFdyYXBwZXIucHJvdG90eXBlID0gYmFzZUNyZWF0ZShiYXNlTG9kYXNoLnByb3RvdHlwZSk7XG4gICAgTG9kYXNoV3JhcHBlci5wcm90b3R5cGUuY29uc3RydWN0b3IgPSBMb2Rhc2hXcmFwcGVyO1xuXG4gICAgLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIGxhenkgd3JhcHBlciBvYmplY3Qgd2hpY2ggd3JhcHMgYHZhbHVlYCB0byBlbmFibGUgbGF6eSBldmFsdWF0aW9uLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byB3cmFwLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIExhenlXcmFwcGVyKHZhbHVlKSB7XG4gICAgICB0aGlzLl9fd3JhcHBlZF9fID0gdmFsdWU7XG4gICAgICB0aGlzLl9fYWN0aW9uc19fID0gW107XG4gICAgICB0aGlzLl9fZGlyX18gPSAxO1xuICAgICAgdGhpcy5fX2ZpbHRlcmVkX18gPSBmYWxzZTtcbiAgICAgIHRoaXMuX19pdGVyYXRlZXNfXyA9IFtdO1xuICAgICAgdGhpcy5fX3Rha2VDb3VudF9fID0gTUFYX0FSUkFZX0xFTkdUSDtcbiAgICAgIHRoaXMuX192aWV3c19fID0gW107XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIGNsb25lIG9mIHRoZSBsYXp5IHdyYXBwZXIgb2JqZWN0LlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAbmFtZSBjbG9uZVxuICAgICAqIEBtZW1iZXJPZiBMYXp5V3JhcHBlclxuICAgICAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgdGhlIGNsb25lZCBgTGF6eVdyYXBwZXJgIG9iamVjdC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBsYXp5Q2xvbmUoKSB7XG4gICAgICB2YXIgcmVzdWx0ID0gbmV3IExhenlXcmFwcGVyKHRoaXMuX193cmFwcGVkX18pO1xuICAgICAgcmVzdWx0Ll9fYWN0aW9uc19fID0gY29weUFycmF5KHRoaXMuX19hY3Rpb25zX18pO1xuICAgICAgcmVzdWx0Ll9fZGlyX18gPSB0aGlzLl9fZGlyX187XG4gICAgICByZXN1bHQuX19maWx0ZXJlZF9fID0gdGhpcy5fX2ZpbHRlcmVkX187XG4gICAgICByZXN1bHQuX19pdGVyYXRlZXNfXyA9IGNvcHlBcnJheSh0aGlzLl9faXRlcmF0ZWVzX18pO1xuICAgICAgcmVzdWx0Ll9fdGFrZUNvdW50X18gPSB0aGlzLl9fdGFrZUNvdW50X187XG4gICAgICByZXN1bHQuX192aWV3c19fID0gY29weUFycmF5KHRoaXMuX192aWV3c19fKTtcbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmV2ZXJzZXMgdGhlIGRpcmVjdGlvbiBvZiBsYXp5IGl0ZXJhdGlvbi5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQG5hbWUgcmV2ZXJzZVxuICAgICAqIEBtZW1iZXJPZiBMYXp5V3JhcHBlclxuICAgICAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgdGhlIG5ldyByZXZlcnNlZCBgTGF6eVdyYXBwZXJgIG9iamVjdC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBsYXp5UmV2ZXJzZSgpIHtcbiAgICAgIGlmICh0aGlzLl9fZmlsdGVyZWRfXykge1xuICAgICAgICB2YXIgcmVzdWx0ID0gbmV3IExhenlXcmFwcGVyKHRoaXMpO1xuICAgICAgICByZXN1bHQuX19kaXJfXyA9IC0xO1xuICAgICAgICByZXN1bHQuX19maWx0ZXJlZF9fID0gdHJ1ZTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJlc3VsdCA9IHRoaXMuY2xvbmUoKTtcbiAgICAgICAgcmVzdWx0Ll9fZGlyX18gKj0gLTE7XG4gICAgICB9XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEV4dHJhY3RzIHRoZSB1bndyYXBwZWQgdmFsdWUgZnJvbSBpdHMgbGF6eSB3cmFwcGVyLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAbmFtZSB2YWx1ZVxuICAgICAqIEBtZW1iZXJPZiBMYXp5V3JhcHBlclxuICAgICAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSB1bndyYXBwZWQgdmFsdWUuXG4gICAgICovXG4gICAgZnVuY3Rpb24gbGF6eVZhbHVlKCkge1xuICAgICAgdmFyIGFycmF5ID0gdGhpcy5fX3dyYXBwZWRfXy52YWx1ZSgpLFxuICAgICAgICAgIGRpciA9IHRoaXMuX19kaXJfXyxcbiAgICAgICAgICBpc0FyciA9IGlzQXJyYXkoYXJyYXkpLFxuICAgICAgICAgIGlzUmlnaHQgPSBkaXIgPCAwLFxuICAgICAgICAgIGFyckxlbmd0aCA9IGlzQXJyID8gYXJyYXkubGVuZ3RoIDogMCxcbiAgICAgICAgICB2aWV3ID0gZ2V0VmlldygwLCBhcnJMZW5ndGgsIHRoaXMuX192aWV3c19fKSxcbiAgICAgICAgICBzdGFydCA9IHZpZXcuc3RhcnQsXG4gICAgICAgICAgZW5kID0gdmlldy5lbmQsXG4gICAgICAgICAgbGVuZ3RoID0gZW5kIC0gc3RhcnQsXG4gICAgICAgICAgaW5kZXggPSBpc1JpZ2h0ID8gZW5kIDogKHN0YXJ0IC0gMSksXG4gICAgICAgICAgaXRlcmF0ZWVzID0gdGhpcy5fX2l0ZXJhdGVlc19fLFxuICAgICAgICAgIGl0ZXJMZW5ndGggPSBpdGVyYXRlZXMubGVuZ3RoLFxuICAgICAgICAgIHJlc0luZGV4ID0gMCxcbiAgICAgICAgICB0YWtlQ291bnQgPSBuYXRpdmVNaW4obGVuZ3RoLCB0aGlzLl9fdGFrZUNvdW50X18pO1xuXG4gICAgICBpZiAoIWlzQXJyIHx8ICghaXNSaWdodCAmJiBhcnJMZW5ndGggPT0gbGVuZ3RoICYmIHRha2VDb3VudCA9PSBsZW5ndGgpKSB7XG4gICAgICAgIHJldHVybiBiYXNlV3JhcHBlclZhbHVlKGFycmF5LCB0aGlzLl9fYWN0aW9uc19fKTtcbiAgICAgIH1cbiAgICAgIHZhciByZXN1bHQgPSBbXTtcblxuICAgICAgb3V0ZXI6XG4gICAgICB3aGlsZSAobGVuZ3RoLS0gJiYgcmVzSW5kZXggPCB0YWtlQ291bnQpIHtcbiAgICAgICAgaW5kZXggKz0gZGlyO1xuXG4gICAgICAgIHZhciBpdGVySW5kZXggPSAtMSxcbiAgICAgICAgICAgIHZhbHVlID0gYXJyYXlbaW5kZXhdO1xuXG4gICAgICAgIHdoaWxlICgrK2l0ZXJJbmRleCA8IGl0ZXJMZW5ndGgpIHtcbiAgICAgICAgICB2YXIgZGF0YSA9IGl0ZXJhdGVlc1tpdGVySW5kZXhdLFxuICAgICAgICAgICAgICBpdGVyYXRlZSA9IGRhdGEuaXRlcmF0ZWUsXG4gICAgICAgICAgICAgIHR5cGUgPSBkYXRhLnR5cGUsXG4gICAgICAgICAgICAgIGNvbXB1dGVkID0gaXRlcmF0ZWUodmFsdWUpO1xuXG4gICAgICAgICAgaWYgKHR5cGUgPT0gTEFaWV9NQVBfRkxBRykge1xuICAgICAgICAgICAgdmFsdWUgPSBjb21wdXRlZDtcbiAgICAgICAgICB9IGVsc2UgaWYgKCFjb21wdXRlZCkge1xuICAgICAgICAgICAgaWYgKHR5cGUgPT0gTEFaWV9GSUxURVJfRkxBRykge1xuICAgICAgICAgICAgICBjb250aW51ZSBvdXRlcjtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIGJyZWFrIG91dGVyO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXN1bHRbcmVzSW5kZXgrK10gPSB2YWx1ZTtcbiAgICAgIH1cbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgLy8gRW5zdXJlIGBMYXp5V3JhcHBlcmAgaXMgYW4gaW5zdGFuY2Ugb2YgYGJhc2VMb2Rhc2hgLlxuICAgIExhenlXcmFwcGVyLnByb3RvdHlwZSA9IGJhc2VDcmVhdGUoYmFzZUxvZGFzaC5wcm90b3R5cGUpO1xuICAgIExhenlXcmFwcGVyLnByb3RvdHlwZS5jb25zdHJ1Y3RvciA9IExhenlXcmFwcGVyO1xuXG4gICAgLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIGhhc2ggb2JqZWN0LlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBbZW50cmllc10gVGhlIGtleS12YWx1ZSBwYWlycyB0byBjYWNoZS5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBIYXNoKGVudHJpZXMpIHtcbiAgICAgIHZhciBpbmRleCA9IC0xLFxuICAgICAgICAgIGxlbmd0aCA9IGVudHJpZXMgPT0gbnVsbCA/IDAgOiBlbnRyaWVzLmxlbmd0aDtcblxuICAgICAgdGhpcy5jbGVhcigpO1xuICAgICAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHtcbiAgICAgICAgdmFyIGVudHJ5ID0gZW50cmllc1tpbmRleF07XG4gICAgICAgIHRoaXMuc2V0KGVudHJ5WzBdLCBlbnRyeVsxXSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmVtb3ZlcyBhbGwga2V5LXZhbHVlIGVudHJpZXMgZnJvbSB0aGUgaGFzaC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQG5hbWUgY2xlYXJcbiAgICAgKiBAbWVtYmVyT2YgSGFzaFxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGhhc2hDbGVhcigpIHtcbiAgICAgIHRoaXMuX19kYXRhX18gPSBuYXRpdmVDcmVhdGUgPyBuYXRpdmVDcmVhdGUobnVsbCkgOiB7fTtcbiAgICAgIHRoaXMuc2l6ZSA9IDA7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmVtb3ZlcyBga2V5YCBhbmQgaXRzIHZhbHVlIGZyb20gdGhlIGhhc2guXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBuYW1lIGRlbGV0ZVxuICAgICAqIEBtZW1iZXJPZiBIYXNoXG4gICAgICogQHBhcmFtIHtPYmplY3R9IGhhc2ggVGhlIGhhc2ggdG8gbW9kaWZ5LlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgVGhlIGtleSBvZiB0aGUgdmFsdWUgdG8gcmVtb3ZlLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiB0aGUgZW50cnkgd2FzIHJlbW92ZWQsIGVsc2UgYGZhbHNlYC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBoYXNoRGVsZXRlKGtleSkge1xuICAgICAgdmFyIHJlc3VsdCA9IHRoaXMuaGFzKGtleSkgJiYgZGVsZXRlIHRoaXMuX19kYXRhX19ba2V5XTtcbiAgICAgIHRoaXMuc2l6ZSAtPSByZXN1bHQgPyAxIDogMDtcbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0cyB0aGUgaGFzaCB2YWx1ZSBmb3IgYGtleWAuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBuYW1lIGdldFxuICAgICAqIEBtZW1iZXJPZiBIYXNoXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGtleSBUaGUga2V5IG9mIHRoZSB2YWx1ZSB0byBnZXQuXG4gICAgICogQHJldHVybnMgeyp9IFJldHVybnMgdGhlIGVudHJ5IHZhbHVlLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGhhc2hHZXQoa2V5KSB7XG4gICAgICB2YXIgZGF0YSA9IHRoaXMuX19kYXRhX187XG4gICAgICBpZiAobmF0aXZlQ3JlYXRlKSB7XG4gICAgICAgIHZhciByZXN1bHQgPSBkYXRhW2tleV07XG4gICAgICAgIHJldHVybiByZXN1bHQgPT09IEhBU0hfVU5ERUZJTkVEID8gdW5kZWZpbmVkIDogcmVzdWx0O1xuICAgICAgfVxuICAgICAgcmV0dXJuIGhhc093blByb3BlcnR5LmNhbGwoZGF0YSwga2V5KSA/IGRhdGFba2V5XSA6IHVuZGVmaW5lZDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDaGVja3MgaWYgYSBoYXNoIHZhbHVlIGZvciBga2V5YCBleGlzdHMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBuYW1lIGhhc1xuICAgICAqIEBtZW1iZXJPZiBIYXNoXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGtleSBUaGUga2V5IG9mIHRoZSBlbnRyeSB0byBjaGVjay5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYW4gZW50cnkgZm9yIGBrZXlgIGV4aXN0cywgZWxzZSBgZmFsc2VgLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGhhc2hIYXMoa2V5KSB7XG4gICAgICB2YXIgZGF0YSA9IHRoaXMuX19kYXRhX187XG4gICAgICByZXR1cm4gbmF0aXZlQ3JlYXRlID8gKGRhdGFba2V5XSAhPT0gdW5kZWZpbmVkKSA6IGhhc093blByb3BlcnR5LmNhbGwoZGF0YSwga2V5KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTZXRzIHRoZSBoYXNoIGBrZXlgIHRvIGB2YWx1ZWAuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBuYW1lIHNldFxuICAgICAqIEBtZW1iZXJPZiBIYXNoXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGtleSBUaGUga2V5IG9mIHRoZSB2YWx1ZSB0byBzZXQuXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gc2V0LlxuICAgICAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgdGhlIGhhc2ggaW5zdGFuY2UuXG4gICAgICovXG4gICAgZnVuY3Rpb24gaGFzaFNldChrZXksIHZhbHVlKSB7XG4gICAgICB2YXIgZGF0YSA9IHRoaXMuX19kYXRhX187XG4gICAgICB0aGlzLnNpemUgKz0gdGhpcy5oYXMoa2V5KSA/IDAgOiAxO1xuICAgICAgZGF0YVtrZXldID0gKG5hdGl2ZUNyZWF0ZSAmJiB2YWx1ZSA9PT0gdW5kZWZpbmVkKSA/IEhBU0hfVU5ERUZJTkVEIDogdmFsdWU7XG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvLyBBZGQgbWV0aG9kcyB0byBgSGFzaGAuXG4gICAgSGFzaC5wcm90b3R5cGUuY2xlYXIgPSBoYXNoQ2xlYXI7XG4gICAgSGFzaC5wcm90b3R5cGVbJ2RlbGV0ZSddID0gaGFzaERlbGV0ZTtcbiAgICBIYXNoLnByb3RvdHlwZS5nZXQgPSBoYXNoR2V0O1xuICAgIEhhc2gucHJvdG90eXBlLmhhcyA9IGhhc2hIYXM7XG4gICAgSGFzaC5wcm90b3R5cGUuc2V0ID0gaGFzaFNldDtcblxuICAgIC8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi9cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYW4gbGlzdCBjYWNoZSBvYmplY3QuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAqIEBwYXJhbSB7QXJyYXl9IFtlbnRyaWVzXSBUaGUga2V5LXZhbHVlIHBhaXJzIHRvIGNhY2hlLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIExpc3RDYWNoZShlbnRyaWVzKSB7XG4gICAgICB2YXIgaW5kZXggPSAtMSxcbiAgICAgICAgICBsZW5ndGggPSBlbnRyaWVzID09IG51bGwgPyAwIDogZW50cmllcy5sZW5ndGg7XG5cbiAgICAgIHRoaXMuY2xlYXIoKTtcbiAgICAgIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XG4gICAgICAgIHZhciBlbnRyeSA9IGVudHJpZXNbaW5kZXhdO1xuICAgICAgICB0aGlzLnNldChlbnRyeVswXSwgZW50cnlbMV0pO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJlbW92ZXMgYWxsIGtleS12YWx1ZSBlbnRyaWVzIGZyb20gdGhlIGxpc3QgY2FjaGUuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBuYW1lIGNsZWFyXG4gICAgICogQG1lbWJlck9mIExpc3RDYWNoZVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGxpc3RDYWNoZUNsZWFyKCkge1xuICAgICAgdGhpcy5fX2RhdGFfXyA9IFtdO1xuICAgICAgdGhpcy5zaXplID0gMDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZW1vdmVzIGBrZXlgIGFuZCBpdHMgdmFsdWUgZnJvbSB0aGUgbGlzdCBjYWNoZS5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQG5hbWUgZGVsZXRlXG4gICAgICogQG1lbWJlck9mIExpc3RDYWNoZVxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgVGhlIGtleSBvZiB0aGUgdmFsdWUgdG8gcmVtb3ZlLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiB0aGUgZW50cnkgd2FzIHJlbW92ZWQsIGVsc2UgYGZhbHNlYC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBsaXN0Q2FjaGVEZWxldGUoa2V5KSB7XG4gICAgICB2YXIgZGF0YSA9IHRoaXMuX19kYXRhX18sXG4gICAgICAgICAgaW5kZXggPSBhc3NvY0luZGV4T2YoZGF0YSwga2V5KTtcblxuICAgICAgaWYgKGluZGV4IDwgMCkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgICB2YXIgbGFzdEluZGV4ID0gZGF0YS5sZW5ndGggLSAxO1xuICAgICAgaWYgKGluZGV4ID09IGxhc3RJbmRleCkge1xuICAgICAgICBkYXRhLnBvcCgpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgc3BsaWNlLmNhbGwoZGF0YSwgaW5kZXgsIDEpO1xuICAgICAgfVxuICAgICAgLS10aGlzLnNpemU7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXRzIHRoZSBsaXN0IGNhY2hlIHZhbHVlIGZvciBga2V5YC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQG5hbWUgZ2V0XG4gICAgICogQG1lbWJlck9mIExpc3RDYWNoZVxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgVGhlIGtleSBvZiB0aGUgdmFsdWUgdG8gZ2V0LlxuICAgICAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSBlbnRyeSB2YWx1ZS5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBsaXN0Q2FjaGVHZXQoa2V5KSB7XG4gICAgICB2YXIgZGF0YSA9IHRoaXMuX19kYXRhX18sXG4gICAgICAgICAgaW5kZXggPSBhc3NvY0luZGV4T2YoZGF0YSwga2V5KTtcblxuICAgICAgcmV0dXJuIGluZGV4IDwgMCA/IHVuZGVmaW5lZCA6IGRhdGFbaW5kZXhdWzFdO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENoZWNrcyBpZiBhIGxpc3QgY2FjaGUgdmFsdWUgZm9yIGBrZXlgIGV4aXN0cy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQG5hbWUgaGFzXG4gICAgICogQG1lbWJlck9mIExpc3RDYWNoZVxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgVGhlIGtleSBvZiB0aGUgZW50cnkgdG8gY2hlY2suXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGFuIGVudHJ5IGZvciBga2V5YCBleGlzdHMsIGVsc2UgYGZhbHNlYC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBsaXN0Q2FjaGVIYXMoa2V5KSB7XG4gICAgICByZXR1cm4gYXNzb2NJbmRleE9mKHRoaXMuX19kYXRhX18sIGtleSkgPiAtMTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTZXRzIHRoZSBsaXN0IGNhY2hlIGBrZXlgIHRvIGB2YWx1ZWAuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBuYW1lIHNldFxuICAgICAqIEBtZW1iZXJPZiBMaXN0Q2FjaGVcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30ga2V5IFRoZSBrZXkgb2YgdGhlIHZhbHVlIHRvIHNldC5cbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBzZXQuXG4gICAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyB0aGUgbGlzdCBjYWNoZSBpbnN0YW5jZS5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBsaXN0Q2FjaGVTZXQoa2V5LCB2YWx1ZSkge1xuICAgICAgdmFyIGRhdGEgPSB0aGlzLl9fZGF0YV9fLFxuICAgICAgICAgIGluZGV4ID0gYXNzb2NJbmRleE9mKGRhdGEsIGtleSk7XG5cbiAgICAgIGlmIChpbmRleCA8IDApIHtcbiAgICAgICAgKyt0aGlzLnNpemU7XG4gICAgICAgIGRhdGEucHVzaChba2V5LCB2YWx1ZV0pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZGF0YVtpbmRleF1bMV0gPSB2YWx1ZTtcbiAgICAgIH1cbiAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8vIEFkZCBtZXRob2RzIHRvIGBMaXN0Q2FjaGVgLlxuICAgIExpc3RDYWNoZS5wcm90b3R5cGUuY2xlYXIgPSBsaXN0Q2FjaGVDbGVhcjtcbiAgICBMaXN0Q2FjaGUucHJvdG90eXBlWydkZWxldGUnXSA9IGxpc3RDYWNoZURlbGV0ZTtcbiAgICBMaXN0Q2FjaGUucHJvdG90eXBlLmdldCA9IGxpc3RDYWNoZUdldDtcbiAgICBMaXN0Q2FjaGUucHJvdG90eXBlLmhhcyA9IGxpc3RDYWNoZUhhcztcbiAgICBMaXN0Q2FjaGUucHJvdG90eXBlLnNldCA9IGxpc3RDYWNoZVNldDtcblxuICAgIC8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi9cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBtYXAgY2FjaGUgb2JqZWN0IHRvIHN0b3JlIGtleS12YWx1ZSBwYWlycy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQGNvbnN0cnVjdG9yXG4gICAgICogQHBhcmFtIHtBcnJheX0gW2VudHJpZXNdIFRoZSBrZXktdmFsdWUgcGFpcnMgdG8gY2FjaGUuXG4gICAgICovXG4gICAgZnVuY3Rpb24gTWFwQ2FjaGUoZW50cmllcykge1xuICAgICAgdmFyIGluZGV4ID0gLTEsXG4gICAgICAgICAgbGVuZ3RoID0gZW50cmllcyA9PSBudWxsID8gMCA6IGVudHJpZXMubGVuZ3RoO1xuXG4gICAgICB0aGlzLmNsZWFyKCk7XG4gICAgICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgICAgICB2YXIgZW50cnkgPSBlbnRyaWVzW2luZGV4XTtcbiAgICAgICAgdGhpcy5zZXQoZW50cnlbMF0sIGVudHJ5WzFdKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZW1vdmVzIGFsbCBrZXktdmFsdWUgZW50cmllcyBmcm9tIHRoZSBtYXAuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBuYW1lIGNsZWFyXG4gICAgICogQG1lbWJlck9mIE1hcENhY2hlXG4gICAgICovXG4gICAgZnVuY3Rpb24gbWFwQ2FjaGVDbGVhcigpIHtcbiAgICAgIHRoaXMuc2l6ZSA9IDA7XG4gICAgICB0aGlzLl9fZGF0YV9fID0ge1xuICAgICAgICAnaGFzaCc6IG5ldyBIYXNoLFxuICAgICAgICAnbWFwJzogbmV3IChNYXAgfHwgTGlzdENhY2hlKSxcbiAgICAgICAgJ3N0cmluZyc6IG5ldyBIYXNoXG4gICAgICB9O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJlbW92ZXMgYGtleWAgYW5kIGl0cyB2YWx1ZSBmcm9tIHRoZSBtYXAuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBuYW1lIGRlbGV0ZVxuICAgICAqIEBtZW1iZXJPZiBNYXBDYWNoZVxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgVGhlIGtleSBvZiB0aGUgdmFsdWUgdG8gcmVtb3ZlLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiB0aGUgZW50cnkgd2FzIHJlbW92ZWQsIGVsc2UgYGZhbHNlYC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBtYXBDYWNoZURlbGV0ZShrZXkpIHtcbiAgICAgIHZhciByZXN1bHQgPSBnZXRNYXBEYXRhKHRoaXMsIGtleSlbJ2RlbGV0ZSddKGtleSk7XG4gICAgICB0aGlzLnNpemUgLT0gcmVzdWx0ID8gMSA6IDA7XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldHMgdGhlIG1hcCB2YWx1ZSBmb3IgYGtleWAuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBuYW1lIGdldFxuICAgICAqIEBtZW1iZXJPZiBNYXBDYWNoZVxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgVGhlIGtleSBvZiB0aGUgdmFsdWUgdG8gZ2V0LlxuICAgICAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSBlbnRyeSB2YWx1ZS5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBtYXBDYWNoZUdldChrZXkpIHtcbiAgICAgIHJldHVybiBnZXRNYXBEYXRhKHRoaXMsIGtleSkuZ2V0KGtleSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2hlY2tzIGlmIGEgbWFwIHZhbHVlIGZvciBga2V5YCBleGlzdHMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBuYW1lIGhhc1xuICAgICAqIEBtZW1iZXJPZiBNYXBDYWNoZVxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgVGhlIGtleSBvZiB0aGUgZW50cnkgdG8gY2hlY2suXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGFuIGVudHJ5IGZvciBga2V5YCBleGlzdHMsIGVsc2UgYGZhbHNlYC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBtYXBDYWNoZUhhcyhrZXkpIHtcbiAgICAgIHJldHVybiBnZXRNYXBEYXRhKHRoaXMsIGtleSkuaGFzKGtleSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2V0cyB0aGUgbWFwIGBrZXlgIHRvIGB2YWx1ZWAuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBuYW1lIHNldFxuICAgICAqIEBtZW1iZXJPZiBNYXBDYWNoZVxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgVGhlIGtleSBvZiB0aGUgdmFsdWUgdG8gc2V0LlxuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIHNldC5cbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIHRoZSBtYXAgY2FjaGUgaW5zdGFuY2UuXG4gICAgICovXG4gICAgZnVuY3Rpb24gbWFwQ2FjaGVTZXQoa2V5LCB2YWx1ZSkge1xuICAgICAgdmFyIGRhdGEgPSBnZXRNYXBEYXRhKHRoaXMsIGtleSksXG4gICAgICAgICAgc2l6ZSA9IGRhdGEuc2l6ZTtcblxuICAgICAgZGF0YS5zZXQoa2V5LCB2YWx1ZSk7XG4gICAgICB0aGlzLnNpemUgKz0gZGF0YS5zaXplID09IHNpemUgPyAwIDogMTtcbiAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8vIEFkZCBtZXRob2RzIHRvIGBNYXBDYWNoZWAuXG4gICAgTWFwQ2FjaGUucHJvdG90eXBlLmNsZWFyID0gbWFwQ2FjaGVDbGVhcjtcbiAgICBNYXBDYWNoZS5wcm90b3R5cGVbJ2RlbGV0ZSddID0gbWFwQ2FjaGVEZWxldGU7XG4gICAgTWFwQ2FjaGUucHJvdG90eXBlLmdldCA9IG1hcENhY2hlR2V0O1xuICAgIE1hcENhY2hlLnByb3RvdHlwZS5oYXMgPSBtYXBDYWNoZUhhcztcbiAgICBNYXBDYWNoZS5wcm90b3R5cGUuc2V0ID0gbWFwQ2FjaGVTZXQ7XG5cbiAgICAvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovXG5cbiAgICAvKipcbiAgICAgKlxuICAgICAqIENyZWF0ZXMgYW4gYXJyYXkgY2FjaGUgb2JqZWN0IHRvIHN0b3JlIHVuaXF1ZSB2YWx1ZXMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAqIEBwYXJhbSB7QXJyYXl9IFt2YWx1ZXNdIFRoZSB2YWx1ZXMgdG8gY2FjaGUuXG4gICAgICovXG4gICAgZnVuY3Rpb24gU2V0Q2FjaGUodmFsdWVzKSB7XG4gICAgICB2YXIgaW5kZXggPSAtMSxcbiAgICAgICAgICBsZW5ndGggPSB2YWx1ZXMgPT0gbnVsbCA/IDAgOiB2YWx1ZXMubGVuZ3RoO1xuXG4gICAgICB0aGlzLl9fZGF0YV9fID0gbmV3IE1hcENhY2hlO1xuICAgICAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHtcbiAgICAgICAgdGhpcy5hZGQodmFsdWVzW2luZGV4XSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQWRkcyBgdmFsdWVgIHRvIHRoZSBhcnJheSBjYWNoZS5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQG5hbWUgYWRkXG4gICAgICogQG1lbWJlck9mIFNldENhY2hlXG4gICAgICogQGFsaWFzIHB1c2hcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjYWNoZS5cbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIHRoZSBjYWNoZSBpbnN0YW5jZS5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBzZXRDYWNoZUFkZCh2YWx1ZSkge1xuICAgICAgdGhpcy5fX2RhdGFfXy5zZXQodmFsdWUsIEhBU0hfVU5ERUZJTkVEKTtcbiAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIGluIHRoZSBhcnJheSBjYWNoZS5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQG5hbWUgaGFzXG4gICAgICogQG1lbWJlck9mIFNldENhY2hlXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gc2VhcmNoIGZvci5cbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGZvdW5kLCBlbHNlIGBmYWxzZWAuXG4gICAgICovXG4gICAgZnVuY3Rpb24gc2V0Q2FjaGVIYXModmFsdWUpIHtcbiAgICAgIHJldHVybiB0aGlzLl9fZGF0YV9fLmhhcyh2YWx1ZSk7XG4gICAgfVxuXG4gICAgLy8gQWRkIG1ldGhvZHMgdG8gYFNldENhY2hlYC5cbiAgICBTZXRDYWNoZS5wcm90b3R5cGUuYWRkID0gU2V0Q2FjaGUucHJvdG90eXBlLnB1c2ggPSBzZXRDYWNoZUFkZDtcbiAgICBTZXRDYWNoZS5wcm90b3R5cGUuaGFzID0gc2V0Q2FjaGVIYXM7XG5cbiAgICAvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovXG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgc3RhY2sgY2FjaGUgb2JqZWN0IHRvIHN0b3JlIGtleS12YWx1ZSBwYWlycy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQGNvbnN0cnVjdG9yXG4gICAgICogQHBhcmFtIHtBcnJheX0gW2VudHJpZXNdIFRoZSBrZXktdmFsdWUgcGFpcnMgdG8gY2FjaGUuXG4gICAgICovXG4gICAgZnVuY3Rpb24gU3RhY2soZW50cmllcykge1xuICAgICAgdmFyIGRhdGEgPSB0aGlzLl9fZGF0YV9fID0gbmV3IExpc3RDYWNoZShlbnRyaWVzKTtcbiAgICAgIHRoaXMuc2l6ZSA9IGRhdGEuc2l6ZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZW1vdmVzIGFsbCBrZXktdmFsdWUgZW50cmllcyBmcm9tIHRoZSBzdGFjay5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQG5hbWUgY2xlYXJcbiAgICAgKiBAbWVtYmVyT2YgU3RhY2tcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBzdGFja0NsZWFyKCkge1xuICAgICAgdGhpcy5fX2RhdGFfXyA9IG5ldyBMaXN0Q2FjaGU7XG4gICAgICB0aGlzLnNpemUgPSAwO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJlbW92ZXMgYGtleWAgYW5kIGl0cyB2YWx1ZSBmcm9tIHRoZSBzdGFjay5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQG5hbWUgZGVsZXRlXG4gICAgICogQG1lbWJlck9mIFN0YWNrXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGtleSBUaGUga2V5IG9mIHRoZSB2YWx1ZSB0byByZW1vdmUuXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIHRoZSBlbnRyeSB3YXMgcmVtb3ZlZCwgZWxzZSBgZmFsc2VgLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIHN0YWNrRGVsZXRlKGtleSkge1xuICAgICAgdmFyIGRhdGEgPSB0aGlzLl9fZGF0YV9fLFxuICAgICAgICAgIHJlc3VsdCA9IGRhdGFbJ2RlbGV0ZSddKGtleSk7XG5cbiAgICAgIHRoaXMuc2l6ZSA9IGRhdGEuc2l6ZTtcbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0cyB0aGUgc3RhY2sgdmFsdWUgZm9yIGBrZXlgLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAbmFtZSBnZXRcbiAgICAgKiBAbWVtYmVyT2YgU3RhY2tcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30ga2V5IFRoZSBrZXkgb2YgdGhlIHZhbHVlIHRvIGdldC5cbiAgICAgKiBAcmV0dXJucyB7Kn0gUmV0dXJucyB0aGUgZW50cnkgdmFsdWUuXG4gICAgICovXG4gICAgZnVuY3Rpb24gc3RhY2tHZXQoa2V5KSB7XG4gICAgICByZXR1cm4gdGhpcy5fX2RhdGFfXy5nZXQoa2V5KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDaGVja3MgaWYgYSBzdGFjayB2YWx1ZSBmb3IgYGtleWAgZXhpc3RzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAbmFtZSBoYXNcbiAgICAgKiBAbWVtYmVyT2YgU3RhY2tcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30ga2V5IFRoZSBrZXkgb2YgdGhlIGVudHJ5IHRvIGNoZWNrLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBhbiBlbnRyeSBmb3IgYGtleWAgZXhpc3RzLCBlbHNlIGBmYWxzZWAuXG4gICAgICovXG4gICAgZnVuY3Rpb24gc3RhY2tIYXMoa2V5KSB7XG4gICAgICByZXR1cm4gdGhpcy5fX2RhdGFfXy5oYXMoa2V5KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTZXRzIHRoZSBzdGFjayBga2V5YCB0byBgdmFsdWVgLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAbmFtZSBzZXRcbiAgICAgKiBAbWVtYmVyT2YgU3RhY2tcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30ga2V5IFRoZSBrZXkgb2YgdGhlIHZhbHVlIHRvIHNldC5cbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBzZXQuXG4gICAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyB0aGUgc3RhY2sgY2FjaGUgaW5zdGFuY2UuXG4gICAgICovXG4gICAgZnVuY3Rpb24gc3RhY2tTZXQoa2V5LCB2YWx1ZSkge1xuICAgICAgdmFyIGRhdGEgPSB0aGlzLl9fZGF0YV9fO1xuICAgICAgaWYgKGRhdGEgaW5zdGFuY2VvZiBMaXN0Q2FjaGUpIHtcbiAgICAgICAgdmFyIHBhaXJzID0gZGF0YS5fX2RhdGFfXztcbiAgICAgICAgaWYgKCFNYXAgfHwgKHBhaXJzLmxlbmd0aCA8IExBUkdFX0FSUkFZX1NJWkUgLSAxKSkge1xuICAgICAgICAgIHBhaXJzLnB1c2goW2tleSwgdmFsdWVdKTtcbiAgICAgICAgICB0aGlzLnNpemUgPSArK2RhdGEuc2l6ZTtcbiAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgfVxuICAgICAgICBkYXRhID0gdGhpcy5fX2RhdGFfXyA9IG5ldyBNYXBDYWNoZShwYWlycyk7XG4gICAgICB9XG4gICAgICBkYXRhLnNldChrZXksIHZhbHVlKTtcbiAgICAgIHRoaXMuc2l6ZSA9IGRhdGEuc2l6ZTtcbiAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8vIEFkZCBtZXRob2RzIHRvIGBTdGFja2AuXG4gICAgU3RhY2sucHJvdG90eXBlLmNsZWFyID0gc3RhY2tDbGVhcjtcbiAgICBTdGFjay5wcm90b3R5cGVbJ2RlbGV0ZSddID0gc3RhY2tEZWxldGU7XG4gICAgU3RhY2sucHJvdG90eXBlLmdldCA9IHN0YWNrR2V0O1xuICAgIFN0YWNrLnByb3RvdHlwZS5oYXMgPSBzdGFja0hhcztcbiAgICBTdGFjay5wcm90b3R5cGUuc2V0ID0gc3RhY2tTZXQ7XG5cbiAgICAvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovXG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGFuIGFycmF5IG9mIHRoZSBlbnVtZXJhYmxlIHByb3BlcnR5IG5hbWVzIG9mIHRoZSBhcnJheS1saWtlIGB2YWx1ZWAuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIHF1ZXJ5LlxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbn0gaW5oZXJpdGVkIFNwZWNpZnkgcmV0dXJuaW5nIGluaGVyaXRlZCBwcm9wZXJ0eSBuYW1lcy5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIGFycmF5IG9mIHByb3BlcnR5IG5hbWVzLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGFycmF5TGlrZUtleXModmFsdWUsIGluaGVyaXRlZCkge1xuICAgICAgdmFyIGlzQXJyID0gaXNBcnJheSh2YWx1ZSksXG4gICAgICAgICAgaXNBcmcgPSAhaXNBcnIgJiYgaXNBcmd1bWVudHModmFsdWUpLFxuICAgICAgICAgIGlzQnVmZiA9ICFpc0FyciAmJiAhaXNBcmcgJiYgaXNCdWZmZXIodmFsdWUpLFxuICAgICAgICAgIGlzVHlwZSA9ICFpc0FyciAmJiAhaXNBcmcgJiYgIWlzQnVmZiAmJiBpc1R5cGVkQXJyYXkodmFsdWUpLFxuICAgICAgICAgIHNraXBJbmRleGVzID0gaXNBcnIgfHwgaXNBcmcgfHwgaXNCdWZmIHx8IGlzVHlwZSxcbiAgICAgICAgICByZXN1bHQgPSBza2lwSW5kZXhlcyA/IGJhc2VUaW1lcyh2YWx1ZS5sZW5ndGgsIFN0cmluZykgOiBbXSxcbiAgICAgICAgICBsZW5ndGggPSByZXN1bHQubGVuZ3RoO1xuXG4gICAgICBmb3IgKHZhciBrZXkgaW4gdmFsdWUpIHtcbiAgICAgICAgaWYgKChpbmhlcml0ZWQgfHwgaGFzT3duUHJvcGVydHkuY2FsbCh2YWx1ZSwga2V5KSkgJiZcbiAgICAgICAgICAgICEoc2tpcEluZGV4ZXMgJiYgKFxuICAgICAgICAgICAgICAgLy8gU2FmYXJpIDkgaGFzIGVudW1lcmFibGUgYGFyZ3VtZW50cy5sZW5ndGhgIGluIHN0cmljdCBtb2RlLlxuICAgICAgICAgICAgICAga2V5ID09ICdsZW5ndGgnIHx8XG4gICAgICAgICAgICAgICAvLyBOb2RlLmpzIDAuMTAgaGFzIGVudW1lcmFibGUgbm9uLWluZGV4IHByb3BlcnRpZXMgb24gYnVmZmVycy5cbiAgICAgICAgICAgICAgIChpc0J1ZmYgJiYgKGtleSA9PSAnb2Zmc2V0JyB8fCBrZXkgPT0gJ3BhcmVudCcpKSB8fFxuICAgICAgICAgICAgICAgLy8gUGhhbnRvbUpTIDIgaGFzIGVudW1lcmFibGUgbm9uLWluZGV4IHByb3BlcnRpZXMgb24gdHlwZWQgYXJyYXlzLlxuICAgICAgICAgICAgICAgKGlzVHlwZSAmJiAoa2V5ID09ICdidWZmZXInIHx8IGtleSA9PSAnYnl0ZUxlbmd0aCcgfHwga2V5ID09ICdieXRlT2Zmc2V0JykpIHx8XG4gICAgICAgICAgICAgICAvLyBTa2lwIGluZGV4IHByb3BlcnRpZXMuXG4gICAgICAgICAgICAgICBpc0luZGV4KGtleSwgbGVuZ3RoKVxuICAgICAgICAgICAgKSkpIHtcbiAgICAgICAgICByZXN1bHQucHVzaChrZXkpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEEgc3BlY2lhbGl6ZWQgdmVyc2lvbiBvZiBgXy5zYW1wbGVgIGZvciBhcnJheXMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBzYW1wbGUuXG4gICAgICogQHJldHVybnMgeyp9IFJldHVybnMgdGhlIHJhbmRvbSBlbGVtZW50LlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGFycmF5U2FtcGxlKGFycmF5KSB7XG4gICAgICB2YXIgbGVuZ3RoID0gYXJyYXkubGVuZ3RoO1xuICAgICAgcmV0dXJuIGxlbmd0aCA/IGFycmF5W2Jhc2VSYW5kb20oMCwgbGVuZ3RoIC0gMSldIDogdW5kZWZpbmVkO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEEgc3BlY2lhbGl6ZWQgdmVyc2lvbiBvZiBgXy5zYW1wbGVTaXplYCBmb3IgYXJyYXlzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gc2FtcGxlLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBuIFRoZSBudW1iZXIgb2YgZWxlbWVudHMgdG8gc2FtcGxlLlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgcmFuZG9tIGVsZW1lbnRzLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGFycmF5U2FtcGxlU2l6ZShhcnJheSwgbikge1xuICAgICAgcmV0dXJuIHNodWZmbGVTZWxmKGNvcHlBcnJheShhcnJheSksIGJhc2VDbGFtcChuLCAwLCBhcnJheS5sZW5ndGgpKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBBIHNwZWNpYWxpemVkIHZlcnNpb24gb2YgYF8uc2h1ZmZsZWAgZm9yIGFycmF5cy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIHNodWZmbGUuXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBuZXcgc2h1ZmZsZWQgYXJyYXkuXG4gICAgICovXG4gICAgZnVuY3Rpb24gYXJyYXlTaHVmZmxlKGFycmF5KSB7XG4gICAgICByZXR1cm4gc2h1ZmZsZVNlbGYoY29weUFycmF5KGFycmF5KSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhpcyBmdW5jdGlvbiBpcyBsaWtlIGBhc3NpZ25WYWx1ZWAgZXhjZXB0IHRoYXQgaXQgZG9lc24ndCBhc3NpZ25cbiAgICAgKiBgdW5kZWZpbmVkYCB2YWx1ZXMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBtb2RpZnkuXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGtleSBUaGUga2V5IG9mIHRoZSBwcm9wZXJ0eSB0byBhc3NpZ24uXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gYXNzaWduLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGFzc2lnbk1lcmdlVmFsdWUob2JqZWN0LCBrZXksIHZhbHVlKSB7XG4gICAgICBpZiAoKHZhbHVlICE9PSB1bmRlZmluZWQgJiYgIWVxKG9iamVjdFtrZXldLCB2YWx1ZSkpIHx8XG4gICAgICAgICAgKHZhbHVlID09PSB1bmRlZmluZWQgJiYgIShrZXkgaW4gb2JqZWN0KSkpIHtcbiAgICAgICAgYmFzZUFzc2lnblZhbHVlKG9iamVjdCwga2V5LCB2YWx1ZSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQXNzaWducyBgdmFsdWVgIHRvIGBrZXlgIG9mIGBvYmplY3RgIGlmIHRoZSBleGlzdGluZyB2YWx1ZSBpcyBub3QgZXF1aXZhbGVudFxuICAgICAqIHVzaW5nIFtgU2FtZVZhbHVlWmVyb2BdKGh0dHA6Ly9lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzcuMC8jc2VjLXNhbWV2YWx1ZXplcm8pXG4gICAgICogZm9yIGVxdWFsaXR5IGNvbXBhcmlzb25zLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gbW9kaWZ5LlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgVGhlIGtleSBvZiB0aGUgcHJvcGVydHkgdG8gYXNzaWduLlxuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGFzc2lnbi5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBhc3NpZ25WYWx1ZShvYmplY3QsIGtleSwgdmFsdWUpIHtcbiAgICAgIHZhciBvYmpWYWx1ZSA9IG9iamVjdFtrZXldO1xuICAgICAgaWYgKCEoaGFzT3duUHJvcGVydHkuY2FsbChvYmplY3QsIGtleSkgJiYgZXEob2JqVmFsdWUsIHZhbHVlKSkgfHxcbiAgICAgICAgICAodmFsdWUgPT09IHVuZGVmaW5lZCAmJiAhKGtleSBpbiBvYmplY3QpKSkge1xuICAgICAgICBiYXNlQXNzaWduVmFsdWUob2JqZWN0LCBrZXksIHZhbHVlKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXRzIHRoZSBpbmRleCBhdCB3aGljaCB0aGUgYGtleWAgaXMgZm91bmQgaW4gYGFycmF5YCBvZiBrZXktdmFsdWUgcGFpcnMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBpbnNwZWN0LlxuICAgICAqIEBwYXJhbSB7Kn0ga2V5IFRoZSBrZXkgdG8gc2VhcmNoIGZvci5cbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBSZXR1cm5zIHRoZSBpbmRleCBvZiB0aGUgbWF0Y2hlZCB2YWx1ZSwgZWxzZSBgLTFgLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGFzc29jSW5kZXhPZihhcnJheSwga2V5KSB7XG4gICAgICB2YXIgbGVuZ3RoID0gYXJyYXkubGVuZ3RoO1xuICAgICAgd2hpbGUgKGxlbmd0aC0tKSB7XG4gICAgICAgIGlmIChlcShhcnJheVtsZW5ndGhdWzBdLCBrZXkpKSB7XG4gICAgICAgICAgcmV0dXJuIGxlbmd0aDtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIC0xO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEFnZ3JlZ2F0ZXMgZWxlbWVudHMgb2YgYGNvbGxlY3Rpb25gIG9uIGBhY2N1bXVsYXRvcmAgd2l0aCBrZXlzIHRyYW5zZm9ybWVkXG4gICAgICogYnkgYGl0ZXJhdGVlYCBhbmQgdmFsdWVzIHNldCBieSBgc2V0dGVyYC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtBcnJheXxPYmplY3R9IGNvbGxlY3Rpb24gVGhlIGNvbGxlY3Rpb24gdG8gaXRlcmF0ZSBvdmVyLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IHNldHRlciBUaGUgZnVuY3Rpb24gdG8gc2V0IGBhY2N1bXVsYXRvcmAgdmFsdWVzLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGl0ZXJhdGVlIFRoZSBpdGVyYXRlZSB0byB0cmFuc2Zvcm0ga2V5cy5cbiAgICAgKiBAcGFyYW0ge09iamVjdH0gYWNjdW11bGF0b3IgVGhlIGluaXRpYWwgYWdncmVnYXRlZCBvYmplY3QuXG4gICAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIGBhY2N1bXVsYXRvcmAuXG4gICAgICovXG4gICAgZnVuY3Rpb24gYmFzZUFnZ3JlZ2F0b3IoY29sbGVjdGlvbiwgc2V0dGVyLCBpdGVyYXRlZSwgYWNjdW11bGF0b3IpIHtcbiAgICAgIGJhc2VFYWNoKGNvbGxlY3Rpb24sIGZ1bmN0aW9uKHZhbHVlLCBrZXksIGNvbGxlY3Rpb24pIHtcbiAgICAgICAgc2V0dGVyKGFjY3VtdWxhdG9yLCB2YWx1ZSwgaXRlcmF0ZWUodmFsdWUpLCBjb2xsZWN0aW9uKTtcbiAgICAgIH0pO1xuICAgICAgcmV0dXJuIGFjY3VtdWxhdG9yO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLmFzc2lnbmAgd2l0aG91dCBzdXBwb3J0IGZvciBtdWx0aXBsZSBzb3VyY2VzXG4gICAgICogb3IgYGN1c3RvbWl6ZXJgIGZ1bmN0aW9ucy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgZGVzdGluYXRpb24gb2JqZWN0LlxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBzb3VyY2UgVGhlIHNvdXJjZSBvYmplY3QuXG4gICAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyBgb2JqZWN0YC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBiYXNlQXNzaWduKG9iamVjdCwgc291cmNlKSB7XG4gICAgICByZXR1cm4gb2JqZWN0ICYmIGNvcHlPYmplY3Qoc291cmNlLCBrZXlzKHNvdXJjZSksIG9iamVjdCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uYXNzaWduSW5gIHdpdGhvdXQgc3VwcG9ydCBmb3IgbXVsdGlwbGUgc291cmNlc1xuICAgICAqIG9yIGBjdXN0b21pemVyYCBmdW5jdGlvbnMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIGRlc3RpbmF0aW9uIG9iamVjdC5cbiAgICAgKiBAcGFyYW0ge09iamVjdH0gc291cmNlIFRoZSBzb3VyY2Ugb2JqZWN0LlxuICAgICAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgYG9iamVjdGAuXG4gICAgICovXG4gICAgZnVuY3Rpb24gYmFzZUFzc2lnbkluKG9iamVjdCwgc291cmNlKSB7XG4gICAgICByZXR1cm4gb2JqZWN0ICYmIGNvcHlPYmplY3Qoc291cmNlLCBrZXlzSW4oc291cmNlKSwgb2JqZWN0KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgYXNzaWduVmFsdWVgIGFuZCBgYXNzaWduTWVyZ2VWYWx1ZWAgd2l0aG91dFxuICAgICAqIHZhbHVlIGNoZWNrcy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIG1vZGlmeS5cbiAgICAgKiBAcGFyYW0ge3N0cmluZ30ga2V5IFRoZSBrZXkgb2YgdGhlIHByb3BlcnR5IHRvIGFzc2lnbi5cbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBhc3NpZ24uXG4gICAgICovXG4gICAgZnVuY3Rpb24gYmFzZUFzc2lnblZhbHVlKG9iamVjdCwga2V5LCB2YWx1ZSkge1xuICAgICAgaWYgKGtleSA9PSAnX19wcm90b19fJyAmJiBkZWZpbmVQcm9wZXJ0eSkge1xuICAgICAgICBkZWZpbmVQcm9wZXJ0eShvYmplY3QsIGtleSwge1xuICAgICAgICAgICdjb25maWd1cmFibGUnOiB0cnVlLFxuICAgICAgICAgICdlbnVtZXJhYmxlJzogdHJ1ZSxcbiAgICAgICAgICAndmFsdWUnOiB2YWx1ZSxcbiAgICAgICAgICAnd3JpdGFibGUnOiB0cnVlXG4gICAgICAgIH0pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgb2JqZWN0W2tleV0gPSB2YWx1ZTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5hdGAgd2l0aG91dCBzdXBwb3J0IGZvciBpbmRpdmlkdWFsIHBhdGhzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gaXRlcmF0ZSBvdmVyLlxuICAgICAqIEBwYXJhbSB7c3RyaW5nW119IHBhdGhzIFRoZSBwcm9wZXJ0eSBwYXRocyB0byBwaWNrLlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgcGlja2VkIGVsZW1lbnRzLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGJhc2VBdChvYmplY3QsIHBhdGhzKSB7XG4gICAgICB2YXIgaW5kZXggPSAtMSxcbiAgICAgICAgICBsZW5ndGggPSBwYXRocy5sZW5ndGgsXG4gICAgICAgICAgcmVzdWx0ID0gQXJyYXkobGVuZ3RoKSxcbiAgICAgICAgICBza2lwID0gb2JqZWN0ID09IG51bGw7XG5cbiAgICAgIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XG4gICAgICAgIHJlc3VsdFtpbmRleF0gPSBza2lwID8gdW5kZWZpbmVkIDogZ2V0KG9iamVjdCwgcGF0aHNbaW5kZXhdKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uY2xhbXBgIHdoaWNoIGRvZXNuJ3QgY29lcmNlIGFyZ3VtZW50cy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IG51bWJlciBUaGUgbnVtYmVyIHRvIGNsYW1wLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbbG93ZXJdIFRoZSBsb3dlciBib3VuZC5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gdXBwZXIgVGhlIHVwcGVyIGJvdW5kLlxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9IFJldHVybnMgdGhlIGNsYW1wZWQgbnVtYmVyLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGJhc2VDbGFtcChudW1iZXIsIGxvd2VyLCB1cHBlcikge1xuICAgICAgaWYgKG51bWJlciA9PT0gbnVtYmVyKSB7XG4gICAgICAgIGlmICh1cHBlciAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgbnVtYmVyID0gbnVtYmVyIDw9IHVwcGVyID8gbnVtYmVyIDogdXBwZXI7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGxvd2VyICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICBudW1iZXIgPSBudW1iZXIgPj0gbG93ZXIgPyBudW1iZXIgOiBsb3dlcjtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIG51bWJlcjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5jbG9uZWAgYW5kIGBfLmNsb25lRGVlcGAgd2hpY2ggdHJhY2tzXG4gICAgICogdHJhdmVyc2VkIG9iamVjdHMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNsb25lLlxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbn0gYml0bWFzayBUaGUgYml0bWFzayBmbGFncy5cbiAgICAgKiAgMSAtIERlZXAgY2xvbmVcbiAgICAgKiAgMiAtIEZsYXR0ZW4gaW5oZXJpdGVkIHByb3BlcnRpZXNcbiAgICAgKiAgNCAtIENsb25lIHN5bWJvbHNcbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbY3VzdG9taXplcl0gVGhlIGZ1bmN0aW9uIHRvIGN1c3RvbWl6ZSBjbG9uaW5nLlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBba2V5XSBUaGUga2V5IG9mIGB2YWx1ZWAuXG4gICAgICogQHBhcmFtIHtPYmplY3R9IFtvYmplY3RdIFRoZSBwYXJlbnQgb2JqZWN0IG9mIGB2YWx1ZWAuXG4gICAgICogQHBhcmFtIHtPYmplY3R9IFtzdGFja10gVHJhY2tzIHRyYXZlcnNlZCBvYmplY3RzIGFuZCB0aGVpciBjbG9uZSBjb3VudGVycGFydHMuXG4gICAgICogQHJldHVybnMgeyp9IFJldHVybnMgdGhlIGNsb25lZCB2YWx1ZS5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBiYXNlQ2xvbmUodmFsdWUsIGJpdG1hc2ssIGN1c3RvbWl6ZXIsIGtleSwgb2JqZWN0LCBzdGFjaykge1xuICAgICAgdmFyIHJlc3VsdCxcbiAgICAgICAgICBpc0RlZXAgPSBiaXRtYXNrICYgQ0xPTkVfREVFUF9GTEFHLFxuICAgICAgICAgIGlzRmxhdCA9IGJpdG1hc2sgJiBDTE9ORV9GTEFUX0ZMQUcsXG4gICAgICAgICAgaXNGdWxsID0gYml0bWFzayAmIENMT05FX1NZTUJPTFNfRkxBRztcblxuICAgICAgaWYgKGN1c3RvbWl6ZXIpIHtcbiAgICAgICAgcmVzdWx0ID0gb2JqZWN0ID8gY3VzdG9taXplcih2YWx1ZSwga2V5LCBvYmplY3QsIHN0YWNrKSA6IGN1c3RvbWl6ZXIodmFsdWUpO1xuICAgICAgfVxuICAgICAgaWYgKHJlc3VsdCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICB9XG4gICAgICBpZiAoIWlzT2JqZWN0KHZhbHVlKSkge1xuICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgICB9XG4gICAgICB2YXIgaXNBcnIgPSBpc0FycmF5KHZhbHVlKTtcbiAgICAgIGlmIChpc0Fycikge1xuICAgICAgICByZXN1bHQgPSBpbml0Q2xvbmVBcnJheSh2YWx1ZSk7XG4gICAgICAgIGlmICghaXNEZWVwKSB7XG4gICAgICAgICAgcmV0dXJuIGNvcHlBcnJheSh2YWx1ZSwgcmVzdWx0KTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdmFyIHRhZyA9IGdldFRhZyh2YWx1ZSksXG4gICAgICAgICAgICBpc0Z1bmMgPSB0YWcgPT0gZnVuY1RhZyB8fCB0YWcgPT0gZ2VuVGFnO1xuXG4gICAgICAgIGlmIChpc0J1ZmZlcih2YWx1ZSkpIHtcbiAgICAgICAgICByZXR1cm4gY2xvbmVCdWZmZXIodmFsdWUsIGlzRGVlcCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRhZyA9PSBvYmplY3RUYWcgfHwgdGFnID09IGFyZ3NUYWcgfHwgKGlzRnVuYyAmJiAhb2JqZWN0KSkge1xuICAgICAgICAgIHJlc3VsdCA9IChpc0ZsYXQgfHwgaXNGdW5jKSA/IHt9IDogaW5pdENsb25lT2JqZWN0KHZhbHVlKTtcbiAgICAgICAgICBpZiAoIWlzRGVlcCkge1xuICAgICAgICAgICAgcmV0dXJuIGlzRmxhdFxuICAgICAgICAgICAgICA/IGNvcHlTeW1ib2xzSW4odmFsdWUsIGJhc2VBc3NpZ25JbihyZXN1bHQsIHZhbHVlKSlcbiAgICAgICAgICAgICAgOiBjb3B5U3ltYm9scyh2YWx1ZSwgYmFzZUFzc2lnbihyZXN1bHQsIHZhbHVlKSk7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGlmICghY2xvbmVhYmxlVGFnc1t0YWddKSB7XG4gICAgICAgICAgICByZXR1cm4gb2JqZWN0ID8gdmFsdWUgOiB7fTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmVzdWx0ID0gaW5pdENsb25lQnlUYWcodmFsdWUsIHRhZywgaXNEZWVwKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgLy8gQ2hlY2sgZm9yIGNpcmN1bGFyIHJlZmVyZW5jZXMgYW5kIHJldHVybiBpdHMgY29ycmVzcG9uZGluZyBjbG9uZS5cbiAgICAgIHN0YWNrIHx8IChzdGFjayA9IG5ldyBTdGFjayk7XG4gICAgICB2YXIgc3RhY2tlZCA9IHN0YWNrLmdldCh2YWx1ZSk7XG4gICAgICBpZiAoc3RhY2tlZCkge1xuICAgICAgICByZXR1cm4gc3RhY2tlZDtcbiAgICAgIH1cbiAgICAgIHN0YWNrLnNldCh2YWx1ZSwgcmVzdWx0KTtcblxuICAgICAgaWYgKGlzU2V0KHZhbHVlKSkge1xuICAgICAgICB2YWx1ZS5mb3JFYWNoKGZ1bmN0aW9uKHN1YlZhbHVlKSB7XG4gICAgICAgICAgcmVzdWx0LmFkZChiYXNlQ2xvbmUoc3ViVmFsdWUsIGJpdG1hc2ssIGN1c3RvbWl6ZXIsIHN1YlZhbHVlLCB2YWx1ZSwgc3RhY2spKTtcbiAgICAgICAgfSk7XG4gICAgICB9IGVsc2UgaWYgKGlzTWFwKHZhbHVlKSkge1xuICAgICAgICB2YWx1ZS5mb3JFYWNoKGZ1bmN0aW9uKHN1YlZhbHVlLCBrZXkpIHtcbiAgICAgICAgICByZXN1bHQuc2V0KGtleSwgYmFzZUNsb25lKHN1YlZhbHVlLCBiaXRtYXNrLCBjdXN0b21pemVyLCBrZXksIHZhbHVlLCBzdGFjaykpO1xuICAgICAgICB9KTtcbiAgICAgIH1cblxuICAgICAgdmFyIGtleXNGdW5jID0gaXNGdWxsXG4gICAgICAgID8gKGlzRmxhdCA/IGdldEFsbEtleXNJbiA6IGdldEFsbEtleXMpXG4gICAgICAgIDogKGlzRmxhdCA/IGtleXNJbiA6IGtleXMpO1xuXG4gICAgICB2YXIgcHJvcHMgPSBpc0FyciA/IHVuZGVmaW5lZCA6IGtleXNGdW5jKHZhbHVlKTtcbiAgICAgIGFycmF5RWFjaChwcm9wcyB8fCB2YWx1ZSwgZnVuY3Rpb24oc3ViVmFsdWUsIGtleSkge1xuICAgICAgICBpZiAocHJvcHMpIHtcbiAgICAgICAgICBrZXkgPSBzdWJWYWx1ZTtcbiAgICAgICAgICBzdWJWYWx1ZSA9IHZhbHVlW2tleV07XG4gICAgICAgIH1cbiAgICAgICAgLy8gUmVjdXJzaXZlbHkgcG9wdWxhdGUgY2xvbmUgKHN1c2NlcHRpYmxlIHRvIGNhbGwgc3RhY2sgbGltaXRzKS5cbiAgICAgICAgYXNzaWduVmFsdWUocmVzdWx0LCBrZXksIGJhc2VDbG9uZShzdWJWYWx1ZSwgYml0bWFzaywgY3VzdG9taXplciwga2V5LCB2YWx1ZSwgc3RhY2spKTtcbiAgICAgIH0pO1xuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5jb25mb3Jtc2Agd2hpY2ggZG9lc24ndCBjbG9uZSBgc291cmNlYC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtPYmplY3R9IHNvdXJjZSBUaGUgb2JqZWN0IG9mIHByb3BlcnR5IHByZWRpY2F0ZXMgdG8gY29uZm9ybSB0by5cbiAgICAgKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBzcGVjIGZ1bmN0aW9uLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGJhc2VDb25mb3Jtcyhzb3VyY2UpIHtcbiAgICAgIHZhciBwcm9wcyA9IGtleXMoc291cmNlKTtcbiAgICAgIHJldHVybiBmdW5jdGlvbihvYmplY3QpIHtcbiAgICAgICAgcmV0dXJuIGJhc2VDb25mb3Jtc1RvKG9iamVjdCwgc291cmNlLCBwcm9wcyk7XG4gICAgICB9O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLmNvbmZvcm1zVG9gIHdoaWNoIGFjY2VwdHMgYHByb3BzYCB0byBjaGVjay5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIGluc3BlY3QuXG4gICAgICogQHBhcmFtIHtPYmplY3R9IHNvdXJjZSBUaGUgb2JqZWN0IG9mIHByb3BlcnR5IHByZWRpY2F0ZXMgdG8gY29uZm9ybSB0by5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYG9iamVjdGAgY29uZm9ybXMsIGVsc2UgYGZhbHNlYC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBiYXNlQ29uZm9ybXNUbyhvYmplY3QsIHNvdXJjZSwgcHJvcHMpIHtcbiAgICAgIHZhciBsZW5ndGggPSBwcm9wcy5sZW5ndGg7XG4gICAgICBpZiAob2JqZWN0ID09IG51bGwpIHtcbiAgICAgICAgcmV0dXJuICFsZW5ndGg7XG4gICAgICB9XG4gICAgICBvYmplY3QgPSBPYmplY3Qob2JqZWN0KTtcbiAgICAgIHdoaWxlIChsZW5ndGgtLSkge1xuICAgICAgICB2YXIga2V5ID0gcHJvcHNbbGVuZ3RoXSxcbiAgICAgICAgICAgIHByZWRpY2F0ZSA9IHNvdXJjZVtrZXldLFxuICAgICAgICAgICAgdmFsdWUgPSBvYmplY3Rba2V5XTtcblxuICAgICAgICBpZiAoKHZhbHVlID09PSB1bmRlZmluZWQgJiYgIShrZXkgaW4gb2JqZWN0KSkgfHwgIXByZWRpY2F0ZSh2YWx1ZSkpIHtcbiAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLmRlbGF5YCBhbmQgYF8uZGVmZXJgIHdoaWNoIGFjY2VwdHMgYGFyZ3NgXG4gICAgICogdG8gcHJvdmlkZSB0byBgZnVuY2AuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIGRlbGF5LlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSB3YWl0IFRoZSBudW1iZXIgb2YgbWlsbGlzZWNvbmRzIHRvIGRlbGF5IGludm9jYXRpb24uXG4gICAgICogQHBhcmFtIHtBcnJheX0gYXJncyBUaGUgYXJndW1lbnRzIHRvIHByb3ZpZGUgdG8gYGZ1bmNgLlxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ8T2JqZWN0fSBSZXR1cm5zIHRoZSB0aW1lciBpZCBvciB0aW1lb3V0IG9iamVjdC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBiYXNlRGVsYXkoZnVuYywgd2FpdCwgYXJncykge1xuICAgICAgaWYgKHR5cGVvZiBmdW5jICE9ICdmdW5jdGlvbicpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihGVU5DX0VSUk9SX1RFWFQpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHNldFRpbWVvdXQoZnVuY3Rpb24oKSB7IGZ1bmMuYXBwbHkodW5kZWZpbmVkLCBhcmdzKTsgfSwgd2FpdCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgbWV0aG9kcyBsaWtlIGBfLmRpZmZlcmVuY2VgIHdpdGhvdXQgc3VwcG9ydFxuICAgICAqIGZvciBleGNsdWRpbmcgbXVsdGlwbGUgYXJyYXlzIG9yIGl0ZXJhdGVlIHNob3J0aGFuZHMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBpbnNwZWN0LlxuICAgICAqIEBwYXJhbSB7QXJyYXl9IHZhbHVlcyBUaGUgdmFsdWVzIHRvIGV4Y2x1ZGUuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW2l0ZXJhdGVlXSBUaGUgaXRlcmF0ZWUgaW52b2tlZCBwZXIgZWxlbWVudC5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbY29tcGFyYXRvcl0gVGhlIGNvbXBhcmF0b3IgaW52b2tlZCBwZXIgZWxlbWVudC5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIG5ldyBhcnJheSBvZiBmaWx0ZXJlZCB2YWx1ZXMuXG4gICAgICovXG4gICAgZnVuY3Rpb24gYmFzZURpZmZlcmVuY2UoYXJyYXksIHZhbHVlcywgaXRlcmF0ZWUsIGNvbXBhcmF0b3IpIHtcbiAgICAgIHZhciBpbmRleCA9IC0xLFxuICAgICAgICAgIGluY2x1ZGVzID0gYXJyYXlJbmNsdWRlcyxcbiAgICAgICAgICBpc0NvbW1vbiA9IHRydWUsXG4gICAgICAgICAgbGVuZ3RoID0gYXJyYXkubGVuZ3RoLFxuICAgICAgICAgIHJlc3VsdCA9IFtdLFxuICAgICAgICAgIHZhbHVlc0xlbmd0aCA9IHZhbHVlcy5sZW5ndGg7XG5cbiAgICAgIGlmICghbGVuZ3RoKSB7XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICB9XG4gICAgICBpZiAoaXRlcmF0ZWUpIHtcbiAgICAgICAgdmFsdWVzID0gYXJyYXlNYXAodmFsdWVzLCBiYXNlVW5hcnkoaXRlcmF0ZWUpKTtcbiAgICAgIH1cbiAgICAgIGlmIChjb21wYXJhdG9yKSB7XG4gICAgICAgIGluY2x1ZGVzID0gYXJyYXlJbmNsdWRlc1dpdGg7XG4gICAgICAgIGlzQ29tbW9uID0gZmFsc2U7XG4gICAgICB9XG4gICAgICBlbHNlIGlmICh2YWx1ZXMubGVuZ3RoID49IExBUkdFX0FSUkFZX1NJWkUpIHtcbiAgICAgICAgaW5jbHVkZXMgPSBjYWNoZUhhcztcbiAgICAgICAgaXNDb21tb24gPSBmYWxzZTtcbiAgICAgICAgdmFsdWVzID0gbmV3IFNldENhY2hlKHZhbHVlcyk7XG4gICAgICB9XG4gICAgICBvdXRlcjpcbiAgICAgIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XG4gICAgICAgIHZhciB2YWx1ZSA9IGFycmF5W2luZGV4XSxcbiAgICAgICAgICAgIGNvbXB1dGVkID0gaXRlcmF0ZWUgPT0gbnVsbCA/IHZhbHVlIDogaXRlcmF0ZWUodmFsdWUpO1xuXG4gICAgICAgIHZhbHVlID0gKGNvbXBhcmF0b3IgfHwgdmFsdWUgIT09IDApID8gdmFsdWUgOiAwO1xuICAgICAgICBpZiAoaXNDb21tb24gJiYgY29tcHV0ZWQgPT09IGNvbXB1dGVkKSB7XG4gICAgICAgICAgdmFyIHZhbHVlc0luZGV4ID0gdmFsdWVzTGVuZ3RoO1xuICAgICAgICAgIHdoaWxlICh2YWx1ZXNJbmRleC0tKSB7XG4gICAgICAgICAgICBpZiAodmFsdWVzW3ZhbHVlc0luZGV4XSA9PT0gY29tcHV0ZWQpIHtcbiAgICAgICAgICAgICAgY29udGludWUgb3V0ZXI7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICAgIHJlc3VsdC5wdXNoKHZhbHVlKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmICghaW5jbHVkZXModmFsdWVzLCBjb21wdXRlZCwgY29tcGFyYXRvcikpIHtcbiAgICAgICAgICByZXN1bHQucHVzaCh2YWx1ZSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uZm9yRWFjaGAgd2l0aG91dCBzdXBwb3J0IGZvciBpdGVyYXRlZSBzaG9ydGhhbmRzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0FycmF5fE9iamVjdH0gY29sbGVjdGlvbiBUaGUgY29sbGVjdGlvbiB0byBpdGVyYXRlIG92ZXIuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gaXRlcmF0ZWUgVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIGl0ZXJhdGlvbi5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl8T2JqZWN0fSBSZXR1cm5zIGBjb2xsZWN0aW9uYC5cbiAgICAgKi9cbiAgICB2YXIgYmFzZUVhY2ggPSBjcmVhdGVCYXNlRWFjaChiYXNlRm9yT3duKTtcblxuICAgIC8qKlxuICAgICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLmZvckVhY2hSaWdodGAgd2l0aG91dCBzdXBwb3J0IGZvciBpdGVyYXRlZSBzaG9ydGhhbmRzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0FycmF5fE9iamVjdH0gY29sbGVjdGlvbiBUaGUgY29sbGVjdGlvbiB0byBpdGVyYXRlIG92ZXIuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gaXRlcmF0ZWUgVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIGl0ZXJhdGlvbi5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl8T2JqZWN0fSBSZXR1cm5zIGBjb2xsZWN0aW9uYC5cbiAgICAgKi9cbiAgICB2YXIgYmFzZUVhY2hSaWdodCA9IGNyZWF0ZUJhc2VFYWNoKGJhc2VGb3JPd25SaWdodCwgdHJ1ZSk7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5ldmVyeWAgd2l0aG91dCBzdXBwb3J0IGZvciBpdGVyYXRlZSBzaG9ydGhhbmRzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0FycmF5fE9iamVjdH0gY29sbGVjdGlvbiBUaGUgY29sbGVjdGlvbiB0byBpdGVyYXRlIG92ZXIuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gcHJlZGljYXRlIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGFsbCBlbGVtZW50cyBwYXNzIHRoZSBwcmVkaWNhdGUgY2hlY2ssXG4gICAgICogIGVsc2UgYGZhbHNlYFxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGJhc2VFdmVyeShjb2xsZWN0aW9uLCBwcmVkaWNhdGUpIHtcbiAgICAgIHZhciByZXN1bHQgPSB0cnVlO1xuICAgICAgYmFzZUVhY2goY29sbGVjdGlvbiwgZnVuY3Rpb24odmFsdWUsIGluZGV4LCBjb2xsZWN0aW9uKSB7XG4gICAgICAgIHJlc3VsdCA9ICEhcHJlZGljYXRlKHZhbHVlLCBpbmRleCwgY29sbGVjdGlvbik7XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICB9KTtcbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgbWV0aG9kcyBsaWtlIGBfLm1heGAgYW5kIGBfLm1pbmAgd2hpY2ggYWNjZXB0cyBhXG4gICAgICogYGNvbXBhcmF0b3JgIHRvIGRldGVybWluZSB0aGUgZXh0cmVtdW0gdmFsdWUuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBpdGVyYXRlIG92ZXIuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gaXRlcmF0ZWUgVGhlIGl0ZXJhdGVlIGludm9rZWQgcGVyIGl0ZXJhdGlvbi5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBjb21wYXJhdG9yIFRoZSBjb21wYXJhdG9yIHVzZWQgdG8gY29tcGFyZSB2YWx1ZXMuXG4gICAgICogQHJldHVybnMgeyp9IFJldHVybnMgdGhlIGV4dHJlbXVtIHZhbHVlLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGJhc2VFeHRyZW11bShhcnJheSwgaXRlcmF0ZWUsIGNvbXBhcmF0b3IpIHtcbiAgICAgIHZhciBpbmRleCA9IC0xLFxuICAgICAgICAgIGxlbmd0aCA9IGFycmF5Lmxlbmd0aDtcblxuICAgICAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHtcbiAgICAgICAgdmFyIHZhbHVlID0gYXJyYXlbaW5kZXhdLFxuICAgICAgICAgICAgY3VycmVudCA9IGl0ZXJhdGVlKHZhbHVlKTtcblxuICAgICAgICBpZiAoY3VycmVudCAhPSBudWxsICYmIChjb21wdXRlZCA9PT0gdW5kZWZpbmVkXG4gICAgICAgICAgICAgID8gKGN1cnJlbnQgPT09IGN1cnJlbnQgJiYgIWlzU3ltYm9sKGN1cnJlbnQpKVxuICAgICAgICAgICAgICA6IGNvbXBhcmF0b3IoY3VycmVudCwgY29tcHV0ZWQpXG4gICAgICAgICAgICApKSB7XG4gICAgICAgICAgdmFyIGNvbXB1dGVkID0gY3VycmVudCxcbiAgICAgICAgICAgICAgcmVzdWx0ID0gdmFsdWU7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uZmlsbGAgd2l0aG91dCBhbiBpdGVyYXRlZSBjYWxsIGd1YXJkLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gZmlsbC5cbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBmaWxsIGBhcnJheWAgd2l0aC5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW3N0YXJ0PTBdIFRoZSBzdGFydCBwb3NpdGlvbi5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW2VuZD1hcnJheS5sZW5ndGhdIFRoZSBlbmQgcG9zaXRpb24uXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIGBhcnJheWAuXG4gICAgICovXG4gICAgZnVuY3Rpb24gYmFzZUZpbGwoYXJyYXksIHZhbHVlLCBzdGFydCwgZW5kKSB7XG4gICAgICB2YXIgbGVuZ3RoID0gYXJyYXkubGVuZ3RoO1xuXG4gICAgICBzdGFydCA9IHRvSW50ZWdlcihzdGFydCk7XG4gICAgICBpZiAoc3RhcnQgPCAwKSB7XG4gICAgICAgIHN0YXJ0ID0gLXN0YXJ0ID4gbGVuZ3RoID8gMCA6IChsZW5ndGggKyBzdGFydCk7XG4gICAgICB9XG4gICAgICBlbmQgPSAoZW5kID09PSB1bmRlZmluZWQgfHwgZW5kID4gbGVuZ3RoKSA/IGxlbmd0aCA6IHRvSW50ZWdlcihlbmQpO1xuICAgICAgaWYgKGVuZCA8IDApIHtcbiAgICAgICAgZW5kICs9IGxlbmd0aDtcbiAgICAgIH1cbiAgICAgIGVuZCA9IHN0YXJ0ID4gZW5kID8gMCA6IHRvTGVuZ3RoKGVuZCk7XG4gICAgICB3aGlsZSAoc3RhcnQgPCBlbmQpIHtcbiAgICAgICAgYXJyYXlbc3RhcnQrK10gPSB2YWx1ZTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBhcnJheTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5maWx0ZXJgIHdpdGhvdXQgc3VwcG9ydCBmb3IgaXRlcmF0ZWUgc2hvcnRoYW5kcy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtBcnJheXxPYmplY3R9IGNvbGxlY3Rpb24gVGhlIGNvbGxlY3Rpb24gdG8gaXRlcmF0ZSBvdmVyLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IHByZWRpY2F0ZSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IGZpbHRlcmVkIGFycmF5LlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGJhc2VGaWx0ZXIoY29sbGVjdGlvbiwgcHJlZGljYXRlKSB7XG4gICAgICB2YXIgcmVzdWx0ID0gW107XG4gICAgICBiYXNlRWFjaChjb2xsZWN0aW9uLCBmdW5jdGlvbih2YWx1ZSwgaW5kZXgsIGNvbGxlY3Rpb24pIHtcbiAgICAgICAgaWYgKHByZWRpY2F0ZSh2YWx1ZSwgaW5kZXgsIGNvbGxlY3Rpb24pKSB7XG4gICAgICAgICAgcmVzdWx0LnB1c2godmFsdWUpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uZmxhdHRlbmAgd2l0aCBzdXBwb3J0IGZvciByZXN0cmljdGluZyBmbGF0dGVuaW5nLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gZmxhdHRlbi5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gZGVwdGggVGhlIG1heGltdW0gcmVjdXJzaW9uIGRlcHRoLlxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbn0gW3ByZWRpY2F0ZT1pc0ZsYXR0ZW5hYmxlXSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbn0gW2lzU3RyaWN0XSBSZXN0cmljdCB0byB2YWx1ZXMgdGhhdCBwYXNzIGBwcmVkaWNhdGVgIGNoZWNrcy5cbiAgICAgKiBAcGFyYW0ge0FycmF5fSBbcmVzdWx0PVtdXSBUaGUgaW5pdGlhbCByZXN1bHQgdmFsdWUuXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBuZXcgZmxhdHRlbmVkIGFycmF5LlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGJhc2VGbGF0dGVuKGFycmF5LCBkZXB0aCwgcHJlZGljYXRlLCBpc1N0cmljdCwgcmVzdWx0KSB7XG4gICAgICB2YXIgaW5kZXggPSAtMSxcbiAgICAgICAgICBsZW5ndGggPSBhcnJheS5sZW5ndGg7XG5cbiAgICAgIHByZWRpY2F0ZSB8fCAocHJlZGljYXRlID0gaXNGbGF0dGVuYWJsZSk7XG4gICAgICByZXN1bHQgfHwgKHJlc3VsdCA9IFtdKTtcblxuICAgICAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHtcbiAgICAgICAgdmFyIHZhbHVlID0gYXJyYXlbaW5kZXhdO1xuICAgICAgICBpZiAoZGVwdGggPiAwICYmIHByZWRpY2F0ZSh2YWx1ZSkpIHtcbiAgICAgICAgICBpZiAoZGVwdGggPiAxKSB7XG4gICAgICAgICAgICAvLyBSZWN1cnNpdmVseSBmbGF0dGVuIGFycmF5cyAoc3VzY2VwdGlibGUgdG8gY2FsbCBzdGFjayBsaW1pdHMpLlxuICAgICAgICAgICAgYmFzZUZsYXR0ZW4odmFsdWUsIGRlcHRoIC0gMSwgcHJlZGljYXRlLCBpc1N0cmljdCwgcmVzdWx0KTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgYXJyYXlQdXNoKHJlc3VsdCwgdmFsdWUpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIGlmICghaXNTdHJpY3QpIHtcbiAgICAgICAgICByZXN1bHRbcmVzdWx0Lmxlbmd0aF0gPSB2YWx1ZTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgYmFzZUZvck93bmAgd2hpY2ggaXRlcmF0ZXMgb3ZlciBgb2JqZWN0YFxuICAgICAqIHByb3BlcnRpZXMgcmV0dXJuZWQgYnkgYGtleXNGdW5jYCBhbmQgaW52b2tlcyBgaXRlcmF0ZWVgIGZvciBlYWNoIHByb3BlcnR5LlxuICAgICAqIEl0ZXJhdGVlIGZ1bmN0aW9ucyBtYXkgZXhpdCBpdGVyYXRpb24gZWFybHkgYnkgZXhwbGljaXRseSByZXR1cm5pbmcgYGZhbHNlYC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIGl0ZXJhdGUgb3Zlci5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBpdGVyYXRlZSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGtleXNGdW5jIFRoZSBmdW5jdGlvbiB0byBnZXQgdGhlIGtleXMgb2YgYG9iamVjdGAuXG4gICAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyBgb2JqZWN0YC5cbiAgICAgKi9cbiAgICB2YXIgYmFzZUZvciA9IGNyZWF0ZUJhc2VGb3IoKTtcblxuICAgIC8qKlxuICAgICAqIFRoaXMgZnVuY3Rpb24gaXMgbGlrZSBgYmFzZUZvcmAgZXhjZXB0IHRoYXQgaXQgaXRlcmF0ZXMgb3ZlciBwcm9wZXJ0aWVzXG4gICAgICogaW4gdGhlIG9wcG9zaXRlIG9yZGVyLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gaXRlcmF0ZSBvdmVyLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGl0ZXJhdGVlIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0ga2V5c0Z1bmMgVGhlIGZ1bmN0aW9uIHRvIGdldCB0aGUga2V5cyBvZiBgb2JqZWN0YC5cbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIGBvYmplY3RgLlxuICAgICAqL1xuICAgIHZhciBiYXNlRm9yUmlnaHQgPSBjcmVhdGVCYXNlRm9yKHRydWUpO1xuXG4gICAgLyoqXG4gICAgICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uZm9yT3duYCB3aXRob3V0IHN1cHBvcnQgZm9yIGl0ZXJhdGVlIHNob3J0aGFuZHMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBpdGVyYXRlIG92ZXIuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gaXRlcmF0ZWUgVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIGl0ZXJhdGlvbi5cbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIGBvYmplY3RgLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGJhc2VGb3JPd24ob2JqZWN0LCBpdGVyYXRlZSkge1xuICAgICAgcmV0dXJuIG9iamVjdCAmJiBiYXNlRm9yKG9iamVjdCwgaXRlcmF0ZWUsIGtleXMpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLmZvck93blJpZ2h0YCB3aXRob3V0IHN1cHBvcnQgZm9yIGl0ZXJhdGVlIHNob3J0aGFuZHMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBpdGVyYXRlIG92ZXIuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gaXRlcmF0ZWUgVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIGl0ZXJhdGlvbi5cbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIGBvYmplY3RgLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGJhc2VGb3JPd25SaWdodChvYmplY3QsIGl0ZXJhdGVlKSB7XG4gICAgICByZXR1cm4gb2JqZWN0ICYmIGJhc2VGb3JSaWdodChvYmplY3QsIGl0ZXJhdGVlLCBrZXlzKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5mdW5jdGlvbnNgIHdoaWNoIGNyZWF0ZXMgYW4gYXJyYXkgb2ZcbiAgICAgKiBgb2JqZWN0YCBmdW5jdGlvbiBwcm9wZXJ0eSBuYW1lcyBmaWx0ZXJlZCBmcm9tIGBwcm9wc2AuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBpbnNwZWN0LlxuICAgICAqIEBwYXJhbSB7QXJyYXl9IHByb3BzIFRoZSBwcm9wZXJ0eSBuYW1lcyB0byBmaWx0ZXIuXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBmdW5jdGlvbiBuYW1lcy5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBiYXNlRnVuY3Rpb25zKG9iamVjdCwgcHJvcHMpIHtcbiAgICAgIHJldHVybiBhcnJheUZpbHRlcihwcm9wcywgZnVuY3Rpb24oa2V5KSB7XG4gICAgICAgIHJldHVybiBpc0Z1bmN0aW9uKG9iamVjdFtrZXldKTtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLmdldGAgd2l0aG91dCBzdXBwb3J0IGZvciBkZWZhdWx0IHZhbHVlcy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIHF1ZXJ5LlxuICAgICAqIEBwYXJhbSB7QXJyYXl8c3RyaW5nfSBwYXRoIFRoZSBwYXRoIG9mIHRoZSBwcm9wZXJ0eSB0byBnZXQuXG4gICAgICogQHJldHVybnMgeyp9IFJldHVybnMgdGhlIHJlc29sdmVkIHZhbHVlLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGJhc2VHZXQob2JqZWN0LCBwYXRoKSB7XG4gICAgICBwYXRoID0gY2FzdFBhdGgocGF0aCwgb2JqZWN0KTtcblxuICAgICAgdmFyIGluZGV4ID0gMCxcbiAgICAgICAgICBsZW5ndGggPSBwYXRoLmxlbmd0aDtcblxuICAgICAgd2hpbGUgKG9iamVjdCAhPSBudWxsICYmIGluZGV4IDwgbGVuZ3RoKSB7XG4gICAgICAgIG9iamVjdCA9IG9iamVjdFt0b0tleShwYXRoW2luZGV4KytdKV07XG4gICAgICB9XG4gICAgICByZXR1cm4gKGluZGV4ICYmIGluZGV4ID09IGxlbmd0aCkgPyBvYmplY3QgOiB1bmRlZmluZWQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYGdldEFsbEtleXNgIGFuZCBgZ2V0QWxsS2V5c0luYCB3aGljaCB1c2VzXG4gICAgICogYGtleXNGdW5jYCBhbmQgYHN5bWJvbHNGdW5jYCB0byBnZXQgdGhlIGVudW1lcmFibGUgcHJvcGVydHkgbmFtZXMgYW5kXG4gICAgICogc3ltYm9scyBvZiBgb2JqZWN0YC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIHF1ZXJ5LlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGtleXNGdW5jIFRoZSBmdW5jdGlvbiB0byBnZXQgdGhlIGtleXMgb2YgYG9iamVjdGAuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gc3ltYm9sc0Z1bmMgVGhlIGZ1bmN0aW9uIHRvIGdldCB0aGUgc3ltYm9scyBvZiBgb2JqZWN0YC5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIGFycmF5IG9mIHByb3BlcnR5IG5hbWVzIGFuZCBzeW1ib2xzLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGJhc2VHZXRBbGxLZXlzKG9iamVjdCwga2V5c0Z1bmMsIHN5bWJvbHNGdW5jKSB7XG4gICAgICB2YXIgcmVzdWx0ID0ga2V5c0Z1bmMob2JqZWN0KTtcbiAgICAgIHJldHVybiBpc0FycmF5KG9iamVjdCkgPyByZXN1bHQgOiBhcnJheVB1c2gocmVzdWx0LCBzeW1ib2xzRnVuYyhvYmplY3QpKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgZ2V0VGFnYCB3aXRob3V0IGZhbGxiYWNrcyBmb3IgYnVnZ3kgZW52aXJvbm1lbnRzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBxdWVyeS5cbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfSBSZXR1cm5zIHRoZSBgdG9TdHJpbmdUYWdgLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGJhc2VHZXRUYWcodmFsdWUpIHtcbiAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7XG4gICAgICAgIHJldHVybiB2YWx1ZSA9PT0gdW5kZWZpbmVkID8gdW5kZWZpbmVkVGFnIDogbnVsbFRhZztcbiAgICAgIH1cbiAgICAgIHJldHVybiAoc3ltVG9TdHJpbmdUYWcgJiYgc3ltVG9TdHJpbmdUYWcgaW4gT2JqZWN0KHZhbHVlKSlcbiAgICAgICAgPyBnZXRSYXdUYWcodmFsdWUpXG4gICAgICAgIDogb2JqZWN0VG9TdHJpbmcodmFsdWUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLmd0YCB3aGljaCBkb2Vzbid0IGNvZXJjZSBhcmd1bWVudHMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNvbXBhcmUuXG4gICAgICogQHBhcmFtIHsqfSBvdGhlciBUaGUgb3RoZXIgdmFsdWUgdG8gY29tcGFyZS5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBncmVhdGVyIHRoYW4gYG90aGVyYCxcbiAgICAgKiAgZWxzZSBgZmFsc2VgLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGJhc2VHdCh2YWx1ZSwgb3RoZXIpIHtcbiAgICAgIHJldHVybiB2YWx1ZSA+IG90aGVyO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLmhhc2Agd2l0aG91dCBzdXBwb3J0IGZvciBkZWVwIHBhdGhzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gW29iamVjdF0gVGhlIG9iamVjdCB0byBxdWVyeS5cbiAgICAgKiBAcGFyYW0ge0FycmF5fHN0cmluZ30ga2V5IFRoZSBrZXkgdG8gY2hlY2suXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGBrZXlgIGV4aXN0cywgZWxzZSBgZmFsc2VgLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGJhc2VIYXMob2JqZWN0LCBrZXkpIHtcbiAgICAgIHJldHVybiBvYmplY3QgIT0gbnVsbCAmJiBoYXNPd25Qcm9wZXJ0eS5jYWxsKG9iamVjdCwga2V5KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5oYXNJbmAgd2l0aG91dCBzdXBwb3J0IGZvciBkZWVwIHBhdGhzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gW29iamVjdF0gVGhlIG9iamVjdCB0byBxdWVyeS5cbiAgICAgKiBAcGFyYW0ge0FycmF5fHN0cmluZ30ga2V5IFRoZSBrZXkgdG8gY2hlY2suXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGBrZXlgIGV4aXN0cywgZWxzZSBgZmFsc2VgLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGJhc2VIYXNJbihvYmplY3QsIGtleSkge1xuICAgICAgcmV0dXJuIG9iamVjdCAhPSBudWxsICYmIGtleSBpbiBPYmplY3Qob2JqZWN0KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5pblJhbmdlYCB3aGljaCBkb2Vzbid0IGNvZXJjZSBhcmd1bWVudHMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBudW1iZXIgVGhlIG51bWJlciB0byBjaGVjay5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gc3RhcnQgVGhlIHN0YXJ0IG9mIHRoZSByYW5nZS5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gZW5kIFRoZSBlbmQgb2YgdGhlIHJhbmdlLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgbnVtYmVyYCBpcyBpbiB0aGUgcmFuZ2UsIGVsc2UgYGZhbHNlYC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBiYXNlSW5SYW5nZShudW1iZXIsIHN0YXJ0LCBlbmQpIHtcbiAgICAgIHJldHVybiBudW1iZXIgPj0gbmF0aXZlTWluKHN0YXJ0LCBlbmQpICYmIG51bWJlciA8IG5hdGl2ZU1heChzdGFydCwgZW5kKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBtZXRob2RzIGxpa2UgYF8uaW50ZXJzZWN0aW9uYCwgd2l0aG91dCBzdXBwb3J0XG4gICAgICogZm9yIGl0ZXJhdGVlIHNob3J0aGFuZHMsIHRoYXQgYWNjZXB0cyBhbiBhcnJheSBvZiBhcnJheXMgdG8gaW5zcGVjdC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtBcnJheX0gYXJyYXlzIFRoZSBhcnJheXMgdG8gaW5zcGVjdC5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbaXRlcmF0ZWVdIFRoZSBpdGVyYXRlZSBpbnZva2VkIHBlciBlbGVtZW50LlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IFtjb21wYXJhdG9yXSBUaGUgY29tcGFyYXRvciBpbnZva2VkIHBlciBlbGVtZW50LlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IGFycmF5IG9mIHNoYXJlZCB2YWx1ZXMuXG4gICAgICovXG4gICAgZnVuY3Rpb24gYmFzZUludGVyc2VjdGlvbihhcnJheXMsIGl0ZXJhdGVlLCBjb21wYXJhdG9yKSB7XG4gICAgICB2YXIgaW5jbHVkZXMgPSBjb21wYXJhdG9yID8gYXJyYXlJbmNsdWRlc1dpdGggOiBhcnJheUluY2x1ZGVzLFxuICAgICAgICAgIGxlbmd0aCA9IGFycmF5c1swXS5sZW5ndGgsXG4gICAgICAgICAgb3RoTGVuZ3RoID0gYXJyYXlzLmxlbmd0aCxcbiAgICAgICAgICBvdGhJbmRleCA9IG90aExlbmd0aCxcbiAgICAgICAgICBjYWNoZXMgPSBBcnJheShvdGhMZW5ndGgpLFxuICAgICAgICAgIG1heExlbmd0aCA9IEluZmluaXR5LFxuICAgICAgICAgIHJlc3VsdCA9IFtdO1xuXG4gICAgICB3aGlsZSAob3RoSW5kZXgtLSkge1xuICAgICAgICB2YXIgYXJyYXkgPSBhcnJheXNbb3RoSW5kZXhdO1xuICAgICAgICBpZiAob3RoSW5kZXggJiYgaXRlcmF0ZWUpIHtcbiAgICAgICAgICBhcnJheSA9IGFycmF5TWFwKGFycmF5LCBiYXNlVW5hcnkoaXRlcmF0ZWUpKTtcbiAgICAgICAgfVxuICAgICAgICBtYXhMZW5ndGggPSBuYXRpdmVNaW4oYXJyYXkubGVuZ3RoLCBtYXhMZW5ndGgpO1xuICAgICAgICBjYWNoZXNbb3RoSW5kZXhdID0gIWNvbXBhcmF0b3IgJiYgKGl0ZXJhdGVlIHx8IChsZW5ndGggPj0gMTIwICYmIGFycmF5Lmxlbmd0aCA+PSAxMjApKVxuICAgICAgICAgID8gbmV3IFNldENhY2hlKG90aEluZGV4ICYmIGFycmF5KVxuICAgICAgICAgIDogdW5kZWZpbmVkO1xuICAgICAgfVxuICAgICAgYXJyYXkgPSBhcnJheXNbMF07XG5cbiAgICAgIHZhciBpbmRleCA9IC0xLFxuICAgICAgICAgIHNlZW4gPSBjYWNoZXNbMF07XG5cbiAgICAgIG91dGVyOlxuICAgICAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGggJiYgcmVzdWx0Lmxlbmd0aCA8IG1heExlbmd0aCkge1xuICAgICAgICB2YXIgdmFsdWUgPSBhcnJheVtpbmRleF0sXG4gICAgICAgICAgICBjb21wdXRlZCA9IGl0ZXJhdGVlID8gaXRlcmF0ZWUodmFsdWUpIDogdmFsdWU7XG5cbiAgICAgICAgdmFsdWUgPSAoY29tcGFyYXRvciB8fCB2YWx1ZSAhPT0gMCkgPyB2YWx1ZSA6IDA7XG4gICAgICAgIGlmICghKHNlZW5cbiAgICAgICAgICAgICAgPyBjYWNoZUhhcyhzZWVuLCBjb21wdXRlZClcbiAgICAgICAgICAgICAgOiBpbmNsdWRlcyhyZXN1bHQsIGNvbXB1dGVkLCBjb21wYXJhdG9yKVxuICAgICAgICAgICAgKSkge1xuICAgICAgICAgIG90aEluZGV4ID0gb3RoTGVuZ3RoO1xuICAgICAgICAgIHdoaWxlICgtLW90aEluZGV4KSB7XG4gICAgICAgICAgICB2YXIgY2FjaGUgPSBjYWNoZXNbb3RoSW5kZXhdO1xuICAgICAgICAgICAgaWYgKCEoY2FjaGVcbiAgICAgICAgICAgICAgICAgID8gY2FjaGVIYXMoY2FjaGUsIGNvbXB1dGVkKVxuICAgICAgICAgICAgICAgICAgOiBpbmNsdWRlcyhhcnJheXNbb3RoSW5kZXhdLCBjb21wdXRlZCwgY29tcGFyYXRvcikpXG4gICAgICAgICAgICAgICAgKSB7XG4gICAgICAgICAgICAgIGNvbnRpbnVlIG91dGVyO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoc2Vlbikge1xuICAgICAgICAgICAgc2Vlbi5wdXNoKGNvbXB1dGVkKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmVzdWx0LnB1c2godmFsdWUpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLmludmVydGAgYW5kIGBfLmludmVydEJ5YCB3aGljaCBpbnZlcnRzXG4gICAgICogYG9iamVjdGAgd2l0aCB2YWx1ZXMgdHJhbnNmb3JtZWQgYnkgYGl0ZXJhdGVlYCBhbmQgc2V0IGJ5IGBzZXR0ZXJgLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gaXRlcmF0ZSBvdmVyLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IHNldHRlciBUaGUgZnVuY3Rpb24gdG8gc2V0IGBhY2N1bXVsYXRvcmAgdmFsdWVzLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGl0ZXJhdGVlIFRoZSBpdGVyYXRlZSB0byB0cmFuc2Zvcm0gdmFsdWVzLlxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBhY2N1bXVsYXRvciBUaGUgaW5pdGlhbCBpbnZlcnRlZCBvYmplY3QuXG4gICAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIGBhY2N1bXVsYXRvcmAuXG4gICAgICovXG4gICAgZnVuY3Rpb24gYmFzZUludmVydGVyKG9iamVjdCwgc2V0dGVyLCBpdGVyYXRlZSwgYWNjdW11bGF0b3IpIHtcbiAgICAgIGJhc2VGb3JPd24ob2JqZWN0LCBmdW5jdGlvbih2YWx1ZSwga2V5LCBvYmplY3QpIHtcbiAgICAgICAgc2V0dGVyKGFjY3VtdWxhdG9yLCBpdGVyYXRlZSh2YWx1ZSksIGtleSwgb2JqZWN0KTtcbiAgICAgIH0pO1xuICAgICAgcmV0dXJuIGFjY3VtdWxhdG9yO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLmludm9rZWAgd2l0aG91dCBzdXBwb3J0IGZvciBpbmRpdmlkdWFsXG4gICAgICogbWV0aG9kIGFyZ3VtZW50cy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIHF1ZXJ5LlxuICAgICAqIEBwYXJhbSB7QXJyYXl8c3RyaW5nfSBwYXRoIFRoZSBwYXRoIG9mIHRoZSBtZXRob2QgdG8gaW52b2tlLlxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGFyZ3MgVGhlIGFyZ3VtZW50cyB0byBpbnZva2UgdGhlIG1ldGhvZCB3aXRoLlxuICAgICAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSByZXN1bHQgb2YgdGhlIGludm9rZWQgbWV0aG9kLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGJhc2VJbnZva2Uob2JqZWN0LCBwYXRoLCBhcmdzKSB7XG4gICAgICBwYXRoID0gY2FzdFBhdGgocGF0aCwgb2JqZWN0KTtcbiAgICAgIG9iamVjdCA9IHBhcmVudChvYmplY3QsIHBhdGgpO1xuICAgICAgdmFyIGZ1bmMgPSBvYmplY3QgPT0gbnVsbCA/IG9iamVjdCA6IG9iamVjdFt0b0tleShsYXN0KHBhdGgpKV07XG4gICAgICByZXR1cm4gZnVuYyA9PSBudWxsID8gdW5kZWZpbmVkIDogYXBwbHkoZnVuYywgb2JqZWN0LCBhcmdzKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5pc0FyZ3VtZW50c2AuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGFuIGBhcmd1bWVudHNgIG9iamVjdCxcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBiYXNlSXNBcmd1bWVudHModmFsdWUpIHtcbiAgICAgIHJldHVybiBpc09iamVjdExpa2UodmFsdWUpICYmIGJhc2VHZXRUYWcodmFsdWUpID09IGFyZ3NUYWc7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uaXNBcnJheUJ1ZmZlcmAgd2l0aG91dCBOb2RlLmpzIG9wdGltaXphdGlvbnMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGFuIGFycmF5IGJ1ZmZlciwgZWxzZSBgZmFsc2VgLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGJhc2VJc0FycmF5QnVmZmVyKHZhbHVlKSB7XG4gICAgICByZXR1cm4gaXNPYmplY3RMaWtlKHZhbHVlKSAmJiBiYXNlR2V0VGFnKHZhbHVlKSA9PSBhcnJheUJ1ZmZlclRhZztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5pc0RhdGVgIHdpdGhvdXQgTm9kZS5qcyBvcHRpbWl6YXRpb25zLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhIGRhdGUgb2JqZWN0LCBlbHNlIGBmYWxzZWAuXG4gICAgICovXG4gICAgZnVuY3Rpb24gYmFzZUlzRGF0ZSh2YWx1ZSkge1xuICAgICAgcmV0dXJuIGlzT2JqZWN0TGlrZSh2YWx1ZSkgJiYgYmFzZUdldFRhZyh2YWx1ZSkgPT0gZGF0ZVRhZztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5pc0VxdWFsYCB3aGljaCBzdXBwb3J0cyBwYXJ0aWFsIGNvbXBhcmlzb25zXG4gICAgICogYW5kIHRyYWNrcyB0cmF2ZXJzZWQgb2JqZWN0cy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY29tcGFyZS5cbiAgICAgKiBAcGFyYW0geyp9IG90aGVyIFRoZSBvdGhlciB2YWx1ZSB0byBjb21wYXJlLlxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbn0gYml0bWFzayBUaGUgYml0bWFzayBmbGFncy5cbiAgICAgKiAgMSAtIFVub3JkZXJlZCBjb21wYXJpc29uXG4gICAgICogIDIgLSBQYXJ0aWFsIGNvbXBhcmlzb25cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbY3VzdG9taXplcl0gVGhlIGZ1bmN0aW9uIHRvIGN1c3RvbWl6ZSBjb21wYXJpc29ucy5cbiAgICAgKiBAcGFyYW0ge09iamVjdH0gW3N0YWNrXSBUcmFja3MgdHJhdmVyc2VkIGB2YWx1ZWAgYW5kIGBvdGhlcmAgb2JqZWN0cy5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgdGhlIHZhbHVlcyBhcmUgZXF1aXZhbGVudCwgZWxzZSBgZmFsc2VgLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGJhc2VJc0VxdWFsKHZhbHVlLCBvdGhlciwgYml0bWFzaywgY3VzdG9taXplciwgc3RhY2spIHtcbiAgICAgIGlmICh2YWx1ZSA9PT0gb3RoZXIpIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9XG4gICAgICBpZiAodmFsdWUgPT0gbnVsbCB8fCBvdGhlciA9PSBudWxsIHx8ICghaXNPYmplY3RMaWtlKHZhbHVlKSAmJiAhaXNPYmplY3RMaWtlKG90aGVyKSkpIHtcbiAgICAgICAgcmV0dXJuIHZhbHVlICE9PSB2YWx1ZSAmJiBvdGhlciAhPT0gb3RoZXI7XG4gICAgICB9XG4gICAgICByZXR1cm4gYmFzZUlzRXF1YWxEZWVwKHZhbHVlLCBvdGhlciwgYml0bWFzaywgY3VzdG9taXplciwgYmFzZUlzRXF1YWwsIHN0YWNrKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBBIHNwZWNpYWxpemVkIHZlcnNpb24gb2YgYGJhc2VJc0VxdWFsYCBmb3IgYXJyYXlzIGFuZCBvYmplY3RzIHdoaWNoIHBlcmZvcm1zXG4gICAgICogZGVlcCBjb21wYXJpc29ucyBhbmQgdHJhY2tzIHRyYXZlcnNlZCBvYmplY3RzIGVuYWJsaW5nIG9iamVjdHMgd2l0aCBjaXJjdWxhclxuICAgICAqIHJlZmVyZW5jZXMgdG8gYmUgY29tcGFyZWQuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBjb21wYXJlLlxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvdGhlciBUaGUgb3RoZXIgb2JqZWN0IHRvIGNvbXBhcmUuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IGJpdG1hc2sgVGhlIGJpdG1hc2sgZmxhZ3MuIFNlZSBgYmFzZUlzRXF1YWxgIGZvciBtb3JlIGRldGFpbHMuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gY3VzdG9taXplciBUaGUgZnVuY3Rpb24gdG8gY3VzdG9taXplIGNvbXBhcmlzb25zLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGVxdWFsRnVuYyBUaGUgZnVuY3Rpb24gdG8gZGV0ZXJtaW5lIGVxdWl2YWxlbnRzIG9mIHZhbHVlcy5cbiAgICAgKiBAcGFyYW0ge09iamVjdH0gW3N0YWNrXSBUcmFja3MgdHJhdmVyc2VkIGBvYmplY3RgIGFuZCBgb3RoZXJgIG9iamVjdHMuXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIHRoZSBvYmplY3RzIGFyZSBlcXVpdmFsZW50LCBlbHNlIGBmYWxzZWAuXG4gICAgICovXG4gICAgZnVuY3Rpb24gYmFzZUlzRXF1YWxEZWVwKG9iamVjdCwgb3RoZXIsIGJpdG1hc2ssIGN1c3RvbWl6ZXIsIGVxdWFsRnVuYywgc3RhY2spIHtcbiAgICAgIHZhciBvYmpJc0FyciA9IGlzQXJyYXkob2JqZWN0KSxcbiAgICAgICAgICBvdGhJc0FyciA9IGlzQXJyYXkob3RoZXIpLFxuICAgICAgICAgIG9ialRhZyA9IG9iaklzQXJyID8gYXJyYXlUYWcgOiBnZXRUYWcob2JqZWN0KSxcbiAgICAgICAgICBvdGhUYWcgPSBvdGhJc0FyciA/IGFycmF5VGFnIDogZ2V0VGFnKG90aGVyKTtcblxuICAgICAgb2JqVGFnID0gb2JqVGFnID09IGFyZ3NUYWcgPyBvYmplY3RUYWcgOiBvYmpUYWc7XG4gICAgICBvdGhUYWcgPSBvdGhUYWcgPT0gYXJnc1RhZyA/IG9iamVjdFRhZyA6IG90aFRhZztcblxuICAgICAgdmFyIG9iaklzT2JqID0gb2JqVGFnID09IG9iamVjdFRhZyxcbiAgICAgICAgICBvdGhJc09iaiA9IG90aFRhZyA9PSBvYmplY3RUYWcsXG4gICAgICAgICAgaXNTYW1lVGFnID0gb2JqVGFnID09IG90aFRhZztcblxuICAgICAgaWYgKGlzU2FtZVRhZyAmJiBpc0J1ZmZlcihvYmplY3QpKSB7XG4gICAgICAgIGlmICghaXNCdWZmZXIob3RoZXIpKSB7XG4gICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIG9iaklzQXJyID0gdHJ1ZTtcbiAgICAgICAgb2JqSXNPYmogPSBmYWxzZTtcbiAgICAgIH1cbiAgICAgIGlmIChpc1NhbWVUYWcgJiYgIW9iaklzT2JqKSB7XG4gICAgICAgIHN0YWNrIHx8IChzdGFjayA9IG5ldyBTdGFjayk7XG4gICAgICAgIHJldHVybiAob2JqSXNBcnIgfHwgaXNUeXBlZEFycmF5KG9iamVjdCkpXG4gICAgICAgICAgPyBlcXVhbEFycmF5cyhvYmplY3QsIG90aGVyLCBiaXRtYXNrLCBjdXN0b21pemVyLCBlcXVhbEZ1bmMsIHN0YWNrKVxuICAgICAgICAgIDogZXF1YWxCeVRhZyhvYmplY3QsIG90aGVyLCBvYmpUYWcsIGJpdG1hc2ssIGN1c3RvbWl6ZXIsIGVxdWFsRnVuYywgc3RhY2spO1xuICAgICAgfVxuICAgICAgaWYgKCEoYml0bWFzayAmIENPTVBBUkVfUEFSVElBTF9GTEFHKSkge1xuICAgICAgICB2YXIgb2JqSXNXcmFwcGVkID0gb2JqSXNPYmogJiYgaGFzT3duUHJvcGVydHkuY2FsbChvYmplY3QsICdfX3dyYXBwZWRfXycpLFxuICAgICAgICAgICAgb3RoSXNXcmFwcGVkID0gb3RoSXNPYmogJiYgaGFzT3duUHJvcGVydHkuY2FsbChvdGhlciwgJ19fd3JhcHBlZF9fJyk7XG5cbiAgICAgICAgaWYgKG9iaklzV3JhcHBlZCB8fCBvdGhJc1dyYXBwZWQpIHtcbiAgICAgICAgICB2YXIgb2JqVW53cmFwcGVkID0gb2JqSXNXcmFwcGVkID8gb2JqZWN0LnZhbHVlKCkgOiBvYmplY3QsXG4gICAgICAgICAgICAgIG90aFVud3JhcHBlZCA9IG90aElzV3JhcHBlZCA/IG90aGVyLnZhbHVlKCkgOiBvdGhlcjtcblxuICAgICAgICAgIHN0YWNrIHx8IChzdGFjayA9IG5ldyBTdGFjayk7XG4gICAgICAgICAgcmV0dXJuIGVxdWFsRnVuYyhvYmpVbndyYXBwZWQsIG90aFVud3JhcHBlZCwgYml0bWFzaywgY3VzdG9taXplciwgc3RhY2spO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAoIWlzU2FtZVRhZykge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgICBzdGFjayB8fCAoc3RhY2sgPSBuZXcgU3RhY2spO1xuICAgICAgcmV0dXJuIGVxdWFsT2JqZWN0cyhvYmplY3QsIG90aGVyLCBiaXRtYXNrLCBjdXN0b21pemVyLCBlcXVhbEZ1bmMsIHN0YWNrKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5pc01hcGAgd2l0aG91dCBOb2RlLmpzIG9wdGltaXphdGlvbnMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGEgbWFwLCBlbHNlIGBmYWxzZWAuXG4gICAgICovXG4gICAgZnVuY3Rpb24gYmFzZUlzTWFwKHZhbHVlKSB7XG4gICAgICByZXR1cm4gaXNPYmplY3RMaWtlKHZhbHVlKSAmJiBnZXRUYWcodmFsdWUpID09IG1hcFRhZztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5pc01hdGNoYCB3aXRob3V0IHN1cHBvcnQgZm9yIGl0ZXJhdGVlIHNob3J0aGFuZHMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBpbnNwZWN0LlxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBzb3VyY2UgVGhlIG9iamVjdCBvZiBwcm9wZXJ0eSB2YWx1ZXMgdG8gbWF0Y2guXG4gICAgICogQHBhcmFtIHtBcnJheX0gbWF0Y2hEYXRhIFRoZSBwcm9wZXJ0eSBuYW1lcywgdmFsdWVzLCBhbmQgY29tcGFyZSBmbGFncyB0byBtYXRjaC5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbY3VzdG9taXplcl0gVGhlIGZ1bmN0aW9uIHRvIGN1c3RvbWl6ZSBjb21wYXJpc29ucy5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYG9iamVjdGAgaXMgYSBtYXRjaCwgZWxzZSBgZmFsc2VgLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGJhc2VJc01hdGNoKG9iamVjdCwgc291cmNlLCBtYXRjaERhdGEsIGN1c3RvbWl6ZXIpIHtcbiAgICAgIHZhciBpbmRleCA9IG1hdGNoRGF0YS5sZW5ndGgsXG4gICAgICAgICAgbGVuZ3RoID0gaW5kZXgsXG4gICAgICAgICAgbm9DdXN0b21pemVyID0gIWN1c3RvbWl6ZXI7XG5cbiAgICAgIGlmIChvYmplY3QgPT0gbnVsbCkge1xuICAgICAgICByZXR1cm4gIWxlbmd0aDtcbiAgICAgIH1cbiAgICAgIG9iamVjdCA9IE9iamVjdChvYmplY3QpO1xuICAgICAgd2hpbGUgKGluZGV4LS0pIHtcbiAgICAgICAgdmFyIGRhdGEgPSBtYXRjaERhdGFbaW5kZXhdO1xuICAgICAgICBpZiAoKG5vQ3VzdG9taXplciAmJiBkYXRhWzJdKVxuICAgICAgICAgICAgICA/IGRhdGFbMV0gIT09IG9iamVjdFtkYXRhWzBdXVxuICAgICAgICAgICAgICA6ICEoZGF0YVswXSBpbiBvYmplY3QpXG4gICAgICAgICAgICApIHtcbiAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XG4gICAgICAgIGRhdGEgPSBtYXRjaERhdGFbaW5kZXhdO1xuICAgICAgICB2YXIga2V5ID0gZGF0YVswXSxcbiAgICAgICAgICAgIG9ialZhbHVlID0gb2JqZWN0W2tleV0sXG4gICAgICAgICAgICBzcmNWYWx1ZSA9IGRhdGFbMV07XG5cbiAgICAgICAgaWYgKG5vQ3VzdG9taXplciAmJiBkYXRhWzJdKSB7XG4gICAgICAgICAgaWYgKG9ialZhbHVlID09PSB1bmRlZmluZWQgJiYgIShrZXkgaW4gb2JqZWN0KSkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB2YXIgc3RhY2sgPSBuZXcgU3RhY2s7XG4gICAgICAgICAgaWYgKGN1c3RvbWl6ZXIpIHtcbiAgICAgICAgICAgIHZhciByZXN1bHQgPSBjdXN0b21pemVyKG9ialZhbHVlLCBzcmNWYWx1ZSwga2V5LCBvYmplY3QsIHNvdXJjZSwgc3RhY2spO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoIShyZXN1bHQgPT09IHVuZGVmaW5lZFxuICAgICAgICAgICAgICAgID8gYmFzZUlzRXF1YWwoc3JjVmFsdWUsIG9ialZhbHVlLCBDT01QQVJFX1BBUlRJQUxfRkxBRyB8IENPTVBBUkVfVU5PUkRFUkVEX0ZMQUcsIGN1c3RvbWl6ZXIsIHN0YWNrKVxuICAgICAgICAgICAgICAgIDogcmVzdWx0XG4gICAgICAgICAgICAgICkpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLmlzTmF0aXZlYCB3aXRob3V0IGJhZCBzaGltIGNoZWNrcy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgYSBuYXRpdmUgZnVuY3Rpb24sXG4gICAgICogIGVsc2UgYGZhbHNlYC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBiYXNlSXNOYXRpdmUodmFsdWUpIHtcbiAgICAgIGlmICghaXNPYmplY3QodmFsdWUpIHx8IGlzTWFza2VkKHZhbHVlKSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgICB2YXIgcGF0dGVybiA9IGlzRnVuY3Rpb24odmFsdWUpID8gcmVJc05hdGl2ZSA6IHJlSXNIb3N0Q3RvcjtcbiAgICAgIHJldHVybiBwYXR0ZXJuLnRlc3QodG9Tb3VyY2UodmFsdWUpKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5pc1JlZ0V4cGAgd2l0aG91dCBOb2RlLmpzIG9wdGltaXphdGlvbnMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGEgcmVnZXhwLCBlbHNlIGBmYWxzZWAuXG4gICAgICovXG4gICAgZnVuY3Rpb24gYmFzZUlzUmVnRXhwKHZhbHVlKSB7XG4gICAgICByZXR1cm4gaXNPYmplY3RMaWtlKHZhbHVlKSAmJiBiYXNlR2V0VGFnKHZhbHVlKSA9PSByZWdleHBUYWc7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uaXNTZXRgIHdpdGhvdXQgTm9kZS5qcyBvcHRpbWl6YXRpb25zLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhIHNldCwgZWxzZSBgZmFsc2VgLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGJhc2VJc1NldCh2YWx1ZSkge1xuICAgICAgcmV0dXJuIGlzT2JqZWN0TGlrZSh2YWx1ZSkgJiYgZ2V0VGFnKHZhbHVlKSA9PSBzZXRUYWc7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uaXNUeXBlZEFycmF5YCB3aXRob3V0IE5vZGUuanMgb3B0aW1pemF0aW9ucy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgYSB0eXBlZCBhcnJheSwgZWxzZSBgZmFsc2VgLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGJhc2VJc1R5cGVkQXJyYXkodmFsdWUpIHtcbiAgICAgIHJldHVybiBpc09iamVjdExpa2UodmFsdWUpICYmXG4gICAgICAgIGlzTGVuZ3RoKHZhbHVlLmxlbmd0aCkgJiYgISF0eXBlZEFycmF5VGFnc1tiYXNlR2V0VGFnKHZhbHVlKV07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uaXRlcmF0ZWVgLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0geyp9IFt2YWx1ZT1fLmlkZW50aXR5XSBUaGUgdmFsdWUgdG8gY29udmVydCB0byBhbiBpdGVyYXRlZS5cbiAgICAgKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIGl0ZXJhdGVlLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGJhc2VJdGVyYXRlZSh2YWx1ZSkge1xuICAgICAgLy8gRG9uJ3Qgc3RvcmUgdGhlIGB0eXBlb2ZgIHJlc3VsdCBpbiBhIHZhcmlhYmxlIHRvIGF2b2lkIGEgSklUIGJ1ZyBpbiBTYWZhcmkgOS5cbiAgICAgIC8vIFNlZSBodHRwczovL2J1Z3Mud2Via2l0Lm9yZy9zaG93X2J1Zy5jZ2k/aWQ9MTU2MDM0IGZvciBtb3JlIGRldGFpbHMuXG4gICAgICBpZiAodHlwZW9mIHZhbHVlID09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgICAgfVxuICAgICAgaWYgKHZhbHVlID09IG51bGwpIHtcbiAgICAgICAgcmV0dXJuIGlkZW50aXR5O1xuICAgICAgfVxuICAgICAgaWYgKHR5cGVvZiB2YWx1ZSA9PSAnb2JqZWN0Jykge1xuICAgICAgICByZXR1cm4gaXNBcnJheSh2YWx1ZSlcbiAgICAgICAgICA/IGJhc2VNYXRjaGVzUHJvcGVydHkodmFsdWVbMF0sIHZhbHVlWzFdKVxuICAgICAgICAgIDogYmFzZU1hdGNoZXModmFsdWUpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHByb3BlcnR5KHZhbHVlKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5rZXlzYCB3aGljaCBkb2Vzbid0IHRyZWF0IHNwYXJzZSBhcnJheXMgYXMgZGVuc2UuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBxdWVyeS5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIGFycmF5IG9mIHByb3BlcnR5IG5hbWVzLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGJhc2VLZXlzKG9iamVjdCkge1xuICAgICAgaWYgKCFpc1Byb3RvdHlwZShvYmplY3QpKSB7XG4gICAgICAgIHJldHVybiBuYXRpdmVLZXlzKG9iamVjdCk7XG4gICAgICB9XG4gICAgICB2YXIgcmVzdWx0ID0gW107XG4gICAgICBmb3IgKHZhciBrZXkgaW4gT2JqZWN0KG9iamVjdCkpIHtcbiAgICAgICAgaWYgKGhhc093blByb3BlcnR5LmNhbGwob2JqZWN0LCBrZXkpICYmIGtleSAhPSAnY29uc3RydWN0b3InKSB7XG4gICAgICAgICAgcmVzdWx0LnB1c2goa2V5KTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5rZXlzSW5gIHdoaWNoIGRvZXNuJ3QgdHJlYXQgc3BhcnNlIGFycmF5cyBhcyBkZW5zZS5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIHF1ZXJ5LlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgYXJyYXkgb2YgcHJvcGVydHkgbmFtZXMuXG4gICAgICovXG4gICAgZnVuY3Rpb24gYmFzZUtleXNJbihvYmplY3QpIHtcbiAgICAgIGlmICghaXNPYmplY3Qob2JqZWN0KSkge1xuICAgICAgICByZXR1cm4gbmF0aXZlS2V5c0luKG9iamVjdCk7XG4gICAgICB9XG4gICAgICB2YXIgaXNQcm90byA9IGlzUHJvdG90eXBlKG9iamVjdCksXG4gICAgICAgICAgcmVzdWx0ID0gW107XG5cbiAgICAgIGZvciAodmFyIGtleSBpbiBvYmplY3QpIHtcbiAgICAgICAgaWYgKCEoa2V5ID09ICdjb25zdHJ1Y3RvcicgJiYgKGlzUHJvdG8gfHwgIWhhc093blByb3BlcnR5LmNhbGwob2JqZWN0LCBrZXkpKSkpIHtcbiAgICAgICAgICByZXN1bHQucHVzaChrZXkpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLmx0YCB3aGljaCBkb2Vzbid0IGNvZXJjZSBhcmd1bWVudHMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNvbXBhcmUuXG4gICAgICogQHBhcmFtIHsqfSBvdGhlciBUaGUgb3RoZXIgdmFsdWUgdG8gY29tcGFyZS5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBsZXNzIHRoYW4gYG90aGVyYCxcbiAgICAgKiAgZWxzZSBgZmFsc2VgLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGJhc2VMdCh2YWx1ZSwgb3RoZXIpIHtcbiAgICAgIHJldHVybiB2YWx1ZSA8IG90aGVyO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLm1hcGAgd2l0aG91dCBzdXBwb3J0IGZvciBpdGVyYXRlZSBzaG9ydGhhbmRzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0FycmF5fE9iamVjdH0gY29sbGVjdGlvbiBUaGUgY29sbGVjdGlvbiB0byBpdGVyYXRlIG92ZXIuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gaXRlcmF0ZWUgVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIGl0ZXJhdGlvbi5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIG5ldyBtYXBwZWQgYXJyYXkuXG4gICAgICovXG4gICAgZnVuY3Rpb24gYmFzZU1hcChjb2xsZWN0aW9uLCBpdGVyYXRlZSkge1xuICAgICAgdmFyIGluZGV4ID0gLTEsXG4gICAgICAgICAgcmVzdWx0ID0gaXNBcnJheUxpa2UoY29sbGVjdGlvbikgPyBBcnJheShjb2xsZWN0aW9uLmxlbmd0aCkgOiBbXTtcblxuICAgICAgYmFzZUVhY2goY29sbGVjdGlvbiwgZnVuY3Rpb24odmFsdWUsIGtleSwgY29sbGVjdGlvbikge1xuICAgICAgICByZXN1bHRbKytpbmRleF0gPSBpdGVyYXRlZSh2YWx1ZSwga2V5LCBjb2xsZWN0aW9uKTtcbiAgICAgIH0pO1xuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5tYXRjaGVzYCB3aGljaCBkb2Vzbid0IGNsb25lIGBzb3VyY2VgLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gc291cmNlIFRoZSBvYmplY3Qgb2YgcHJvcGVydHkgdmFsdWVzIHRvIG1hdGNoLlxuICAgICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IHNwZWMgZnVuY3Rpb24uXG4gICAgICovXG4gICAgZnVuY3Rpb24gYmFzZU1hdGNoZXMoc291cmNlKSB7XG4gICAgICB2YXIgbWF0Y2hEYXRhID0gZ2V0TWF0Y2hEYXRhKHNvdXJjZSk7XG4gICAgICBpZiAobWF0Y2hEYXRhLmxlbmd0aCA9PSAxICYmIG1hdGNoRGF0YVswXVsyXSkge1xuICAgICAgICByZXR1cm4gbWF0Y2hlc1N0cmljdENvbXBhcmFibGUobWF0Y2hEYXRhWzBdWzBdLCBtYXRjaERhdGFbMF1bMV0pO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGZ1bmN0aW9uKG9iamVjdCkge1xuICAgICAgICByZXR1cm4gb2JqZWN0ID09PSBzb3VyY2UgfHwgYmFzZUlzTWF0Y2gob2JqZWN0LCBzb3VyY2UsIG1hdGNoRGF0YSk7XG4gICAgICB9O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLm1hdGNoZXNQcm9wZXJ0eWAgd2hpY2ggZG9lc24ndCBjbG9uZSBgc3JjVmFsdWVgLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gcGF0aCBUaGUgcGF0aCBvZiB0aGUgcHJvcGVydHkgdG8gZ2V0LlxuICAgICAqIEBwYXJhbSB7Kn0gc3JjVmFsdWUgVGhlIHZhbHVlIHRvIG1hdGNoLlxuICAgICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IHNwZWMgZnVuY3Rpb24uXG4gICAgICovXG4gICAgZnVuY3Rpb24gYmFzZU1hdGNoZXNQcm9wZXJ0eShwYXRoLCBzcmNWYWx1ZSkge1xuICAgICAgaWYgKGlzS2V5KHBhdGgpICYmIGlzU3RyaWN0Q29tcGFyYWJsZShzcmNWYWx1ZSkpIHtcbiAgICAgICAgcmV0dXJuIG1hdGNoZXNTdHJpY3RDb21wYXJhYmxlKHRvS2V5KHBhdGgpLCBzcmNWYWx1ZSk7XG4gICAgICB9XG4gICAgICByZXR1cm4gZnVuY3Rpb24ob2JqZWN0KSB7XG4gICAgICAgIHZhciBvYmpWYWx1ZSA9IGdldChvYmplY3QsIHBhdGgpO1xuICAgICAgICByZXR1cm4gKG9ialZhbHVlID09PSB1bmRlZmluZWQgJiYgb2JqVmFsdWUgPT09IHNyY1ZhbHVlKVxuICAgICAgICAgID8gaGFzSW4ob2JqZWN0LCBwYXRoKVxuICAgICAgICAgIDogYmFzZUlzRXF1YWwoc3JjVmFsdWUsIG9ialZhbHVlLCBDT01QQVJFX1BBUlRJQUxfRkxBRyB8IENPTVBBUkVfVU5PUkRFUkVEX0ZMQUcpO1xuICAgICAgfTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5tZXJnZWAgd2l0aG91dCBzdXBwb3J0IGZvciBtdWx0aXBsZSBzb3VyY2VzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBkZXN0aW5hdGlvbiBvYmplY3QuXG4gICAgICogQHBhcmFtIHtPYmplY3R9IHNvdXJjZSBUaGUgc291cmNlIG9iamVjdC5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gc3JjSW5kZXggVGhlIGluZGV4IG9mIGBzb3VyY2VgLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IFtjdXN0b21pemVyXSBUaGUgZnVuY3Rpb24gdG8gY3VzdG9taXplIG1lcmdlZCB2YWx1ZXMuXG4gICAgICogQHBhcmFtIHtPYmplY3R9IFtzdGFja10gVHJhY2tzIHRyYXZlcnNlZCBzb3VyY2UgdmFsdWVzIGFuZCB0aGVpciBtZXJnZWRcbiAgICAgKiAgY291bnRlcnBhcnRzLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGJhc2VNZXJnZShvYmplY3QsIHNvdXJjZSwgc3JjSW5kZXgsIGN1c3RvbWl6ZXIsIHN0YWNrKSB7XG4gICAgICBpZiAob2JqZWN0ID09PSBzb3VyY2UpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgYmFzZUZvcihzb3VyY2UsIGZ1bmN0aW9uKHNyY1ZhbHVlLCBrZXkpIHtcbiAgICAgICAgc3RhY2sgfHwgKHN0YWNrID0gbmV3IFN0YWNrKTtcbiAgICAgICAgaWYgKGlzT2JqZWN0KHNyY1ZhbHVlKSkge1xuICAgICAgICAgIGJhc2VNZXJnZURlZXAob2JqZWN0LCBzb3VyY2UsIGtleSwgc3JjSW5kZXgsIGJhc2VNZXJnZSwgY3VzdG9taXplciwgc3RhY2spO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgIHZhciBuZXdWYWx1ZSA9IGN1c3RvbWl6ZXJcbiAgICAgICAgICAgID8gY3VzdG9taXplcihzYWZlR2V0KG9iamVjdCwga2V5KSwgc3JjVmFsdWUsIChrZXkgKyAnJyksIG9iamVjdCwgc291cmNlLCBzdGFjaylcbiAgICAgICAgICAgIDogdW5kZWZpbmVkO1xuXG4gICAgICAgICAgaWYgKG5ld1ZhbHVlID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIG5ld1ZhbHVlID0gc3JjVmFsdWU7XG4gICAgICAgICAgfVxuICAgICAgICAgIGFzc2lnbk1lcmdlVmFsdWUob2JqZWN0LCBrZXksIG5ld1ZhbHVlKTtcbiAgICAgICAgfVxuICAgICAgfSwga2V5c0luKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBBIHNwZWNpYWxpemVkIHZlcnNpb24gb2YgYGJhc2VNZXJnZWAgZm9yIGFycmF5cyBhbmQgb2JqZWN0cyB3aGljaCBwZXJmb3Jtc1xuICAgICAqIGRlZXAgbWVyZ2VzIGFuZCB0cmFja3MgdHJhdmVyc2VkIG9iamVjdHMgZW5hYmxpbmcgb2JqZWN0cyB3aXRoIGNpcmN1bGFyXG4gICAgICogcmVmZXJlbmNlcyB0byBiZSBtZXJnZWQuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIGRlc3RpbmF0aW9uIG9iamVjdC5cbiAgICAgKiBAcGFyYW0ge09iamVjdH0gc291cmNlIFRoZSBzb3VyY2Ugb2JqZWN0LlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgVGhlIGtleSBvZiB0aGUgdmFsdWUgdG8gbWVyZ2UuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHNyY0luZGV4IFRoZSBpbmRleCBvZiBgc291cmNlYC5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBtZXJnZUZ1bmMgVGhlIGZ1bmN0aW9uIHRvIG1lcmdlIHZhbHVlcy5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbY3VzdG9taXplcl0gVGhlIGZ1bmN0aW9uIHRvIGN1c3RvbWl6ZSBhc3NpZ25lZCB2YWx1ZXMuXG4gICAgICogQHBhcmFtIHtPYmplY3R9IFtzdGFja10gVHJhY2tzIHRyYXZlcnNlZCBzb3VyY2UgdmFsdWVzIGFuZCB0aGVpciBtZXJnZWRcbiAgICAgKiAgY291bnRlcnBhcnRzLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGJhc2VNZXJnZURlZXAob2JqZWN0LCBzb3VyY2UsIGtleSwgc3JjSW5kZXgsIG1lcmdlRnVuYywgY3VzdG9taXplciwgc3RhY2spIHtcbiAgICAgIHZhciBvYmpWYWx1ZSA9IHNhZmVHZXQob2JqZWN0LCBrZXkpLFxuICAgICAgICAgIHNyY1ZhbHVlID0gc2FmZUdldChzb3VyY2UsIGtleSksXG4gICAgICAgICAgc3RhY2tlZCA9IHN0YWNrLmdldChzcmNWYWx1ZSk7XG5cbiAgICAgIGlmIChzdGFja2VkKSB7XG4gICAgICAgIGFzc2lnbk1lcmdlVmFsdWUob2JqZWN0LCBrZXksIHN0YWNrZWQpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICB2YXIgbmV3VmFsdWUgPSBjdXN0b21pemVyXG4gICAgICAgID8gY3VzdG9taXplcihvYmpWYWx1ZSwgc3JjVmFsdWUsIChrZXkgKyAnJyksIG9iamVjdCwgc291cmNlLCBzdGFjaylcbiAgICAgICAgOiB1bmRlZmluZWQ7XG5cbiAgICAgIHZhciBpc0NvbW1vbiA9IG5ld1ZhbHVlID09PSB1bmRlZmluZWQ7XG5cbiAgICAgIGlmIChpc0NvbW1vbikge1xuICAgICAgICB2YXIgaXNBcnIgPSBpc0FycmF5KHNyY1ZhbHVlKSxcbiAgICAgICAgICAgIGlzQnVmZiA9ICFpc0FyciAmJiBpc0J1ZmZlcihzcmNWYWx1ZSksXG4gICAgICAgICAgICBpc1R5cGVkID0gIWlzQXJyICYmICFpc0J1ZmYgJiYgaXNUeXBlZEFycmF5KHNyY1ZhbHVlKTtcblxuICAgICAgICBuZXdWYWx1ZSA9IHNyY1ZhbHVlO1xuICAgICAgICBpZiAoaXNBcnIgfHwgaXNCdWZmIHx8IGlzVHlwZWQpIHtcbiAgICAgICAgICBpZiAoaXNBcnJheShvYmpWYWx1ZSkpIHtcbiAgICAgICAgICAgIG5ld1ZhbHVlID0gb2JqVmFsdWU7XG4gICAgICAgICAgfVxuICAgICAgICAgIGVsc2UgaWYgKGlzQXJyYXlMaWtlT2JqZWN0KG9ialZhbHVlKSkge1xuICAgICAgICAgICAgbmV3VmFsdWUgPSBjb3B5QXJyYXkob2JqVmFsdWUpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBlbHNlIGlmIChpc0J1ZmYpIHtcbiAgICAgICAgICAgIGlzQ29tbW9uID0gZmFsc2U7XG4gICAgICAgICAgICBuZXdWYWx1ZSA9IGNsb25lQnVmZmVyKHNyY1ZhbHVlLCB0cnVlKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgZWxzZSBpZiAoaXNUeXBlZCkge1xuICAgICAgICAgICAgaXNDb21tb24gPSBmYWxzZTtcbiAgICAgICAgICAgIG5ld1ZhbHVlID0gY2xvbmVUeXBlZEFycmF5KHNyY1ZhbHVlLCB0cnVlKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBuZXdWYWx1ZSA9IFtdO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChpc1BsYWluT2JqZWN0KHNyY1ZhbHVlKSB8fCBpc0FyZ3VtZW50cyhzcmNWYWx1ZSkpIHtcbiAgICAgICAgICBuZXdWYWx1ZSA9IG9ialZhbHVlO1xuICAgICAgICAgIGlmIChpc0FyZ3VtZW50cyhvYmpWYWx1ZSkpIHtcbiAgICAgICAgICAgIG5ld1ZhbHVlID0gdG9QbGFpbk9iamVjdChvYmpWYWx1ZSk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGVsc2UgaWYgKCFpc09iamVjdChvYmpWYWx1ZSkgfHwgaXNGdW5jdGlvbihvYmpWYWx1ZSkpIHtcbiAgICAgICAgICAgIG5ld1ZhbHVlID0gaW5pdENsb25lT2JqZWN0KHNyY1ZhbHVlKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgaXNDb21tb24gPSBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKGlzQ29tbW9uKSB7XG4gICAgICAgIC8vIFJlY3Vyc2l2ZWx5IG1lcmdlIG9iamVjdHMgYW5kIGFycmF5cyAoc3VzY2VwdGlibGUgdG8gY2FsbCBzdGFjayBsaW1pdHMpLlxuICAgICAgICBzdGFjay5zZXQoc3JjVmFsdWUsIG5ld1ZhbHVlKTtcbiAgICAgICAgbWVyZ2VGdW5jKG5ld1ZhbHVlLCBzcmNWYWx1ZSwgc3JjSW5kZXgsIGN1c3RvbWl6ZXIsIHN0YWNrKTtcbiAgICAgICAgc3RhY2tbJ2RlbGV0ZSddKHNyY1ZhbHVlKTtcbiAgICAgIH1cbiAgICAgIGFzc2lnbk1lcmdlVmFsdWUob2JqZWN0LCBrZXksIG5ld1ZhbHVlKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5udGhgIHdoaWNoIGRvZXNuJ3QgY29lcmNlIGFyZ3VtZW50cy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIHF1ZXJ5LlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBuIFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uXG4gICAgICogQHJldHVybnMgeyp9IFJldHVybnMgdGhlIG50aCBlbGVtZW50IG9mIGBhcnJheWAuXG4gICAgICovXG4gICAgZnVuY3Rpb24gYmFzZU50aChhcnJheSwgbikge1xuICAgICAgdmFyIGxlbmd0aCA9IGFycmF5Lmxlbmd0aDtcbiAgICAgIGlmICghbGVuZ3RoKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIG4gKz0gbiA8IDAgPyBsZW5ndGggOiAwO1xuICAgICAgcmV0dXJuIGlzSW5kZXgobiwgbGVuZ3RoKSA/IGFycmF5W25dIDogdW5kZWZpbmVkO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLm9yZGVyQnlgIHdpdGhvdXQgcGFyYW0gZ3VhcmRzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0FycmF5fE9iamVjdH0gY29sbGVjdGlvbiBUaGUgY29sbGVjdGlvbiB0byBpdGVyYXRlIG92ZXIuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbltdfE9iamVjdFtdfHN0cmluZ1tdfSBpdGVyYXRlZXMgVGhlIGl0ZXJhdGVlcyB0byBzb3J0IGJ5LlxuICAgICAqIEBwYXJhbSB7c3RyaW5nW119IG9yZGVycyBUaGUgc29ydCBvcmRlcnMgb2YgYGl0ZXJhdGVlc2AuXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBuZXcgc29ydGVkIGFycmF5LlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGJhc2VPcmRlckJ5KGNvbGxlY3Rpb24sIGl0ZXJhdGVlcywgb3JkZXJzKSB7XG4gICAgICBpZiAoaXRlcmF0ZWVzLmxlbmd0aCkge1xuICAgICAgICBpdGVyYXRlZXMgPSBhcnJheU1hcChpdGVyYXRlZXMsIGZ1bmN0aW9uKGl0ZXJhdGVlKSB7XG4gICAgICAgICAgaWYgKGlzQXJyYXkoaXRlcmF0ZWUpKSB7XG4gICAgICAgICAgICByZXR1cm4gZnVuY3Rpb24odmFsdWUpIHtcbiAgICAgICAgICAgICAgcmV0dXJuIGJhc2VHZXQodmFsdWUsIGl0ZXJhdGVlLmxlbmd0aCA9PT0gMSA/IGl0ZXJhdGVlWzBdIDogaXRlcmF0ZWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4gaXRlcmF0ZWU7XG4gICAgICAgIH0pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaXRlcmF0ZWVzID0gW2lkZW50aXR5XTtcbiAgICAgIH1cblxuICAgICAgdmFyIGluZGV4ID0gLTE7XG4gICAgICBpdGVyYXRlZXMgPSBhcnJheU1hcChpdGVyYXRlZXMsIGJhc2VVbmFyeShnZXRJdGVyYXRlZSgpKSk7XG5cbiAgICAgIHZhciByZXN1bHQgPSBiYXNlTWFwKGNvbGxlY3Rpb24sIGZ1bmN0aW9uKHZhbHVlLCBrZXksIGNvbGxlY3Rpb24pIHtcbiAgICAgICAgdmFyIGNyaXRlcmlhID0gYXJyYXlNYXAoaXRlcmF0ZWVzLCBmdW5jdGlvbihpdGVyYXRlZSkge1xuICAgICAgICAgIHJldHVybiBpdGVyYXRlZSh2YWx1ZSk7XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4geyAnY3JpdGVyaWEnOiBjcml0ZXJpYSwgJ2luZGV4JzogKytpbmRleCwgJ3ZhbHVlJzogdmFsdWUgfTtcbiAgICAgIH0pO1xuXG4gICAgICByZXR1cm4gYmFzZVNvcnRCeShyZXN1bHQsIGZ1bmN0aW9uKG9iamVjdCwgb3RoZXIpIHtcbiAgICAgICAgcmV0dXJuIGNvbXBhcmVNdWx0aXBsZShvYmplY3QsIG90aGVyLCBvcmRlcnMpO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8ucGlja2Agd2l0aG91dCBzdXBwb3J0IGZvciBpbmRpdmlkdWFsXG4gICAgICogcHJvcGVydHkgaWRlbnRpZmllcnMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIHNvdXJjZSBvYmplY3QuXG4gICAgICogQHBhcmFtIHtzdHJpbmdbXX0gcGF0aHMgVGhlIHByb3BlcnR5IHBhdGhzIHRvIHBpY2suXG4gICAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyB0aGUgbmV3IG9iamVjdC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBiYXNlUGljayhvYmplY3QsIHBhdGhzKSB7XG4gICAgICByZXR1cm4gYmFzZVBpY2tCeShvYmplY3QsIHBhdGhzLCBmdW5jdGlvbih2YWx1ZSwgcGF0aCkge1xuICAgICAgICByZXR1cm4gaGFzSW4ob2JqZWN0LCBwYXRoKTtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mICBgXy5waWNrQnlgIHdpdGhvdXQgc3VwcG9ydCBmb3IgaXRlcmF0ZWUgc2hvcnRoYW5kcy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgc291cmNlIG9iamVjdC5cbiAgICAgKiBAcGFyYW0ge3N0cmluZ1tdfSBwYXRocyBUaGUgcHJvcGVydHkgcGF0aHMgdG8gcGljay5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBwcmVkaWNhdGUgVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIHByb3BlcnR5LlxuICAgICAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgdGhlIG5ldyBvYmplY3QuXG4gICAgICovXG4gICAgZnVuY3Rpb24gYmFzZVBpY2tCeShvYmplY3QsIHBhdGhzLCBwcmVkaWNhdGUpIHtcbiAgICAgIHZhciBpbmRleCA9IC0xLFxuICAgICAgICAgIGxlbmd0aCA9IHBhdGhzLmxlbmd0aCxcbiAgICAgICAgICByZXN1bHQgPSB7fTtcblxuICAgICAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHtcbiAgICAgICAgdmFyIHBhdGggPSBwYXRoc1tpbmRleF0sXG4gICAgICAgICAgICB2YWx1ZSA9IGJhc2VHZXQob2JqZWN0LCBwYXRoKTtcblxuICAgICAgICBpZiAocHJlZGljYXRlKHZhbHVlLCBwYXRoKSkge1xuICAgICAgICAgIGJhc2VTZXQocmVzdWx0LCBjYXN0UGF0aChwYXRoLCBvYmplY3QpLCB2YWx1ZSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQSBzcGVjaWFsaXplZCB2ZXJzaW9uIG9mIGBiYXNlUHJvcGVydHlgIHdoaWNoIHN1cHBvcnRzIGRlZXAgcGF0aHMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7QXJyYXl8c3RyaW5nfSBwYXRoIFRoZSBwYXRoIG9mIHRoZSBwcm9wZXJ0eSB0byBnZXQuXG4gICAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgYWNjZXNzb3IgZnVuY3Rpb24uXG4gICAgICovXG4gICAgZnVuY3Rpb24gYmFzZVByb3BlcnR5RGVlcChwYXRoKSB7XG4gICAgICByZXR1cm4gZnVuY3Rpb24ob2JqZWN0KSB7XG4gICAgICAgIHJldHVybiBiYXNlR2V0KG9iamVjdCwgcGF0aCk7XG4gICAgICB9O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLnB1bGxBbGxCeWAgd2l0aG91dCBzdXBwb3J0IGZvciBpdGVyYXRlZVxuICAgICAqIHNob3J0aGFuZHMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBtb2RpZnkuXG4gICAgICogQHBhcmFtIHtBcnJheX0gdmFsdWVzIFRoZSB2YWx1ZXMgdG8gcmVtb3ZlLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IFtpdGVyYXRlZV0gVGhlIGl0ZXJhdGVlIGludm9rZWQgcGVyIGVsZW1lbnQuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW2NvbXBhcmF0b3JdIFRoZSBjb21wYXJhdG9yIGludm9rZWQgcGVyIGVsZW1lbnQuXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIGBhcnJheWAuXG4gICAgICovXG4gICAgZnVuY3Rpb24gYmFzZVB1bGxBbGwoYXJyYXksIHZhbHVlcywgaXRlcmF0ZWUsIGNvbXBhcmF0b3IpIHtcbiAgICAgIHZhciBpbmRleE9mID0gY29tcGFyYXRvciA/IGJhc2VJbmRleE9mV2l0aCA6IGJhc2VJbmRleE9mLFxuICAgICAgICAgIGluZGV4ID0gLTEsXG4gICAgICAgICAgbGVuZ3RoID0gdmFsdWVzLmxlbmd0aCxcbiAgICAgICAgICBzZWVuID0gYXJyYXk7XG5cbiAgICAgIGlmIChhcnJheSA9PT0gdmFsdWVzKSB7XG4gICAgICAgIHZhbHVlcyA9IGNvcHlBcnJheSh2YWx1ZXMpO1xuICAgICAgfVxuICAgICAgaWYgKGl0ZXJhdGVlKSB7XG4gICAgICAgIHNlZW4gPSBhcnJheU1hcChhcnJheSwgYmFzZVVuYXJ5KGl0ZXJhdGVlKSk7XG4gICAgICB9XG4gICAgICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgICAgICB2YXIgZnJvbUluZGV4ID0gMCxcbiAgICAgICAgICAgIHZhbHVlID0gdmFsdWVzW2luZGV4XSxcbiAgICAgICAgICAgIGNvbXB1dGVkID0gaXRlcmF0ZWUgPyBpdGVyYXRlZSh2YWx1ZSkgOiB2YWx1ZTtcblxuICAgICAgICB3aGlsZSAoKGZyb21JbmRleCA9IGluZGV4T2Yoc2VlbiwgY29tcHV0ZWQsIGZyb21JbmRleCwgY29tcGFyYXRvcikpID4gLTEpIHtcbiAgICAgICAgICBpZiAoc2VlbiAhPT0gYXJyYXkpIHtcbiAgICAgICAgICAgIHNwbGljZS5jYWxsKHNlZW4sIGZyb21JbmRleCwgMSk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHNwbGljZS5jYWxsKGFycmF5LCBmcm9tSW5kZXgsIDEpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gYXJyYXk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8ucHVsbEF0YCB3aXRob3V0IHN1cHBvcnQgZm9yIGluZGl2aWR1YWxcbiAgICAgKiBpbmRleGVzIG9yIGNhcHR1cmluZyB0aGUgcmVtb3ZlZCBlbGVtZW50cy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIG1vZGlmeS5cbiAgICAgKiBAcGFyYW0ge251bWJlcltdfSBpbmRleGVzIFRoZSBpbmRleGVzIG9mIGVsZW1lbnRzIHRvIHJlbW92ZS5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgYGFycmF5YC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBiYXNlUHVsbEF0KGFycmF5LCBpbmRleGVzKSB7XG4gICAgICB2YXIgbGVuZ3RoID0gYXJyYXkgPyBpbmRleGVzLmxlbmd0aCA6IDAsXG4gICAgICAgICAgbGFzdEluZGV4ID0gbGVuZ3RoIC0gMTtcblxuICAgICAgd2hpbGUgKGxlbmd0aC0tKSB7XG4gICAgICAgIHZhciBpbmRleCA9IGluZGV4ZXNbbGVuZ3RoXTtcbiAgICAgICAgaWYgKGxlbmd0aCA9PSBsYXN0SW5kZXggfHwgaW5kZXggIT09IHByZXZpb3VzKSB7XG4gICAgICAgICAgdmFyIHByZXZpb3VzID0gaW5kZXg7XG4gICAgICAgICAgaWYgKGlzSW5kZXgoaW5kZXgpKSB7XG4gICAgICAgICAgICBzcGxpY2UuY2FsbChhcnJheSwgaW5kZXgsIDEpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBiYXNlVW5zZXQoYXJyYXksIGluZGV4KTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiBhcnJheTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5yYW5kb21gIHdpdGhvdXQgc3VwcG9ydCBmb3IgcmV0dXJuaW5nXG4gICAgICogZmxvYXRpbmctcG9pbnQgbnVtYmVycy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IGxvd2VyIFRoZSBsb3dlciBib3VuZC5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gdXBwZXIgVGhlIHVwcGVyIGJvdW5kLlxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9IFJldHVybnMgdGhlIHJhbmRvbSBudW1iZXIuXG4gICAgICovXG4gICAgZnVuY3Rpb24gYmFzZVJhbmRvbShsb3dlciwgdXBwZXIpIHtcbiAgICAgIHJldHVybiBsb3dlciArIG5hdGl2ZUZsb29yKG5hdGl2ZVJhbmRvbSgpICogKHVwcGVyIC0gbG93ZXIgKyAxKSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8ucmFuZ2VgIGFuZCBgXy5yYW5nZVJpZ2h0YCB3aGljaCBkb2Vzbid0XG4gICAgICogY29lcmNlIGFyZ3VtZW50cy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHN0YXJ0IFRoZSBzdGFydCBvZiB0aGUgcmFuZ2UuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IGVuZCBUaGUgZW5kIG9mIHRoZSByYW5nZS5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gc3RlcCBUaGUgdmFsdWUgdG8gaW5jcmVtZW50IG9yIGRlY3JlbWVudCBieS5cbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW59IFtmcm9tUmlnaHRdIFNwZWNpZnkgaXRlcmF0aW5nIGZyb20gcmlnaHQgdG8gbGVmdC5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIHJhbmdlIG9mIG51bWJlcnMuXG4gICAgICovXG4gICAgZnVuY3Rpb24gYmFzZVJhbmdlKHN0YXJ0LCBlbmQsIHN0ZXAsIGZyb21SaWdodCkge1xuICAgICAgdmFyIGluZGV4ID0gLTEsXG4gICAgICAgICAgbGVuZ3RoID0gbmF0aXZlTWF4KG5hdGl2ZUNlaWwoKGVuZCAtIHN0YXJ0KSAvIChzdGVwIHx8IDEpKSwgMCksXG4gICAgICAgICAgcmVzdWx0ID0gQXJyYXkobGVuZ3RoKTtcblxuICAgICAgd2hpbGUgKGxlbmd0aC0tKSB7XG4gICAgICAgIHJlc3VsdFtmcm9tUmlnaHQgPyBsZW5ndGggOiArK2luZGV4XSA9IHN0YXJ0O1xuICAgICAgICBzdGFydCArPSBzdGVwO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5yZXBlYXRgIHdoaWNoIGRvZXNuJ3QgY29lcmNlIGFyZ3VtZW50cy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IHN0cmluZyBUaGUgc3RyaW5nIHRvIHJlcGVhdC5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gbiBUaGUgbnVtYmVyIG9mIHRpbWVzIHRvIHJlcGVhdCB0aGUgc3RyaW5nLlxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IFJldHVybnMgdGhlIHJlcGVhdGVkIHN0cmluZy5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBiYXNlUmVwZWF0KHN0cmluZywgbikge1xuICAgICAgdmFyIHJlc3VsdCA9ICcnO1xuICAgICAgaWYgKCFzdHJpbmcgfHwgbiA8IDEgfHwgbiA+IE1BWF9TQUZFX0lOVEVHRVIpIHtcbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgIH1cbiAgICAgIC8vIExldmVyYWdlIHRoZSBleHBvbmVudGlhdGlvbiBieSBzcXVhcmluZyBhbGdvcml0aG0gZm9yIGEgZmFzdGVyIHJlcGVhdC5cbiAgICAgIC8vIFNlZSBodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9FeHBvbmVudGlhdGlvbl9ieV9zcXVhcmluZyBmb3IgbW9yZSBkZXRhaWxzLlxuICAgICAgZG8ge1xuICAgICAgICBpZiAobiAlIDIpIHtcbiAgICAgICAgICByZXN1bHQgKz0gc3RyaW5nO1xuICAgICAgICB9XG4gICAgICAgIG4gPSBuYXRpdmVGbG9vcihuIC8gMik7XG4gICAgICAgIGlmIChuKSB7XG4gICAgICAgICAgc3RyaW5nICs9IHN0cmluZztcbiAgICAgICAgfVxuICAgICAgfSB3aGlsZSAobik7XG5cbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8ucmVzdGAgd2hpY2ggZG9lc24ndCB2YWxpZGF0ZSBvciBjb2VyY2UgYXJndW1lbnRzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byBhcHBseSBhIHJlc3QgcGFyYW1ldGVyIHRvLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbc3RhcnQ9ZnVuYy5sZW5ndGgtMV0gVGhlIHN0YXJ0IHBvc2l0aW9uIG9mIHRoZSByZXN0IHBhcmFtZXRlci5cbiAgICAgKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBmdW5jdGlvbi5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBiYXNlUmVzdChmdW5jLCBzdGFydCkge1xuICAgICAgcmV0dXJuIHNldFRvU3RyaW5nKG92ZXJSZXN0KGZ1bmMsIHN0YXJ0LCBpZGVudGl0eSksIGZ1bmMgKyAnJyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uc2FtcGxlYC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtBcnJheXxPYmplY3R9IGNvbGxlY3Rpb24gVGhlIGNvbGxlY3Rpb24gdG8gc2FtcGxlLlxuICAgICAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSByYW5kb20gZWxlbWVudC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBiYXNlU2FtcGxlKGNvbGxlY3Rpb24pIHtcbiAgICAgIHJldHVybiBhcnJheVNhbXBsZSh2YWx1ZXMoY29sbGVjdGlvbikpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLnNhbXBsZVNpemVgIHdpdGhvdXQgcGFyYW0gZ3VhcmRzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0FycmF5fE9iamVjdH0gY29sbGVjdGlvbiBUaGUgY29sbGVjdGlvbiB0byBzYW1wbGUuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IG4gVGhlIG51bWJlciBvZiBlbGVtZW50cyB0byBzYW1wbGUuXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSByYW5kb20gZWxlbWVudHMuXG4gICAgICovXG4gICAgZnVuY3Rpb24gYmFzZVNhbXBsZVNpemUoY29sbGVjdGlvbiwgbikge1xuICAgICAgdmFyIGFycmF5ID0gdmFsdWVzKGNvbGxlY3Rpb24pO1xuICAgICAgcmV0dXJuIHNodWZmbGVTZWxmKGFycmF5LCBiYXNlQ2xhbXAobiwgMCwgYXJyYXkubGVuZ3RoKSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uc2V0YC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIG1vZGlmeS5cbiAgICAgKiBAcGFyYW0ge0FycmF5fHN0cmluZ30gcGF0aCBUaGUgcGF0aCBvZiB0aGUgcHJvcGVydHkgdG8gc2V0LlxuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIHNldC5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbY3VzdG9taXplcl0gVGhlIGZ1bmN0aW9uIHRvIGN1c3RvbWl6ZSBwYXRoIGNyZWF0aW9uLlxuICAgICAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgYG9iamVjdGAuXG4gICAgICovXG4gICAgZnVuY3Rpb24gYmFzZVNldChvYmplY3QsIHBhdGgsIHZhbHVlLCBjdXN0b21pemVyKSB7XG4gICAgICBpZiAoIWlzT2JqZWN0KG9iamVjdCkpIHtcbiAgICAgICAgcmV0dXJuIG9iamVjdDtcbiAgICAgIH1cbiAgICAgIHBhdGggPSBjYXN0UGF0aChwYXRoLCBvYmplY3QpO1xuXG4gICAgICB2YXIgaW5kZXggPSAtMSxcbiAgICAgICAgICBsZW5ndGggPSBwYXRoLmxlbmd0aCxcbiAgICAgICAgICBsYXN0SW5kZXggPSBsZW5ndGggLSAxLFxuICAgICAgICAgIG5lc3RlZCA9IG9iamVjdDtcblxuICAgICAgd2hpbGUgKG5lc3RlZCAhPSBudWxsICYmICsraW5kZXggPCBsZW5ndGgpIHtcbiAgICAgICAgdmFyIGtleSA9IHRvS2V5KHBhdGhbaW5kZXhdKSxcbiAgICAgICAgICAgIG5ld1ZhbHVlID0gdmFsdWU7XG5cbiAgICAgICAgaWYgKGtleSA9PT0gJ19fcHJvdG9fXycgfHwga2V5ID09PSAnY29uc3RydWN0b3InIHx8IGtleSA9PT0gJ3Byb3RvdHlwZScpIHtcbiAgICAgICAgICByZXR1cm4gb2JqZWN0O1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGluZGV4ICE9IGxhc3RJbmRleCkge1xuICAgICAgICAgIHZhciBvYmpWYWx1ZSA9IG5lc3RlZFtrZXldO1xuICAgICAgICAgIG5ld1ZhbHVlID0gY3VzdG9taXplciA/IGN1c3RvbWl6ZXIob2JqVmFsdWUsIGtleSwgbmVzdGVkKSA6IHVuZGVmaW5lZDtcbiAgICAgICAgICBpZiAobmV3VmFsdWUgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgbmV3VmFsdWUgPSBpc09iamVjdChvYmpWYWx1ZSlcbiAgICAgICAgICAgICAgPyBvYmpWYWx1ZVxuICAgICAgICAgICAgICA6IChpc0luZGV4KHBhdGhbaW5kZXggKyAxXSkgPyBbXSA6IHt9KTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgYXNzaWduVmFsdWUobmVzdGVkLCBrZXksIG5ld1ZhbHVlKTtcbiAgICAgICAgbmVzdGVkID0gbmVzdGVkW2tleV07XG4gICAgICB9XG4gICAgICByZXR1cm4gb2JqZWN0O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBzZXREYXRhYCB3aXRob3V0IHN1cHBvcnQgZm9yIGhvdCBsb29wIHNob3J0aW5nLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byBhc3NvY2lhdGUgbWV0YWRhdGEgd2l0aC5cbiAgICAgKiBAcGFyYW0geyp9IGRhdGEgVGhlIG1ldGFkYXRhLlxuICAgICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyBgZnVuY2AuXG4gICAgICovXG4gICAgdmFyIGJhc2VTZXREYXRhID0gIW1ldGFNYXAgPyBpZGVudGl0eSA6IGZ1bmN0aW9uKGZ1bmMsIGRhdGEpIHtcbiAgICAgIG1ldGFNYXAuc2V0KGZ1bmMsIGRhdGEpO1xuICAgICAgcmV0dXJuIGZ1bmM7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBzZXRUb1N0cmluZ2Agd2l0aG91dCBzdXBwb3J0IGZvciBob3QgbG9vcCBzaG9ydGluZy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gZnVuYyBUaGUgZnVuY3Rpb24gdG8gbW9kaWZ5LlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IHN0cmluZyBUaGUgYHRvU3RyaW5nYCByZXN1bHQuXG4gICAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIGBmdW5jYC5cbiAgICAgKi9cbiAgICB2YXIgYmFzZVNldFRvU3RyaW5nID0gIWRlZmluZVByb3BlcnR5ID8gaWRlbnRpdHkgOiBmdW5jdGlvbihmdW5jLCBzdHJpbmcpIHtcbiAgICAgIHJldHVybiBkZWZpbmVQcm9wZXJ0eShmdW5jLCAndG9TdHJpbmcnLCB7XG4gICAgICAgICdjb25maWd1cmFibGUnOiB0cnVlLFxuICAgICAgICAnZW51bWVyYWJsZSc6IGZhbHNlLFxuICAgICAgICAndmFsdWUnOiBjb25zdGFudChzdHJpbmcpLFxuICAgICAgICAnd3JpdGFibGUnOiB0cnVlXG4gICAgICB9KTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uc2h1ZmZsZWAuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7QXJyYXl8T2JqZWN0fSBjb2xsZWN0aW9uIFRoZSBjb2xsZWN0aW9uIHRvIHNodWZmbGUuXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBuZXcgc2h1ZmZsZWQgYXJyYXkuXG4gICAgICovXG4gICAgZnVuY3Rpb24gYmFzZVNodWZmbGUoY29sbGVjdGlvbikge1xuICAgICAgcmV0dXJuIHNodWZmbGVTZWxmKHZhbHVlcyhjb2xsZWN0aW9uKSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uc2xpY2VgIHdpdGhvdXQgYW4gaXRlcmF0ZWUgY2FsbCBndWFyZC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIHNsaWNlLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbc3RhcnQ9MF0gVGhlIHN0YXJ0IHBvc2l0aW9uLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbZW5kPWFycmF5Lmxlbmd0aF0gVGhlIGVuZCBwb3NpdGlvbi5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIHNsaWNlIG9mIGBhcnJheWAuXG4gICAgICovXG4gICAgZnVuY3Rpb24gYmFzZVNsaWNlKGFycmF5LCBzdGFydCwgZW5kKSB7XG4gICAgICB2YXIgaW5kZXggPSAtMSxcbiAgICAgICAgICBsZW5ndGggPSBhcnJheS5sZW5ndGg7XG5cbiAgICAgIGlmIChzdGFydCA8IDApIHtcbiAgICAgICAgc3RhcnQgPSAtc3RhcnQgPiBsZW5ndGggPyAwIDogKGxlbmd0aCArIHN0YXJ0KTtcbiAgICAgIH1cbiAgICAgIGVuZCA9IGVuZCA+IGxlbmd0aCA/IGxlbmd0aCA6IGVuZDtcbiAgICAgIGlmIChlbmQgPCAwKSB7XG4gICAgICAgIGVuZCArPSBsZW5ndGg7XG4gICAgICB9XG4gICAgICBsZW5ndGggPSBzdGFydCA+IGVuZCA/IDAgOiAoKGVuZCAtIHN0YXJ0KSA+Pj4gMCk7XG4gICAgICBzdGFydCA+Pj49IDA7XG5cbiAgICAgIHZhciByZXN1bHQgPSBBcnJheShsZW5ndGgpO1xuICAgICAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHtcbiAgICAgICAgcmVzdWx0W2luZGV4XSA9IGFycmF5W2luZGV4ICsgc3RhcnRdO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5zb21lYCB3aXRob3V0IHN1cHBvcnQgZm9yIGl0ZXJhdGVlIHNob3J0aGFuZHMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7QXJyYXl8T2JqZWN0fSBjb2xsZWN0aW9uIFRoZSBjb2xsZWN0aW9uIHRvIGl0ZXJhdGUgb3Zlci5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBwcmVkaWNhdGUgVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIGl0ZXJhdGlvbi5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYW55IGVsZW1lbnQgcGFzc2VzIHRoZSBwcmVkaWNhdGUgY2hlY2ssXG4gICAgICogIGVsc2UgYGZhbHNlYC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBiYXNlU29tZShjb2xsZWN0aW9uLCBwcmVkaWNhdGUpIHtcbiAgICAgIHZhciByZXN1bHQ7XG5cbiAgICAgIGJhc2VFYWNoKGNvbGxlY3Rpb24sIGZ1bmN0aW9uKHZhbHVlLCBpbmRleCwgY29sbGVjdGlvbikge1xuICAgICAgICByZXN1bHQgPSBwcmVkaWNhdGUodmFsdWUsIGluZGV4LCBjb2xsZWN0aW9uKTtcbiAgICAgICAgcmV0dXJuICFyZXN1bHQ7XG4gICAgICB9KTtcbiAgICAgIHJldHVybiAhIXJlc3VsdDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5zb3J0ZWRJbmRleGAgYW5kIGBfLnNvcnRlZExhc3RJbmRleGAgd2hpY2hcbiAgICAgKiBwZXJmb3JtcyBhIGJpbmFyeSBzZWFyY2ggb2YgYGFycmF5YCB0byBkZXRlcm1pbmUgdGhlIGluZGV4IGF0IHdoaWNoIGB2YWx1ZWBcbiAgICAgKiBzaG91bGQgYmUgaW5zZXJ0ZWQgaW50byBgYXJyYXlgIGluIG9yZGVyIHRvIG1haW50YWluIGl0cyBzb3J0IG9yZGVyLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgc29ydGVkIGFycmF5IHRvIGluc3BlY3QuXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gZXZhbHVhdGUuXG4gICAgICogQHBhcmFtIHtib29sZWFufSBbcmV0SGlnaGVzdF0gU3BlY2lmeSByZXR1cm5pbmcgdGhlIGhpZ2hlc3QgcXVhbGlmaWVkIGluZGV4LlxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9IFJldHVybnMgdGhlIGluZGV4IGF0IHdoaWNoIGB2YWx1ZWAgc2hvdWxkIGJlIGluc2VydGVkXG4gICAgICogIGludG8gYGFycmF5YC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBiYXNlU29ydGVkSW5kZXgoYXJyYXksIHZhbHVlLCByZXRIaWdoZXN0KSB7XG4gICAgICB2YXIgbG93ID0gMCxcbiAgICAgICAgICBoaWdoID0gYXJyYXkgPT0gbnVsbCA/IGxvdyA6IGFycmF5Lmxlbmd0aDtcblxuICAgICAgaWYgKHR5cGVvZiB2YWx1ZSA9PSAnbnVtYmVyJyAmJiB2YWx1ZSA9PT0gdmFsdWUgJiYgaGlnaCA8PSBIQUxGX01BWF9BUlJBWV9MRU5HVEgpIHtcbiAgICAgICAgd2hpbGUgKGxvdyA8IGhpZ2gpIHtcbiAgICAgICAgICB2YXIgbWlkID0gKGxvdyArIGhpZ2gpID4+PiAxLFxuICAgICAgICAgICAgICBjb21wdXRlZCA9IGFycmF5W21pZF07XG5cbiAgICAgICAgICBpZiAoY29tcHV0ZWQgIT09IG51bGwgJiYgIWlzU3ltYm9sKGNvbXB1dGVkKSAmJlxuICAgICAgICAgICAgICAocmV0SGlnaGVzdCA/IChjb21wdXRlZCA8PSB2YWx1ZSkgOiAoY29tcHV0ZWQgPCB2YWx1ZSkpKSB7XG4gICAgICAgICAgICBsb3cgPSBtaWQgKyAxO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBoaWdoID0gbWlkO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gaGlnaDtcbiAgICAgIH1cbiAgICAgIHJldHVybiBiYXNlU29ydGVkSW5kZXhCeShhcnJheSwgdmFsdWUsIGlkZW50aXR5LCByZXRIaWdoZXN0KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5zb3J0ZWRJbmRleEJ5YCBhbmQgYF8uc29ydGVkTGFzdEluZGV4QnlgXG4gICAgICogd2hpY2ggaW52b2tlcyBgaXRlcmF0ZWVgIGZvciBgdmFsdWVgIGFuZCBlYWNoIGVsZW1lbnQgb2YgYGFycmF5YCB0byBjb21wdXRlXG4gICAgICogdGhlaXIgc29ydCByYW5raW5nLiBUaGUgaXRlcmF0ZWUgaXMgaW52b2tlZCB3aXRoIG9uZSBhcmd1bWVudDsgKHZhbHVlKS5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIHNvcnRlZCBhcnJheSB0byBpbnNwZWN0LlxuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGV2YWx1YXRlLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGl0ZXJhdGVlIFRoZSBpdGVyYXRlZSBpbnZva2VkIHBlciBlbGVtZW50LlxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbn0gW3JldEhpZ2hlc3RdIFNwZWNpZnkgcmV0dXJuaW5nIHRoZSBoaWdoZXN0IHF1YWxpZmllZCBpbmRleC5cbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBSZXR1cm5zIHRoZSBpbmRleCBhdCB3aGljaCBgdmFsdWVgIHNob3VsZCBiZSBpbnNlcnRlZFxuICAgICAqICBpbnRvIGBhcnJheWAuXG4gICAgICovXG4gICAgZnVuY3Rpb24gYmFzZVNvcnRlZEluZGV4QnkoYXJyYXksIHZhbHVlLCBpdGVyYXRlZSwgcmV0SGlnaGVzdCkge1xuICAgICAgdmFyIGxvdyA9IDAsXG4gICAgICAgICAgaGlnaCA9IGFycmF5ID09IG51bGwgPyAwIDogYXJyYXkubGVuZ3RoO1xuICAgICAgaWYgKGhpZ2ggPT09IDApIHtcbiAgICAgICAgcmV0dXJuIDA7XG4gICAgICB9XG5cbiAgICAgIHZhbHVlID0gaXRlcmF0ZWUodmFsdWUpO1xuICAgICAgdmFyIHZhbElzTmFOID0gdmFsdWUgIT09IHZhbHVlLFxuICAgICAgICAgIHZhbElzTnVsbCA9IHZhbHVlID09PSBudWxsLFxuICAgICAgICAgIHZhbElzU3ltYm9sID0gaXNTeW1ib2wodmFsdWUpLFxuICAgICAgICAgIHZhbElzVW5kZWZpbmVkID0gdmFsdWUgPT09IHVuZGVmaW5lZDtcblxuICAgICAgd2hpbGUgKGxvdyA8IGhpZ2gpIHtcbiAgICAgICAgdmFyIG1pZCA9IG5hdGl2ZUZsb29yKChsb3cgKyBoaWdoKSAvIDIpLFxuICAgICAgICAgICAgY29tcHV0ZWQgPSBpdGVyYXRlZShhcnJheVttaWRdKSxcbiAgICAgICAgICAgIG90aElzRGVmaW5lZCA9IGNvbXB1dGVkICE9PSB1bmRlZmluZWQsXG4gICAgICAgICAgICBvdGhJc051bGwgPSBjb21wdXRlZCA9PT0gbnVsbCxcbiAgICAgICAgICAgIG90aElzUmVmbGV4aXZlID0gY29tcHV0ZWQgPT09IGNvbXB1dGVkLFxuICAgICAgICAgICAgb3RoSXNTeW1ib2wgPSBpc1N5bWJvbChjb21wdXRlZCk7XG5cbiAgICAgICAgaWYgKHZhbElzTmFOKSB7XG4gICAgICAgICAgdmFyIHNldExvdyA9IHJldEhpZ2hlc3QgfHwgb3RoSXNSZWZsZXhpdmU7XG4gICAgICAgIH0gZWxzZSBpZiAodmFsSXNVbmRlZmluZWQpIHtcbiAgICAgICAgICBzZXRMb3cgPSBvdGhJc1JlZmxleGl2ZSAmJiAocmV0SGlnaGVzdCB8fCBvdGhJc0RlZmluZWQpO1xuICAgICAgICB9IGVsc2UgaWYgKHZhbElzTnVsbCkge1xuICAgICAgICAgIHNldExvdyA9IG90aElzUmVmbGV4aXZlICYmIG90aElzRGVmaW5lZCAmJiAocmV0SGlnaGVzdCB8fCAhb3RoSXNOdWxsKTtcbiAgICAgICAgfSBlbHNlIGlmICh2YWxJc1N5bWJvbCkge1xuICAgICAgICAgIHNldExvdyA9IG90aElzUmVmbGV4aXZlICYmIG90aElzRGVmaW5lZCAmJiAhb3RoSXNOdWxsICYmIChyZXRIaWdoZXN0IHx8ICFvdGhJc1N5bWJvbCk7XG4gICAgICAgIH0gZWxzZSBpZiAob3RoSXNOdWxsIHx8IG90aElzU3ltYm9sKSB7XG4gICAgICAgICAgc2V0TG93ID0gZmFsc2U7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgc2V0TG93ID0gcmV0SGlnaGVzdCA/IChjb21wdXRlZCA8PSB2YWx1ZSkgOiAoY29tcHV0ZWQgPCB2YWx1ZSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHNldExvdykge1xuICAgICAgICAgIGxvdyA9IG1pZCArIDE7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgaGlnaCA9IG1pZDtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIG5hdGl2ZU1pbihoaWdoLCBNQVhfQVJSQVlfSU5ERVgpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLnNvcnRlZFVuaXFgIGFuZCBgXy5zb3J0ZWRVbmlxQnlgIHdpdGhvdXRcbiAgICAgKiBzdXBwb3J0IGZvciBpdGVyYXRlZSBzaG9ydGhhbmRzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gaW5zcGVjdC5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbaXRlcmF0ZWVdIFRoZSBpdGVyYXRlZSBpbnZva2VkIHBlciBlbGVtZW50LlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IGR1cGxpY2F0ZSBmcmVlIGFycmF5LlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGJhc2VTb3J0ZWRVbmlxKGFycmF5LCBpdGVyYXRlZSkge1xuICAgICAgdmFyIGluZGV4ID0gLTEsXG4gICAgICAgICAgbGVuZ3RoID0gYXJyYXkubGVuZ3RoLFxuICAgICAgICAgIHJlc0luZGV4ID0gMCxcbiAgICAgICAgICByZXN1bHQgPSBbXTtcblxuICAgICAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHtcbiAgICAgICAgdmFyIHZhbHVlID0gYXJyYXlbaW5kZXhdLFxuICAgICAgICAgICAgY29tcHV0ZWQgPSBpdGVyYXRlZSA/IGl0ZXJhdGVlKHZhbHVlKSA6IHZhbHVlO1xuXG4gICAgICAgIGlmICghaW5kZXggfHwgIWVxKGNvbXB1dGVkLCBzZWVuKSkge1xuICAgICAgICAgIHZhciBzZWVuID0gY29tcHV0ZWQ7XG4gICAgICAgICAgcmVzdWx0W3Jlc0luZGV4KytdID0gdmFsdWUgPT09IDAgPyAwIDogdmFsdWU7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8udG9OdW1iZXJgIHdoaWNoIGRvZXNuJ3QgZW5zdXJlIGNvcnJlY3RcbiAgICAgKiBjb252ZXJzaW9ucyBvZiBiaW5hcnksIGhleGFkZWNpbWFsLCBvciBvY3RhbCBzdHJpbmcgdmFsdWVzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBwcm9jZXNzLlxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9IFJldHVybnMgdGhlIG51bWJlci5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBiYXNlVG9OdW1iZXIodmFsdWUpIHtcbiAgICAgIGlmICh0eXBlb2YgdmFsdWUgPT0gJ251bWJlcicpIHtcbiAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgICAgfVxuICAgICAgaWYgKGlzU3ltYm9sKHZhbHVlKSkge1xuICAgICAgICByZXR1cm4gTkFOO1xuICAgICAgfVxuICAgICAgcmV0dXJuICt2YWx1ZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy50b1N0cmluZ2Agd2hpY2ggZG9lc24ndCBjb252ZXJ0IG51bGxpc2hcbiAgICAgKiB2YWx1ZXMgdG8gZW1wdHkgc3RyaW5ncy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gcHJvY2Vzcy5cbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfSBSZXR1cm5zIHRoZSBzdHJpbmcuXG4gICAgICovXG4gICAgZnVuY3Rpb24gYmFzZVRvU3RyaW5nKHZhbHVlKSB7XG4gICAgICAvLyBFeGl0IGVhcmx5IGZvciBzdHJpbmdzIHRvIGF2b2lkIGEgcGVyZm9ybWFuY2UgaGl0IGluIHNvbWUgZW52aXJvbm1lbnRzLlxuICAgICAgaWYgKHR5cGVvZiB2YWx1ZSA9PSAnc3RyaW5nJykge1xuICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgICB9XG4gICAgICBpZiAoaXNBcnJheSh2YWx1ZSkpIHtcbiAgICAgICAgLy8gUmVjdXJzaXZlbHkgY29udmVydCB2YWx1ZXMgKHN1c2NlcHRpYmxlIHRvIGNhbGwgc3RhY2sgbGltaXRzKS5cbiAgICAgICAgcmV0dXJuIGFycmF5TWFwKHZhbHVlLCBiYXNlVG9TdHJpbmcpICsgJyc7XG4gICAgICB9XG4gICAgICBpZiAoaXNTeW1ib2wodmFsdWUpKSB7XG4gICAgICAgIHJldHVybiBzeW1ib2xUb1N0cmluZyA/IHN5bWJvbFRvU3RyaW5nLmNhbGwodmFsdWUpIDogJyc7XG4gICAgICB9XG4gICAgICB2YXIgcmVzdWx0ID0gKHZhbHVlICsgJycpO1xuICAgICAgcmV0dXJuIChyZXN1bHQgPT0gJzAnICYmICgxIC8gdmFsdWUpID09IC1JTkZJTklUWSkgPyAnLTAnIDogcmVzdWx0O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLnVuaXFCeWAgd2l0aG91dCBzdXBwb3J0IGZvciBpdGVyYXRlZSBzaG9ydGhhbmRzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gaW5zcGVjdC5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbaXRlcmF0ZWVdIFRoZSBpdGVyYXRlZSBpbnZva2VkIHBlciBlbGVtZW50LlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IFtjb21wYXJhdG9yXSBUaGUgY29tcGFyYXRvciBpbnZva2VkIHBlciBlbGVtZW50LlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IGR1cGxpY2F0ZSBmcmVlIGFycmF5LlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGJhc2VVbmlxKGFycmF5LCBpdGVyYXRlZSwgY29tcGFyYXRvcikge1xuICAgICAgdmFyIGluZGV4ID0gLTEsXG4gICAgICAgICAgaW5jbHVkZXMgPSBhcnJheUluY2x1ZGVzLFxuICAgICAgICAgIGxlbmd0aCA9IGFycmF5Lmxlbmd0aCxcbiAgICAgICAgICBpc0NvbW1vbiA9IHRydWUsXG4gICAgICAgICAgcmVzdWx0ID0gW10sXG4gICAgICAgICAgc2VlbiA9IHJlc3VsdDtcblxuICAgICAgaWYgKGNvbXBhcmF0b3IpIHtcbiAgICAgICAgaXNDb21tb24gPSBmYWxzZTtcbiAgICAgICAgaW5jbHVkZXMgPSBhcnJheUluY2x1ZGVzV2l0aDtcbiAgICAgIH1cbiAgICAgIGVsc2UgaWYgKGxlbmd0aCA+PSBMQVJHRV9BUlJBWV9TSVpFKSB7XG4gICAgICAgIHZhciBzZXQgPSBpdGVyYXRlZSA/IG51bGwgOiBjcmVhdGVTZXQoYXJyYXkpO1xuICAgICAgICBpZiAoc2V0KSB7XG4gICAgICAgICAgcmV0dXJuIHNldFRvQXJyYXkoc2V0KTtcbiAgICAgICAgfVxuICAgICAgICBpc0NvbW1vbiA9IGZhbHNlO1xuICAgICAgICBpbmNsdWRlcyA9IGNhY2hlSGFzO1xuICAgICAgICBzZWVuID0gbmV3IFNldENhY2hlO1xuICAgICAgfVxuICAgICAgZWxzZSB7XG4gICAgICAgIHNlZW4gPSBpdGVyYXRlZSA/IFtdIDogcmVzdWx0O1xuICAgICAgfVxuICAgICAgb3V0ZXI6XG4gICAgICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgICAgICB2YXIgdmFsdWUgPSBhcnJheVtpbmRleF0sXG4gICAgICAgICAgICBjb21wdXRlZCA9IGl0ZXJhdGVlID8gaXRlcmF0ZWUodmFsdWUpIDogdmFsdWU7XG5cbiAgICAgICAgdmFsdWUgPSAoY29tcGFyYXRvciB8fCB2YWx1ZSAhPT0gMCkgPyB2YWx1ZSA6IDA7XG4gICAgICAgIGlmIChpc0NvbW1vbiAmJiBjb21wdXRlZCA9PT0gY29tcHV0ZWQpIHtcbiAgICAgICAgICB2YXIgc2VlbkluZGV4ID0gc2Vlbi5sZW5ndGg7XG4gICAgICAgICAgd2hpbGUgKHNlZW5JbmRleC0tKSB7XG4gICAgICAgICAgICBpZiAoc2VlbltzZWVuSW5kZXhdID09PSBjb21wdXRlZCkge1xuICAgICAgICAgICAgICBjb250aW51ZSBvdXRlcjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKGl0ZXJhdGVlKSB7XG4gICAgICAgICAgICBzZWVuLnB1c2goY29tcHV0ZWQpO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXN1bHQucHVzaCh2YWx1ZSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoIWluY2x1ZGVzKHNlZW4sIGNvbXB1dGVkLCBjb21wYXJhdG9yKSkge1xuICAgICAgICAgIGlmIChzZWVuICE9PSByZXN1bHQpIHtcbiAgICAgICAgICAgIHNlZW4ucHVzaChjb21wdXRlZCk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJlc3VsdC5wdXNoKHZhbHVlKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy51bnNldGAuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBtb2RpZnkuXG4gICAgICogQHBhcmFtIHtBcnJheXxzdHJpbmd9IHBhdGggVGhlIHByb3BlcnR5IHBhdGggdG8gdW5zZXQuXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIHRoZSBwcm9wZXJ0eSBpcyBkZWxldGVkLCBlbHNlIGBmYWxzZWAuXG4gICAgICovXG4gICAgZnVuY3Rpb24gYmFzZVVuc2V0KG9iamVjdCwgcGF0aCkge1xuICAgICAgcGF0aCA9IGNhc3RQYXRoKHBhdGgsIG9iamVjdCk7XG4gICAgICBvYmplY3QgPSBwYXJlbnQob2JqZWN0LCBwYXRoKTtcbiAgICAgIHJldHVybiBvYmplY3QgPT0gbnVsbCB8fCBkZWxldGUgb2JqZWN0W3RvS2V5KGxhc3QocGF0aCkpXTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy51cGRhdGVgLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gbW9kaWZ5LlxuICAgICAqIEBwYXJhbSB7QXJyYXl8c3RyaW5nfSBwYXRoIFRoZSBwYXRoIG9mIHRoZSBwcm9wZXJ0eSB0byB1cGRhdGUuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gdXBkYXRlciBUaGUgZnVuY3Rpb24gdG8gcHJvZHVjZSB0aGUgdXBkYXRlZCB2YWx1ZS5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbY3VzdG9taXplcl0gVGhlIGZ1bmN0aW9uIHRvIGN1c3RvbWl6ZSBwYXRoIGNyZWF0aW9uLlxuICAgICAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgYG9iamVjdGAuXG4gICAgICovXG4gICAgZnVuY3Rpb24gYmFzZVVwZGF0ZShvYmplY3QsIHBhdGgsIHVwZGF0ZXIsIGN1c3RvbWl6ZXIpIHtcbiAgICAgIHJldHVybiBiYXNlU2V0KG9iamVjdCwgcGF0aCwgdXBkYXRlcihiYXNlR2V0KG9iamVjdCwgcGF0aCkpLCBjdXN0b21pemVyKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBtZXRob2RzIGxpa2UgYF8uZHJvcFdoaWxlYCBhbmQgYF8udGFrZVdoaWxlYFxuICAgICAqIHdpdGhvdXQgc3VwcG9ydCBmb3IgaXRlcmF0ZWUgc2hvcnRoYW5kcy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIHF1ZXJ5LlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IHByZWRpY2F0ZSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbn0gW2lzRHJvcF0gU3BlY2lmeSBkcm9wcGluZyBlbGVtZW50cyBpbnN0ZWFkIG9mIHRha2luZyB0aGVtLlxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbn0gW2Zyb21SaWdodF0gU3BlY2lmeSBpdGVyYXRpbmcgZnJvbSByaWdodCB0byBsZWZ0LlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgc2xpY2Ugb2YgYGFycmF5YC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBiYXNlV2hpbGUoYXJyYXksIHByZWRpY2F0ZSwgaXNEcm9wLCBmcm9tUmlnaHQpIHtcbiAgICAgIHZhciBsZW5ndGggPSBhcnJheS5sZW5ndGgsXG4gICAgICAgICAgaW5kZXggPSBmcm9tUmlnaHQgPyBsZW5ndGggOiAtMTtcblxuICAgICAgd2hpbGUgKChmcm9tUmlnaHQgPyBpbmRleC0tIDogKytpbmRleCA8IGxlbmd0aCkgJiZcbiAgICAgICAgcHJlZGljYXRlKGFycmF5W2luZGV4XSwgaW5kZXgsIGFycmF5KSkge31cblxuICAgICAgcmV0dXJuIGlzRHJvcFxuICAgICAgICA/IGJhc2VTbGljZShhcnJheSwgKGZyb21SaWdodCA/IDAgOiBpbmRleCksIChmcm9tUmlnaHQgPyBpbmRleCArIDEgOiBsZW5ndGgpKVxuICAgICAgICA6IGJhc2VTbGljZShhcnJheSwgKGZyb21SaWdodCA/IGluZGV4ICsgMSA6IDApLCAoZnJvbVJpZ2h0ID8gbGVuZ3RoIDogaW5kZXgpKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgd3JhcHBlclZhbHVlYCB3aGljaCByZXR1cm5zIHRoZSByZXN1bHQgb2ZcbiAgICAgKiBwZXJmb3JtaW5nIGEgc2VxdWVuY2Ugb2YgYWN0aW9ucyBvbiB0aGUgdW53cmFwcGVkIGB2YWx1ZWAsIHdoZXJlIGVhY2hcbiAgICAgKiBzdWNjZXNzaXZlIGFjdGlvbiBpcyBzdXBwbGllZCB0aGUgcmV0dXJuIHZhbHVlIG9mIHRoZSBwcmV2aW91cy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdW53cmFwcGVkIHZhbHVlLlxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGFjdGlvbnMgQWN0aW9ucyB0byBwZXJmb3JtIHRvIHJlc29sdmUgdGhlIHVud3JhcHBlZCB2YWx1ZS5cbiAgICAgKiBAcmV0dXJucyB7Kn0gUmV0dXJucyB0aGUgcmVzb2x2ZWQgdmFsdWUuXG4gICAgICovXG4gICAgZnVuY3Rpb24gYmFzZVdyYXBwZXJWYWx1ZSh2YWx1ZSwgYWN0aW9ucykge1xuICAgICAgdmFyIHJlc3VsdCA9IHZhbHVlO1xuICAgICAgaWYgKHJlc3VsdCBpbnN0YW5jZW9mIExhenlXcmFwcGVyKSB7XG4gICAgICAgIHJlc3VsdCA9IHJlc3VsdC52YWx1ZSgpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGFycmF5UmVkdWNlKGFjdGlvbnMsIGZ1bmN0aW9uKHJlc3VsdCwgYWN0aW9uKSB7XG4gICAgICAgIHJldHVybiBhY3Rpb24uZnVuYy5hcHBseShhY3Rpb24udGhpc0FyZywgYXJyYXlQdXNoKFtyZXN1bHRdLCBhY3Rpb24uYXJncykpO1xuICAgICAgfSwgcmVzdWx0KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBtZXRob2RzIGxpa2UgYF8ueG9yYCwgd2l0aG91dCBzdXBwb3J0IGZvclxuICAgICAqIGl0ZXJhdGVlIHNob3J0aGFuZHMsIHRoYXQgYWNjZXB0cyBhbiBhcnJheSBvZiBhcnJheXMgdG8gaW5zcGVjdC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtBcnJheX0gYXJyYXlzIFRoZSBhcnJheXMgdG8gaW5zcGVjdC5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbaXRlcmF0ZWVdIFRoZSBpdGVyYXRlZSBpbnZva2VkIHBlciBlbGVtZW50LlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IFtjb21wYXJhdG9yXSBUaGUgY29tcGFyYXRvciBpbnZva2VkIHBlciBlbGVtZW50LlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IGFycmF5IG9mIHZhbHVlcy5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBiYXNlWG9yKGFycmF5cywgaXRlcmF0ZWUsIGNvbXBhcmF0b3IpIHtcbiAgICAgIHZhciBsZW5ndGggPSBhcnJheXMubGVuZ3RoO1xuICAgICAgaWYgKGxlbmd0aCA8IDIpIHtcbiAgICAgICAgcmV0dXJuIGxlbmd0aCA/IGJhc2VVbmlxKGFycmF5c1swXSkgOiBbXTtcbiAgICAgIH1cbiAgICAgIHZhciBpbmRleCA9IC0xLFxuICAgICAgICAgIHJlc3VsdCA9IEFycmF5KGxlbmd0aCk7XG5cbiAgICAgIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XG4gICAgICAgIHZhciBhcnJheSA9IGFycmF5c1tpbmRleF0sXG4gICAgICAgICAgICBvdGhJbmRleCA9IC0xO1xuXG4gICAgICAgIHdoaWxlICgrK290aEluZGV4IDwgbGVuZ3RoKSB7XG4gICAgICAgICAgaWYgKG90aEluZGV4ICE9IGluZGV4KSB7XG4gICAgICAgICAgICByZXN1bHRbaW5kZXhdID0gYmFzZURpZmZlcmVuY2UocmVzdWx0W2luZGV4XSB8fCBhcnJheSwgYXJyYXlzW290aEluZGV4XSwgaXRlcmF0ZWUsIGNvbXBhcmF0b3IpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIGJhc2VVbmlxKGJhc2VGbGF0dGVuKHJlc3VsdCwgMSksIGl0ZXJhdGVlLCBjb21wYXJhdG9yKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uemlwT2JqZWN0YCB3aGljaCBhc3NpZ25zIHZhbHVlcyB1c2luZyBgYXNzaWduRnVuY2AuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IHByb3BzIFRoZSBwcm9wZXJ0eSBpZGVudGlmaWVycy5cbiAgICAgKiBAcGFyYW0ge0FycmF5fSB2YWx1ZXMgVGhlIHByb3BlcnR5IHZhbHVlcy5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBhc3NpZ25GdW5jIFRoZSBmdW5jdGlvbiB0byBhc3NpZ24gdmFsdWVzLlxuICAgICAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgdGhlIG5ldyBvYmplY3QuXG4gICAgICovXG4gICAgZnVuY3Rpb24gYmFzZVppcE9iamVjdChwcm9wcywgdmFsdWVzLCBhc3NpZ25GdW5jKSB7XG4gICAgICB2YXIgaW5kZXggPSAtMSxcbiAgICAgICAgICBsZW5ndGggPSBwcm9wcy5sZW5ndGgsXG4gICAgICAgICAgdmFsc0xlbmd0aCA9IHZhbHVlcy5sZW5ndGgsXG4gICAgICAgICAgcmVzdWx0ID0ge307XG5cbiAgICAgIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XG4gICAgICAgIHZhciB2YWx1ZSA9IGluZGV4IDwgdmFsc0xlbmd0aCA/IHZhbHVlc1tpbmRleF0gOiB1bmRlZmluZWQ7XG4gICAgICAgIGFzc2lnbkZ1bmMocmVzdWx0LCBwcm9wc1tpbmRleF0sIHZhbHVlKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2FzdHMgYHZhbHVlYCB0byBhbiBlbXB0eSBhcnJheSBpZiBpdCdzIG5vdCBhbiBhcnJheSBsaWtlIG9iamVjdC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gaW5zcGVjdC5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl8T2JqZWN0fSBSZXR1cm5zIHRoZSBjYXN0IGFycmF5LWxpa2Ugb2JqZWN0LlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGNhc3RBcnJheUxpa2VPYmplY3QodmFsdWUpIHtcbiAgICAgIHJldHVybiBpc0FycmF5TGlrZU9iamVjdCh2YWx1ZSkgPyB2YWx1ZSA6IFtdO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENhc3RzIGB2YWx1ZWAgdG8gYGlkZW50aXR5YCBpZiBpdCdzIG5vdCBhIGZ1bmN0aW9uLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBpbnNwZWN0LlxuICAgICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyBjYXN0IGZ1bmN0aW9uLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGNhc3RGdW5jdGlvbih2YWx1ZSkge1xuICAgICAgcmV0dXJuIHR5cGVvZiB2YWx1ZSA9PSAnZnVuY3Rpb24nID8gdmFsdWUgOiBpZGVudGl0eTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDYXN0cyBgdmFsdWVgIHRvIGEgcGF0aCBhcnJheSBpZiBpdCdzIG5vdCBvbmUuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGluc3BlY3QuXG4gICAgICogQHBhcmFtIHtPYmplY3R9IFtvYmplY3RdIFRoZSBvYmplY3QgdG8gcXVlcnkga2V5cyBvbi5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIGNhc3QgcHJvcGVydHkgcGF0aCBhcnJheS5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBjYXN0UGF0aCh2YWx1ZSwgb2JqZWN0KSB7XG4gICAgICBpZiAoaXNBcnJheSh2YWx1ZSkpIHtcbiAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGlzS2V5KHZhbHVlLCBvYmplY3QpID8gW3ZhbHVlXSA6IHN0cmluZ1RvUGF0aCh0b1N0cmluZyh2YWx1ZSkpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEEgYGJhc2VSZXN0YCBhbGlhcyB3aGljaCBjYW4gYmUgcmVwbGFjZWQgd2l0aCBgaWRlbnRpdHlgIGJ5IG1vZHVsZVxuICAgICAqIHJlcGxhY2VtZW50IHBsdWdpbnMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtGdW5jdGlvbn1cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byBhcHBseSBhIHJlc3QgcGFyYW1ldGVyIHRvLlxuICAgICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IGZ1bmN0aW9uLlxuICAgICAqL1xuICAgIHZhciBjYXN0UmVzdCA9IGJhc2VSZXN0O1xuXG4gICAgLyoqXG4gICAgICogQ2FzdHMgYGFycmF5YCB0byBhIHNsaWNlIGlmIGl0J3MgbmVlZGVkLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gaW5zcGVjdC5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gc3RhcnQgVGhlIHN0YXJ0IHBvc2l0aW9uLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbZW5kPWFycmF5Lmxlbmd0aF0gVGhlIGVuZCBwb3NpdGlvbi5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIGNhc3Qgc2xpY2UuXG4gICAgICovXG4gICAgZnVuY3Rpb24gY2FzdFNsaWNlKGFycmF5LCBzdGFydCwgZW5kKSB7XG4gICAgICB2YXIgbGVuZ3RoID0gYXJyYXkubGVuZ3RoO1xuICAgICAgZW5kID0gZW5kID09PSB1bmRlZmluZWQgPyBsZW5ndGggOiBlbmQ7XG4gICAgICByZXR1cm4gKCFzdGFydCAmJiBlbmQgPj0gbGVuZ3RoKSA/IGFycmF5IDogYmFzZVNsaWNlKGFycmF5LCBzdGFydCwgZW5kKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBBIHNpbXBsZSB3cmFwcGVyIGFyb3VuZCB0aGUgZ2xvYmFsIFtgY2xlYXJUaW1lb3V0YF0oaHR0cHM6Ly9tZG4uaW8vY2xlYXJUaW1lb3V0KS5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtudW1iZXJ8T2JqZWN0fSBpZCBUaGUgdGltZXIgaWQgb3IgdGltZW91dCBvYmplY3Qgb2YgdGhlIHRpbWVyIHRvIGNsZWFyLlxuICAgICAqL1xuICAgIHZhciBjbGVhclRpbWVvdXQgPSBjdHhDbGVhclRpbWVvdXQgfHwgZnVuY3Rpb24oaWQpIHtcbiAgICAgIHJldHVybiByb290LmNsZWFyVGltZW91dChpZCk7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBjbG9uZSBvZiAgYGJ1ZmZlcmAuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7QnVmZmVyfSBidWZmZXIgVGhlIGJ1ZmZlciB0byBjbG9uZS5cbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW59IFtpc0RlZXBdIFNwZWNpZnkgYSBkZWVwIGNsb25lLlxuICAgICAqIEByZXR1cm5zIHtCdWZmZXJ9IFJldHVybnMgdGhlIGNsb25lZCBidWZmZXIuXG4gICAgICovXG4gICAgZnVuY3Rpb24gY2xvbmVCdWZmZXIoYnVmZmVyLCBpc0RlZXApIHtcbiAgICAgIGlmIChpc0RlZXApIHtcbiAgICAgICAgcmV0dXJuIGJ1ZmZlci5zbGljZSgpO1xuICAgICAgfVxuICAgICAgdmFyIGxlbmd0aCA9IGJ1ZmZlci5sZW5ndGgsXG4gICAgICAgICAgcmVzdWx0ID0gYWxsb2NVbnNhZmUgPyBhbGxvY1Vuc2FmZShsZW5ndGgpIDogbmV3IGJ1ZmZlci5jb25zdHJ1Y3RvcihsZW5ndGgpO1xuXG4gICAgICBidWZmZXIuY29weShyZXN1bHQpO1xuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgY2xvbmUgb2YgYGFycmF5QnVmZmVyYC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtBcnJheUJ1ZmZlcn0gYXJyYXlCdWZmZXIgVGhlIGFycmF5IGJ1ZmZlciB0byBjbG9uZS5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXlCdWZmZXJ9IFJldHVybnMgdGhlIGNsb25lZCBhcnJheSBidWZmZXIuXG4gICAgICovXG4gICAgZnVuY3Rpb24gY2xvbmVBcnJheUJ1ZmZlcihhcnJheUJ1ZmZlcikge1xuICAgICAgdmFyIHJlc3VsdCA9IG5ldyBhcnJheUJ1ZmZlci5jb25zdHJ1Y3RvcihhcnJheUJ1ZmZlci5ieXRlTGVuZ3RoKTtcbiAgICAgIG5ldyBVaW50OEFycmF5KHJlc3VsdCkuc2V0KG5ldyBVaW50OEFycmF5KGFycmF5QnVmZmVyKSk7XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBjbG9uZSBvZiBgZGF0YVZpZXdgLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gZGF0YVZpZXcgVGhlIGRhdGEgdmlldyB0byBjbG9uZS5cbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW59IFtpc0RlZXBdIFNwZWNpZnkgYSBkZWVwIGNsb25lLlxuICAgICAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgdGhlIGNsb25lZCBkYXRhIHZpZXcuXG4gICAgICovXG4gICAgZnVuY3Rpb24gY2xvbmVEYXRhVmlldyhkYXRhVmlldywgaXNEZWVwKSB7XG4gICAgICB2YXIgYnVmZmVyID0gaXNEZWVwID8gY2xvbmVBcnJheUJ1ZmZlcihkYXRhVmlldy5idWZmZXIpIDogZGF0YVZpZXcuYnVmZmVyO1xuICAgICAgcmV0dXJuIG5ldyBkYXRhVmlldy5jb25zdHJ1Y3RvcihidWZmZXIsIGRhdGFWaWV3LmJ5dGVPZmZzZXQsIGRhdGFWaWV3LmJ5dGVMZW5ndGgpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBjbG9uZSBvZiBgcmVnZXhwYC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtPYmplY3R9IHJlZ2V4cCBUaGUgcmVnZXhwIHRvIGNsb25lLlxuICAgICAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgdGhlIGNsb25lZCByZWdleHAuXG4gICAgICovXG4gICAgZnVuY3Rpb24gY2xvbmVSZWdFeHAocmVnZXhwKSB7XG4gICAgICB2YXIgcmVzdWx0ID0gbmV3IHJlZ2V4cC5jb25zdHJ1Y3RvcihyZWdleHAuc291cmNlLCByZUZsYWdzLmV4ZWMocmVnZXhwKSk7XG4gICAgICByZXN1bHQubGFzdEluZGV4ID0gcmVnZXhwLmxhc3RJbmRleDtcbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIGNsb25lIG9mIHRoZSBgc3ltYm9sYCBvYmplY3QuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBzeW1ib2wgVGhlIHN5bWJvbCBvYmplY3QgdG8gY2xvbmUuXG4gICAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyB0aGUgY2xvbmVkIHN5bWJvbCBvYmplY3QuXG4gICAgICovXG4gICAgZnVuY3Rpb24gY2xvbmVTeW1ib2woc3ltYm9sKSB7XG4gICAgICByZXR1cm4gc3ltYm9sVmFsdWVPZiA/IE9iamVjdChzeW1ib2xWYWx1ZU9mLmNhbGwoc3ltYm9sKSkgOiB7fTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgY2xvbmUgb2YgYHR5cGVkQXJyYXlgLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gdHlwZWRBcnJheSBUaGUgdHlwZWQgYXJyYXkgdG8gY2xvbmUuXG4gICAgICogQHBhcmFtIHtib29sZWFufSBbaXNEZWVwXSBTcGVjaWZ5IGEgZGVlcCBjbG9uZS5cbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIHRoZSBjbG9uZWQgdHlwZWQgYXJyYXkuXG4gICAgICovXG4gICAgZnVuY3Rpb24gY2xvbmVUeXBlZEFycmF5KHR5cGVkQXJyYXksIGlzRGVlcCkge1xuICAgICAgdmFyIGJ1ZmZlciA9IGlzRGVlcCA/IGNsb25lQXJyYXlCdWZmZXIodHlwZWRBcnJheS5idWZmZXIpIDogdHlwZWRBcnJheS5idWZmZXI7XG4gICAgICByZXR1cm4gbmV3IHR5cGVkQXJyYXkuY29uc3RydWN0b3IoYnVmZmVyLCB0eXBlZEFycmF5LmJ5dGVPZmZzZXQsIHR5cGVkQXJyYXkubGVuZ3RoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDb21wYXJlcyB2YWx1ZXMgdG8gc29ydCB0aGVtIGluIGFzY2VuZGluZyBvcmRlci5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY29tcGFyZS5cbiAgICAgKiBAcGFyYW0geyp9IG90aGVyIFRoZSBvdGhlciB2YWx1ZSB0byBjb21wYXJlLlxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9IFJldHVybnMgdGhlIHNvcnQgb3JkZXIgaW5kaWNhdG9yIGZvciBgdmFsdWVgLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGNvbXBhcmVBc2NlbmRpbmcodmFsdWUsIG90aGVyKSB7XG4gICAgICBpZiAodmFsdWUgIT09IG90aGVyKSB7XG4gICAgICAgIHZhciB2YWxJc0RlZmluZWQgPSB2YWx1ZSAhPT0gdW5kZWZpbmVkLFxuICAgICAgICAgICAgdmFsSXNOdWxsID0gdmFsdWUgPT09IG51bGwsXG4gICAgICAgICAgICB2YWxJc1JlZmxleGl2ZSA9IHZhbHVlID09PSB2YWx1ZSxcbiAgICAgICAgICAgIHZhbElzU3ltYm9sID0gaXNTeW1ib2wodmFsdWUpO1xuXG4gICAgICAgIHZhciBvdGhJc0RlZmluZWQgPSBvdGhlciAhPT0gdW5kZWZpbmVkLFxuICAgICAgICAgICAgb3RoSXNOdWxsID0gb3RoZXIgPT09IG51bGwsXG4gICAgICAgICAgICBvdGhJc1JlZmxleGl2ZSA9IG90aGVyID09PSBvdGhlcixcbiAgICAgICAgICAgIG90aElzU3ltYm9sID0gaXNTeW1ib2wob3RoZXIpO1xuXG4gICAgICAgIGlmICgoIW90aElzTnVsbCAmJiAhb3RoSXNTeW1ib2wgJiYgIXZhbElzU3ltYm9sICYmIHZhbHVlID4gb3RoZXIpIHx8XG4gICAgICAgICAgICAodmFsSXNTeW1ib2wgJiYgb3RoSXNEZWZpbmVkICYmIG90aElzUmVmbGV4aXZlICYmICFvdGhJc051bGwgJiYgIW90aElzU3ltYm9sKSB8fFxuICAgICAgICAgICAgKHZhbElzTnVsbCAmJiBvdGhJc0RlZmluZWQgJiYgb3RoSXNSZWZsZXhpdmUpIHx8XG4gICAgICAgICAgICAoIXZhbElzRGVmaW5lZCAmJiBvdGhJc1JlZmxleGl2ZSkgfHxcbiAgICAgICAgICAgICF2YWxJc1JlZmxleGl2ZSkge1xuICAgICAgICAgIHJldHVybiAxO1xuICAgICAgICB9XG4gICAgICAgIGlmICgoIXZhbElzTnVsbCAmJiAhdmFsSXNTeW1ib2wgJiYgIW90aElzU3ltYm9sICYmIHZhbHVlIDwgb3RoZXIpIHx8XG4gICAgICAgICAgICAob3RoSXNTeW1ib2wgJiYgdmFsSXNEZWZpbmVkICYmIHZhbElzUmVmbGV4aXZlICYmICF2YWxJc051bGwgJiYgIXZhbElzU3ltYm9sKSB8fFxuICAgICAgICAgICAgKG90aElzTnVsbCAmJiB2YWxJc0RlZmluZWQgJiYgdmFsSXNSZWZsZXhpdmUpIHx8XG4gICAgICAgICAgICAoIW90aElzRGVmaW5lZCAmJiB2YWxJc1JlZmxleGl2ZSkgfHxcbiAgICAgICAgICAgICFvdGhJc1JlZmxleGl2ZSkge1xuICAgICAgICAgIHJldHVybiAtMTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIDA7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVXNlZCBieSBgXy5vcmRlckJ5YCB0byBjb21wYXJlIG11bHRpcGxlIHByb3BlcnRpZXMgb2YgYSB2YWx1ZSB0byBhbm90aGVyXG4gICAgICogYW5kIHN0YWJsZSBzb3J0IHRoZW0uXG4gICAgICpcbiAgICAgKiBJZiBgb3JkZXJzYCBpcyB1bnNwZWNpZmllZCwgYWxsIHZhbHVlcyBhcmUgc29ydGVkIGluIGFzY2VuZGluZyBvcmRlci4gT3RoZXJ3aXNlLFxuICAgICAqIHNwZWNpZnkgYW4gb3JkZXIgb2YgXCJkZXNjXCIgZm9yIGRlc2NlbmRpbmcgb3IgXCJhc2NcIiBmb3IgYXNjZW5kaW5nIHNvcnQgb3JkZXJcbiAgICAgKiBvZiBjb3JyZXNwb25kaW5nIHZhbHVlcy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIGNvbXBhcmUuXG4gICAgICogQHBhcmFtIHtPYmplY3R9IG90aGVyIFRoZSBvdGhlciBvYmplY3QgdG8gY29tcGFyZS5cbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW5bXXxzdHJpbmdbXX0gb3JkZXJzIFRoZSBvcmRlciB0byBzb3J0IGJ5IGZvciBlYWNoIHByb3BlcnR5LlxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9IFJldHVybnMgdGhlIHNvcnQgb3JkZXIgaW5kaWNhdG9yIGZvciBgb2JqZWN0YC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBjb21wYXJlTXVsdGlwbGUob2JqZWN0LCBvdGhlciwgb3JkZXJzKSB7XG4gICAgICB2YXIgaW5kZXggPSAtMSxcbiAgICAgICAgICBvYmpDcml0ZXJpYSA9IG9iamVjdC5jcml0ZXJpYSxcbiAgICAgICAgICBvdGhDcml0ZXJpYSA9IG90aGVyLmNyaXRlcmlhLFxuICAgICAgICAgIGxlbmd0aCA9IG9iakNyaXRlcmlhLmxlbmd0aCxcbiAgICAgICAgICBvcmRlcnNMZW5ndGggPSBvcmRlcnMubGVuZ3RoO1xuXG4gICAgICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgICAgICB2YXIgcmVzdWx0ID0gY29tcGFyZUFzY2VuZGluZyhvYmpDcml0ZXJpYVtpbmRleF0sIG90aENyaXRlcmlhW2luZGV4XSk7XG4gICAgICAgIGlmIChyZXN1bHQpIHtcbiAgICAgICAgICBpZiAoaW5kZXggPj0gb3JkZXJzTGVuZ3RoKSB7XG4gICAgICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgICAgIH1cbiAgICAgICAgICB2YXIgb3JkZXIgPSBvcmRlcnNbaW5kZXhdO1xuICAgICAgICAgIHJldHVybiByZXN1bHQgKiAob3JkZXIgPT0gJ2Rlc2MnID8gLTEgOiAxKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgLy8gRml4ZXMgYW4gYEFycmF5I3NvcnRgIGJ1ZyBpbiB0aGUgSlMgZW5naW5lIGVtYmVkZGVkIGluIEFkb2JlIGFwcGxpY2F0aW9uc1xuICAgICAgLy8gdGhhdCBjYXVzZXMgaXQsIHVuZGVyIGNlcnRhaW4gY2lyY3Vtc3RhbmNlcywgdG8gcHJvdmlkZSB0aGUgc2FtZSB2YWx1ZSBmb3JcbiAgICAgIC8vIGBvYmplY3RgIGFuZCBgb3RoZXJgLiBTZWUgaHR0cHM6Ly9naXRodWIuY29tL2phc2hrZW5hcy91bmRlcnNjb3JlL3B1bGwvMTI0N1xuICAgICAgLy8gZm9yIG1vcmUgZGV0YWlscy5cbiAgICAgIC8vXG4gICAgICAvLyBUaGlzIGFsc28gZW5zdXJlcyBhIHN0YWJsZSBzb3J0IGluIFY4IGFuZCBvdGhlciBlbmdpbmVzLlxuICAgICAgLy8gU2VlIGh0dHBzOi8vYnVncy5jaHJvbWl1bS5vcmcvcC92OC9pc3N1ZXMvZGV0YWlsP2lkPTkwIGZvciBtb3JlIGRldGFpbHMuXG4gICAgICByZXR1cm4gb2JqZWN0LmluZGV4IC0gb3RoZXIuaW5kZXg7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhbiBhcnJheSB0aGF0IGlzIHRoZSBjb21wb3NpdGlvbiBvZiBwYXJ0aWFsbHkgYXBwbGllZCBhcmd1bWVudHMsXG4gICAgICogcGxhY2Vob2xkZXJzLCBhbmQgcHJvdmlkZWQgYXJndW1lbnRzIGludG8gYSBzaW5nbGUgYXJyYXkgb2YgYXJndW1lbnRzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBhcmdzIFRoZSBwcm92aWRlZCBhcmd1bWVudHMuXG4gICAgICogQHBhcmFtIHtBcnJheX0gcGFydGlhbHMgVGhlIGFyZ3VtZW50cyB0byBwcmVwZW5kIHRvIHRob3NlIHByb3ZpZGVkLlxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGhvbGRlcnMgVGhlIGBwYXJ0aWFsc2AgcGxhY2Vob2xkZXIgaW5kZXhlcy5cbiAgICAgKiBAcGFyYW1zIHtib29sZWFufSBbaXNDdXJyaWVkXSBTcGVjaWZ5IGNvbXBvc2luZyBmb3IgYSBjdXJyaWVkIGZ1bmN0aW9uLlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IGFycmF5IG9mIGNvbXBvc2VkIGFyZ3VtZW50cy5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBjb21wb3NlQXJncyhhcmdzLCBwYXJ0aWFscywgaG9sZGVycywgaXNDdXJyaWVkKSB7XG4gICAgICB2YXIgYXJnc0luZGV4ID0gLTEsXG4gICAgICAgICAgYXJnc0xlbmd0aCA9IGFyZ3MubGVuZ3RoLFxuICAgICAgICAgIGhvbGRlcnNMZW5ndGggPSBob2xkZXJzLmxlbmd0aCxcbiAgICAgICAgICBsZWZ0SW5kZXggPSAtMSxcbiAgICAgICAgICBsZWZ0TGVuZ3RoID0gcGFydGlhbHMubGVuZ3RoLFxuICAgICAgICAgIHJhbmdlTGVuZ3RoID0gbmF0aXZlTWF4KGFyZ3NMZW5ndGggLSBob2xkZXJzTGVuZ3RoLCAwKSxcbiAgICAgICAgICByZXN1bHQgPSBBcnJheShsZWZ0TGVuZ3RoICsgcmFuZ2VMZW5ndGgpLFxuICAgICAgICAgIGlzVW5jdXJyaWVkID0gIWlzQ3VycmllZDtcblxuICAgICAgd2hpbGUgKCsrbGVmdEluZGV4IDwgbGVmdExlbmd0aCkge1xuICAgICAgICByZXN1bHRbbGVmdEluZGV4XSA9IHBhcnRpYWxzW2xlZnRJbmRleF07XG4gICAgICB9XG4gICAgICB3aGlsZSAoKythcmdzSW5kZXggPCBob2xkZXJzTGVuZ3RoKSB7XG4gICAgICAgIGlmIChpc1VuY3VycmllZCB8fCBhcmdzSW5kZXggPCBhcmdzTGVuZ3RoKSB7XG4gICAgICAgICAgcmVzdWx0W2hvbGRlcnNbYXJnc0luZGV4XV0gPSBhcmdzW2FyZ3NJbmRleF07XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHdoaWxlIChyYW5nZUxlbmd0aC0tKSB7XG4gICAgICAgIHJlc3VsdFtsZWZ0SW5kZXgrK10gPSBhcmdzW2FyZ3NJbmRleCsrXTtcbiAgICAgIH1cbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhpcyBmdW5jdGlvbiBpcyBsaWtlIGBjb21wb3NlQXJnc2AgZXhjZXB0IHRoYXQgdGhlIGFyZ3VtZW50cyBjb21wb3NpdGlvblxuICAgICAqIGlzIHRhaWxvcmVkIGZvciBgXy5wYXJ0aWFsUmlnaHRgLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBhcmdzIFRoZSBwcm92aWRlZCBhcmd1bWVudHMuXG4gICAgICogQHBhcmFtIHtBcnJheX0gcGFydGlhbHMgVGhlIGFyZ3VtZW50cyB0byBhcHBlbmQgdG8gdGhvc2UgcHJvdmlkZWQuXG4gICAgICogQHBhcmFtIHtBcnJheX0gaG9sZGVycyBUaGUgYHBhcnRpYWxzYCBwbGFjZWhvbGRlciBpbmRleGVzLlxuICAgICAqIEBwYXJhbXMge2Jvb2xlYW59IFtpc0N1cnJpZWRdIFNwZWNpZnkgY29tcG9zaW5nIGZvciBhIGN1cnJpZWQgZnVuY3Rpb24uXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBuZXcgYXJyYXkgb2YgY29tcG9zZWQgYXJndW1lbnRzLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGNvbXBvc2VBcmdzUmlnaHQoYXJncywgcGFydGlhbHMsIGhvbGRlcnMsIGlzQ3VycmllZCkge1xuICAgICAgdmFyIGFyZ3NJbmRleCA9IC0xLFxuICAgICAgICAgIGFyZ3NMZW5ndGggPSBhcmdzLmxlbmd0aCxcbiAgICAgICAgICBob2xkZXJzSW5kZXggPSAtMSxcbiAgICAgICAgICBob2xkZXJzTGVuZ3RoID0gaG9sZGVycy5sZW5ndGgsXG4gICAgICAgICAgcmlnaHRJbmRleCA9IC0xLFxuICAgICAgICAgIHJpZ2h0TGVuZ3RoID0gcGFydGlhbHMubGVuZ3RoLFxuICAgICAgICAgIHJhbmdlTGVuZ3RoID0gbmF0aXZlTWF4KGFyZ3NMZW5ndGggLSBob2xkZXJzTGVuZ3RoLCAwKSxcbiAgICAgICAgICByZXN1bHQgPSBBcnJheShyYW5nZUxlbmd0aCArIHJpZ2h0TGVuZ3RoKSxcbiAgICAgICAgICBpc1VuY3VycmllZCA9ICFpc0N1cnJpZWQ7XG5cbiAgICAgIHdoaWxlICgrK2FyZ3NJbmRleCA8IHJhbmdlTGVuZ3RoKSB7XG4gICAgICAgIHJlc3VsdFthcmdzSW5kZXhdID0gYXJnc1thcmdzSW5kZXhdO1xuICAgICAgfVxuICAgICAgdmFyIG9mZnNldCA9IGFyZ3NJbmRleDtcbiAgICAgIHdoaWxlICgrK3JpZ2h0SW5kZXggPCByaWdodExlbmd0aCkge1xuICAgICAgICByZXN1bHRbb2Zmc2V0ICsgcmlnaHRJbmRleF0gPSBwYXJ0aWFsc1tyaWdodEluZGV4XTtcbiAgICAgIH1cbiAgICAgIHdoaWxlICgrK2hvbGRlcnNJbmRleCA8IGhvbGRlcnNMZW5ndGgpIHtcbiAgICAgICAgaWYgKGlzVW5jdXJyaWVkIHx8IGFyZ3NJbmRleCA8IGFyZ3NMZW5ndGgpIHtcbiAgICAgICAgICByZXN1bHRbb2Zmc2V0ICsgaG9sZGVyc1tob2xkZXJzSW5kZXhdXSA9IGFyZ3NbYXJnc0luZGV4KytdO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENvcGllcyB0aGUgdmFsdWVzIG9mIGBzb3VyY2VgIHRvIGBhcnJheWAuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IHNvdXJjZSBUaGUgYXJyYXkgdG8gY29weSB2YWx1ZXMgZnJvbS5cbiAgICAgKiBAcGFyYW0ge0FycmF5fSBbYXJyYXk9W11dIFRoZSBhcnJheSB0byBjb3B5IHZhbHVlcyB0by5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgYGFycmF5YC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBjb3B5QXJyYXkoc291cmNlLCBhcnJheSkge1xuICAgICAgdmFyIGluZGV4ID0gLTEsXG4gICAgICAgICAgbGVuZ3RoID0gc291cmNlLmxlbmd0aDtcblxuICAgICAgYXJyYXkgfHwgKGFycmF5ID0gQXJyYXkobGVuZ3RoKSk7XG4gICAgICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgICAgICBhcnJheVtpbmRleF0gPSBzb3VyY2VbaW5kZXhdO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGFycmF5O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENvcGllcyBwcm9wZXJ0aWVzIG9mIGBzb3VyY2VgIHRvIGBvYmplY3RgLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gc291cmNlIFRoZSBvYmplY3QgdG8gY29weSBwcm9wZXJ0aWVzIGZyb20uXG4gICAgICogQHBhcmFtIHtBcnJheX0gcHJvcHMgVGhlIHByb3BlcnR5IGlkZW50aWZpZXJzIHRvIGNvcHkuXG4gICAgICogQHBhcmFtIHtPYmplY3R9IFtvYmplY3Q9e31dIFRoZSBvYmplY3QgdG8gY29weSBwcm9wZXJ0aWVzIHRvLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IFtjdXN0b21pemVyXSBUaGUgZnVuY3Rpb24gdG8gY3VzdG9taXplIGNvcGllZCB2YWx1ZXMuXG4gICAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyBgb2JqZWN0YC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBjb3B5T2JqZWN0KHNvdXJjZSwgcHJvcHMsIG9iamVjdCwgY3VzdG9taXplcikge1xuICAgICAgdmFyIGlzTmV3ID0gIW9iamVjdDtcbiAgICAgIG9iamVjdCB8fCAob2JqZWN0ID0ge30pO1xuXG4gICAgICB2YXIgaW5kZXggPSAtMSxcbiAgICAgICAgICBsZW5ndGggPSBwcm9wcy5sZW5ndGg7XG5cbiAgICAgIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XG4gICAgICAgIHZhciBrZXkgPSBwcm9wc1tpbmRleF07XG5cbiAgICAgICAgdmFyIG5ld1ZhbHVlID0gY3VzdG9taXplclxuICAgICAgICAgID8gY3VzdG9taXplcihvYmplY3Rba2V5XSwgc291cmNlW2tleV0sIGtleSwgb2JqZWN0LCBzb3VyY2UpXG4gICAgICAgICAgOiB1bmRlZmluZWQ7XG5cbiAgICAgICAgaWYgKG5ld1ZhbHVlID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICBuZXdWYWx1ZSA9IHNvdXJjZVtrZXldO1xuICAgICAgICB9XG4gICAgICAgIGlmIChpc05ldykge1xuICAgICAgICAgIGJhc2VBc3NpZ25WYWx1ZShvYmplY3QsIGtleSwgbmV3VmFsdWUpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGFzc2lnblZhbHVlKG9iamVjdCwga2V5LCBuZXdWYWx1ZSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiBvYmplY3Q7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ29waWVzIG93biBzeW1ib2xzIG9mIGBzb3VyY2VgIHRvIGBvYmplY3RgLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gc291cmNlIFRoZSBvYmplY3QgdG8gY29weSBzeW1ib2xzIGZyb20uXG4gICAgICogQHBhcmFtIHtPYmplY3R9IFtvYmplY3Q9e31dIFRoZSBvYmplY3QgdG8gY29weSBzeW1ib2xzIHRvLlxuICAgICAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgYG9iamVjdGAuXG4gICAgICovXG4gICAgZnVuY3Rpb24gY29weVN5bWJvbHMoc291cmNlLCBvYmplY3QpIHtcbiAgICAgIHJldHVybiBjb3B5T2JqZWN0KHNvdXJjZSwgZ2V0U3ltYm9scyhzb3VyY2UpLCBvYmplY3QpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENvcGllcyBvd24gYW5kIGluaGVyaXRlZCBzeW1ib2xzIG9mIGBzb3VyY2VgIHRvIGBvYmplY3RgLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gc291cmNlIFRoZSBvYmplY3QgdG8gY29weSBzeW1ib2xzIGZyb20uXG4gICAgICogQHBhcmFtIHtPYmplY3R9IFtvYmplY3Q9e31dIFRoZSBvYmplY3QgdG8gY29weSBzeW1ib2xzIHRvLlxuICAgICAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgYG9iamVjdGAuXG4gICAgICovXG4gICAgZnVuY3Rpb24gY29weVN5bWJvbHNJbihzb3VyY2UsIG9iamVjdCkge1xuICAgICAgcmV0dXJuIGNvcHlPYmplY3Qoc291cmNlLCBnZXRTeW1ib2xzSW4oc291cmNlKSwgb2JqZWN0KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgZnVuY3Rpb24gbGlrZSBgXy5ncm91cEJ5YC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gc2V0dGVyIFRoZSBmdW5jdGlvbiB0byBzZXQgYWNjdW11bGF0b3IgdmFsdWVzLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IFtpbml0aWFsaXplcl0gVGhlIGFjY3VtdWxhdG9yIG9iamVjdCBpbml0aWFsaXplci5cbiAgICAgKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBhZ2dyZWdhdG9yIGZ1bmN0aW9uLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGNyZWF0ZUFnZ3JlZ2F0b3Ioc2V0dGVyLCBpbml0aWFsaXplcikge1xuICAgICAgcmV0dXJuIGZ1bmN0aW9uKGNvbGxlY3Rpb24sIGl0ZXJhdGVlKSB7XG4gICAgICAgIHZhciBmdW5jID0gaXNBcnJheShjb2xsZWN0aW9uKSA/IGFycmF5QWdncmVnYXRvciA6IGJhc2VBZ2dyZWdhdG9yLFxuICAgICAgICAgICAgYWNjdW11bGF0b3IgPSBpbml0aWFsaXplciA/IGluaXRpYWxpemVyKCkgOiB7fTtcblxuICAgICAgICByZXR1cm4gZnVuYyhjb2xsZWN0aW9uLCBzZXR0ZXIsIGdldEl0ZXJhdGVlKGl0ZXJhdGVlLCAyKSwgYWNjdW11bGF0b3IpO1xuICAgICAgfTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgZnVuY3Rpb24gbGlrZSBgXy5hc3NpZ25gLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBhc3NpZ25lciBUaGUgZnVuY3Rpb24gdG8gYXNzaWduIHZhbHVlcy5cbiAgICAgKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBhc3NpZ25lciBmdW5jdGlvbi5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBjcmVhdGVBc3NpZ25lcihhc3NpZ25lcikge1xuICAgICAgcmV0dXJuIGJhc2VSZXN0KGZ1bmN0aW9uKG9iamVjdCwgc291cmNlcykge1xuICAgICAgICB2YXIgaW5kZXggPSAtMSxcbiAgICAgICAgICAgIGxlbmd0aCA9IHNvdXJjZXMubGVuZ3RoLFxuICAgICAgICAgICAgY3VzdG9taXplciA9IGxlbmd0aCA+IDEgPyBzb3VyY2VzW2xlbmd0aCAtIDFdIDogdW5kZWZpbmVkLFxuICAgICAgICAgICAgZ3VhcmQgPSBsZW5ndGggPiAyID8gc291cmNlc1syXSA6IHVuZGVmaW5lZDtcblxuICAgICAgICBjdXN0b21pemVyID0gKGFzc2lnbmVyLmxlbmd0aCA+IDMgJiYgdHlwZW9mIGN1c3RvbWl6ZXIgPT0gJ2Z1bmN0aW9uJylcbiAgICAgICAgICA/IChsZW5ndGgtLSwgY3VzdG9taXplcilcbiAgICAgICAgICA6IHVuZGVmaW5lZDtcblxuICAgICAgICBpZiAoZ3VhcmQgJiYgaXNJdGVyYXRlZUNhbGwoc291cmNlc1swXSwgc291cmNlc1sxXSwgZ3VhcmQpKSB7XG4gICAgICAgICAgY3VzdG9taXplciA9IGxlbmd0aCA8IDMgPyB1bmRlZmluZWQgOiBjdXN0b21pemVyO1xuICAgICAgICAgIGxlbmd0aCA9IDE7XG4gICAgICAgIH1cbiAgICAgICAgb2JqZWN0ID0gT2JqZWN0KG9iamVjdCk7XG4gICAgICAgIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XG4gICAgICAgICAgdmFyIHNvdXJjZSA9IHNvdXJjZXNbaW5kZXhdO1xuICAgICAgICAgIGlmIChzb3VyY2UpIHtcbiAgICAgICAgICAgIGFzc2lnbmVyKG9iamVjdCwgc291cmNlLCBpbmRleCwgY3VzdG9taXplcik7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBvYmplY3Q7XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgYGJhc2VFYWNoYCBvciBgYmFzZUVhY2hSaWdodGAgZnVuY3Rpb24uXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGVhY2hGdW5jIFRoZSBmdW5jdGlvbiB0byBpdGVyYXRlIG92ZXIgYSBjb2xsZWN0aW9uLlxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbn0gW2Zyb21SaWdodF0gU3BlY2lmeSBpdGVyYXRpbmcgZnJvbSByaWdodCB0byBsZWZ0LlxuICAgICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IGJhc2UgZnVuY3Rpb24uXG4gICAgICovXG4gICAgZnVuY3Rpb24gY3JlYXRlQmFzZUVhY2goZWFjaEZ1bmMsIGZyb21SaWdodCkge1xuICAgICAgcmV0dXJuIGZ1bmN0aW9uKGNvbGxlY3Rpb24sIGl0ZXJhdGVlKSB7XG4gICAgICAgIGlmIChjb2xsZWN0aW9uID09IG51bGwpIHtcbiAgICAgICAgICByZXR1cm4gY29sbGVjdGlvbjtcbiAgICAgICAgfVxuICAgICAgICBpZiAoIWlzQXJyYXlMaWtlKGNvbGxlY3Rpb24pKSB7XG4gICAgICAgICAgcmV0dXJuIGVhY2hGdW5jKGNvbGxlY3Rpb24sIGl0ZXJhdGVlKTtcbiAgICAgICAgfVxuICAgICAgICB2YXIgbGVuZ3RoID0gY29sbGVjdGlvbi5sZW5ndGgsXG4gICAgICAgICAgICBpbmRleCA9IGZyb21SaWdodCA/IGxlbmd0aCA6IC0xLFxuICAgICAgICAgICAgaXRlcmFibGUgPSBPYmplY3QoY29sbGVjdGlvbik7XG5cbiAgICAgICAgd2hpbGUgKChmcm9tUmlnaHQgPyBpbmRleC0tIDogKytpbmRleCA8IGxlbmd0aCkpIHtcbiAgICAgICAgICBpZiAoaXRlcmF0ZWUoaXRlcmFibGVbaW5kZXhdLCBpbmRleCwgaXRlcmFibGUpID09PSBmYWxzZSkge1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBjb2xsZWN0aW9uO1xuICAgICAgfTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgYmFzZSBmdW5jdGlvbiBmb3IgbWV0aG9kcyBsaWtlIGBfLmZvckluYCBhbmQgYF8uZm9yT3duYC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtib29sZWFufSBbZnJvbVJpZ2h0XSBTcGVjaWZ5IGl0ZXJhdGluZyBmcm9tIHJpZ2h0IHRvIGxlZnQuXG4gICAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgYmFzZSBmdW5jdGlvbi5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBjcmVhdGVCYXNlRm9yKGZyb21SaWdodCkge1xuICAgICAgcmV0dXJuIGZ1bmN0aW9uKG9iamVjdCwgaXRlcmF0ZWUsIGtleXNGdW5jKSB7XG4gICAgICAgIHZhciBpbmRleCA9IC0xLFxuICAgICAgICAgICAgaXRlcmFibGUgPSBPYmplY3Qob2JqZWN0KSxcbiAgICAgICAgICAgIHByb3BzID0ga2V5c0Z1bmMob2JqZWN0KSxcbiAgICAgICAgICAgIGxlbmd0aCA9IHByb3BzLmxlbmd0aDtcblxuICAgICAgICB3aGlsZSAobGVuZ3RoLS0pIHtcbiAgICAgICAgICB2YXIga2V5ID0gcHJvcHNbZnJvbVJpZ2h0ID8gbGVuZ3RoIDogKytpbmRleF07XG4gICAgICAgICAgaWYgKGl0ZXJhdGVlKGl0ZXJhYmxlW2tleV0sIGtleSwgaXRlcmFibGUpID09PSBmYWxzZSkge1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBvYmplY3Q7XG4gICAgICB9O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBmdW5jdGlvbiB0aGF0IHdyYXBzIGBmdW5jYCB0byBpbnZva2UgaXQgd2l0aCB0aGUgb3B0aW9uYWwgYHRoaXNgXG4gICAgICogYmluZGluZyBvZiBgdGhpc0FyZ2AuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIHdyYXAuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IGJpdG1hc2sgVGhlIGJpdG1hc2sgZmxhZ3MuIFNlZSBgY3JlYXRlV3JhcGAgZm9yIG1vcmUgZGV0YWlscy5cbiAgICAgKiBAcGFyYW0geyp9IFt0aGlzQXJnXSBUaGUgYHRoaXNgIGJpbmRpbmcgb2YgYGZ1bmNgLlxuICAgICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IHdyYXBwZWQgZnVuY3Rpb24uXG4gICAgICovXG4gICAgZnVuY3Rpb24gY3JlYXRlQmluZChmdW5jLCBiaXRtYXNrLCB0aGlzQXJnKSB7XG4gICAgICB2YXIgaXNCaW5kID0gYml0bWFzayAmIFdSQVBfQklORF9GTEFHLFxuICAgICAgICAgIEN0b3IgPSBjcmVhdGVDdG9yKGZ1bmMpO1xuXG4gICAgICBmdW5jdGlvbiB3cmFwcGVyKCkge1xuICAgICAgICB2YXIgZm4gPSAodGhpcyAmJiB0aGlzICE9PSByb290ICYmIHRoaXMgaW5zdGFuY2VvZiB3cmFwcGVyKSA/IEN0b3IgOiBmdW5jO1xuICAgICAgICByZXR1cm4gZm4uYXBwbHkoaXNCaW5kID8gdGhpc0FyZyA6IHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgICB9XG4gICAgICByZXR1cm4gd3JhcHBlcjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgZnVuY3Rpb24gbGlrZSBgXy5sb3dlckZpcnN0YC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IG1ldGhvZE5hbWUgVGhlIG5hbWUgb2YgdGhlIGBTdHJpbmdgIGNhc2UgbWV0aG9kIHRvIHVzZS5cbiAgICAgKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBjYXNlIGZ1bmN0aW9uLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGNyZWF0ZUNhc2VGaXJzdChtZXRob2ROYW1lKSB7XG4gICAgICByZXR1cm4gZnVuY3Rpb24oc3RyaW5nKSB7XG4gICAgICAgIHN0cmluZyA9IHRvU3RyaW5nKHN0cmluZyk7XG5cbiAgICAgICAgdmFyIHN0clN5bWJvbHMgPSBoYXNVbmljb2RlKHN0cmluZylcbiAgICAgICAgICA/IHN0cmluZ1RvQXJyYXkoc3RyaW5nKVxuICAgICAgICAgIDogdW5kZWZpbmVkO1xuXG4gICAgICAgIHZhciBjaHIgPSBzdHJTeW1ib2xzXG4gICAgICAgICAgPyBzdHJTeW1ib2xzWzBdXG4gICAgICAgICAgOiBzdHJpbmcuY2hhckF0KDApO1xuXG4gICAgICAgIHZhciB0cmFpbGluZyA9IHN0clN5bWJvbHNcbiAgICAgICAgICA/IGNhc3RTbGljZShzdHJTeW1ib2xzLCAxKS5qb2luKCcnKVxuICAgICAgICAgIDogc3RyaW5nLnNsaWNlKDEpO1xuXG4gICAgICAgIHJldHVybiBjaHJbbWV0aG9kTmFtZV0oKSArIHRyYWlsaW5nO1xuICAgICAgfTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgZnVuY3Rpb24gbGlrZSBgXy5jYW1lbENhc2VgLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFjayBUaGUgZnVuY3Rpb24gdG8gY29tYmluZSBlYWNoIHdvcmQuXG4gICAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgY29tcG91bmRlciBmdW5jdGlvbi5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBjcmVhdGVDb21wb3VuZGVyKGNhbGxiYWNrKSB7XG4gICAgICByZXR1cm4gZnVuY3Rpb24oc3RyaW5nKSB7XG4gICAgICAgIHJldHVybiBhcnJheVJlZHVjZSh3b3JkcyhkZWJ1cnIoc3RyaW5nKS5yZXBsYWNlKHJlQXBvcywgJycpKSwgY2FsbGJhY2ssICcnKTtcbiAgICAgIH07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIGZ1bmN0aW9uIHRoYXQgcHJvZHVjZXMgYW4gaW5zdGFuY2Ugb2YgYEN0b3JgIHJlZ2FyZGxlc3Mgb2ZcbiAgICAgKiB3aGV0aGVyIGl0IHdhcyBpbnZva2VkIGFzIHBhcnQgb2YgYSBgbmV3YCBleHByZXNzaW9uIG9yIGJ5IGBjYWxsYCBvciBgYXBwbHlgLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBDdG9yIFRoZSBjb25zdHJ1Y3RvciB0byB3cmFwLlxuICAgICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IHdyYXBwZWQgZnVuY3Rpb24uXG4gICAgICovXG4gICAgZnVuY3Rpb24gY3JlYXRlQ3RvcihDdG9yKSB7XG4gICAgICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgICAgIC8vIFVzZSBhIGBzd2l0Y2hgIHN0YXRlbWVudCB0byB3b3JrIHdpdGggY2xhc3MgY29uc3RydWN0b3JzLiBTZWVcbiAgICAgICAgLy8gaHR0cDovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNy4wLyNzZWMtZWNtYXNjcmlwdC1mdW5jdGlvbi1vYmplY3RzLWNhbGwtdGhpc2FyZ3VtZW50LWFyZ3VtZW50c2xpc3RcbiAgICAgICAgLy8gZm9yIG1vcmUgZGV0YWlscy5cbiAgICAgICAgdmFyIGFyZ3MgPSBhcmd1bWVudHM7XG4gICAgICAgIHN3aXRjaCAoYXJncy5sZW5ndGgpIHtcbiAgICAgICAgICBjYXNlIDA6IHJldHVybiBuZXcgQ3RvcjtcbiAgICAgICAgICBjYXNlIDE6IHJldHVybiBuZXcgQ3RvcihhcmdzWzBdKTtcbiAgICAgICAgICBjYXNlIDI6IHJldHVybiBuZXcgQ3RvcihhcmdzWzBdLCBhcmdzWzFdKTtcbiAgICAgICAgICBjYXNlIDM6IHJldHVybiBuZXcgQ3RvcihhcmdzWzBdLCBhcmdzWzFdLCBhcmdzWzJdKTtcbiAgICAgICAgICBjYXNlIDQ6IHJldHVybiBuZXcgQ3RvcihhcmdzWzBdLCBhcmdzWzFdLCBhcmdzWzJdLCBhcmdzWzNdKTtcbiAgICAgICAgICBjYXNlIDU6IHJldHVybiBuZXcgQ3RvcihhcmdzWzBdLCBhcmdzWzFdLCBhcmdzWzJdLCBhcmdzWzNdLCBhcmdzWzRdKTtcbiAgICAgICAgICBjYXNlIDY6IHJldHVybiBuZXcgQ3RvcihhcmdzWzBdLCBhcmdzWzFdLCBhcmdzWzJdLCBhcmdzWzNdLCBhcmdzWzRdLCBhcmdzWzVdKTtcbiAgICAgICAgICBjYXNlIDc6IHJldHVybiBuZXcgQ3RvcihhcmdzWzBdLCBhcmdzWzFdLCBhcmdzWzJdLCBhcmdzWzNdLCBhcmdzWzRdLCBhcmdzWzVdLCBhcmdzWzZdKTtcbiAgICAgICAgfVxuICAgICAgICB2YXIgdGhpc0JpbmRpbmcgPSBiYXNlQ3JlYXRlKEN0b3IucHJvdG90eXBlKSxcbiAgICAgICAgICAgIHJlc3VsdCA9IEN0b3IuYXBwbHkodGhpc0JpbmRpbmcsIGFyZ3MpO1xuXG4gICAgICAgIC8vIE1pbWljIHRoZSBjb25zdHJ1Y3RvcidzIGByZXR1cm5gIGJlaGF2aW9yLlxuICAgICAgICAvLyBTZWUgaHR0cHM6Ly9lczUuZ2l0aHViLmlvLyN4MTMuMi4yIGZvciBtb3JlIGRldGFpbHMuXG4gICAgICAgIHJldHVybiBpc09iamVjdChyZXN1bHQpID8gcmVzdWx0IDogdGhpc0JpbmRpbmc7XG4gICAgICB9O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBmdW5jdGlvbiB0aGF0IHdyYXBzIGBmdW5jYCB0byBlbmFibGUgY3VycnlpbmcuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIHdyYXAuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IGJpdG1hc2sgVGhlIGJpdG1hc2sgZmxhZ3MuIFNlZSBgY3JlYXRlV3JhcGAgZm9yIG1vcmUgZGV0YWlscy5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gYXJpdHkgVGhlIGFyaXR5IG9mIGBmdW5jYC5cbiAgICAgKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyB3cmFwcGVkIGZ1bmN0aW9uLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGNyZWF0ZUN1cnJ5KGZ1bmMsIGJpdG1hc2ssIGFyaXR5KSB7XG4gICAgICB2YXIgQ3RvciA9IGNyZWF0ZUN0b3IoZnVuYyk7XG5cbiAgICAgIGZ1bmN0aW9uIHdyYXBwZXIoKSB7XG4gICAgICAgIHZhciBsZW5ndGggPSBhcmd1bWVudHMubGVuZ3RoLFxuICAgICAgICAgICAgYXJncyA9IEFycmF5KGxlbmd0aCksXG4gICAgICAgICAgICBpbmRleCA9IGxlbmd0aCxcbiAgICAgICAgICAgIHBsYWNlaG9sZGVyID0gZ2V0SG9sZGVyKHdyYXBwZXIpO1xuXG4gICAgICAgIHdoaWxlIChpbmRleC0tKSB7XG4gICAgICAgICAgYXJnc1tpbmRleF0gPSBhcmd1bWVudHNbaW5kZXhdO1xuICAgICAgICB9XG4gICAgICAgIHZhciBob2xkZXJzID0gKGxlbmd0aCA8IDMgJiYgYXJnc1swXSAhPT0gcGxhY2Vob2xkZXIgJiYgYXJnc1tsZW5ndGggLSAxXSAhPT0gcGxhY2Vob2xkZXIpXG4gICAgICAgICAgPyBbXVxuICAgICAgICAgIDogcmVwbGFjZUhvbGRlcnMoYXJncywgcGxhY2Vob2xkZXIpO1xuXG4gICAgICAgIGxlbmd0aCAtPSBob2xkZXJzLmxlbmd0aDtcbiAgICAgICAgaWYgKGxlbmd0aCA8IGFyaXR5KSB7XG4gICAgICAgICAgcmV0dXJuIGNyZWF0ZVJlY3VycnkoXG4gICAgICAgICAgICBmdW5jLCBiaXRtYXNrLCBjcmVhdGVIeWJyaWQsIHdyYXBwZXIucGxhY2Vob2xkZXIsIHVuZGVmaW5lZCxcbiAgICAgICAgICAgIGFyZ3MsIGhvbGRlcnMsIHVuZGVmaW5lZCwgdW5kZWZpbmVkLCBhcml0eSAtIGxlbmd0aCk7XG4gICAgICAgIH1cbiAgICAgICAgdmFyIGZuID0gKHRoaXMgJiYgdGhpcyAhPT0gcm9vdCAmJiB0aGlzIGluc3RhbmNlb2Ygd3JhcHBlcikgPyBDdG9yIDogZnVuYztcbiAgICAgICAgcmV0dXJuIGFwcGx5KGZuLCB0aGlzLCBhcmdzKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiB3cmFwcGVyO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBgXy5maW5kYCBvciBgXy5maW5kTGFzdGAgZnVuY3Rpb24uXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGZpbmRJbmRleEZ1bmMgVGhlIGZ1bmN0aW9uIHRvIGZpbmQgdGhlIGNvbGxlY3Rpb24gaW5kZXguXG4gICAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgZmluZCBmdW5jdGlvbi5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBjcmVhdGVGaW5kKGZpbmRJbmRleEZ1bmMpIHtcbiAgICAgIHJldHVybiBmdW5jdGlvbihjb2xsZWN0aW9uLCBwcmVkaWNhdGUsIGZyb21JbmRleCkge1xuICAgICAgICB2YXIgaXRlcmFibGUgPSBPYmplY3QoY29sbGVjdGlvbik7XG4gICAgICAgIGlmICghaXNBcnJheUxpa2UoY29sbGVjdGlvbikpIHtcbiAgICAgICAgICB2YXIgaXRlcmF0ZWUgPSBnZXRJdGVyYXRlZShwcmVkaWNhdGUsIDMpO1xuICAgICAgICAgIGNvbGxlY3Rpb24gPSBrZXlzKGNvbGxlY3Rpb24pO1xuICAgICAgICAgIHByZWRpY2F0ZSA9IGZ1bmN0aW9uKGtleSkgeyByZXR1cm4gaXRlcmF0ZWUoaXRlcmFibGVba2V5XSwga2V5LCBpdGVyYWJsZSk7IH07XG4gICAgICAgIH1cbiAgICAgICAgdmFyIGluZGV4ID0gZmluZEluZGV4RnVuYyhjb2xsZWN0aW9uLCBwcmVkaWNhdGUsIGZyb21JbmRleCk7XG4gICAgICAgIHJldHVybiBpbmRleCA+IC0xID8gaXRlcmFibGVbaXRlcmF0ZWUgPyBjb2xsZWN0aW9uW2luZGV4XSA6IGluZGV4XSA6IHVuZGVmaW5lZDtcbiAgICAgIH07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIGBfLmZsb3dgIG9yIGBfLmZsb3dSaWdodGAgZnVuY3Rpb24uXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbn0gW2Zyb21SaWdodF0gU3BlY2lmeSBpdGVyYXRpbmcgZnJvbSByaWdodCB0byBsZWZ0LlxuICAgICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IGZsb3cgZnVuY3Rpb24uXG4gICAgICovXG4gICAgZnVuY3Rpb24gY3JlYXRlRmxvdyhmcm9tUmlnaHQpIHtcbiAgICAgIHJldHVybiBmbGF0UmVzdChmdW5jdGlvbihmdW5jcykge1xuICAgICAgICB2YXIgbGVuZ3RoID0gZnVuY3MubGVuZ3RoLFxuICAgICAgICAgICAgaW5kZXggPSBsZW5ndGgsXG4gICAgICAgICAgICBwcmVyZXEgPSBMb2Rhc2hXcmFwcGVyLnByb3RvdHlwZS50aHJ1O1xuXG4gICAgICAgIGlmIChmcm9tUmlnaHQpIHtcbiAgICAgICAgICBmdW5jcy5yZXZlcnNlKCk7XG4gICAgICAgIH1cbiAgICAgICAgd2hpbGUgKGluZGV4LS0pIHtcbiAgICAgICAgICB2YXIgZnVuYyA9IGZ1bmNzW2luZGV4XTtcbiAgICAgICAgICBpZiAodHlwZW9mIGZ1bmMgIT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihGVU5DX0VSUk9SX1RFWFQpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAocHJlcmVxICYmICF3cmFwcGVyICYmIGdldEZ1bmNOYW1lKGZ1bmMpID09ICd3cmFwcGVyJykge1xuICAgICAgICAgICAgdmFyIHdyYXBwZXIgPSBuZXcgTG9kYXNoV3JhcHBlcihbXSwgdHJ1ZSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGluZGV4ID0gd3JhcHBlciA/IGluZGV4IDogbGVuZ3RoO1xuICAgICAgICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgICAgICAgIGZ1bmMgPSBmdW5jc1tpbmRleF07XG5cbiAgICAgICAgICB2YXIgZnVuY05hbWUgPSBnZXRGdW5jTmFtZShmdW5jKSxcbiAgICAgICAgICAgICAgZGF0YSA9IGZ1bmNOYW1lID09ICd3cmFwcGVyJyA/IGdldERhdGEoZnVuYykgOiB1bmRlZmluZWQ7XG5cbiAgICAgICAgICBpZiAoZGF0YSAmJiBpc0xhemlhYmxlKGRhdGFbMF0pICYmXG4gICAgICAgICAgICAgICAgZGF0YVsxXSA9PSAoV1JBUF9BUllfRkxBRyB8IFdSQVBfQ1VSUllfRkxBRyB8IFdSQVBfUEFSVElBTF9GTEFHIHwgV1JBUF9SRUFSR19GTEFHKSAmJlxuICAgICAgICAgICAgICAgICFkYXRhWzRdLmxlbmd0aCAmJiBkYXRhWzldID09IDFcbiAgICAgICAgICAgICAgKSB7XG4gICAgICAgICAgICB3cmFwcGVyID0gd3JhcHBlcltnZXRGdW5jTmFtZShkYXRhWzBdKV0uYXBwbHkod3JhcHBlciwgZGF0YVszXSk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHdyYXBwZXIgPSAoZnVuYy5sZW5ndGggPT0gMSAmJiBpc0xhemlhYmxlKGZ1bmMpKVxuICAgICAgICAgICAgICA/IHdyYXBwZXJbZnVuY05hbWVdKClcbiAgICAgICAgICAgICAgOiB3cmFwcGVyLnRocnUoZnVuYyk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBmdW5jdGlvbigpIHtcbiAgICAgICAgICB2YXIgYXJncyA9IGFyZ3VtZW50cyxcbiAgICAgICAgICAgICAgdmFsdWUgPSBhcmdzWzBdO1xuXG4gICAgICAgICAgaWYgKHdyYXBwZXIgJiYgYXJncy5sZW5ndGggPT0gMSAmJiBpc0FycmF5KHZhbHVlKSkge1xuICAgICAgICAgICAgcmV0dXJuIHdyYXBwZXIucGxhbnQodmFsdWUpLnZhbHVlKCk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHZhciBpbmRleCA9IDAsXG4gICAgICAgICAgICAgIHJlc3VsdCA9IGxlbmd0aCA/IGZ1bmNzW2luZGV4XS5hcHBseSh0aGlzLCBhcmdzKSA6IHZhbHVlO1xuXG4gICAgICAgICAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHtcbiAgICAgICAgICAgIHJlc3VsdCA9IGZ1bmNzW2luZGV4XS5jYWxsKHRoaXMsIHJlc3VsdCk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICAgIH07XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgZnVuY3Rpb24gdGhhdCB3cmFwcyBgZnVuY2AgdG8gaW52b2tlIGl0IHdpdGggb3B0aW9uYWwgYHRoaXNgXG4gICAgICogYmluZGluZyBvZiBgdGhpc0FyZ2AsIHBhcnRpYWwgYXBwbGljYXRpb24sIGFuZCBjdXJyeWluZy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbnxzdHJpbmd9IGZ1bmMgVGhlIGZ1bmN0aW9uIG9yIG1ldGhvZCBuYW1lIHRvIHdyYXAuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IGJpdG1hc2sgVGhlIGJpdG1hc2sgZmxhZ3MuIFNlZSBgY3JlYXRlV3JhcGAgZm9yIG1vcmUgZGV0YWlscy5cbiAgICAgKiBAcGFyYW0geyp9IFt0aGlzQXJnXSBUaGUgYHRoaXNgIGJpbmRpbmcgb2YgYGZ1bmNgLlxuICAgICAqIEBwYXJhbSB7QXJyYXl9IFtwYXJ0aWFsc10gVGhlIGFyZ3VtZW50cyB0byBwcmVwZW5kIHRvIHRob3NlIHByb3ZpZGVkIHRvXG4gICAgICogIHRoZSBuZXcgZnVuY3Rpb24uXG4gICAgICogQHBhcmFtIHtBcnJheX0gW2hvbGRlcnNdIFRoZSBgcGFydGlhbHNgIHBsYWNlaG9sZGVyIGluZGV4ZXMuXG4gICAgICogQHBhcmFtIHtBcnJheX0gW3BhcnRpYWxzUmlnaHRdIFRoZSBhcmd1bWVudHMgdG8gYXBwZW5kIHRvIHRob3NlIHByb3ZpZGVkXG4gICAgICogIHRvIHRoZSBuZXcgZnVuY3Rpb24uXG4gICAgICogQHBhcmFtIHtBcnJheX0gW2hvbGRlcnNSaWdodF0gVGhlIGBwYXJ0aWFsc1JpZ2h0YCBwbGFjZWhvbGRlciBpbmRleGVzLlxuICAgICAqIEBwYXJhbSB7QXJyYXl9IFthcmdQb3NdIFRoZSBhcmd1bWVudCBwb3NpdGlvbnMgb2YgdGhlIG5ldyBmdW5jdGlvbi5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW2FyeV0gVGhlIGFyaXR5IGNhcCBvZiBgZnVuY2AuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFthcml0eV0gVGhlIGFyaXR5IG9mIGBmdW5jYC5cbiAgICAgKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyB3cmFwcGVkIGZ1bmN0aW9uLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGNyZWF0ZUh5YnJpZChmdW5jLCBiaXRtYXNrLCB0aGlzQXJnLCBwYXJ0aWFscywgaG9sZGVycywgcGFydGlhbHNSaWdodCwgaG9sZGVyc1JpZ2h0LCBhcmdQb3MsIGFyeSwgYXJpdHkpIHtcbiAgICAgIHZhciBpc0FyeSA9IGJpdG1hc2sgJiBXUkFQX0FSWV9GTEFHLFxuICAgICAgICAgIGlzQmluZCA9IGJpdG1hc2sgJiBXUkFQX0JJTkRfRkxBRyxcbiAgICAgICAgICBpc0JpbmRLZXkgPSBiaXRtYXNrICYgV1JBUF9CSU5EX0tFWV9GTEFHLFxuICAgICAgICAgIGlzQ3VycmllZCA9IGJpdG1hc2sgJiAoV1JBUF9DVVJSWV9GTEFHIHwgV1JBUF9DVVJSWV9SSUdIVF9GTEFHKSxcbiAgICAgICAgICBpc0ZsaXAgPSBiaXRtYXNrICYgV1JBUF9GTElQX0ZMQUcsXG4gICAgICAgICAgQ3RvciA9IGlzQmluZEtleSA/IHVuZGVmaW5lZCA6IGNyZWF0ZUN0b3IoZnVuYyk7XG5cbiAgICAgIGZ1bmN0aW9uIHdyYXBwZXIoKSB7XG4gICAgICAgIHZhciBsZW5ndGggPSBhcmd1bWVudHMubGVuZ3RoLFxuICAgICAgICAgICAgYXJncyA9IEFycmF5KGxlbmd0aCksXG4gICAgICAgICAgICBpbmRleCA9IGxlbmd0aDtcblxuICAgICAgICB3aGlsZSAoaW5kZXgtLSkge1xuICAgICAgICAgIGFyZ3NbaW5kZXhdID0gYXJndW1lbnRzW2luZGV4XTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoaXNDdXJyaWVkKSB7XG4gICAgICAgICAgdmFyIHBsYWNlaG9sZGVyID0gZ2V0SG9sZGVyKHdyYXBwZXIpLFxuICAgICAgICAgICAgICBob2xkZXJzQ291bnQgPSBjb3VudEhvbGRlcnMoYXJncywgcGxhY2Vob2xkZXIpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChwYXJ0aWFscykge1xuICAgICAgICAgIGFyZ3MgPSBjb21wb3NlQXJncyhhcmdzLCBwYXJ0aWFscywgaG9sZGVycywgaXNDdXJyaWVkKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAocGFydGlhbHNSaWdodCkge1xuICAgICAgICAgIGFyZ3MgPSBjb21wb3NlQXJnc1JpZ2h0KGFyZ3MsIHBhcnRpYWxzUmlnaHQsIGhvbGRlcnNSaWdodCwgaXNDdXJyaWVkKTtcbiAgICAgICAgfVxuICAgICAgICBsZW5ndGggLT0gaG9sZGVyc0NvdW50O1xuICAgICAgICBpZiAoaXNDdXJyaWVkICYmIGxlbmd0aCA8IGFyaXR5KSB7XG4gICAgICAgICAgdmFyIG5ld0hvbGRlcnMgPSByZXBsYWNlSG9sZGVycyhhcmdzLCBwbGFjZWhvbGRlcik7XG4gICAgICAgICAgcmV0dXJuIGNyZWF0ZVJlY3VycnkoXG4gICAgICAgICAgICBmdW5jLCBiaXRtYXNrLCBjcmVhdGVIeWJyaWQsIHdyYXBwZXIucGxhY2Vob2xkZXIsIHRoaXNBcmcsXG4gICAgICAgICAgICBhcmdzLCBuZXdIb2xkZXJzLCBhcmdQb3MsIGFyeSwgYXJpdHkgLSBsZW5ndGhcbiAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICAgIHZhciB0aGlzQmluZGluZyA9IGlzQmluZCA/IHRoaXNBcmcgOiB0aGlzLFxuICAgICAgICAgICAgZm4gPSBpc0JpbmRLZXkgPyB0aGlzQmluZGluZ1tmdW5jXSA6IGZ1bmM7XG5cbiAgICAgICAgbGVuZ3RoID0gYXJncy5sZW5ndGg7XG4gICAgICAgIGlmIChhcmdQb3MpIHtcbiAgICAgICAgICBhcmdzID0gcmVvcmRlcihhcmdzLCBhcmdQb3MpO1xuICAgICAgICB9IGVsc2UgaWYgKGlzRmxpcCAmJiBsZW5ndGggPiAxKSB7XG4gICAgICAgICAgYXJncy5yZXZlcnNlKCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGlzQXJ5ICYmIGFyeSA8IGxlbmd0aCkge1xuICAgICAgICAgIGFyZ3MubGVuZ3RoID0gYXJ5O1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzICYmIHRoaXMgIT09IHJvb3QgJiYgdGhpcyBpbnN0YW5jZW9mIHdyYXBwZXIpIHtcbiAgICAgICAgICBmbiA9IEN0b3IgfHwgY3JlYXRlQ3Rvcihmbik7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGZuLmFwcGx5KHRoaXNCaW5kaW5nLCBhcmdzKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiB3cmFwcGVyO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBmdW5jdGlvbiBsaWtlIGBfLmludmVydEJ5YC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gc2V0dGVyIFRoZSBmdW5jdGlvbiB0byBzZXQgYWNjdW11bGF0b3IgdmFsdWVzLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IHRvSXRlcmF0ZWUgVGhlIGZ1bmN0aW9uIHRvIHJlc29sdmUgaXRlcmF0ZWVzLlxuICAgICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IGludmVydGVyIGZ1bmN0aW9uLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGNyZWF0ZUludmVydGVyKHNldHRlciwgdG9JdGVyYXRlZSkge1xuICAgICAgcmV0dXJuIGZ1bmN0aW9uKG9iamVjdCwgaXRlcmF0ZWUpIHtcbiAgICAgICAgcmV0dXJuIGJhc2VJbnZlcnRlcihvYmplY3QsIHNldHRlciwgdG9JdGVyYXRlZShpdGVyYXRlZSksIHt9KTtcbiAgICAgIH07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIGZ1bmN0aW9uIHRoYXQgcGVyZm9ybXMgYSBtYXRoZW1hdGljYWwgb3BlcmF0aW9uIG9uIHR3byB2YWx1ZXMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IG9wZXJhdG9yIFRoZSBmdW5jdGlvbiB0byBwZXJmb3JtIHRoZSBvcGVyYXRpb24uXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtkZWZhdWx0VmFsdWVdIFRoZSB2YWx1ZSB1c2VkIGZvciBgdW5kZWZpbmVkYCBhcmd1bWVudHMuXG4gICAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgbWF0aGVtYXRpY2FsIG9wZXJhdGlvbiBmdW5jdGlvbi5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBjcmVhdGVNYXRoT3BlcmF0aW9uKG9wZXJhdG9yLCBkZWZhdWx0VmFsdWUpIHtcbiAgICAgIHJldHVybiBmdW5jdGlvbih2YWx1ZSwgb3RoZXIpIHtcbiAgICAgICAgdmFyIHJlc3VsdDtcbiAgICAgICAgaWYgKHZhbHVlID09PSB1bmRlZmluZWQgJiYgb3RoZXIgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIHJldHVybiBkZWZhdWx0VmFsdWU7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHZhbHVlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICByZXN1bHQgPSB2YWx1ZTtcbiAgICAgICAgfVxuICAgICAgICBpZiAob3RoZXIgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIGlmIChyZXN1bHQgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgcmV0dXJuIG90aGVyO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAodHlwZW9mIHZhbHVlID09ICdzdHJpbmcnIHx8IHR5cGVvZiBvdGhlciA9PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgdmFsdWUgPSBiYXNlVG9TdHJpbmcodmFsdWUpO1xuICAgICAgICAgICAgb3RoZXIgPSBiYXNlVG9TdHJpbmcob3RoZXIpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB2YWx1ZSA9IGJhc2VUb051bWJlcih2YWx1ZSk7XG4gICAgICAgICAgICBvdGhlciA9IGJhc2VUb051bWJlcihvdGhlcik7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJlc3VsdCA9IG9wZXJhdG9yKHZhbHVlLCBvdGhlcik7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgIH07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIGZ1bmN0aW9uIGxpa2UgYF8ub3ZlcmAuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGFycmF5RnVuYyBUaGUgZnVuY3Rpb24gdG8gaXRlcmF0ZSBvdmVyIGl0ZXJhdGVlcy5cbiAgICAgKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBvdmVyIGZ1bmN0aW9uLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGNyZWF0ZU92ZXIoYXJyYXlGdW5jKSB7XG4gICAgICByZXR1cm4gZmxhdFJlc3QoZnVuY3Rpb24oaXRlcmF0ZWVzKSB7XG4gICAgICAgIGl0ZXJhdGVlcyA9IGFycmF5TWFwKGl0ZXJhdGVlcywgYmFzZVVuYXJ5KGdldEl0ZXJhdGVlKCkpKTtcbiAgICAgICAgcmV0dXJuIGJhc2VSZXN0KGZ1bmN0aW9uKGFyZ3MpIHtcbiAgICAgICAgICB2YXIgdGhpc0FyZyA9IHRoaXM7XG4gICAgICAgICAgcmV0dXJuIGFycmF5RnVuYyhpdGVyYXRlZXMsIGZ1bmN0aW9uKGl0ZXJhdGVlKSB7XG4gICAgICAgICAgICByZXR1cm4gYXBwbHkoaXRlcmF0ZWUsIHRoaXNBcmcsIGFyZ3MpO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgdGhlIHBhZGRpbmcgZm9yIGBzdHJpbmdgIGJhc2VkIG9uIGBsZW5ndGhgLiBUaGUgYGNoYXJzYCBzdHJpbmdcbiAgICAgKiBpcyB0cnVuY2F0ZWQgaWYgdGhlIG51bWJlciBvZiBjaGFyYWN0ZXJzIGV4Y2VlZHMgYGxlbmd0aGAuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBsZW5ndGggVGhlIHBhZGRpbmcgbGVuZ3RoLlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBbY2hhcnM9JyAnXSBUaGUgc3RyaW5nIHVzZWQgYXMgcGFkZGluZy5cbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfSBSZXR1cm5zIHRoZSBwYWRkaW5nIGZvciBgc3RyaW5nYC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBjcmVhdGVQYWRkaW5nKGxlbmd0aCwgY2hhcnMpIHtcbiAgICAgIGNoYXJzID0gY2hhcnMgPT09IHVuZGVmaW5lZCA/ICcgJyA6IGJhc2VUb1N0cmluZyhjaGFycyk7XG5cbiAgICAgIHZhciBjaGFyc0xlbmd0aCA9IGNoYXJzLmxlbmd0aDtcbiAgICAgIGlmIChjaGFyc0xlbmd0aCA8IDIpIHtcbiAgICAgICAgcmV0dXJuIGNoYXJzTGVuZ3RoID8gYmFzZVJlcGVhdChjaGFycywgbGVuZ3RoKSA6IGNoYXJzO1xuICAgICAgfVxuICAgICAgdmFyIHJlc3VsdCA9IGJhc2VSZXBlYXQoY2hhcnMsIG5hdGl2ZUNlaWwobGVuZ3RoIC8gc3RyaW5nU2l6ZShjaGFycykpKTtcbiAgICAgIHJldHVybiBoYXNVbmljb2RlKGNoYXJzKVxuICAgICAgICA/IGNhc3RTbGljZShzdHJpbmdUb0FycmF5KHJlc3VsdCksIDAsIGxlbmd0aCkuam9pbignJylcbiAgICAgICAgOiByZXN1bHQuc2xpY2UoMCwgbGVuZ3RoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgZnVuY3Rpb24gdGhhdCB3cmFwcyBgZnVuY2AgdG8gaW52b2tlIGl0IHdpdGggdGhlIGB0aGlzYCBiaW5kaW5nXG4gICAgICogb2YgYHRoaXNBcmdgIGFuZCBgcGFydGlhbHNgIHByZXBlbmRlZCB0byB0aGUgYXJndW1lbnRzIGl0IHJlY2VpdmVzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byB3cmFwLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBiaXRtYXNrIFRoZSBiaXRtYXNrIGZsYWdzLiBTZWUgYGNyZWF0ZVdyYXBgIGZvciBtb3JlIGRldGFpbHMuXG4gICAgICogQHBhcmFtIHsqfSB0aGlzQXJnIFRoZSBgdGhpc2AgYmluZGluZyBvZiBgZnVuY2AuXG4gICAgICogQHBhcmFtIHtBcnJheX0gcGFydGlhbHMgVGhlIGFyZ3VtZW50cyB0byBwcmVwZW5kIHRvIHRob3NlIHByb3ZpZGVkIHRvXG4gICAgICogIHRoZSBuZXcgZnVuY3Rpb24uXG4gICAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgd3JhcHBlZCBmdW5jdGlvbi5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBjcmVhdGVQYXJ0aWFsKGZ1bmMsIGJpdG1hc2ssIHRoaXNBcmcsIHBhcnRpYWxzKSB7XG4gICAgICB2YXIgaXNCaW5kID0gYml0bWFzayAmIFdSQVBfQklORF9GTEFHLFxuICAgICAgICAgIEN0b3IgPSBjcmVhdGVDdG9yKGZ1bmMpO1xuXG4gICAgICBmdW5jdGlvbiB3cmFwcGVyKCkge1xuICAgICAgICB2YXIgYXJnc0luZGV4ID0gLTEsXG4gICAgICAgICAgICBhcmdzTGVuZ3RoID0gYXJndW1lbnRzLmxlbmd0aCxcbiAgICAgICAgICAgIGxlZnRJbmRleCA9IC0xLFxuICAgICAgICAgICAgbGVmdExlbmd0aCA9IHBhcnRpYWxzLmxlbmd0aCxcbiAgICAgICAgICAgIGFyZ3MgPSBBcnJheShsZWZ0TGVuZ3RoICsgYXJnc0xlbmd0aCksXG4gICAgICAgICAgICBmbiA9ICh0aGlzICYmIHRoaXMgIT09IHJvb3QgJiYgdGhpcyBpbnN0YW5jZW9mIHdyYXBwZXIpID8gQ3RvciA6IGZ1bmM7XG5cbiAgICAgICAgd2hpbGUgKCsrbGVmdEluZGV4IDwgbGVmdExlbmd0aCkge1xuICAgICAgICAgIGFyZ3NbbGVmdEluZGV4XSA9IHBhcnRpYWxzW2xlZnRJbmRleF07XG4gICAgICAgIH1cbiAgICAgICAgd2hpbGUgKGFyZ3NMZW5ndGgtLSkge1xuICAgICAgICAgIGFyZ3NbbGVmdEluZGV4KytdID0gYXJndW1lbnRzWysrYXJnc0luZGV4XTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gYXBwbHkoZm4sIGlzQmluZCA/IHRoaXNBcmcgOiB0aGlzLCBhcmdzKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiB3cmFwcGVyO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBgXy5yYW5nZWAgb3IgYF8ucmFuZ2VSaWdodGAgZnVuY3Rpb24uXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbn0gW2Zyb21SaWdodF0gU3BlY2lmeSBpdGVyYXRpbmcgZnJvbSByaWdodCB0byBsZWZ0LlxuICAgICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IHJhbmdlIGZ1bmN0aW9uLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGNyZWF0ZVJhbmdlKGZyb21SaWdodCkge1xuICAgICAgcmV0dXJuIGZ1bmN0aW9uKHN0YXJ0LCBlbmQsIHN0ZXApIHtcbiAgICAgICAgaWYgKHN0ZXAgJiYgdHlwZW9mIHN0ZXAgIT0gJ251bWJlcicgJiYgaXNJdGVyYXRlZUNhbGwoc3RhcnQsIGVuZCwgc3RlcCkpIHtcbiAgICAgICAgICBlbmQgPSBzdGVwID0gdW5kZWZpbmVkO1xuICAgICAgICB9XG4gICAgICAgIC8vIEVuc3VyZSB0aGUgc2lnbiBvZiBgLTBgIGlzIHByZXNlcnZlZC5cbiAgICAgICAgc3RhcnQgPSB0b0Zpbml0ZShzdGFydCk7XG4gICAgICAgIGlmIChlbmQgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIGVuZCA9IHN0YXJ0O1xuICAgICAgICAgIHN0YXJ0ID0gMDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBlbmQgPSB0b0Zpbml0ZShlbmQpO1xuICAgICAgICB9XG4gICAgICAgIHN0ZXAgPSBzdGVwID09PSB1bmRlZmluZWQgPyAoc3RhcnQgPCBlbmQgPyAxIDogLTEpIDogdG9GaW5pdGUoc3RlcCk7XG4gICAgICAgIHJldHVybiBiYXNlUmFuZ2Uoc3RhcnQsIGVuZCwgc3RlcCwgZnJvbVJpZ2h0KTtcbiAgICAgIH07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIGZ1bmN0aW9uIHRoYXQgcGVyZm9ybXMgYSByZWxhdGlvbmFsIG9wZXJhdGlvbiBvbiB0d28gdmFsdWVzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBvcGVyYXRvciBUaGUgZnVuY3Rpb24gdG8gcGVyZm9ybSB0aGUgb3BlcmF0aW9uLlxuICAgICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IHJlbGF0aW9uYWwgb3BlcmF0aW9uIGZ1bmN0aW9uLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGNyZWF0ZVJlbGF0aW9uYWxPcGVyYXRpb24ob3BlcmF0b3IpIHtcbiAgICAgIHJldHVybiBmdW5jdGlvbih2YWx1ZSwgb3RoZXIpIHtcbiAgICAgICAgaWYgKCEodHlwZW9mIHZhbHVlID09ICdzdHJpbmcnICYmIHR5cGVvZiBvdGhlciA9PSAnc3RyaW5nJykpIHtcbiAgICAgICAgICB2YWx1ZSA9IHRvTnVtYmVyKHZhbHVlKTtcbiAgICAgICAgICBvdGhlciA9IHRvTnVtYmVyKG90aGVyKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gb3BlcmF0b3IodmFsdWUsIG90aGVyKTtcbiAgICAgIH07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIGZ1bmN0aW9uIHRoYXQgd3JhcHMgYGZ1bmNgIHRvIGNvbnRpbnVlIGN1cnJ5aW5nLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byB3cmFwLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBiaXRtYXNrIFRoZSBiaXRtYXNrIGZsYWdzLiBTZWUgYGNyZWF0ZVdyYXBgIGZvciBtb3JlIGRldGFpbHMuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gd3JhcEZ1bmMgVGhlIGZ1bmN0aW9uIHRvIGNyZWF0ZSB0aGUgYGZ1bmNgIHdyYXBwZXIuXG4gICAgICogQHBhcmFtIHsqfSBwbGFjZWhvbGRlciBUaGUgcGxhY2Vob2xkZXIgdmFsdWUuXG4gICAgICogQHBhcmFtIHsqfSBbdGhpc0FyZ10gVGhlIGB0aGlzYCBiaW5kaW5nIG9mIGBmdW5jYC5cbiAgICAgKiBAcGFyYW0ge0FycmF5fSBbcGFydGlhbHNdIFRoZSBhcmd1bWVudHMgdG8gcHJlcGVuZCB0byB0aG9zZSBwcm92aWRlZCB0b1xuICAgICAqICB0aGUgbmV3IGZ1bmN0aW9uLlxuICAgICAqIEBwYXJhbSB7QXJyYXl9IFtob2xkZXJzXSBUaGUgYHBhcnRpYWxzYCBwbGFjZWhvbGRlciBpbmRleGVzLlxuICAgICAqIEBwYXJhbSB7QXJyYXl9IFthcmdQb3NdIFRoZSBhcmd1bWVudCBwb3NpdGlvbnMgb2YgdGhlIG5ldyBmdW5jdGlvbi5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW2FyeV0gVGhlIGFyaXR5IGNhcCBvZiBgZnVuY2AuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFthcml0eV0gVGhlIGFyaXR5IG9mIGBmdW5jYC5cbiAgICAgKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyB3cmFwcGVkIGZ1bmN0aW9uLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGNyZWF0ZVJlY3VycnkoZnVuYywgYml0bWFzaywgd3JhcEZ1bmMsIHBsYWNlaG9sZGVyLCB0aGlzQXJnLCBwYXJ0aWFscywgaG9sZGVycywgYXJnUG9zLCBhcnksIGFyaXR5KSB7XG4gICAgICB2YXIgaXNDdXJyeSA9IGJpdG1hc2sgJiBXUkFQX0NVUlJZX0ZMQUcsXG4gICAgICAgICAgbmV3SG9sZGVycyA9IGlzQ3VycnkgPyBob2xkZXJzIDogdW5kZWZpbmVkLFxuICAgICAgICAgIG5ld0hvbGRlcnNSaWdodCA9IGlzQ3VycnkgPyB1bmRlZmluZWQgOiBob2xkZXJzLFxuICAgICAgICAgIG5ld1BhcnRpYWxzID0gaXNDdXJyeSA/IHBhcnRpYWxzIDogdW5kZWZpbmVkLFxuICAgICAgICAgIG5ld1BhcnRpYWxzUmlnaHQgPSBpc0N1cnJ5ID8gdW5kZWZpbmVkIDogcGFydGlhbHM7XG5cbiAgICAgIGJpdG1hc2sgfD0gKGlzQ3VycnkgPyBXUkFQX1BBUlRJQUxfRkxBRyA6IFdSQVBfUEFSVElBTF9SSUdIVF9GTEFHKTtcbiAgICAgIGJpdG1hc2sgJj0gfihpc0N1cnJ5ID8gV1JBUF9QQVJUSUFMX1JJR0hUX0ZMQUcgOiBXUkFQX1BBUlRJQUxfRkxBRyk7XG5cbiAgICAgIGlmICghKGJpdG1hc2sgJiBXUkFQX0NVUlJZX0JPVU5EX0ZMQUcpKSB7XG4gICAgICAgIGJpdG1hc2sgJj0gfihXUkFQX0JJTkRfRkxBRyB8IFdSQVBfQklORF9LRVlfRkxBRyk7XG4gICAgICB9XG4gICAgICB2YXIgbmV3RGF0YSA9IFtcbiAgICAgICAgZnVuYywgYml0bWFzaywgdGhpc0FyZywgbmV3UGFydGlhbHMsIG5ld0hvbGRlcnMsIG5ld1BhcnRpYWxzUmlnaHQsXG4gICAgICAgIG5ld0hvbGRlcnNSaWdodCwgYXJnUG9zLCBhcnksIGFyaXR5XG4gICAgICBdO1xuXG4gICAgICB2YXIgcmVzdWx0ID0gd3JhcEZ1bmMuYXBwbHkodW5kZWZpbmVkLCBuZXdEYXRhKTtcbiAgICAgIGlmIChpc0xhemlhYmxlKGZ1bmMpKSB7XG4gICAgICAgIHNldERhdGEocmVzdWx0LCBuZXdEYXRhKTtcbiAgICAgIH1cbiAgICAgIHJlc3VsdC5wbGFjZWhvbGRlciA9IHBsYWNlaG9sZGVyO1xuICAgICAgcmV0dXJuIHNldFdyYXBUb1N0cmluZyhyZXN1bHQsIGZ1bmMsIGJpdG1hc2spO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBmdW5jdGlvbiBsaWtlIGBfLnJvdW5kYC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IG1ldGhvZE5hbWUgVGhlIG5hbWUgb2YgdGhlIGBNYXRoYCBtZXRob2QgdG8gdXNlIHdoZW4gcm91bmRpbmcuXG4gICAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgcm91bmQgZnVuY3Rpb24uXG4gICAgICovXG4gICAgZnVuY3Rpb24gY3JlYXRlUm91bmQobWV0aG9kTmFtZSkge1xuICAgICAgdmFyIGZ1bmMgPSBNYXRoW21ldGhvZE5hbWVdO1xuICAgICAgcmV0dXJuIGZ1bmN0aW9uKG51bWJlciwgcHJlY2lzaW9uKSB7XG4gICAgICAgIG51bWJlciA9IHRvTnVtYmVyKG51bWJlcik7XG4gICAgICAgIHByZWNpc2lvbiA9IHByZWNpc2lvbiA9PSBudWxsID8gMCA6IG5hdGl2ZU1pbih0b0ludGVnZXIocHJlY2lzaW9uKSwgMjkyKTtcbiAgICAgICAgaWYgKHByZWNpc2lvbiAmJiBuYXRpdmVJc0Zpbml0ZShudW1iZXIpKSB7XG4gICAgICAgICAgLy8gU2hpZnQgd2l0aCBleHBvbmVudGlhbCBub3RhdGlvbiB0byBhdm9pZCBmbG9hdGluZy1wb2ludCBpc3N1ZXMuXG4gICAgICAgICAgLy8gU2VlIFtNRE5dKGh0dHBzOi8vbWRuLmlvL3JvdW5kI0V4YW1wbGVzKSBmb3IgbW9yZSBkZXRhaWxzLlxuICAgICAgICAgIHZhciBwYWlyID0gKHRvU3RyaW5nKG51bWJlcikgKyAnZScpLnNwbGl0KCdlJyksXG4gICAgICAgICAgICAgIHZhbHVlID0gZnVuYyhwYWlyWzBdICsgJ2UnICsgKCtwYWlyWzFdICsgcHJlY2lzaW9uKSk7XG5cbiAgICAgICAgICBwYWlyID0gKHRvU3RyaW5nKHZhbHVlKSArICdlJykuc3BsaXQoJ2UnKTtcbiAgICAgICAgICByZXR1cm4gKyhwYWlyWzBdICsgJ2UnICsgKCtwYWlyWzFdIC0gcHJlY2lzaW9uKSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGZ1bmMobnVtYmVyKTtcbiAgICAgIH07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIHNldCBvYmplY3Qgb2YgYHZhbHVlc2AuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IHZhbHVlcyBUaGUgdmFsdWVzIHRvIGFkZCB0byB0aGUgc2V0LlxuICAgICAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgdGhlIG5ldyBzZXQuXG4gICAgICovXG4gICAgdmFyIGNyZWF0ZVNldCA9ICEoU2V0ICYmICgxIC8gc2V0VG9BcnJheShuZXcgU2V0KFssLTBdKSlbMV0pID09IElORklOSVRZKSA/IG5vb3AgOiBmdW5jdGlvbih2YWx1ZXMpIHtcbiAgICAgIHJldHVybiBuZXcgU2V0KHZhbHVlcyk7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBgXy50b1BhaXJzYCBvciBgXy50b1BhaXJzSW5gIGZ1bmN0aW9uLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBrZXlzRnVuYyBUaGUgZnVuY3Rpb24gdG8gZ2V0IHRoZSBrZXlzIG9mIGEgZ2l2ZW4gb2JqZWN0LlxuICAgICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IHBhaXJzIGZ1bmN0aW9uLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGNyZWF0ZVRvUGFpcnMoa2V5c0Z1bmMpIHtcbiAgICAgIHJldHVybiBmdW5jdGlvbihvYmplY3QpIHtcbiAgICAgICAgdmFyIHRhZyA9IGdldFRhZyhvYmplY3QpO1xuICAgICAgICBpZiAodGFnID09IG1hcFRhZykge1xuICAgICAgICAgIHJldHVybiBtYXBUb0FycmF5KG9iamVjdCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRhZyA9PSBzZXRUYWcpIHtcbiAgICAgICAgICByZXR1cm4gc2V0VG9QYWlycyhvYmplY3QpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBiYXNlVG9QYWlycyhvYmplY3QsIGtleXNGdW5jKG9iamVjdCkpO1xuICAgICAgfTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgZnVuY3Rpb24gdGhhdCBlaXRoZXIgY3VycmllcyBvciBpbnZva2VzIGBmdW5jYCB3aXRoIG9wdGlvbmFsXG4gICAgICogYHRoaXNgIGJpbmRpbmcgYW5kIHBhcnRpYWxseSBhcHBsaWVkIGFyZ3VtZW50cy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbnxzdHJpbmd9IGZ1bmMgVGhlIGZ1bmN0aW9uIG9yIG1ldGhvZCBuYW1lIHRvIHdyYXAuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IGJpdG1hc2sgVGhlIGJpdG1hc2sgZmxhZ3MuXG4gICAgICogICAgMSAtIGBfLmJpbmRgXG4gICAgICogICAgMiAtIGBfLmJpbmRLZXlgXG4gICAgICogICAgNCAtIGBfLmN1cnJ5YCBvciBgXy5jdXJyeVJpZ2h0YCBvZiBhIGJvdW5kIGZ1bmN0aW9uXG4gICAgICogICAgOCAtIGBfLmN1cnJ5YFxuICAgICAqICAgMTYgLSBgXy5jdXJyeVJpZ2h0YFxuICAgICAqICAgMzIgLSBgXy5wYXJ0aWFsYFxuICAgICAqICAgNjQgLSBgXy5wYXJ0aWFsUmlnaHRgXG4gICAgICogIDEyOCAtIGBfLnJlYXJnYFxuICAgICAqICAyNTYgLSBgXy5hcnlgXG4gICAgICogIDUxMiAtIGBfLmZsaXBgXG4gICAgICogQHBhcmFtIHsqfSBbdGhpc0FyZ10gVGhlIGB0aGlzYCBiaW5kaW5nIG9mIGBmdW5jYC5cbiAgICAgKiBAcGFyYW0ge0FycmF5fSBbcGFydGlhbHNdIFRoZSBhcmd1bWVudHMgdG8gYmUgcGFydGlhbGx5IGFwcGxpZWQuXG4gICAgICogQHBhcmFtIHtBcnJheX0gW2hvbGRlcnNdIFRoZSBgcGFydGlhbHNgIHBsYWNlaG9sZGVyIGluZGV4ZXMuXG4gICAgICogQHBhcmFtIHtBcnJheX0gW2FyZ1Bvc10gVGhlIGFyZ3VtZW50IHBvc2l0aW9ucyBvZiB0aGUgbmV3IGZ1bmN0aW9uLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbYXJ5XSBUaGUgYXJpdHkgY2FwIG9mIGBmdW5jYC5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW2FyaXR5XSBUaGUgYXJpdHkgb2YgYGZ1bmNgLlxuICAgICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IHdyYXBwZWQgZnVuY3Rpb24uXG4gICAgICovXG4gICAgZnVuY3Rpb24gY3JlYXRlV3JhcChmdW5jLCBiaXRtYXNrLCB0aGlzQXJnLCBwYXJ0aWFscywgaG9sZGVycywgYXJnUG9zLCBhcnksIGFyaXR5KSB7XG4gICAgICB2YXIgaXNCaW5kS2V5ID0gYml0bWFzayAmIFdSQVBfQklORF9LRVlfRkxBRztcbiAgICAgIGlmICghaXNCaW5kS2V5ICYmIHR5cGVvZiBmdW5jICE9ICdmdW5jdGlvbicpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihGVU5DX0VSUk9SX1RFWFQpO1xuICAgICAgfVxuICAgICAgdmFyIGxlbmd0aCA9IHBhcnRpYWxzID8gcGFydGlhbHMubGVuZ3RoIDogMDtcbiAgICAgIGlmICghbGVuZ3RoKSB7XG4gICAgICAgIGJpdG1hc2sgJj0gfihXUkFQX1BBUlRJQUxfRkxBRyB8IFdSQVBfUEFSVElBTF9SSUdIVF9GTEFHKTtcbiAgICAgICAgcGFydGlhbHMgPSBob2xkZXJzID0gdW5kZWZpbmVkO1xuICAgICAgfVxuICAgICAgYXJ5ID0gYXJ5ID09PSB1bmRlZmluZWQgPyBhcnkgOiBuYXRpdmVNYXgodG9JbnRlZ2VyKGFyeSksIDApO1xuICAgICAgYXJpdHkgPSBhcml0eSA9PT0gdW5kZWZpbmVkID8gYXJpdHkgOiB0b0ludGVnZXIoYXJpdHkpO1xuICAgICAgbGVuZ3RoIC09IGhvbGRlcnMgPyBob2xkZXJzLmxlbmd0aCA6IDA7XG5cbiAgICAgIGlmIChiaXRtYXNrICYgV1JBUF9QQVJUSUFMX1JJR0hUX0ZMQUcpIHtcbiAgICAgICAgdmFyIHBhcnRpYWxzUmlnaHQgPSBwYXJ0aWFscyxcbiAgICAgICAgICAgIGhvbGRlcnNSaWdodCA9IGhvbGRlcnM7XG5cbiAgICAgICAgcGFydGlhbHMgPSBob2xkZXJzID0gdW5kZWZpbmVkO1xuICAgICAgfVxuICAgICAgdmFyIGRhdGEgPSBpc0JpbmRLZXkgPyB1bmRlZmluZWQgOiBnZXREYXRhKGZ1bmMpO1xuXG4gICAgICB2YXIgbmV3RGF0YSA9IFtcbiAgICAgICAgZnVuYywgYml0bWFzaywgdGhpc0FyZywgcGFydGlhbHMsIGhvbGRlcnMsIHBhcnRpYWxzUmlnaHQsIGhvbGRlcnNSaWdodCxcbiAgICAgICAgYXJnUG9zLCBhcnksIGFyaXR5XG4gICAgICBdO1xuXG4gICAgICBpZiAoZGF0YSkge1xuICAgICAgICBtZXJnZURhdGEobmV3RGF0YSwgZGF0YSk7XG4gICAgICB9XG4gICAgICBmdW5jID0gbmV3RGF0YVswXTtcbiAgICAgIGJpdG1hc2sgPSBuZXdEYXRhWzFdO1xuICAgICAgdGhpc0FyZyA9IG5ld0RhdGFbMl07XG4gICAgICBwYXJ0aWFscyA9IG5ld0RhdGFbM107XG4gICAgICBob2xkZXJzID0gbmV3RGF0YVs0XTtcbiAgICAgIGFyaXR5ID0gbmV3RGF0YVs5XSA9IG5ld0RhdGFbOV0gPT09IHVuZGVmaW5lZFxuICAgICAgICA/IChpc0JpbmRLZXkgPyAwIDogZnVuYy5sZW5ndGgpXG4gICAgICAgIDogbmF0aXZlTWF4KG5ld0RhdGFbOV0gLSBsZW5ndGgsIDApO1xuXG4gICAgICBpZiAoIWFyaXR5ICYmIGJpdG1hc2sgJiAoV1JBUF9DVVJSWV9GTEFHIHwgV1JBUF9DVVJSWV9SSUdIVF9GTEFHKSkge1xuICAgICAgICBiaXRtYXNrICY9IH4oV1JBUF9DVVJSWV9GTEFHIHwgV1JBUF9DVVJSWV9SSUdIVF9GTEFHKTtcbiAgICAgIH1cbiAgICAgIGlmICghYml0bWFzayB8fCBiaXRtYXNrID09IFdSQVBfQklORF9GTEFHKSB7XG4gICAgICAgIHZhciByZXN1bHQgPSBjcmVhdGVCaW5kKGZ1bmMsIGJpdG1hc2ssIHRoaXNBcmcpO1xuICAgICAgfSBlbHNlIGlmIChiaXRtYXNrID09IFdSQVBfQ1VSUllfRkxBRyB8fCBiaXRtYXNrID09IFdSQVBfQ1VSUllfUklHSFRfRkxBRykge1xuICAgICAgICByZXN1bHQgPSBjcmVhdGVDdXJyeShmdW5jLCBiaXRtYXNrLCBhcml0eSk7XG4gICAgICB9IGVsc2UgaWYgKChiaXRtYXNrID09IFdSQVBfUEFSVElBTF9GTEFHIHx8IGJpdG1hc2sgPT0gKFdSQVBfQklORF9GTEFHIHwgV1JBUF9QQVJUSUFMX0ZMQUcpKSAmJiAhaG9sZGVycy5sZW5ndGgpIHtcbiAgICAgICAgcmVzdWx0ID0gY3JlYXRlUGFydGlhbChmdW5jLCBiaXRtYXNrLCB0aGlzQXJnLCBwYXJ0aWFscyk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXN1bHQgPSBjcmVhdGVIeWJyaWQuYXBwbHkodW5kZWZpbmVkLCBuZXdEYXRhKTtcbiAgICAgIH1cbiAgICAgIHZhciBzZXR0ZXIgPSBkYXRhID8gYmFzZVNldERhdGEgOiBzZXREYXRhO1xuICAgICAgcmV0dXJuIHNldFdyYXBUb1N0cmluZyhzZXR0ZXIocmVzdWx0LCBuZXdEYXRhKSwgZnVuYywgYml0bWFzayk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVXNlZCBieSBgXy5kZWZhdWx0c2AgdG8gY3VzdG9taXplIGl0cyBgXy5hc3NpZ25JbmAgdXNlIHRvIGFzc2lnbiBwcm9wZXJ0aWVzXG4gICAgICogb2Ygc291cmNlIG9iamVjdHMgdG8gdGhlIGRlc3RpbmF0aW9uIG9iamVjdCBmb3IgYWxsIGRlc3RpbmF0aW9uIHByb3BlcnRpZXNcbiAgICAgKiB0aGF0IHJlc29sdmUgdG8gYHVuZGVmaW5lZGAuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7Kn0gb2JqVmFsdWUgVGhlIGRlc3RpbmF0aW9uIHZhbHVlLlxuICAgICAqIEBwYXJhbSB7Kn0gc3JjVmFsdWUgVGhlIHNvdXJjZSB2YWx1ZS5cbiAgICAgKiBAcGFyYW0ge3N0cmluZ30ga2V5IFRoZSBrZXkgb2YgdGhlIHByb3BlcnR5IHRvIGFzc2lnbi5cbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBwYXJlbnQgb2JqZWN0IG9mIGBvYmpWYWx1ZWAuXG4gICAgICogQHJldHVybnMgeyp9IFJldHVybnMgdGhlIHZhbHVlIHRvIGFzc2lnbi5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBjdXN0b21EZWZhdWx0c0Fzc2lnbkluKG9ialZhbHVlLCBzcmNWYWx1ZSwga2V5LCBvYmplY3QpIHtcbiAgICAgIGlmIChvYmpWYWx1ZSA9PT0gdW5kZWZpbmVkIHx8XG4gICAgICAgICAgKGVxKG9ialZhbHVlLCBvYmplY3RQcm90b1trZXldKSAmJiAhaGFzT3duUHJvcGVydHkuY2FsbChvYmplY3QsIGtleSkpKSB7XG4gICAgICAgIHJldHVybiBzcmNWYWx1ZTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBvYmpWYWx1ZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBVc2VkIGJ5IGBfLmRlZmF1bHRzRGVlcGAgdG8gY3VzdG9taXplIGl0cyBgXy5tZXJnZWAgdXNlIHRvIG1lcmdlIHNvdXJjZVxuICAgICAqIG9iamVjdHMgaW50byBkZXN0aW5hdGlvbiBvYmplY3RzIHRoYXQgYXJlIHBhc3NlZCB0aHJ1LlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0geyp9IG9ialZhbHVlIFRoZSBkZXN0aW5hdGlvbiB2YWx1ZS5cbiAgICAgKiBAcGFyYW0geyp9IHNyY1ZhbHVlIFRoZSBzb3VyY2UgdmFsdWUuXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGtleSBUaGUga2V5IG9mIHRoZSBwcm9wZXJ0eSB0byBtZXJnZS5cbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBwYXJlbnQgb2JqZWN0IG9mIGBvYmpWYWx1ZWAuXG4gICAgICogQHBhcmFtIHtPYmplY3R9IHNvdXJjZSBUaGUgcGFyZW50IG9iamVjdCBvZiBgc3JjVmFsdWVgLlxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBbc3RhY2tdIFRyYWNrcyB0cmF2ZXJzZWQgc291cmNlIHZhbHVlcyBhbmQgdGhlaXIgbWVyZ2VkXG4gICAgICogIGNvdW50ZXJwYXJ0cy5cbiAgICAgKiBAcmV0dXJucyB7Kn0gUmV0dXJucyB0aGUgdmFsdWUgdG8gYXNzaWduLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGN1c3RvbURlZmF1bHRzTWVyZ2Uob2JqVmFsdWUsIHNyY1ZhbHVlLCBrZXksIG9iamVjdCwgc291cmNlLCBzdGFjaykge1xuICAgICAgaWYgKGlzT2JqZWN0KG9ialZhbHVlKSAmJiBpc09iamVjdChzcmNWYWx1ZSkpIHtcbiAgICAgICAgLy8gUmVjdXJzaXZlbHkgbWVyZ2Ugb2JqZWN0cyBhbmQgYXJyYXlzIChzdXNjZXB0aWJsZSB0byBjYWxsIHN0YWNrIGxpbWl0cykuXG4gICAgICAgIHN0YWNrLnNldChzcmNWYWx1ZSwgb2JqVmFsdWUpO1xuICAgICAgICBiYXNlTWVyZ2Uob2JqVmFsdWUsIHNyY1ZhbHVlLCB1bmRlZmluZWQsIGN1c3RvbURlZmF1bHRzTWVyZ2UsIHN0YWNrKTtcbiAgICAgICAgc3RhY2tbJ2RlbGV0ZSddKHNyY1ZhbHVlKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBvYmpWYWx1ZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBVc2VkIGJ5IGBfLm9taXRgIHRvIGN1c3RvbWl6ZSBpdHMgYF8uY2xvbmVEZWVwYCB1c2UgdG8gb25seSBjbG9uZSBwbGFpblxuICAgICAqIG9iamVjdHMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGluc3BlY3QuXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGtleSBUaGUga2V5IG9mIHRoZSBwcm9wZXJ0eSB0byBpbnNwZWN0LlxuICAgICAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSB1bmNsb25lZCB2YWx1ZSBvciBgdW5kZWZpbmVkYCB0byBkZWZlciBjbG9uaW5nIHRvIGBfLmNsb25lRGVlcGAuXG4gICAgICovXG4gICAgZnVuY3Rpb24gY3VzdG9tT21pdENsb25lKHZhbHVlKSB7XG4gICAgICByZXR1cm4gaXNQbGFpbk9iamVjdCh2YWx1ZSkgPyB1bmRlZmluZWQgOiB2YWx1ZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBBIHNwZWNpYWxpemVkIHZlcnNpb24gb2YgYGJhc2VJc0VxdWFsRGVlcGAgZm9yIGFycmF5cyB3aXRoIHN1cHBvcnQgZm9yXG4gICAgICogcGFydGlhbCBkZWVwIGNvbXBhcmlzb25zLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gY29tcGFyZS5cbiAgICAgKiBAcGFyYW0ge0FycmF5fSBvdGhlciBUaGUgb3RoZXIgYXJyYXkgdG8gY29tcGFyZS5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gYml0bWFzayBUaGUgYml0bWFzayBmbGFncy4gU2VlIGBiYXNlSXNFcXVhbGAgZm9yIG1vcmUgZGV0YWlscy5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBjdXN0b21pemVyIFRoZSBmdW5jdGlvbiB0byBjdXN0b21pemUgY29tcGFyaXNvbnMuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gZXF1YWxGdW5jIFRoZSBmdW5jdGlvbiB0byBkZXRlcm1pbmUgZXF1aXZhbGVudHMgb2YgdmFsdWVzLlxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBzdGFjayBUcmFja3MgdHJhdmVyc2VkIGBhcnJheWAgYW5kIGBvdGhlcmAgb2JqZWN0cy5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgdGhlIGFycmF5cyBhcmUgZXF1aXZhbGVudCwgZWxzZSBgZmFsc2VgLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGVxdWFsQXJyYXlzKGFycmF5LCBvdGhlciwgYml0bWFzaywgY3VzdG9taXplciwgZXF1YWxGdW5jLCBzdGFjaykge1xuICAgICAgdmFyIGlzUGFydGlhbCA9IGJpdG1hc2sgJiBDT01QQVJFX1BBUlRJQUxfRkxBRyxcbiAgICAgICAgICBhcnJMZW5ndGggPSBhcnJheS5sZW5ndGgsXG4gICAgICAgICAgb3RoTGVuZ3RoID0gb3RoZXIubGVuZ3RoO1xuXG4gICAgICBpZiAoYXJyTGVuZ3RoICE9IG90aExlbmd0aCAmJiAhKGlzUGFydGlhbCAmJiBvdGhMZW5ndGggPiBhcnJMZW5ndGgpKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICAgIC8vIENoZWNrIHRoYXQgY3ljbGljIHZhbHVlcyBhcmUgZXF1YWwuXG4gICAgICB2YXIgYXJyU3RhY2tlZCA9IHN0YWNrLmdldChhcnJheSk7XG4gICAgICB2YXIgb3RoU3RhY2tlZCA9IHN0YWNrLmdldChvdGhlcik7XG4gICAgICBpZiAoYXJyU3RhY2tlZCAmJiBvdGhTdGFja2VkKSB7XG4gICAgICAgIHJldHVybiBhcnJTdGFja2VkID09IG90aGVyICYmIG90aFN0YWNrZWQgPT0gYXJyYXk7XG4gICAgICB9XG4gICAgICB2YXIgaW5kZXggPSAtMSxcbiAgICAgICAgICByZXN1bHQgPSB0cnVlLFxuICAgICAgICAgIHNlZW4gPSAoYml0bWFzayAmIENPTVBBUkVfVU5PUkRFUkVEX0ZMQUcpID8gbmV3IFNldENhY2hlIDogdW5kZWZpbmVkO1xuXG4gICAgICBzdGFjay5zZXQoYXJyYXksIG90aGVyKTtcbiAgICAgIHN0YWNrLnNldChvdGhlciwgYXJyYXkpO1xuXG4gICAgICAvLyBJZ25vcmUgbm9uLWluZGV4IHByb3BlcnRpZXMuXG4gICAgICB3aGlsZSAoKytpbmRleCA8IGFyckxlbmd0aCkge1xuICAgICAgICB2YXIgYXJyVmFsdWUgPSBhcnJheVtpbmRleF0sXG4gICAgICAgICAgICBvdGhWYWx1ZSA9IG90aGVyW2luZGV4XTtcblxuICAgICAgICBpZiAoY3VzdG9taXplcikge1xuICAgICAgICAgIHZhciBjb21wYXJlZCA9IGlzUGFydGlhbFxuICAgICAgICAgICAgPyBjdXN0b21pemVyKG90aFZhbHVlLCBhcnJWYWx1ZSwgaW5kZXgsIG90aGVyLCBhcnJheSwgc3RhY2spXG4gICAgICAgICAgICA6IGN1c3RvbWl6ZXIoYXJyVmFsdWUsIG90aFZhbHVlLCBpbmRleCwgYXJyYXksIG90aGVyLCBzdGFjayk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGNvbXBhcmVkICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICBpZiAoY29tcGFyZWQpIHtcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXN1bHQgPSBmYWxzZTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgICAvLyBSZWN1cnNpdmVseSBjb21wYXJlIGFycmF5cyAoc3VzY2VwdGlibGUgdG8gY2FsbCBzdGFjayBsaW1pdHMpLlxuICAgICAgICBpZiAoc2Vlbikge1xuICAgICAgICAgIGlmICghYXJyYXlTb21lKG90aGVyLCBmdW5jdGlvbihvdGhWYWx1ZSwgb3RoSW5kZXgpIHtcbiAgICAgICAgICAgICAgICBpZiAoIWNhY2hlSGFzKHNlZW4sIG90aEluZGV4KSAmJlxuICAgICAgICAgICAgICAgICAgICAoYXJyVmFsdWUgPT09IG90aFZhbHVlIHx8IGVxdWFsRnVuYyhhcnJWYWx1ZSwgb3RoVmFsdWUsIGJpdG1hc2ssIGN1c3RvbWl6ZXIsIHN0YWNrKSkpIHtcbiAgICAgICAgICAgICAgICAgIHJldHVybiBzZWVuLnB1c2gob3RoSW5kZXgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfSkpIHtcbiAgICAgICAgICAgIHJlc3VsdCA9IGZhbHNlO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2UgaWYgKCEoXG4gICAgICAgICAgICAgIGFyclZhbHVlID09PSBvdGhWYWx1ZSB8fFxuICAgICAgICAgICAgICAgIGVxdWFsRnVuYyhhcnJWYWx1ZSwgb3RoVmFsdWUsIGJpdG1hc2ssIGN1c3RvbWl6ZXIsIHN0YWNrKVxuICAgICAgICAgICAgKSkge1xuICAgICAgICAgIHJlc3VsdCA9IGZhbHNlO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBzdGFja1snZGVsZXRlJ10oYXJyYXkpO1xuICAgICAgc3RhY2tbJ2RlbGV0ZSddKG90aGVyKTtcbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQSBzcGVjaWFsaXplZCB2ZXJzaW9uIG9mIGBiYXNlSXNFcXVhbERlZXBgIGZvciBjb21wYXJpbmcgb2JqZWN0cyBvZlxuICAgICAqIHRoZSBzYW1lIGB0b1N0cmluZ1RhZ2AuXG4gICAgICpcbiAgICAgKiAqKk5vdGU6KiogVGhpcyBmdW5jdGlvbiBvbmx5IHN1cHBvcnRzIGNvbXBhcmluZyB2YWx1ZXMgd2l0aCB0YWdzIG9mXG4gICAgICogYEJvb2xlYW5gLCBgRGF0ZWAsIGBFcnJvcmAsIGBOdW1iZXJgLCBgUmVnRXhwYCwgb3IgYFN0cmluZ2AuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBjb21wYXJlLlxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvdGhlciBUaGUgb3RoZXIgb2JqZWN0IHRvIGNvbXBhcmUuXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IHRhZyBUaGUgYHRvU3RyaW5nVGFnYCBvZiB0aGUgb2JqZWN0cyB0byBjb21wYXJlLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBiaXRtYXNrIFRoZSBiaXRtYXNrIGZsYWdzLiBTZWUgYGJhc2VJc0VxdWFsYCBmb3IgbW9yZSBkZXRhaWxzLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGN1c3RvbWl6ZXIgVGhlIGZ1bmN0aW9uIHRvIGN1c3RvbWl6ZSBjb21wYXJpc29ucy5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBlcXVhbEZ1bmMgVGhlIGZ1bmN0aW9uIHRvIGRldGVybWluZSBlcXVpdmFsZW50cyBvZiB2YWx1ZXMuXG4gICAgICogQHBhcmFtIHtPYmplY3R9IHN0YWNrIFRyYWNrcyB0cmF2ZXJzZWQgYG9iamVjdGAgYW5kIGBvdGhlcmAgb2JqZWN0cy5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgdGhlIG9iamVjdHMgYXJlIGVxdWl2YWxlbnQsIGVsc2UgYGZhbHNlYC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBlcXVhbEJ5VGFnKG9iamVjdCwgb3RoZXIsIHRhZywgYml0bWFzaywgY3VzdG9taXplciwgZXF1YWxGdW5jLCBzdGFjaykge1xuICAgICAgc3dpdGNoICh0YWcpIHtcbiAgICAgICAgY2FzZSBkYXRhVmlld1RhZzpcbiAgICAgICAgICBpZiAoKG9iamVjdC5ieXRlTGVuZ3RoICE9IG90aGVyLmJ5dGVMZW5ndGgpIHx8XG4gICAgICAgICAgICAgIChvYmplY3QuYnl0ZU9mZnNldCAhPSBvdGhlci5ieXRlT2Zmc2V0KSkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgIH1cbiAgICAgICAgICBvYmplY3QgPSBvYmplY3QuYnVmZmVyO1xuICAgICAgICAgIG90aGVyID0gb3RoZXIuYnVmZmVyO1xuXG4gICAgICAgIGNhc2UgYXJyYXlCdWZmZXJUYWc6XG4gICAgICAgICAgaWYgKChvYmplY3QuYnl0ZUxlbmd0aCAhPSBvdGhlci5ieXRlTGVuZ3RoKSB8fFxuICAgICAgICAgICAgICAhZXF1YWxGdW5jKG5ldyBVaW50OEFycmF5KG9iamVjdCksIG5ldyBVaW50OEFycmF5KG90aGVyKSkpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIHRydWU7XG5cbiAgICAgICAgY2FzZSBib29sVGFnOlxuICAgICAgICBjYXNlIGRhdGVUYWc6XG4gICAgICAgIGNhc2UgbnVtYmVyVGFnOlxuICAgICAgICAgIC8vIENvZXJjZSBib29sZWFucyB0byBgMWAgb3IgYDBgIGFuZCBkYXRlcyB0byBtaWxsaXNlY29uZHMuXG4gICAgICAgICAgLy8gSW52YWxpZCBkYXRlcyBhcmUgY29lcmNlZCB0byBgTmFOYC5cbiAgICAgICAgICByZXR1cm4gZXEoK29iamVjdCwgK290aGVyKTtcblxuICAgICAgICBjYXNlIGVycm9yVGFnOlxuICAgICAgICAgIHJldHVybiBvYmplY3QubmFtZSA9PSBvdGhlci5uYW1lICYmIG9iamVjdC5tZXNzYWdlID09IG90aGVyLm1lc3NhZ2U7XG5cbiAgICAgICAgY2FzZSByZWdleHBUYWc6XG4gICAgICAgIGNhc2Ugc3RyaW5nVGFnOlxuICAgICAgICAgIC8vIENvZXJjZSByZWdleGVzIHRvIHN0cmluZ3MgYW5kIHRyZWF0IHN0cmluZ3MsIHByaW1pdGl2ZXMgYW5kIG9iamVjdHMsXG4gICAgICAgICAgLy8gYXMgZXF1YWwuIFNlZSBodHRwOi8vd3d3LmVjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNy4wLyNzZWMtcmVnZXhwLnByb3RvdHlwZS50b3N0cmluZ1xuICAgICAgICAgIC8vIGZvciBtb3JlIGRldGFpbHMuXG4gICAgICAgICAgcmV0dXJuIG9iamVjdCA9PSAob3RoZXIgKyAnJyk7XG5cbiAgICAgICAgY2FzZSBtYXBUYWc6XG4gICAgICAgICAgdmFyIGNvbnZlcnQgPSBtYXBUb0FycmF5O1xuXG4gICAgICAgIGNhc2Ugc2V0VGFnOlxuICAgICAgICAgIHZhciBpc1BhcnRpYWwgPSBiaXRtYXNrICYgQ09NUEFSRV9QQVJUSUFMX0ZMQUc7XG4gICAgICAgICAgY29udmVydCB8fCAoY29udmVydCA9IHNldFRvQXJyYXkpO1xuXG4gICAgICAgICAgaWYgKG9iamVjdC5zaXplICE9IG90aGVyLnNpemUgJiYgIWlzUGFydGlhbCkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgIH1cbiAgICAgICAgICAvLyBBc3N1bWUgY3ljbGljIHZhbHVlcyBhcmUgZXF1YWwuXG4gICAgICAgICAgdmFyIHN0YWNrZWQgPSBzdGFjay5nZXQob2JqZWN0KTtcbiAgICAgICAgICBpZiAoc3RhY2tlZCkge1xuICAgICAgICAgICAgcmV0dXJuIHN0YWNrZWQgPT0gb3RoZXI7XG4gICAgICAgICAgfVxuICAgICAgICAgIGJpdG1hc2sgfD0gQ09NUEFSRV9VTk9SREVSRURfRkxBRztcblxuICAgICAgICAgIC8vIFJlY3Vyc2l2ZWx5IGNvbXBhcmUgb2JqZWN0cyAoc3VzY2VwdGlibGUgdG8gY2FsbCBzdGFjayBsaW1pdHMpLlxuICAgICAgICAgIHN0YWNrLnNldChvYmplY3QsIG90aGVyKTtcbiAgICAgICAgICB2YXIgcmVzdWx0ID0gZXF1YWxBcnJheXMoY29udmVydChvYmplY3QpLCBjb252ZXJ0KG90aGVyKSwgYml0bWFzaywgY3VzdG9taXplciwgZXF1YWxGdW5jLCBzdGFjayk7XG4gICAgICAgICAgc3RhY2tbJ2RlbGV0ZSddKG9iamVjdCk7XG4gICAgICAgICAgcmV0dXJuIHJlc3VsdDtcblxuICAgICAgICBjYXNlIHN5bWJvbFRhZzpcbiAgICAgICAgICBpZiAoc3ltYm9sVmFsdWVPZikge1xuICAgICAgICAgICAgcmV0dXJuIHN5bWJvbFZhbHVlT2YuY2FsbChvYmplY3QpID09IHN5bWJvbFZhbHVlT2YuY2FsbChvdGhlcik7XG4gICAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEEgc3BlY2lhbGl6ZWQgdmVyc2lvbiBvZiBgYmFzZUlzRXF1YWxEZWVwYCBmb3Igb2JqZWN0cyB3aXRoIHN1cHBvcnQgZm9yXG4gICAgICogcGFydGlhbCBkZWVwIGNvbXBhcmlzb25zLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gY29tcGFyZS5cbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb3RoZXIgVGhlIG90aGVyIG9iamVjdCB0byBjb21wYXJlLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBiaXRtYXNrIFRoZSBiaXRtYXNrIGZsYWdzLiBTZWUgYGJhc2VJc0VxdWFsYCBmb3IgbW9yZSBkZXRhaWxzLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGN1c3RvbWl6ZXIgVGhlIGZ1bmN0aW9uIHRvIGN1c3RvbWl6ZSBjb21wYXJpc29ucy5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBlcXVhbEZ1bmMgVGhlIGZ1bmN0aW9uIHRvIGRldGVybWluZSBlcXVpdmFsZW50cyBvZiB2YWx1ZXMuXG4gICAgICogQHBhcmFtIHtPYmplY3R9IHN0YWNrIFRyYWNrcyB0cmF2ZXJzZWQgYG9iamVjdGAgYW5kIGBvdGhlcmAgb2JqZWN0cy5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgdGhlIG9iamVjdHMgYXJlIGVxdWl2YWxlbnQsIGVsc2UgYGZhbHNlYC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBlcXVhbE9iamVjdHMob2JqZWN0LCBvdGhlciwgYml0bWFzaywgY3VzdG9taXplciwgZXF1YWxGdW5jLCBzdGFjaykge1xuICAgICAgdmFyIGlzUGFydGlhbCA9IGJpdG1hc2sgJiBDT01QQVJFX1BBUlRJQUxfRkxBRyxcbiAgICAgICAgICBvYmpQcm9wcyA9IGdldEFsbEtleXMob2JqZWN0KSxcbiAgICAgICAgICBvYmpMZW5ndGggPSBvYmpQcm9wcy5sZW5ndGgsXG4gICAgICAgICAgb3RoUHJvcHMgPSBnZXRBbGxLZXlzKG90aGVyKSxcbiAgICAgICAgICBvdGhMZW5ndGggPSBvdGhQcm9wcy5sZW5ndGg7XG5cbiAgICAgIGlmIChvYmpMZW5ndGggIT0gb3RoTGVuZ3RoICYmICFpc1BhcnRpYWwpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgICAgdmFyIGluZGV4ID0gb2JqTGVuZ3RoO1xuICAgICAgd2hpbGUgKGluZGV4LS0pIHtcbiAgICAgICAgdmFyIGtleSA9IG9ialByb3BzW2luZGV4XTtcbiAgICAgICAgaWYgKCEoaXNQYXJ0aWFsID8ga2V5IGluIG90aGVyIDogaGFzT3duUHJvcGVydHkuY2FsbChvdGhlciwga2V5KSkpIHtcbiAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIC8vIENoZWNrIHRoYXQgY3ljbGljIHZhbHVlcyBhcmUgZXF1YWwuXG4gICAgICB2YXIgb2JqU3RhY2tlZCA9IHN0YWNrLmdldChvYmplY3QpO1xuICAgICAgdmFyIG90aFN0YWNrZWQgPSBzdGFjay5nZXQob3RoZXIpO1xuICAgICAgaWYgKG9ialN0YWNrZWQgJiYgb3RoU3RhY2tlZCkge1xuICAgICAgICByZXR1cm4gb2JqU3RhY2tlZCA9PSBvdGhlciAmJiBvdGhTdGFja2VkID09IG9iamVjdDtcbiAgICAgIH1cbiAgICAgIHZhciByZXN1bHQgPSB0cnVlO1xuICAgICAgc3RhY2suc2V0KG9iamVjdCwgb3RoZXIpO1xuICAgICAgc3RhY2suc2V0KG90aGVyLCBvYmplY3QpO1xuXG4gICAgICB2YXIgc2tpcEN0b3IgPSBpc1BhcnRpYWw7XG4gICAgICB3aGlsZSAoKytpbmRleCA8IG9iakxlbmd0aCkge1xuICAgICAgICBrZXkgPSBvYmpQcm9wc1tpbmRleF07XG4gICAgICAgIHZhciBvYmpWYWx1ZSA9IG9iamVjdFtrZXldLFxuICAgICAgICAgICAgb3RoVmFsdWUgPSBvdGhlcltrZXldO1xuXG4gICAgICAgIGlmIChjdXN0b21pemVyKSB7XG4gICAgICAgICAgdmFyIGNvbXBhcmVkID0gaXNQYXJ0aWFsXG4gICAgICAgICAgICA/IGN1c3RvbWl6ZXIob3RoVmFsdWUsIG9ialZhbHVlLCBrZXksIG90aGVyLCBvYmplY3QsIHN0YWNrKVxuICAgICAgICAgICAgOiBjdXN0b21pemVyKG9ialZhbHVlLCBvdGhWYWx1ZSwga2V5LCBvYmplY3QsIG90aGVyLCBzdGFjayk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gUmVjdXJzaXZlbHkgY29tcGFyZSBvYmplY3RzIChzdXNjZXB0aWJsZSB0byBjYWxsIHN0YWNrIGxpbWl0cykuXG4gICAgICAgIGlmICghKGNvbXBhcmVkID09PSB1bmRlZmluZWRcbiAgICAgICAgICAgICAgPyAob2JqVmFsdWUgPT09IG90aFZhbHVlIHx8IGVxdWFsRnVuYyhvYmpWYWx1ZSwgb3RoVmFsdWUsIGJpdG1hc2ssIGN1c3RvbWl6ZXIsIHN0YWNrKSlcbiAgICAgICAgICAgICAgOiBjb21wYXJlZFxuICAgICAgICAgICAgKSkge1xuICAgICAgICAgIHJlc3VsdCA9IGZhbHNlO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICAgIHNraXBDdG9yIHx8IChza2lwQ3RvciA9IGtleSA9PSAnY29uc3RydWN0b3InKTtcbiAgICAgIH1cbiAgICAgIGlmIChyZXN1bHQgJiYgIXNraXBDdG9yKSB7XG4gICAgICAgIHZhciBvYmpDdG9yID0gb2JqZWN0LmNvbnN0cnVjdG9yLFxuICAgICAgICAgICAgb3RoQ3RvciA9IG90aGVyLmNvbnN0cnVjdG9yO1xuXG4gICAgICAgIC8vIE5vbiBgT2JqZWN0YCBvYmplY3QgaW5zdGFuY2VzIHdpdGggZGlmZmVyZW50IGNvbnN0cnVjdG9ycyBhcmUgbm90IGVxdWFsLlxuICAgICAgICBpZiAob2JqQ3RvciAhPSBvdGhDdG9yICYmXG4gICAgICAgICAgICAoJ2NvbnN0cnVjdG9yJyBpbiBvYmplY3QgJiYgJ2NvbnN0cnVjdG9yJyBpbiBvdGhlcikgJiZcbiAgICAgICAgICAgICEodHlwZW9mIG9iakN0b3IgPT0gJ2Z1bmN0aW9uJyAmJiBvYmpDdG9yIGluc3RhbmNlb2Ygb2JqQ3RvciAmJlxuICAgICAgICAgICAgICB0eXBlb2Ygb3RoQ3RvciA9PSAnZnVuY3Rpb24nICYmIG90aEN0b3IgaW5zdGFuY2VvZiBvdGhDdG9yKSkge1xuICAgICAgICAgIHJlc3VsdCA9IGZhbHNlO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBzdGFja1snZGVsZXRlJ10ob2JqZWN0KTtcbiAgICAgIHN0YWNrWydkZWxldGUnXShvdGhlcik7XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEEgc3BlY2lhbGl6ZWQgdmVyc2lvbiBvZiBgYmFzZVJlc3RgIHdoaWNoIGZsYXR0ZW5zIHRoZSByZXN0IGFycmF5LlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byBhcHBseSBhIHJlc3QgcGFyYW1ldGVyIHRvLlxuICAgICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IGZ1bmN0aW9uLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGZsYXRSZXN0KGZ1bmMpIHtcbiAgICAgIHJldHVybiBzZXRUb1N0cmluZyhvdmVyUmVzdChmdW5jLCB1bmRlZmluZWQsIGZsYXR0ZW4pLCBmdW5jICsgJycpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYW4gYXJyYXkgb2Ygb3duIGVudW1lcmFibGUgcHJvcGVydHkgbmFtZXMgYW5kIHN5bWJvbHMgb2YgYG9iamVjdGAuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBxdWVyeS5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIGFycmF5IG9mIHByb3BlcnR5IG5hbWVzIGFuZCBzeW1ib2xzLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGdldEFsbEtleXMob2JqZWN0KSB7XG4gICAgICByZXR1cm4gYmFzZUdldEFsbEtleXMob2JqZWN0LCBrZXlzLCBnZXRTeW1ib2xzKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGFuIGFycmF5IG9mIG93biBhbmQgaW5oZXJpdGVkIGVudW1lcmFibGUgcHJvcGVydHkgbmFtZXMgYW5kXG4gICAgICogc3ltYm9scyBvZiBgb2JqZWN0YC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIHF1ZXJ5LlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgYXJyYXkgb2YgcHJvcGVydHkgbmFtZXMgYW5kIHN5bWJvbHMuXG4gICAgICovXG4gICAgZnVuY3Rpb24gZ2V0QWxsS2V5c0luKG9iamVjdCkge1xuICAgICAgcmV0dXJuIGJhc2VHZXRBbGxLZXlzKG9iamVjdCwga2V5c0luLCBnZXRTeW1ib2xzSW4pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldHMgbWV0YWRhdGEgZm9yIGBmdW5jYC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gZnVuYyBUaGUgZnVuY3Rpb24gdG8gcXVlcnkuXG4gICAgICogQHJldHVybnMgeyp9IFJldHVybnMgdGhlIG1ldGFkYXRhIGZvciBgZnVuY2AuXG4gICAgICovXG4gICAgdmFyIGdldERhdGEgPSAhbWV0YU1hcCA/IG5vb3AgOiBmdW5jdGlvbihmdW5jKSB7XG4gICAgICByZXR1cm4gbWV0YU1hcC5nZXQoZnVuYyk7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIEdldHMgdGhlIG5hbWUgb2YgYGZ1bmNgLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byBxdWVyeS5cbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfSBSZXR1cm5zIHRoZSBmdW5jdGlvbiBuYW1lLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGdldEZ1bmNOYW1lKGZ1bmMpIHtcbiAgICAgIHZhciByZXN1bHQgPSAoZnVuYy5uYW1lICsgJycpLFxuICAgICAgICAgIGFycmF5ID0gcmVhbE5hbWVzW3Jlc3VsdF0sXG4gICAgICAgICAgbGVuZ3RoID0gaGFzT3duUHJvcGVydHkuY2FsbChyZWFsTmFtZXMsIHJlc3VsdCkgPyBhcnJheS5sZW5ndGggOiAwO1xuXG4gICAgICB3aGlsZSAobGVuZ3RoLS0pIHtcbiAgICAgICAgdmFyIGRhdGEgPSBhcnJheVtsZW5ndGhdLFxuICAgICAgICAgICAgb3RoZXJGdW5jID0gZGF0YS5mdW5jO1xuICAgICAgICBpZiAob3RoZXJGdW5jID09IG51bGwgfHwgb3RoZXJGdW5jID09IGZ1bmMpIHtcbiAgICAgICAgICByZXR1cm4gZGF0YS5uYW1lO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldHMgdGhlIGFyZ3VtZW50IHBsYWNlaG9sZGVyIHZhbHVlIGZvciBgZnVuY2AuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIGluc3BlY3QuXG4gICAgICogQHJldHVybnMgeyp9IFJldHVybnMgdGhlIHBsYWNlaG9sZGVyIHZhbHVlLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGdldEhvbGRlcihmdW5jKSB7XG4gICAgICB2YXIgb2JqZWN0ID0gaGFzT3duUHJvcGVydHkuY2FsbChsb2Rhc2gsICdwbGFjZWhvbGRlcicpID8gbG9kYXNoIDogZnVuYztcbiAgICAgIHJldHVybiBvYmplY3QucGxhY2Vob2xkZXI7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0cyB0aGUgYXBwcm9wcmlhdGUgXCJpdGVyYXRlZVwiIGZ1bmN0aW9uLiBJZiBgXy5pdGVyYXRlZWAgaXMgY3VzdG9taXplZCxcbiAgICAgKiB0aGlzIGZ1bmN0aW9uIHJldHVybnMgdGhlIGN1c3RvbSBtZXRob2QsIG90aGVyd2lzZSBpdCByZXR1cm5zIGBiYXNlSXRlcmF0ZWVgLlxuICAgICAqIElmIGFyZ3VtZW50cyBhcmUgcHJvdmlkZWQsIHRoZSBjaG9zZW4gZnVuY3Rpb24gaXMgaW52b2tlZCB3aXRoIHRoZW0gYW5kXG4gICAgICogaXRzIHJlc3VsdCBpcyByZXR1cm5lZC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHsqfSBbdmFsdWVdIFRoZSB2YWx1ZSB0byBjb252ZXJ0IHRvIGFuIGl0ZXJhdGVlLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbYXJpdHldIFRoZSBhcml0eSBvZiB0aGUgY3JlYXRlZCBpdGVyYXRlZS5cbiAgICAgKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIGNob3NlbiBmdW5jdGlvbiBvciBpdHMgcmVzdWx0LlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGdldEl0ZXJhdGVlKCkge1xuICAgICAgdmFyIHJlc3VsdCA9IGxvZGFzaC5pdGVyYXRlZSB8fCBpdGVyYXRlZTtcbiAgICAgIHJlc3VsdCA9IHJlc3VsdCA9PT0gaXRlcmF0ZWUgPyBiYXNlSXRlcmF0ZWUgOiByZXN1bHQ7XG4gICAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/IHJlc3VsdChhcmd1bWVudHNbMF0sIGFyZ3VtZW50c1sxXSkgOiByZXN1bHQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0cyB0aGUgZGF0YSBmb3IgYG1hcGAuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBtYXAgVGhlIG1hcCB0byBxdWVyeS5cbiAgICAgKiBAcGFyYW0ge3N0cmluZ30ga2V5IFRoZSByZWZlcmVuY2Uga2V5LlxuICAgICAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSBtYXAgZGF0YS5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBnZXRNYXBEYXRhKG1hcCwga2V5KSB7XG4gICAgICB2YXIgZGF0YSA9IG1hcC5fX2RhdGFfXztcbiAgICAgIHJldHVybiBpc0tleWFibGUoa2V5KVxuICAgICAgICA/IGRhdGFbdHlwZW9mIGtleSA9PSAnc3RyaW5nJyA/ICdzdHJpbmcnIDogJ2hhc2gnXVxuICAgICAgICA6IGRhdGEubWFwO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldHMgdGhlIHByb3BlcnR5IG5hbWVzLCB2YWx1ZXMsIGFuZCBjb21wYXJlIGZsYWdzIG9mIGBvYmplY3RgLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gcXVlcnkuXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBtYXRjaCBkYXRhIG9mIGBvYmplY3RgLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGdldE1hdGNoRGF0YShvYmplY3QpIHtcbiAgICAgIHZhciByZXN1bHQgPSBrZXlzKG9iamVjdCksXG4gICAgICAgICAgbGVuZ3RoID0gcmVzdWx0Lmxlbmd0aDtcblxuICAgICAgd2hpbGUgKGxlbmd0aC0tKSB7XG4gICAgICAgIHZhciBrZXkgPSByZXN1bHRbbGVuZ3RoXSxcbiAgICAgICAgICAgIHZhbHVlID0gb2JqZWN0W2tleV07XG5cbiAgICAgICAgcmVzdWx0W2xlbmd0aF0gPSBba2V5LCB2YWx1ZSwgaXNTdHJpY3RDb21wYXJhYmxlKHZhbHVlKV07XG4gICAgICB9XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldHMgdGhlIG5hdGl2ZSBmdW5jdGlvbiBhdCBga2V5YCBvZiBgb2JqZWN0YC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIHF1ZXJ5LlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgVGhlIGtleSBvZiB0aGUgbWV0aG9kIHRvIGdldC5cbiAgICAgKiBAcmV0dXJucyB7Kn0gUmV0dXJucyB0aGUgZnVuY3Rpb24gaWYgaXQncyBuYXRpdmUsIGVsc2UgYHVuZGVmaW5lZGAuXG4gICAgICovXG4gICAgZnVuY3Rpb24gZ2V0TmF0aXZlKG9iamVjdCwga2V5KSB7XG4gICAgICB2YXIgdmFsdWUgPSBnZXRWYWx1ZShvYmplY3QsIGtleSk7XG4gICAgICByZXR1cm4gYmFzZUlzTmF0aXZlKHZhbHVlKSA/IHZhbHVlIDogdW5kZWZpbmVkO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEEgc3BlY2lhbGl6ZWQgdmVyc2lvbiBvZiBgYmFzZUdldFRhZ2Agd2hpY2ggaWdub3JlcyBgU3ltYm9sLnRvU3RyaW5nVGFnYCB2YWx1ZXMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIHF1ZXJ5LlxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IFJldHVybnMgdGhlIHJhdyBgdG9TdHJpbmdUYWdgLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGdldFJhd1RhZyh2YWx1ZSkge1xuICAgICAgdmFyIGlzT3duID0gaGFzT3duUHJvcGVydHkuY2FsbCh2YWx1ZSwgc3ltVG9TdHJpbmdUYWcpLFxuICAgICAgICAgIHRhZyA9IHZhbHVlW3N5bVRvU3RyaW5nVGFnXTtcblxuICAgICAgdHJ5IHtcbiAgICAgICAgdmFsdWVbc3ltVG9TdHJpbmdUYWddID0gdW5kZWZpbmVkO1xuICAgICAgICB2YXIgdW5tYXNrZWQgPSB0cnVlO1xuICAgICAgfSBjYXRjaCAoZSkge31cblxuICAgICAgdmFyIHJlc3VsdCA9IG5hdGl2ZU9iamVjdFRvU3RyaW5nLmNhbGwodmFsdWUpO1xuICAgICAgaWYgKHVubWFza2VkKSB7XG4gICAgICAgIGlmIChpc093bikge1xuICAgICAgICAgIHZhbHVlW3N5bVRvU3RyaW5nVGFnXSA9IHRhZztcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBkZWxldGUgdmFsdWVbc3ltVG9TdHJpbmdUYWddO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYW4gYXJyYXkgb2YgdGhlIG93biBlbnVtZXJhYmxlIHN5bWJvbHMgb2YgYG9iamVjdGAuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBxdWVyeS5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIGFycmF5IG9mIHN5bWJvbHMuXG4gICAgICovXG4gICAgdmFyIGdldFN5bWJvbHMgPSAhbmF0aXZlR2V0U3ltYm9scyA/IHN0dWJBcnJheSA6IGZ1bmN0aW9uKG9iamVjdCkge1xuICAgICAgaWYgKG9iamVjdCA9PSBudWxsKSB7XG4gICAgICAgIHJldHVybiBbXTtcbiAgICAgIH1cbiAgICAgIG9iamVjdCA9IE9iamVjdChvYmplY3QpO1xuICAgICAgcmV0dXJuIGFycmF5RmlsdGVyKG5hdGl2ZUdldFN5bWJvbHMob2JqZWN0KSwgZnVuY3Rpb24oc3ltYm9sKSB7XG4gICAgICAgIHJldHVybiBwcm9wZXJ0eUlzRW51bWVyYWJsZS5jYWxsKG9iamVjdCwgc3ltYm9sKTtcbiAgICAgIH0pO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGFuIGFycmF5IG9mIHRoZSBvd24gYW5kIGluaGVyaXRlZCBlbnVtZXJhYmxlIHN5bWJvbHMgb2YgYG9iamVjdGAuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBxdWVyeS5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIGFycmF5IG9mIHN5bWJvbHMuXG4gICAgICovXG4gICAgdmFyIGdldFN5bWJvbHNJbiA9ICFuYXRpdmVHZXRTeW1ib2xzID8gc3R1YkFycmF5IDogZnVuY3Rpb24ob2JqZWN0KSB7XG4gICAgICB2YXIgcmVzdWx0ID0gW107XG4gICAgICB3aGlsZSAob2JqZWN0KSB7XG4gICAgICAgIGFycmF5UHVzaChyZXN1bHQsIGdldFN5bWJvbHMob2JqZWN0KSk7XG4gICAgICAgIG9iamVjdCA9IGdldFByb3RvdHlwZShvYmplY3QpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogR2V0cyB0aGUgYHRvU3RyaW5nVGFnYCBvZiBgdmFsdWVgLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBxdWVyeS5cbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfSBSZXR1cm5zIHRoZSBgdG9TdHJpbmdUYWdgLlxuICAgICAqL1xuICAgIHZhciBnZXRUYWcgPSBiYXNlR2V0VGFnO1xuXG4gICAgLy8gRmFsbGJhY2sgZm9yIGRhdGEgdmlld3MsIG1hcHMsIHNldHMsIGFuZCB3ZWFrIG1hcHMgaW4gSUUgMTEgYW5kIHByb21pc2VzIGluIE5vZGUuanMgPCA2LlxuICAgIGlmICgoRGF0YVZpZXcgJiYgZ2V0VGFnKG5ldyBEYXRhVmlldyhuZXcgQXJyYXlCdWZmZXIoMSkpKSAhPSBkYXRhVmlld1RhZykgfHxcbiAgICAgICAgKE1hcCAmJiBnZXRUYWcobmV3IE1hcCkgIT0gbWFwVGFnKSB8fFxuICAgICAgICAoUHJvbWlzZSAmJiBnZXRUYWcoUHJvbWlzZS5yZXNvbHZlKCkpICE9IHByb21pc2VUYWcpIHx8XG4gICAgICAgIChTZXQgJiYgZ2V0VGFnKG5ldyBTZXQpICE9IHNldFRhZykgfHxcbiAgICAgICAgKFdlYWtNYXAgJiYgZ2V0VGFnKG5ldyBXZWFrTWFwKSAhPSB3ZWFrTWFwVGFnKSkge1xuICAgICAgZ2V0VGFnID0gZnVuY3Rpb24odmFsdWUpIHtcbiAgICAgICAgdmFyIHJlc3VsdCA9IGJhc2VHZXRUYWcodmFsdWUpLFxuICAgICAgICAgICAgQ3RvciA9IHJlc3VsdCA9PSBvYmplY3RUYWcgPyB2YWx1ZS5jb25zdHJ1Y3RvciA6IHVuZGVmaW5lZCxcbiAgICAgICAgICAgIGN0b3JTdHJpbmcgPSBDdG9yID8gdG9Tb3VyY2UoQ3RvcikgOiAnJztcblxuICAgICAgICBpZiAoY3RvclN0cmluZykge1xuICAgICAgICAgIHN3aXRjaCAoY3RvclN0cmluZykge1xuICAgICAgICAgICAgY2FzZSBkYXRhVmlld0N0b3JTdHJpbmc6IHJldHVybiBkYXRhVmlld1RhZztcbiAgICAgICAgICAgIGNhc2UgbWFwQ3RvclN0cmluZzogcmV0dXJuIG1hcFRhZztcbiAgICAgICAgICAgIGNhc2UgcHJvbWlzZUN0b3JTdHJpbmc6IHJldHVybiBwcm9taXNlVGFnO1xuICAgICAgICAgICAgY2FzZSBzZXRDdG9yU3RyaW5nOiByZXR1cm4gc2V0VGFnO1xuICAgICAgICAgICAgY2FzZSB3ZWFrTWFwQ3RvclN0cmluZzogcmV0dXJuIHdlYWtNYXBUYWc7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICB9O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldHMgdGhlIHZpZXcsIGFwcGx5aW5nIGFueSBgdHJhbnNmb3Jtc2AgdG8gdGhlIGBzdGFydGAgYW5kIGBlbmRgIHBvc2l0aW9ucy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHN0YXJ0IFRoZSBzdGFydCBvZiB0aGUgdmlldy5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gZW5kIFRoZSBlbmQgb2YgdGhlIHZpZXcuXG4gICAgICogQHBhcmFtIHtBcnJheX0gdHJhbnNmb3JtcyBUaGUgdHJhbnNmb3JtYXRpb25zIHRvIGFwcGx5IHRvIHRoZSB2aWV3LlxuICAgICAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgYW4gb2JqZWN0IGNvbnRhaW5pbmcgdGhlIGBzdGFydGAgYW5kIGBlbmRgXG4gICAgICogIHBvc2l0aW9ucyBvZiB0aGUgdmlldy5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBnZXRWaWV3KHN0YXJ0LCBlbmQsIHRyYW5zZm9ybXMpIHtcbiAgICAgIHZhciBpbmRleCA9IC0xLFxuICAgICAgICAgIGxlbmd0aCA9IHRyYW5zZm9ybXMubGVuZ3RoO1xuXG4gICAgICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgICAgICB2YXIgZGF0YSA9IHRyYW5zZm9ybXNbaW5kZXhdLFxuICAgICAgICAgICAgc2l6ZSA9IGRhdGEuc2l6ZTtcblxuICAgICAgICBzd2l0Y2ggKGRhdGEudHlwZSkge1xuICAgICAgICAgIGNhc2UgJ2Ryb3AnOiAgICAgIHN0YXJ0ICs9IHNpemU7IGJyZWFrO1xuICAgICAgICAgIGNhc2UgJ2Ryb3BSaWdodCc6IGVuZCAtPSBzaXplOyBicmVhaztcbiAgICAgICAgICBjYXNlICd0YWtlJzogICAgICBlbmQgPSBuYXRpdmVNaW4oZW5kLCBzdGFydCArIHNpemUpOyBicmVhaztcbiAgICAgICAgICBjYXNlICd0YWtlUmlnaHQnOiBzdGFydCA9IG5hdGl2ZU1heChzdGFydCwgZW5kIC0gc2l6ZSk7IGJyZWFrO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4geyAnc3RhcnQnOiBzdGFydCwgJ2VuZCc6IGVuZCB9O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEV4dHJhY3RzIHdyYXBwZXIgZGV0YWlscyBmcm9tIHRoZSBgc291cmNlYCBib2R5IGNvbW1lbnQuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBzb3VyY2UgVGhlIHNvdXJjZSB0byBpbnNwZWN0LlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgd3JhcHBlciBkZXRhaWxzLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGdldFdyYXBEZXRhaWxzKHNvdXJjZSkge1xuICAgICAgdmFyIG1hdGNoID0gc291cmNlLm1hdGNoKHJlV3JhcERldGFpbHMpO1xuICAgICAgcmV0dXJuIG1hdGNoID8gbWF0Y2hbMV0uc3BsaXQocmVTcGxpdERldGFpbHMpIDogW107XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2hlY2tzIGlmIGBwYXRoYCBleGlzdHMgb24gYG9iamVjdGAuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBxdWVyeS5cbiAgICAgKiBAcGFyYW0ge0FycmF5fHN0cmluZ30gcGF0aCBUaGUgcGF0aCB0byBjaGVjay5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBoYXNGdW5jIFRoZSBmdW5jdGlvbiB0byBjaGVjayBwcm9wZXJ0aWVzLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgcGF0aGAgZXhpc3RzLCBlbHNlIGBmYWxzZWAuXG4gICAgICovXG4gICAgZnVuY3Rpb24gaGFzUGF0aChvYmplY3QsIHBhdGgsIGhhc0Z1bmMpIHtcbiAgICAgIHBhdGggPSBjYXN0UGF0aChwYXRoLCBvYmplY3QpO1xuXG4gICAgICB2YXIgaW5kZXggPSAtMSxcbiAgICAgICAgICBsZW5ndGggPSBwYXRoLmxlbmd0aCxcbiAgICAgICAgICByZXN1bHQgPSBmYWxzZTtcblxuICAgICAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHtcbiAgICAgICAgdmFyIGtleSA9IHRvS2V5KHBhdGhbaW5kZXhdKTtcbiAgICAgICAgaWYgKCEocmVzdWx0ID0gb2JqZWN0ICE9IG51bGwgJiYgaGFzRnVuYyhvYmplY3QsIGtleSkpKSB7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgICAgb2JqZWN0ID0gb2JqZWN0W2tleV07XG4gICAgICB9XG4gICAgICBpZiAocmVzdWx0IHx8ICsraW5kZXggIT0gbGVuZ3RoKSB7XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICB9XG4gICAgICBsZW5ndGggPSBvYmplY3QgPT0gbnVsbCA/IDAgOiBvYmplY3QubGVuZ3RoO1xuICAgICAgcmV0dXJuICEhbGVuZ3RoICYmIGlzTGVuZ3RoKGxlbmd0aCkgJiYgaXNJbmRleChrZXksIGxlbmd0aCkgJiZcbiAgICAgICAgKGlzQXJyYXkob2JqZWN0KSB8fCBpc0FyZ3VtZW50cyhvYmplY3QpKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBJbml0aWFsaXplcyBhbiBhcnJheSBjbG9uZS5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIGNsb25lLlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgaW5pdGlhbGl6ZWQgY2xvbmUuXG4gICAgICovXG4gICAgZnVuY3Rpb24gaW5pdENsb25lQXJyYXkoYXJyYXkpIHtcbiAgICAgIHZhciBsZW5ndGggPSBhcnJheS5sZW5ndGgsXG4gICAgICAgICAgcmVzdWx0ID0gbmV3IGFycmF5LmNvbnN0cnVjdG9yKGxlbmd0aCk7XG5cbiAgICAgIC8vIEFkZCBwcm9wZXJ0aWVzIGFzc2lnbmVkIGJ5IGBSZWdFeHAjZXhlY2AuXG4gICAgICBpZiAobGVuZ3RoICYmIHR5cGVvZiBhcnJheVswXSA9PSAnc3RyaW5nJyAmJiBoYXNPd25Qcm9wZXJ0eS5jYWxsKGFycmF5LCAnaW5kZXgnKSkge1xuICAgICAgICByZXN1bHQuaW5kZXggPSBhcnJheS5pbmRleDtcbiAgICAgICAgcmVzdWx0LmlucHV0ID0gYXJyYXkuaW5wdXQ7XG4gICAgICB9XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEluaXRpYWxpemVzIGFuIG9iamVjdCBjbG9uZS5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIGNsb25lLlxuICAgICAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgdGhlIGluaXRpYWxpemVkIGNsb25lLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGluaXRDbG9uZU9iamVjdChvYmplY3QpIHtcbiAgICAgIHJldHVybiAodHlwZW9mIG9iamVjdC5jb25zdHJ1Y3RvciA9PSAnZnVuY3Rpb24nICYmICFpc1Byb3RvdHlwZShvYmplY3QpKVxuICAgICAgICA/IGJhc2VDcmVhdGUoZ2V0UHJvdG90eXBlKG9iamVjdCkpXG4gICAgICAgIDoge307XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogSW5pdGlhbGl6ZXMgYW4gb2JqZWN0IGNsb25lIGJhc2VkIG9uIGl0cyBgdG9TdHJpbmdUYWdgLlxuICAgICAqXG4gICAgICogKipOb3RlOioqIFRoaXMgZnVuY3Rpb24gb25seSBzdXBwb3J0cyBjbG9uaW5nIHZhbHVlcyB3aXRoIHRhZ3Mgb2ZcbiAgICAgKiBgQm9vbGVhbmAsIGBEYXRlYCwgYEVycm9yYCwgYE1hcGAsIGBOdW1iZXJgLCBgUmVnRXhwYCwgYFNldGAsIG9yIGBTdHJpbmdgLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gY2xvbmUuXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IHRhZyBUaGUgYHRvU3RyaW5nVGFnYCBvZiB0aGUgb2JqZWN0IHRvIGNsb25lLlxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbn0gW2lzRGVlcF0gU3BlY2lmeSBhIGRlZXAgY2xvbmUuXG4gICAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyB0aGUgaW5pdGlhbGl6ZWQgY2xvbmUuXG4gICAgICovXG4gICAgZnVuY3Rpb24gaW5pdENsb25lQnlUYWcob2JqZWN0LCB0YWcsIGlzRGVlcCkge1xuICAgICAgdmFyIEN0b3IgPSBvYmplY3QuY29uc3RydWN0b3I7XG4gICAgICBzd2l0Y2ggKHRhZykge1xuICAgICAgICBjYXNlIGFycmF5QnVmZmVyVGFnOlxuICAgICAgICAgIHJldHVybiBjbG9uZUFycmF5QnVmZmVyKG9iamVjdCk7XG5cbiAgICAgICAgY2FzZSBib29sVGFnOlxuICAgICAgICBjYXNlIGRhdGVUYWc6XG4gICAgICAgICAgcmV0dXJuIG5ldyBDdG9yKCtvYmplY3QpO1xuXG4gICAgICAgIGNhc2UgZGF0YVZpZXdUYWc6XG4gICAgICAgICAgcmV0dXJuIGNsb25lRGF0YVZpZXcob2JqZWN0LCBpc0RlZXApO1xuXG4gICAgICAgIGNhc2UgZmxvYXQzMlRhZzogY2FzZSBmbG9hdDY0VGFnOlxuICAgICAgICBjYXNlIGludDhUYWc6IGNhc2UgaW50MTZUYWc6IGNhc2UgaW50MzJUYWc6XG4gICAgICAgIGNhc2UgdWludDhUYWc6IGNhc2UgdWludDhDbGFtcGVkVGFnOiBjYXNlIHVpbnQxNlRhZzogY2FzZSB1aW50MzJUYWc6XG4gICAgICAgICAgcmV0dXJuIGNsb25lVHlwZWRBcnJheShvYmplY3QsIGlzRGVlcCk7XG5cbiAgICAgICAgY2FzZSBtYXBUYWc6XG4gICAgICAgICAgcmV0dXJuIG5ldyBDdG9yO1xuXG4gICAgICAgIGNhc2UgbnVtYmVyVGFnOlxuICAgICAgICBjYXNlIHN0cmluZ1RhZzpcbiAgICAgICAgICByZXR1cm4gbmV3IEN0b3Iob2JqZWN0KTtcblxuICAgICAgICBjYXNlIHJlZ2V4cFRhZzpcbiAgICAgICAgICByZXR1cm4gY2xvbmVSZWdFeHAob2JqZWN0KTtcblxuICAgICAgICBjYXNlIHNldFRhZzpcbiAgICAgICAgICByZXR1cm4gbmV3IEN0b3I7XG5cbiAgICAgICAgY2FzZSBzeW1ib2xUYWc6XG4gICAgICAgICAgcmV0dXJuIGNsb25lU3ltYm9sKG9iamVjdCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogSW5zZXJ0cyB3cmFwcGVyIGBkZXRhaWxzYCBpbiBhIGNvbW1lbnQgYXQgdGhlIHRvcCBvZiB0aGUgYHNvdXJjZWAgYm9keS5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IHNvdXJjZSBUaGUgc291cmNlIHRvIG1vZGlmeS5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IGRldGFpbHMgVGhlIGRldGFpbHMgdG8gaW5zZXJ0LlxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IFJldHVybnMgdGhlIG1vZGlmaWVkIHNvdXJjZS5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBpbnNlcnRXcmFwRGV0YWlscyhzb3VyY2UsIGRldGFpbHMpIHtcbiAgICAgIHZhciBsZW5ndGggPSBkZXRhaWxzLmxlbmd0aDtcbiAgICAgIGlmICghbGVuZ3RoKSB7XG4gICAgICAgIHJldHVybiBzb3VyY2U7XG4gICAgICB9XG4gICAgICB2YXIgbGFzdEluZGV4ID0gbGVuZ3RoIC0gMTtcbiAgICAgIGRldGFpbHNbbGFzdEluZGV4XSA9IChsZW5ndGggPiAxID8gJyYgJyA6ICcnKSArIGRldGFpbHNbbGFzdEluZGV4XTtcbiAgICAgIGRldGFpbHMgPSBkZXRhaWxzLmpvaW4obGVuZ3RoID4gMiA/ICcsICcgOiAnICcpO1xuICAgICAgcmV0dXJuIHNvdXJjZS5yZXBsYWNlKHJlV3JhcENvbW1lbnQsICd7XFxuLyogW3dyYXBwZWQgd2l0aCAnICsgZGV0YWlscyArICddICovXFxuJyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgYSBmbGF0dGVuYWJsZSBgYXJndW1lbnRzYCBvYmplY3Qgb3IgYXJyYXkuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGZsYXR0ZW5hYmxlLCBlbHNlIGBmYWxzZWAuXG4gICAgICovXG4gICAgZnVuY3Rpb24gaXNGbGF0dGVuYWJsZSh2YWx1ZSkge1xuICAgICAgcmV0dXJuIGlzQXJyYXkodmFsdWUpIHx8IGlzQXJndW1lbnRzKHZhbHVlKSB8fFxuICAgICAgICAhIShzcHJlYWRhYmxlU3ltYm9sICYmIHZhbHVlICYmIHZhbHVlW3NwcmVhZGFibGVTeW1ib2xdKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBhIHZhbGlkIGFycmF5LWxpa2UgaW5kZXguXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbbGVuZ3RoPU1BWF9TQUZFX0lOVEVHRVJdIFRoZSB1cHBlciBib3VuZHMgb2YgYSB2YWxpZCBpbmRleC5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhIHZhbGlkIGluZGV4LCBlbHNlIGBmYWxzZWAuXG4gICAgICovXG4gICAgZnVuY3Rpb24gaXNJbmRleCh2YWx1ZSwgbGVuZ3RoKSB7XG4gICAgICB2YXIgdHlwZSA9IHR5cGVvZiB2YWx1ZTtcbiAgICAgIGxlbmd0aCA9IGxlbmd0aCA9PSBudWxsID8gTUFYX1NBRkVfSU5URUdFUiA6IGxlbmd0aDtcblxuICAgICAgcmV0dXJuICEhbGVuZ3RoICYmXG4gICAgICAgICh0eXBlID09ICdudW1iZXInIHx8XG4gICAgICAgICAgKHR5cGUgIT0gJ3N5bWJvbCcgJiYgcmVJc1VpbnQudGVzdCh2YWx1ZSkpKSAmJlxuICAgICAgICAgICAgKHZhbHVlID4gLTEgJiYgdmFsdWUgJSAxID09IDAgJiYgdmFsdWUgPCBsZW5ndGgpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENoZWNrcyBpZiB0aGUgZ2l2ZW4gYXJndW1lbnRzIGFyZSBmcm9tIGFuIGl0ZXJhdGVlIGNhbGwuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHBvdGVudGlhbCBpdGVyYXRlZSB2YWx1ZSBhcmd1bWVudC5cbiAgICAgKiBAcGFyYW0geyp9IGluZGV4IFRoZSBwb3RlbnRpYWwgaXRlcmF0ZWUgaW5kZXggb3Iga2V5IGFyZ3VtZW50LlxuICAgICAqIEBwYXJhbSB7Kn0gb2JqZWN0IFRoZSBwb3RlbnRpYWwgaXRlcmF0ZWUgb2JqZWN0IGFyZ3VtZW50LlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiB0aGUgYXJndW1lbnRzIGFyZSBmcm9tIGFuIGl0ZXJhdGVlIGNhbGwsXG4gICAgICogIGVsc2UgYGZhbHNlYC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBpc0l0ZXJhdGVlQ2FsbCh2YWx1ZSwgaW5kZXgsIG9iamVjdCkge1xuICAgICAgaWYgKCFpc09iamVjdChvYmplY3QpKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICAgIHZhciB0eXBlID0gdHlwZW9mIGluZGV4O1xuICAgICAgaWYgKHR5cGUgPT0gJ251bWJlcidcbiAgICAgICAgICAgID8gKGlzQXJyYXlMaWtlKG9iamVjdCkgJiYgaXNJbmRleChpbmRleCwgb2JqZWN0Lmxlbmd0aCkpXG4gICAgICAgICAgICA6ICh0eXBlID09ICdzdHJpbmcnICYmIGluZGV4IGluIG9iamVjdClcbiAgICAgICAgICApIHtcbiAgICAgICAgcmV0dXJuIGVxKG9iamVjdFtpbmRleF0sIHZhbHVlKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBhIHByb3BlcnR5IG5hbWUgYW5kIG5vdCBhIHByb3BlcnR5IHBhdGguXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBbb2JqZWN0XSBUaGUgb2JqZWN0IHRvIHF1ZXJ5IGtleXMgb24uXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgYSBwcm9wZXJ0eSBuYW1lLCBlbHNlIGBmYWxzZWAuXG4gICAgICovXG4gICAgZnVuY3Rpb24gaXNLZXkodmFsdWUsIG9iamVjdCkge1xuICAgICAgaWYgKGlzQXJyYXkodmFsdWUpKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICAgIHZhciB0eXBlID0gdHlwZW9mIHZhbHVlO1xuICAgICAgaWYgKHR5cGUgPT0gJ251bWJlcicgfHwgdHlwZSA9PSAnc3ltYm9sJyB8fCB0eXBlID09ICdib29sZWFuJyB8fFxuICAgICAgICAgIHZhbHVlID09IG51bGwgfHwgaXNTeW1ib2wodmFsdWUpKSB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHJlSXNQbGFpblByb3AudGVzdCh2YWx1ZSkgfHwgIXJlSXNEZWVwUHJvcC50ZXN0KHZhbHVlKSB8fFxuICAgICAgICAob2JqZWN0ICE9IG51bGwgJiYgdmFsdWUgaW4gT2JqZWN0KG9iamVjdCkpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIHN1aXRhYmxlIGZvciB1c2UgYXMgdW5pcXVlIG9iamVjdCBrZXkuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIHN1aXRhYmxlLCBlbHNlIGBmYWxzZWAuXG4gICAgICovXG4gICAgZnVuY3Rpb24gaXNLZXlhYmxlKHZhbHVlKSB7XG4gICAgICB2YXIgdHlwZSA9IHR5cGVvZiB2YWx1ZTtcbiAgICAgIHJldHVybiAodHlwZSA9PSAnc3RyaW5nJyB8fCB0eXBlID09ICdudW1iZXInIHx8IHR5cGUgPT0gJ3N5bWJvbCcgfHwgdHlwZSA9PSAnYm9vbGVhbicpXG4gICAgICAgID8gKHZhbHVlICE9PSAnX19wcm90b19fJylcbiAgICAgICAgOiAodmFsdWUgPT09IG51bGwpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENoZWNrcyBpZiBgZnVuY2AgaGFzIGEgbGF6eSBjb3VudGVycGFydC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gZnVuYyBUaGUgZnVuY3Rpb24gdG8gY2hlY2suXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGBmdW5jYCBoYXMgYSBsYXp5IGNvdW50ZXJwYXJ0LFxuICAgICAqICBlbHNlIGBmYWxzZWAuXG4gICAgICovXG4gICAgZnVuY3Rpb24gaXNMYXppYWJsZShmdW5jKSB7XG4gICAgICB2YXIgZnVuY05hbWUgPSBnZXRGdW5jTmFtZShmdW5jKSxcbiAgICAgICAgICBvdGhlciA9IGxvZGFzaFtmdW5jTmFtZV07XG5cbiAgICAgIGlmICh0eXBlb2Ygb3RoZXIgIT0gJ2Z1bmN0aW9uJyB8fCAhKGZ1bmNOYW1lIGluIExhenlXcmFwcGVyLnByb3RvdHlwZSkpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgICAgaWYgKGZ1bmMgPT09IG90aGVyKSB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgfVxuICAgICAgdmFyIGRhdGEgPSBnZXREYXRhKG90aGVyKTtcbiAgICAgIHJldHVybiAhIWRhdGEgJiYgZnVuYyA9PT0gZGF0YVswXTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDaGVja3MgaWYgYGZ1bmNgIGhhcyBpdHMgc291cmNlIG1hc2tlZC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gZnVuYyBUaGUgZnVuY3Rpb24gdG8gY2hlY2suXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGBmdW5jYCBpcyBtYXNrZWQsIGVsc2UgYGZhbHNlYC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBpc01hc2tlZChmdW5jKSB7XG4gICAgICByZXR1cm4gISFtYXNrU3JjS2V5ICYmIChtYXNrU3JjS2V5IGluIGZ1bmMpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENoZWNrcyBpZiBgZnVuY2AgaXMgY2FwYWJsZSBvZiBiZWluZyBtYXNrZWQuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgZnVuY2AgaXMgbWFza2FibGUsIGVsc2UgYGZhbHNlYC5cbiAgICAgKi9cbiAgICB2YXIgaXNNYXNrYWJsZSA9IGNvcmVKc0RhdGEgPyBpc0Z1bmN0aW9uIDogc3R1YkZhbHNlO1xuXG4gICAgLyoqXG4gICAgICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgbGlrZWx5IGEgcHJvdG90eXBlIG9iamVjdC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgYSBwcm90b3R5cGUsIGVsc2UgYGZhbHNlYC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBpc1Byb3RvdHlwZSh2YWx1ZSkge1xuICAgICAgdmFyIEN0b3IgPSB2YWx1ZSAmJiB2YWx1ZS5jb25zdHJ1Y3RvcixcbiAgICAgICAgICBwcm90byA9ICh0eXBlb2YgQ3RvciA9PSAnZnVuY3Rpb24nICYmIEN0b3IucHJvdG90eXBlKSB8fCBvYmplY3RQcm90bztcblxuICAgICAgcmV0dXJuIHZhbHVlID09PSBwcm90bztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBzdWl0YWJsZSBmb3Igc3RyaWN0IGVxdWFsaXR5IGNvbXBhcmlzb25zLCBpLmUuIGA9PT1gLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpZiBzdWl0YWJsZSBmb3Igc3RyaWN0XG4gICAgICogIGVxdWFsaXR5IGNvbXBhcmlzb25zLCBlbHNlIGBmYWxzZWAuXG4gICAgICovXG4gICAgZnVuY3Rpb24gaXNTdHJpY3RDb21wYXJhYmxlKHZhbHVlKSB7XG4gICAgICByZXR1cm4gdmFsdWUgPT09IHZhbHVlICYmICFpc09iamVjdCh2YWx1ZSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQSBzcGVjaWFsaXplZCB2ZXJzaW9uIG9mIGBtYXRjaGVzUHJvcGVydHlgIGZvciBzb3VyY2UgdmFsdWVzIHN1aXRhYmxlXG4gICAgICogZm9yIHN0cmljdCBlcXVhbGl0eSBjb21wYXJpc29ucywgaS5lLiBgPT09YC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGtleSBUaGUga2V5IG9mIHRoZSBwcm9wZXJ0eSB0byBnZXQuXG4gICAgICogQHBhcmFtIHsqfSBzcmNWYWx1ZSBUaGUgdmFsdWUgdG8gbWF0Y2guXG4gICAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgc3BlYyBmdW5jdGlvbi5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBtYXRjaGVzU3RyaWN0Q29tcGFyYWJsZShrZXksIHNyY1ZhbHVlKSB7XG4gICAgICByZXR1cm4gZnVuY3Rpb24ob2JqZWN0KSB7XG4gICAgICAgIGlmIChvYmplY3QgPT0gbnVsbCkge1xuICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gb2JqZWN0W2tleV0gPT09IHNyY1ZhbHVlICYmXG4gICAgICAgICAgKHNyY1ZhbHVlICE9PSB1bmRlZmluZWQgfHwgKGtleSBpbiBPYmplY3Qob2JqZWN0KSkpO1xuICAgICAgfTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBBIHNwZWNpYWxpemVkIHZlcnNpb24gb2YgYF8ubWVtb2l6ZWAgd2hpY2ggY2xlYXJzIHRoZSBtZW1vaXplZCBmdW5jdGlvbidzXG4gICAgICogY2FjaGUgd2hlbiBpdCBleGNlZWRzIGBNQVhfTUVNT0laRV9TSVpFYC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gZnVuYyBUaGUgZnVuY3Rpb24gdG8gaGF2ZSBpdHMgb3V0cHV0IG1lbW9pemVkLlxuICAgICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IG1lbW9pemVkIGZ1bmN0aW9uLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIG1lbW9pemVDYXBwZWQoZnVuYykge1xuICAgICAgdmFyIHJlc3VsdCA9IG1lbW9pemUoZnVuYywgZnVuY3Rpb24oa2V5KSB7XG4gICAgICAgIGlmIChjYWNoZS5zaXplID09PSBNQVhfTUVNT0laRV9TSVpFKSB7XG4gICAgICAgICAgY2FjaGUuY2xlYXIoKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4ga2V5O1xuICAgICAgfSk7XG5cbiAgICAgIHZhciBjYWNoZSA9IHJlc3VsdC5jYWNoZTtcbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogTWVyZ2VzIHRoZSBmdW5jdGlvbiBtZXRhZGF0YSBvZiBgc291cmNlYCBpbnRvIGBkYXRhYC5cbiAgICAgKlxuICAgICAqIE1lcmdpbmcgbWV0YWRhdGEgcmVkdWNlcyB0aGUgbnVtYmVyIG9mIHdyYXBwZXJzIHVzZWQgdG8gaW52b2tlIGEgZnVuY3Rpb24uXG4gICAgICogVGhpcyBpcyBwb3NzaWJsZSBiZWNhdXNlIG1ldGhvZHMgbGlrZSBgXy5iaW5kYCwgYF8uY3VycnlgLCBhbmQgYF8ucGFydGlhbGBcbiAgICAgKiBtYXkgYmUgYXBwbGllZCByZWdhcmRsZXNzIG9mIGV4ZWN1dGlvbiBvcmRlci4gTWV0aG9kcyBsaWtlIGBfLmFyeWAgYW5kXG4gICAgICogYF8ucmVhcmdgIG1vZGlmeSBmdW5jdGlvbiBhcmd1bWVudHMsIG1ha2luZyB0aGUgb3JkZXIgaW4gd2hpY2ggdGhleSBhcmVcbiAgICAgKiBleGVjdXRlZCBpbXBvcnRhbnQsIHByZXZlbnRpbmcgdGhlIG1lcmdpbmcgb2YgbWV0YWRhdGEuIEhvd2V2ZXIsIHdlIG1ha2VcbiAgICAgKiBhbiBleGNlcHRpb24gZm9yIGEgc2FmZSBjb21iaW5lZCBjYXNlIHdoZXJlIGN1cnJpZWQgZnVuY3Rpb25zIGhhdmUgYF8uYXJ5YFxuICAgICAqIGFuZCBvciBgXy5yZWFyZ2AgYXBwbGllZC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtBcnJheX0gZGF0YSBUaGUgZGVzdGluYXRpb24gbWV0YWRhdGEuXG4gICAgICogQHBhcmFtIHtBcnJheX0gc291cmNlIFRoZSBzb3VyY2UgbWV0YWRhdGEuXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIGBkYXRhYC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBtZXJnZURhdGEoZGF0YSwgc291cmNlKSB7XG4gICAgICB2YXIgYml0bWFzayA9IGRhdGFbMV0sXG4gICAgICAgICAgc3JjQml0bWFzayA9IHNvdXJjZVsxXSxcbiAgICAgICAgICBuZXdCaXRtYXNrID0gYml0bWFzayB8IHNyY0JpdG1hc2ssXG4gICAgICAgICAgaXNDb21tb24gPSBuZXdCaXRtYXNrIDwgKFdSQVBfQklORF9GTEFHIHwgV1JBUF9CSU5EX0tFWV9GTEFHIHwgV1JBUF9BUllfRkxBRyk7XG5cbiAgICAgIHZhciBpc0NvbWJvID1cbiAgICAgICAgKChzcmNCaXRtYXNrID09IFdSQVBfQVJZX0ZMQUcpICYmIChiaXRtYXNrID09IFdSQVBfQ1VSUllfRkxBRykpIHx8XG4gICAgICAgICgoc3JjQml0bWFzayA9PSBXUkFQX0FSWV9GTEFHKSAmJiAoYml0bWFzayA9PSBXUkFQX1JFQVJHX0ZMQUcpICYmIChkYXRhWzddLmxlbmd0aCA8PSBzb3VyY2VbOF0pKSB8fFxuICAgICAgICAoKHNyY0JpdG1hc2sgPT0gKFdSQVBfQVJZX0ZMQUcgfCBXUkFQX1JFQVJHX0ZMQUcpKSAmJiAoc291cmNlWzddLmxlbmd0aCA8PSBzb3VyY2VbOF0pICYmIChiaXRtYXNrID09IFdSQVBfQ1VSUllfRkxBRykpO1xuXG4gICAgICAvLyBFeGl0IGVhcmx5IGlmIG1ldGFkYXRhIGNhbid0IGJlIG1lcmdlZC5cbiAgICAgIGlmICghKGlzQ29tbW9uIHx8IGlzQ29tYm8pKSB7XG4gICAgICAgIHJldHVybiBkYXRhO1xuICAgICAgfVxuICAgICAgLy8gVXNlIHNvdXJjZSBgdGhpc0FyZ2AgaWYgYXZhaWxhYmxlLlxuICAgICAgaWYgKHNyY0JpdG1hc2sgJiBXUkFQX0JJTkRfRkxBRykge1xuICAgICAgICBkYXRhWzJdID0gc291cmNlWzJdO1xuICAgICAgICAvLyBTZXQgd2hlbiBjdXJyeWluZyBhIGJvdW5kIGZ1bmN0aW9uLlxuICAgICAgICBuZXdCaXRtYXNrIHw9IGJpdG1hc2sgJiBXUkFQX0JJTkRfRkxBRyA/IDAgOiBXUkFQX0NVUlJZX0JPVU5EX0ZMQUc7XG4gICAgICB9XG4gICAgICAvLyBDb21wb3NlIHBhcnRpYWwgYXJndW1lbnRzLlxuICAgICAgdmFyIHZhbHVlID0gc291cmNlWzNdO1xuICAgICAgaWYgKHZhbHVlKSB7XG4gICAgICAgIHZhciBwYXJ0aWFscyA9IGRhdGFbM107XG4gICAgICAgIGRhdGFbM10gPSBwYXJ0aWFscyA/IGNvbXBvc2VBcmdzKHBhcnRpYWxzLCB2YWx1ZSwgc291cmNlWzRdKSA6IHZhbHVlO1xuICAgICAgICBkYXRhWzRdID0gcGFydGlhbHMgPyByZXBsYWNlSG9sZGVycyhkYXRhWzNdLCBQTEFDRUhPTERFUikgOiBzb3VyY2VbNF07XG4gICAgICB9XG4gICAgICAvLyBDb21wb3NlIHBhcnRpYWwgcmlnaHQgYXJndW1lbnRzLlxuICAgICAgdmFsdWUgPSBzb3VyY2VbNV07XG4gICAgICBpZiAodmFsdWUpIHtcbiAgICAgICAgcGFydGlhbHMgPSBkYXRhWzVdO1xuICAgICAgICBkYXRhWzVdID0gcGFydGlhbHMgPyBjb21wb3NlQXJnc1JpZ2h0KHBhcnRpYWxzLCB2YWx1ZSwgc291cmNlWzZdKSA6IHZhbHVlO1xuICAgICAgICBkYXRhWzZdID0gcGFydGlhbHMgPyByZXBsYWNlSG9sZGVycyhkYXRhWzVdLCBQTEFDRUhPTERFUikgOiBzb3VyY2VbNl07XG4gICAgICB9XG4gICAgICAvLyBVc2Ugc291cmNlIGBhcmdQb3NgIGlmIGF2YWlsYWJsZS5cbiAgICAgIHZhbHVlID0gc291cmNlWzddO1xuICAgICAgaWYgKHZhbHVlKSB7XG4gICAgICAgIGRhdGFbN10gPSB2YWx1ZTtcbiAgICAgIH1cbiAgICAgIC8vIFVzZSBzb3VyY2UgYGFyeWAgaWYgaXQncyBzbWFsbGVyLlxuICAgICAgaWYgKHNyY0JpdG1hc2sgJiBXUkFQX0FSWV9GTEFHKSB7XG4gICAgICAgIGRhdGFbOF0gPSBkYXRhWzhdID09IG51bGwgPyBzb3VyY2VbOF0gOiBuYXRpdmVNaW4oZGF0YVs4XSwgc291cmNlWzhdKTtcbiAgICAgIH1cbiAgICAgIC8vIFVzZSBzb3VyY2UgYGFyaXR5YCBpZiBvbmUgaXMgbm90IHByb3ZpZGVkLlxuICAgICAgaWYgKGRhdGFbOV0gPT0gbnVsbCkge1xuICAgICAgICBkYXRhWzldID0gc291cmNlWzldO1xuICAgICAgfVxuICAgICAgLy8gVXNlIHNvdXJjZSBgZnVuY2AgYW5kIG1lcmdlIGJpdG1hc2tzLlxuICAgICAgZGF0YVswXSA9IHNvdXJjZVswXTtcbiAgICAgIGRhdGFbMV0gPSBuZXdCaXRtYXNrO1xuXG4gICAgICByZXR1cm4gZGF0YTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIGZ1bmN0aW9uIGlzIGxpa2VcbiAgICAgKiBbYE9iamVjdC5rZXlzYF0oaHR0cDovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNy4wLyNzZWMtb2JqZWN0LmtleXMpXG4gICAgICogZXhjZXB0IHRoYXQgaXQgaW5jbHVkZXMgaW5oZXJpdGVkIGVudW1lcmFibGUgcHJvcGVydGllcy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIHF1ZXJ5LlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgYXJyYXkgb2YgcHJvcGVydHkgbmFtZXMuXG4gICAgICovXG4gICAgZnVuY3Rpb24gbmF0aXZlS2V5c0luKG9iamVjdCkge1xuICAgICAgdmFyIHJlc3VsdCA9IFtdO1xuICAgICAgaWYgKG9iamVjdCAhPSBudWxsKSB7XG4gICAgICAgIGZvciAodmFyIGtleSBpbiBPYmplY3Qob2JqZWN0KSkge1xuICAgICAgICAgIHJlc3VsdC5wdXNoKGtleSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ29udmVydHMgYHZhbHVlYCB0byBhIHN0cmluZyB1c2luZyBgT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZ2AuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNvbnZlcnQuXG4gICAgICogQHJldHVybnMge3N0cmluZ30gUmV0dXJucyB0aGUgY29udmVydGVkIHN0cmluZy5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBvYmplY3RUb1N0cmluZyh2YWx1ZSkge1xuICAgICAgcmV0dXJuIG5hdGl2ZU9iamVjdFRvU3RyaW5nLmNhbGwodmFsdWUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEEgc3BlY2lhbGl6ZWQgdmVyc2lvbiBvZiBgYmFzZVJlc3RgIHdoaWNoIHRyYW5zZm9ybXMgdGhlIHJlc3QgYXJyYXkuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIGFwcGx5IGEgcmVzdCBwYXJhbWV0ZXIgdG8uXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtzdGFydD1mdW5jLmxlbmd0aC0xXSBUaGUgc3RhcnQgcG9zaXRpb24gb2YgdGhlIHJlc3QgcGFyYW1ldGVyLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IHRyYW5zZm9ybSBUaGUgcmVzdCBhcnJheSB0cmFuc2Zvcm0uXG4gICAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgZnVuY3Rpb24uXG4gICAgICovXG4gICAgZnVuY3Rpb24gb3ZlclJlc3QoZnVuYywgc3RhcnQsIHRyYW5zZm9ybSkge1xuICAgICAgc3RhcnQgPSBuYXRpdmVNYXgoc3RhcnQgPT09IHVuZGVmaW5lZCA/IChmdW5jLmxlbmd0aCAtIDEpIDogc3RhcnQsIDApO1xuICAgICAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgICAgICB2YXIgYXJncyA9IGFyZ3VtZW50cyxcbiAgICAgICAgICAgIGluZGV4ID0gLTEsXG4gICAgICAgICAgICBsZW5ndGggPSBuYXRpdmVNYXgoYXJncy5sZW5ndGggLSBzdGFydCwgMCksXG4gICAgICAgICAgICBhcnJheSA9IEFycmF5KGxlbmd0aCk7XG5cbiAgICAgICAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHtcbiAgICAgICAgICBhcnJheVtpbmRleF0gPSBhcmdzW3N0YXJ0ICsgaW5kZXhdO1xuICAgICAgICB9XG4gICAgICAgIGluZGV4ID0gLTE7XG4gICAgICAgIHZhciBvdGhlckFyZ3MgPSBBcnJheShzdGFydCArIDEpO1xuICAgICAgICB3aGlsZSAoKytpbmRleCA8IHN0YXJ0KSB7XG4gICAgICAgICAgb3RoZXJBcmdzW2luZGV4XSA9IGFyZ3NbaW5kZXhdO1xuICAgICAgICB9XG4gICAgICAgIG90aGVyQXJnc1tzdGFydF0gPSB0cmFuc2Zvcm0oYXJyYXkpO1xuICAgICAgICByZXR1cm4gYXBwbHkoZnVuYywgdGhpcywgb3RoZXJBcmdzKTtcbiAgICAgIH07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0cyB0aGUgcGFyZW50IHZhbHVlIGF0IGBwYXRoYCBvZiBgb2JqZWN0YC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIHF1ZXJ5LlxuICAgICAqIEBwYXJhbSB7QXJyYXl9IHBhdGggVGhlIHBhdGggdG8gZ2V0IHRoZSBwYXJlbnQgdmFsdWUgb2YuXG4gICAgICogQHJldHVybnMgeyp9IFJldHVybnMgdGhlIHBhcmVudCB2YWx1ZS5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBwYXJlbnQob2JqZWN0LCBwYXRoKSB7XG4gICAgICByZXR1cm4gcGF0aC5sZW5ndGggPCAyID8gb2JqZWN0IDogYmFzZUdldChvYmplY3QsIGJhc2VTbGljZShwYXRoLCAwLCAtMSkpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJlb3JkZXIgYGFycmF5YCBhY2NvcmRpbmcgdG8gdGhlIHNwZWNpZmllZCBpbmRleGVzIHdoZXJlIHRoZSBlbGVtZW50IGF0XG4gICAgICogdGhlIGZpcnN0IGluZGV4IGlzIGFzc2lnbmVkIGFzIHRoZSBmaXJzdCBlbGVtZW50LCB0aGUgZWxlbWVudCBhdFxuICAgICAqIHRoZSBzZWNvbmQgaW5kZXggaXMgYXNzaWduZWQgYXMgdGhlIHNlY29uZCBlbGVtZW50LCBhbmQgc28gb24uXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byByZW9yZGVyLlxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGluZGV4ZXMgVGhlIGFycmFuZ2VkIGFycmF5IGluZGV4ZXMuXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIGBhcnJheWAuXG4gICAgICovXG4gICAgZnVuY3Rpb24gcmVvcmRlcihhcnJheSwgaW5kZXhlcykge1xuICAgICAgdmFyIGFyckxlbmd0aCA9IGFycmF5Lmxlbmd0aCxcbiAgICAgICAgICBsZW5ndGggPSBuYXRpdmVNaW4oaW5kZXhlcy5sZW5ndGgsIGFyckxlbmd0aCksXG4gICAgICAgICAgb2xkQXJyYXkgPSBjb3B5QXJyYXkoYXJyYXkpO1xuXG4gICAgICB3aGlsZSAobGVuZ3RoLS0pIHtcbiAgICAgICAgdmFyIGluZGV4ID0gaW5kZXhlc1tsZW5ndGhdO1xuICAgICAgICBhcnJheVtsZW5ndGhdID0gaXNJbmRleChpbmRleCwgYXJyTGVuZ3RoKSA/IG9sZEFycmF5W2luZGV4XSA6IHVuZGVmaW5lZDtcbiAgICAgIH1cbiAgICAgIHJldHVybiBhcnJheTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXRzIHRoZSB2YWx1ZSBhdCBga2V5YCwgdW5sZXNzIGBrZXlgIGlzIFwiX19wcm90b19fXCIgb3IgXCJjb25zdHJ1Y3RvclwiLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gcXVlcnkuXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGtleSBUaGUga2V5IG9mIHRoZSBwcm9wZXJ0eSB0byBnZXQuXG4gICAgICogQHJldHVybnMgeyp9IFJldHVybnMgdGhlIHByb3BlcnR5IHZhbHVlLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIHNhZmVHZXQob2JqZWN0LCBrZXkpIHtcbiAgICAgIGlmIChrZXkgPT09ICdjb25zdHJ1Y3RvcicgJiYgdHlwZW9mIG9iamVjdFtrZXldID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgaWYgKGtleSA9PSAnX19wcm90b19fJykge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBvYmplY3Rba2V5XTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTZXRzIG1ldGFkYXRhIGZvciBgZnVuY2AuXG4gICAgICpcbiAgICAgKiAqKk5vdGU6KiogSWYgdGhpcyBmdW5jdGlvbiBiZWNvbWVzIGhvdCwgaS5lLiBpcyBpbnZva2VkIGEgbG90IGluIGEgc2hvcnRcbiAgICAgKiBwZXJpb2Qgb2YgdGltZSwgaXQgd2lsbCB0cmlwIGl0cyBicmVha2VyIGFuZCB0cmFuc2l0aW9uIHRvIGFuIGlkZW50aXR5XG4gICAgICogZnVuY3Rpb24gdG8gYXZvaWQgZ2FyYmFnZSBjb2xsZWN0aW9uIHBhdXNlcyBpbiBWOC4gU2VlXG4gICAgICogW1Y4IGlzc3VlIDIwNzBdKGh0dHBzOi8vYnVncy5jaHJvbWl1bS5vcmcvcC92OC9pc3N1ZXMvZGV0YWlsP2lkPTIwNzApXG4gICAgICogZm9yIG1vcmUgZGV0YWlscy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gZnVuYyBUaGUgZnVuY3Rpb24gdG8gYXNzb2NpYXRlIG1ldGFkYXRhIHdpdGguXG4gICAgICogQHBhcmFtIHsqfSBkYXRhIFRoZSBtZXRhZGF0YS5cbiAgICAgKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgYGZ1bmNgLlxuICAgICAqL1xuICAgIHZhciBzZXREYXRhID0gc2hvcnRPdXQoYmFzZVNldERhdGEpO1xuXG4gICAgLyoqXG4gICAgICogQSBzaW1wbGUgd3JhcHBlciBhcm91bmQgdGhlIGdsb2JhbCBbYHNldFRpbWVvdXRgXShodHRwczovL21kbi5pby9zZXRUaW1lb3V0KS5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gZnVuYyBUaGUgZnVuY3Rpb24gdG8gZGVsYXkuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHdhaXQgVGhlIG51bWJlciBvZiBtaWxsaXNlY29uZHMgdG8gZGVsYXkgaW52b2NhdGlvbi5cbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfE9iamVjdH0gUmV0dXJucyB0aGUgdGltZXIgaWQgb3IgdGltZW91dCBvYmplY3QuXG4gICAgICovXG4gICAgdmFyIHNldFRpbWVvdXQgPSBjdHhTZXRUaW1lb3V0IHx8IGZ1bmN0aW9uKGZ1bmMsIHdhaXQpIHtcbiAgICAgIHJldHVybiByb290LnNldFRpbWVvdXQoZnVuYywgd2FpdCk7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIFNldHMgdGhlIGB0b1N0cmluZ2AgbWV0aG9kIG9mIGBmdW5jYCB0byByZXR1cm4gYHN0cmluZ2AuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIG1vZGlmeS5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBzdHJpbmcgVGhlIGB0b1N0cmluZ2AgcmVzdWx0LlxuICAgICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyBgZnVuY2AuXG4gICAgICovXG4gICAgdmFyIHNldFRvU3RyaW5nID0gc2hvcnRPdXQoYmFzZVNldFRvU3RyaW5nKTtcblxuICAgIC8qKlxuICAgICAqIFNldHMgdGhlIGB0b1N0cmluZ2AgbWV0aG9kIG9mIGB3cmFwcGVyYCB0byBtaW1pYyB0aGUgc291cmNlIG9mIGByZWZlcmVuY2VgXG4gICAgICogd2l0aCB3cmFwcGVyIGRldGFpbHMgaW4gYSBjb21tZW50IGF0IHRoZSB0b3Agb2YgdGhlIHNvdXJjZSBib2R5LlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSB3cmFwcGVyIFRoZSBmdW5jdGlvbiB0byBtb2RpZnkuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gcmVmZXJlbmNlIFRoZSByZWZlcmVuY2UgZnVuY3Rpb24uXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IGJpdG1hc2sgVGhlIGJpdG1hc2sgZmxhZ3MuIFNlZSBgY3JlYXRlV3JhcGAgZm9yIG1vcmUgZGV0YWlscy5cbiAgICAgKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgYHdyYXBwZXJgLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIHNldFdyYXBUb1N0cmluZyh3cmFwcGVyLCByZWZlcmVuY2UsIGJpdG1hc2spIHtcbiAgICAgIHZhciBzb3VyY2UgPSAocmVmZXJlbmNlICsgJycpO1xuICAgICAgcmV0dXJuIHNldFRvU3RyaW5nKHdyYXBwZXIsIGluc2VydFdyYXBEZXRhaWxzKHNvdXJjZSwgdXBkYXRlV3JhcERldGFpbHMoZ2V0V3JhcERldGFpbHMoc291cmNlKSwgYml0bWFzaykpKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgZnVuY3Rpb24gdGhhdCdsbCBzaG9ydCBvdXQgYW5kIGludm9rZSBgaWRlbnRpdHlgIGluc3RlYWRcbiAgICAgKiBvZiBgZnVuY2Agd2hlbiBpdCdzIGNhbGxlZCBgSE9UX0NPVU5UYCBvciBtb3JlIHRpbWVzIGluIGBIT1RfU1BBTmBcbiAgICAgKiBtaWxsaXNlY29uZHMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIHJlc3RyaWN0LlxuICAgICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IHNob3J0YWJsZSBmdW5jdGlvbi5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBzaG9ydE91dChmdW5jKSB7XG4gICAgICB2YXIgY291bnQgPSAwLFxuICAgICAgICAgIGxhc3RDYWxsZWQgPSAwO1xuXG4gICAgICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgICAgIHZhciBzdGFtcCA9IG5hdGl2ZU5vdygpLFxuICAgICAgICAgICAgcmVtYWluaW5nID0gSE9UX1NQQU4gLSAoc3RhbXAgLSBsYXN0Q2FsbGVkKTtcblxuICAgICAgICBsYXN0Q2FsbGVkID0gc3RhbXA7XG4gICAgICAgIGlmIChyZW1haW5pbmcgPiAwKSB7XG4gICAgICAgICAgaWYgKCsrY291bnQgPj0gSE9UX0NPVU5UKSB7XG4gICAgICAgICAgICByZXR1cm4gYXJndW1lbnRzWzBdO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBjb3VudCA9IDA7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGZ1bmMuYXBwbHkodW5kZWZpbmVkLCBhcmd1bWVudHMpO1xuICAgICAgfTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBBIHNwZWNpYWxpemVkIHZlcnNpb24gb2YgYF8uc2h1ZmZsZWAgd2hpY2ggbXV0YXRlcyBhbmQgc2V0cyB0aGUgc2l6ZSBvZiBgYXJyYXlgLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gc2h1ZmZsZS5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW3NpemU9YXJyYXkubGVuZ3RoXSBUaGUgc2l6ZSBvZiBgYXJyYXlgLlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyBgYXJyYXlgLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIHNodWZmbGVTZWxmKGFycmF5LCBzaXplKSB7XG4gICAgICB2YXIgaW5kZXggPSAtMSxcbiAgICAgICAgICBsZW5ndGggPSBhcnJheS5sZW5ndGgsXG4gICAgICAgICAgbGFzdEluZGV4ID0gbGVuZ3RoIC0gMTtcblxuICAgICAgc2l6ZSA9IHNpemUgPT09IHVuZGVmaW5lZCA/IGxlbmd0aCA6IHNpemU7XG4gICAgICB3aGlsZSAoKytpbmRleCA8IHNpemUpIHtcbiAgICAgICAgdmFyIHJhbmQgPSBiYXNlUmFuZG9tKGluZGV4LCBsYXN0SW5kZXgpLFxuICAgICAgICAgICAgdmFsdWUgPSBhcnJheVtyYW5kXTtcblxuICAgICAgICBhcnJheVtyYW5kXSA9IGFycmF5W2luZGV4XTtcbiAgICAgICAgYXJyYXlbaW5kZXhdID0gdmFsdWU7XG4gICAgICB9XG4gICAgICBhcnJheS5sZW5ndGggPSBzaXplO1xuICAgICAgcmV0dXJuIGFycmF5O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENvbnZlcnRzIGBzdHJpbmdgIHRvIGEgcHJvcGVydHkgcGF0aCBhcnJheS5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IHN0cmluZyBUaGUgc3RyaW5nIHRvIGNvbnZlcnQuXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBwcm9wZXJ0eSBwYXRoIGFycmF5LlxuICAgICAqL1xuICAgIHZhciBzdHJpbmdUb1BhdGggPSBtZW1vaXplQ2FwcGVkKGZ1bmN0aW9uKHN0cmluZykge1xuICAgICAgdmFyIHJlc3VsdCA9IFtdO1xuICAgICAgaWYgKHN0cmluZy5jaGFyQ29kZUF0KDApID09PSA0NiAvKiAuICovKSB7XG4gICAgICAgIHJlc3VsdC5wdXNoKCcnKTtcbiAgICAgIH1cbiAgICAgIHN0cmluZy5yZXBsYWNlKHJlUHJvcE5hbWUsIGZ1bmN0aW9uKG1hdGNoLCBudW1iZXIsIHF1b3RlLCBzdWJTdHJpbmcpIHtcbiAgICAgICAgcmVzdWx0LnB1c2gocXVvdGUgPyBzdWJTdHJpbmcucmVwbGFjZShyZUVzY2FwZUNoYXIsICckMScpIDogKG51bWJlciB8fCBtYXRjaCkpO1xuICAgICAgfSk7XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH0pO1xuXG4gICAgLyoqXG4gICAgICogQ29udmVydHMgYHZhbHVlYCB0byBhIHN0cmluZyBrZXkgaWYgaXQncyBub3QgYSBzdHJpbmcgb3Igc3ltYm9sLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBpbnNwZWN0LlxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd8c3ltYm9sfSBSZXR1cm5zIHRoZSBrZXkuXG4gICAgICovXG4gICAgZnVuY3Rpb24gdG9LZXkodmFsdWUpIHtcbiAgICAgIGlmICh0eXBlb2YgdmFsdWUgPT0gJ3N0cmluZycgfHwgaXNTeW1ib2wodmFsdWUpKSB7XG4gICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICAgIH1cbiAgICAgIHZhciByZXN1bHQgPSAodmFsdWUgKyAnJyk7XG4gICAgICByZXR1cm4gKHJlc3VsdCA9PSAnMCcgJiYgKDEgLyB2YWx1ZSkgPT0gLUlORklOSVRZKSA/ICctMCcgOiByZXN1bHQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ29udmVydHMgYGZ1bmNgIHRvIGl0cyBzb3VyY2UgY29kZS5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gZnVuYyBUaGUgZnVuY3Rpb24gdG8gY29udmVydC5cbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfSBSZXR1cm5zIHRoZSBzb3VyY2UgY29kZS5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiB0b1NvdXJjZShmdW5jKSB7XG4gICAgICBpZiAoZnVuYyAhPSBudWxsKSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgcmV0dXJuIGZ1bmNUb1N0cmluZy5jYWxsKGZ1bmMpO1xuICAgICAgICB9IGNhdGNoIChlKSB7fVxuICAgICAgICB0cnkge1xuICAgICAgICAgIHJldHVybiAoZnVuYyArICcnKTtcbiAgICAgICAgfSBjYXRjaCAoZSkge31cbiAgICAgIH1cbiAgICAgIHJldHVybiAnJztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBVcGRhdGVzIHdyYXBwZXIgYGRldGFpbHNgIGJhc2VkIG9uIGBiaXRtYXNrYCBmbGFncy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHJldHVybnMge0FycmF5fSBkZXRhaWxzIFRoZSBkZXRhaWxzIHRvIG1vZGlmeS5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gYml0bWFzayBUaGUgYml0bWFzayBmbGFncy4gU2VlIGBjcmVhdGVXcmFwYCBmb3IgbW9yZSBkZXRhaWxzLlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyBgZGV0YWlsc2AuXG4gICAgICovXG4gICAgZnVuY3Rpb24gdXBkYXRlV3JhcERldGFpbHMoZGV0YWlscywgYml0bWFzaykge1xuICAgICAgYXJyYXlFYWNoKHdyYXBGbGFncywgZnVuY3Rpb24ocGFpcikge1xuICAgICAgICB2YXIgdmFsdWUgPSAnXy4nICsgcGFpclswXTtcbiAgICAgICAgaWYgKChiaXRtYXNrICYgcGFpclsxXSkgJiYgIWFycmF5SW5jbHVkZXMoZGV0YWlscywgdmFsdWUpKSB7XG4gICAgICAgICAgZGV0YWlscy5wdXNoKHZhbHVlKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgICByZXR1cm4gZGV0YWlscy5zb3J0KCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIGNsb25lIG9mIGB3cmFwcGVyYC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtPYmplY3R9IHdyYXBwZXIgVGhlIHdyYXBwZXIgdG8gY2xvbmUuXG4gICAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyB0aGUgY2xvbmVkIHdyYXBwZXIuXG4gICAgICovXG4gICAgZnVuY3Rpb24gd3JhcHBlckNsb25lKHdyYXBwZXIpIHtcbiAgICAgIGlmICh3cmFwcGVyIGluc3RhbmNlb2YgTGF6eVdyYXBwZXIpIHtcbiAgICAgICAgcmV0dXJuIHdyYXBwZXIuY2xvbmUoKTtcbiAgICAgIH1cbiAgICAgIHZhciByZXN1bHQgPSBuZXcgTG9kYXNoV3JhcHBlcih3cmFwcGVyLl9fd3JhcHBlZF9fLCB3cmFwcGVyLl9fY2hhaW5fXyk7XG4gICAgICByZXN1bHQuX19hY3Rpb25zX18gPSBjb3B5QXJyYXkod3JhcHBlci5fX2FjdGlvbnNfXyk7XG4gICAgICByZXN1bHQuX19pbmRleF9fICA9IHdyYXBwZXIuX19pbmRleF9fO1xuICAgICAgcmVzdWx0Ll9fdmFsdWVzX18gPSB3cmFwcGVyLl9fdmFsdWVzX187XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cblxuICAgIC8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi9cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYW4gYXJyYXkgb2YgZWxlbWVudHMgc3BsaXQgaW50byBncm91cHMgdGhlIGxlbmd0aCBvZiBgc2l6ZWAuXG4gICAgICogSWYgYGFycmF5YCBjYW4ndCBiZSBzcGxpdCBldmVubHksIHRoZSBmaW5hbCBjaHVuayB3aWxsIGJlIHRoZSByZW1haW5pbmdcbiAgICAgKiBlbGVtZW50cy5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAzLjAuMFxuICAgICAqIEBjYXRlZ29yeSBBcnJheVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBwcm9jZXNzLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbc2l6ZT0xXSBUaGUgbGVuZ3RoIG9mIGVhY2ggY2h1bmtcbiAgICAgKiBAcGFyYW0tIHtPYmplY3R9IFtndWFyZF0gRW5hYmxlcyB1c2UgYXMgYW4gaXRlcmF0ZWUgZm9yIG1ldGhvZHMgbGlrZSBgXy5tYXBgLlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IGFycmF5IG9mIGNodW5rcy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5jaHVuayhbJ2EnLCAnYicsICdjJywgJ2QnXSwgMik7XG4gICAgICogLy8gPT4gW1snYScsICdiJ10sIFsnYycsICdkJ11dXG4gICAgICpcbiAgICAgKiBfLmNodW5rKFsnYScsICdiJywgJ2MnLCAnZCddLCAzKTtcbiAgICAgKiAvLyA9PiBbWydhJywgJ2InLCAnYyddLCBbJ2QnXV1cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBjaHVuayhhcnJheSwgc2l6ZSwgZ3VhcmQpIHtcbiAgICAgIGlmICgoZ3VhcmQgPyBpc0l0ZXJhdGVlQ2FsbChhcnJheSwgc2l6ZSwgZ3VhcmQpIDogc2l6ZSA9PT0gdW5kZWZpbmVkKSkge1xuICAgICAgICBzaXplID0gMTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHNpemUgPSBuYXRpdmVNYXgodG9JbnRlZ2VyKHNpemUpLCAwKTtcbiAgICAgIH1cbiAgICAgIHZhciBsZW5ndGggPSBhcnJheSA9PSBudWxsID8gMCA6IGFycmF5Lmxlbmd0aDtcbiAgICAgIGlmICghbGVuZ3RoIHx8IHNpemUgPCAxKSB7XG4gICAgICAgIHJldHVybiBbXTtcbiAgICAgIH1cbiAgICAgIHZhciBpbmRleCA9IDAsXG4gICAgICAgICAgcmVzSW5kZXggPSAwLFxuICAgICAgICAgIHJlc3VsdCA9IEFycmF5KG5hdGl2ZUNlaWwobGVuZ3RoIC8gc2l6ZSkpO1xuXG4gICAgICB3aGlsZSAoaW5kZXggPCBsZW5ndGgpIHtcbiAgICAgICAgcmVzdWx0W3Jlc0luZGV4KytdID0gYmFzZVNsaWNlKGFycmF5LCBpbmRleCwgKGluZGV4ICs9IHNpemUpKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhbiBhcnJheSB3aXRoIGFsbCBmYWxzZXkgdmFsdWVzIHJlbW92ZWQuIFRoZSB2YWx1ZXMgYGZhbHNlYCwgYG51bGxgLFxuICAgICAqIGAwYCwgYFwiXCJgLCBgdW5kZWZpbmVkYCwgYW5kIGBOYU5gIGFyZSBmYWxzZXkuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMC4xLjBcbiAgICAgKiBAY2F0ZWdvcnkgQXJyYXlcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gY29tcGFjdC5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIG5ldyBhcnJheSBvZiBmaWx0ZXJlZCB2YWx1ZXMuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uY29tcGFjdChbMCwgMSwgZmFsc2UsIDIsICcnLCAzXSk7XG4gICAgICogLy8gPT4gWzEsIDIsIDNdXG4gICAgICovXG4gICAgZnVuY3Rpb24gY29tcGFjdChhcnJheSkge1xuICAgICAgdmFyIGluZGV4ID0gLTEsXG4gICAgICAgICAgbGVuZ3RoID0gYXJyYXkgPT0gbnVsbCA/IDAgOiBhcnJheS5sZW5ndGgsXG4gICAgICAgICAgcmVzSW5kZXggPSAwLFxuICAgICAgICAgIHJlc3VsdCA9IFtdO1xuXG4gICAgICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgICAgICB2YXIgdmFsdWUgPSBhcnJheVtpbmRleF07XG4gICAgICAgIGlmICh2YWx1ZSkge1xuICAgICAgICAgIHJlc3VsdFtyZXNJbmRleCsrXSA9IHZhbHVlO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBuZXcgYXJyYXkgY29uY2F0ZW5hdGluZyBgYXJyYXlgIHdpdGggYW55IGFkZGl0aW9uYWwgYXJyYXlzXG4gICAgICogYW5kL29yIHZhbHVlcy5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjAuMFxuICAgICAqIEBjYXRlZ29yeSBBcnJheVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBjb25jYXRlbmF0ZS5cbiAgICAgKiBAcGFyYW0gey4uLip9IFt2YWx1ZXNdIFRoZSB2YWx1ZXMgdG8gY29uY2F0ZW5hdGUuXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBuZXcgY29uY2F0ZW5hdGVkIGFycmF5LlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgYXJyYXkgPSBbMV07XG4gICAgICogdmFyIG90aGVyID0gXy5jb25jYXQoYXJyYXksIDIsIFszXSwgW1s0XV0pO1xuICAgICAqXG4gICAgICogY29uc29sZS5sb2cob3RoZXIpO1xuICAgICAqIC8vID0+IFsxLCAyLCAzLCBbNF1dXG4gICAgICpcbiAgICAgKiBjb25zb2xlLmxvZyhhcnJheSk7XG4gICAgICogLy8gPT4gWzFdXG4gICAgICovXG4gICAgZnVuY3Rpb24gY29uY2F0KCkge1xuICAgICAgdmFyIGxlbmd0aCA9IGFyZ3VtZW50cy5sZW5ndGg7XG4gICAgICBpZiAoIWxlbmd0aCkge1xuICAgICAgICByZXR1cm4gW107XG4gICAgICB9XG4gICAgICB2YXIgYXJncyA9IEFycmF5KGxlbmd0aCAtIDEpLFxuICAgICAgICAgIGFycmF5ID0gYXJndW1lbnRzWzBdLFxuICAgICAgICAgIGluZGV4ID0gbGVuZ3RoO1xuXG4gICAgICB3aGlsZSAoaW5kZXgtLSkge1xuICAgICAgICBhcmdzW2luZGV4IC0gMV0gPSBhcmd1bWVudHNbaW5kZXhdO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGFycmF5UHVzaChpc0FycmF5KGFycmF5KSA/IGNvcHlBcnJheShhcnJheSkgOiBbYXJyYXldLCBiYXNlRmxhdHRlbihhcmdzLCAxKSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhbiBhcnJheSBvZiBgYXJyYXlgIHZhbHVlcyBub3QgaW5jbHVkZWQgaW4gdGhlIG90aGVyIGdpdmVuIGFycmF5c1xuICAgICAqIHVzaW5nIFtgU2FtZVZhbHVlWmVyb2BdKGh0dHA6Ly9lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzcuMC8jc2VjLXNhbWV2YWx1ZXplcm8pXG4gICAgICogZm9yIGVxdWFsaXR5IGNvbXBhcmlzb25zLiBUaGUgb3JkZXIgYW5kIHJlZmVyZW5jZXMgb2YgcmVzdWx0IHZhbHVlcyBhcmVcbiAgICAgKiBkZXRlcm1pbmVkIGJ5IHRoZSBmaXJzdCBhcnJheS5cbiAgICAgKlxuICAgICAqICoqTm90ZToqKiBVbmxpa2UgYF8ucHVsbEFsbGAsIHRoaXMgbWV0aG9kIHJldHVybnMgYSBuZXcgYXJyYXkuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMC4xLjBcbiAgICAgKiBAY2F0ZWdvcnkgQXJyYXlcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gaW5zcGVjdC5cbiAgICAgKiBAcGFyYW0gey4uLkFycmF5fSBbdmFsdWVzXSBUaGUgdmFsdWVzIHRvIGV4Y2x1ZGUuXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBuZXcgYXJyYXkgb2YgZmlsdGVyZWQgdmFsdWVzLlxuICAgICAqIEBzZWUgXy53aXRob3V0LCBfLnhvclxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLmRpZmZlcmVuY2UoWzIsIDFdLCBbMiwgM10pO1xuICAgICAqIC8vID0+IFsxXVxuICAgICAqL1xuICAgIHZhciBkaWZmZXJlbmNlID0gYmFzZVJlc3QoZnVuY3Rpb24oYXJyYXksIHZhbHVlcykge1xuICAgICAgcmV0dXJuIGlzQXJyYXlMaWtlT2JqZWN0KGFycmF5KVxuICAgICAgICA/IGJhc2VEaWZmZXJlbmNlKGFycmF5LCBiYXNlRmxhdHRlbih2YWx1ZXMsIDEsIGlzQXJyYXlMaWtlT2JqZWN0LCB0cnVlKSlcbiAgICAgICAgOiBbXTtcbiAgICB9KTtcblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIGlzIGxpa2UgYF8uZGlmZmVyZW5jZWAgZXhjZXB0IHRoYXQgaXQgYWNjZXB0cyBgaXRlcmF0ZWVgIHdoaWNoXG4gICAgICogaXMgaW52b2tlZCBmb3IgZWFjaCBlbGVtZW50IG9mIGBhcnJheWAgYW5kIGB2YWx1ZXNgIHRvIGdlbmVyYXRlIHRoZSBjcml0ZXJpb25cbiAgICAgKiBieSB3aGljaCB0aGV5J3JlIGNvbXBhcmVkLiBUaGUgb3JkZXIgYW5kIHJlZmVyZW5jZXMgb2YgcmVzdWx0IHZhbHVlcyBhcmVcbiAgICAgKiBkZXRlcm1pbmVkIGJ5IHRoZSBmaXJzdCBhcnJheS4gVGhlIGl0ZXJhdGVlIGlzIGludm9rZWQgd2l0aCBvbmUgYXJndW1lbnQ6XG4gICAgICogKHZhbHVlKS5cbiAgICAgKlxuICAgICAqICoqTm90ZToqKiBVbmxpa2UgYF8ucHVsbEFsbEJ5YCwgdGhpcyBtZXRob2QgcmV0dXJucyBhIG5ldyBhcnJheS5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjAuMFxuICAgICAqIEBjYXRlZ29yeSBBcnJheVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBpbnNwZWN0LlxuICAgICAqIEBwYXJhbSB7Li4uQXJyYXl9IFt2YWx1ZXNdIFRoZSB2YWx1ZXMgdG8gZXhjbHVkZS5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbaXRlcmF0ZWU9Xy5pZGVudGl0eV0gVGhlIGl0ZXJhdGVlIGludm9rZWQgcGVyIGVsZW1lbnQuXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBuZXcgYXJyYXkgb2YgZmlsdGVyZWQgdmFsdWVzLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLmRpZmZlcmVuY2VCeShbMi4xLCAxLjJdLCBbMi4zLCAzLjRdLCBNYXRoLmZsb29yKTtcbiAgICAgKiAvLyA9PiBbMS4yXVxuICAgICAqXG4gICAgICogLy8gVGhlIGBfLnByb3BlcnR5YCBpdGVyYXRlZSBzaG9ydGhhbmQuXG4gICAgICogXy5kaWZmZXJlbmNlQnkoW3sgJ3gnOiAyIH0sIHsgJ3gnOiAxIH1dLCBbeyAneCc6IDEgfV0sICd4Jyk7XG4gICAgICogLy8gPT4gW3sgJ3gnOiAyIH1dXG4gICAgICovXG4gICAgdmFyIGRpZmZlcmVuY2VCeSA9IGJhc2VSZXN0KGZ1bmN0aW9uKGFycmF5LCB2YWx1ZXMpIHtcbiAgICAgIHZhciBpdGVyYXRlZSA9IGxhc3QodmFsdWVzKTtcbiAgICAgIGlmIChpc0FycmF5TGlrZU9iamVjdChpdGVyYXRlZSkpIHtcbiAgICAgICAgaXRlcmF0ZWUgPSB1bmRlZmluZWQ7XG4gICAgICB9XG4gICAgICByZXR1cm4gaXNBcnJheUxpa2VPYmplY3QoYXJyYXkpXG4gICAgICAgID8gYmFzZURpZmZlcmVuY2UoYXJyYXksIGJhc2VGbGF0dGVuKHZhbHVlcywgMSwgaXNBcnJheUxpa2VPYmplY3QsIHRydWUpLCBnZXRJdGVyYXRlZShpdGVyYXRlZSwgMikpXG4gICAgICAgIDogW107XG4gICAgfSk7XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIG1ldGhvZCBpcyBsaWtlIGBfLmRpZmZlcmVuY2VgIGV4Y2VwdCB0aGF0IGl0IGFjY2VwdHMgYGNvbXBhcmF0b3JgXG4gICAgICogd2hpY2ggaXMgaW52b2tlZCB0byBjb21wYXJlIGVsZW1lbnRzIG9mIGBhcnJheWAgdG8gYHZhbHVlc2AuIFRoZSBvcmRlciBhbmRcbiAgICAgKiByZWZlcmVuY2VzIG9mIHJlc3VsdCB2YWx1ZXMgYXJlIGRldGVybWluZWQgYnkgdGhlIGZpcnN0IGFycmF5LiBUaGUgY29tcGFyYXRvclxuICAgICAqIGlzIGludm9rZWQgd2l0aCB0d28gYXJndW1lbnRzOiAoYXJyVmFsLCBvdGhWYWwpLlxuICAgICAqXG4gICAgICogKipOb3RlOioqIFVubGlrZSBgXy5wdWxsQWxsV2l0aGAsIHRoaXMgbWV0aG9kIHJldHVybnMgYSBuZXcgYXJyYXkuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgQXJyYXlcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gaW5zcGVjdC5cbiAgICAgKiBAcGFyYW0gey4uLkFycmF5fSBbdmFsdWVzXSBUaGUgdmFsdWVzIHRvIGV4Y2x1ZGUuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW2NvbXBhcmF0b3JdIFRoZSBjb21wYXJhdG9yIGludm9rZWQgcGVyIGVsZW1lbnQuXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBuZXcgYXJyYXkgb2YgZmlsdGVyZWQgdmFsdWVzLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgb2JqZWN0cyA9IFt7ICd4JzogMSwgJ3knOiAyIH0sIHsgJ3gnOiAyLCAneSc6IDEgfV07XG4gICAgICpcbiAgICAgKiBfLmRpZmZlcmVuY2VXaXRoKG9iamVjdHMsIFt7ICd4JzogMSwgJ3knOiAyIH1dLCBfLmlzRXF1YWwpO1xuICAgICAqIC8vID0+IFt7ICd4JzogMiwgJ3knOiAxIH1dXG4gICAgICovXG4gICAgdmFyIGRpZmZlcmVuY2VXaXRoID0gYmFzZVJlc3QoZnVuY3Rpb24oYXJyYXksIHZhbHVlcykge1xuICAgICAgdmFyIGNvbXBhcmF0b3IgPSBsYXN0KHZhbHVlcyk7XG4gICAgICBpZiAoaXNBcnJheUxpa2VPYmplY3QoY29tcGFyYXRvcikpIHtcbiAgICAgICAgY29tcGFyYXRvciA9IHVuZGVmaW5lZDtcbiAgICAgIH1cbiAgICAgIHJldHVybiBpc0FycmF5TGlrZU9iamVjdChhcnJheSlcbiAgICAgICAgPyBiYXNlRGlmZmVyZW5jZShhcnJheSwgYmFzZUZsYXR0ZW4odmFsdWVzLCAxLCBpc0FycmF5TGlrZU9iamVjdCwgdHJ1ZSksIHVuZGVmaW5lZCwgY29tcGFyYXRvcilcbiAgICAgICAgOiBbXTtcbiAgICB9KTtcblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBzbGljZSBvZiBgYXJyYXlgIHdpdGggYG5gIGVsZW1lbnRzIGRyb3BwZWQgZnJvbSB0aGUgYmVnaW5uaW5nLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDAuNS4wXG4gICAgICogQGNhdGVnb3J5IEFycmF5XG4gICAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIHF1ZXJ5LlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbbj0xXSBUaGUgbnVtYmVyIG9mIGVsZW1lbnRzIHRvIGRyb3AuXG4gICAgICogQHBhcmFtLSB7T2JqZWN0fSBbZ3VhcmRdIEVuYWJsZXMgdXNlIGFzIGFuIGl0ZXJhdGVlIGZvciBtZXRob2RzIGxpa2UgYF8ubWFwYC5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIHNsaWNlIG9mIGBhcnJheWAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uZHJvcChbMSwgMiwgM10pO1xuICAgICAqIC8vID0+IFsyLCAzXVxuICAgICAqXG4gICAgICogXy5kcm9wKFsxLCAyLCAzXSwgMik7XG4gICAgICogLy8gPT4gWzNdXG4gICAgICpcbiAgICAgKiBfLmRyb3AoWzEsIDIsIDNdLCA1KTtcbiAgICAgKiAvLyA9PiBbXVxuICAgICAqXG4gICAgICogXy5kcm9wKFsxLCAyLCAzXSwgMCk7XG4gICAgICogLy8gPT4gWzEsIDIsIDNdXG4gICAgICovXG4gICAgZnVuY3Rpb24gZHJvcChhcnJheSwgbiwgZ3VhcmQpIHtcbiAgICAgIHZhciBsZW5ndGggPSBhcnJheSA9PSBudWxsID8gMCA6IGFycmF5Lmxlbmd0aDtcbiAgICAgIGlmICghbGVuZ3RoKSB7XG4gICAgICAgIHJldHVybiBbXTtcbiAgICAgIH1cbiAgICAgIG4gPSAoZ3VhcmQgfHwgbiA9PT0gdW5kZWZpbmVkKSA/IDEgOiB0b0ludGVnZXIobik7XG4gICAgICByZXR1cm4gYmFzZVNsaWNlKGFycmF5LCBuIDwgMCA/IDAgOiBuLCBsZW5ndGgpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBzbGljZSBvZiBgYXJyYXlgIHdpdGggYG5gIGVsZW1lbnRzIGRyb3BwZWQgZnJvbSB0aGUgZW5kLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDMuMC4wXG4gICAgICogQGNhdGVnb3J5IEFycmF5XG4gICAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIHF1ZXJ5LlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbbj0xXSBUaGUgbnVtYmVyIG9mIGVsZW1lbnRzIHRvIGRyb3AuXG4gICAgICogQHBhcmFtLSB7T2JqZWN0fSBbZ3VhcmRdIEVuYWJsZXMgdXNlIGFzIGFuIGl0ZXJhdGVlIGZvciBtZXRob2RzIGxpa2UgYF8ubWFwYC5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIHNsaWNlIG9mIGBhcnJheWAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uZHJvcFJpZ2h0KFsxLCAyLCAzXSk7XG4gICAgICogLy8gPT4gWzEsIDJdXG4gICAgICpcbiAgICAgKiBfLmRyb3BSaWdodChbMSwgMiwgM10sIDIpO1xuICAgICAqIC8vID0+IFsxXVxuICAgICAqXG4gICAgICogXy5kcm9wUmlnaHQoWzEsIDIsIDNdLCA1KTtcbiAgICAgKiAvLyA9PiBbXVxuICAgICAqXG4gICAgICogXy5kcm9wUmlnaHQoWzEsIDIsIDNdLCAwKTtcbiAgICAgKiAvLyA9PiBbMSwgMiwgM11cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBkcm9wUmlnaHQoYXJyYXksIG4sIGd1YXJkKSB7XG4gICAgICB2YXIgbGVuZ3RoID0gYXJyYXkgPT0gbnVsbCA/IDAgOiBhcnJheS5sZW5ndGg7XG4gICAgICBpZiAoIWxlbmd0aCkge1xuICAgICAgICByZXR1cm4gW107XG4gICAgICB9XG4gICAgICBuID0gKGd1YXJkIHx8IG4gPT09IHVuZGVmaW5lZCkgPyAxIDogdG9JbnRlZ2VyKG4pO1xuICAgICAgbiA9IGxlbmd0aCAtIG47XG4gICAgICByZXR1cm4gYmFzZVNsaWNlKGFycmF5LCAwLCBuIDwgMCA/IDAgOiBuKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgc2xpY2Ugb2YgYGFycmF5YCBleGNsdWRpbmcgZWxlbWVudHMgZHJvcHBlZCBmcm9tIHRoZSBlbmQuXG4gICAgICogRWxlbWVudHMgYXJlIGRyb3BwZWQgdW50aWwgYHByZWRpY2F0ZWAgcmV0dXJucyBmYWxzZXkuIFRoZSBwcmVkaWNhdGUgaXNcbiAgICAgKiBpbnZva2VkIHdpdGggdGhyZWUgYXJndW1lbnRzOiAodmFsdWUsIGluZGV4LCBhcnJheSkuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMy4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgQXJyYXlcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gcXVlcnkuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW3ByZWRpY2F0ZT1fLmlkZW50aXR5XSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgc2xpY2Ugb2YgYGFycmF5YC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIHVzZXJzID0gW1xuICAgICAqICAgeyAndXNlcic6ICdiYXJuZXknLCAgJ2FjdGl2ZSc6IHRydWUgfSxcbiAgICAgKiAgIHsgJ3VzZXInOiAnZnJlZCcsICAgICdhY3RpdmUnOiBmYWxzZSB9LFxuICAgICAqICAgeyAndXNlcic6ICdwZWJibGVzJywgJ2FjdGl2ZSc6IGZhbHNlIH1cbiAgICAgKiBdO1xuICAgICAqXG4gICAgICogXy5kcm9wUmlnaHRXaGlsZSh1c2VycywgZnVuY3Rpb24obykgeyByZXR1cm4gIW8uYWN0aXZlOyB9KTtcbiAgICAgKiAvLyA9PiBvYmplY3RzIGZvciBbJ2Jhcm5leSddXG4gICAgICpcbiAgICAgKiAvLyBUaGUgYF8ubWF0Y2hlc2AgaXRlcmF0ZWUgc2hvcnRoYW5kLlxuICAgICAqIF8uZHJvcFJpZ2h0V2hpbGUodXNlcnMsIHsgJ3VzZXInOiAncGViYmxlcycsICdhY3RpdmUnOiBmYWxzZSB9KTtcbiAgICAgKiAvLyA9PiBvYmplY3RzIGZvciBbJ2Jhcm5leScsICdmcmVkJ11cbiAgICAgKlxuICAgICAqIC8vIFRoZSBgXy5tYXRjaGVzUHJvcGVydHlgIGl0ZXJhdGVlIHNob3J0aGFuZC5cbiAgICAgKiBfLmRyb3BSaWdodFdoaWxlKHVzZXJzLCBbJ2FjdGl2ZScsIGZhbHNlXSk7XG4gICAgICogLy8gPT4gb2JqZWN0cyBmb3IgWydiYXJuZXknXVxuICAgICAqXG4gICAgICogLy8gVGhlIGBfLnByb3BlcnR5YCBpdGVyYXRlZSBzaG9ydGhhbmQuXG4gICAgICogXy5kcm9wUmlnaHRXaGlsZSh1c2VycywgJ2FjdGl2ZScpO1xuICAgICAqIC8vID0+IG9iamVjdHMgZm9yIFsnYmFybmV5JywgJ2ZyZWQnLCAncGViYmxlcyddXG4gICAgICovXG4gICAgZnVuY3Rpb24gZHJvcFJpZ2h0V2hpbGUoYXJyYXksIHByZWRpY2F0ZSkge1xuICAgICAgcmV0dXJuIChhcnJheSAmJiBhcnJheS5sZW5ndGgpXG4gICAgICAgID8gYmFzZVdoaWxlKGFycmF5LCBnZXRJdGVyYXRlZShwcmVkaWNhdGUsIDMpLCB0cnVlLCB0cnVlKVxuICAgICAgICA6IFtdO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBzbGljZSBvZiBgYXJyYXlgIGV4Y2x1ZGluZyBlbGVtZW50cyBkcm9wcGVkIGZyb20gdGhlIGJlZ2lubmluZy5cbiAgICAgKiBFbGVtZW50cyBhcmUgZHJvcHBlZCB1bnRpbCBgcHJlZGljYXRlYCByZXR1cm5zIGZhbHNleS4gVGhlIHByZWRpY2F0ZSBpc1xuICAgICAqIGludm9rZWQgd2l0aCB0aHJlZSBhcmd1bWVudHM6ICh2YWx1ZSwgaW5kZXgsIGFycmF5KS5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAzLjAuMFxuICAgICAqIEBjYXRlZ29yeSBBcnJheVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBxdWVyeS5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbcHJlZGljYXRlPV8uaWRlbnRpdHldIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBzbGljZSBvZiBgYXJyYXlgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgdXNlcnMgPSBbXG4gICAgICogICB7ICd1c2VyJzogJ2Jhcm5leScsICAnYWN0aXZlJzogZmFsc2UgfSxcbiAgICAgKiAgIHsgJ3VzZXInOiAnZnJlZCcsICAgICdhY3RpdmUnOiBmYWxzZSB9LFxuICAgICAqICAgeyAndXNlcic6ICdwZWJibGVzJywgJ2FjdGl2ZSc6IHRydWUgfVxuICAgICAqIF07XG4gICAgICpcbiAgICAgKiBfLmRyb3BXaGlsZSh1c2VycywgZnVuY3Rpb24obykgeyByZXR1cm4gIW8uYWN0aXZlOyB9KTtcbiAgICAgKiAvLyA9PiBvYmplY3RzIGZvciBbJ3BlYmJsZXMnXVxuICAgICAqXG4gICAgICogLy8gVGhlIGBfLm1hdGNoZXNgIGl0ZXJhdGVlIHNob3J0aGFuZC5cbiAgICAgKiBfLmRyb3BXaGlsZSh1c2VycywgeyAndXNlcic6ICdiYXJuZXknLCAnYWN0aXZlJzogZmFsc2UgfSk7XG4gICAgICogLy8gPT4gb2JqZWN0cyBmb3IgWydmcmVkJywgJ3BlYmJsZXMnXVxuICAgICAqXG4gICAgICogLy8gVGhlIGBfLm1hdGNoZXNQcm9wZXJ0eWAgaXRlcmF0ZWUgc2hvcnRoYW5kLlxuICAgICAqIF8uZHJvcFdoaWxlKHVzZXJzLCBbJ2FjdGl2ZScsIGZhbHNlXSk7XG4gICAgICogLy8gPT4gb2JqZWN0cyBmb3IgWydwZWJibGVzJ11cbiAgICAgKlxuICAgICAqIC8vIFRoZSBgXy5wcm9wZXJ0eWAgaXRlcmF0ZWUgc2hvcnRoYW5kLlxuICAgICAqIF8uZHJvcFdoaWxlKHVzZXJzLCAnYWN0aXZlJyk7XG4gICAgICogLy8gPT4gb2JqZWN0cyBmb3IgWydiYXJuZXknLCAnZnJlZCcsICdwZWJibGVzJ11cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBkcm9wV2hpbGUoYXJyYXksIHByZWRpY2F0ZSkge1xuICAgICAgcmV0dXJuIChhcnJheSAmJiBhcnJheS5sZW5ndGgpXG4gICAgICAgID8gYmFzZVdoaWxlKGFycmF5LCBnZXRJdGVyYXRlZShwcmVkaWNhdGUsIDMpLCB0cnVlKVxuICAgICAgICA6IFtdO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEZpbGxzIGVsZW1lbnRzIG9mIGBhcnJheWAgd2l0aCBgdmFsdWVgIGZyb20gYHN0YXJ0YCB1cCB0bywgYnV0IG5vdFxuICAgICAqIGluY2x1ZGluZywgYGVuZGAuXG4gICAgICpcbiAgICAgKiAqKk5vdGU6KiogVGhpcyBtZXRob2QgbXV0YXRlcyBgYXJyYXlgLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDMuMi4wXG4gICAgICogQGNhdGVnb3J5IEFycmF5XG4gICAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIGZpbGwuXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gZmlsbCBgYXJyYXlgIHdpdGguXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtzdGFydD0wXSBUaGUgc3RhcnQgcG9zaXRpb24uXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtlbmQ9YXJyYXkubGVuZ3RoXSBUaGUgZW5kIHBvc2l0aW9uLlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyBgYXJyYXlgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgYXJyYXkgPSBbMSwgMiwgM107XG4gICAgICpcbiAgICAgKiBfLmZpbGwoYXJyYXksICdhJyk7XG4gICAgICogY29uc29sZS5sb2coYXJyYXkpO1xuICAgICAqIC8vID0+IFsnYScsICdhJywgJ2EnXVxuICAgICAqXG4gICAgICogXy5maWxsKEFycmF5KDMpLCAyKTtcbiAgICAgKiAvLyA9PiBbMiwgMiwgMl1cbiAgICAgKlxuICAgICAqIF8uZmlsbChbNCwgNiwgOCwgMTBdLCAnKicsIDEsIDMpO1xuICAgICAqIC8vID0+IFs0LCAnKicsICcqJywgMTBdXG4gICAgICovXG4gICAgZnVuY3Rpb24gZmlsbChhcnJheSwgdmFsdWUsIHN0YXJ0LCBlbmQpIHtcbiAgICAgIHZhciBsZW5ndGggPSBhcnJheSA9PSBudWxsID8gMCA6IGFycmF5Lmxlbmd0aDtcbiAgICAgIGlmICghbGVuZ3RoKSB7XG4gICAgICAgIHJldHVybiBbXTtcbiAgICAgIH1cbiAgICAgIGlmIChzdGFydCAmJiB0eXBlb2Ygc3RhcnQgIT0gJ251bWJlcicgJiYgaXNJdGVyYXRlZUNhbGwoYXJyYXksIHZhbHVlLCBzdGFydCkpIHtcbiAgICAgICAgc3RhcnQgPSAwO1xuICAgICAgICBlbmQgPSBsZW5ndGg7XG4gICAgICB9XG4gICAgICByZXR1cm4gYmFzZUZpbGwoYXJyYXksIHZhbHVlLCBzdGFydCwgZW5kKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIG1ldGhvZCBpcyBsaWtlIGBfLmZpbmRgIGV4Y2VwdCB0aGF0IGl0IHJldHVybnMgdGhlIGluZGV4IG9mIHRoZSBmaXJzdFxuICAgICAqIGVsZW1lbnQgYHByZWRpY2F0ZWAgcmV0dXJucyB0cnV0aHkgZm9yIGluc3RlYWQgb2YgdGhlIGVsZW1lbnQgaXRzZWxmLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDEuMS4wXG4gICAgICogQGNhdGVnb3J5IEFycmF5XG4gICAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIGluc3BlY3QuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW3ByZWRpY2F0ZT1fLmlkZW50aXR5XSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbZnJvbUluZGV4PTBdIFRoZSBpbmRleCB0byBzZWFyY2ggZnJvbS5cbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBSZXR1cm5zIHRoZSBpbmRleCBvZiB0aGUgZm91bmQgZWxlbWVudCwgZWxzZSBgLTFgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgdXNlcnMgPSBbXG4gICAgICogICB7ICd1c2VyJzogJ2Jhcm5leScsICAnYWN0aXZlJzogZmFsc2UgfSxcbiAgICAgKiAgIHsgJ3VzZXInOiAnZnJlZCcsICAgICdhY3RpdmUnOiBmYWxzZSB9LFxuICAgICAqICAgeyAndXNlcic6ICdwZWJibGVzJywgJ2FjdGl2ZSc6IHRydWUgfVxuICAgICAqIF07XG4gICAgICpcbiAgICAgKiBfLmZpbmRJbmRleCh1c2VycywgZnVuY3Rpb24obykgeyByZXR1cm4gby51c2VyID09ICdiYXJuZXknOyB9KTtcbiAgICAgKiAvLyA9PiAwXG4gICAgICpcbiAgICAgKiAvLyBUaGUgYF8ubWF0Y2hlc2AgaXRlcmF0ZWUgc2hvcnRoYW5kLlxuICAgICAqIF8uZmluZEluZGV4KHVzZXJzLCB7ICd1c2VyJzogJ2ZyZWQnLCAnYWN0aXZlJzogZmFsc2UgfSk7XG4gICAgICogLy8gPT4gMVxuICAgICAqXG4gICAgICogLy8gVGhlIGBfLm1hdGNoZXNQcm9wZXJ0eWAgaXRlcmF0ZWUgc2hvcnRoYW5kLlxuICAgICAqIF8uZmluZEluZGV4KHVzZXJzLCBbJ2FjdGl2ZScsIGZhbHNlXSk7XG4gICAgICogLy8gPT4gMFxuICAgICAqXG4gICAgICogLy8gVGhlIGBfLnByb3BlcnR5YCBpdGVyYXRlZSBzaG9ydGhhbmQuXG4gICAgICogXy5maW5kSW5kZXgodXNlcnMsICdhY3RpdmUnKTtcbiAgICAgKiAvLyA9PiAyXG4gICAgICovXG4gICAgZnVuY3Rpb24gZmluZEluZGV4KGFycmF5LCBwcmVkaWNhdGUsIGZyb21JbmRleCkge1xuICAgICAgdmFyIGxlbmd0aCA9IGFycmF5ID09IG51bGwgPyAwIDogYXJyYXkubGVuZ3RoO1xuICAgICAgaWYgKCFsZW5ndGgpIHtcbiAgICAgICAgcmV0dXJuIC0xO1xuICAgICAgfVxuICAgICAgdmFyIGluZGV4ID0gZnJvbUluZGV4ID09IG51bGwgPyAwIDogdG9JbnRlZ2VyKGZyb21JbmRleCk7XG4gICAgICBpZiAoaW5kZXggPCAwKSB7XG4gICAgICAgIGluZGV4ID0gbmF0aXZlTWF4KGxlbmd0aCArIGluZGV4LCAwKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBiYXNlRmluZEluZGV4KGFycmF5LCBnZXRJdGVyYXRlZShwcmVkaWNhdGUsIDMpLCBpbmRleCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgaXMgbGlrZSBgXy5maW5kSW5kZXhgIGV4Y2VwdCB0aGF0IGl0IGl0ZXJhdGVzIG92ZXIgZWxlbWVudHNcbiAgICAgKiBvZiBgY29sbGVjdGlvbmAgZnJvbSByaWdodCB0byBsZWZ0LlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDIuMC4wXG4gICAgICogQGNhdGVnb3J5IEFycmF5XG4gICAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIGluc3BlY3QuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW3ByZWRpY2F0ZT1fLmlkZW50aXR5XSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbZnJvbUluZGV4PWFycmF5Lmxlbmd0aC0xXSBUaGUgaW5kZXggdG8gc2VhcmNoIGZyb20uXG4gICAgICogQHJldHVybnMge251bWJlcn0gUmV0dXJucyB0aGUgaW5kZXggb2YgdGhlIGZvdW5kIGVsZW1lbnQsIGVsc2UgYC0xYC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIHVzZXJzID0gW1xuICAgICAqICAgeyAndXNlcic6ICdiYXJuZXknLCAgJ2FjdGl2ZSc6IHRydWUgfSxcbiAgICAgKiAgIHsgJ3VzZXInOiAnZnJlZCcsICAgICdhY3RpdmUnOiBmYWxzZSB9LFxuICAgICAqICAgeyAndXNlcic6ICdwZWJibGVzJywgJ2FjdGl2ZSc6IGZhbHNlIH1cbiAgICAgKiBdO1xuICAgICAqXG4gICAgICogXy5maW5kTGFzdEluZGV4KHVzZXJzLCBmdW5jdGlvbihvKSB7IHJldHVybiBvLnVzZXIgPT0gJ3BlYmJsZXMnOyB9KTtcbiAgICAgKiAvLyA9PiAyXG4gICAgICpcbiAgICAgKiAvLyBUaGUgYF8ubWF0Y2hlc2AgaXRlcmF0ZWUgc2hvcnRoYW5kLlxuICAgICAqIF8uZmluZExhc3RJbmRleCh1c2VycywgeyAndXNlcic6ICdiYXJuZXknLCAnYWN0aXZlJzogdHJ1ZSB9KTtcbiAgICAgKiAvLyA9PiAwXG4gICAgICpcbiAgICAgKiAvLyBUaGUgYF8ubWF0Y2hlc1Byb3BlcnR5YCBpdGVyYXRlZSBzaG9ydGhhbmQuXG4gICAgICogXy5maW5kTGFzdEluZGV4KHVzZXJzLCBbJ2FjdGl2ZScsIGZhbHNlXSk7XG4gICAgICogLy8gPT4gMlxuICAgICAqXG4gICAgICogLy8gVGhlIGBfLnByb3BlcnR5YCBpdGVyYXRlZSBzaG9ydGhhbmQuXG4gICAgICogXy5maW5kTGFzdEluZGV4KHVzZXJzLCAnYWN0aXZlJyk7XG4gICAgICogLy8gPT4gMFxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGZpbmRMYXN0SW5kZXgoYXJyYXksIHByZWRpY2F0ZSwgZnJvbUluZGV4KSB7XG4gICAgICB2YXIgbGVuZ3RoID0gYXJyYXkgPT0gbnVsbCA/IDAgOiBhcnJheS5sZW5ndGg7XG4gICAgICBpZiAoIWxlbmd0aCkge1xuICAgICAgICByZXR1cm4gLTE7XG4gICAgICB9XG4gICAgICB2YXIgaW5kZXggPSBsZW5ndGggLSAxO1xuICAgICAgaWYgKGZyb21JbmRleCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGluZGV4ID0gdG9JbnRlZ2VyKGZyb21JbmRleCk7XG4gICAgICAgIGluZGV4ID0gZnJvbUluZGV4IDwgMFxuICAgICAgICAgID8gbmF0aXZlTWF4KGxlbmd0aCArIGluZGV4LCAwKVxuICAgICAgICAgIDogbmF0aXZlTWluKGluZGV4LCBsZW5ndGggLSAxKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBiYXNlRmluZEluZGV4KGFycmF5LCBnZXRJdGVyYXRlZShwcmVkaWNhdGUsIDMpLCBpbmRleCwgdHJ1ZSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRmxhdHRlbnMgYGFycmF5YCBhIHNpbmdsZSBsZXZlbCBkZWVwLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDAuMS4wXG4gICAgICogQGNhdGVnb3J5IEFycmF5XG4gICAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIGZsYXR0ZW4uXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBuZXcgZmxhdHRlbmVkIGFycmF5LlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLmZsYXR0ZW4oWzEsIFsyLCBbMywgWzRdXSwgNV1dKTtcbiAgICAgKiAvLyA9PiBbMSwgMiwgWzMsIFs0XV0sIDVdXG4gICAgICovXG4gICAgZnVuY3Rpb24gZmxhdHRlbihhcnJheSkge1xuICAgICAgdmFyIGxlbmd0aCA9IGFycmF5ID09IG51bGwgPyAwIDogYXJyYXkubGVuZ3RoO1xuICAgICAgcmV0dXJuIGxlbmd0aCA/IGJhc2VGbGF0dGVuKGFycmF5LCAxKSA6IFtdO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJlY3Vyc2l2ZWx5IGZsYXR0ZW5zIGBhcnJheWAuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMy4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgQXJyYXlcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gZmxhdHRlbi5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIG5ldyBmbGF0dGVuZWQgYXJyYXkuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uZmxhdHRlbkRlZXAoWzEsIFsyLCBbMywgWzRdXSwgNV1dKTtcbiAgICAgKiAvLyA9PiBbMSwgMiwgMywgNCwgNV1cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBmbGF0dGVuRGVlcChhcnJheSkge1xuICAgICAgdmFyIGxlbmd0aCA9IGFycmF5ID09IG51bGwgPyAwIDogYXJyYXkubGVuZ3RoO1xuICAgICAgcmV0dXJuIGxlbmd0aCA/IGJhc2VGbGF0dGVuKGFycmF5LCBJTkZJTklUWSkgOiBbXTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZWN1cnNpdmVseSBmbGF0dGVuIGBhcnJheWAgdXAgdG8gYGRlcHRoYCB0aW1lcy5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjQuMFxuICAgICAqIEBjYXRlZ29yeSBBcnJheVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBmbGF0dGVuLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbZGVwdGg9MV0gVGhlIG1heGltdW0gcmVjdXJzaW9uIGRlcHRoLlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IGZsYXR0ZW5lZCBhcnJheS5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIGFycmF5ID0gWzEsIFsyLCBbMywgWzRdXSwgNV1dO1xuICAgICAqXG4gICAgICogXy5mbGF0dGVuRGVwdGgoYXJyYXksIDEpO1xuICAgICAqIC8vID0+IFsxLCAyLCBbMywgWzRdXSwgNV1cbiAgICAgKlxuICAgICAqIF8uZmxhdHRlbkRlcHRoKGFycmF5LCAyKTtcbiAgICAgKiAvLyA9PiBbMSwgMiwgMywgWzRdLCA1XVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGZsYXR0ZW5EZXB0aChhcnJheSwgZGVwdGgpIHtcbiAgICAgIHZhciBsZW5ndGggPSBhcnJheSA9PSBudWxsID8gMCA6IGFycmF5Lmxlbmd0aDtcbiAgICAgIGlmICghbGVuZ3RoKSB7XG4gICAgICAgIHJldHVybiBbXTtcbiAgICAgIH1cbiAgICAgIGRlcHRoID0gZGVwdGggPT09IHVuZGVmaW5lZCA/IDEgOiB0b0ludGVnZXIoZGVwdGgpO1xuICAgICAgcmV0dXJuIGJhc2VGbGF0dGVuKGFycmF5LCBkZXB0aCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIGludmVyc2Ugb2YgYF8udG9QYWlyc2A7IHRoaXMgbWV0aG9kIHJldHVybnMgYW4gb2JqZWN0IGNvbXBvc2VkXG4gICAgICogZnJvbSBrZXktdmFsdWUgYHBhaXJzYC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjAuMFxuICAgICAqIEBjYXRlZ29yeSBBcnJheVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IHBhaXJzIFRoZSBrZXktdmFsdWUgcGFpcnMuXG4gICAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyB0aGUgbmV3IG9iamVjdC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5mcm9tUGFpcnMoW1snYScsIDFdLCBbJ2InLCAyXV0pO1xuICAgICAqIC8vID0+IHsgJ2EnOiAxLCAnYic6IDIgfVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGZyb21QYWlycyhwYWlycykge1xuICAgICAgdmFyIGluZGV4ID0gLTEsXG4gICAgICAgICAgbGVuZ3RoID0gcGFpcnMgPT0gbnVsbCA/IDAgOiBwYWlycy5sZW5ndGgsXG4gICAgICAgICAgcmVzdWx0ID0ge307XG5cbiAgICAgIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XG4gICAgICAgIHZhciBwYWlyID0gcGFpcnNbaW5kZXhdO1xuICAgICAgICByZXN1bHRbcGFpclswXV0gPSBwYWlyWzFdO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXRzIHRoZSBmaXJzdCBlbGVtZW50IG9mIGBhcnJheWAuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMC4xLjBcbiAgICAgKiBAYWxpYXMgZmlyc3RcbiAgICAgKiBAY2F0ZWdvcnkgQXJyYXlcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gcXVlcnkuXG4gICAgICogQHJldHVybnMgeyp9IFJldHVybnMgdGhlIGZpcnN0IGVsZW1lbnQgb2YgYGFycmF5YC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5oZWFkKFsxLCAyLCAzXSk7XG4gICAgICogLy8gPT4gMVxuICAgICAqXG4gICAgICogXy5oZWFkKFtdKTtcbiAgICAgKiAvLyA9PiB1bmRlZmluZWRcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBoZWFkKGFycmF5KSB7XG4gICAgICByZXR1cm4gKGFycmF5ICYmIGFycmF5Lmxlbmd0aCkgPyBhcnJheVswXSA6IHVuZGVmaW5lZDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXRzIHRoZSBpbmRleCBhdCB3aGljaCB0aGUgZmlyc3Qgb2NjdXJyZW5jZSBvZiBgdmFsdWVgIGlzIGZvdW5kIGluIGBhcnJheWBcbiAgICAgKiB1c2luZyBbYFNhbWVWYWx1ZVplcm9gXShodHRwOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi83LjAvI3NlYy1zYW1ldmFsdWV6ZXJvKVxuICAgICAqIGZvciBlcXVhbGl0eSBjb21wYXJpc29ucy4gSWYgYGZyb21JbmRleGAgaXMgbmVnYXRpdmUsIGl0J3MgdXNlZCBhcyB0aGVcbiAgICAgKiBvZmZzZXQgZnJvbSB0aGUgZW5kIG9mIGBhcnJheWAuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMC4xLjBcbiAgICAgKiBAY2F0ZWdvcnkgQXJyYXlcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gaW5zcGVjdC5cbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBzZWFyY2ggZm9yLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbZnJvbUluZGV4PTBdIFRoZSBpbmRleCB0byBzZWFyY2ggZnJvbS5cbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBSZXR1cm5zIHRoZSBpbmRleCBvZiB0aGUgbWF0Y2hlZCB2YWx1ZSwgZWxzZSBgLTFgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLmluZGV4T2YoWzEsIDIsIDEsIDJdLCAyKTtcbiAgICAgKiAvLyA9PiAxXG4gICAgICpcbiAgICAgKiAvLyBTZWFyY2ggZnJvbSB0aGUgYGZyb21JbmRleGAuXG4gICAgICogXy5pbmRleE9mKFsxLCAyLCAxLCAyXSwgMiwgMik7XG4gICAgICogLy8gPT4gM1xuICAgICAqL1xuICAgIGZ1bmN0aW9uIGluZGV4T2YoYXJyYXksIHZhbHVlLCBmcm9tSW5kZXgpIHtcbiAgICAgIHZhciBsZW5ndGggPSBhcnJheSA9PSBudWxsID8gMCA6IGFycmF5Lmxlbmd0aDtcbiAgICAgIGlmICghbGVuZ3RoKSB7XG4gICAgICAgIHJldHVybiAtMTtcbiAgICAgIH1cbiAgICAgIHZhciBpbmRleCA9IGZyb21JbmRleCA9PSBudWxsID8gMCA6IHRvSW50ZWdlcihmcm9tSW5kZXgpO1xuICAgICAgaWYgKGluZGV4IDwgMCkge1xuICAgICAgICBpbmRleCA9IG5hdGl2ZU1heChsZW5ndGggKyBpbmRleCwgMCk7XG4gICAgICB9XG4gICAgICByZXR1cm4gYmFzZUluZGV4T2YoYXJyYXksIHZhbHVlLCBpbmRleCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0cyBhbGwgYnV0IHRoZSBsYXN0IGVsZW1lbnQgb2YgYGFycmF5YC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAwLjEuMFxuICAgICAqIEBjYXRlZ29yeSBBcnJheVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBxdWVyeS5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIHNsaWNlIG9mIGBhcnJheWAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uaW5pdGlhbChbMSwgMiwgM10pO1xuICAgICAqIC8vID0+IFsxLCAyXVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGluaXRpYWwoYXJyYXkpIHtcbiAgICAgIHZhciBsZW5ndGggPSBhcnJheSA9PSBudWxsID8gMCA6IGFycmF5Lmxlbmd0aDtcbiAgICAgIHJldHVybiBsZW5ndGggPyBiYXNlU2xpY2UoYXJyYXksIDAsIC0xKSA6IFtdO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYW4gYXJyYXkgb2YgdW5pcXVlIHZhbHVlcyB0aGF0IGFyZSBpbmNsdWRlZCBpbiBhbGwgZ2l2ZW4gYXJyYXlzXG4gICAgICogdXNpbmcgW2BTYW1lVmFsdWVaZXJvYF0oaHR0cDovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNy4wLyNzZWMtc2FtZXZhbHVlemVybylcbiAgICAgKiBmb3IgZXF1YWxpdHkgY29tcGFyaXNvbnMuIFRoZSBvcmRlciBhbmQgcmVmZXJlbmNlcyBvZiByZXN1bHQgdmFsdWVzIGFyZVxuICAgICAqIGRldGVybWluZWQgYnkgdGhlIGZpcnN0IGFycmF5LlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDAuMS4wXG4gICAgICogQGNhdGVnb3J5IEFycmF5XG4gICAgICogQHBhcmFtIHsuLi5BcnJheX0gW2FycmF5c10gVGhlIGFycmF5cyB0byBpbnNwZWN0LlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IGFycmF5IG9mIGludGVyc2VjdGluZyB2YWx1ZXMuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uaW50ZXJzZWN0aW9uKFsyLCAxXSwgWzIsIDNdKTtcbiAgICAgKiAvLyA9PiBbMl1cbiAgICAgKi9cbiAgICB2YXIgaW50ZXJzZWN0aW9uID0gYmFzZVJlc3QoZnVuY3Rpb24oYXJyYXlzKSB7XG4gICAgICB2YXIgbWFwcGVkID0gYXJyYXlNYXAoYXJyYXlzLCBjYXN0QXJyYXlMaWtlT2JqZWN0KTtcbiAgICAgIHJldHVybiAobWFwcGVkLmxlbmd0aCAmJiBtYXBwZWRbMF0gPT09IGFycmF5c1swXSlcbiAgICAgICAgPyBiYXNlSW50ZXJzZWN0aW9uKG1hcHBlZClcbiAgICAgICAgOiBbXTtcbiAgICB9KTtcblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIGlzIGxpa2UgYF8uaW50ZXJzZWN0aW9uYCBleGNlcHQgdGhhdCBpdCBhY2NlcHRzIGBpdGVyYXRlZWBcbiAgICAgKiB3aGljaCBpcyBpbnZva2VkIGZvciBlYWNoIGVsZW1lbnQgb2YgZWFjaCBgYXJyYXlzYCB0byBnZW5lcmF0ZSB0aGUgY3JpdGVyaW9uXG4gICAgICogYnkgd2hpY2ggdGhleSdyZSBjb21wYXJlZC4gVGhlIG9yZGVyIGFuZCByZWZlcmVuY2VzIG9mIHJlc3VsdCB2YWx1ZXMgYXJlXG4gICAgICogZGV0ZXJtaW5lZCBieSB0aGUgZmlyc3QgYXJyYXkuIFRoZSBpdGVyYXRlZSBpcyBpbnZva2VkIHdpdGggb25lIGFyZ3VtZW50OlxuICAgICAqICh2YWx1ZSkuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgQXJyYXlcbiAgICAgKiBAcGFyYW0gey4uLkFycmF5fSBbYXJyYXlzXSBUaGUgYXJyYXlzIHRvIGluc3BlY3QuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW2l0ZXJhdGVlPV8uaWRlbnRpdHldIFRoZSBpdGVyYXRlZSBpbnZva2VkIHBlciBlbGVtZW50LlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IGFycmF5IG9mIGludGVyc2VjdGluZyB2YWx1ZXMuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uaW50ZXJzZWN0aW9uQnkoWzIuMSwgMS4yXSwgWzIuMywgMy40XSwgTWF0aC5mbG9vcik7XG4gICAgICogLy8gPT4gWzIuMV1cbiAgICAgKlxuICAgICAqIC8vIFRoZSBgXy5wcm9wZXJ0eWAgaXRlcmF0ZWUgc2hvcnRoYW5kLlxuICAgICAqIF8uaW50ZXJzZWN0aW9uQnkoW3sgJ3gnOiAxIH1dLCBbeyAneCc6IDIgfSwgeyAneCc6IDEgfV0sICd4Jyk7XG4gICAgICogLy8gPT4gW3sgJ3gnOiAxIH1dXG4gICAgICovXG4gICAgdmFyIGludGVyc2VjdGlvbkJ5ID0gYmFzZVJlc3QoZnVuY3Rpb24oYXJyYXlzKSB7XG4gICAgICB2YXIgaXRlcmF0ZWUgPSBsYXN0KGFycmF5cyksXG4gICAgICAgICAgbWFwcGVkID0gYXJyYXlNYXAoYXJyYXlzLCBjYXN0QXJyYXlMaWtlT2JqZWN0KTtcblxuICAgICAgaWYgKGl0ZXJhdGVlID09PSBsYXN0KG1hcHBlZCkpIHtcbiAgICAgICAgaXRlcmF0ZWUgPSB1bmRlZmluZWQ7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBtYXBwZWQucG9wKCk7XG4gICAgICB9XG4gICAgICByZXR1cm4gKG1hcHBlZC5sZW5ndGggJiYgbWFwcGVkWzBdID09PSBhcnJheXNbMF0pXG4gICAgICAgID8gYmFzZUludGVyc2VjdGlvbihtYXBwZWQsIGdldEl0ZXJhdGVlKGl0ZXJhdGVlLCAyKSlcbiAgICAgICAgOiBbXTtcbiAgICB9KTtcblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIGlzIGxpa2UgYF8uaW50ZXJzZWN0aW9uYCBleGNlcHQgdGhhdCBpdCBhY2NlcHRzIGBjb21wYXJhdG9yYFxuICAgICAqIHdoaWNoIGlzIGludm9rZWQgdG8gY29tcGFyZSBlbGVtZW50cyBvZiBgYXJyYXlzYC4gVGhlIG9yZGVyIGFuZCByZWZlcmVuY2VzXG4gICAgICogb2YgcmVzdWx0IHZhbHVlcyBhcmUgZGV0ZXJtaW5lZCBieSB0aGUgZmlyc3QgYXJyYXkuIFRoZSBjb21wYXJhdG9yIGlzXG4gICAgICogaW52b2tlZCB3aXRoIHR3byBhcmd1bWVudHM6IChhcnJWYWwsIG90aFZhbCkuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgQXJyYXlcbiAgICAgKiBAcGFyYW0gey4uLkFycmF5fSBbYXJyYXlzXSBUaGUgYXJyYXlzIHRvIGluc3BlY3QuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW2NvbXBhcmF0b3JdIFRoZSBjb21wYXJhdG9yIGludm9rZWQgcGVyIGVsZW1lbnQuXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBuZXcgYXJyYXkgb2YgaW50ZXJzZWN0aW5nIHZhbHVlcy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIG9iamVjdHMgPSBbeyAneCc6IDEsICd5JzogMiB9LCB7ICd4JzogMiwgJ3knOiAxIH1dO1xuICAgICAqIHZhciBvdGhlcnMgPSBbeyAneCc6IDEsICd5JzogMSB9LCB7ICd4JzogMSwgJ3knOiAyIH1dO1xuICAgICAqXG4gICAgICogXy5pbnRlcnNlY3Rpb25XaXRoKG9iamVjdHMsIG90aGVycywgXy5pc0VxdWFsKTtcbiAgICAgKiAvLyA9PiBbeyAneCc6IDEsICd5JzogMiB9XVxuICAgICAqL1xuICAgIHZhciBpbnRlcnNlY3Rpb25XaXRoID0gYmFzZVJlc3QoZnVuY3Rpb24oYXJyYXlzKSB7XG4gICAgICB2YXIgY29tcGFyYXRvciA9IGxhc3QoYXJyYXlzKSxcbiAgICAgICAgICBtYXBwZWQgPSBhcnJheU1hcChhcnJheXMsIGNhc3RBcnJheUxpa2VPYmplY3QpO1xuXG4gICAgICBjb21wYXJhdG9yID0gdHlwZW9mIGNvbXBhcmF0b3IgPT0gJ2Z1bmN0aW9uJyA/IGNvbXBhcmF0b3IgOiB1bmRlZmluZWQ7XG4gICAgICBpZiAoY29tcGFyYXRvcikge1xuICAgICAgICBtYXBwZWQucG9wKCk7XG4gICAgICB9XG4gICAgICByZXR1cm4gKG1hcHBlZC5sZW5ndGggJiYgbWFwcGVkWzBdID09PSBhcnJheXNbMF0pXG4gICAgICAgID8gYmFzZUludGVyc2VjdGlvbihtYXBwZWQsIHVuZGVmaW5lZCwgY29tcGFyYXRvcilcbiAgICAgICAgOiBbXTtcbiAgICB9KTtcblxuICAgIC8qKlxuICAgICAqIENvbnZlcnRzIGFsbCBlbGVtZW50cyBpbiBgYXJyYXlgIGludG8gYSBzdHJpbmcgc2VwYXJhdGVkIGJ5IGBzZXBhcmF0b3JgLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMC4wXG4gICAgICogQGNhdGVnb3J5IEFycmF5XG4gICAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIGNvbnZlcnQuXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IFtzZXBhcmF0b3I9JywnXSBUaGUgZWxlbWVudCBzZXBhcmF0b3IuXG4gICAgICogQHJldHVybnMge3N0cmluZ30gUmV0dXJucyB0aGUgam9pbmVkIHN0cmluZy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5qb2luKFsnYScsICdiJywgJ2MnXSwgJ34nKTtcbiAgICAgKiAvLyA9PiAnYX5ifmMnXG4gICAgICovXG4gICAgZnVuY3Rpb24gam9pbihhcnJheSwgc2VwYXJhdG9yKSB7XG4gICAgICByZXR1cm4gYXJyYXkgPT0gbnVsbCA/ICcnIDogbmF0aXZlSm9pbi5jYWxsKGFycmF5LCBzZXBhcmF0b3IpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldHMgdGhlIGxhc3QgZWxlbWVudCBvZiBgYXJyYXlgLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDAuMS4wXG4gICAgICogQGNhdGVnb3J5IEFycmF5XG4gICAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIHF1ZXJ5LlxuICAgICAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSBsYXN0IGVsZW1lbnQgb2YgYGFycmF5YC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5sYXN0KFsxLCAyLCAzXSk7XG4gICAgICogLy8gPT4gM1xuICAgICAqL1xuICAgIGZ1bmN0aW9uIGxhc3QoYXJyYXkpIHtcbiAgICAgIHZhciBsZW5ndGggPSBhcnJheSA9PSBudWxsID8gMCA6IGFycmF5Lmxlbmd0aDtcbiAgICAgIHJldHVybiBsZW5ndGggPyBhcnJheVtsZW5ndGggLSAxXSA6IHVuZGVmaW5lZDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIG1ldGhvZCBpcyBsaWtlIGBfLmluZGV4T2ZgIGV4Y2VwdCB0aGF0IGl0IGl0ZXJhdGVzIG92ZXIgZWxlbWVudHMgb2ZcbiAgICAgKiBgYXJyYXlgIGZyb20gcmlnaHQgdG8gbGVmdC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAwLjEuMFxuICAgICAqIEBjYXRlZ29yeSBBcnJheVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBpbnNwZWN0LlxuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIHNlYXJjaCBmb3IuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtmcm9tSW5kZXg9YXJyYXkubGVuZ3RoLTFdIFRoZSBpbmRleCB0byBzZWFyY2ggZnJvbS5cbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBSZXR1cm5zIHRoZSBpbmRleCBvZiB0aGUgbWF0Y2hlZCB2YWx1ZSwgZWxzZSBgLTFgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLmxhc3RJbmRleE9mKFsxLCAyLCAxLCAyXSwgMik7XG4gICAgICogLy8gPT4gM1xuICAgICAqXG4gICAgICogLy8gU2VhcmNoIGZyb20gdGhlIGBmcm9tSW5kZXhgLlxuICAgICAqIF8ubGFzdEluZGV4T2YoWzEsIDIsIDEsIDJdLCAyLCAyKTtcbiAgICAgKiAvLyA9PiAxXG4gICAgICovXG4gICAgZnVuY3Rpb24gbGFzdEluZGV4T2YoYXJyYXksIHZhbHVlLCBmcm9tSW5kZXgpIHtcbiAgICAgIHZhciBsZW5ndGggPSBhcnJheSA9PSBudWxsID8gMCA6IGFycmF5Lmxlbmd0aDtcbiAgICAgIGlmICghbGVuZ3RoKSB7XG4gICAgICAgIHJldHVybiAtMTtcbiAgICAgIH1cbiAgICAgIHZhciBpbmRleCA9IGxlbmd0aDtcbiAgICAgIGlmIChmcm9tSW5kZXggIT09IHVuZGVmaW5lZCkge1xuICAgICAgICBpbmRleCA9IHRvSW50ZWdlcihmcm9tSW5kZXgpO1xuICAgICAgICBpbmRleCA9IGluZGV4IDwgMCA/IG5hdGl2ZU1heChsZW5ndGggKyBpbmRleCwgMCkgOiBuYXRpdmVNaW4oaW5kZXgsIGxlbmd0aCAtIDEpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHZhbHVlID09PSB2YWx1ZVxuICAgICAgICA/IHN0cmljdExhc3RJbmRleE9mKGFycmF5LCB2YWx1ZSwgaW5kZXgpXG4gICAgICAgIDogYmFzZUZpbmRJbmRleChhcnJheSwgYmFzZUlzTmFOLCBpbmRleCwgdHJ1ZSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0cyB0aGUgZWxlbWVudCBhdCBpbmRleCBgbmAgb2YgYGFycmF5YC4gSWYgYG5gIGlzIG5lZ2F0aXZlLCB0aGUgbnRoXG4gICAgICogZWxlbWVudCBmcm9tIHRoZSBlbmQgaXMgcmV0dXJuZWQuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4xMS4wXG4gICAgICogQGNhdGVnb3J5IEFycmF5XG4gICAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIHF1ZXJ5LlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbbj0wXSBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLlxuICAgICAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSBudGggZWxlbWVudCBvZiBgYXJyYXlgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgYXJyYXkgPSBbJ2EnLCAnYicsICdjJywgJ2QnXTtcbiAgICAgKlxuICAgICAqIF8ubnRoKGFycmF5LCAxKTtcbiAgICAgKiAvLyA9PiAnYidcbiAgICAgKlxuICAgICAqIF8ubnRoKGFycmF5LCAtMik7XG4gICAgICogLy8gPT4gJ2MnO1xuICAgICAqL1xuICAgIGZ1bmN0aW9uIG50aChhcnJheSwgbikge1xuICAgICAgcmV0dXJuIChhcnJheSAmJiBhcnJheS5sZW5ndGgpID8gYmFzZU50aChhcnJheSwgdG9JbnRlZ2VyKG4pKSA6IHVuZGVmaW5lZDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZW1vdmVzIGFsbCBnaXZlbiB2YWx1ZXMgZnJvbSBgYXJyYXlgIHVzaW5nXG4gICAgICogW2BTYW1lVmFsdWVaZXJvYF0oaHR0cDovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNy4wLyNzZWMtc2FtZXZhbHVlemVybylcbiAgICAgKiBmb3IgZXF1YWxpdHkgY29tcGFyaXNvbnMuXG4gICAgICpcbiAgICAgKiAqKk5vdGU6KiogVW5saWtlIGBfLndpdGhvdXRgLCB0aGlzIG1ldGhvZCBtdXRhdGVzIGBhcnJheWAuIFVzZSBgXy5yZW1vdmVgXG4gICAgICogdG8gcmVtb3ZlIGVsZW1lbnRzIGZyb20gYW4gYXJyYXkgYnkgcHJlZGljYXRlLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDIuMC4wXG4gICAgICogQGNhdGVnb3J5IEFycmF5XG4gICAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIG1vZGlmeS5cbiAgICAgKiBAcGFyYW0gey4uLip9IFt2YWx1ZXNdIFRoZSB2YWx1ZXMgdG8gcmVtb3ZlLlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyBgYXJyYXlgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgYXJyYXkgPSBbJ2EnLCAnYicsICdjJywgJ2EnLCAnYicsICdjJ107XG4gICAgICpcbiAgICAgKiBfLnB1bGwoYXJyYXksICdhJywgJ2MnKTtcbiAgICAgKiBjb25zb2xlLmxvZyhhcnJheSk7XG4gICAgICogLy8gPT4gWydiJywgJ2InXVxuICAgICAqL1xuICAgIHZhciBwdWxsID0gYmFzZVJlc3QocHVsbEFsbCk7XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIG1ldGhvZCBpcyBsaWtlIGBfLnB1bGxgIGV4Y2VwdCB0aGF0IGl0IGFjY2VwdHMgYW4gYXJyYXkgb2YgdmFsdWVzIHRvIHJlbW92ZS5cbiAgICAgKlxuICAgICAqICoqTm90ZToqKiBVbmxpa2UgYF8uZGlmZmVyZW5jZWAsIHRoaXMgbWV0aG9kIG11dGF0ZXMgYGFycmF5YC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjAuMFxuICAgICAqIEBjYXRlZ29yeSBBcnJheVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBtb2RpZnkuXG4gICAgICogQHBhcmFtIHtBcnJheX0gdmFsdWVzIFRoZSB2YWx1ZXMgdG8gcmVtb3ZlLlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyBgYXJyYXlgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgYXJyYXkgPSBbJ2EnLCAnYicsICdjJywgJ2EnLCAnYicsICdjJ107XG4gICAgICpcbiAgICAgKiBfLnB1bGxBbGwoYXJyYXksIFsnYScsICdjJ10pO1xuICAgICAqIGNvbnNvbGUubG9nKGFycmF5KTtcbiAgICAgKiAvLyA9PiBbJ2InLCAnYiddXG4gICAgICovXG4gICAgZnVuY3Rpb24gcHVsbEFsbChhcnJheSwgdmFsdWVzKSB7XG4gICAgICByZXR1cm4gKGFycmF5ICYmIGFycmF5Lmxlbmd0aCAmJiB2YWx1ZXMgJiYgdmFsdWVzLmxlbmd0aClcbiAgICAgICAgPyBiYXNlUHVsbEFsbChhcnJheSwgdmFsdWVzKVxuICAgICAgICA6IGFycmF5O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIGlzIGxpa2UgYF8ucHVsbEFsbGAgZXhjZXB0IHRoYXQgaXQgYWNjZXB0cyBgaXRlcmF0ZWVgIHdoaWNoIGlzXG4gICAgICogaW52b2tlZCBmb3IgZWFjaCBlbGVtZW50IG9mIGBhcnJheWAgYW5kIGB2YWx1ZXNgIHRvIGdlbmVyYXRlIHRoZSBjcml0ZXJpb25cbiAgICAgKiBieSB3aGljaCB0aGV5J3JlIGNvbXBhcmVkLiBUaGUgaXRlcmF0ZWUgaXMgaW52b2tlZCB3aXRoIG9uZSBhcmd1bWVudDogKHZhbHVlKS5cbiAgICAgKlxuICAgICAqICoqTm90ZToqKiBVbmxpa2UgYF8uZGlmZmVyZW5jZUJ5YCwgdGhpcyBtZXRob2QgbXV0YXRlcyBgYXJyYXlgLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMC4wXG4gICAgICogQGNhdGVnb3J5IEFycmF5XG4gICAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIG1vZGlmeS5cbiAgICAgKiBAcGFyYW0ge0FycmF5fSB2YWx1ZXMgVGhlIHZhbHVlcyB0byByZW1vdmUuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW2l0ZXJhdGVlPV8uaWRlbnRpdHldIFRoZSBpdGVyYXRlZSBpbnZva2VkIHBlciBlbGVtZW50LlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyBgYXJyYXlgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgYXJyYXkgPSBbeyAneCc6IDEgfSwgeyAneCc6IDIgfSwgeyAneCc6IDMgfSwgeyAneCc6IDEgfV07XG4gICAgICpcbiAgICAgKiBfLnB1bGxBbGxCeShhcnJheSwgW3sgJ3gnOiAxIH0sIHsgJ3gnOiAzIH1dLCAneCcpO1xuICAgICAqIGNvbnNvbGUubG9nKGFycmF5KTtcbiAgICAgKiAvLyA9PiBbeyAneCc6IDIgfV1cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBwdWxsQWxsQnkoYXJyYXksIHZhbHVlcywgaXRlcmF0ZWUpIHtcbiAgICAgIHJldHVybiAoYXJyYXkgJiYgYXJyYXkubGVuZ3RoICYmIHZhbHVlcyAmJiB2YWx1ZXMubGVuZ3RoKVxuICAgICAgICA/IGJhc2VQdWxsQWxsKGFycmF5LCB2YWx1ZXMsIGdldEl0ZXJhdGVlKGl0ZXJhdGVlLCAyKSlcbiAgICAgICAgOiBhcnJheTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIG1ldGhvZCBpcyBsaWtlIGBfLnB1bGxBbGxgIGV4Y2VwdCB0aGF0IGl0IGFjY2VwdHMgYGNvbXBhcmF0b3JgIHdoaWNoXG4gICAgICogaXMgaW52b2tlZCB0byBjb21wYXJlIGVsZW1lbnRzIG9mIGBhcnJheWAgdG8gYHZhbHVlc2AuIFRoZSBjb21wYXJhdG9yIGlzXG4gICAgICogaW52b2tlZCB3aXRoIHR3byBhcmd1bWVudHM6IChhcnJWYWwsIG90aFZhbCkuXG4gICAgICpcbiAgICAgKiAqKk5vdGU6KiogVW5saWtlIGBfLmRpZmZlcmVuY2VXaXRoYCwgdGhpcyBtZXRob2QgbXV0YXRlcyBgYXJyYXlgLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuNi4wXG4gICAgICogQGNhdGVnb3J5IEFycmF5XG4gICAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIG1vZGlmeS5cbiAgICAgKiBAcGFyYW0ge0FycmF5fSB2YWx1ZXMgVGhlIHZhbHVlcyB0byByZW1vdmUuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW2NvbXBhcmF0b3JdIFRoZSBjb21wYXJhdG9yIGludm9rZWQgcGVyIGVsZW1lbnQuXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIGBhcnJheWAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciBhcnJheSA9IFt7ICd4JzogMSwgJ3knOiAyIH0sIHsgJ3gnOiAzLCAneSc6IDQgfSwgeyAneCc6IDUsICd5JzogNiB9XTtcbiAgICAgKlxuICAgICAqIF8ucHVsbEFsbFdpdGgoYXJyYXksIFt7ICd4JzogMywgJ3knOiA0IH1dLCBfLmlzRXF1YWwpO1xuICAgICAqIGNvbnNvbGUubG9nKGFycmF5KTtcbiAgICAgKiAvLyA9PiBbeyAneCc6IDEsICd5JzogMiB9LCB7ICd4JzogNSwgJ3knOiA2IH1dXG4gICAgICovXG4gICAgZnVuY3Rpb24gcHVsbEFsbFdpdGgoYXJyYXksIHZhbHVlcywgY29tcGFyYXRvcikge1xuICAgICAgcmV0dXJuIChhcnJheSAmJiBhcnJheS5sZW5ndGggJiYgdmFsdWVzICYmIHZhbHVlcy5sZW5ndGgpXG4gICAgICAgID8gYmFzZVB1bGxBbGwoYXJyYXksIHZhbHVlcywgdW5kZWZpbmVkLCBjb21wYXJhdG9yKVxuICAgICAgICA6IGFycmF5O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJlbW92ZXMgZWxlbWVudHMgZnJvbSBgYXJyYXlgIGNvcnJlc3BvbmRpbmcgdG8gYGluZGV4ZXNgIGFuZCByZXR1cm5zIGFuXG4gICAgICogYXJyYXkgb2YgcmVtb3ZlZCBlbGVtZW50cy5cbiAgICAgKlxuICAgICAqICoqTm90ZToqKiBVbmxpa2UgYF8uYXRgLCB0aGlzIG1ldGhvZCBtdXRhdGVzIGBhcnJheWAuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMy4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgQXJyYXlcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gbW9kaWZ5LlxuICAgICAqIEBwYXJhbSB7Li4uKG51bWJlcnxudW1iZXJbXSl9IFtpbmRleGVzXSBUaGUgaW5kZXhlcyBvZiBlbGVtZW50cyB0byByZW1vdmUuXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBuZXcgYXJyYXkgb2YgcmVtb3ZlZCBlbGVtZW50cy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIGFycmF5ID0gWydhJywgJ2InLCAnYycsICdkJ107XG4gICAgICogdmFyIHB1bGxlZCA9IF8ucHVsbEF0KGFycmF5LCBbMSwgM10pO1xuICAgICAqXG4gICAgICogY29uc29sZS5sb2coYXJyYXkpO1xuICAgICAqIC8vID0+IFsnYScsICdjJ11cbiAgICAgKlxuICAgICAqIGNvbnNvbGUubG9nKHB1bGxlZCk7XG4gICAgICogLy8gPT4gWydiJywgJ2QnXVxuICAgICAqL1xuICAgIHZhciBwdWxsQXQgPSBmbGF0UmVzdChmdW5jdGlvbihhcnJheSwgaW5kZXhlcykge1xuICAgICAgdmFyIGxlbmd0aCA9IGFycmF5ID09IG51bGwgPyAwIDogYXJyYXkubGVuZ3RoLFxuICAgICAgICAgIHJlc3VsdCA9IGJhc2VBdChhcnJheSwgaW5kZXhlcyk7XG5cbiAgICAgIGJhc2VQdWxsQXQoYXJyYXksIGFycmF5TWFwKGluZGV4ZXMsIGZ1bmN0aW9uKGluZGV4KSB7XG4gICAgICAgIHJldHVybiBpc0luZGV4KGluZGV4LCBsZW5ndGgpID8gK2luZGV4IDogaW5kZXg7XG4gICAgICB9KS5zb3J0KGNvbXBhcmVBc2NlbmRpbmcpKTtcblxuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9KTtcblxuICAgIC8qKlxuICAgICAqIFJlbW92ZXMgYWxsIGVsZW1lbnRzIGZyb20gYGFycmF5YCB0aGF0IGBwcmVkaWNhdGVgIHJldHVybnMgdHJ1dGh5IGZvclxuICAgICAqIGFuZCByZXR1cm5zIGFuIGFycmF5IG9mIHRoZSByZW1vdmVkIGVsZW1lbnRzLiBUaGUgcHJlZGljYXRlIGlzIGludm9rZWRcbiAgICAgKiB3aXRoIHRocmVlIGFyZ3VtZW50czogKHZhbHVlLCBpbmRleCwgYXJyYXkpLlxuICAgICAqXG4gICAgICogKipOb3RlOioqIFVubGlrZSBgXy5maWx0ZXJgLCB0aGlzIG1ldGhvZCBtdXRhdGVzIGBhcnJheWAuIFVzZSBgXy5wdWxsYFxuICAgICAqIHRvIHB1bGwgZWxlbWVudHMgZnJvbSBhbiBhcnJheSBieSB2YWx1ZS5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAyLjAuMFxuICAgICAqIEBjYXRlZ29yeSBBcnJheVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBtb2RpZnkuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW3ByZWRpY2F0ZT1fLmlkZW50aXR5XSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IGFycmF5IG9mIHJlbW92ZWQgZWxlbWVudHMuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciBhcnJheSA9IFsxLCAyLCAzLCA0XTtcbiAgICAgKiB2YXIgZXZlbnMgPSBfLnJlbW92ZShhcnJheSwgZnVuY3Rpb24obikge1xuICAgICAqICAgcmV0dXJuIG4gJSAyID09IDA7XG4gICAgICogfSk7XG4gICAgICpcbiAgICAgKiBjb25zb2xlLmxvZyhhcnJheSk7XG4gICAgICogLy8gPT4gWzEsIDNdXG4gICAgICpcbiAgICAgKiBjb25zb2xlLmxvZyhldmVucyk7XG4gICAgICogLy8gPT4gWzIsIDRdXG4gICAgICovXG4gICAgZnVuY3Rpb24gcmVtb3ZlKGFycmF5LCBwcmVkaWNhdGUpIHtcbiAgICAgIHZhciByZXN1bHQgPSBbXTtcbiAgICAgIGlmICghKGFycmF5ICYmIGFycmF5Lmxlbmd0aCkpIHtcbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgIH1cbiAgICAgIHZhciBpbmRleCA9IC0xLFxuICAgICAgICAgIGluZGV4ZXMgPSBbXSxcbiAgICAgICAgICBsZW5ndGggPSBhcnJheS5sZW5ndGg7XG5cbiAgICAgIHByZWRpY2F0ZSA9IGdldEl0ZXJhdGVlKHByZWRpY2F0ZSwgMyk7XG4gICAgICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgICAgICB2YXIgdmFsdWUgPSBhcnJheVtpbmRleF07XG4gICAgICAgIGlmIChwcmVkaWNhdGUodmFsdWUsIGluZGV4LCBhcnJheSkpIHtcbiAgICAgICAgICByZXN1bHQucHVzaCh2YWx1ZSk7XG4gICAgICAgICAgaW5kZXhlcy5wdXNoKGluZGV4KTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgYmFzZVB1bGxBdChhcnJheSwgaW5kZXhlcyk7XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJldmVyc2VzIGBhcnJheWAgc28gdGhhdCB0aGUgZmlyc3QgZWxlbWVudCBiZWNvbWVzIHRoZSBsYXN0LCB0aGUgc2Vjb25kXG4gICAgICogZWxlbWVudCBiZWNvbWVzIHRoZSBzZWNvbmQgdG8gbGFzdCwgYW5kIHNvIG9uLlxuICAgICAqXG4gICAgICogKipOb3RlOioqIFRoaXMgbWV0aG9kIG11dGF0ZXMgYGFycmF5YCBhbmQgaXMgYmFzZWQgb25cbiAgICAgKiBbYEFycmF5I3JldmVyc2VgXShodHRwczovL21kbi5pby9BcnJheS9yZXZlcnNlKS5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjAuMFxuICAgICAqIEBjYXRlZ29yeSBBcnJheVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBtb2RpZnkuXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIGBhcnJheWAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciBhcnJheSA9IFsxLCAyLCAzXTtcbiAgICAgKlxuICAgICAqIF8ucmV2ZXJzZShhcnJheSk7XG4gICAgICogLy8gPT4gWzMsIDIsIDFdXG4gICAgICpcbiAgICAgKiBjb25zb2xlLmxvZyhhcnJheSk7XG4gICAgICogLy8gPT4gWzMsIDIsIDFdXG4gICAgICovXG4gICAgZnVuY3Rpb24gcmV2ZXJzZShhcnJheSkge1xuICAgICAgcmV0dXJuIGFycmF5ID09IG51bGwgPyBhcnJheSA6IG5hdGl2ZVJldmVyc2UuY2FsbChhcnJheSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIHNsaWNlIG9mIGBhcnJheWAgZnJvbSBgc3RhcnRgIHVwIHRvLCBidXQgbm90IGluY2x1ZGluZywgYGVuZGAuXG4gICAgICpcbiAgICAgKiAqKk5vdGU6KiogVGhpcyBtZXRob2QgaXMgdXNlZCBpbnN0ZWFkIG9mXG4gICAgICogW2BBcnJheSNzbGljZWBdKGh0dHBzOi8vbWRuLmlvL0FycmF5L3NsaWNlKSB0byBlbnN1cmUgZGVuc2UgYXJyYXlzIGFyZVxuICAgICAqIHJldHVybmVkLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDMuMC4wXG4gICAgICogQGNhdGVnb3J5IEFycmF5XG4gICAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIHNsaWNlLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbc3RhcnQ9MF0gVGhlIHN0YXJ0IHBvc2l0aW9uLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbZW5kPWFycmF5Lmxlbmd0aF0gVGhlIGVuZCBwb3NpdGlvbi5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIHNsaWNlIG9mIGBhcnJheWAuXG4gICAgICovXG4gICAgZnVuY3Rpb24gc2xpY2UoYXJyYXksIHN0YXJ0LCBlbmQpIHtcbiAgICAgIHZhciBsZW5ndGggPSBhcnJheSA9PSBudWxsID8gMCA6IGFycmF5Lmxlbmd0aDtcbiAgICAgIGlmICghbGVuZ3RoKSB7XG4gICAgICAgIHJldHVybiBbXTtcbiAgICAgIH1cbiAgICAgIGlmIChlbmQgJiYgdHlwZW9mIGVuZCAhPSAnbnVtYmVyJyAmJiBpc0l0ZXJhdGVlQ2FsbChhcnJheSwgc3RhcnQsIGVuZCkpIHtcbiAgICAgICAgc3RhcnQgPSAwO1xuICAgICAgICBlbmQgPSBsZW5ndGg7XG4gICAgICB9XG4gICAgICBlbHNlIHtcbiAgICAgICAgc3RhcnQgPSBzdGFydCA9PSBudWxsID8gMCA6IHRvSW50ZWdlcihzdGFydCk7XG4gICAgICAgIGVuZCA9IGVuZCA9PT0gdW5kZWZpbmVkID8gbGVuZ3RoIDogdG9JbnRlZ2VyKGVuZCk7XG4gICAgICB9XG4gICAgICByZXR1cm4gYmFzZVNsaWNlKGFycmF5LCBzdGFydCwgZW5kKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBVc2VzIGEgYmluYXJ5IHNlYXJjaCB0byBkZXRlcm1pbmUgdGhlIGxvd2VzdCBpbmRleCBhdCB3aGljaCBgdmFsdWVgXG4gICAgICogc2hvdWxkIGJlIGluc2VydGVkIGludG8gYGFycmF5YCBpbiBvcmRlciB0byBtYWludGFpbiBpdHMgc29ydCBvcmRlci5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAwLjEuMFxuICAgICAqIEBjYXRlZ29yeSBBcnJheVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBzb3J0ZWQgYXJyYXkgdG8gaW5zcGVjdC5cbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBldmFsdWF0ZS5cbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBSZXR1cm5zIHRoZSBpbmRleCBhdCB3aGljaCBgdmFsdWVgIHNob3VsZCBiZSBpbnNlcnRlZFxuICAgICAqICBpbnRvIGBhcnJheWAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uc29ydGVkSW5kZXgoWzMwLCA1MF0sIDQwKTtcbiAgICAgKiAvLyA9PiAxXG4gICAgICovXG4gICAgZnVuY3Rpb24gc29ydGVkSW5kZXgoYXJyYXksIHZhbHVlKSB7XG4gICAgICByZXR1cm4gYmFzZVNvcnRlZEluZGV4KGFycmF5LCB2YWx1ZSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgaXMgbGlrZSBgXy5zb3J0ZWRJbmRleGAgZXhjZXB0IHRoYXQgaXQgYWNjZXB0cyBgaXRlcmF0ZWVgXG4gICAgICogd2hpY2ggaXMgaW52b2tlZCBmb3IgYHZhbHVlYCBhbmQgZWFjaCBlbGVtZW50IG9mIGBhcnJheWAgdG8gY29tcHV0ZSB0aGVpclxuICAgICAqIHNvcnQgcmFua2luZy4gVGhlIGl0ZXJhdGVlIGlzIGludm9rZWQgd2l0aCBvbmUgYXJndW1lbnQ6ICh2YWx1ZSkuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgQXJyYXlcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgc29ydGVkIGFycmF5IHRvIGluc3BlY3QuXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gZXZhbHVhdGUuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW2l0ZXJhdGVlPV8uaWRlbnRpdHldIFRoZSBpdGVyYXRlZSBpbnZva2VkIHBlciBlbGVtZW50LlxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9IFJldHVybnMgdGhlIGluZGV4IGF0IHdoaWNoIGB2YWx1ZWAgc2hvdWxkIGJlIGluc2VydGVkXG4gICAgICogIGludG8gYGFycmF5YC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIG9iamVjdHMgPSBbeyAneCc6IDQgfSwgeyAneCc6IDUgfV07XG4gICAgICpcbiAgICAgKiBfLnNvcnRlZEluZGV4Qnkob2JqZWN0cywgeyAneCc6IDQgfSwgZnVuY3Rpb24obykgeyByZXR1cm4gby54OyB9KTtcbiAgICAgKiAvLyA9PiAwXG4gICAgICpcbiAgICAgKiAvLyBUaGUgYF8ucHJvcGVydHlgIGl0ZXJhdGVlIHNob3J0aGFuZC5cbiAgICAgKiBfLnNvcnRlZEluZGV4Qnkob2JqZWN0cywgeyAneCc6IDQgfSwgJ3gnKTtcbiAgICAgKiAvLyA9PiAwXG4gICAgICovXG4gICAgZnVuY3Rpb24gc29ydGVkSW5kZXhCeShhcnJheSwgdmFsdWUsIGl0ZXJhdGVlKSB7XG4gICAgICByZXR1cm4gYmFzZVNvcnRlZEluZGV4QnkoYXJyYXksIHZhbHVlLCBnZXRJdGVyYXRlZShpdGVyYXRlZSwgMikpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIGlzIGxpa2UgYF8uaW5kZXhPZmAgZXhjZXB0IHRoYXQgaXQgcGVyZm9ybXMgYSBiaW5hcnlcbiAgICAgKiBzZWFyY2ggb24gYSBzb3J0ZWQgYGFycmF5YC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjAuMFxuICAgICAqIEBjYXRlZ29yeSBBcnJheVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBpbnNwZWN0LlxuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIHNlYXJjaCBmb3IuXG4gICAgICogQHJldHVybnMge251bWJlcn0gUmV0dXJucyB0aGUgaW5kZXggb2YgdGhlIG1hdGNoZWQgdmFsdWUsIGVsc2UgYC0xYC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5zb3J0ZWRJbmRleE9mKFs0LCA1LCA1LCA1LCA2XSwgNSk7XG4gICAgICogLy8gPT4gMVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIHNvcnRlZEluZGV4T2YoYXJyYXksIHZhbHVlKSB7XG4gICAgICB2YXIgbGVuZ3RoID0gYXJyYXkgPT0gbnVsbCA/IDAgOiBhcnJheS5sZW5ndGg7XG4gICAgICBpZiAobGVuZ3RoKSB7XG4gICAgICAgIHZhciBpbmRleCA9IGJhc2VTb3J0ZWRJbmRleChhcnJheSwgdmFsdWUpO1xuICAgICAgICBpZiAoaW5kZXggPCBsZW5ndGggJiYgZXEoYXJyYXlbaW5kZXhdLCB2YWx1ZSkpIHtcbiAgICAgICAgICByZXR1cm4gaW5kZXg7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiAtMTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIG1ldGhvZCBpcyBsaWtlIGBfLnNvcnRlZEluZGV4YCBleGNlcHQgdGhhdCBpdCByZXR1cm5zIHRoZSBoaWdoZXN0XG4gICAgICogaW5kZXggYXQgd2hpY2ggYHZhbHVlYCBzaG91bGQgYmUgaW5zZXJ0ZWQgaW50byBgYXJyYXlgIGluIG9yZGVyIHRvXG4gICAgICogbWFpbnRhaW4gaXRzIHNvcnQgb3JkZXIuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMy4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgQXJyYXlcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgc29ydGVkIGFycmF5IHRvIGluc3BlY3QuXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gZXZhbHVhdGUuXG4gICAgICogQHJldHVybnMge251bWJlcn0gUmV0dXJucyB0aGUgaW5kZXggYXQgd2hpY2ggYHZhbHVlYCBzaG91bGQgYmUgaW5zZXJ0ZWRcbiAgICAgKiAgaW50byBgYXJyYXlgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLnNvcnRlZExhc3RJbmRleChbNCwgNSwgNSwgNSwgNl0sIDUpO1xuICAgICAqIC8vID0+IDRcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBzb3J0ZWRMYXN0SW5kZXgoYXJyYXksIHZhbHVlKSB7XG4gICAgICByZXR1cm4gYmFzZVNvcnRlZEluZGV4KGFycmF5LCB2YWx1ZSwgdHJ1ZSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgaXMgbGlrZSBgXy5zb3J0ZWRMYXN0SW5kZXhgIGV4Y2VwdCB0aGF0IGl0IGFjY2VwdHMgYGl0ZXJhdGVlYFxuICAgICAqIHdoaWNoIGlzIGludm9rZWQgZm9yIGB2YWx1ZWAgYW5kIGVhY2ggZWxlbWVudCBvZiBgYXJyYXlgIHRvIGNvbXB1dGUgdGhlaXJcbiAgICAgKiBzb3J0IHJhbmtpbmcuIFRoZSBpdGVyYXRlZSBpcyBpbnZva2VkIHdpdGggb25lIGFyZ3VtZW50OiAodmFsdWUpLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMC4wXG4gICAgICogQGNhdGVnb3J5IEFycmF5XG4gICAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIHNvcnRlZCBhcnJheSB0byBpbnNwZWN0LlxuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGV2YWx1YXRlLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IFtpdGVyYXRlZT1fLmlkZW50aXR5XSBUaGUgaXRlcmF0ZWUgaW52b2tlZCBwZXIgZWxlbWVudC5cbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBSZXR1cm5zIHRoZSBpbmRleCBhdCB3aGljaCBgdmFsdWVgIHNob3VsZCBiZSBpbnNlcnRlZFxuICAgICAqICBpbnRvIGBhcnJheWAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciBvYmplY3RzID0gW3sgJ3gnOiA0IH0sIHsgJ3gnOiA1IH1dO1xuICAgICAqXG4gICAgICogXy5zb3J0ZWRMYXN0SW5kZXhCeShvYmplY3RzLCB7ICd4JzogNCB9LCBmdW5jdGlvbihvKSB7IHJldHVybiBvLng7IH0pO1xuICAgICAqIC8vID0+IDFcbiAgICAgKlxuICAgICAqIC8vIFRoZSBgXy5wcm9wZXJ0eWAgaXRlcmF0ZWUgc2hvcnRoYW5kLlxuICAgICAqIF8uc29ydGVkTGFzdEluZGV4Qnkob2JqZWN0cywgeyAneCc6IDQgfSwgJ3gnKTtcbiAgICAgKiAvLyA9PiAxXG4gICAgICovXG4gICAgZnVuY3Rpb24gc29ydGVkTGFzdEluZGV4QnkoYXJyYXksIHZhbHVlLCBpdGVyYXRlZSkge1xuICAgICAgcmV0dXJuIGJhc2VTb3J0ZWRJbmRleEJ5KGFycmF5LCB2YWx1ZSwgZ2V0SXRlcmF0ZWUoaXRlcmF0ZWUsIDIpLCB0cnVlKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIG1ldGhvZCBpcyBsaWtlIGBfLmxhc3RJbmRleE9mYCBleGNlcHQgdGhhdCBpdCBwZXJmb3JtcyBhIGJpbmFyeVxuICAgICAqIHNlYXJjaCBvbiBhIHNvcnRlZCBgYXJyYXlgLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMC4wXG4gICAgICogQGNhdGVnb3J5IEFycmF5XG4gICAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIGluc3BlY3QuXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gc2VhcmNoIGZvci5cbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBSZXR1cm5zIHRoZSBpbmRleCBvZiB0aGUgbWF0Y2hlZCB2YWx1ZSwgZWxzZSBgLTFgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLnNvcnRlZExhc3RJbmRleE9mKFs0LCA1LCA1LCA1LCA2XSwgNSk7XG4gICAgICogLy8gPT4gM1xuICAgICAqL1xuICAgIGZ1bmN0aW9uIHNvcnRlZExhc3RJbmRleE9mKGFycmF5LCB2YWx1ZSkge1xuICAgICAgdmFyIGxlbmd0aCA9IGFycmF5ID09IG51bGwgPyAwIDogYXJyYXkubGVuZ3RoO1xuICAgICAgaWYgKGxlbmd0aCkge1xuICAgICAgICB2YXIgaW5kZXggPSBiYXNlU29ydGVkSW5kZXgoYXJyYXksIHZhbHVlLCB0cnVlKSAtIDE7XG4gICAgICAgIGlmIChlcShhcnJheVtpbmRleF0sIHZhbHVlKSkge1xuICAgICAgICAgIHJldHVybiBpbmRleDtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIC0xO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIGlzIGxpa2UgYF8udW5pcWAgZXhjZXB0IHRoYXQgaXQncyBkZXNpZ25lZCBhbmQgb3B0aW1pemVkXG4gICAgICogZm9yIHNvcnRlZCBhcnJheXMuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgQXJyYXlcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gaW5zcGVjdC5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIG5ldyBkdXBsaWNhdGUgZnJlZSBhcnJheS5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5zb3J0ZWRVbmlxKFsxLCAxLCAyXSk7XG4gICAgICogLy8gPT4gWzEsIDJdXG4gICAgICovXG4gICAgZnVuY3Rpb24gc29ydGVkVW5pcShhcnJheSkge1xuICAgICAgcmV0dXJuIChhcnJheSAmJiBhcnJheS5sZW5ndGgpXG4gICAgICAgID8gYmFzZVNvcnRlZFVuaXEoYXJyYXkpXG4gICAgICAgIDogW107XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgaXMgbGlrZSBgXy51bmlxQnlgIGV4Y2VwdCB0aGF0IGl0J3MgZGVzaWduZWQgYW5kIG9wdGltaXplZFxuICAgICAqIGZvciBzb3J0ZWQgYXJyYXlzLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMC4wXG4gICAgICogQGNhdGVnb3J5IEFycmF5XG4gICAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIGluc3BlY3QuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW2l0ZXJhdGVlXSBUaGUgaXRlcmF0ZWUgaW52b2tlZCBwZXIgZWxlbWVudC5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIG5ldyBkdXBsaWNhdGUgZnJlZSBhcnJheS5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5zb3J0ZWRVbmlxQnkoWzEuMSwgMS4yLCAyLjMsIDIuNF0sIE1hdGguZmxvb3IpO1xuICAgICAqIC8vID0+IFsxLjEsIDIuM11cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBzb3J0ZWRVbmlxQnkoYXJyYXksIGl0ZXJhdGVlKSB7XG4gICAgICByZXR1cm4gKGFycmF5ICYmIGFycmF5Lmxlbmd0aClcbiAgICAgICAgPyBiYXNlU29ydGVkVW5pcShhcnJheSwgZ2V0SXRlcmF0ZWUoaXRlcmF0ZWUsIDIpKVxuICAgICAgICA6IFtdO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldHMgYWxsIGJ1dCB0aGUgZmlyc3QgZWxlbWVudCBvZiBgYXJyYXlgLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMC4wXG4gICAgICogQGNhdGVnb3J5IEFycmF5XG4gICAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIHF1ZXJ5LlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgc2xpY2Ugb2YgYGFycmF5YC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy50YWlsKFsxLCAyLCAzXSk7XG4gICAgICogLy8gPT4gWzIsIDNdXG4gICAgICovXG4gICAgZnVuY3Rpb24gdGFpbChhcnJheSkge1xuICAgICAgdmFyIGxlbmd0aCA9IGFycmF5ID09IG51bGwgPyAwIDogYXJyYXkubGVuZ3RoO1xuICAgICAgcmV0dXJuIGxlbmd0aCA/IGJhc2VTbGljZShhcnJheSwgMSwgbGVuZ3RoKSA6IFtdO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBzbGljZSBvZiBgYXJyYXlgIHdpdGggYG5gIGVsZW1lbnRzIHRha2VuIGZyb20gdGhlIGJlZ2lubmluZy5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAwLjEuMFxuICAgICAqIEBjYXRlZ29yeSBBcnJheVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBxdWVyeS5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW249MV0gVGhlIG51bWJlciBvZiBlbGVtZW50cyB0byB0YWtlLlxuICAgICAqIEBwYXJhbS0ge09iamVjdH0gW2d1YXJkXSBFbmFibGVzIHVzZSBhcyBhbiBpdGVyYXRlZSBmb3IgbWV0aG9kcyBsaWtlIGBfLm1hcGAuXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBzbGljZSBvZiBgYXJyYXlgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLnRha2UoWzEsIDIsIDNdKTtcbiAgICAgKiAvLyA9PiBbMV1cbiAgICAgKlxuICAgICAqIF8udGFrZShbMSwgMiwgM10sIDIpO1xuICAgICAqIC8vID0+IFsxLCAyXVxuICAgICAqXG4gICAgICogXy50YWtlKFsxLCAyLCAzXSwgNSk7XG4gICAgICogLy8gPT4gWzEsIDIsIDNdXG4gICAgICpcbiAgICAgKiBfLnRha2UoWzEsIDIsIDNdLCAwKTtcbiAgICAgKiAvLyA9PiBbXVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIHRha2UoYXJyYXksIG4sIGd1YXJkKSB7XG4gICAgICBpZiAoIShhcnJheSAmJiBhcnJheS5sZW5ndGgpKSB7XG4gICAgICAgIHJldHVybiBbXTtcbiAgICAgIH1cbiAgICAgIG4gPSAoZ3VhcmQgfHwgbiA9PT0gdW5kZWZpbmVkKSA/IDEgOiB0b0ludGVnZXIobik7XG4gICAgICByZXR1cm4gYmFzZVNsaWNlKGFycmF5LCAwLCBuIDwgMCA/IDAgOiBuKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgc2xpY2Ugb2YgYGFycmF5YCB3aXRoIGBuYCBlbGVtZW50cyB0YWtlbiBmcm9tIHRoZSBlbmQuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMy4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgQXJyYXlcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gcXVlcnkuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtuPTFdIFRoZSBudW1iZXIgb2YgZWxlbWVudHMgdG8gdGFrZS5cbiAgICAgKiBAcGFyYW0tIHtPYmplY3R9IFtndWFyZF0gRW5hYmxlcyB1c2UgYXMgYW4gaXRlcmF0ZWUgZm9yIG1ldGhvZHMgbGlrZSBgXy5tYXBgLlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgc2xpY2Ugb2YgYGFycmF5YC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy50YWtlUmlnaHQoWzEsIDIsIDNdKTtcbiAgICAgKiAvLyA9PiBbM11cbiAgICAgKlxuICAgICAqIF8udGFrZVJpZ2h0KFsxLCAyLCAzXSwgMik7XG4gICAgICogLy8gPT4gWzIsIDNdXG4gICAgICpcbiAgICAgKiBfLnRha2VSaWdodChbMSwgMiwgM10sIDUpO1xuICAgICAqIC8vID0+IFsxLCAyLCAzXVxuICAgICAqXG4gICAgICogXy50YWtlUmlnaHQoWzEsIDIsIDNdLCAwKTtcbiAgICAgKiAvLyA9PiBbXVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIHRha2VSaWdodChhcnJheSwgbiwgZ3VhcmQpIHtcbiAgICAgIHZhciBsZW5ndGggPSBhcnJheSA9PSBudWxsID8gMCA6IGFycmF5Lmxlbmd0aDtcbiAgICAgIGlmICghbGVuZ3RoKSB7XG4gICAgICAgIHJldHVybiBbXTtcbiAgICAgIH1cbiAgICAgIG4gPSAoZ3VhcmQgfHwgbiA9PT0gdW5kZWZpbmVkKSA/IDEgOiB0b0ludGVnZXIobik7XG4gICAgICBuID0gbGVuZ3RoIC0gbjtcbiAgICAgIHJldHVybiBiYXNlU2xpY2UoYXJyYXksIG4gPCAwID8gMCA6IG4sIGxlbmd0aCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIHNsaWNlIG9mIGBhcnJheWAgd2l0aCBlbGVtZW50cyB0YWtlbiBmcm9tIHRoZSBlbmQuIEVsZW1lbnRzIGFyZVxuICAgICAqIHRha2VuIHVudGlsIGBwcmVkaWNhdGVgIHJldHVybnMgZmFsc2V5LiBUaGUgcHJlZGljYXRlIGlzIGludm9rZWQgd2l0aFxuICAgICAqIHRocmVlIGFyZ3VtZW50czogKHZhbHVlLCBpbmRleCwgYXJyYXkpLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDMuMC4wXG4gICAgICogQGNhdGVnb3J5IEFycmF5XG4gICAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIHF1ZXJ5LlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IFtwcmVkaWNhdGU9Xy5pZGVudGl0eV0gVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIGl0ZXJhdGlvbi5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIHNsaWNlIG9mIGBhcnJheWAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciB1c2VycyA9IFtcbiAgICAgKiAgIHsgJ3VzZXInOiAnYmFybmV5JywgICdhY3RpdmUnOiB0cnVlIH0sXG4gICAgICogICB7ICd1c2VyJzogJ2ZyZWQnLCAgICAnYWN0aXZlJzogZmFsc2UgfSxcbiAgICAgKiAgIHsgJ3VzZXInOiAncGViYmxlcycsICdhY3RpdmUnOiBmYWxzZSB9XG4gICAgICogXTtcbiAgICAgKlxuICAgICAqIF8udGFrZVJpZ2h0V2hpbGUodXNlcnMsIGZ1bmN0aW9uKG8pIHsgcmV0dXJuICFvLmFjdGl2ZTsgfSk7XG4gICAgICogLy8gPT4gb2JqZWN0cyBmb3IgWydmcmVkJywgJ3BlYmJsZXMnXVxuICAgICAqXG4gICAgICogLy8gVGhlIGBfLm1hdGNoZXNgIGl0ZXJhdGVlIHNob3J0aGFuZC5cbiAgICAgKiBfLnRha2VSaWdodFdoaWxlKHVzZXJzLCB7ICd1c2VyJzogJ3BlYmJsZXMnLCAnYWN0aXZlJzogZmFsc2UgfSk7XG4gICAgICogLy8gPT4gb2JqZWN0cyBmb3IgWydwZWJibGVzJ11cbiAgICAgKlxuICAgICAqIC8vIFRoZSBgXy5tYXRjaGVzUHJvcGVydHlgIGl0ZXJhdGVlIHNob3J0aGFuZC5cbiAgICAgKiBfLnRha2VSaWdodFdoaWxlKHVzZXJzLCBbJ2FjdGl2ZScsIGZhbHNlXSk7XG4gICAgICogLy8gPT4gb2JqZWN0cyBmb3IgWydmcmVkJywgJ3BlYmJsZXMnXVxuICAgICAqXG4gICAgICogLy8gVGhlIGBfLnByb3BlcnR5YCBpdGVyYXRlZSBzaG9ydGhhbmQuXG4gICAgICogXy50YWtlUmlnaHRXaGlsZSh1c2VycywgJ2FjdGl2ZScpO1xuICAgICAqIC8vID0+IFtdXG4gICAgICovXG4gICAgZnVuY3Rpb24gdGFrZVJpZ2h0V2hpbGUoYXJyYXksIHByZWRpY2F0ZSkge1xuICAgICAgcmV0dXJuIChhcnJheSAmJiBhcnJheS5sZW5ndGgpXG4gICAgICAgID8gYmFzZVdoaWxlKGFycmF5LCBnZXRJdGVyYXRlZShwcmVkaWNhdGUsIDMpLCBmYWxzZSwgdHJ1ZSlcbiAgICAgICAgOiBbXTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgc2xpY2Ugb2YgYGFycmF5YCB3aXRoIGVsZW1lbnRzIHRha2VuIGZyb20gdGhlIGJlZ2lubmluZy4gRWxlbWVudHNcbiAgICAgKiBhcmUgdGFrZW4gdW50aWwgYHByZWRpY2F0ZWAgcmV0dXJucyBmYWxzZXkuIFRoZSBwcmVkaWNhdGUgaXMgaW52b2tlZCB3aXRoXG4gICAgICogdGhyZWUgYXJndW1lbnRzOiAodmFsdWUsIGluZGV4LCBhcnJheSkuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMy4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgQXJyYXlcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gcXVlcnkuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW3ByZWRpY2F0ZT1fLmlkZW50aXR5XSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgc2xpY2Ugb2YgYGFycmF5YC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIHVzZXJzID0gW1xuICAgICAqICAgeyAndXNlcic6ICdiYXJuZXknLCAgJ2FjdGl2ZSc6IGZhbHNlIH0sXG4gICAgICogICB7ICd1c2VyJzogJ2ZyZWQnLCAgICAnYWN0aXZlJzogZmFsc2UgfSxcbiAgICAgKiAgIHsgJ3VzZXInOiAncGViYmxlcycsICdhY3RpdmUnOiB0cnVlIH1cbiAgICAgKiBdO1xuICAgICAqXG4gICAgICogXy50YWtlV2hpbGUodXNlcnMsIGZ1bmN0aW9uKG8pIHsgcmV0dXJuICFvLmFjdGl2ZTsgfSk7XG4gICAgICogLy8gPT4gb2JqZWN0cyBmb3IgWydiYXJuZXknLCAnZnJlZCddXG4gICAgICpcbiAgICAgKiAvLyBUaGUgYF8ubWF0Y2hlc2AgaXRlcmF0ZWUgc2hvcnRoYW5kLlxuICAgICAqIF8udGFrZVdoaWxlKHVzZXJzLCB7ICd1c2VyJzogJ2Jhcm5leScsICdhY3RpdmUnOiBmYWxzZSB9KTtcbiAgICAgKiAvLyA9PiBvYmplY3RzIGZvciBbJ2Jhcm5leSddXG4gICAgICpcbiAgICAgKiAvLyBUaGUgYF8ubWF0Y2hlc1Byb3BlcnR5YCBpdGVyYXRlZSBzaG9ydGhhbmQuXG4gICAgICogXy50YWtlV2hpbGUodXNlcnMsIFsnYWN0aXZlJywgZmFsc2VdKTtcbiAgICAgKiAvLyA9PiBvYmplY3RzIGZvciBbJ2Jhcm5leScsICdmcmVkJ11cbiAgICAgKlxuICAgICAqIC8vIFRoZSBgXy5wcm9wZXJ0eWAgaXRlcmF0ZWUgc2hvcnRoYW5kLlxuICAgICAqIF8udGFrZVdoaWxlKHVzZXJzLCAnYWN0aXZlJyk7XG4gICAgICogLy8gPT4gW11cbiAgICAgKi9cbiAgICBmdW5jdGlvbiB0YWtlV2hpbGUoYXJyYXksIHByZWRpY2F0ZSkge1xuICAgICAgcmV0dXJuIChhcnJheSAmJiBhcnJheS5sZW5ndGgpXG4gICAgICAgID8gYmFzZVdoaWxlKGFycmF5LCBnZXRJdGVyYXRlZShwcmVkaWNhdGUsIDMpKVxuICAgICAgICA6IFtdO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYW4gYXJyYXkgb2YgdW5pcXVlIHZhbHVlcywgaW4gb3JkZXIsIGZyb20gYWxsIGdpdmVuIGFycmF5cyB1c2luZ1xuICAgICAqIFtgU2FtZVZhbHVlWmVyb2BdKGh0dHA6Ly9lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzcuMC8jc2VjLXNhbWV2YWx1ZXplcm8pXG4gICAgICogZm9yIGVxdWFsaXR5IGNvbXBhcmlzb25zLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDAuMS4wXG4gICAgICogQGNhdGVnb3J5IEFycmF5XG4gICAgICogQHBhcmFtIHsuLi5BcnJheX0gW2FycmF5c10gVGhlIGFycmF5cyB0byBpbnNwZWN0LlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IGFycmF5IG9mIGNvbWJpbmVkIHZhbHVlcy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy51bmlvbihbMl0sIFsxLCAyXSk7XG4gICAgICogLy8gPT4gWzIsIDFdXG4gICAgICovXG4gICAgdmFyIHVuaW9uID0gYmFzZVJlc3QoZnVuY3Rpb24oYXJyYXlzKSB7XG4gICAgICByZXR1cm4gYmFzZVVuaXEoYmFzZUZsYXR0ZW4oYXJyYXlzLCAxLCBpc0FycmF5TGlrZU9iamVjdCwgdHJ1ZSkpO1xuICAgIH0pO1xuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgaXMgbGlrZSBgXy51bmlvbmAgZXhjZXB0IHRoYXQgaXQgYWNjZXB0cyBgaXRlcmF0ZWVgIHdoaWNoIGlzXG4gICAgICogaW52b2tlZCBmb3IgZWFjaCBlbGVtZW50IG9mIGVhY2ggYGFycmF5c2AgdG8gZ2VuZXJhdGUgdGhlIGNyaXRlcmlvbiBieVxuICAgICAqIHdoaWNoIHVuaXF1ZW5lc3MgaXMgY29tcHV0ZWQuIFJlc3VsdCB2YWx1ZXMgYXJlIGNob3NlbiBmcm9tIHRoZSBmaXJzdFxuICAgICAqIGFycmF5IGluIHdoaWNoIHRoZSB2YWx1ZSBvY2N1cnMuIFRoZSBpdGVyYXRlZSBpcyBpbnZva2VkIHdpdGggb25lIGFyZ3VtZW50OlxuICAgICAqICh2YWx1ZSkuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgQXJyYXlcbiAgICAgKiBAcGFyYW0gey4uLkFycmF5fSBbYXJyYXlzXSBUaGUgYXJyYXlzIHRvIGluc3BlY3QuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW2l0ZXJhdGVlPV8uaWRlbnRpdHldIFRoZSBpdGVyYXRlZSBpbnZva2VkIHBlciBlbGVtZW50LlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IGFycmF5IG9mIGNvbWJpbmVkIHZhbHVlcy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy51bmlvbkJ5KFsyLjFdLCBbMS4yLCAyLjNdLCBNYXRoLmZsb29yKTtcbiAgICAgKiAvLyA9PiBbMi4xLCAxLjJdXG4gICAgICpcbiAgICAgKiAvLyBUaGUgYF8ucHJvcGVydHlgIGl0ZXJhdGVlIHNob3J0aGFuZC5cbiAgICAgKiBfLnVuaW9uQnkoW3sgJ3gnOiAxIH1dLCBbeyAneCc6IDIgfSwgeyAneCc6IDEgfV0sICd4Jyk7XG4gICAgICogLy8gPT4gW3sgJ3gnOiAxIH0sIHsgJ3gnOiAyIH1dXG4gICAgICovXG4gICAgdmFyIHVuaW9uQnkgPSBiYXNlUmVzdChmdW5jdGlvbihhcnJheXMpIHtcbiAgICAgIHZhciBpdGVyYXRlZSA9IGxhc3QoYXJyYXlzKTtcbiAgICAgIGlmIChpc0FycmF5TGlrZU9iamVjdChpdGVyYXRlZSkpIHtcbiAgICAgICAgaXRlcmF0ZWUgPSB1bmRlZmluZWQ7XG4gICAgICB9XG4gICAgICByZXR1cm4gYmFzZVVuaXEoYmFzZUZsYXR0ZW4oYXJyYXlzLCAxLCBpc0FycmF5TGlrZU9iamVjdCwgdHJ1ZSksIGdldEl0ZXJhdGVlKGl0ZXJhdGVlLCAyKSk7XG4gICAgfSk7XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIG1ldGhvZCBpcyBsaWtlIGBfLnVuaW9uYCBleGNlcHQgdGhhdCBpdCBhY2NlcHRzIGBjb21wYXJhdG9yYCB3aGljaFxuICAgICAqIGlzIGludm9rZWQgdG8gY29tcGFyZSBlbGVtZW50cyBvZiBgYXJyYXlzYC4gUmVzdWx0IHZhbHVlcyBhcmUgY2hvc2VuIGZyb21cbiAgICAgKiB0aGUgZmlyc3QgYXJyYXkgaW4gd2hpY2ggdGhlIHZhbHVlIG9jY3Vycy4gVGhlIGNvbXBhcmF0b3IgaXMgaW52b2tlZFxuICAgICAqIHdpdGggdHdvIGFyZ3VtZW50czogKGFyclZhbCwgb3RoVmFsKS5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjAuMFxuICAgICAqIEBjYXRlZ29yeSBBcnJheVxuICAgICAqIEBwYXJhbSB7Li4uQXJyYXl9IFthcnJheXNdIFRoZSBhcnJheXMgdG8gaW5zcGVjdC5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbY29tcGFyYXRvcl0gVGhlIGNvbXBhcmF0b3IgaW52b2tlZCBwZXIgZWxlbWVudC5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIG5ldyBhcnJheSBvZiBjb21iaW5lZCB2YWx1ZXMuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciBvYmplY3RzID0gW3sgJ3gnOiAxLCAneSc6IDIgfSwgeyAneCc6IDIsICd5JzogMSB9XTtcbiAgICAgKiB2YXIgb3RoZXJzID0gW3sgJ3gnOiAxLCAneSc6IDEgfSwgeyAneCc6IDEsICd5JzogMiB9XTtcbiAgICAgKlxuICAgICAqIF8udW5pb25XaXRoKG9iamVjdHMsIG90aGVycywgXy5pc0VxdWFsKTtcbiAgICAgKiAvLyA9PiBbeyAneCc6IDEsICd5JzogMiB9LCB7ICd4JzogMiwgJ3knOiAxIH0sIHsgJ3gnOiAxLCAneSc6IDEgfV1cbiAgICAgKi9cbiAgICB2YXIgdW5pb25XaXRoID0gYmFzZVJlc3QoZnVuY3Rpb24oYXJyYXlzKSB7XG4gICAgICB2YXIgY29tcGFyYXRvciA9IGxhc3QoYXJyYXlzKTtcbiAgICAgIGNvbXBhcmF0b3IgPSB0eXBlb2YgY29tcGFyYXRvciA9PSAnZnVuY3Rpb24nID8gY29tcGFyYXRvciA6IHVuZGVmaW5lZDtcbiAgICAgIHJldHVybiBiYXNlVW5pcShiYXNlRmxhdHRlbihhcnJheXMsIDEsIGlzQXJyYXlMaWtlT2JqZWN0LCB0cnVlKSwgdW5kZWZpbmVkLCBjb21wYXJhdG9yKTtcbiAgICB9KTtcblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBkdXBsaWNhdGUtZnJlZSB2ZXJzaW9uIG9mIGFuIGFycmF5LCB1c2luZ1xuICAgICAqIFtgU2FtZVZhbHVlWmVyb2BdKGh0dHA6Ly9lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzcuMC8jc2VjLXNhbWV2YWx1ZXplcm8pXG4gICAgICogZm9yIGVxdWFsaXR5IGNvbXBhcmlzb25zLCBpbiB3aGljaCBvbmx5IHRoZSBmaXJzdCBvY2N1cnJlbmNlIG9mIGVhY2ggZWxlbWVudFxuICAgICAqIGlzIGtlcHQuIFRoZSBvcmRlciBvZiByZXN1bHQgdmFsdWVzIGlzIGRldGVybWluZWQgYnkgdGhlIG9yZGVyIHRoZXkgb2NjdXJcbiAgICAgKiBpbiB0aGUgYXJyYXkuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMC4xLjBcbiAgICAgKiBAY2F0ZWdvcnkgQXJyYXlcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gaW5zcGVjdC5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIG5ldyBkdXBsaWNhdGUgZnJlZSBhcnJheS5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy51bmlxKFsyLCAxLCAyXSk7XG4gICAgICogLy8gPT4gWzIsIDFdXG4gICAgICovXG4gICAgZnVuY3Rpb24gdW5pcShhcnJheSkge1xuICAgICAgcmV0dXJuIChhcnJheSAmJiBhcnJheS5sZW5ndGgpID8gYmFzZVVuaXEoYXJyYXkpIDogW107XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgaXMgbGlrZSBgXy51bmlxYCBleGNlcHQgdGhhdCBpdCBhY2NlcHRzIGBpdGVyYXRlZWAgd2hpY2ggaXNcbiAgICAgKiBpbnZva2VkIGZvciBlYWNoIGVsZW1lbnQgaW4gYGFycmF5YCB0byBnZW5lcmF0ZSB0aGUgY3JpdGVyaW9uIGJ5IHdoaWNoXG4gICAgICogdW5pcXVlbmVzcyBpcyBjb21wdXRlZC4gVGhlIG9yZGVyIG9mIHJlc3VsdCB2YWx1ZXMgaXMgZGV0ZXJtaW5lZCBieSB0aGVcbiAgICAgKiBvcmRlciB0aGV5IG9jY3VyIGluIHRoZSBhcnJheS4gVGhlIGl0ZXJhdGVlIGlzIGludm9rZWQgd2l0aCBvbmUgYXJndW1lbnQ6XG4gICAgICogKHZhbHVlKS5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjAuMFxuICAgICAqIEBjYXRlZ29yeSBBcnJheVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBpbnNwZWN0LlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IFtpdGVyYXRlZT1fLmlkZW50aXR5XSBUaGUgaXRlcmF0ZWUgaW52b2tlZCBwZXIgZWxlbWVudC5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIG5ldyBkdXBsaWNhdGUgZnJlZSBhcnJheS5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy51bmlxQnkoWzIuMSwgMS4yLCAyLjNdLCBNYXRoLmZsb29yKTtcbiAgICAgKiAvLyA9PiBbMi4xLCAxLjJdXG4gICAgICpcbiAgICAgKiAvLyBUaGUgYF8ucHJvcGVydHlgIGl0ZXJhdGVlIHNob3J0aGFuZC5cbiAgICAgKiBfLnVuaXFCeShbeyAneCc6IDEgfSwgeyAneCc6IDIgfSwgeyAneCc6IDEgfV0sICd4Jyk7XG4gICAgICogLy8gPT4gW3sgJ3gnOiAxIH0sIHsgJ3gnOiAyIH1dXG4gICAgICovXG4gICAgZnVuY3Rpb24gdW5pcUJ5KGFycmF5LCBpdGVyYXRlZSkge1xuICAgICAgcmV0dXJuIChhcnJheSAmJiBhcnJheS5sZW5ndGgpID8gYmFzZVVuaXEoYXJyYXksIGdldEl0ZXJhdGVlKGl0ZXJhdGVlLCAyKSkgOiBbXTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIG1ldGhvZCBpcyBsaWtlIGBfLnVuaXFgIGV4Y2VwdCB0aGF0IGl0IGFjY2VwdHMgYGNvbXBhcmF0b3JgIHdoaWNoXG4gICAgICogaXMgaW52b2tlZCB0byBjb21wYXJlIGVsZW1lbnRzIG9mIGBhcnJheWAuIFRoZSBvcmRlciBvZiByZXN1bHQgdmFsdWVzIGlzXG4gICAgICogZGV0ZXJtaW5lZCBieSB0aGUgb3JkZXIgdGhleSBvY2N1ciBpbiB0aGUgYXJyYXkuVGhlIGNvbXBhcmF0b3IgaXMgaW52b2tlZFxuICAgICAqIHdpdGggdHdvIGFyZ3VtZW50czogKGFyclZhbCwgb3RoVmFsKS5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjAuMFxuICAgICAqIEBjYXRlZ29yeSBBcnJheVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBpbnNwZWN0LlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IFtjb21wYXJhdG9yXSBUaGUgY29tcGFyYXRvciBpbnZva2VkIHBlciBlbGVtZW50LlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IGR1cGxpY2F0ZSBmcmVlIGFycmF5LlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgb2JqZWN0cyA9IFt7ICd4JzogMSwgJ3knOiAyIH0sIHsgJ3gnOiAyLCAneSc6IDEgfSwgeyAneCc6IDEsICd5JzogMiB9XTtcbiAgICAgKlxuICAgICAqIF8udW5pcVdpdGgob2JqZWN0cywgXy5pc0VxdWFsKTtcbiAgICAgKiAvLyA9PiBbeyAneCc6IDEsICd5JzogMiB9LCB7ICd4JzogMiwgJ3knOiAxIH1dXG4gICAgICovXG4gICAgZnVuY3Rpb24gdW5pcVdpdGgoYXJyYXksIGNvbXBhcmF0b3IpIHtcbiAgICAgIGNvbXBhcmF0b3IgPSB0eXBlb2YgY29tcGFyYXRvciA9PSAnZnVuY3Rpb24nID8gY29tcGFyYXRvciA6IHVuZGVmaW5lZDtcbiAgICAgIHJldHVybiAoYXJyYXkgJiYgYXJyYXkubGVuZ3RoKSA/IGJhc2VVbmlxKGFycmF5LCB1bmRlZmluZWQsIGNvbXBhcmF0b3IpIDogW107XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgaXMgbGlrZSBgXy56aXBgIGV4Y2VwdCB0aGF0IGl0IGFjY2VwdHMgYW4gYXJyYXkgb2YgZ3JvdXBlZFxuICAgICAqIGVsZW1lbnRzIGFuZCBjcmVhdGVzIGFuIGFycmF5IHJlZ3JvdXBpbmcgdGhlIGVsZW1lbnRzIHRvIHRoZWlyIHByZS16aXBcbiAgICAgKiBjb25maWd1cmF0aW9uLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDEuMi4wXG4gICAgICogQGNhdGVnb3J5IEFycmF5XG4gICAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IG9mIGdyb3VwZWQgZWxlbWVudHMgdG8gcHJvY2Vzcy5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIG5ldyBhcnJheSBvZiByZWdyb3VwZWQgZWxlbWVudHMuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciB6aXBwZWQgPSBfLnppcChbJ2EnLCAnYiddLCBbMSwgMl0sIFt0cnVlLCBmYWxzZV0pO1xuICAgICAqIC8vID0+IFtbJ2EnLCAxLCB0cnVlXSwgWydiJywgMiwgZmFsc2VdXVxuICAgICAqXG4gICAgICogXy51bnppcCh6aXBwZWQpO1xuICAgICAqIC8vID0+IFtbJ2EnLCAnYiddLCBbMSwgMl0sIFt0cnVlLCBmYWxzZV1dXG4gICAgICovXG4gICAgZnVuY3Rpb24gdW56aXAoYXJyYXkpIHtcbiAgICAgIGlmICghKGFycmF5ICYmIGFycmF5Lmxlbmd0aCkpIHtcbiAgICAgICAgcmV0dXJuIFtdO1xuICAgICAgfVxuICAgICAgdmFyIGxlbmd0aCA9IDA7XG4gICAgICBhcnJheSA9IGFycmF5RmlsdGVyKGFycmF5LCBmdW5jdGlvbihncm91cCkge1xuICAgICAgICBpZiAoaXNBcnJheUxpa2VPYmplY3QoZ3JvdXApKSB7XG4gICAgICAgICAgbGVuZ3RoID0gbmF0aXZlTWF4KGdyb3VwLmxlbmd0aCwgbGVuZ3RoKTtcbiAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgICByZXR1cm4gYmFzZVRpbWVzKGxlbmd0aCwgZnVuY3Rpb24oaW5kZXgpIHtcbiAgICAgICAgcmV0dXJuIGFycmF5TWFwKGFycmF5LCBiYXNlUHJvcGVydHkoaW5kZXgpKTtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIGlzIGxpa2UgYF8udW56aXBgIGV4Y2VwdCB0aGF0IGl0IGFjY2VwdHMgYGl0ZXJhdGVlYCB0byBzcGVjaWZ5XG4gICAgICogaG93IHJlZ3JvdXBlZCB2YWx1ZXMgc2hvdWxkIGJlIGNvbWJpbmVkLiBUaGUgaXRlcmF0ZWUgaXMgaW52b2tlZCB3aXRoIHRoZVxuICAgICAqIGVsZW1lbnRzIG9mIGVhY2ggZ3JvdXA6ICguLi5ncm91cCkuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMy44LjBcbiAgICAgKiBAY2F0ZWdvcnkgQXJyYXlcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgb2YgZ3JvdXBlZCBlbGVtZW50cyB0byBwcm9jZXNzLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IFtpdGVyYXRlZT1fLmlkZW50aXR5XSBUaGUgZnVuY3Rpb24gdG8gY29tYmluZVxuICAgICAqICByZWdyb3VwZWQgdmFsdWVzLlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IGFycmF5IG9mIHJlZ3JvdXBlZCBlbGVtZW50cy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIHppcHBlZCA9IF8uemlwKFsxLCAyXSwgWzEwLCAyMF0sIFsxMDAsIDIwMF0pO1xuICAgICAqIC8vID0+IFtbMSwgMTAsIDEwMF0sIFsyLCAyMCwgMjAwXV1cbiAgICAgKlxuICAgICAqIF8udW56aXBXaXRoKHppcHBlZCwgXy5hZGQpO1xuICAgICAqIC8vID0+IFszLCAzMCwgMzAwXVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIHVuemlwV2l0aChhcnJheSwgaXRlcmF0ZWUpIHtcbiAgICAgIGlmICghKGFycmF5ICYmIGFycmF5Lmxlbmd0aCkpIHtcbiAgICAgICAgcmV0dXJuIFtdO1xuICAgICAgfVxuICAgICAgdmFyIHJlc3VsdCA9IHVuemlwKGFycmF5KTtcbiAgICAgIGlmIChpdGVyYXRlZSA9PSBudWxsKSB7XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICB9XG4gICAgICByZXR1cm4gYXJyYXlNYXAocmVzdWx0LCBmdW5jdGlvbihncm91cCkge1xuICAgICAgICByZXR1cm4gYXBwbHkoaXRlcmF0ZWUsIHVuZGVmaW5lZCwgZ3JvdXApO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhbiBhcnJheSBleGNsdWRpbmcgYWxsIGdpdmVuIHZhbHVlcyB1c2luZ1xuICAgICAqIFtgU2FtZVZhbHVlWmVyb2BdKGh0dHA6Ly9lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzcuMC8jc2VjLXNhbWV2YWx1ZXplcm8pXG4gICAgICogZm9yIGVxdWFsaXR5IGNvbXBhcmlzb25zLlxuICAgICAqXG4gICAgICogKipOb3RlOioqIFVubGlrZSBgXy5wdWxsYCwgdGhpcyBtZXRob2QgcmV0dXJucyBhIG5ldyBhcnJheS5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAwLjEuMFxuICAgICAqIEBjYXRlZ29yeSBBcnJheVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBpbnNwZWN0LlxuICAgICAqIEBwYXJhbSB7Li4uKn0gW3ZhbHVlc10gVGhlIHZhbHVlcyB0byBleGNsdWRlLlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IGFycmF5IG9mIGZpbHRlcmVkIHZhbHVlcy5cbiAgICAgKiBAc2VlIF8uZGlmZmVyZW5jZSwgXy54b3JcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy53aXRob3V0KFsyLCAxLCAyLCAzXSwgMSwgMik7XG4gICAgICogLy8gPT4gWzNdXG4gICAgICovXG4gICAgdmFyIHdpdGhvdXQgPSBiYXNlUmVzdChmdW5jdGlvbihhcnJheSwgdmFsdWVzKSB7XG4gICAgICByZXR1cm4gaXNBcnJheUxpa2VPYmplY3QoYXJyYXkpXG4gICAgICAgID8gYmFzZURpZmZlcmVuY2UoYXJyYXksIHZhbHVlcylcbiAgICAgICAgOiBbXTtcbiAgICB9KTtcblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYW4gYXJyYXkgb2YgdW5pcXVlIHZhbHVlcyB0aGF0IGlzIHRoZVxuICAgICAqIFtzeW1tZXRyaWMgZGlmZmVyZW5jZV0oaHR0cHM6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvU3ltbWV0cmljX2RpZmZlcmVuY2UpXG4gICAgICogb2YgdGhlIGdpdmVuIGFycmF5cy4gVGhlIG9yZGVyIG9mIHJlc3VsdCB2YWx1ZXMgaXMgZGV0ZXJtaW5lZCBieSB0aGUgb3JkZXJcbiAgICAgKiB0aGV5IG9jY3VyIGluIHRoZSBhcnJheXMuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMi40LjBcbiAgICAgKiBAY2F0ZWdvcnkgQXJyYXlcbiAgICAgKiBAcGFyYW0gey4uLkFycmF5fSBbYXJyYXlzXSBUaGUgYXJyYXlzIHRvIGluc3BlY3QuXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBuZXcgYXJyYXkgb2YgZmlsdGVyZWQgdmFsdWVzLlxuICAgICAqIEBzZWUgXy5kaWZmZXJlbmNlLCBfLndpdGhvdXRcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy54b3IoWzIsIDFdLCBbMiwgM10pO1xuICAgICAqIC8vID0+IFsxLCAzXVxuICAgICAqL1xuICAgIHZhciB4b3IgPSBiYXNlUmVzdChmdW5jdGlvbihhcnJheXMpIHtcbiAgICAgIHJldHVybiBiYXNlWG9yKGFycmF5RmlsdGVyKGFycmF5cywgaXNBcnJheUxpa2VPYmplY3QpKTtcbiAgICB9KTtcblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIGlzIGxpa2UgYF8ueG9yYCBleGNlcHQgdGhhdCBpdCBhY2NlcHRzIGBpdGVyYXRlZWAgd2hpY2ggaXNcbiAgICAgKiBpbnZva2VkIGZvciBlYWNoIGVsZW1lbnQgb2YgZWFjaCBgYXJyYXlzYCB0byBnZW5lcmF0ZSB0aGUgY3JpdGVyaW9uIGJ5XG4gICAgICogd2hpY2ggYnkgd2hpY2ggdGhleSdyZSBjb21wYXJlZC4gVGhlIG9yZGVyIG9mIHJlc3VsdCB2YWx1ZXMgaXMgZGV0ZXJtaW5lZFxuICAgICAqIGJ5IHRoZSBvcmRlciB0aGV5IG9jY3VyIGluIHRoZSBhcnJheXMuIFRoZSBpdGVyYXRlZSBpcyBpbnZva2VkIHdpdGggb25lXG4gICAgICogYXJndW1lbnQ6ICh2YWx1ZSkuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgQXJyYXlcbiAgICAgKiBAcGFyYW0gey4uLkFycmF5fSBbYXJyYXlzXSBUaGUgYXJyYXlzIHRvIGluc3BlY3QuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW2l0ZXJhdGVlPV8uaWRlbnRpdHldIFRoZSBpdGVyYXRlZSBpbnZva2VkIHBlciBlbGVtZW50LlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IGFycmF5IG9mIGZpbHRlcmVkIHZhbHVlcy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy54b3JCeShbMi4xLCAxLjJdLCBbMi4zLCAzLjRdLCBNYXRoLmZsb29yKTtcbiAgICAgKiAvLyA9PiBbMS4yLCAzLjRdXG4gICAgICpcbiAgICAgKiAvLyBUaGUgYF8ucHJvcGVydHlgIGl0ZXJhdGVlIHNob3J0aGFuZC5cbiAgICAgKiBfLnhvckJ5KFt7ICd4JzogMSB9XSwgW3sgJ3gnOiAyIH0sIHsgJ3gnOiAxIH1dLCAneCcpO1xuICAgICAqIC8vID0+IFt7ICd4JzogMiB9XVxuICAgICAqL1xuICAgIHZhciB4b3JCeSA9IGJhc2VSZXN0KGZ1bmN0aW9uKGFycmF5cykge1xuICAgICAgdmFyIGl0ZXJhdGVlID0gbGFzdChhcnJheXMpO1xuICAgICAgaWYgKGlzQXJyYXlMaWtlT2JqZWN0KGl0ZXJhdGVlKSkge1xuICAgICAgICBpdGVyYXRlZSA9IHVuZGVmaW5lZDtcbiAgICAgIH1cbiAgICAgIHJldHVybiBiYXNlWG9yKGFycmF5RmlsdGVyKGFycmF5cywgaXNBcnJheUxpa2VPYmplY3QpLCBnZXRJdGVyYXRlZShpdGVyYXRlZSwgMikpO1xuICAgIH0pO1xuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgaXMgbGlrZSBgXy54b3JgIGV4Y2VwdCB0aGF0IGl0IGFjY2VwdHMgYGNvbXBhcmF0b3JgIHdoaWNoIGlzXG4gICAgICogaW52b2tlZCB0byBjb21wYXJlIGVsZW1lbnRzIG9mIGBhcnJheXNgLiBUaGUgb3JkZXIgb2YgcmVzdWx0IHZhbHVlcyBpc1xuICAgICAqIGRldGVybWluZWQgYnkgdGhlIG9yZGVyIHRoZXkgb2NjdXIgaW4gdGhlIGFycmF5cy4gVGhlIGNvbXBhcmF0b3IgaXMgaW52b2tlZFxuICAgICAqIHdpdGggdHdvIGFyZ3VtZW50czogKGFyclZhbCwgb3RoVmFsKS5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjAuMFxuICAgICAqIEBjYXRlZ29yeSBBcnJheVxuICAgICAqIEBwYXJhbSB7Li4uQXJyYXl9IFthcnJheXNdIFRoZSBhcnJheXMgdG8gaW5zcGVjdC5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbY29tcGFyYXRvcl0gVGhlIGNvbXBhcmF0b3IgaW52b2tlZCBwZXIgZWxlbWVudC5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIG5ldyBhcnJheSBvZiBmaWx0ZXJlZCB2YWx1ZXMuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciBvYmplY3RzID0gW3sgJ3gnOiAxLCAneSc6IDIgfSwgeyAneCc6IDIsICd5JzogMSB9XTtcbiAgICAgKiB2YXIgb3RoZXJzID0gW3sgJ3gnOiAxLCAneSc6IDEgfSwgeyAneCc6IDEsICd5JzogMiB9XTtcbiAgICAgKlxuICAgICAqIF8ueG9yV2l0aChvYmplY3RzLCBvdGhlcnMsIF8uaXNFcXVhbCk7XG4gICAgICogLy8gPT4gW3sgJ3gnOiAyLCAneSc6IDEgfSwgeyAneCc6IDEsICd5JzogMSB9XVxuICAgICAqL1xuICAgIHZhciB4b3JXaXRoID0gYmFzZVJlc3QoZnVuY3Rpb24oYXJyYXlzKSB7XG4gICAgICB2YXIgY29tcGFyYXRvciA9IGxhc3QoYXJyYXlzKTtcbiAgICAgIGNvbXBhcmF0b3IgPSB0eXBlb2YgY29tcGFyYXRvciA9PSAnZnVuY3Rpb24nID8gY29tcGFyYXRvciA6IHVuZGVmaW5lZDtcbiAgICAgIHJldHVybiBiYXNlWG9yKGFycmF5RmlsdGVyKGFycmF5cywgaXNBcnJheUxpa2VPYmplY3QpLCB1bmRlZmluZWQsIGNvbXBhcmF0b3IpO1xuICAgIH0pO1xuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhbiBhcnJheSBvZiBncm91cGVkIGVsZW1lbnRzLCB0aGUgZmlyc3Qgb2Ygd2hpY2ggY29udGFpbnMgdGhlXG4gICAgICogZmlyc3QgZWxlbWVudHMgb2YgdGhlIGdpdmVuIGFycmF5cywgdGhlIHNlY29uZCBvZiB3aGljaCBjb250YWlucyB0aGVcbiAgICAgKiBzZWNvbmQgZWxlbWVudHMgb2YgdGhlIGdpdmVuIGFycmF5cywgYW5kIHNvIG9uLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDAuMS4wXG4gICAgICogQGNhdGVnb3J5IEFycmF5XG4gICAgICogQHBhcmFtIHsuLi5BcnJheX0gW2FycmF5c10gVGhlIGFycmF5cyB0byBwcm9jZXNzLlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IGFycmF5IG9mIGdyb3VwZWQgZWxlbWVudHMuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uemlwKFsnYScsICdiJ10sIFsxLCAyXSwgW3RydWUsIGZhbHNlXSk7XG4gICAgICogLy8gPT4gW1snYScsIDEsIHRydWVdLCBbJ2InLCAyLCBmYWxzZV1dXG4gICAgICovXG4gICAgdmFyIHppcCA9IGJhc2VSZXN0KHVuemlwKTtcblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIGlzIGxpa2UgYF8uZnJvbVBhaXJzYCBleGNlcHQgdGhhdCBpdCBhY2NlcHRzIHR3byBhcnJheXMsXG4gICAgICogb25lIG9mIHByb3BlcnR5IGlkZW50aWZpZXJzIGFuZCBvbmUgb2YgY29ycmVzcG9uZGluZyB2YWx1ZXMuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMC40LjBcbiAgICAgKiBAY2F0ZWdvcnkgQXJyYXlcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBbcHJvcHM9W11dIFRoZSBwcm9wZXJ0eSBpZGVudGlmaWVycy5cbiAgICAgKiBAcGFyYW0ge0FycmF5fSBbdmFsdWVzPVtdXSBUaGUgcHJvcGVydHkgdmFsdWVzLlxuICAgICAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgdGhlIG5ldyBvYmplY3QuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uemlwT2JqZWN0KFsnYScsICdiJ10sIFsxLCAyXSk7XG4gICAgICogLy8gPT4geyAnYSc6IDEsICdiJzogMiB9XG4gICAgICovXG4gICAgZnVuY3Rpb24gemlwT2JqZWN0KHByb3BzLCB2YWx1ZXMpIHtcbiAgICAgIHJldHVybiBiYXNlWmlwT2JqZWN0KHByb3BzIHx8IFtdLCB2YWx1ZXMgfHwgW10sIGFzc2lnblZhbHVlKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIG1ldGhvZCBpcyBsaWtlIGBfLnppcE9iamVjdGAgZXhjZXB0IHRoYXQgaXQgc3VwcG9ydHMgcHJvcGVydHkgcGF0aHMuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4xLjBcbiAgICAgKiBAY2F0ZWdvcnkgQXJyYXlcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBbcHJvcHM9W11dIFRoZSBwcm9wZXJ0eSBpZGVudGlmaWVycy5cbiAgICAgKiBAcGFyYW0ge0FycmF5fSBbdmFsdWVzPVtdXSBUaGUgcHJvcGVydHkgdmFsdWVzLlxuICAgICAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgdGhlIG5ldyBvYmplY3QuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uemlwT2JqZWN0RGVlcChbJ2EuYlswXS5jJywgJ2EuYlsxXS5kJ10sIFsxLCAyXSk7XG4gICAgICogLy8gPT4geyAnYSc6IHsgJ2InOiBbeyAnYyc6IDEgfSwgeyAnZCc6IDIgfV0gfSB9XG4gICAgICovXG4gICAgZnVuY3Rpb24gemlwT2JqZWN0RGVlcChwcm9wcywgdmFsdWVzKSB7XG4gICAgICByZXR1cm4gYmFzZVppcE9iamVjdChwcm9wcyB8fCBbXSwgdmFsdWVzIHx8IFtdLCBiYXNlU2V0KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIG1ldGhvZCBpcyBsaWtlIGBfLnppcGAgZXhjZXB0IHRoYXQgaXQgYWNjZXB0cyBgaXRlcmF0ZWVgIHRvIHNwZWNpZnlcbiAgICAgKiBob3cgZ3JvdXBlZCB2YWx1ZXMgc2hvdWxkIGJlIGNvbWJpbmVkLiBUaGUgaXRlcmF0ZWUgaXMgaW52b2tlZCB3aXRoIHRoZVxuICAgICAqIGVsZW1lbnRzIG9mIGVhY2ggZ3JvdXA6ICguLi5ncm91cCkuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMy44LjBcbiAgICAgKiBAY2F0ZWdvcnkgQXJyYXlcbiAgICAgKiBAcGFyYW0gey4uLkFycmF5fSBbYXJyYXlzXSBUaGUgYXJyYXlzIHRvIHByb2Nlc3MuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW2l0ZXJhdGVlPV8uaWRlbnRpdHldIFRoZSBmdW5jdGlvbiB0byBjb21iaW5lXG4gICAgICogIGdyb3VwZWQgdmFsdWVzLlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IGFycmF5IG9mIGdyb3VwZWQgZWxlbWVudHMuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uemlwV2l0aChbMSwgMl0sIFsxMCwgMjBdLCBbMTAwLCAyMDBdLCBmdW5jdGlvbihhLCBiLCBjKSB7XG4gICAgICogICByZXR1cm4gYSArIGIgKyBjO1xuICAgICAqIH0pO1xuICAgICAqIC8vID0+IFsxMTEsIDIyMl1cbiAgICAgKi9cbiAgICB2YXIgemlwV2l0aCA9IGJhc2VSZXN0KGZ1bmN0aW9uKGFycmF5cykge1xuICAgICAgdmFyIGxlbmd0aCA9IGFycmF5cy5sZW5ndGgsXG4gICAgICAgICAgaXRlcmF0ZWUgPSBsZW5ndGggPiAxID8gYXJyYXlzW2xlbmd0aCAtIDFdIDogdW5kZWZpbmVkO1xuXG4gICAgICBpdGVyYXRlZSA9IHR5cGVvZiBpdGVyYXRlZSA9PSAnZnVuY3Rpb24nID8gKGFycmF5cy5wb3AoKSwgaXRlcmF0ZWUpIDogdW5kZWZpbmVkO1xuICAgICAgcmV0dXJuIHVuemlwV2l0aChhcnJheXMsIGl0ZXJhdGVlKTtcbiAgICB9KTtcblxuICAgIC8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi9cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBgbG9kYXNoYCB3cmFwcGVyIGluc3RhbmNlIHRoYXQgd3JhcHMgYHZhbHVlYCB3aXRoIGV4cGxpY2l0IG1ldGhvZFxuICAgICAqIGNoYWluIHNlcXVlbmNlcyBlbmFibGVkLiBUaGUgcmVzdWx0IG9mIHN1Y2ggc2VxdWVuY2VzIG11c3QgYmUgdW53cmFwcGVkXG4gICAgICogd2l0aCBgXyN2YWx1ZWAuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMS4zLjBcbiAgICAgKiBAY2F0ZWdvcnkgU2VxXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gd3JhcC5cbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIHRoZSBuZXcgYGxvZGFzaGAgd3JhcHBlciBpbnN0YW5jZS5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIHVzZXJzID0gW1xuICAgICAqICAgeyAndXNlcic6ICdiYXJuZXknLCAgJ2FnZSc6IDM2IH0sXG4gICAgICogICB7ICd1c2VyJzogJ2ZyZWQnLCAgICAnYWdlJzogNDAgfSxcbiAgICAgKiAgIHsgJ3VzZXInOiAncGViYmxlcycsICdhZ2UnOiAxIH1cbiAgICAgKiBdO1xuICAgICAqXG4gICAgICogdmFyIHlvdW5nZXN0ID0gX1xuICAgICAqICAgLmNoYWluKHVzZXJzKVxuICAgICAqICAgLnNvcnRCeSgnYWdlJylcbiAgICAgKiAgIC5tYXAoZnVuY3Rpb24obykge1xuICAgICAqICAgICByZXR1cm4gby51c2VyICsgJyBpcyAnICsgby5hZ2U7XG4gICAgICogICB9KVxuICAgICAqICAgLmhlYWQoKVxuICAgICAqICAgLnZhbHVlKCk7XG4gICAgICogLy8gPT4gJ3BlYmJsZXMgaXMgMSdcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBjaGFpbih2YWx1ZSkge1xuICAgICAgdmFyIHJlc3VsdCA9IGxvZGFzaCh2YWx1ZSk7XG4gICAgICByZXN1bHQuX19jaGFpbl9fID0gdHJ1ZTtcbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgaW52b2tlcyBgaW50ZXJjZXB0b3JgIGFuZCByZXR1cm5zIGB2YWx1ZWAuIFRoZSBpbnRlcmNlcHRvclxuICAgICAqIGlzIGludm9rZWQgd2l0aCBvbmUgYXJndW1lbnQ7ICh2YWx1ZSkuIFRoZSBwdXJwb3NlIG9mIHRoaXMgbWV0aG9kIGlzIHRvXG4gICAgICogXCJ0YXAgaW50b1wiIGEgbWV0aG9kIGNoYWluIHNlcXVlbmNlIGluIG9yZGVyIHRvIG1vZGlmeSBpbnRlcm1lZGlhdGUgcmVzdWx0cy5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAwLjEuMFxuICAgICAqIEBjYXRlZ29yeSBTZXFcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBwcm92aWRlIHRvIGBpbnRlcmNlcHRvcmAuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gaW50ZXJjZXB0b3IgVGhlIGZ1bmN0aW9uIHRvIGludm9rZS5cbiAgICAgKiBAcmV0dXJucyB7Kn0gUmV0dXJucyBgdmFsdWVgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfKFsxLCAyLCAzXSlcbiAgICAgKiAgLnRhcChmdW5jdGlvbihhcnJheSkge1xuICAgICAqICAgIC8vIE11dGF0ZSBpbnB1dCBhcnJheS5cbiAgICAgKiAgICBhcnJheS5wb3AoKTtcbiAgICAgKiAgfSlcbiAgICAgKiAgLnJldmVyc2UoKVxuICAgICAqICAudmFsdWUoKTtcbiAgICAgKiAvLyA9PiBbMiwgMV1cbiAgICAgKi9cbiAgICBmdW5jdGlvbiB0YXAodmFsdWUsIGludGVyY2VwdG9yKSB7XG4gICAgICBpbnRlcmNlcHRvcih2YWx1ZSk7XG4gICAgICByZXR1cm4gdmFsdWU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgaXMgbGlrZSBgXy50YXBgIGV4Y2VwdCB0aGF0IGl0IHJldHVybnMgdGhlIHJlc3VsdCBvZiBgaW50ZXJjZXB0b3JgLlxuICAgICAqIFRoZSBwdXJwb3NlIG9mIHRoaXMgbWV0aG9kIGlzIHRvIFwicGFzcyB0aHJ1XCIgdmFsdWVzIHJlcGxhY2luZyBpbnRlcm1lZGlhdGVcbiAgICAgKiByZXN1bHRzIGluIGEgbWV0aG9kIGNoYWluIHNlcXVlbmNlLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDMuMC4wXG4gICAgICogQGNhdGVnb3J5IFNlcVxuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIHByb3ZpZGUgdG8gYGludGVyY2VwdG9yYC5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBpbnRlcmNlcHRvciBUaGUgZnVuY3Rpb24gdG8gaW52b2tlLlxuICAgICAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSByZXN1bHQgb2YgYGludGVyY2VwdG9yYC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXygnICBhYmMgICcpXG4gICAgICogIC5jaGFpbigpXG4gICAgICogIC50cmltKClcbiAgICAgKiAgLnRocnUoZnVuY3Rpb24odmFsdWUpIHtcbiAgICAgKiAgICByZXR1cm4gW3ZhbHVlXTtcbiAgICAgKiAgfSlcbiAgICAgKiAgLnZhbHVlKCk7XG4gICAgICogLy8gPT4gWydhYmMnXVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIHRocnUodmFsdWUsIGludGVyY2VwdG9yKSB7XG4gICAgICByZXR1cm4gaW50ZXJjZXB0b3IodmFsdWUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIGlzIHRoZSB3cmFwcGVyIHZlcnNpb24gb2YgYF8uYXRgLlxuICAgICAqXG4gICAgICogQG5hbWUgYXRcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAxLjAuMFxuICAgICAqIEBjYXRlZ29yeSBTZXFcbiAgICAgKiBAcGFyYW0gey4uLihzdHJpbmd8c3RyaW5nW10pfSBbcGF0aHNdIFRoZSBwcm9wZXJ0eSBwYXRocyB0byBwaWNrLlxuICAgICAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgdGhlIG5ldyBgbG9kYXNoYCB3cmFwcGVyIGluc3RhbmNlLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgb2JqZWN0ID0geyAnYSc6IFt7ICdiJzogeyAnYyc6IDMgfSB9LCA0XSB9O1xuICAgICAqXG4gICAgICogXyhvYmplY3QpLmF0KFsnYVswXS5iLmMnLCAnYVsxXSddKS52YWx1ZSgpO1xuICAgICAqIC8vID0+IFszLCA0XVxuICAgICAqL1xuICAgIHZhciB3cmFwcGVyQXQgPSBmbGF0UmVzdChmdW5jdGlvbihwYXRocykge1xuICAgICAgdmFyIGxlbmd0aCA9IHBhdGhzLmxlbmd0aCxcbiAgICAgICAgICBzdGFydCA9IGxlbmd0aCA/IHBhdGhzWzBdIDogMCxcbiAgICAgICAgICB2YWx1ZSA9IHRoaXMuX193cmFwcGVkX18sXG4gICAgICAgICAgaW50ZXJjZXB0b3IgPSBmdW5jdGlvbihvYmplY3QpIHsgcmV0dXJuIGJhc2VBdChvYmplY3QsIHBhdGhzKTsgfTtcblxuICAgICAgaWYgKGxlbmd0aCA+IDEgfHwgdGhpcy5fX2FjdGlvbnNfXy5sZW5ndGggfHxcbiAgICAgICAgICAhKHZhbHVlIGluc3RhbmNlb2YgTGF6eVdyYXBwZXIpIHx8ICFpc0luZGV4KHN0YXJ0KSkge1xuICAgICAgICByZXR1cm4gdGhpcy50aHJ1KGludGVyY2VwdG9yKTtcbiAgICAgIH1cbiAgICAgIHZhbHVlID0gdmFsdWUuc2xpY2Uoc3RhcnQsICtzdGFydCArIChsZW5ndGggPyAxIDogMCkpO1xuICAgICAgdmFsdWUuX19hY3Rpb25zX18ucHVzaCh7XG4gICAgICAgICdmdW5jJzogdGhydSxcbiAgICAgICAgJ2FyZ3MnOiBbaW50ZXJjZXB0b3JdLFxuICAgICAgICAndGhpc0FyZyc6IHVuZGVmaW5lZFxuICAgICAgfSk7XG4gICAgICByZXR1cm4gbmV3IExvZGFzaFdyYXBwZXIodmFsdWUsIHRoaXMuX19jaGFpbl9fKS50aHJ1KGZ1bmN0aW9uKGFycmF5KSB7XG4gICAgICAgIGlmIChsZW5ndGggJiYgIWFycmF5Lmxlbmd0aCkge1xuICAgICAgICAgIGFycmF5LnB1c2godW5kZWZpbmVkKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gYXJyYXk7XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBgbG9kYXNoYCB3cmFwcGVyIGluc3RhbmNlIHdpdGggZXhwbGljaXQgbWV0aG9kIGNoYWluIHNlcXVlbmNlcyBlbmFibGVkLlxuICAgICAqXG4gICAgICogQG5hbWUgY2hhaW5cbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAwLjEuMFxuICAgICAqIEBjYXRlZ29yeSBTZXFcbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIHRoZSBuZXcgYGxvZGFzaGAgd3JhcHBlciBpbnN0YW5jZS5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIHVzZXJzID0gW1xuICAgICAqICAgeyAndXNlcic6ICdiYXJuZXknLCAnYWdlJzogMzYgfSxcbiAgICAgKiAgIHsgJ3VzZXInOiAnZnJlZCcsICAgJ2FnZSc6IDQwIH1cbiAgICAgKiBdO1xuICAgICAqXG4gICAgICogLy8gQSBzZXF1ZW5jZSB3aXRob3V0IGV4cGxpY2l0IGNoYWluaW5nLlxuICAgICAqIF8odXNlcnMpLmhlYWQoKTtcbiAgICAgKiAvLyA9PiB7ICd1c2VyJzogJ2Jhcm5leScsICdhZ2UnOiAzNiB9XG4gICAgICpcbiAgICAgKiAvLyBBIHNlcXVlbmNlIHdpdGggZXhwbGljaXQgY2hhaW5pbmcuXG4gICAgICogXyh1c2VycylcbiAgICAgKiAgIC5jaGFpbigpXG4gICAgICogICAuaGVhZCgpXG4gICAgICogICAucGljaygndXNlcicpXG4gICAgICogICAudmFsdWUoKTtcbiAgICAgKiAvLyA9PiB7ICd1c2VyJzogJ2Jhcm5leScgfVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIHdyYXBwZXJDaGFpbigpIHtcbiAgICAgIHJldHVybiBjaGFpbih0aGlzKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBFeGVjdXRlcyB0aGUgY2hhaW4gc2VxdWVuY2UgYW5kIHJldHVybnMgdGhlIHdyYXBwZWQgcmVzdWx0LlxuICAgICAqXG4gICAgICogQG5hbWUgY29tbWl0XG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMy4yLjBcbiAgICAgKiBAY2F0ZWdvcnkgU2VxXG4gICAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyB0aGUgbmV3IGBsb2Rhc2hgIHdyYXBwZXIgaW5zdGFuY2UuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciBhcnJheSA9IFsxLCAyXTtcbiAgICAgKiB2YXIgd3JhcHBlZCA9IF8oYXJyYXkpLnB1c2goMyk7XG4gICAgICpcbiAgICAgKiBjb25zb2xlLmxvZyhhcnJheSk7XG4gICAgICogLy8gPT4gWzEsIDJdXG4gICAgICpcbiAgICAgKiB3cmFwcGVkID0gd3JhcHBlZC5jb21taXQoKTtcbiAgICAgKiBjb25zb2xlLmxvZyhhcnJheSk7XG4gICAgICogLy8gPT4gWzEsIDIsIDNdXG4gICAgICpcbiAgICAgKiB3cmFwcGVkLmxhc3QoKTtcbiAgICAgKiAvLyA9PiAzXG4gICAgICpcbiAgICAgKiBjb25zb2xlLmxvZyhhcnJheSk7XG4gICAgICogLy8gPT4gWzEsIDIsIDNdXG4gICAgICovXG4gICAgZnVuY3Rpb24gd3JhcHBlckNvbW1pdCgpIHtcbiAgICAgIHJldHVybiBuZXcgTG9kYXNoV3JhcHBlcih0aGlzLnZhbHVlKCksIHRoaXMuX19jaGFpbl9fKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXRzIHRoZSBuZXh0IHZhbHVlIG9uIGEgd3JhcHBlZCBvYmplY3QgZm9sbG93aW5nIHRoZVxuICAgICAqIFtpdGVyYXRvciBwcm90b2NvbF0oaHR0cHM6Ly9tZG4uaW8vaXRlcmF0aW9uX3Byb3RvY29scyNpdGVyYXRvcikuXG4gICAgICpcbiAgICAgKiBAbmFtZSBuZXh0XG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgU2VxXG4gICAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyB0aGUgbmV4dCBpdGVyYXRvciB2YWx1ZS5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIHdyYXBwZWQgPSBfKFsxLCAyXSk7XG4gICAgICpcbiAgICAgKiB3cmFwcGVkLm5leHQoKTtcbiAgICAgKiAvLyA9PiB7ICdkb25lJzogZmFsc2UsICd2YWx1ZSc6IDEgfVxuICAgICAqXG4gICAgICogd3JhcHBlZC5uZXh0KCk7XG4gICAgICogLy8gPT4geyAnZG9uZSc6IGZhbHNlLCAndmFsdWUnOiAyIH1cbiAgICAgKlxuICAgICAqIHdyYXBwZWQubmV4dCgpO1xuICAgICAqIC8vID0+IHsgJ2RvbmUnOiB0cnVlLCAndmFsdWUnOiB1bmRlZmluZWQgfVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIHdyYXBwZXJOZXh0KCkge1xuICAgICAgaWYgKHRoaXMuX192YWx1ZXNfXyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHRoaXMuX192YWx1ZXNfXyA9IHRvQXJyYXkodGhpcy52YWx1ZSgpKTtcbiAgICAgIH1cbiAgICAgIHZhciBkb25lID0gdGhpcy5fX2luZGV4X18gPj0gdGhpcy5fX3ZhbHVlc19fLmxlbmd0aCxcbiAgICAgICAgICB2YWx1ZSA9IGRvbmUgPyB1bmRlZmluZWQgOiB0aGlzLl9fdmFsdWVzX19bdGhpcy5fX2luZGV4X18rK107XG5cbiAgICAgIHJldHVybiB7ICdkb25lJzogZG9uZSwgJ3ZhbHVlJzogdmFsdWUgfTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBFbmFibGVzIHRoZSB3cmFwcGVyIHRvIGJlIGl0ZXJhYmxlLlxuICAgICAqXG4gICAgICogQG5hbWUgU3ltYm9sLml0ZXJhdG9yXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgU2VxXG4gICAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyB0aGUgd3JhcHBlciBvYmplY3QuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciB3cmFwcGVkID0gXyhbMSwgMl0pO1xuICAgICAqXG4gICAgICogd3JhcHBlZFtTeW1ib2wuaXRlcmF0b3JdKCkgPT09IHdyYXBwZWQ7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqXG4gICAgICogQXJyYXkuZnJvbSh3cmFwcGVkKTtcbiAgICAgKiAvLyA9PiBbMSwgMl1cbiAgICAgKi9cbiAgICBmdW5jdGlvbiB3cmFwcGVyVG9JdGVyYXRvcigpIHtcbiAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBjbG9uZSBvZiB0aGUgY2hhaW4gc2VxdWVuY2UgcGxhbnRpbmcgYHZhbHVlYCBhcyB0aGUgd3JhcHBlZCB2YWx1ZS5cbiAgICAgKlxuICAgICAqIEBuYW1lIHBsYW50XG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMy4yLjBcbiAgICAgKiBAY2F0ZWdvcnkgU2VxXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gcGxhbnQuXG4gICAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyB0aGUgbmV3IGBsb2Rhc2hgIHdyYXBwZXIgaW5zdGFuY2UuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIGZ1bmN0aW9uIHNxdWFyZShuKSB7XG4gICAgICogICByZXR1cm4gbiAqIG47XG4gICAgICogfVxuICAgICAqXG4gICAgICogdmFyIHdyYXBwZWQgPSBfKFsxLCAyXSkubWFwKHNxdWFyZSk7XG4gICAgICogdmFyIG90aGVyID0gd3JhcHBlZC5wbGFudChbMywgNF0pO1xuICAgICAqXG4gICAgICogb3RoZXIudmFsdWUoKTtcbiAgICAgKiAvLyA9PiBbOSwgMTZdXG4gICAgICpcbiAgICAgKiB3cmFwcGVkLnZhbHVlKCk7XG4gICAgICogLy8gPT4gWzEsIDRdXG4gICAgICovXG4gICAgZnVuY3Rpb24gd3JhcHBlclBsYW50KHZhbHVlKSB7XG4gICAgICB2YXIgcmVzdWx0LFxuICAgICAgICAgIHBhcmVudCA9IHRoaXM7XG5cbiAgICAgIHdoaWxlIChwYXJlbnQgaW5zdGFuY2VvZiBiYXNlTG9kYXNoKSB7XG4gICAgICAgIHZhciBjbG9uZSA9IHdyYXBwZXJDbG9uZShwYXJlbnQpO1xuICAgICAgICBjbG9uZS5fX2luZGV4X18gPSAwO1xuICAgICAgICBjbG9uZS5fX3ZhbHVlc19fID0gdW5kZWZpbmVkO1xuICAgICAgICBpZiAocmVzdWx0KSB7XG4gICAgICAgICAgcHJldmlvdXMuX193cmFwcGVkX18gPSBjbG9uZTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXN1bHQgPSBjbG9uZTtcbiAgICAgICAgfVxuICAgICAgICB2YXIgcHJldmlvdXMgPSBjbG9uZTtcbiAgICAgICAgcGFyZW50ID0gcGFyZW50Ll9fd3JhcHBlZF9fO1xuICAgICAgfVxuICAgICAgcHJldmlvdXMuX193cmFwcGVkX18gPSB2YWx1ZTtcbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgaXMgdGhlIHdyYXBwZXIgdmVyc2lvbiBvZiBgXy5yZXZlcnNlYC5cbiAgICAgKlxuICAgICAqICoqTm90ZToqKiBUaGlzIG1ldGhvZCBtdXRhdGVzIHRoZSB3cmFwcGVkIGFycmF5LlxuICAgICAqXG4gICAgICogQG5hbWUgcmV2ZXJzZVxuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDAuMS4wXG4gICAgICogQGNhdGVnb3J5IFNlcVxuICAgICAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgdGhlIG5ldyBgbG9kYXNoYCB3cmFwcGVyIGluc3RhbmNlLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgYXJyYXkgPSBbMSwgMiwgM107XG4gICAgICpcbiAgICAgKiBfKGFycmF5KS5yZXZlcnNlKCkudmFsdWUoKVxuICAgICAqIC8vID0+IFszLCAyLCAxXVxuICAgICAqXG4gICAgICogY29uc29sZS5sb2coYXJyYXkpO1xuICAgICAqIC8vID0+IFszLCAyLCAxXVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIHdyYXBwZXJSZXZlcnNlKCkge1xuICAgICAgdmFyIHZhbHVlID0gdGhpcy5fX3dyYXBwZWRfXztcbiAgICAgIGlmICh2YWx1ZSBpbnN0YW5jZW9mIExhenlXcmFwcGVyKSB7XG4gICAgICAgIHZhciB3cmFwcGVkID0gdmFsdWU7XG4gICAgICAgIGlmICh0aGlzLl9fYWN0aW9uc19fLmxlbmd0aCkge1xuICAgICAgICAgIHdyYXBwZWQgPSBuZXcgTGF6eVdyYXBwZXIodGhpcyk7XG4gICAgICAgIH1cbiAgICAgICAgd3JhcHBlZCA9IHdyYXBwZWQucmV2ZXJzZSgpO1xuICAgICAgICB3cmFwcGVkLl9fYWN0aW9uc19fLnB1c2goe1xuICAgICAgICAgICdmdW5jJzogdGhydSxcbiAgICAgICAgICAnYXJncyc6IFtyZXZlcnNlXSxcbiAgICAgICAgICAndGhpc0FyZyc6IHVuZGVmaW5lZFxuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIG5ldyBMb2Rhc2hXcmFwcGVyKHdyYXBwZWQsIHRoaXMuX19jaGFpbl9fKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiB0aGlzLnRocnUocmV2ZXJzZSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRXhlY3V0ZXMgdGhlIGNoYWluIHNlcXVlbmNlIHRvIHJlc29sdmUgdGhlIHVud3JhcHBlZCB2YWx1ZS5cbiAgICAgKlxuICAgICAqIEBuYW1lIHZhbHVlXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMC4xLjBcbiAgICAgKiBAYWxpYXMgdG9KU09OLCB2YWx1ZU9mXG4gICAgICogQGNhdGVnb3J5IFNlcVxuICAgICAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSByZXNvbHZlZCB1bndyYXBwZWQgdmFsdWUuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8oWzEsIDIsIDNdKS52YWx1ZSgpO1xuICAgICAqIC8vID0+IFsxLCAyLCAzXVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIHdyYXBwZXJWYWx1ZSgpIHtcbiAgICAgIHJldHVybiBiYXNlV3JhcHBlclZhbHVlKHRoaXMuX193cmFwcGVkX18sIHRoaXMuX19hY3Rpb25zX18pO1xuICAgIH1cblxuICAgIC8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi9cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYW4gb2JqZWN0IGNvbXBvc2VkIG9mIGtleXMgZ2VuZXJhdGVkIGZyb20gdGhlIHJlc3VsdHMgb2YgcnVubmluZ1xuICAgICAqIGVhY2ggZWxlbWVudCBvZiBgY29sbGVjdGlvbmAgdGhydSBgaXRlcmF0ZWVgLiBUaGUgY29ycmVzcG9uZGluZyB2YWx1ZSBvZlxuICAgICAqIGVhY2gga2V5IGlzIHRoZSBudW1iZXIgb2YgdGltZXMgdGhlIGtleSB3YXMgcmV0dXJuZWQgYnkgYGl0ZXJhdGVlYC4gVGhlXG4gICAgICogaXRlcmF0ZWUgaXMgaW52b2tlZCB3aXRoIG9uZSBhcmd1bWVudDogKHZhbHVlKS5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAwLjUuMFxuICAgICAqIEBjYXRlZ29yeSBDb2xsZWN0aW9uXG4gICAgICogQHBhcmFtIHtBcnJheXxPYmplY3R9IGNvbGxlY3Rpb24gVGhlIGNvbGxlY3Rpb24gdG8gaXRlcmF0ZSBvdmVyLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IFtpdGVyYXRlZT1fLmlkZW50aXR5XSBUaGUgaXRlcmF0ZWUgdG8gdHJhbnNmb3JtIGtleXMuXG4gICAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyB0aGUgY29tcG9zZWQgYWdncmVnYXRlIG9iamVjdC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5jb3VudEJ5KFs2LjEsIDQuMiwgNi4zXSwgTWF0aC5mbG9vcik7XG4gICAgICogLy8gPT4geyAnNCc6IDEsICc2JzogMiB9XG4gICAgICpcbiAgICAgKiAvLyBUaGUgYF8ucHJvcGVydHlgIGl0ZXJhdGVlIHNob3J0aGFuZC5cbiAgICAgKiBfLmNvdW50QnkoWydvbmUnLCAndHdvJywgJ3RocmVlJ10sICdsZW5ndGgnKTtcbiAgICAgKiAvLyA9PiB7ICczJzogMiwgJzUnOiAxIH1cbiAgICAgKi9cbiAgICB2YXIgY291bnRCeSA9IGNyZWF0ZUFnZ3JlZ2F0b3IoZnVuY3Rpb24ocmVzdWx0LCB2YWx1ZSwga2V5KSB7XG4gICAgICBpZiAoaGFzT3duUHJvcGVydHkuY2FsbChyZXN1bHQsIGtleSkpIHtcbiAgICAgICAgKytyZXN1bHRba2V5XTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGJhc2VBc3NpZ25WYWx1ZShyZXN1bHQsIGtleSwgMSk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICAvKipcbiAgICAgKiBDaGVja3MgaWYgYHByZWRpY2F0ZWAgcmV0dXJucyB0cnV0aHkgZm9yICoqYWxsKiogZWxlbWVudHMgb2YgYGNvbGxlY3Rpb25gLlxuICAgICAqIEl0ZXJhdGlvbiBpcyBzdG9wcGVkIG9uY2UgYHByZWRpY2F0ZWAgcmV0dXJucyBmYWxzZXkuIFRoZSBwcmVkaWNhdGUgaXNcbiAgICAgKiBpbnZva2VkIHdpdGggdGhyZWUgYXJndW1lbnRzOiAodmFsdWUsIGluZGV4fGtleSwgY29sbGVjdGlvbikuXG4gICAgICpcbiAgICAgKiAqKk5vdGU6KiogVGhpcyBtZXRob2QgcmV0dXJucyBgdHJ1ZWAgZm9yXG4gICAgICogW2VtcHR5IGNvbGxlY3Rpb25zXShodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9FbXB0eV9zZXQpIGJlY2F1c2VcbiAgICAgKiBbZXZlcnl0aGluZyBpcyB0cnVlXShodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9WYWN1b3VzX3RydXRoKSBvZlxuICAgICAqIGVsZW1lbnRzIG9mIGVtcHR5IGNvbGxlY3Rpb25zLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDAuMS4wXG4gICAgICogQGNhdGVnb3J5IENvbGxlY3Rpb25cbiAgICAgKiBAcGFyYW0ge0FycmF5fE9iamVjdH0gY29sbGVjdGlvbiBUaGUgY29sbGVjdGlvbiB0byBpdGVyYXRlIG92ZXIuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW3ByZWRpY2F0ZT1fLmlkZW50aXR5XSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICAgICAqIEBwYXJhbS0ge09iamVjdH0gW2d1YXJkXSBFbmFibGVzIHVzZSBhcyBhbiBpdGVyYXRlZSBmb3IgbWV0aG9kcyBsaWtlIGBfLm1hcGAuXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGFsbCBlbGVtZW50cyBwYXNzIHRoZSBwcmVkaWNhdGUgY2hlY2ssXG4gICAgICogIGVsc2UgYGZhbHNlYC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5ldmVyeShbdHJ1ZSwgMSwgbnVsbCwgJ3llcyddLCBCb29sZWFuKTtcbiAgICAgKiAvLyA9PiBmYWxzZVxuICAgICAqXG4gICAgICogdmFyIHVzZXJzID0gW1xuICAgICAqICAgeyAndXNlcic6ICdiYXJuZXknLCAnYWdlJzogMzYsICdhY3RpdmUnOiBmYWxzZSB9LFxuICAgICAqICAgeyAndXNlcic6ICdmcmVkJywgICAnYWdlJzogNDAsICdhY3RpdmUnOiBmYWxzZSB9XG4gICAgICogXTtcbiAgICAgKlxuICAgICAqIC8vIFRoZSBgXy5tYXRjaGVzYCBpdGVyYXRlZSBzaG9ydGhhbmQuXG4gICAgICogXy5ldmVyeSh1c2VycywgeyAndXNlcic6ICdiYXJuZXknLCAnYWN0aXZlJzogZmFsc2UgfSk7XG4gICAgICogLy8gPT4gZmFsc2VcbiAgICAgKlxuICAgICAqIC8vIFRoZSBgXy5tYXRjaGVzUHJvcGVydHlgIGl0ZXJhdGVlIHNob3J0aGFuZC5cbiAgICAgKiBfLmV2ZXJ5KHVzZXJzLCBbJ2FjdGl2ZScsIGZhbHNlXSk7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqXG4gICAgICogLy8gVGhlIGBfLnByb3BlcnR5YCBpdGVyYXRlZSBzaG9ydGhhbmQuXG4gICAgICogXy5ldmVyeSh1c2VycywgJ2FjdGl2ZScpO1xuICAgICAqIC8vID0+IGZhbHNlXG4gICAgICovXG4gICAgZnVuY3Rpb24gZXZlcnkoY29sbGVjdGlvbiwgcHJlZGljYXRlLCBndWFyZCkge1xuICAgICAgdmFyIGZ1bmMgPSBpc0FycmF5KGNvbGxlY3Rpb24pID8gYXJyYXlFdmVyeSA6IGJhc2VFdmVyeTtcbiAgICAgIGlmIChndWFyZCAmJiBpc0l0ZXJhdGVlQ2FsbChjb2xsZWN0aW9uLCBwcmVkaWNhdGUsIGd1YXJkKSkge1xuICAgICAgICBwcmVkaWNhdGUgPSB1bmRlZmluZWQ7XG4gICAgICB9XG4gICAgICByZXR1cm4gZnVuYyhjb2xsZWN0aW9uLCBnZXRJdGVyYXRlZShwcmVkaWNhdGUsIDMpKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBJdGVyYXRlcyBvdmVyIGVsZW1lbnRzIG9mIGBjb2xsZWN0aW9uYCwgcmV0dXJuaW5nIGFuIGFycmF5IG9mIGFsbCBlbGVtZW50c1xuICAgICAqIGBwcmVkaWNhdGVgIHJldHVybnMgdHJ1dGh5IGZvci4gVGhlIHByZWRpY2F0ZSBpcyBpbnZva2VkIHdpdGggdGhyZWVcbiAgICAgKiBhcmd1bWVudHM6ICh2YWx1ZSwgaW5kZXh8a2V5LCBjb2xsZWN0aW9uKS5cbiAgICAgKlxuICAgICAqICoqTm90ZToqKiBVbmxpa2UgYF8ucmVtb3ZlYCwgdGhpcyBtZXRob2QgcmV0dXJucyBhIG5ldyBhcnJheS5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAwLjEuMFxuICAgICAqIEBjYXRlZ29yeSBDb2xsZWN0aW9uXG4gICAgICogQHBhcmFtIHtBcnJheXxPYmplY3R9IGNvbGxlY3Rpb24gVGhlIGNvbGxlY3Rpb24gdG8gaXRlcmF0ZSBvdmVyLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IFtwcmVkaWNhdGU9Xy5pZGVudGl0eV0gVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIGl0ZXJhdGlvbi5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIG5ldyBmaWx0ZXJlZCBhcnJheS5cbiAgICAgKiBAc2VlIF8ucmVqZWN0XG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciB1c2VycyA9IFtcbiAgICAgKiAgIHsgJ3VzZXInOiAnYmFybmV5JywgJ2FnZSc6IDM2LCAnYWN0aXZlJzogdHJ1ZSB9LFxuICAgICAqICAgeyAndXNlcic6ICdmcmVkJywgICAnYWdlJzogNDAsICdhY3RpdmUnOiBmYWxzZSB9XG4gICAgICogXTtcbiAgICAgKlxuICAgICAqIF8uZmlsdGVyKHVzZXJzLCBmdW5jdGlvbihvKSB7IHJldHVybiAhby5hY3RpdmU7IH0pO1xuICAgICAqIC8vID0+IG9iamVjdHMgZm9yIFsnZnJlZCddXG4gICAgICpcbiAgICAgKiAvLyBUaGUgYF8ubWF0Y2hlc2AgaXRlcmF0ZWUgc2hvcnRoYW5kLlxuICAgICAqIF8uZmlsdGVyKHVzZXJzLCB7ICdhZ2UnOiAzNiwgJ2FjdGl2ZSc6IHRydWUgfSk7XG4gICAgICogLy8gPT4gb2JqZWN0cyBmb3IgWydiYXJuZXknXVxuICAgICAqXG4gICAgICogLy8gVGhlIGBfLm1hdGNoZXNQcm9wZXJ0eWAgaXRlcmF0ZWUgc2hvcnRoYW5kLlxuICAgICAqIF8uZmlsdGVyKHVzZXJzLCBbJ2FjdGl2ZScsIGZhbHNlXSk7XG4gICAgICogLy8gPT4gb2JqZWN0cyBmb3IgWydmcmVkJ11cbiAgICAgKlxuICAgICAqIC8vIFRoZSBgXy5wcm9wZXJ0eWAgaXRlcmF0ZWUgc2hvcnRoYW5kLlxuICAgICAqIF8uZmlsdGVyKHVzZXJzLCAnYWN0aXZlJyk7XG4gICAgICogLy8gPT4gb2JqZWN0cyBmb3IgWydiYXJuZXknXVxuICAgICAqXG4gICAgICogLy8gQ29tYmluaW5nIHNldmVyYWwgcHJlZGljYXRlcyB1c2luZyBgXy5vdmVyRXZlcnlgIG9yIGBfLm92ZXJTb21lYC5cbiAgICAgKiBfLmZpbHRlcih1c2VycywgXy5vdmVyU29tZShbeyAnYWdlJzogMzYgfSwgWydhZ2UnLCA0MF1dKSk7XG4gICAgICogLy8gPT4gb2JqZWN0cyBmb3IgWydmcmVkJywgJ2Jhcm5leSddXG4gICAgICovXG4gICAgZnVuY3Rpb24gZmlsdGVyKGNvbGxlY3Rpb24sIHByZWRpY2F0ZSkge1xuICAgICAgdmFyIGZ1bmMgPSBpc0FycmF5KGNvbGxlY3Rpb24pID8gYXJyYXlGaWx0ZXIgOiBiYXNlRmlsdGVyO1xuICAgICAgcmV0dXJuIGZ1bmMoY29sbGVjdGlvbiwgZ2V0SXRlcmF0ZWUocHJlZGljYXRlLCAzKSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogSXRlcmF0ZXMgb3ZlciBlbGVtZW50cyBvZiBgY29sbGVjdGlvbmAsIHJldHVybmluZyB0aGUgZmlyc3QgZWxlbWVudFxuICAgICAqIGBwcmVkaWNhdGVgIHJldHVybnMgdHJ1dGh5IGZvci4gVGhlIHByZWRpY2F0ZSBpcyBpbnZva2VkIHdpdGggdGhyZWVcbiAgICAgKiBhcmd1bWVudHM6ICh2YWx1ZSwgaW5kZXh8a2V5LCBjb2xsZWN0aW9uKS5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAwLjEuMFxuICAgICAqIEBjYXRlZ29yeSBDb2xsZWN0aW9uXG4gICAgICogQHBhcmFtIHtBcnJheXxPYmplY3R9IGNvbGxlY3Rpb24gVGhlIGNvbGxlY3Rpb24gdG8gaW5zcGVjdC5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbcHJlZGljYXRlPV8uaWRlbnRpdHldIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtmcm9tSW5kZXg9MF0gVGhlIGluZGV4IHRvIHNlYXJjaCBmcm9tLlxuICAgICAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSBtYXRjaGVkIGVsZW1lbnQsIGVsc2UgYHVuZGVmaW5lZGAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciB1c2VycyA9IFtcbiAgICAgKiAgIHsgJ3VzZXInOiAnYmFybmV5JywgICdhZ2UnOiAzNiwgJ2FjdGl2ZSc6IHRydWUgfSxcbiAgICAgKiAgIHsgJ3VzZXInOiAnZnJlZCcsICAgICdhZ2UnOiA0MCwgJ2FjdGl2ZSc6IGZhbHNlIH0sXG4gICAgICogICB7ICd1c2VyJzogJ3BlYmJsZXMnLCAnYWdlJzogMSwgICdhY3RpdmUnOiB0cnVlIH1cbiAgICAgKiBdO1xuICAgICAqXG4gICAgICogXy5maW5kKHVzZXJzLCBmdW5jdGlvbihvKSB7IHJldHVybiBvLmFnZSA8IDQwOyB9KTtcbiAgICAgKiAvLyA9PiBvYmplY3QgZm9yICdiYXJuZXknXG4gICAgICpcbiAgICAgKiAvLyBUaGUgYF8ubWF0Y2hlc2AgaXRlcmF0ZWUgc2hvcnRoYW5kLlxuICAgICAqIF8uZmluZCh1c2VycywgeyAnYWdlJzogMSwgJ2FjdGl2ZSc6IHRydWUgfSk7XG4gICAgICogLy8gPT4gb2JqZWN0IGZvciAncGViYmxlcydcbiAgICAgKlxuICAgICAqIC8vIFRoZSBgXy5tYXRjaGVzUHJvcGVydHlgIGl0ZXJhdGVlIHNob3J0aGFuZC5cbiAgICAgKiBfLmZpbmQodXNlcnMsIFsnYWN0aXZlJywgZmFsc2VdKTtcbiAgICAgKiAvLyA9PiBvYmplY3QgZm9yICdmcmVkJ1xuICAgICAqXG4gICAgICogLy8gVGhlIGBfLnByb3BlcnR5YCBpdGVyYXRlZSBzaG9ydGhhbmQuXG4gICAgICogXy5maW5kKHVzZXJzLCAnYWN0aXZlJyk7XG4gICAgICogLy8gPT4gb2JqZWN0IGZvciAnYmFybmV5J1xuICAgICAqL1xuICAgIHZhciBmaW5kID0gY3JlYXRlRmluZChmaW5kSW5kZXgpO1xuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgaXMgbGlrZSBgXy5maW5kYCBleGNlcHQgdGhhdCBpdCBpdGVyYXRlcyBvdmVyIGVsZW1lbnRzIG9mXG4gICAgICogYGNvbGxlY3Rpb25gIGZyb20gcmlnaHQgdG8gbGVmdC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAyLjAuMFxuICAgICAqIEBjYXRlZ29yeSBDb2xsZWN0aW9uXG4gICAgICogQHBhcmFtIHtBcnJheXxPYmplY3R9IGNvbGxlY3Rpb24gVGhlIGNvbGxlY3Rpb24gdG8gaW5zcGVjdC5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbcHJlZGljYXRlPV8uaWRlbnRpdHldIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtmcm9tSW5kZXg9Y29sbGVjdGlvbi5sZW5ndGgtMV0gVGhlIGluZGV4IHRvIHNlYXJjaCBmcm9tLlxuICAgICAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSBtYXRjaGVkIGVsZW1lbnQsIGVsc2UgYHVuZGVmaW5lZGAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uZmluZExhc3QoWzEsIDIsIDMsIDRdLCBmdW5jdGlvbihuKSB7XG4gICAgICogICByZXR1cm4gbiAlIDIgPT0gMTtcbiAgICAgKiB9KTtcbiAgICAgKiAvLyA9PiAzXG4gICAgICovXG4gICAgdmFyIGZpbmRMYXN0ID0gY3JlYXRlRmluZChmaW5kTGFzdEluZGV4KTtcblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBmbGF0dGVuZWQgYXJyYXkgb2YgdmFsdWVzIGJ5IHJ1bm5pbmcgZWFjaCBlbGVtZW50IGluIGBjb2xsZWN0aW9uYFxuICAgICAqIHRocnUgYGl0ZXJhdGVlYCBhbmQgZmxhdHRlbmluZyB0aGUgbWFwcGVkIHJlc3VsdHMuIFRoZSBpdGVyYXRlZSBpcyBpbnZva2VkXG4gICAgICogd2l0aCB0aHJlZSBhcmd1bWVudHM6ICh2YWx1ZSwgaW5kZXh8a2V5LCBjb2xsZWN0aW9uKS5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjAuMFxuICAgICAqIEBjYXRlZ29yeSBDb2xsZWN0aW9uXG4gICAgICogQHBhcmFtIHtBcnJheXxPYmplY3R9IGNvbGxlY3Rpb24gVGhlIGNvbGxlY3Rpb24gdG8gaXRlcmF0ZSBvdmVyLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IFtpdGVyYXRlZT1fLmlkZW50aXR5XSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IGZsYXR0ZW5lZCBhcnJheS5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogZnVuY3Rpb24gZHVwbGljYXRlKG4pIHtcbiAgICAgKiAgIHJldHVybiBbbiwgbl07XG4gICAgICogfVxuICAgICAqXG4gICAgICogXy5mbGF0TWFwKFsxLCAyXSwgZHVwbGljYXRlKTtcbiAgICAgKiAvLyA9PiBbMSwgMSwgMiwgMl1cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBmbGF0TWFwKGNvbGxlY3Rpb24sIGl0ZXJhdGVlKSB7XG4gICAgICByZXR1cm4gYmFzZUZsYXR0ZW4obWFwKGNvbGxlY3Rpb24sIGl0ZXJhdGVlKSwgMSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgaXMgbGlrZSBgXy5mbGF0TWFwYCBleGNlcHQgdGhhdCBpdCByZWN1cnNpdmVseSBmbGF0dGVucyB0aGVcbiAgICAgKiBtYXBwZWQgcmVzdWx0cy5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjcuMFxuICAgICAqIEBjYXRlZ29yeSBDb2xsZWN0aW9uXG4gICAgICogQHBhcmFtIHtBcnJheXxPYmplY3R9IGNvbGxlY3Rpb24gVGhlIGNvbGxlY3Rpb24gdG8gaXRlcmF0ZSBvdmVyLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IFtpdGVyYXRlZT1fLmlkZW50aXR5XSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IGZsYXR0ZW5lZCBhcnJheS5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogZnVuY3Rpb24gZHVwbGljYXRlKG4pIHtcbiAgICAgKiAgIHJldHVybiBbW1tuLCBuXV1dO1xuICAgICAqIH1cbiAgICAgKlxuICAgICAqIF8uZmxhdE1hcERlZXAoWzEsIDJdLCBkdXBsaWNhdGUpO1xuICAgICAqIC8vID0+IFsxLCAxLCAyLCAyXVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGZsYXRNYXBEZWVwKGNvbGxlY3Rpb24sIGl0ZXJhdGVlKSB7XG4gICAgICByZXR1cm4gYmFzZUZsYXR0ZW4obWFwKGNvbGxlY3Rpb24sIGl0ZXJhdGVlKSwgSU5GSU5JVFkpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIGlzIGxpa2UgYF8uZmxhdE1hcGAgZXhjZXB0IHRoYXQgaXQgcmVjdXJzaXZlbHkgZmxhdHRlbnMgdGhlXG4gICAgICogbWFwcGVkIHJlc3VsdHMgdXAgdG8gYGRlcHRoYCB0aW1lcy5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjcuMFxuICAgICAqIEBjYXRlZ29yeSBDb2xsZWN0aW9uXG4gICAgICogQHBhcmFtIHtBcnJheXxPYmplY3R9IGNvbGxlY3Rpb24gVGhlIGNvbGxlY3Rpb24gdG8gaXRlcmF0ZSBvdmVyLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IFtpdGVyYXRlZT1fLmlkZW50aXR5XSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbZGVwdGg9MV0gVGhlIG1heGltdW0gcmVjdXJzaW9uIGRlcHRoLlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IGZsYXR0ZW5lZCBhcnJheS5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogZnVuY3Rpb24gZHVwbGljYXRlKG4pIHtcbiAgICAgKiAgIHJldHVybiBbW1tuLCBuXV1dO1xuICAgICAqIH1cbiAgICAgKlxuICAgICAqIF8uZmxhdE1hcERlcHRoKFsxLCAyXSwgZHVwbGljYXRlLCAyKTtcbiAgICAgKiAvLyA9PiBbWzEsIDFdLCBbMiwgMl1dXG4gICAgICovXG4gICAgZnVuY3Rpb24gZmxhdE1hcERlcHRoKGNvbGxlY3Rpb24sIGl0ZXJhdGVlLCBkZXB0aCkge1xuICAgICAgZGVwdGggPSBkZXB0aCA9PT0gdW5kZWZpbmVkID8gMSA6IHRvSW50ZWdlcihkZXB0aCk7XG4gICAgICByZXR1cm4gYmFzZUZsYXR0ZW4obWFwKGNvbGxlY3Rpb24sIGl0ZXJhdGVlKSwgZGVwdGgpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEl0ZXJhdGVzIG92ZXIgZWxlbWVudHMgb2YgYGNvbGxlY3Rpb25gIGFuZCBpbnZva2VzIGBpdGVyYXRlZWAgZm9yIGVhY2ggZWxlbWVudC5cbiAgICAgKiBUaGUgaXRlcmF0ZWUgaXMgaW52b2tlZCB3aXRoIHRocmVlIGFyZ3VtZW50czogKHZhbHVlLCBpbmRleHxrZXksIGNvbGxlY3Rpb24pLlxuICAgICAqIEl0ZXJhdGVlIGZ1bmN0aW9ucyBtYXkgZXhpdCBpdGVyYXRpb24gZWFybHkgYnkgZXhwbGljaXRseSByZXR1cm5pbmcgYGZhbHNlYC5cbiAgICAgKlxuICAgICAqICoqTm90ZToqKiBBcyB3aXRoIG90aGVyIFwiQ29sbGVjdGlvbnNcIiBtZXRob2RzLCBvYmplY3RzIHdpdGggYSBcImxlbmd0aFwiXG4gICAgICogcHJvcGVydHkgYXJlIGl0ZXJhdGVkIGxpa2UgYXJyYXlzLiBUbyBhdm9pZCB0aGlzIGJlaGF2aW9yIHVzZSBgXy5mb3JJbmBcbiAgICAgKiBvciBgXy5mb3JPd25gIGZvciBvYmplY3QgaXRlcmF0aW9uLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDAuMS4wXG4gICAgICogQGFsaWFzIGVhY2hcbiAgICAgKiBAY2F0ZWdvcnkgQ29sbGVjdGlvblxuICAgICAqIEBwYXJhbSB7QXJyYXl8T2JqZWN0fSBjb2xsZWN0aW9uIFRoZSBjb2xsZWN0aW9uIHRvIGl0ZXJhdGUgb3Zlci5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbaXRlcmF0ZWU9Xy5pZGVudGl0eV0gVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIGl0ZXJhdGlvbi5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl8T2JqZWN0fSBSZXR1cm5zIGBjb2xsZWN0aW9uYC5cbiAgICAgKiBAc2VlIF8uZm9yRWFjaFJpZ2h0XG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uZm9yRWFjaChbMSwgMl0sIGZ1bmN0aW9uKHZhbHVlKSB7XG4gICAgICogICBjb25zb2xlLmxvZyh2YWx1ZSk7XG4gICAgICogfSk7XG4gICAgICogLy8gPT4gTG9ncyBgMWAgdGhlbiBgMmAuXG4gICAgICpcbiAgICAgKiBfLmZvckVhY2goeyAnYSc6IDEsICdiJzogMiB9LCBmdW5jdGlvbih2YWx1ZSwga2V5KSB7XG4gICAgICogICBjb25zb2xlLmxvZyhrZXkpO1xuICAgICAqIH0pO1xuICAgICAqIC8vID0+IExvZ3MgJ2EnIHRoZW4gJ2InIChpdGVyYXRpb24gb3JkZXIgaXMgbm90IGd1YXJhbnRlZWQpLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGZvckVhY2goY29sbGVjdGlvbiwgaXRlcmF0ZWUpIHtcbiAgICAgIHZhciBmdW5jID0gaXNBcnJheShjb2xsZWN0aW9uKSA/IGFycmF5RWFjaCA6IGJhc2VFYWNoO1xuICAgICAgcmV0dXJuIGZ1bmMoY29sbGVjdGlvbiwgZ2V0SXRlcmF0ZWUoaXRlcmF0ZWUsIDMpKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIG1ldGhvZCBpcyBsaWtlIGBfLmZvckVhY2hgIGV4Y2VwdCB0aGF0IGl0IGl0ZXJhdGVzIG92ZXIgZWxlbWVudHMgb2ZcbiAgICAgKiBgY29sbGVjdGlvbmAgZnJvbSByaWdodCB0byBsZWZ0LlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDIuMC4wXG4gICAgICogQGFsaWFzIGVhY2hSaWdodFxuICAgICAqIEBjYXRlZ29yeSBDb2xsZWN0aW9uXG4gICAgICogQHBhcmFtIHtBcnJheXxPYmplY3R9IGNvbGxlY3Rpb24gVGhlIGNvbGxlY3Rpb24gdG8gaXRlcmF0ZSBvdmVyLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IFtpdGVyYXRlZT1fLmlkZW50aXR5XSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICAgICAqIEByZXR1cm5zIHtBcnJheXxPYmplY3R9IFJldHVybnMgYGNvbGxlY3Rpb25gLlxuICAgICAqIEBzZWUgXy5mb3JFYWNoXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uZm9yRWFjaFJpZ2h0KFsxLCAyXSwgZnVuY3Rpb24odmFsdWUpIHtcbiAgICAgKiAgIGNvbnNvbGUubG9nKHZhbHVlKTtcbiAgICAgKiB9KTtcbiAgICAgKiAvLyA9PiBMb2dzIGAyYCB0aGVuIGAxYC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBmb3JFYWNoUmlnaHQoY29sbGVjdGlvbiwgaXRlcmF0ZWUpIHtcbiAgICAgIHZhciBmdW5jID0gaXNBcnJheShjb2xsZWN0aW9uKSA/IGFycmF5RWFjaFJpZ2h0IDogYmFzZUVhY2hSaWdodDtcbiAgICAgIHJldHVybiBmdW5jKGNvbGxlY3Rpb24sIGdldEl0ZXJhdGVlKGl0ZXJhdGVlLCAzKSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhbiBvYmplY3QgY29tcG9zZWQgb2Yga2V5cyBnZW5lcmF0ZWQgZnJvbSB0aGUgcmVzdWx0cyBvZiBydW5uaW5nXG4gICAgICogZWFjaCBlbGVtZW50IG9mIGBjb2xsZWN0aW9uYCB0aHJ1IGBpdGVyYXRlZWAuIFRoZSBvcmRlciBvZiBncm91cGVkIHZhbHVlc1xuICAgICAqIGlzIGRldGVybWluZWQgYnkgdGhlIG9yZGVyIHRoZXkgb2NjdXIgaW4gYGNvbGxlY3Rpb25gLiBUaGUgY29ycmVzcG9uZGluZ1xuICAgICAqIHZhbHVlIG9mIGVhY2gga2V5IGlzIGFuIGFycmF5IG9mIGVsZW1lbnRzIHJlc3BvbnNpYmxlIGZvciBnZW5lcmF0aW5nIHRoZVxuICAgICAqIGtleS4gVGhlIGl0ZXJhdGVlIGlzIGludm9rZWQgd2l0aCBvbmUgYXJndW1lbnQ6ICh2YWx1ZSkuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMC4xLjBcbiAgICAgKiBAY2F0ZWdvcnkgQ29sbGVjdGlvblxuICAgICAqIEBwYXJhbSB7QXJyYXl8T2JqZWN0fSBjb2xsZWN0aW9uIFRoZSBjb2xsZWN0aW9uIHRvIGl0ZXJhdGUgb3Zlci5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbaXRlcmF0ZWU9Xy5pZGVudGl0eV0gVGhlIGl0ZXJhdGVlIHRvIHRyYW5zZm9ybSBrZXlzLlxuICAgICAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgdGhlIGNvbXBvc2VkIGFnZ3JlZ2F0ZSBvYmplY3QuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uZ3JvdXBCeShbNi4xLCA0LjIsIDYuM10sIE1hdGguZmxvb3IpO1xuICAgICAqIC8vID0+IHsgJzQnOiBbNC4yXSwgJzYnOiBbNi4xLCA2LjNdIH1cbiAgICAgKlxuICAgICAqIC8vIFRoZSBgXy5wcm9wZXJ0eWAgaXRlcmF0ZWUgc2hvcnRoYW5kLlxuICAgICAqIF8uZ3JvdXBCeShbJ29uZScsICd0d28nLCAndGhyZWUnXSwgJ2xlbmd0aCcpO1xuICAgICAqIC8vID0+IHsgJzMnOiBbJ29uZScsICd0d28nXSwgJzUnOiBbJ3RocmVlJ10gfVxuICAgICAqL1xuICAgIHZhciBncm91cEJ5ID0gY3JlYXRlQWdncmVnYXRvcihmdW5jdGlvbihyZXN1bHQsIHZhbHVlLCBrZXkpIHtcbiAgICAgIGlmIChoYXNPd25Qcm9wZXJ0eS5jYWxsKHJlc3VsdCwga2V5KSkge1xuICAgICAgICByZXN1bHRba2V5XS5wdXNoKHZhbHVlKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGJhc2VBc3NpZ25WYWx1ZShyZXN1bHQsIGtleSwgW3ZhbHVlXSk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICAvKipcbiAgICAgKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBpbiBgY29sbGVjdGlvbmAuIElmIGBjb2xsZWN0aW9uYCBpcyBhIHN0cmluZywgaXQnc1xuICAgICAqIGNoZWNrZWQgZm9yIGEgc3Vic3RyaW5nIG9mIGB2YWx1ZWAsIG90aGVyd2lzZVxuICAgICAqIFtgU2FtZVZhbHVlWmVyb2BdKGh0dHA6Ly9lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzcuMC8jc2VjLXNhbWV2YWx1ZXplcm8pXG4gICAgICogaXMgdXNlZCBmb3IgZXF1YWxpdHkgY29tcGFyaXNvbnMuIElmIGBmcm9tSW5kZXhgIGlzIG5lZ2F0aXZlLCBpdCdzIHVzZWQgYXNcbiAgICAgKiB0aGUgb2Zmc2V0IGZyb20gdGhlIGVuZCBvZiBgY29sbGVjdGlvbmAuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMC4xLjBcbiAgICAgKiBAY2F0ZWdvcnkgQ29sbGVjdGlvblxuICAgICAqIEBwYXJhbSB7QXJyYXl8T2JqZWN0fHN0cmluZ30gY29sbGVjdGlvbiBUaGUgY29sbGVjdGlvbiB0byBpbnNwZWN0LlxuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIHNlYXJjaCBmb3IuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtmcm9tSW5kZXg9MF0gVGhlIGluZGV4IHRvIHNlYXJjaCBmcm9tLlxuICAgICAqIEBwYXJhbS0ge09iamVjdH0gW2d1YXJkXSBFbmFibGVzIHVzZSBhcyBhbiBpdGVyYXRlZSBmb3IgbWV0aG9kcyBsaWtlIGBfLnJlZHVjZWAuXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgZm91bmQsIGVsc2UgYGZhbHNlYC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5pbmNsdWRlcyhbMSwgMiwgM10sIDEpO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKlxuICAgICAqIF8uaW5jbHVkZXMoWzEsIDIsIDNdLCAxLCAyKTtcbiAgICAgKiAvLyA9PiBmYWxzZVxuICAgICAqXG4gICAgICogXy5pbmNsdWRlcyh7ICdhJzogMSwgJ2InOiAyIH0sIDEpO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKlxuICAgICAqIF8uaW5jbHVkZXMoJ2FiY2QnLCAnYmMnKTtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICovXG4gICAgZnVuY3Rpb24gaW5jbHVkZXMoY29sbGVjdGlvbiwgdmFsdWUsIGZyb21JbmRleCwgZ3VhcmQpIHtcbiAgICAgIGNvbGxlY3Rpb24gPSBpc0FycmF5TGlrZShjb2xsZWN0aW9uKSA/IGNvbGxlY3Rpb24gOiB2YWx1ZXMoY29sbGVjdGlvbik7XG4gICAgICBmcm9tSW5kZXggPSAoZnJvbUluZGV4ICYmICFndWFyZCkgPyB0b0ludGVnZXIoZnJvbUluZGV4KSA6IDA7XG5cbiAgICAgIHZhciBsZW5ndGggPSBjb2xsZWN0aW9uLmxlbmd0aDtcbiAgICAgIGlmIChmcm9tSW5kZXggPCAwKSB7XG4gICAgICAgIGZyb21JbmRleCA9IG5hdGl2ZU1heChsZW5ndGggKyBmcm9tSW5kZXgsIDApO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGlzU3RyaW5nKGNvbGxlY3Rpb24pXG4gICAgICAgID8gKGZyb21JbmRleCA8PSBsZW5ndGggJiYgY29sbGVjdGlvbi5pbmRleE9mKHZhbHVlLCBmcm9tSW5kZXgpID4gLTEpXG4gICAgICAgIDogKCEhbGVuZ3RoICYmIGJhc2VJbmRleE9mKGNvbGxlY3Rpb24sIHZhbHVlLCBmcm9tSW5kZXgpID4gLTEpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEludm9rZXMgdGhlIG1ldGhvZCBhdCBgcGF0aGAgb2YgZWFjaCBlbGVtZW50IGluIGBjb2xsZWN0aW9uYCwgcmV0dXJuaW5nXG4gICAgICogYW4gYXJyYXkgb2YgdGhlIHJlc3VsdHMgb2YgZWFjaCBpbnZva2VkIG1ldGhvZC4gQW55IGFkZGl0aW9uYWwgYXJndW1lbnRzXG4gICAgICogYXJlIHByb3ZpZGVkIHRvIGVhY2ggaW52b2tlZCBtZXRob2QuIElmIGBwYXRoYCBpcyBhIGZ1bmN0aW9uLCBpdCdzIGludm9rZWRcbiAgICAgKiBmb3IsIGFuZCBgdGhpc2AgYm91bmQgdG8sIGVhY2ggZWxlbWVudCBpbiBgY29sbGVjdGlvbmAuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgQ29sbGVjdGlvblxuICAgICAqIEBwYXJhbSB7QXJyYXl8T2JqZWN0fSBjb2xsZWN0aW9uIFRoZSBjb2xsZWN0aW9uIHRvIGl0ZXJhdGUgb3Zlci5cbiAgICAgKiBAcGFyYW0ge0FycmF5fEZ1bmN0aW9ufHN0cmluZ30gcGF0aCBUaGUgcGF0aCBvZiB0aGUgbWV0aG9kIHRvIGludm9rZSBvclxuICAgICAqICB0aGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICAgICAqIEBwYXJhbSB7Li4uKn0gW2FyZ3NdIFRoZSBhcmd1bWVudHMgdG8gaW52b2tlIGVhY2ggbWV0aG9kIHdpdGguXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBhcnJheSBvZiByZXN1bHRzLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLmludm9rZU1hcChbWzUsIDEsIDddLCBbMywgMiwgMV1dLCAnc29ydCcpO1xuICAgICAqIC8vID0+IFtbMSwgNSwgN10sIFsxLCAyLCAzXV1cbiAgICAgKlxuICAgICAqIF8uaW52b2tlTWFwKFsxMjMsIDQ1Nl0sIFN0cmluZy5wcm90b3R5cGUuc3BsaXQsICcnKTtcbiAgICAgKiAvLyA9PiBbWycxJywgJzInLCAnMyddLCBbJzQnLCAnNScsICc2J11dXG4gICAgICovXG4gICAgdmFyIGludm9rZU1hcCA9IGJhc2VSZXN0KGZ1bmN0aW9uKGNvbGxlY3Rpb24sIHBhdGgsIGFyZ3MpIHtcbiAgICAgIHZhciBpbmRleCA9IC0xLFxuICAgICAgICAgIGlzRnVuYyA9IHR5cGVvZiBwYXRoID09ICdmdW5jdGlvbicsXG4gICAgICAgICAgcmVzdWx0ID0gaXNBcnJheUxpa2UoY29sbGVjdGlvbikgPyBBcnJheShjb2xsZWN0aW9uLmxlbmd0aCkgOiBbXTtcblxuICAgICAgYmFzZUVhY2goY29sbGVjdGlvbiwgZnVuY3Rpb24odmFsdWUpIHtcbiAgICAgICAgcmVzdWx0WysraW5kZXhdID0gaXNGdW5jID8gYXBwbHkocGF0aCwgdmFsdWUsIGFyZ3MpIDogYmFzZUludm9rZSh2YWx1ZSwgcGF0aCwgYXJncyk7XG4gICAgICB9KTtcbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfSk7XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGFuIG9iamVjdCBjb21wb3NlZCBvZiBrZXlzIGdlbmVyYXRlZCBmcm9tIHRoZSByZXN1bHRzIG9mIHJ1bm5pbmdcbiAgICAgKiBlYWNoIGVsZW1lbnQgb2YgYGNvbGxlY3Rpb25gIHRocnUgYGl0ZXJhdGVlYC4gVGhlIGNvcnJlc3BvbmRpbmcgdmFsdWUgb2ZcbiAgICAgKiBlYWNoIGtleSBpcyB0aGUgbGFzdCBlbGVtZW50IHJlc3BvbnNpYmxlIGZvciBnZW5lcmF0aW5nIHRoZSBrZXkuIFRoZVxuICAgICAqIGl0ZXJhdGVlIGlzIGludm9rZWQgd2l0aCBvbmUgYXJndW1lbnQ6ICh2YWx1ZSkuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgQ29sbGVjdGlvblxuICAgICAqIEBwYXJhbSB7QXJyYXl8T2JqZWN0fSBjb2xsZWN0aW9uIFRoZSBjb2xsZWN0aW9uIHRvIGl0ZXJhdGUgb3Zlci5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbaXRlcmF0ZWU9Xy5pZGVudGl0eV0gVGhlIGl0ZXJhdGVlIHRvIHRyYW5zZm9ybSBrZXlzLlxuICAgICAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgdGhlIGNvbXBvc2VkIGFnZ3JlZ2F0ZSBvYmplY3QuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciBhcnJheSA9IFtcbiAgICAgKiAgIHsgJ2Rpcic6ICdsZWZ0JywgJ2NvZGUnOiA5NyB9LFxuICAgICAqICAgeyAnZGlyJzogJ3JpZ2h0JywgJ2NvZGUnOiAxMDAgfVxuICAgICAqIF07XG4gICAgICpcbiAgICAgKiBfLmtleUJ5KGFycmF5LCBmdW5jdGlvbihvKSB7XG4gICAgICogICByZXR1cm4gU3RyaW5nLmZyb21DaGFyQ29kZShvLmNvZGUpO1xuICAgICAqIH0pO1xuICAgICAqIC8vID0+IHsgJ2EnOiB7ICdkaXInOiAnbGVmdCcsICdjb2RlJzogOTcgfSwgJ2QnOiB7ICdkaXInOiAncmlnaHQnLCAnY29kZSc6IDEwMCB9IH1cbiAgICAgKlxuICAgICAqIF8ua2V5QnkoYXJyYXksICdkaXInKTtcbiAgICAgKiAvLyA9PiB7ICdsZWZ0JzogeyAnZGlyJzogJ2xlZnQnLCAnY29kZSc6IDk3IH0sICdyaWdodCc6IHsgJ2Rpcic6ICdyaWdodCcsICdjb2RlJzogMTAwIH0gfVxuICAgICAqL1xuICAgIHZhciBrZXlCeSA9IGNyZWF0ZUFnZ3JlZ2F0b3IoZnVuY3Rpb24ocmVzdWx0LCB2YWx1ZSwga2V5KSB7XG4gICAgICBiYXNlQXNzaWduVmFsdWUocmVzdWx0LCBrZXksIHZhbHVlKTtcbiAgICB9KTtcblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYW4gYXJyYXkgb2YgdmFsdWVzIGJ5IHJ1bm5pbmcgZWFjaCBlbGVtZW50IGluIGBjb2xsZWN0aW9uYCB0aHJ1XG4gICAgICogYGl0ZXJhdGVlYC4gVGhlIGl0ZXJhdGVlIGlzIGludm9rZWQgd2l0aCB0aHJlZSBhcmd1bWVudHM6XG4gICAgICogKHZhbHVlLCBpbmRleHxrZXksIGNvbGxlY3Rpb24pLlxuICAgICAqXG4gICAgICogTWFueSBsb2Rhc2ggbWV0aG9kcyBhcmUgZ3VhcmRlZCB0byB3b3JrIGFzIGl0ZXJhdGVlcyBmb3IgbWV0aG9kcyBsaWtlXG4gICAgICogYF8uZXZlcnlgLCBgXy5maWx0ZXJgLCBgXy5tYXBgLCBgXy5tYXBWYWx1ZXNgLCBgXy5yZWplY3RgLCBhbmQgYF8uc29tZWAuXG4gICAgICpcbiAgICAgKiBUaGUgZ3VhcmRlZCBtZXRob2RzIGFyZTpcbiAgICAgKiBgYXJ5YCwgYGNodW5rYCwgYGN1cnJ5YCwgYGN1cnJ5UmlnaHRgLCBgZHJvcGAsIGBkcm9wUmlnaHRgLCBgZXZlcnlgLFxuICAgICAqIGBmaWxsYCwgYGludmVydGAsIGBwYXJzZUludGAsIGByYW5kb21gLCBgcmFuZ2VgLCBgcmFuZ2VSaWdodGAsIGByZXBlYXRgLFxuICAgICAqIGBzYW1wbGVTaXplYCwgYHNsaWNlYCwgYHNvbWVgLCBgc29ydEJ5YCwgYHNwbGl0YCwgYHRha2VgLCBgdGFrZVJpZ2h0YCxcbiAgICAgKiBgdGVtcGxhdGVgLCBgdHJpbWAsIGB0cmltRW5kYCwgYHRyaW1TdGFydGAsIGFuZCBgd29yZHNgXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMC4xLjBcbiAgICAgKiBAY2F0ZWdvcnkgQ29sbGVjdGlvblxuICAgICAqIEBwYXJhbSB7QXJyYXl8T2JqZWN0fSBjb2xsZWN0aW9uIFRoZSBjb2xsZWN0aW9uIHRvIGl0ZXJhdGUgb3Zlci5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbaXRlcmF0ZWU9Xy5pZGVudGl0eV0gVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIGl0ZXJhdGlvbi5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIG5ldyBtYXBwZWQgYXJyYXkuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIGZ1bmN0aW9uIHNxdWFyZShuKSB7XG4gICAgICogICByZXR1cm4gbiAqIG47XG4gICAgICogfVxuICAgICAqXG4gICAgICogXy5tYXAoWzQsIDhdLCBzcXVhcmUpO1xuICAgICAqIC8vID0+IFsxNiwgNjRdXG4gICAgICpcbiAgICAgKiBfLm1hcCh7ICdhJzogNCwgJ2InOiA4IH0sIHNxdWFyZSk7XG4gICAgICogLy8gPT4gWzE2LCA2NF0gKGl0ZXJhdGlvbiBvcmRlciBpcyBub3QgZ3VhcmFudGVlZClcbiAgICAgKlxuICAgICAqIHZhciB1c2VycyA9IFtcbiAgICAgKiAgIHsgJ3VzZXInOiAnYmFybmV5JyB9LFxuICAgICAqICAgeyAndXNlcic6ICdmcmVkJyB9XG4gICAgICogXTtcbiAgICAgKlxuICAgICAqIC8vIFRoZSBgXy5wcm9wZXJ0eWAgaXRlcmF0ZWUgc2hvcnRoYW5kLlxuICAgICAqIF8ubWFwKHVzZXJzLCAndXNlcicpO1xuICAgICAqIC8vID0+IFsnYmFybmV5JywgJ2ZyZWQnXVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIG1hcChjb2xsZWN0aW9uLCBpdGVyYXRlZSkge1xuICAgICAgdmFyIGZ1bmMgPSBpc0FycmF5KGNvbGxlY3Rpb24pID8gYXJyYXlNYXAgOiBiYXNlTWFwO1xuICAgICAgcmV0dXJuIGZ1bmMoY29sbGVjdGlvbiwgZ2V0SXRlcmF0ZWUoaXRlcmF0ZWUsIDMpKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIG1ldGhvZCBpcyBsaWtlIGBfLnNvcnRCeWAgZXhjZXB0IHRoYXQgaXQgYWxsb3dzIHNwZWNpZnlpbmcgdGhlIHNvcnRcbiAgICAgKiBvcmRlcnMgb2YgdGhlIGl0ZXJhdGVlcyB0byBzb3J0IGJ5LiBJZiBgb3JkZXJzYCBpcyB1bnNwZWNpZmllZCwgYWxsIHZhbHVlc1xuICAgICAqIGFyZSBzb3J0ZWQgaW4gYXNjZW5kaW5nIG9yZGVyLiBPdGhlcndpc2UsIHNwZWNpZnkgYW4gb3JkZXIgb2YgXCJkZXNjXCIgZm9yXG4gICAgICogZGVzY2VuZGluZyBvciBcImFzY1wiIGZvciBhc2NlbmRpbmcgc29ydCBvcmRlciBvZiBjb3JyZXNwb25kaW5nIHZhbHVlcy5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjAuMFxuICAgICAqIEBjYXRlZ29yeSBDb2xsZWN0aW9uXG4gICAgICogQHBhcmFtIHtBcnJheXxPYmplY3R9IGNvbGxlY3Rpb24gVGhlIGNvbGxlY3Rpb24gdG8gaXRlcmF0ZSBvdmVyLlxuICAgICAqIEBwYXJhbSB7QXJyYXlbXXxGdW5jdGlvbltdfE9iamVjdFtdfHN0cmluZ1tdfSBbaXRlcmF0ZWVzPVtfLmlkZW50aXR5XV1cbiAgICAgKiAgVGhlIGl0ZXJhdGVlcyB0byBzb3J0IGJ5LlxuICAgICAqIEBwYXJhbSB7c3RyaW5nW119IFtvcmRlcnNdIFRoZSBzb3J0IG9yZGVycyBvZiBgaXRlcmF0ZWVzYC5cbiAgICAgKiBAcGFyYW0tIHtPYmplY3R9IFtndWFyZF0gRW5hYmxlcyB1c2UgYXMgYW4gaXRlcmF0ZWUgZm9yIG1ldGhvZHMgbGlrZSBgXy5yZWR1Y2VgLlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IHNvcnRlZCBhcnJheS5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIHVzZXJzID0gW1xuICAgICAqICAgeyAndXNlcic6ICdmcmVkJywgICAnYWdlJzogNDggfSxcbiAgICAgKiAgIHsgJ3VzZXInOiAnYmFybmV5JywgJ2FnZSc6IDM0IH0sXG4gICAgICogICB7ICd1c2VyJzogJ2ZyZWQnLCAgICdhZ2UnOiA0MCB9LFxuICAgICAqICAgeyAndXNlcic6ICdiYXJuZXknLCAnYWdlJzogMzYgfVxuICAgICAqIF07XG4gICAgICpcbiAgICAgKiAvLyBTb3J0IGJ5IGB1c2VyYCBpbiBhc2NlbmRpbmcgb3JkZXIgYW5kIGJ5IGBhZ2VgIGluIGRlc2NlbmRpbmcgb3JkZXIuXG4gICAgICogXy5vcmRlckJ5KHVzZXJzLCBbJ3VzZXInLCAnYWdlJ10sIFsnYXNjJywgJ2Rlc2MnXSk7XG4gICAgICogLy8gPT4gb2JqZWN0cyBmb3IgW1snYmFybmV5JywgMzZdLCBbJ2Jhcm5leScsIDM0XSwgWydmcmVkJywgNDhdLCBbJ2ZyZWQnLCA0MF1dXG4gICAgICovXG4gICAgZnVuY3Rpb24gb3JkZXJCeShjb2xsZWN0aW9uLCBpdGVyYXRlZXMsIG9yZGVycywgZ3VhcmQpIHtcbiAgICAgIGlmIChjb2xsZWN0aW9uID09IG51bGwpIHtcbiAgICAgICAgcmV0dXJuIFtdO1xuICAgICAgfVxuICAgICAgaWYgKCFpc0FycmF5KGl0ZXJhdGVlcykpIHtcbiAgICAgICAgaXRlcmF0ZWVzID0gaXRlcmF0ZWVzID09IG51bGwgPyBbXSA6IFtpdGVyYXRlZXNdO1xuICAgICAgfVxuICAgICAgb3JkZXJzID0gZ3VhcmQgPyB1bmRlZmluZWQgOiBvcmRlcnM7XG4gICAgICBpZiAoIWlzQXJyYXkob3JkZXJzKSkge1xuICAgICAgICBvcmRlcnMgPSBvcmRlcnMgPT0gbnVsbCA/IFtdIDogW29yZGVyc107XG4gICAgICB9XG4gICAgICByZXR1cm4gYmFzZU9yZGVyQnkoY29sbGVjdGlvbiwgaXRlcmF0ZWVzLCBvcmRlcnMpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYW4gYXJyYXkgb2YgZWxlbWVudHMgc3BsaXQgaW50byB0d28gZ3JvdXBzLCB0aGUgZmlyc3Qgb2Ygd2hpY2hcbiAgICAgKiBjb250YWlucyBlbGVtZW50cyBgcHJlZGljYXRlYCByZXR1cm5zIHRydXRoeSBmb3IsIHRoZSBzZWNvbmQgb2Ygd2hpY2hcbiAgICAgKiBjb250YWlucyBlbGVtZW50cyBgcHJlZGljYXRlYCByZXR1cm5zIGZhbHNleSBmb3IuIFRoZSBwcmVkaWNhdGUgaXNcbiAgICAgKiBpbnZva2VkIHdpdGggb25lIGFyZ3VtZW50OiAodmFsdWUpLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDMuMC4wXG4gICAgICogQGNhdGVnb3J5IENvbGxlY3Rpb25cbiAgICAgKiBAcGFyYW0ge0FycmF5fE9iamVjdH0gY29sbGVjdGlvbiBUaGUgY29sbGVjdGlvbiB0byBpdGVyYXRlIG92ZXIuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW3ByZWRpY2F0ZT1fLmlkZW50aXR5XSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgYXJyYXkgb2YgZ3JvdXBlZCBlbGVtZW50cy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIHVzZXJzID0gW1xuICAgICAqICAgeyAndXNlcic6ICdiYXJuZXknLCAgJ2FnZSc6IDM2LCAnYWN0aXZlJzogZmFsc2UgfSxcbiAgICAgKiAgIHsgJ3VzZXInOiAnZnJlZCcsICAgICdhZ2UnOiA0MCwgJ2FjdGl2ZSc6IHRydWUgfSxcbiAgICAgKiAgIHsgJ3VzZXInOiAncGViYmxlcycsICdhZ2UnOiAxLCAgJ2FjdGl2ZSc6IGZhbHNlIH1cbiAgICAgKiBdO1xuICAgICAqXG4gICAgICogXy5wYXJ0aXRpb24odXNlcnMsIGZ1bmN0aW9uKG8pIHsgcmV0dXJuIG8uYWN0aXZlOyB9KTtcbiAgICAgKiAvLyA9PiBvYmplY3RzIGZvciBbWydmcmVkJ10sIFsnYmFybmV5JywgJ3BlYmJsZXMnXV1cbiAgICAgKlxuICAgICAqIC8vIFRoZSBgXy5tYXRjaGVzYCBpdGVyYXRlZSBzaG9ydGhhbmQuXG4gICAgICogXy5wYXJ0aXRpb24odXNlcnMsIHsgJ2FnZSc6IDEsICdhY3RpdmUnOiBmYWxzZSB9KTtcbiAgICAgKiAvLyA9PiBvYmplY3RzIGZvciBbWydwZWJibGVzJ10sIFsnYmFybmV5JywgJ2ZyZWQnXV1cbiAgICAgKlxuICAgICAqIC8vIFRoZSBgXy5tYXRjaGVzUHJvcGVydHlgIGl0ZXJhdGVlIHNob3J0aGFuZC5cbiAgICAgKiBfLnBhcnRpdGlvbih1c2VycywgWydhY3RpdmUnLCBmYWxzZV0pO1xuICAgICAqIC8vID0+IG9iamVjdHMgZm9yIFtbJ2Jhcm5leScsICdwZWJibGVzJ10sIFsnZnJlZCddXVxuICAgICAqXG4gICAgICogLy8gVGhlIGBfLnByb3BlcnR5YCBpdGVyYXRlZSBzaG9ydGhhbmQuXG4gICAgICogXy5wYXJ0aXRpb24odXNlcnMsICdhY3RpdmUnKTtcbiAgICAgKiAvLyA9PiBvYmplY3RzIGZvciBbWydmcmVkJ10sIFsnYmFybmV5JywgJ3BlYmJsZXMnXV1cbiAgICAgKi9cbiAgICB2YXIgcGFydGl0aW9uID0gY3JlYXRlQWdncmVnYXRvcihmdW5jdGlvbihyZXN1bHQsIHZhbHVlLCBrZXkpIHtcbiAgICAgIHJlc3VsdFtrZXkgPyAwIDogMV0ucHVzaCh2YWx1ZSk7XG4gICAgfSwgZnVuY3Rpb24oKSB7IHJldHVybiBbW10sIFtdXTsgfSk7XG5cbiAgICAvKipcbiAgICAgKiBSZWR1Y2VzIGBjb2xsZWN0aW9uYCB0byBhIHZhbHVlIHdoaWNoIGlzIHRoZSBhY2N1bXVsYXRlZCByZXN1bHQgb2YgcnVubmluZ1xuICAgICAqIGVhY2ggZWxlbWVudCBpbiBgY29sbGVjdGlvbmAgdGhydSBgaXRlcmF0ZWVgLCB3aGVyZSBlYWNoIHN1Y2Nlc3NpdmVcbiAgICAgKiBpbnZvY2F0aW9uIGlzIHN1cHBsaWVkIHRoZSByZXR1cm4gdmFsdWUgb2YgdGhlIHByZXZpb3VzLiBJZiBgYWNjdW11bGF0b3JgXG4gICAgICogaXMgbm90IGdpdmVuLCB0aGUgZmlyc3QgZWxlbWVudCBvZiBgY29sbGVjdGlvbmAgaXMgdXNlZCBhcyB0aGUgaW5pdGlhbFxuICAgICAqIHZhbHVlLiBUaGUgaXRlcmF0ZWUgaXMgaW52b2tlZCB3aXRoIGZvdXIgYXJndW1lbnRzOlxuICAgICAqIChhY2N1bXVsYXRvciwgdmFsdWUsIGluZGV4fGtleSwgY29sbGVjdGlvbikuXG4gICAgICpcbiAgICAgKiBNYW55IGxvZGFzaCBtZXRob2RzIGFyZSBndWFyZGVkIHRvIHdvcmsgYXMgaXRlcmF0ZWVzIGZvciBtZXRob2RzIGxpa2VcbiAgICAgKiBgXy5yZWR1Y2VgLCBgXy5yZWR1Y2VSaWdodGAsIGFuZCBgXy50cmFuc2Zvcm1gLlxuICAgICAqXG4gICAgICogVGhlIGd1YXJkZWQgbWV0aG9kcyBhcmU6XG4gICAgICogYGFzc2lnbmAsIGBkZWZhdWx0c2AsIGBkZWZhdWx0c0RlZXBgLCBgaW5jbHVkZXNgLCBgbWVyZ2VgLCBgb3JkZXJCeWAsXG4gICAgICogYW5kIGBzb3J0QnlgXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMC4xLjBcbiAgICAgKiBAY2F0ZWdvcnkgQ29sbGVjdGlvblxuICAgICAqIEBwYXJhbSB7QXJyYXl8T2JqZWN0fSBjb2xsZWN0aW9uIFRoZSBjb2xsZWN0aW9uIHRvIGl0ZXJhdGUgb3Zlci5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbaXRlcmF0ZWU9Xy5pZGVudGl0eV0gVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIGl0ZXJhdGlvbi5cbiAgICAgKiBAcGFyYW0geyp9IFthY2N1bXVsYXRvcl0gVGhlIGluaXRpYWwgdmFsdWUuXG4gICAgICogQHJldHVybnMgeyp9IFJldHVybnMgdGhlIGFjY3VtdWxhdGVkIHZhbHVlLlxuICAgICAqIEBzZWUgXy5yZWR1Y2VSaWdodFxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLnJlZHVjZShbMSwgMl0sIGZ1bmN0aW9uKHN1bSwgbikge1xuICAgICAqICAgcmV0dXJuIHN1bSArIG47XG4gICAgICogfSwgMCk7XG4gICAgICogLy8gPT4gM1xuICAgICAqXG4gICAgICogXy5yZWR1Y2UoeyAnYSc6IDEsICdiJzogMiwgJ2MnOiAxIH0sIGZ1bmN0aW9uKHJlc3VsdCwgdmFsdWUsIGtleSkge1xuICAgICAqICAgKHJlc3VsdFt2YWx1ZV0gfHwgKHJlc3VsdFt2YWx1ZV0gPSBbXSkpLnB1c2goa2V5KTtcbiAgICAgKiAgIHJldHVybiByZXN1bHQ7XG4gICAgICogfSwge30pO1xuICAgICAqIC8vID0+IHsgJzEnOiBbJ2EnLCAnYyddLCAnMic6IFsnYiddIH0gKGl0ZXJhdGlvbiBvcmRlciBpcyBub3QgZ3VhcmFudGVlZClcbiAgICAgKi9cbiAgICBmdW5jdGlvbiByZWR1Y2UoY29sbGVjdGlvbiwgaXRlcmF0ZWUsIGFjY3VtdWxhdG9yKSB7XG4gICAgICB2YXIgZnVuYyA9IGlzQXJyYXkoY29sbGVjdGlvbikgPyBhcnJheVJlZHVjZSA6IGJhc2VSZWR1Y2UsXG4gICAgICAgICAgaW5pdEFjY3VtID0gYXJndW1lbnRzLmxlbmd0aCA8IDM7XG5cbiAgICAgIHJldHVybiBmdW5jKGNvbGxlY3Rpb24sIGdldEl0ZXJhdGVlKGl0ZXJhdGVlLCA0KSwgYWNjdW11bGF0b3IsIGluaXRBY2N1bSwgYmFzZUVhY2gpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIGlzIGxpa2UgYF8ucmVkdWNlYCBleGNlcHQgdGhhdCBpdCBpdGVyYXRlcyBvdmVyIGVsZW1lbnRzIG9mXG4gICAgICogYGNvbGxlY3Rpb25gIGZyb20gcmlnaHQgdG8gbGVmdC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAwLjEuMFxuICAgICAqIEBjYXRlZ29yeSBDb2xsZWN0aW9uXG4gICAgICogQHBhcmFtIHtBcnJheXxPYmplY3R9IGNvbGxlY3Rpb24gVGhlIGNvbGxlY3Rpb24gdG8gaXRlcmF0ZSBvdmVyLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IFtpdGVyYXRlZT1fLmlkZW50aXR5XSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICAgICAqIEBwYXJhbSB7Kn0gW2FjY3VtdWxhdG9yXSBUaGUgaW5pdGlhbCB2YWx1ZS5cbiAgICAgKiBAcmV0dXJucyB7Kn0gUmV0dXJucyB0aGUgYWNjdW11bGF0ZWQgdmFsdWUuXG4gICAgICogQHNlZSBfLnJlZHVjZVxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgYXJyYXkgPSBbWzAsIDFdLCBbMiwgM10sIFs0LCA1XV07XG4gICAgICpcbiAgICAgKiBfLnJlZHVjZVJpZ2h0KGFycmF5LCBmdW5jdGlvbihmbGF0dGVuZWQsIG90aGVyKSB7XG4gICAgICogICByZXR1cm4gZmxhdHRlbmVkLmNvbmNhdChvdGhlcik7XG4gICAgICogfSwgW10pO1xuICAgICAqIC8vID0+IFs0LCA1LCAyLCAzLCAwLCAxXVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIHJlZHVjZVJpZ2h0KGNvbGxlY3Rpb24sIGl0ZXJhdGVlLCBhY2N1bXVsYXRvcikge1xuICAgICAgdmFyIGZ1bmMgPSBpc0FycmF5KGNvbGxlY3Rpb24pID8gYXJyYXlSZWR1Y2VSaWdodCA6IGJhc2VSZWR1Y2UsXG4gICAgICAgICAgaW5pdEFjY3VtID0gYXJndW1lbnRzLmxlbmd0aCA8IDM7XG5cbiAgICAgIHJldHVybiBmdW5jKGNvbGxlY3Rpb24sIGdldEl0ZXJhdGVlKGl0ZXJhdGVlLCA0KSwgYWNjdW11bGF0b3IsIGluaXRBY2N1bSwgYmFzZUVhY2hSaWdodCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIG9wcG9zaXRlIG9mIGBfLmZpbHRlcmA7IHRoaXMgbWV0aG9kIHJldHVybnMgdGhlIGVsZW1lbnRzIG9mIGBjb2xsZWN0aW9uYFxuICAgICAqIHRoYXQgYHByZWRpY2F0ZWAgZG9lcyAqKm5vdCoqIHJldHVybiB0cnV0aHkgZm9yLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDAuMS4wXG4gICAgICogQGNhdGVnb3J5IENvbGxlY3Rpb25cbiAgICAgKiBAcGFyYW0ge0FycmF5fE9iamVjdH0gY29sbGVjdGlvbiBUaGUgY29sbGVjdGlvbiB0byBpdGVyYXRlIG92ZXIuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW3ByZWRpY2F0ZT1fLmlkZW50aXR5XSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IGZpbHRlcmVkIGFycmF5LlxuICAgICAqIEBzZWUgXy5maWx0ZXJcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIHVzZXJzID0gW1xuICAgICAqICAgeyAndXNlcic6ICdiYXJuZXknLCAnYWdlJzogMzYsICdhY3RpdmUnOiBmYWxzZSB9LFxuICAgICAqICAgeyAndXNlcic6ICdmcmVkJywgICAnYWdlJzogNDAsICdhY3RpdmUnOiB0cnVlIH1cbiAgICAgKiBdO1xuICAgICAqXG4gICAgICogXy5yZWplY3QodXNlcnMsIGZ1bmN0aW9uKG8pIHsgcmV0dXJuICFvLmFjdGl2ZTsgfSk7XG4gICAgICogLy8gPT4gb2JqZWN0cyBmb3IgWydmcmVkJ11cbiAgICAgKlxuICAgICAqIC8vIFRoZSBgXy5tYXRjaGVzYCBpdGVyYXRlZSBzaG9ydGhhbmQuXG4gICAgICogXy5yZWplY3QodXNlcnMsIHsgJ2FnZSc6IDQwLCAnYWN0aXZlJzogdHJ1ZSB9KTtcbiAgICAgKiAvLyA9PiBvYmplY3RzIGZvciBbJ2Jhcm5leSddXG4gICAgICpcbiAgICAgKiAvLyBUaGUgYF8ubWF0Y2hlc1Byb3BlcnR5YCBpdGVyYXRlZSBzaG9ydGhhbmQuXG4gICAgICogXy5yZWplY3QodXNlcnMsIFsnYWN0aXZlJywgZmFsc2VdKTtcbiAgICAgKiAvLyA9PiBvYmplY3RzIGZvciBbJ2ZyZWQnXVxuICAgICAqXG4gICAgICogLy8gVGhlIGBfLnByb3BlcnR5YCBpdGVyYXRlZSBzaG9ydGhhbmQuXG4gICAgICogXy5yZWplY3QodXNlcnMsICdhY3RpdmUnKTtcbiAgICAgKiAvLyA9PiBvYmplY3RzIGZvciBbJ2Jhcm5leSddXG4gICAgICovXG4gICAgZnVuY3Rpb24gcmVqZWN0KGNvbGxlY3Rpb24sIHByZWRpY2F0ZSkge1xuICAgICAgdmFyIGZ1bmMgPSBpc0FycmF5KGNvbGxlY3Rpb24pID8gYXJyYXlGaWx0ZXIgOiBiYXNlRmlsdGVyO1xuICAgICAgcmV0dXJuIGZ1bmMoY29sbGVjdGlvbiwgbmVnYXRlKGdldEl0ZXJhdGVlKHByZWRpY2F0ZSwgMykpKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXRzIGEgcmFuZG9tIGVsZW1lbnQgZnJvbSBgY29sbGVjdGlvbmAuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMi4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgQ29sbGVjdGlvblxuICAgICAqIEBwYXJhbSB7QXJyYXl8T2JqZWN0fSBjb2xsZWN0aW9uIFRoZSBjb2xsZWN0aW9uIHRvIHNhbXBsZS5cbiAgICAgKiBAcmV0dXJucyB7Kn0gUmV0dXJucyB0aGUgcmFuZG9tIGVsZW1lbnQuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uc2FtcGxlKFsxLCAyLCAzLCA0XSk7XG4gICAgICogLy8gPT4gMlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIHNhbXBsZShjb2xsZWN0aW9uKSB7XG4gICAgICB2YXIgZnVuYyA9IGlzQXJyYXkoY29sbGVjdGlvbikgPyBhcnJheVNhbXBsZSA6IGJhc2VTYW1wbGU7XG4gICAgICByZXR1cm4gZnVuYyhjb2xsZWN0aW9uKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXRzIGBuYCByYW5kb20gZWxlbWVudHMgYXQgdW5pcXVlIGtleXMgZnJvbSBgY29sbGVjdGlvbmAgdXAgdG8gdGhlXG4gICAgICogc2l6ZSBvZiBgY29sbGVjdGlvbmAuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgQ29sbGVjdGlvblxuICAgICAqIEBwYXJhbSB7QXJyYXl8T2JqZWN0fSBjb2xsZWN0aW9uIFRoZSBjb2xsZWN0aW9uIHRvIHNhbXBsZS5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW249MV0gVGhlIG51bWJlciBvZiBlbGVtZW50cyB0byBzYW1wbGUuXG4gICAgICogQHBhcmFtLSB7T2JqZWN0fSBbZ3VhcmRdIEVuYWJsZXMgdXNlIGFzIGFuIGl0ZXJhdGVlIGZvciBtZXRob2RzIGxpa2UgYF8ubWFwYC5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIHJhbmRvbSBlbGVtZW50cy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5zYW1wbGVTaXplKFsxLCAyLCAzXSwgMik7XG4gICAgICogLy8gPT4gWzMsIDFdXG4gICAgICpcbiAgICAgKiBfLnNhbXBsZVNpemUoWzEsIDIsIDNdLCA0KTtcbiAgICAgKiAvLyA9PiBbMiwgMywgMV1cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBzYW1wbGVTaXplKGNvbGxlY3Rpb24sIG4sIGd1YXJkKSB7XG4gICAgICBpZiAoKGd1YXJkID8gaXNJdGVyYXRlZUNhbGwoY29sbGVjdGlvbiwgbiwgZ3VhcmQpIDogbiA9PT0gdW5kZWZpbmVkKSkge1xuICAgICAgICBuID0gMTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIG4gPSB0b0ludGVnZXIobik7XG4gICAgICB9XG4gICAgICB2YXIgZnVuYyA9IGlzQXJyYXkoY29sbGVjdGlvbikgPyBhcnJheVNhbXBsZVNpemUgOiBiYXNlU2FtcGxlU2l6ZTtcbiAgICAgIHJldHVybiBmdW5jKGNvbGxlY3Rpb24sIG4pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYW4gYXJyYXkgb2Ygc2h1ZmZsZWQgdmFsdWVzLCB1c2luZyBhIHZlcnNpb24gb2YgdGhlXG4gICAgICogW0Zpc2hlci1ZYXRlcyBzaHVmZmxlXShodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9GaXNoZXItWWF0ZXNfc2h1ZmZsZSkuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMC4xLjBcbiAgICAgKiBAY2F0ZWdvcnkgQ29sbGVjdGlvblxuICAgICAqIEBwYXJhbSB7QXJyYXl8T2JqZWN0fSBjb2xsZWN0aW9uIFRoZSBjb2xsZWN0aW9uIHRvIHNodWZmbGUuXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBuZXcgc2h1ZmZsZWQgYXJyYXkuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uc2h1ZmZsZShbMSwgMiwgMywgNF0pO1xuICAgICAqIC8vID0+IFs0LCAxLCAzLCAyXVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIHNodWZmbGUoY29sbGVjdGlvbikge1xuICAgICAgdmFyIGZ1bmMgPSBpc0FycmF5KGNvbGxlY3Rpb24pID8gYXJyYXlTaHVmZmxlIDogYmFzZVNodWZmbGU7XG4gICAgICByZXR1cm4gZnVuYyhjb2xsZWN0aW9uKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXRzIHRoZSBzaXplIG9mIGBjb2xsZWN0aW9uYCBieSByZXR1cm5pbmcgaXRzIGxlbmd0aCBmb3IgYXJyYXktbGlrZVxuICAgICAqIHZhbHVlcyBvciB0aGUgbnVtYmVyIG9mIG93biBlbnVtZXJhYmxlIHN0cmluZyBrZXllZCBwcm9wZXJ0aWVzIGZvciBvYmplY3RzLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDAuMS4wXG4gICAgICogQGNhdGVnb3J5IENvbGxlY3Rpb25cbiAgICAgKiBAcGFyYW0ge0FycmF5fE9iamVjdHxzdHJpbmd9IGNvbGxlY3Rpb24gVGhlIGNvbGxlY3Rpb24gdG8gaW5zcGVjdC5cbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBSZXR1cm5zIHRoZSBjb2xsZWN0aW9uIHNpemUuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uc2l6ZShbMSwgMiwgM10pO1xuICAgICAqIC8vID0+IDNcbiAgICAgKlxuICAgICAqIF8uc2l6ZSh7ICdhJzogMSwgJ2InOiAyIH0pO1xuICAgICAqIC8vID0+IDJcbiAgICAgKlxuICAgICAqIF8uc2l6ZSgncGViYmxlcycpO1xuICAgICAqIC8vID0+IDdcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBzaXplKGNvbGxlY3Rpb24pIHtcbiAgICAgIGlmIChjb2xsZWN0aW9uID09IG51bGwpIHtcbiAgICAgICAgcmV0dXJuIDA7XG4gICAgICB9XG4gICAgICBpZiAoaXNBcnJheUxpa2UoY29sbGVjdGlvbikpIHtcbiAgICAgICAgcmV0dXJuIGlzU3RyaW5nKGNvbGxlY3Rpb24pID8gc3RyaW5nU2l6ZShjb2xsZWN0aW9uKSA6IGNvbGxlY3Rpb24ubGVuZ3RoO1xuICAgICAgfVxuICAgICAgdmFyIHRhZyA9IGdldFRhZyhjb2xsZWN0aW9uKTtcbiAgICAgIGlmICh0YWcgPT0gbWFwVGFnIHx8IHRhZyA9PSBzZXRUYWcpIHtcbiAgICAgICAgcmV0dXJuIGNvbGxlY3Rpb24uc2l6ZTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBiYXNlS2V5cyhjb2xsZWN0aW9uKS5sZW5ndGg7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2hlY2tzIGlmIGBwcmVkaWNhdGVgIHJldHVybnMgdHJ1dGh5IGZvciAqKmFueSoqIGVsZW1lbnQgb2YgYGNvbGxlY3Rpb25gLlxuICAgICAqIEl0ZXJhdGlvbiBpcyBzdG9wcGVkIG9uY2UgYHByZWRpY2F0ZWAgcmV0dXJucyB0cnV0aHkuIFRoZSBwcmVkaWNhdGUgaXNcbiAgICAgKiBpbnZva2VkIHdpdGggdGhyZWUgYXJndW1lbnRzOiAodmFsdWUsIGluZGV4fGtleSwgY29sbGVjdGlvbikuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMC4xLjBcbiAgICAgKiBAY2F0ZWdvcnkgQ29sbGVjdGlvblxuICAgICAqIEBwYXJhbSB7QXJyYXl8T2JqZWN0fSBjb2xsZWN0aW9uIFRoZSBjb2xsZWN0aW9uIHRvIGl0ZXJhdGUgb3Zlci5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbcHJlZGljYXRlPV8uaWRlbnRpdHldIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uXG4gICAgICogQHBhcmFtLSB7T2JqZWN0fSBbZ3VhcmRdIEVuYWJsZXMgdXNlIGFzIGFuIGl0ZXJhdGVlIGZvciBtZXRob2RzIGxpa2UgYF8ubWFwYC5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYW55IGVsZW1lbnQgcGFzc2VzIHRoZSBwcmVkaWNhdGUgY2hlY2ssXG4gICAgICogIGVsc2UgYGZhbHNlYC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5zb21lKFtudWxsLCAwLCAneWVzJywgZmFsc2VdLCBCb29sZWFuKTtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICpcbiAgICAgKiB2YXIgdXNlcnMgPSBbXG4gICAgICogICB7ICd1c2VyJzogJ2Jhcm5leScsICdhY3RpdmUnOiB0cnVlIH0sXG4gICAgICogICB7ICd1c2VyJzogJ2ZyZWQnLCAgICdhY3RpdmUnOiBmYWxzZSB9XG4gICAgICogXTtcbiAgICAgKlxuICAgICAqIC8vIFRoZSBgXy5tYXRjaGVzYCBpdGVyYXRlZSBzaG9ydGhhbmQuXG4gICAgICogXy5zb21lKHVzZXJzLCB7ICd1c2VyJzogJ2Jhcm5leScsICdhY3RpdmUnOiBmYWxzZSB9KTtcbiAgICAgKiAvLyA9PiBmYWxzZVxuICAgICAqXG4gICAgICogLy8gVGhlIGBfLm1hdGNoZXNQcm9wZXJ0eWAgaXRlcmF0ZWUgc2hvcnRoYW5kLlxuICAgICAqIF8uc29tZSh1c2VycywgWydhY3RpdmUnLCBmYWxzZV0pO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKlxuICAgICAqIC8vIFRoZSBgXy5wcm9wZXJ0eWAgaXRlcmF0ZWUgc2hvcnRoYW5kLlxuICAgICAqIF8uc29tZSh1c2VycywgJ2FjdGl2ZScpO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBzb21lKGNvbGxlY3Rpb24sIHByZWRpY2F0ZSwgZ3VhcmQpIHtcbiAgICAgIHZhciBmdW5jID0gaXNBcnJheShjb2xsZWN0aW9uKSA/IGFycmF5U29tZSA6IGJhc2VTb21lO1xuICAgICAgaWYgKGd1YXJkICYmIGlzSXRlcmF0ZWVDYWxsKGNvbGxlY3Rpb24sIHByZWRpY2F0ZSwgZ3VhcmQpKSB7XG4gICAgICAgIHByZWRpY2F0ZSA9IHVuZGVmaW5lZDtcbiAgICAgIH1cbiAgICAgIHJldHVybiBmdW5jKGNvbGxlY3Rpb24sIGdldEl0ZXJhdGVlKHByZWRpY2F0ZSwgMykpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYW4gYXJyYXkgb2YgZWxlbWVudHMsIHNvcnRlZCBpbiBhc2NlbmRpbmcgb3JkZXIgYnkgdGhlIHJlc3VsdHMgb2ZcbiAgICAgKiBydW5uaW5nIGVhY2ggZWxlbWVudCBpbiBhIGNvbGxlY3Rpb24gdGhydSBlYWNoIGl0ZXJhdGVlLiBUaGlzIG1ldGhvZFxuICAgICAqIHBlcmZvcm1zIGEgc3RhYmxlIHNvcnQsIHRoYXQgaXMsIGl0IHByZXNlcnZlcyB0aGUgb3JpZ2luYWwgc29ydCBvcmRlciBvZlxuICAgICAqIGVxdWFsIGVsZW1lbnRzLiBUaGUgaXRlcmF0ZWVzIGFyZSBpbnZva2VkIHdpdGggb25lIGFyZ3VtZW50OiAodmFsdWUpLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDAuMS4wXG4gICAgICogQGNhdGVnb3J5IENvbGxlY3Rpb25cbiAgICAgKiBAcGFyYW0ge0FycmF5fE9iamVjdH0gY29sbGVjdGlvbiBUaGUgY29sbGVjdGlvbiB0byBpdGVyYXRlIG92ZXIuXG4gICAgICogQHBhcmFtIHsuLi4oRnVuY3Rpb258RnVuY3Rpb25bXSl9IFtpdGVyYXRlZXM9W18uaWRlbnRpdHldXVxuICAgICAqICBUaGUgaXRlcmF0ZWVzIHRvIHNvcnQgYnkuXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBuZXcgc29ydGVkIGFycmF5LlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgdXNlcnMgPSBbXG4gICAgICogICB7ICd1c2VyJzogJ2ZyZWQnLCAgICdhZ2UnOiA0OCB9LFxuICAgICAqICAgeyAndXNlcic6ICdiYXJuZXknLCAnYWdlJzogMzYgfSxcbiAgICAgKiAgIHsgJ3VzZXInOiAnZnJlZCcsICAgJ2FnZSc6IDMwIH0sXG4gICAgICogICB7ICd1c2VyJzogJ2Jhcm5leScsICdhZ2UnOiAzNCB9XG4gICAgICogXTtcbiAgICAgKlxuICAgICAqIF8uc29ydEJ5KHVzZXJzLCBbZnVuY3Rpb24obykgeyByZXR1cm4gby51c2VyOyB9XSk7XG4gICAgICogLy8gPT4gb2JqZWN0cyBmb3IgW1snYmFybmV5JywgMzZdLCBbJ2Jhcm5leScsIDM0XSwgWydmcmVkJywgNDhdLCBbJ2ZyZWQnLCAzMF1dXG4gICAgICpcbiAgICAgKiBfLnNvcnRCeSh1c2VycywgWyd1c2VyJywgJ2FnZSddKTtcbiAgICAgKiAvLyA9PiBvYmplY3RzIGZvciBbWydiYXJuZXknLCAzNF0sIFsnYmFybmV5JywgMzZdLCBbJ2ZyZWQnLCAzMF0sIFsnZnJlZCcsIDQ4XV1cbiAgICAgKi9cbiAgICB2YXIgc29ydEJ5ID0gYmFzZVJlc3QoZnVuY3Rpb24oY29sbGVjdGlvbiwgaXRlcmF0ZWVzKSB7XG4gICAgICBpZiAoY29sbGVjdGlvbiA9PSBudWxsKSB7XG4gICAgICAgIHJldHVybiBbXTtcbiAgICAgIH1cbiAgICAgIHZhciBsZW5ndGggPSBpdGVyYXRlZXMubGVuZ3RoO1xuICAgICAgaWYgKGxlbmd0aCA+IDEgJiYgaXNJdGVyYXRlZUNhbGwoY29sbGVjdGlvbiwgaXRlcmF0ZWVzWzBdLCBpdGVyYXRlZXNbMV0pKSB7XG4gICAgICAgIGl0ZXJhdGVlcyA9IFtdO1xuICAgICAgfSBlbHNlIGlmIChsZW5ndGggPiAyICYmIGlzSXRlcmF0ZWVDYWxsKGl0ZXJhdGVlc1swXSwgaXRlcmF0ZWVzWzFdLCBpdGVyYXRlZXNbMl0pKSB7XG4gICAgICAgIGl0ZXJhdGVlcyA9IFtpdGVyYXRlZXNbMF1dO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGJhc2VPcmRlckJ5KGNvbGxlY3Rpb24sIGJhc2VGbGF0dGVuKGl0ZXJhdGVlcywgMSksIFtdKTtcbiAgICB9KTtcblxuICAgIC8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi9cblxuICAgIC8qKlxuICAgICAqIEdldHMgdGhlIHRpbWVzdGFtcCBvZiB0aGUgbnVtYmVyIG9mIG1pbGxpc2Vjb25kcyB0aGF0IGhhdmUgZWxhcHNlZCBzaW5jZVxuICAgICAqIHRoZSBVbml4IGVwb2NoICgxIEphbnVhcnkgMTk3MCAwMDowMDowMCBVVEMpLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDIuNC4wXG4gICAgICogQGNhdGVnb3J5IERhdGVcbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBSZXR1cm5zIHRoZSB0aW1lc3RhbXAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uZGVmZXIoZnVuY3Rpb24oc3RhbXApIHtcbiAgICAgKiAgIGNvbnNvbGUubG9nKF8ubm93KCkgLSBzdGFtcCk7XG4gICAgICogfSwgXy5ub3coKSk7XG4gICAgICogLy8gPT4gTG9ncyB0aGUgbnVtYmVyIG9mIG1pbGxpc2Vjb25kcyBpdCB0b29rIGZvciB0aGUgZGVmZXJyZWQgaW52b2NhdGlvbi5cbiAgICAgKi9cbiAgICB2YXIgbm93ID0gY3R4Tm93IHx8IGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIHJvb3QuRGF0ZS5ub3coKTtcbiAgICB9O1xuXG4gICAgLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuXG4gICAgLyoqXG4gICAgICogVGhlIG9wcG9zaXRlIG9mIGBfLmJlZm9yZWA7IHRoaXMgbWV0aG9kIGNyZWF0ZXMgYSBmdW5jdGlvbiB0aGF0IGludm9rZXNcbiAgICAgKiBgZnVuY2Agb25jZSBpdCdzIGNhbGxlZCBgbmAgb3IgbW9yZSB0aW1lcy5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAwLjEuMFxuICAgICAqIEBjYXRlZ29yeSBGdW5jdGlvblxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBuIFRoZSBudW1iZXIgb2YgY2FsbHMgYmVmb3JlIGBmdW5jYCBpcyBpbnZva2VkLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIHJlc3RyaWN0LlxuICAgICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IHJlc3RyaWN0ZWQgZnVuY3Rpb24uXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciBzYXZlcyA9IFsncHJvZmlsZScsICdzZXR0aW5ncyddO1xuICAgICAqXG4gICAgICogdmFyIGRvbmUgPSBfLmFmdGVyKHNhdmVzLmxlbmd0aCwgZnVuY3Rpb24oKSB7XG4gICAgICogICBjb25zb2xlLmxvZygnZG9uZSBzYXZpbmchJyk7XG4gICAgICogfSk7XG4gICAgICpcbiAgICAgKiBfLmZvckVhY2goc2F2ZXMsIGZ1bmN0aW9uKHR5cGUpIHtcbiAgICAgKiAgIGFzeW5jU2F2ZSh7ICd0eXBlJzogdHlwZSwgJ2NvbXBsZXRlJzogZG9uZSB9KTtcbiAgICAgKiB9KTtcbiAgICAgKiAvLyA9PiBMb2dzICdkb25lIHNhdmluZyEnIGFmdGVyIHRoZSB0d28gYXN5bmMgc2F2ZXMgaGF2ZSBjb21wbGV0ZWQuXG4gICAgICovXG4gICAgZnVuY3Rpb24gYWZ0ZXIobiwgZnVuYykge1xuICAgICAgaWYgKHR5cGVvZiBmdW5jICE9ICdmdW5jdGlvbicpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihGVU5DX0VSUk9SX1RFWFQpO1xuICAgICAgfVxuICAgICAgbiA9IHRvSW50ZWdlcihuKTtcbiAgICAgIHJldHVybiBmdW5jdGlvbigpIHtcbiAgICAgICAgaWYgKC0tbiA8IDEpIHtcbiAgICAgICAgICByZXR1cm4gZnVuYy5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgICAgICB9XG4gICAgICB9O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBmdW5jdGlvbiB0aGF0IGludm9rZXMgYGZ1bmNgLCB3aXRoIHVwIHRvIGBuYCBhcmd1bWVudHMsXG4gICAgICogaWdub3JpbmcgYW55IGFkZGl0aW9uYWwgYXJndW1lbnRzLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDMuMC4wXG4gICAgICogQGNhdGVnb3J5IEZ1bmN0aW9uXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gZnVuYyBUaGUgZnVuY3Rpb24gdG8gY2FwIGFyZ3VtZW50cyBmb3IuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtuPWZ1bmMubGVuZ3RoXSBUaGUgYXJpdHkgY2FwLlxuICAgICAqIEBwYXJhbS0ge09iamVjdH0gW2d1YXJkXSBFbmFibGVzIHVzZSBhcyBhbiBpdGVyYXRlZSBmb3IgbWV0aG9kcyBsaWtlIGBfLm1hcGAuXG4gICAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgY2FwcGVkIGZ1bmN0aW9uLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLm1hcChbJzYnLCAnOCcsICcxMCddLCBfLmFyeShwYXJzZUludCwgMSkpO1xuICAgICAqIC8vID0+IFs2LCA4LCAxMF1cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBhcnkoZnVuYywgbiwgZ3VhcmQpIHtcbiAgICAgIG4gPSBndWFyZCA/IHVuZGVmaW5lZCA6IG47XG4gICAgICBuID0gKGZ1bmMgJiYgbiA9PSBudWxsKSA/IGZ1bmMubGVuZ3RoIDogbjtcbiAgICAgIHJldHVybiBjcmVhdGVXcmFwKGZ1bmMsIFdSQVBfQVJZX0ZMQUcsIHVuZGVmaW5lZCwgdW5kZWZpbmVkLCB1bmRlZmluZWQsIHVuZGVmaW5lZCwgbik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIGZ1bmN0aW9uIHRoYXQgaW52b2tlcyBgZnVuY2AsIHdpdGggdGhlIGB0aGlzYCBiaW5kaW5nIGFuZCBhcmd1bWVudHNcbiAgICAgKiBvZiB0aGUgY3JlYXRlZCBmdW5jdGlvbiwgd2hpbGUgaXQncyBjYWxsZWQgbGVzcyB0aGFuIGBuYCB0aW1lcy4gU3Vic2VxdWVudFxuICAgICAqIGNhbGxzIHRvIHRoZSBjcmVhdGVkIGZ1bmN0aW9uIHJldHVybiB0aGUgcmVzdWx0IG9mIHRoZSBsYXN0IGBmdW5jYCBpbnZvY2F0aW9uLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDMuMC4wXG4gICAgICogQGNhdGVnb3J5IEZ1bmN0aW9uXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IG4gVGhlIG51bWJlciBvZiBjYWxscyBhdCB3aGljaCBgZnVuY2AgaXMgbm8gbG9uZ2VyIGludm9rZWQuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gZnVuYyBUaGUgZnVuY3Rpb24gdG8gcmVzdHJpY3QuXG4gICAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgcmVzdHJpY3RlZCBmdW5jdGlvbi5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogalF1ZXJ5KGVsZW1lbnQpLm9uKCdjbGljaycsIF8uYmVmb3JlKDUsIGFkZENvbnRhY3RUb0xpc3QpKTtcbiAgICAgKiAvLyA9PiBBbGxvd3MgYWRkaW5nIHVwIHRvIDQgY29udGFjdHMgdG8gdGhlIGxpc3QuXG4gICAgICovXG4gICAgZnVuY3Rpb24gYmVmb3JlKG4sIGZ1bmMpIHtcbiAgICAgIHZhciByZXN1bHQ7XG4gICAgICBpZiAodHlwZW9mIGZ1bmMgIT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKEZVTkNfRVJST1JfVEVYVCk7XG4gICAgICB9XG4gICAgICBuID0gdG9JbnRlZ2VyKG4pO1xuICAgICAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgICAgICBpZiAoLS1uID4gMCkge1xuICAgICAgICAgIHJlc3VsdCA9IGZ1bmMuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAobiA8PSAxKSB7XG4gICAgICAgICAgZnVuYyA9IHVuZGVmaW5lZDtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgfTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgZnVuY3Rpb24gdGhhdCBpbnZva2VzIGBmdW5jYCB3aXRoIHRoZSBgdGhpc2AgYmluZGluZyBvZiBgdGhpc0FyZ2BcbiAgICAgKiBhbmQgYHBhcnRpYWxzYCBwcmVwZW5kZWQgdG8gdGhlIGFyZ3VtZW50cyBpdCByZWNlaXZlcy5cbiAgICAgKlxuICAgICAqIFRoZSBgXy5iaW5kLnBsYWNlaG9sZGVyYCB2YWx1ZSwgd2hpY2ggZGVmYXVsdHMgdG8gYF9gIGluIG1vbm9saXRoaWMgYnVpbGRzLFxuICAgICAqIG1heSBiZSB1c2VkIGFzIGEgcGxhY2Vob2xkZXIgZm9yIHBhcnRpYWxseSBhcHBsaWVkIGFyZ3VtZW50cy5cbiAgICAgKlxuICAgICAqICoqTm90ZToqKiBVbmxpa2UgbmF0aXZlIGBGdW5jdGlvbiNiaW5kYCwgdGhpcyBtZXRob2QgZG9lc24ndCBzZXQgdGhlIFwibGVuZ3RoXCJcbiAgICAgKiBwcm9wZXJ0eSBvZiBib3VuZCBmdW5jdGlvbnMuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMC4xLjBcbiAgICAgKiBAY2F0ZWdvcnkgRnVuY3Rpb25cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byBiaW5kLlxuICAgICAqIEBwYXJhbSB7Kn0gdGhpc0FyZyBUaGUgYHRoaXNgIGJpbmRpbmcgb2YgYGZ1bmNgLlxuICAgICAqIEBwYXJhbSB7Li4uKn0gW3BhcnRpYWxzXSBUaGUgYXJndW1lbnRzIHRvIGJlIHBhcnRpYWxseSBhcHBsaWVkLlxuICAgICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IGJvdW5kIGZ1bmN0aW9uLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBmdW5jdGlvbiBncmVldChncmVldGluZywgcHVuY3R1YXRpb24pIHtcbiAgICAgKiAgIHJldHVybiBncmVldGluZyArICcgJyArIHRoaXMudXNlciArIHB1bmN0dWF0aW9uO1xuICAgICAqIH1cbiAgICAgKlxuICAgICAqIHZhciBvYmplY3QgPSB7ICd1c2VyJzogJ2ZyZWQnIH07XG4gICAgICpcbiAgICAgKiB2YXIgYm91bmQgPSBfLmJpbmQoZ3JlZXQsIG9iamVjdCwgJ2hpJyk7XG4gICAgICogYm91bmQoJyEnKTtcbiAgICAgKiAvLyA9PiAnaGkgZnJlZCEnXG4gICAgICpcbiAgICAgKiAvLyBCb3VuZCB3aXRoIHBsYWNlaG9sZGVycy5cbiAgICAgKiB2YXIgYm91bmQgPSBfLmJpbmQoZ3JlZXQsIG9iamVjdCwgXywgJyEnKTtcbiAgICAgKiBib3VuZCgnaGknKTtcbiAgICAgKiAvLyA9PiAnaGkgZnJlZCEnXG4gICAgICovXG4gICAgdmFyIGJpbmQgPSBiYXNlUmVzdChmdW5jdGlvbihmdW5jLCB0aGlzQXJnLCBwYXJ0aWFscykge1xuICAgICAgdmFyIGJpdG1hc2sgPSBXUkFQX0JJTkRfRkxBRztcbiAgICAgIGlmIChwYXJ0aWFscy5sZW5ndGgpIHtcbiAgICAgICAgdmFyIGhvbGRlcnMgPSByZXBsYWNlSG9sZGVycyhwYXJ0aWFscywgZ2V0SG9sZGVyKGJpbmQpKTtcbiAgICAgICAgYml0bWFzayB8PSBXUkFQX1BBUlRJQUxfRkxBRztcbiAgICAgIH1cbiAgICAgIHJldHVybiBjcmVhdGVXcmFwKGZ1bmMsIGJpdG1hc2ssIHRoaXNBcmcsIHBhcnRpYWxzLCBob2xkZXJzKTtcbiAgICB9KTtcblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBmdW5jdGlvbiB0aGF0IGludm9rZXMgdGhlIG1ldGhvZCBhdCBgb2JqZWN0W2tleV1gIHdpdGggYHBhcnRpYWxzYFxuICAgICAqIHByZXBlbmRlZCB0byB0aGUgYXJndW1lbnRzIGl0IHJlY2VpdmVzLlxuICAgICAqXG4gICAgICogVGhpcyBtZXRob2QgZGlmZmVycyBmcm9tIGBfLmJpbmRgIGJ5IGFsbG93aW5nIGJvdW5kIGZ1bmN0aW9ucyB0byByZWZlcmVuY2VcbiAgICAgKiBtZXRob2RzIHRoYXQgbWF5IGJlIHJlZGVmaW5lZCBvciBkb24ndCB5ZXQgZXhpc3QuIFNlZVxuICAgICAqIFtQZXRlciBNaWNoYXV4J3MgYXJ0aWNsZV0oaHR0cDovL3BldGVyLm1pY2hhdXguY2EvYXJ0aWNsZXMvbGF6eS1mdW5jdGlvbi1kZWZpbml0aW9uLXBhdHRlcm4pXG4gICAgICogZm9yIG1vcmUgZGV0YWlscy5cbiAgICAgKlxuICAgICAqIFRoZSBgXy5iaW5kS2V5LnBsYWNlaG9sZGVyYCB2YWx1ZSwgd2hpY2ggZGVmYXVsdHMgdG8gYF9gIGluIG1vbm9saXRoaWNcbiAgICAgKiBidWlsZHMsIG1heSBiZSB1c2VkIGFzIGEgcGxhY2Vob2xkZXIgZm9yIHBhcnRpYWxseSBhcHBsaWVkIGFyZ3VtZW50cy5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAwLjEwLjBcbiAgICAgKiBAY2F0ZWdvcnkgRnVuY3Rpb25cbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gaW52b2tlIHRoZSBtZXRob2Qgb24uXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGtleSBUaGUga2V5IG9mIHRoZSBtZXRob2QuXG4gICAgICogQHBhcmFtIHsuLi4qfSBbcGFydGlhbHNdIFRoZSBhcmd1bWVudHMgdG8gYmUgcGFydGlhbGx5IGFwcGxpZWQuXG4gICAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgYm91bmQgZnVuY3Rpb24uXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciBvYmplY3QgPSB7XG4gICAgICogICAndXNlcic6ICdmcmVkJyxcbiAgICAgKiAgICdncmVldCc6IGZ1bmN0aW9uKGdyZWV0aW5nLCBwdW5jdHVhdGlvbikge1xuICAgICAqICAgICByZXR1cm4gZ3JlZXRpbmcgKyAnICcgKyB0aGlzLnVzZXIgKyBwdW5jdHVhdGlvbjtcbiAgICAgKiAgIH1cbiAgICAgKiB9O1xuICAgICAqXG4gICAgICogdmFyIGJvdW5kID0gXy5iaW5kS2V5KG9iamVjdCwgJ2dyZWV0JywgJ2hpJyk7XG4gICAgICogYm91bmQoJyEnKTtcbiAgICAgKiAvLyA9PiAnaGkgZnJlZCEnXG4gICAgICpcbiAgICAgKiBvYmplY3QuZ3JlZXQgPSBmdW5jdGlvbihncmVldGluZywgcHVuY3R1YXRpb24pIHtcbiAgICAgKiAgIHJldHVybiBncmVldGluZyArICd5YSAnICsgdGhpcy51c2VyICsgcHVuY3R1YXRpb247XG4gICAgICogfTtcbiAgICAgKlxuICAgICAqIGJvdW5kKCchJyk7XG4gICAgICogLy8gPT4gJ2hpeWEgZnJlZCEnXG4gICAgICpcbiAgICAgKiAvLyBCb3VuZCB3aXRoIHBsYWNlaG9sZGVycy5cbiAgICAgKiB2YXIgYm91bmQgPSBfLmJpbmRLZXkob2JqZWN0LCAnZ3JlZXQnLCBfLCAnIScpO1xuICAgICAqIGJvdW5kKCdoaScpO1xuICAgICAqIC8vID0+ICdoaXlhIGZyZWQhJ1xuICAgICAqL1xuICAgIHZhciBiaW5kS2V5ID0gYmFzZVJlc3QoZnVuY3Rpb24ob2JqZWN0LCBrZXksIHBhcnRpYWxzKSB7XG4gICAgICB2YXIgYml0bWFzayA9IFdSQVBfQklORF9GTEFHIHwgV1JBUF9CSU5EX0tFWV9GTEFHO1xuICAgICAgaWYgKHBhcnRpYWxzLmxlbmd0aCkge1xuICAgICAgICB2YXIgaG9sZGVycyA9IHJlcGxhY2VIb2xkZXJzKHBhcnRpYWxzLCBnZXRIb2xkZXIoYmluZEtleSkpO1xuICAgICAgICBiaXRtYXNrIHw9IFdSQVBfUEFSVElBTF9GTEFHO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGNyZWF0ZVdyYXAoa2V5LCBiaXRtYXNrLCBvYmplY3QsIHBhcnRpYWxzLCBob2xkZXJzKTtcbiAgICB9KTtcblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBmdW5jdGlvbiB0aGF0IGFjY2VwdHMgYXJndW1lbnRzIG9mIGBmdW5jYCBhbmQgZWl0aGVyIGludm9rZXNcbiAgICAgKiBgZnVuY2AgcmV0dXJuaW5nIGl0cyByZXN1bHQsIGlmIGF0IGxlYXN0IGBhcml0eWAgbnVtYmVyIG9mIGFyZ3VtZW50cyBoYXZlXG4gICAgICogYmVlbiBwcm92aWRlZCwgb3IgcmV0dXJucyBhIGZ1bmN0aW9uIHRoYXQgYWNjZXB0cyB0aGUgcmVtYWluaW5nIGBmdW5jYFxuICAgICAqIGFyZ3VtZW50cywgYW5kIHNvIG9uLiBUaGUgYXJpdHkgb2YgYGZ1bmNgIG1heSBiZSBzcGVjaWZpZWQgaWYgYGZ1bmMubGVuZ3RoYFxuICAgICAqIGlzIG5vdCBzdWZmaWNpZW50LlxuICAgICAqXG4gICAgICogVGhlIGBfLmN1cnJ5LnBsYWNlaG9sZGVyYCB2YWx1ZSwgd2hpY2ggZGVmYXVsdHMgdG8gYF9gIGluIG1vbm9saXRoaWMgYnVpbGRzLFxuICAgICAqIG1heSBiZSB1c2VkIGFzIGEgcGxhY2Vob2xkZXIgZm9yIHByb3ZpZGVkIGFyZ3VtZW50cy5cbiAgICAgKlxuICAgICAqICoqTm90ZToqKiBUaGlzIG1ldGhvZCBkb2Vzbid0IHNldCB0aGUgXCJsZW5ndGhcIiBwcm9wZXJ0eSBvZiBjdXJyaWVkIGZ1bmN0aW9ucy5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAyLjAuMFxuICAgICAqIEBjYXRlZ29yeSBGdW5jdGlvblxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIGN1cnJ5LlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbYXJpdHk9ZnVuYy5sZW5ndGhdIFRoZSBhcml0eSBvZiBgZnVuY2AuXG4gICAgICogQHBhcmFtLSB7T2JqZWN0fSBbZ3VhcmRdIEVuYWJsZXMgdXNlIGFzIGFuIGl0ZXJhdGVlIGZvciBtZXRob2RzIGxpa2UgYF8ubWFwYC5cbiAgICAgKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBjdXJyaWVkIGZ1bmN0aW9uLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgYWJjID0gZnVuY3Rpb24oYSwgYiwgYykge1xuICAgICAqICAgcmV0dXJuIFthLCBiLCBjXTtcbiAgICAgKiB9O1xuICAgICAqXG4gICAgICogdmFyIGN1cnJpZWQgPSBfLmN1cnJ5KGFiYyk7XG4gICAgICpcbiAgICAgKiBjdXJyaWVkKDEpKDIpKDMpO1xuICAgICAqIC8vID0+IFsxLCAyLCAzXVxuICAgICAqXG4gICAgICogY3VycmllZCgxLCAyKSgzKTtcbiAgICAgKiAvLyA9PiBbMSwgMiwgM11cbiAgICAgKlxuICAgICAqIGN1cnJpZWQoMSwgMiwgMyk7XG4gICAgICogLy8gPT4gWzEsIDIsIDNdXG4gICAgICpcbiAgICAgKiAvLyBDdXJyaWVkIHdpdGggcGxhY2Vob2xkZXJzLlxuICAgICAqIGN1cnJpZWQoMSkoXywgMykoMik7XG4gICAgICogLy8gPT4gWzEsIDIsIDNdXG4gICAgICovXG4gICAgZnVuY3Rpb24gY3VycnkoZnVuYywgYXJpdHksIGd1YXJkKSB7XG4gICAgICBhcml0eSA9IGd1YXJkID8gdW5kZWZpbmVkIDogYXJpdHk7XG4gICAgICB2YXIgcmVzdWx0ID0gY3JlYXRlV3JhcChmdW5jLCBXUkFQX0NVUlJZX0ZMQUcsIHVuZGVmaW5lZCwgdW5kZWZpbmVkLCB1bmRlZmluZWQsIHVuZGVmaW5lZCwgdW5kZWZpbmVkLCBhcml0eSk7XG4gICAgICByZXN1bHQucGxhY2Vob2xkZXIgPSBjdXJyeS5wbGFjZWhvbGRlcjtcbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgaXMgbGlrZSBgXy5jdXJyeWAgZXhjZXB0IHRoYXQgYXJndW1lbnRzIGFyZSBhcHBsaWVkIHRvIGBmdW5jYFxuICAgICAqIGluIHRoZSBtYW5uZXIgb2YgYF8ucGFydGlhbFJpZ2h0YCBpbnN0ZWFkIG9mIGBfLnBhcnRpYWxgLlxuICAgICAqXG4gICAgICogVGhlIGBfLmN1cnJ5UmlnaHQucGxhY2Vob2xkZXJgIHZhbHVlLCB3aGljaCBkZWZhdWx0cyB0byBgX2AgaW4gbW9ub2xpdGhpY1xuICAgICAqIGJ1aWxkcywgbWF5IGJlIHVzZWQgYXMgYSBwbGFjZWhvbGRlciBmb3IgcHJvdmlkZWQgYXJndW1lbnRzLlxuICAgICAqXG4gICAgICogKipOb3RlOioqIFRoaXMgbWV0aG9kIGRvZXNuJ3Qgc2V0IHRoZSBcImxlbmd0aFwiIHByb3BlcnR5IG9mIGN1cnJpZWQgZnVuY3Rpb25zLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDMuMC4wXG4gICAgICogQGNhdGVnb3J5IEZ1bmN0aW9uXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gZnVuYyBUaGUgZnVuY3Rpb24gdG8gY3VycnkuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFthcml0eT1mdW5jLmxlbmd0aF0gVGhlIGFyaXR5IG9mIGBmdW5jYC5cbiAgICAgKiBAcGFyYW0tIHtPYmplY3R9IFtndWFyZF0gRW5hYmxlcyB1c2UgYXMgYW4gaXRlcmF0ZWUgZm9yIG1ldGhvZHMgbGlrZSBgXy5tYXBgLlxuICAgICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IGN1cnJpZWQgZnVuY3Rpb24uXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciBhYmMgPSBmdW5jdGlvbihhLCBiLCBjKSB7XG4gICAgICogICByZXR1cm4gW2EsIGIsIGNdO1xuICAgICAqIH07XG4gICAgICpcbiAgICAgKiB2YXIgY3VycmllZCA9IF8uY3VycnlSaWdodChhYmMpO1xuICAgICAqXG4gICAgICogY3VycmllZCgzKSgyKSgxKTtcbiAgICAgKiAvLyA9PiBbMSwgMiwgM11cbiAgICAgKlxuICAgICAqIGN1cnJpZWQoMiwgMykoMSk7XG4gICAgICogLy8gPT4gWzEsIDIsIDNdXG4gICAgICpcbiAgICAgKiBjdXJyaWVkKDEsIDIsIDMpO1xuICAgICAqIC8vID0+IFsxLCAyLCAzXVxuICAgICAqXG4gICAgICogLy8gQ3VycmllZCB3aXRoIHBsYWNlaG9sZGVycy5cbiAgICAgKiBjdXJyaWVkKDMpKDEsIF8pKDIpO1xuICAgICAqIC8vID0+IFsxLCAyLCAzXVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGN1cnJ5UmlnaHQoZnVuYywgYXJpdHksIGd1YXJkKSB7XG4gICAgICBhcml0eSA9IGd1YXJkID8gdW5kZWZpbmVkIDogYXJpdHk7XG4gICAgICB2YXIgcmVzdWx0ID0gY3JlYXRlV3JhcChmdW5jLCBXUkFQX0NVUlJZX1JJR0hUX0ZMQUcsIHVuZGVmaW5lZCwgdW5kZWZpbmVkLCB1bmRlZmluZWQsIHVuZGVmaW5lZCwgdW5kZWZpbmVkLCBhcml0eSk7XG4gICAgICByZXN1bHQucGxhY2Vob2xkZXIgPSBjdXJyeVJpZ2h0LnBsYWNlaG9sZGVyO1xuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgZGVib3VuY2VkIGZ1bmN0aW9uIHRoYXQgZGVsYXlzIGludm9raW5nIGBmdW5jYCB1bnRpbCBhZnRlciBgd2FpdGBcbiAgICAgKiBtaWxsaXNlY29uZHMgaGF2ZSBlbGFwc2VkIHNpbmNlIHRoZSBsYXN0IHRpbWUgdGhlIGRlYm91bmNlZCBmdW5jdGlvbiB3YXNcbiAgICAgKiBpbnZva2VkLiBUaGUgZGVib3VuY2VkIGZ1bmN0aW9uIGNvbWVzIHdpdGggYSBgY2FuY2VsYCBtZXRob2QgdG8gY2FuY2VsXG4gICAgICogZGVsYXllZCBgZnVuY2AgaW52b2NhdGlvbnMgYW5kIGEgYGZsdXNoYCBtZXRob2QgdG8gaW1tZWRpYXRlbHkgaW52b2tlIHRoZW0uXG4gICAgICogUHJvdmlkZSBgb3B0aW9uc2AgdG8gaW5kaWNhdGUgd2hldGhlciBgZnVuY2Agc2hvdWxkIGJlIGludm9rZWQgb24gdGhlXG4gICAgICogbGVhZGluZyBhbmQvb3IgdHJhaWxpbmcgZWRnZSBvZiB0aGUgYHdhaXRgIHRpbWVvdXQuIFRoZSBgZnVuY2AgaXMgaW52b2tlZFxuICAgICAqIHdpdGggdGhlIGxhc3QgYXJndW1lbnRzIHByb3ZpZGVkIHRvIHRoZSBkZWJvdW5jZWQgZnVuY3Rpb24uIFN1YnNlcXVlbnRcbiAgICAgKiBjYWxscyB0byB0aGUgZGVib3VuY2VkIGZ1bmN0aW9uIHJldHVybiB0aGUgcmVzdWx0IG9mIHRoZSBsYXN0IGBmdW5jYFxuICAgICAqIGludm9jYXRpb24uXG4gICAgICpcbiAgICAgKiAqKk5vdGU6KiogSWYgYGxlYWRpbmdgIGFuZCBgdHJhaWxpbmdgIG9wdGlvbnMgYXJlIGB0cnVlYCwgYGZ1bmNgIGlzXG4gICAgICogaW52b2tlZCBvbiB0aGUgdHJhaWxpbmcgZWRnZSBvZiB0aGUgdGltZW91dCBvbmx5IGlmIHRoZSBkZWJvdW5jZWQgZnVuY3Rpb25cbiAgICAgKiBpcyBpbnZva2VkIG1vcmUgdGhhbiBvbmNlIGR1cmluZyB0aGUgYHdhaXRgIHRpbWVvdXQuXG4gICAgICpcbiAgICAgKiBJZiBgd2FpdGAgaXMgYDBgIGFuZCBgbGVhZGluZ2AgaXMgYGZhbHNlYCwgYGZ1bmNgIGludm9jYXRpb24gaXMgZGVmZXJyZWRcbiAgICAgKiB1bnRpbCB0byB0aGUgbmV4dCB0aWNrLCBzaW1pbGFyIHRvIGBzZXRUaW1lb3V0YCB3aXRoIGEgdGltZW91dCBvZiBgMGAuXG4gICAgICpcbiAgICAgKiBTZWUgW0RhdmlkIENvcmJhY2hvJ3MgYXJ0aWNsZV0oaHR0cHM6Ly9jc3MtdHJpY2tzLmNvbS9kZWJvdW5jaW5nLXRocm90dGxpbmctZXhwbGFpbmVkLWV4YW1wbGVzLylcbiAgICAgKiBmb3IgZGV0YWlscyBvdmVyIHRoZSBkaWZmZXJlbmNlcyBiZXR3ZWVuIGBfLmRlYm91bmNlYCBhbmQgYF8udGhyb3R0bGVgLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDAuMS4wXG4gICAgICogQGNhdGVnb3J5IEZ1bmN0aW9uXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gZnVuYyBUaGUgZnVuY3Rpb24gdG8gZGVib3VuY2UuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFt3YWl0PTBdIFRoZSBudW1iZXIgb2YgbWlsbGlzZWNvbmRzIHRvIGRlbGF5LlxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBbb3B0aW9ucz17fV0gVGhlIG9wdGlvbnMgb2JqZWN0LlxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbn0gW29wdGlvbnMubGVhZGluZz1mYWxzZV1cbiAgICAgKiAgU3BlY2lmeSBpbnZva2luZyBvbiB0aGUgbGVhZGluZyBlZGdlIG9mIHRoZSB0aW1lb3V0LlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbb3B0aW9ucy5tYXhXYWl0XVxuICAgICAqICBUaGUgbWF4aW11bSB0aW1lIGBmdW5jYCBpcyBhbGxvd2VkIHRvIGJlIGRlbGF5ZWQgYmVmb3JlIGl0J3MgaW52b2tlZC5cbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW59IFtvcHRpb25zLnRyYWlsaW5nPXRydWVdXG4gICAgICogIFNwZWNpZnkgaW52b2tpbmcgb24gdGhlIHRyYWlsaW5nIGVkZ2Ugb2YgdGhlIHRpbWVvdXQuXG4gICAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgZGVib3VuY2VkIGZ1bmN0aW9uLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiAvLyBBdm9pZCBjb3N0bHkgY2FsY3VsYXRpb25zIHdoaWxlIHRoZSB3aW5kb3cgc2l6ZSBpcyBpbiBmbHV4LlxuICAgICAqIGpRdWVyeSh3aW5kb3cpLm9uKCdyZXNpemUnLCBfLmRlYm91bmNlKGNhbGN1bGF0ZUxheW91dCwgMTUwKSk7XG4gICAgICpcbiAgICAgKiAvLyBJbnZva2UgYHNlbmRNYWlsYCB3aGVuIGNsaWNrZWQsIGRlYm91bmNpbmcgc3Vic2VxdWVudCBjYWxscy5cbiAgICAgKiBqUXVlcnkoZWxlbWVudCkub24oJ2NsaWNrJywgXy5kZWJvdW5jZShzZW5kTWFpbCwgMzAwLCB7XG4gICAgICogICAnbGVhZGluZyc6IHRydWUsXG4gICAgICogICAndHJhaWxpbmcnOiBmYWxzZVxuICAgICAqIH0pKTtcbiAgICAgKlxuICAgICAqIC8vIEVuc3VyZSBgYmF0Y2hMb2dgIGlzIGludm9rZWQgb25jZSBhZnRlciAxIHNlY29uZCBvZiBkZWJvdW5jZWQgY2FsbHMuXG4gICAgICogdmFyIGRlYm91bmNlZCA9IF8uZGVib3VuY2UoYmF0Y2hMb2csIDI1MCwgeyAnbWF4V2FpdCc6IDEwMDAgfSk7XG4gICAgICogdmFyIHNvdXJjZSA9IG5ldyBFdmVudFNvdXJjZSgnL3N0cmVhbScpO1xuICAgICAqIGpRdWVyeShzb3VyY2UpLm9uKCdtZXNzYWdlJywgZGVib3VuY2VkKTtcbiAgICAgKlxuICAgICAqIC8vIENhbmNlbCB0aGUgdHJhaWxpbmcgZGVib3VuY2VkIGludm9jYXRpb24uXG4gICAgICogalF1ZXJ5KHdpbmRvdykub24oJ3BvcHN0YXRlJywgZGVib3VuY2VkLmNhbmNlbCk7XG4gICAgICovXG4gICAgZnVuY3Rpb24gZGVib3VuY2UoZnVuYywgd2FpdCwgb3B0aW9ucykge1xuICAgICAgdmFyIGxhc3RBcmdzLFxuICAgICAgICAgIGxhc3RUaGlzLFxuICAgICAgICAgIG1heFdhaXQsXG4gICAgICAgICAgcmVzdWx0LFxuICAgICAgICAgIHRpbWVySWQsXG4gICAgICAgICAgbGFzdENhbGxUaW1lLFxuICAgICAgICAgIGxhc3RJbnZva2VUaW1lID0gMCxcbiAgICAgICAgICBsZWFkaW5nID0gZmFsc2UsXG4gICAgICAgICAgbWF4aW5nID0gZmFsc2UsXG4gICAgICAgICAgdHJhaWxpbmcgPSB0cnVlO1xuXG4gICAgICBpZiAodHlwZW9mIGZ1bmMgIT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKEZVTkNfRVJST1JfVEVYVCk7XG4gICAgICB9XG4gICAgICB3YWl0ID0gdG9OdW1iZXIod2FpdCkgfHwgMDtcbiAgICAgIGlmIChpc09iamVjdChvcHRpb25zKSkge1xuICAgICAgICBsZWFkaW5nID0gISFvcHRpb25zLmxlYWRpbmc7XG4gICAgICAgIG1heGluZyA9ICdtYXhXYWl0JyBpbiBvcHRpb25zO1xuICAgICAgICBtYXhXYWl0ID0gbWF4aW5nID8gbmF0aXZlTWF4KHRvTnVtYmVyKG9wdGlvbnMubWF4V2FpdCkgfHwgMCwgd2FpdCkgOiBtYXhXYWl0O1xuICAgICAgICB0cmFpbGluZyA9ICd0cmFpbGluZycgaW4gb3B0aW9ucyA/ICEhb3B0aW9ucy50cmFpbGluZyA6IHRyYWlsaW5nO1xuICAgICAgfVxuXG4gICAgICBmdW5jdGlvbiBpbnZva2VGdW5jKHRpbWUpIHtcbiAgICAgICAgdmFyIGFyZ3MgPSBsYXN0QXJncyxcbiAgICAgICAgICAgIHRoaXNBcmcgPSBsYXN0VGhpcztcblxuICAgICAgICBsYXN0QXJncyA9IGxhc3RUaGlzID0gdW5kZWZpbmVkO1xuICAgICAgICBsYXN0SW52b2tlVGltZSA9IHRpbWU7XG4gICAgICAgIHJlc3VsdCA9IGZ1bmMuYXBwbHkodGhpc0FyZywgYXJncyk7XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICB9XG5cbiAgICAgIGZ1bmN0aW9uIGxlYWRpbmdFZGdlKHRpbWUpIHtcbiAgICAgICAgLy8gUmVzZXQgYW55IGBtYXhXYWl0YCB0aW1lci5cbiAgICAgICAgbGFzdEludm9rZVRpbWUgPSB0aW1lO1xuICAgICAgICAvLyBTdGFydCB0aGUgdGltZXIgZm9yIHRoZSB0cmFpbGluZyBlZGdlLlxuICAgICAgICB0aW1lcklkID0gc2V0VGltZW91dCh0aW1lckV4cGlyZWQsIHdhaXQpO1xuICAgICAgICAvLyBJbnZva2UgdGhlIGxlYWRpbmcgZWRnZS5cbiAgICAgICAgcmV0dXJuIGxlYWRpbmcgPyBpbnZva2VGdW5jKHRpbWUpIDogcmVzdWx0O1xuICAgICAgfVxuXG4gICAgICBmdW5jdGlvbiByZW1haW5pbmdXYWl0KHRpbWUpIHtcbiAgICAgICAgdmFyIHRpbWVTaW5jZUxhc3RDYWxsID0gdGltZSAtIGxhc3RDYWxsVGltZSxcbiAgICAgICAgICAgIHRpbWVTaW5jZUxhc3RJbnZva2UgPSB0aW1lIC0gbGFzdEludm9rZVRpbWUsXG4gICAgICAgICAgICB0aW1lV2FpdGluZyA9IHdhaXQgLSB0aW1lU2luY2VMYXN0Q2FsbDtcblxuICAgICAgICByZXR1cm4gbWF4aW5nXG4gICAgICAgICAgPyBuYXRpdmVNaW4odGltZVdhaXRpbmcsIG1heFdhaXQgLSB0aW1lU2luY2VMYXN0SW52b2tlKVxuICAgICAgICAgIDogdGltZVdhaXRpbmc7XG4gICAgICB9XG5cbiAgICAgIGZ1bmN0aW9uIHNob3VsZEludm9rZSh0aW1lKSB7XG4gICAgICAgIHZhciB0aW1lU2luY2VMYXN0Q2FsbCA9IHRpbWUgLSBsYXN0Q2FsbFRpbWUsXG4gICAgICAgICAgICB0aW1lU2luY2VMYXN0SW52b2tlID0gdGltZSAtIGxhc3RJbnZva2VUaW1lO1xuXG4gICAgICAgIC8vIEVpdGhlciB0aGlzIGlzIHRoZSBmaXJzdCBjYWxsLCBhY3Rpdml0eSBoYXMgc3RvcHBlZCBhbmQgd2UncmUgYXQgdGhlXG4gICAgICAgIC8vIHRyYWlsaW5nIGVkZ2UsIHRoZSBzeXN0ZW0gdGltZSBoYXMgZ29uZSBiYWNrd2FyZHMgYW5kIHdlJ3JlIHRyZWF0aW5nXG4gICAgICAgIC8vIGl0IGFzIHRoZSB0cmFpbGluZyBlZGdlLCBvciB3ZSd2ZSBoaXQgdGhlIGBtYXhXYWl0YCBsaW1pdC5cbiAgICAgICAgcmV0dXJuIChsYXN0Q2FsbFRpbWUgPT09IHVuZGVmaW5lZCB8fCAodGltZVNpbmNlTGFzdENhbGwgPj0gd2FpdCkgfHxcbiAgICAgICAgICAodGltZVNpbmNlTGFzdENhbGwgPCAwKSB8fCAobWF4aW5nICYmIHRpbWVTaW5jZUxhc3RJbnZva2UgPj0gbWF4V2FpdCkpO1xuICAgICAgfVxuXG4gICAgICBmdW5jdGlvbiB0aW1lckV4cGlyZWQoKSB7XG4gICAgICAgIHZhciB0aW1lID0gbm93KCk7XG4gICAgICAgIGlmIChzaG91bGRJbnZva2UodGltZSkpIHtcbiAgICAgICAgICByZXR1cm4gdHJhaWxpbmdFZGdlKHRpbWUpO1xuICAgICAgICB9XG4gICAgICAgIC8vIFJlc3RhcnQgdGhlIHRpbWVyLlxuICAgICAgICB0aW1lcklkID0gc2V0VGltZW91dCh0aW1lckV4cGlyZWQsIHJlbWFpbmluZ1dhaXQodGltZSkpO1xuICAgICAgfVxuXG4gICAgICBmdW5jdGlvbiB0cmFpbGluZ0VkZ2UodGltZSkge1xuICAgICAgICB0aW1lcklkID0gdW5kZWZpbmVkO1xuXG4gICAgICAgIC8vIE9ubHkgaW52b2tlIGlmIHdlIGhhdmUgYGxhc3RBcmdzYCB3aGljaCBtZWFucyBgZnVuY2AgaGFzIGJlZW5cbiAgICAgICAgLy8gZGVib3VuY2VkIGF0IGxlYXN0IG9uY2UuXG4gICAgICAgIGlmICh0cmFpbGluZyAmJiBsYXN0QXJncykge1xuICAgICAgICAgIHJldHVybiBpbnZva2VGdW5jKHRpbWUpO1xuICAgICAgICB9XG4gICAgICAgIGxhc3RBcmdzID0gbGFzdFRoaXMgPSB1bmRlZmluZWQ7XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICB9XG5cbiAgICAgIGZ1bmN0aW9uIGNhbmNlbCgpIHtcbiAgICAgICAgaWYgKHRpbWVySWQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIGNsZWFyVGltZW91dCh0aW1lcklkKTtcbiAgICAgICAgfVxuICAgICAgICBsYXN0SW52b2tlVGltZSA9IDA7XG4gICAgICAgIGxhc3RBcmdzID0gbGFzdENhbGxUaW1lID0gbGFzdFRoaXMgPSB0aW1lcklkID0gdW5kZWZpbmVkO1xuICAgICAgfVxuXG4gICAgICBmdW5jdGlvbiBmbHVzaCgpIHtcbiAgICAgICAgcmV0dXJuIHRpbWVySWQgPT09IHVuZGVmaW5lZCA/IHJlc3VsdCA6IHRyYWlsaW5nRWRnZShub3coKSk7XG4gICAgICB9XG5cbiAgICAgIGZ1bmN0aW9uIGRlYm91bmNlZCgpIHtcbiAgICAgICAgdmFyIHRpbWUgPSBub3coKSxcbiAgICAgICAgICAgIGlzSW52b2tpbmcgPSBzaG91bGRJbnZva2UodGltZSk7XG5cbiAgICAgICAgbGFzdEFyZ3MgPSBhcmd1bWVudHM7XG4gICAgICAgIGxhc3RUaGlzID0gdGhpcztcbiAgICAgICAgbGFzdENhbGxUaW1lID0gdGltZTtcblxuICAgICAgICBpZiAoaXNJbnZva2luZykge1xuICAgICAgICAgIGlmICh0aW1lcklkID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHJldHVybiBsZWFkaW5nRWRnZShsYXN0Q2FsbFRpbWUpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAobWF4aW5nKSB7XG4gICAgICAgICAgICAvLyBIYW5kbGUgaW52b2NhdGlvbnMgaW4gYSB0aWdodCBsb29wLlxuICAgICAgICAgICAgY2xlYXJUaW1lb3V0KHRpbWVySWQpO1xuICAgICAgICAgICAgdGltZXJJZCA9IHNldFRpbWVvdXQodGltZXJFeHBpcmVkLCB3YWl0KTtcbiAgICAgICAgICAgIHJldHVybiBpbnZva2VGdW5jKGxhc3RDYWxsVGltZSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmICh0aW1lcklkID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICB0aW1lcklkID0gc2V0VGltZW91dCh0aW1lckV4cGlyZWQsIHdhaXQpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICB9XG4gICAgICBkZWJvdW5jZWQuY2FuY2VsID0gY2FuY2VsO1xuICAgICAgZGVib3VuY2VkLmZsdXNoID0gZmx1c2g7XG4gICAgICByZXR1cm4gZGVib3VuY2VkO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIERlZmVycyBpbnZva2luZyB0aGUgYGZ1bmNgIHVudGlsIHRoZSBjdXJyZW50IGNhbGwgc3RhY2sgaGFzIGNsZWFyZWQuIEFueVxuICAgICAqIGFkZGl0aW9uYWwgYXJndW1lbnRzIGFyZSBwcm92aWRlZCB0byBgZnVuY2Agd2hlbiBpdCdzIGludm9rZWQuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMC4xLjBcbiAgICAgKiBAY2F0ZWdvcnkgRnVuY3Rpb25cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byBkZWZlci5cbiAgICAgKiBAcGFyYW0gey4uLip9IFthcmdzXSBUaGUgYXJndW1lbnRzIHRvIGludm9rZSBgZnVuY2Agd2l0aC5cbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBSZXR1cm5zIHRoZSB0aW1lciBpZC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5kZWZlcihmdW5jdGlvbih0ZXh0KSB7XG4gICAgICogICBjb25zb2xlLmxvZyh0ZXh0KTtcbiAgICAgKiB9LCAnZGVmZXJyZWQnKTtcbiAgICAgKiAvLyA9PiBMb2dzICdkZWZlcnJlZCcgYWZ0ZXIgb25lIG1pbGxpc2Vjb25kLlxuICAgICAqL1xuICAgIHZhciBkZWZlciA9IGJhc2VSZXN0KGZ1bmN0aW9uKGZ1bmMsIGFyZ3MpIHtcbiAgICAgIHJldHVybiBiYXNlRGVsYXkoZnVuYywgMSwgYXJncyk7XG4gICAgfSk7XG5cbiAgICAvKipcbiAgICAgKiBJbnZva2VzIGBmdW5jYCBhZnRlciBgd2FpdGAgbWlsbGlzZWNvbmRzLiBBbnkgYWRkaXRpb25hbCBhcmd1bWVudHMgYXJlXG4gICAgICogcHJvdmlkZWQgdG8gYGZ1bmNgIHdoZW4gaXQncyBpbnZva2VkLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDAuMS4wXG4gICAgICogQGNhdGVnb3J5IEZ1bmN0aW9uXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gZnVuYyBUaGUgZnVuY3Rpb24gdG8gZGVsYXkuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHdhaXQgVGhlIG51bWJlciBvZiBtaWxsaXNlY29uZHMgdG8gZGVsYXkgaW52b2NhdGlvbi5cbiAgICAgKiBAcGFyYW0gey4uLip9IFthcmdzXSBUaGUgYXJndW1lbnRzIHRvIGludm9rZSBgZnVuY2Agd2l0aC5cbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBSZXR1cm5zIHRoZSB0aW1lciBpZC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5kZWxheShmdW5jdGlvbih0ZXh0KSB7XG4gICAgICogICBjb25zb2xlLmxvZyh0ZXh0KTtcbiAgICAgKiB9LCAxMDAwLCAnbGF0ZXInKTtcbiAgICAgKiAvLyA9PiBMb2dzICdsYXRlcicgYWZ0ZXIgb25lIHNlY29uZC5cbiAgICAgKi9cbiAgICB2YXIgZGVsYXkgPSBiYXNlUmVzdChmdW5jdGlvbihmdW5jLCB3YWl0LCBhcmdzKSB7XG4gICAgICByZXR1cm4gYmFzZURlbGF5KGZ1bmMsIHRvTnVtYmVyKHdhaXQpIHx8IDAsIGFyZ3MpO1xuICAgIH0pO1xuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIGZ1bmN0aW9uIHRoYXQgaW52b2tlcyBgZnVuY2Agd2l0aCBhcmd1bWVudHMgcmV2ZXJzZWQuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgRnVuY3Rpb25cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byBmbGlwIGFyZ3VtZW50cyBmb3IuXG4gICAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgZmxpcHBlZCBmdW5jdGlvbi5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIGZsaXBwZWQgPSBfLmZsaXAoZnVuY3Rpb24oKSB7XG4gICAgICogICByZXR1cm4gXy50b0FycmF5KGFyZ3VtZW50cyk7XG4gICAgICogfSk7XG4gICAgICpcbiAgICAgKiBmbGlwcGVkKCdhJywgJ2InLCAnYycsICdkJyk7XG4gICAgICogLy8gPT4gWydkJywgJ2MnLCAnYicsICdhJ11cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBmbGlwKGZ1bmMpIHtcbiAgICAgIHJldHVybiBjcmVhdGVXcmFwKGZ1bmMsIFdSQVBfRkxJUF9GTEFHKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgZnVuY3Rpb24gdGhhdCBtZW1vaXplcyB0aGUgcmVzdWx0IG9mIGBmdW5jYC4gSWYgYHJlc29sdmVyYCBpc1xuICAgICAqIHByb3ZpZGVkLCBpdCBkZXRlcm1pbmVzIHRoZSBjYWNoZSBrZXkgZm9yIHN0b3JpbmcgdGhlIHJlc3VsdCBiYXNlZCBvbiB0aGVcbiAgICAgKiBhcmd1bWVudHMgcHJvdmlkZWQgdG8gdGhlIG1lbW9pemVkIGZ1bmN0aW9uLiBCeSBkZWZhdWx0LCB0aGUgZmlyc3QgYXJndW1lbnRcbiAgICAgKiBwcm92aWRlZCB0byB0aGUgbWVtb2l6ZWQgZnVuY3Rpb24gaXMgdXNlZCBhcyB0aGUgbWFwIGNhY2hlIGtleS4gVGhlIGBmdW5jYFxuICAgICAqIGlzIGludm9rZWQgd2l0aCB0aGUgYHRoaXNgIGJpbmRpbmcgb2YgdGhlIG1lbW9pemVkIGZ1bmN0aW9uLlxuICAgICAqXG4gICAgICogKipOb3RlOioqIFRoZSBjYWNoZSBpcyBleHBvc2VkIGFzIHRoZSBgY2FjaGVgIHByb3BlcnR5IG9uIHRoZSBtZW1vaXplZFxuICAgICAqIGZ1bmN0aW9uLiBJdHMgY3JlYXRpb24gbWF5IGJlIGN1c3RvbWl6ZWQgYnkgcmVwbGFjaW5nIHRoZSBgXy5tZW1vaXplLkNhY2hlYFxuICAgICAqIGNvbnN0cnVjdG9yIHdpdGggb25lIHdob3NlIGluc3RhbmNlcyBpbXBsZW1lbnQgdGhlXG4gICAgICogW2BNYXBgXShodHRwOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi83LjAvI3NlYy1wcm9wZXJ0aWVzLW9mLXRoZS1tYXAtcHJvdG90eXBlLW9iamVjdClcbiAgICAgKiBtZXRob2QgaW50ZXJmYWNlIG9mIGBjbGVhcmAsIGBkZWxldGVgLCBgZ2V0YCwgYGhhc2AsIGFuZCBgc2V0YC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAwLjEuMFxuICAgICAqIEBjYXRlZ29yeSBGdW5jdGlvblxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIGhhdmUgaXRzIG91dHB1dCBtZW1vaXplZC5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbcmVzb2x2ZXJdIFRoZSBmdW5jdGlvbiB0byByZXNvbHZlIHRoZSBjYWNoZSBrZXkuXG4gICAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgbWVtb2l6ZWQgZnVuY3Rpb24uXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciBvYmplY3QgPSB7ICdhJzogMSwgJ2InOiAyIH07XG4gICAgICogdmFyIG90aGVyID0geyAnYyc6IDMsICdkJzogNCB9O1xuICAgICAqXG4gICAgICogdmFyIHZhbHVlcyA9IF8ubWVtb2l6ZShfLnZhbHVlcyk7XG4gICAgICogdmFsdWVzKG9iamVjdCk7XG4gICAgICogLy8gPT4gWzEsIDJdXG4gICAgICpcbiAgICAgKiB2YWx1ZXMob3RoZXIpO1xuICAgICAqIC8vID0+IFszLCA0XVxuICAgICAqXG4gICAgICogb2JqZWN0LmEgPSAyO1xuICAgICAqIHZhbHVlcyhvYmplY3QpO1xuICAgICAqIC8vID0+IFsxLCAyXVxuICAgICAqXG4gICAgICogLy8gTW9kaWZ5IHRoZSByZXN1bHQgY2FjaGUuXG4gICAgICogdmFsdWVzLmNhY2hlLnNldChvYmplY3QsIFsnYScsICdiJ10pO1xuICAgICAqIHZhbHVlcyhvYmplY3QpO1xuICAgICAqIC8vID0+IFsnYScsICdiJ11cbiAgICAgKlxuICAgICAqIC8vIFJlcGxhY2UgYF8ubWVtb2l6ZS5DYWNoZWAuXG4gICAgICogXy5tZW1vaXplLkNhY2hlID0gV2Vha01hcDtcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBtZW1vaXplKGZ1bmMsIHJlc29sdmVyKSB7XG4gICAgICBpZiAodHlwZW9mIGZ1bmMgIT0gJ2Z1bmN0aW9uJyB8fCAocmVzb2x2ZXIgIT0gbnVsbCAmJiB0eXBlb2YgcmVzb2x2ZXIgIT0gJ2Z1bmN0aW9uJykpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihGVU5DX0VSUk9SX1RFWFQpO1xuICAgICAgfVxuICAgICAgdmFyIG1lbW9pemVkID0gZnVuY3Rpb24oKSB7XG4gICAgICAgIHZhciBhcmdzID0gYXJndW1lbnRzLFxuICAgICAgICAgICAga2V5ID0gcmVzb2x2ZXIgPyByZXNvbHZlci5hcHBseSh0aGlzLCBhcmdzKSA6IGFyZ3NbMF0sXG4gICAgICAgICAgICBjYWNoZSA9IG1lbW9pemVkLmNhY2hlO1xuXG4gICAgICAgIGlmIChjYWNoZS5oYXMoa2V5KSkge1xuICAgICAgICAgIHJldHVybiBjYWNoZS5nZXQoa2V5KTtcbiAgICAgICAgfVxuICAgICAgICB2YXIgcmVzdWx0ID0gZnVuYy5hcHBseSh0aGlzLCBhcmdzKTtcbiAgICAgICAgbWVtb2l6ZWQuY2FjaGUgPSBjYWNoZS5zZXQoa2V5LCByZXN1bHQpIHx8IGNhY2hlO1xuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgfTtcbiAgICAgIG1lbW9pemVkLmNhY2hlID0gbmV3IChtZW1vaXplLkNhY2hlIHx8IE1hcENhY2hlKTtcbiAgICAgIHJldHVybiBtZW1vaXplZDtcbiAgICB9XG5cbiAgICAvLyBFeHBvc2UgYE1hcENhY2hlYC5cbiAgICBtZW1vaXplLkNhY2hlID0gTWFwQ2FjaGU7XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgZnVuY3Rpb24gdGhhdCBuZWdhdGVzIHRoZSByZXN1bHQgb2YgdGhlIHByZWRpY2F0ZSBgZnVuY2AuIFRoZVxuICAgICAqIGBmdW5jYCBwcmVkaWNhdGUgaXMgaW52b2tlZCB3aXRoIHRoZSBgdGhpc2AgYmluZGluZyBhbmQgYXJndW1lbnRzIG9mIHRoZVxuICAgICAqIGNyZWF0ZWQgZnVuY3Rpb24uXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMy4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgRnVuY3Rpb25cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBwcmVkaWNhdGUgVGhlIHByZWRpY2F0ZSB0byBuZWdhdGUuXG4gICAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgbmVnYXRlZCBmdW5jdGlvbi5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogZnVuY3Rpb24gaXNFdmVuKG4pIHtcbiAgICAgKiAgIHJldHVybiBuICUgMiA9PSAwO1xuICAgICAqIH1cbiAgICAgKlxuICAgICAqIF8uZmlsdGVyKFsxLCAyLCAzLCA0LCA1LCA2XSwgXy5uZWdhdGUoaXNFdmVuKSk7XG4gICAgICogLy8gPT4gWzEsIDMsIDVdXG4gICAgICovXG4gICAgZnVuY3Rpb24gbmVnYXRlKHByZWRpY2F0ZSkge1xuICAgICAgaWYgKHR5cGVvZiBwcmVkaWNhdGUgIT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKEZVTkNfRVJST1JfVEVYVCk7XG4gICAgICB9XG4gICAgICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgICAgIHZhciBhcmdzID0gYXJndW1lbnRzO1xuICAgICAgICBzd2l0Y2ggKGFyZ3MubGVuZ3RoKSB7XG4gICAgICAgICAgY2FzZSAwOiByZXR1cm4gIXByZWRpY2F0ZS5jYWxsKHRoaXMpO1xuICAgICAgICAgIGNhc2UgMTogcmV0dXJuICFwcmVkaWNhdGUuY2FsbCh0aGlzLCBhcmdzWzBdKTtcbiAgICAgICAgICBjYXNlIDI6IHJldHVybiAhcHJlZGljYXRlLmNhbGwodGhpcywgYXJnc1swXSwgYXJnc1sxXSk7XG4gICAgICAgICAgY2FzZSAzOiByZXR1cm4gIXByZWRpY2F0ZS5jYWxsKHRoaXMsIGFyZ3NbMF0sIGFyZ3NbMV0sIGFyZ3NbMl0pO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiAhcHJlZGljYXRlLmFwcGx5KHRoaXMsIGFyZ3MpO1xuICAgICAgfTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgZnVuY3Rpb24gdGhhdCBpcyByZXN0cmljdGVkIHRvIGludm9raW5nIGBmdW5jYCBvbmNlLiBSZXBlYXQgY2FsbHNcbiAgICAgKiB0byB0aGUgZnVuY3Rpb24gcmV0dXJuIHRoZSB2YWx1ZSBvZiB0aGUgZmlyc3QgaW52b2NhdGlvbi4gVGhlIGBmdW5jYCBpc1xuICAgICAqIGludm9rZWQgd2l0aCB0aGUgYHRoaXNgIGJpbmRpbmcgYW5kIGFyZ3VtZW50cyBvZiB0aGUgY3JlYXRlZCBmdW5jdGlvbi5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAwLjEuMFxuICAgICAqIEBjYXRlZ29yeSBGdW5jdGlvblxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIHJlc3RyaWN0LlxuICAgICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IHJlc3RyaWN0ZWQgZnVuY3Rpb24uXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciBpbml0aWFsaXplID0gXy5vbmNlKGNyZWF0ZUFwcGxpY2F0aW9uKTtcbiAgICAgKiBpbml0aWFsaXplKCk7XG4gICAgICogaW5pdGlhbGl6ZSgpO1xuICAgICAqIC8vID0+IGBjcmVhdGVBcHBsaWNhdGlvbmAgaXMgaW52b2tlZCBvbmNlXG4gICAgICovXG4gICAgZnVuY3Rpb24gb25jZShmdW5jKSB7XG4gICAgICByZXR1cm4gYmVmb3JlKDIsIGZ1bmMpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBmdW5jdGlvbiB0aGF0IGludm9rZXMgYGZ1bmNgIHdpdGggaXRzIGFyZ3VtZW50cyB0cmFuc2Zvcm1lZC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAc2luY2UgNC4wLjBcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBjYXRlZ29yeSBGdW5jdGlvblxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIHdyYXAuXG4gICAgICogQHBhcmFtIHsuLi4oRnVuY3Rpb258RnVuY3Rpb25bXSl9IFt0cmFuc2Zvcm1zPVtfLmlkZW50aXR5XV1cbiAgICAgKiAgVGhlIGFyZ3VtZW50IHRyYW5zZm9ybXMuXG4gICAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgZnVuY3Rpb24uXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIGZ1bmN0aW9uIGRvdWJsZWQobikge1xuICAgICAqICAgcmV0dXJuIG4gKiAyO1xuICAgICAqIH1cbiAgICAgKlxuICAgICAqIGZ1bmN0aW9uIHNxdWFyZShuKSB7XG4gICAgICogICByZXR1cm4gbiAqIG47XG4gICAgICogfVxuICAgICAqXG4gICAgICogdmFyIGZ1bmMgPSBfLm92ZXJBcmdzKGZ1bmN0aW9uKHgsIHkpIHtcbiAgICAgKiAgIHJldHVybiBbeCwgeV07XG4gICAgICogfSwgW3NxdWFyZSwgZG91YmxlZF0pO1xuICAgICAqXG4gICAgICogZnVuYyg5LCAzKTtcbiAgICAgKiAvLyA9PiBbODEsIDZdXG4gICAgICpcbiAgICAgKiBmdW5jKDEwLCA1KTtcbiAgICAgKiAvLyA9PiBbMTAwLCAxMF1cbiAgICAgKi9cbiAgICB2YXIgb3ZlckFyZ3MgPSBjYXN0UmVzdChmdW5jdGlvbihmdW5jLCB0cmFuc2Zvcm1zKSB7XG4gICAgICB0cmFuc2Zvcm1zID0gKHRyYW5zZm9ybXMubGVuZ3RoID09IDEgJiYgaXNBcnJheSh0cmFuc2Zvcm1zWzBdKSlcbiAgICAgICAgPyBhcnJheU1hcCh0cmFuc2Zvcm1zWzBdLCBiYXNlVW5hcnkoZ2V0SXRlcmF0ZWUoKSkpXG4gICAgICAgIDogYXJyYXlNYXAoYmFzZUZsYXR0ZW4odHJhbnNmb3JtcywgMSksIGJhc2VVbmFyeShnZXRJdGVyYXRlZSgpKSk7XG5cbiAgICAgIHZhciBmdW5jc0xlbmd0aCA9IHRyYW5zZm9ybXMubGVuZ3RoO1xuICAgICAgcmV0dXJuIGJhc2VSZXN0KGZ1bmN0aW9uKGFyZ3MpIHtcbiAgICAgICAgdmFyIGluZGV4ID0gLTEsXG4gICAgICAgICAgICBsZW5ndGggPSBuYXRpdmVNaW4oYXJncy5sZW5ndGgsIGZ1bmNzTGVuZ3RoKTtcblxuICAgICAgICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgICAgICAgIGFyZ3NbaW5kZXhdID0gdHJhbnNmb3Jtc1tpbmRleF0uY2FsbCh0aGlzLCBhcmdzW2luZGV4XSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGFwcGx5KGZ1bmMsIHRoaXMsIGFyZ3MpO1xuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgZnVuY3Rpb24gdGhhdCBpbnZva2VzIGBmdW5jYCB3aXRoIGBwYXJ0aWFsc2AgcHJlcGVuZGVkIHRvIHRoZVxuICAgICAqIGFyZ3VtZW50cyBpdCByZWNlaXZlcy4gVGhpcyBtZXRob2QgaXMgbGlrZSBgXy5iaW5kYCBleGNlcHQgaXQgZG9lcyAqKm5vdCoqXG4gICAgICogYWx0ZXIgdGhlIGB0aGlzYCBiaW5kaW5nLlxuICAgICAqXG4gICAgICogVGhlIGBfLnBhcnRpYWwucGxhY2Vob2xkZXJgIHZhbHVlLCB3aGljaCBkZWZhdWx0cyB0byBgX2AgaW4gbW9ub2xpdGhpY1xuICAgICAqIGJ1aWxkcywgbWF5IGJlIHVzZWQgYXMgYSBwbGFjZWhvbGRlciBmb3IgcGFydGlhbGx5IGFwcGxpZWQgYXJndW1lbnRzLlxuICAgICAqXG4gICAgICogKipOb3RlOioqIFRoaXMgbWV0aG9kIGRvZXNuJ3Qgc2V0IHRoZSBcImxlbmd0aFwiIHByb3BlcnR5IG9mIHBhcnRpYWxseVxuICAgICAqIGFwcGxpZWQgZnVuY3Rpb25zLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDAuMi4wXG4gICAgICogQGNhdGVnb3J5IEZ1bmN0aW9uXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gZnVuYyBUaGUgZnVuY3Rpb24gdG8gcGFydGlhbGx5IGFwcGx5IGFyZ3VtZW50cyB0by5cbiAgICAgKiBAcGFyYW0gey4uLip9IFtwYXJ0aWFsc10gVGhlIGFyZ3VtZW50cyB0byBiZSBwYXJ0aWFsbHkgYXBwbGllZC5cbiAgICAgKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBwYXJ0aWFsbHkgYXBwbGllZCBmdW5jdGlvbi5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogZnVuY3Rpb24gZ3JlZXQoZ3JlZXRpbmcsIG5hbWUpIHtcbiAgICAgKiAgIHJldHVybiBncmVldGluZyArICcgJyArIG5hbWU7XG4gICAgICogfVxuICAgICAqXG4gICAgICogdmFyIHNheUhlbGxvVG8gPSBfLnBhcnRpYWwoZ3JlZXQsICdoZWxsbycpO1xuICAgICAqIHNheUhlbGxvVG8oJ2ZyZWQnKTtcbiAgICAgKiAvLyA9PiAnaGVsbG8gZnJlZCdcbiAgICAgKlxuICAgICAqIC8vIFBhcnRpYWxseSBhcHBsaWVkIHdpdGggcGxhY2Vob2xkZXJzLlxuICAgICAqIHZhciBncmVldEZyZWQgPSBfLnBhcnRpYWwoZ3JlZXQsIF8sICdmcmVkJyk7XG4gICAgICogZ3JlZXRGcmVkKCdoaScpO1xuICAgICAqIC8vID0+ICdoaSBmcmVkJ1xuICAgICAqL1xuICAgIHZhciBwYXJ0aWFsID0gYmFzZVJlc3QoZnVuY3Rpb24oZnVuYywgcGFydGlhbHMpIHtcbiAgICAgIHZhciBob2xkZXJzID0gcmVwbGFjZUhvbGRlcnMocGFydGlhbHMsIGdldEhvbGRlcihwYXJ0aWFsKSk7XG4gICAgICByZXR1cm4gY3JlYXRlV3JhcChmdW5jLCBXUkFQX1BBUlRJQUxfRkxBRywgdW5kZWZpbmVkLCBwYXJ0aWFscywgaG9sZGVycyk7XG4gICAgfSk7XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIG1ldGhvZCBpcyBsaWtlIGBfLnBhcnRpYWxgIGV4Y2VwdCB0aGF0IHBhcnRpYWxseSBhcHBsaWVkIGFyZ3VtZW50c1xuICAgICAqIGFyZSBhcHBlbmRlZCB0byB0aGUgYXJndW1lbnRzIGl0IHJlY2VpdmVzLlxuICAgICAqXG4gICAgICogVGhlIGBfLnBhcnRpYWxSaWdodC5wbGFjZWhvbGRlcmAgdmFsdWUsIHdoaWNoIGRlZmF1bHRzIHRvIGBfYCBpbiBtb25vbGl0aGljXG4gICAgICogYnVpbGRzLCBtYXkgYmUgdXNlZCBhcyBhIHBsYWNlaG9sZGVyIGZvciBwYXJ0aWFsbHkgYXBwbGllZCBhcmd1bWVudHMuXG4gICAgICpcbiAgICAgKiAqKk5vdGU6KiogVGhpcyBtZXRob2QgZG9lc24ndCBzZXQgdGhlIFwibGVuZ3RoXCIgcHJvcGVydHkgb2YgcGFydGlhbGx5XG4gICAgICogYXBwbGllZCBmdW5jdGlvbnMuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMS4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgRnVuY3Rpb25cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byBwYXJ0aWFsbHkgYXBwbHkgYXJndW1lbnRzIHRvLlxuICAgICAqIEBwYXJhbSB7Li4uKn0gW3BhcnRpYWxzXSBUaGUgYXJndW1lbnRzIHRvIGJlIHBhcnRpYWxseSBhcHBsaWVkLlxuICAgICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IHBhcnRpYWxseSBhcHBsaWVkIGZ1bmN0aW9uLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBmdW5jdGlvbiBncmVldChncmVldGluZywgbmFtZSkge1xuICAgICAqICAgcmV0dXJuIGdyZWV0aW5nICsgJyAnICsgbmFtZTtcbiAgICAgKiB9XG4gICAgICpcbiAgICAgKiB2YXIgZ3JlZXRGcmVkID0gXy5wYXJ0aWFsUmlnaHQoZ3JlZXQsICdmcmVkJyk7XG4gICAgICogZ3JlZXRGcmVkKCdoaScpO1xuICAgICAqIC8vID0+ICdoaSBmcmVkJ1xuICAgICAqXG4gICAgICogLy8gUGFydGlhbGx5IGFwcGxpZWQgd2l0aCBwbGFjZWhvbGRlcnMuXG4gICAgICogdmFyIHNheUhlbGxvVG8gPSBfLnBhcnRpYWxSaWdodChncmVldCwgJ2hlbGxvJywgXyk7XG4gICAgICogc2F5SGVsbG9UbygnZnJlZCcpO1xuICAgICAqIC8vID0+ICdoZWxsbyBmcmVkJ1xuICAgICAqL1xuICAgIHZhciBwYXJ0aWFsUmlnaHQgPSBiYXNlUmVzdChmdW5jdGlvbihmdW5jLCBwYXJ0aWFscykge1xuICAgICAgdmFyIGhvbGRlcnMgPSByZXBsYWNlSG9sZGVycyhwYXJ0aWFscywgZ2V0SG9sZGVyKHBhcnRpYWxSaWdodCkpO1xuICAgICAgcmV0dXJuIGNyZWF0ZVdyYXAoZnVuYywgV1JBUF9QQVJUSUFMX1JJR0hUX0ZMQUcsIHVuZGVmaW5lZCwgcGFydGlhbHMsIGhvbGRlcnMpO1xuICAgIH0pO1xuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIGZ1bmN0aW9uIHRoYXQgaW52b2tlcyBgZnVuY2Agd2l0aCBhcmd1bWVudHMgYXJyYW5nZWQgYWNjb3JkaW5nXG4gICAgICogdG8gdGhlIHNwZWNpZmllZCBgaW5kZXhlc2Agd2hlcmUgdGhlIGFyZ3VtZW50IHZhbHVlIGF0IHRoZSBmaXJzdCBpbmRleCBpc1xuICAgICAqIHByb3ZpZGVkIGFzIHRoZSBmaXJzdCBhcmd1bWVudCwgdGhlIGFyZ3VtZW50IHZhbHVlIGF0IHRoZSBzZWNvbmQgaW5kZXggaXNcbiAgICAgKiBwcm92aWRlZCBhcyB0aGUgc2Vjb25kIGFyZ3VtZW50LCBhbmQgc28gb24uXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMy4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgRnVuY3Rpb25cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byByZWFycmFuZ2UgYXJndW1lbnRzIGZvci5cbiAgICAgKiBAcGFyYW0gey4uLihudW1iZXJ8bnVtYmVyW10pfSBpbmRleGVzIFRoZSBhcnJhbmdlZCBhcmd1bWVudCBpbmRleGVzLlxuICAgICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IGZ1bmN0aW9uLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgcmVhcmdlZCA9IF8ucmVhcmcoZnVuY3Rpb24oYSwgYiwgYykge1xuICAgICAqICAgcmV0dXJuIFthLCBiLCBjXTtcbiAgICAgKiB9LCBbMiwgMCwgMV0pO1xuICAgICAqXG4gICAgICogcmVhcmdlZCgnYicsICdjJywgJ2EnKVxuICAgICAqIC8vID0+IFsnYScsICdiJywgJ2MnXVxuICAgICAqL1xuICAgIHZhciByZWFyZyA9IGZsYXRSZXN0KGZ1bmN0aW9uKGZ1bmMsIGluZGV4ZXMpIHtcbiAgICAgIHJldHVybiBjcmVhdGVXcmFwKGZ1bmMsIFdSQVBfUkVBUkdfRkxBRywgdW5kZWZpbmVkLCB1bmRlZmluZWQsIHVuZGVmaW5lZCwgaW5kZXhlcyk7XG4gICAgfSk7XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgZnVuY3Rpb24gdGhhdCBpbnZva2VzIGBmdW5jYCB3aXRoIHRoZSBgdGhpc2AgYmluZGluZyBvZiB0aGVcbiAgICAgKiBjcmVhdGVkIGZ1bmN0aW9uIGFuZCBhcmd1bWVudHMgZnJvbSBgc3RhcnRgIGFuZCBiZXlvbmQgcHJvdmlkZWQgYXNcbiAgICAgKiBhbiBhcnJheS5cbiAgICAgKlxuICAgICAqICoqTm90ZToqKiBUaGlzIG1ldGhvZCBpcyBiYXNlZCBvbiB0aGVcbiAgICAgKiBbcmVzdCBwYXJhbWV0ZXJdKGh0dHBzOi8vbWRuLmlvL3Jlc3RfcGFyYW1ldGVycykuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgRnVuY3Rpb25cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byBhcHBseSBhIHJlc3QgcGFyYW1ldGVyIHRvLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbc3RhcnQ9ZnVuYy5sZW5ndGgtMV0gVGhlIHN0YXJ0IHBvc2l0aW9uIG9mIHRoZSByZXN0IHBhcmFtZXRlci5cbiAgICAgKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBmdW5jdGlvbi5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIHNheSA9IF8ucmVzdChmdW5jdGlvbih3aGF0LCBuYW1lcykge1xuICAgICAqICAgcmV0dXJuIHdoYXQgKyAnICcgKyBfLmluaXRpYWwobmFtZXMpLmpvaW4oJywgJykgK1xuICAgICAqICAgICAoXy5zaXplKG5hbWVzKSA+IDEgPyAnLCAmICcgOiAnJykgKyBfLmxhc3QobmFtZXMpO1xuICAgICAqIH0pO1xuICAgICAqXG4gICAgICogc2F5KCdoZWxsbycsICdmcmVkJywgJ2Jhcm5leScsICdwZWJibGVzJyk7XG4gICAgICogLy8gPT4gJ2hlbGxvIGZyZWQsIGJhcm5leSwgJiBwZWJibGVzJ1xuICAgICAqL1xuICAgIGZ1bmN0aW9uIHJlc3QoZnVuYywgc3RhcnQpIHtcbiAgICAgIGlmICh0eXBlb2YgZnVuYyAhPSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoRlVOQ19FUlJPUl9URVhUKTtcbiAgICAgIH1cbiAgICAgIHN0YXJ0ID0gc3RhcnQgPT09IHVuZGVmaW5lZCA/IHN0YXJ0IDogdG9JbnRlZ2VyKHN0YXJ0KTtcbiAgICAgIHJldHVybiBiYXNlUmVzdChmdW5jLCBzdGFydCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIGZ1bmN0aW9uIHRoYXQgaW52b2tlcyBgZnVuY2Agd2l0aCB0aGUgYHRoaXNgIGJpbmRpbmcgb2YgdGhlXG4gICAgICogY3JlYXRlIGZ1bmN0aW9uIGFuZCBhbiBhcnJheSBvZiBhcmd1bWVudHMgbXVjaCBsaWtlXG4gICAgICogW2BGdW5jdGlvbiNhcHBseWBdKGh0dHA6Ly93d3cuZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi83LjAvI3NlYy1mdW5jdGlvbi5wcm90b3R5cGUuYXBwbHkpLlxuICAgICAqXG4gICAgICogKipOb3RlOioqIFRoaXMgbWV0aG9kIGlzIGJhc2VkIG9uIHRoZVxuICAgICAqIFtzcHJlYWQgb3BlcmF0b3JdKGh0dHBzOi8vbWRuLmlvL3NwcmVhZF9vcGVyYXRvcikuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMy4yLjBcbiAgICAgKiBAY2F0ZWdvcnkgRnVuY3Rpb25cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byBzcHJlYWQgYXJndW1lbnRzIG92ZXIuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtzdGFydD0wXSBUaGUgc3RhcnQgcG9zaXRpb24gb2YgdGhlIHNwcmVhZC5cbiAgICAgKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBmdW5jdGlvbi5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIHNheSA9IF8uc3ByZWFkKGZ1bmN0aW9uKHdobywgd2hhdCkge1xuICAgICAqICAgcmV0dXJuIHdobyArICcgc2F5cyAnICsgd2hhdDtcbiAgICAgKiB9KTtcbiAgICAgKlxuICAgICAqIHNheShbJ2ZyZWQnLCAnaGVsbG8nXSk7XG4gICAgICogLy8gPT4gJ2ZyZWQgc2F5cyBoZWxsbydcbiAgICAgKlxuICAgICAqIHZhciBudW1iZXJzID0gUHJvbWlzZS5hbGwoW1xuICAgICAqICAgUHJvbWlzZS5yZXNvbHZlKDQwKSxcbiAgICAgKiAgIFByb21pc2UucmVzb2x2ZSgzNilcbiAgICAgKiBdKTtcbiAgICAgKlxuICAgICAqIG51bWJlcnMudGhlbihfLnNwcmVhZChmdW5jdGlvbih4LCB5KSB7XG4gICAgICogICByZXR1cm4geCArIHk7XG4gICAgICogfSkpO1xuICAgICAqIC8vID0+IGEgUHJvbWlzZSBvZiA3NlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIHNwcmVhZChmdW5jLCBzdGFydCkge1xuICAgICAgaWYgKHR5cGVvZiBmdW5jICE9ICdmdW5jdGlvbicpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihGVU5DX0VSUk9SX1RFWFQpO1xuICAgICAgfVxuICAgICAgc3RhcnQgPSBzdGFydCA9PSBudWxsID8gMCA6IG5hdGl2ZU1heCh0b0ludGVnZXIoc3RhcnQpLCAwKTtcbiAgICAgIHJldHVybiBiYXNlUmVzdChmdW5jdGlvbihhcmdzKSB7XG4gICAgICAgIHZhciBhcnJheSA9IGFyZ3Nbc3RhcnRdLFxuICAgICAgICAgICAgb3RoZXJBcmdzID0gY2FzdFNsaWNlKGFyZ3MsIDAsIHN0YXJ0KTtcblxuICAgICAgICBpZiAoYXJyYXkpIHtcbiAgICAgICAgICBhcnJheVB1c2gob3RoZXJBcmdzLCBhcnJheSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGFwcGx5KGZ1bmMsIHRoaXMsIG90aGVyQXJncyk7XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgdGhyb3R0bGVkIGZ1bmN0aW9uIHRoYXQgb25seSBpbnZva2VzIGBmdW5jYCBhdCBtb3N0IG9uY2UgcGVyXG4gICAgICogZXZlcnkgYHdhaXRgIG1pbGxpc2Vjb25kcy4gVGhlIHRocm90dGxlZCBmdW5jdGlvbiBjb21lcyB3aXRoIGEgYGNhbmNlbGBcbiAgICAgKiBtZXRob2QgdG8gY2FuY2VsIGRlbGF5ZWQgYGZ1bmNgIGludm9jYXRpb25zIGFuZCBhIGBmbHVzaGAgbWV0aG9kIHRvXG4gICAgICogaW1tZWRpYXRlbHkgaW52b2tlIHRoZW0uIFByb3ZpZGUgYG9wdGlvbnNgIHRvIGluZGljYXRlIHdoZXRoZXIgYGZ1bmNgXG4gICAgICogc2hvdWxkIGJlIGludm9rZWQgb24gdGhlIGxlYWRpbmcgYW5kL29yIHRyYWlsaW5nIGVkZ2Ugb2YgdGhlIGB3YWl0YFxuICAgICAqIHRpbWVvdXQuIFRoZSBgZnVuY2AgaXMgaW52b2tlZCB3aXRoIHRoZSBsYXN0IGFyZ3VtZW50cyBwcm92aWRlZCB0byB0aGVcbiAgICAgKiB0aHJvdHRsZWQgZnVuY3Rpb24uIFN1YnNlcXVlbnQgY2FsbHMgdG8gdGhlIHRocm90dGxlZCBmdW5jdGlvbiByZXR1cm4gdGhlXG4gICAgICogcmVzdWx0IG9mIHRoZSBsYXN0IGBmdW5jYCBpbnZvY2F0aW9uLlxuICAgICAqXG4gICAgICogKipOb3RlOioqIElmIGBsZWFkaW5nYCBhbmQgYHRyYWlsaW5nYCBvcHRpb25zIGFyZSBgdHJ1ZWAsIGBmdW5jYCBpc1xuICAgICAqIGludm9rZWQgb24gdGhlIHRyYWlsaW5nIGVkZ2Ugb2YgdGhlIHRpbWVvdXQgb25seSBpZiB0aGUgdGhyb3R0bGVkIGZ1bmN0aW9uXG4gICAgICogaXMgaW52b2tlZCBtb3JlIHRoYW4gb25jZSBkdXJpbmcgdGhlIGB3YWl0YCB0aW1lb3V0LlxuICAgICAqXG4gICAgICogSWYgYHdhaXRgIGlzIGAwYCBhbmQgYGxlYWRpbmdgIGlzIGBmYWxzZWAsIGBmdW5jYCBpbnZvY2F0aW9uIGlzIGRlZmVycmVkXG4gICAgICogdW50aWwgdG8gdGhlIG5leHQgdGljaywgc2ltaWxhciB0byBgc2V0VGltZW91dGAgd2l0aCBhIHRpbWVvdXQgb2YgYDBgLlxuICAgICAqXG4gICAgICogU2VlIFtEYXZpZCBDb3JiYWNobydzIGFydGljbGVdKGh0dHBzOi8vY3NzLXRyaWNrcy5jb20vZGVib3VuY2luZy10aHJvdHRsaW5nLWV4cGxhaW5lZC1leGFtcGxlcy8pXG4gICAgICogZm9yIGRldGFpbHMgb3ZlciB0aGUgZGlmZmVyZW5jZXMgYmV0d2VlbiBgXy50aHJvdHRsZWAgYW5kIGBfLmRlYm91bmNlYC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAwLjEuMFxuICAgICAqIEBjYXRlZ29yeSBGdW5jdGlvblxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIHRocm90dGxlLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbd2FpdD0wXSBUaGUgbnVtYmVyIG9mIG1pbGxpc2Vjb25kcyB0byB0aHJvdHRsZSBpbnZvY2F0aW9ucyB0by5cbiAgICAgKiBAcGFyYW0ge09iamVjdH0gW29wdGlvbnM9e31dIFRoZSBvcHRpb25zIG9iamVjdC5cbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW59IFtvcHRpb25zLmxlYWRpbmc9dHJ1ZV1cbiAgICAgKiAgU3BlY2lmeSBpbnZva2luZyBvbiB0aGUgbGVhZGluZyBlZGdlIG9mIHRoZSB0aW1lb3V0LlxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbn0gW29wdGlvbnMudHJhaWxpbmc9dHJ1ZV1cbiAgICAgKiAgU3BlY2lmeSBpbnZva2luZyBvbiB0aGUgdHJhaWxpbmcgZWRnZSBvZiB0aGUgdGltZW91dC5cbiAgICAgKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyB0aHJvdHRsZWQgZnVuY3Rpb24uXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIC8vIEF2b2lkIGV4Y2Vzc2l2ZWx5IHVwZGF0aW5nIHRoZSBwb3NpdGlvbiB3aGlsZSBzY3JvbGxpbmcuXG4gICAgICogalF1ZXJ5KHdpbmRvdykub24oJ3Njcm9sbCcsIF8udGhyb3R0bGUodXBkYXRlUG9zaXRpb24sIDEwMCkpO1xuICAgICAqXG4gICAgICogLy8gSW52b2tlIGByZW5ld1Rva2VuYCB3aGVuIHRoZSBjbGljayBldmVudCBpcyBmaXJlZCwgYnV0IG5vdCBtb3JlIHRoYW4gb25jZSBldmVyeSA1IG1pbnV0ZXMuXG4gICAgICogdmFyIHRocm90dGxlZCA9IF8udGhyb3R0bGUocmVuZXdUb2tlbiwgMzAwMDAwLCB7ICd0cmFpbGluZyc6IGZhbHNlIH0pO1xuICAgICAqIGpRdWVyeShlbGVtZW50KS5vbignY2xpY2snLCB0aHJvdHRsZWQpO1xuICAgICAqXG4gICAgICogLy8gQ2FuY2VsIHRoZSB0cmFpbGluZyB0aHJvdHRsZWQgaW52b2NhdGlvbi5cbiAgICAgKiBqUXVlcnkod2luZG93KS5vbigncG9wc3RhdGUnLCB0aHJvdHRsZWQuY2FuY2VsKTtcbiAgICAgKi9cbiAgICBmdW5jdGlvbiB0aHJvdHRsZShmdW5jLCB3YWl0LCBvcHRpb25zKSB7XG4gICAgICB2YXIgbGVhZGluZyA9IHRydWUsXG4gICAgICAgICAgdHJhaWxpbmcgPSB0cnVlO1xuXG4gICAgICBpZiAodHlwZW9mIGZ1bmMgIT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKEZVTkNfRVJST1JfVEVYVCk7XG4gICAgICB9XG4gICAgICBpZiAoaXNPYmplY3Qob3B0aW9ucykpIHtcbiAgICAgICAgbGVhZGluZyA9ICdsZWFkaW5nJyBpbiBvcHRpb25zID8gISFvcHRpb25zLmxlYWRpbmcgOiBsZWFkaW5nO1xuICAgICAgICB0cmFpbGluZyA9ICd0cmFpbGluZycgaW4gb3B0aW9ucyA/ICEhb3B0aW9ucy50cmFpbGluZyA6IHRyYWlsaW5nO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGRlYm91bmNlKGZ1bmMsIHdhaXQsIHtcbiAgICAgICAgJ2xlYWRpbmcnOiBsZWFkaW5nLFxuICAgICAgICAnbWF4V2FpdCc6IHdhaXQsXG4gICAgICAgICd0cmFpbGluZyc6IHRyYWlsaW5nXG4gICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgZnVuY3Rpb24gdGhhdCBhY2NlcHRzIHVwIHRvIG9uZSBhcmd1bWVudCwgaWdub3JpbmcgYW55XG4gICAgICogYWRkaXRpb25hbCBhcmd1bWVudHMuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgRnVuY3Rpb25cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byBjYXAgYXJndW1lbnRzIGZvci5cbiAgICAgKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBjYXBwZWQgZnVuY3Rpb24uXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8ubWFwKFsnNicsICc4JywgJzEwJ10sIF8udW5hcnkocGFyc2VJbnQpKTtcbiAgICAgKiAvLyA9PiBbNiwgOCwgMTBdXG4gICAgICovXG4gICAgZnVuY3Rpb24gdW5hcnkoZnVuYykge1xuICAgICAgcmV0dXJuIGFyeShmdW5jLCAxKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgZnVuY3Rpb24gdGhhdCBwcm92aWRlcyBgdmFsdWVgIHRvIGB3cmFwcGVyYCBhcyBpdHMgZmlyc3RcbiAgICAgKiBhcmd1bWVudC4gQW55IGFkZGl0aW9uYWwgYXJndW1lbnRzIHByb3ZpZGVkIHRvIHRoZSBmdW5jdGlvbiBhcmUgYXBwZW5kZWRcbiAgICAgKiB0byB0aG9zZSBwcm92aWRlZCB0byB0aGUgYHdyYXBwZXJgLiBUaGUgd3JhcHBlciBpcyBpbnZva2VkIHdpdGggdGhlIGB0aGlzYFxuICAgICAqIGJpbmRpbmcgb2YgdGhlIGNyZWF0ZWQgZnVuY3Rpb24uXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMC4xLjBcbiAgICAgKiBAY2F0ZWdvcnkgRnVuY3Rpb25cbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byB3cmFwLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IFt3cmFwcGVyPWlkZW50aXR5XSBUaGUgd3JhcHBlciBmdW5jdGlvbi5cbiAgICAgKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBmdW5jdGlvbi5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIHAgPSBfLndyYXAoXy5lc2NhcGUsIGZ1bmN0aW9uKGZ1bmMsIHRleHQpIHtcbiAgICAgKiAgIHJldHVybiAnPHA+JyArIGZ1bmModGV4dCkgKyAnPC9wPic7XG4gICAgICogfSk7XG4gICAgICpcbiAgICAgKiBwKCdmcmVkLCBiYXJuZXksICYgcGViYmxlcycpO1xuICAgICAqIC8vID0+ICc8cD5mcmVkLCBiYXJuZXksICZhbXA7IHBlYmJsZXM8L3A+J1xuICAgICAqL1xuICAgIGZ1bmN0aW9uIHdyYXAodmFsdWUsIHdyYXBwZXIpIHtcbiAgICAgIHJldHVybiBwYXJ0aWFsKGNhc3RGdW5jdGlvbih3cmFwcGVyKSwgdmFsdWUpO1xuICAgIH1cblxuICAgIC8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi9cblxuICAgIC8qKlxuICAgICAqIENhc3RzIGB2YWx1ZWAgYXMgYW4gYXJyYXkgaWYgaXQncyBub3Qgb25lLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuNC4wXG4gICAgICogQGNhdGVnb3J5IExhbmdcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBpbnNwZWN0LlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgY2FzdCBhcnJheS5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5jYXN0QXJyYXkoMSk7XG4gICAgICogLy8gPT4gWzFdXG4gICAgICpcbiAgICAgKiBfLmNhc3RBcnJheSh7ICdhJzogMSB9KTtcbiAgICAgKiAvLyA9PiBbeyAnYSc6IDEgfV1cbiAgICAgKlxuICAgICAqIF8uY2FzdEFycmF5KCdhYmMnKTtcbiAgICAgKiAvLyA9PiBbJ2FiYyddXG4gICAgICpcbiAgICAgKiBfLmNhc3RBcnJheShudWxsKTtcbiAgICAgKiAvLyA9PiBbbnVsbF1cbiAgICAgKlxuICAgICAqIF8uY2FzdEFycmF5KHVuZGVmaW5lZCk7XG4gICAgICogLy8gPT4gW3VuZGVmaW5lZF1cbiAgICAgKlxuICAgICAqIF8uY2FzdEFycmF5KCk7XG4gICAgICogLy8gPT4gW11cbiAgICAgKlxuICAgICAqIHZhciBhcnJheSA9IFsxLCAyLCAzXTtcbiAgICAgKiBjb25zb2xlLmxvZyhfLmNhc3RBcnJheShhcnJheSkgPT09IGFycmF5KTtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICovXG4gICAgZnVuY3Rpb24gY2FzdEFycmF5KCkge1xuICAgICAgaWYgKCFhcmd1bWVudHMubGVuZ3RoKSB7XG4gICAgICAgIHJldHVybiBbXTtcbiAgICAgIH1cbiAgICAgIHZhciB2YWx1ZSA9IGFyZ3VtZW50c1swXTtcbiAgICAgIHJldHVybiBpc0FycmF5KHZhbHVlKSA/IHZhbHVlIDogW3ZhbHVlXTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgc2hhbGxvdyBjbG9uZSBvZiBgdmFsdWVgLlxuICAgICAqXG4gICAgICogKipOb3RlOioqIFRoaXMgbWV0aG9kIGlzIGxvb3NlbHkgYmFzZWQgb24gdGhlXG4gICAgICogW3N0cnVjdHVyZWQgY2xvbmUgYWxnb3JpdGhtXShodHRwczovL21kbi5pby9TdHJ1Y3R1cmVkX2Nsb25lX2FsZ29yaXRobSlcbiAgICAgKiBhbmQgc3VwcG9ydHMgY2xvbmluZyBhcnJheXMsIGFycmF5IGJ1ZmZlcnMsIGJvb2xlYW5zLCBkYXRlIG9iamVjdHMsIG1hcHMsXG4gICAgICogbnVtYmVycywgYE9iamVjdGAgb2JqZWN0cywgcmVnZXhlcywgc2V0cywgc3RyaW5ncywgc3ltYm9scywgYW5kIHR5cGVkXG4gICAgICogYXJyYXlzLiBUaGUgb3duIGVudW1lcmFibGUgcHJvcGVydGllcyBvZiBgYXJndW1lbnRzYCBvYmplY3RzIGFyZSBjbG9uZWRcbiAgICAgKiBhcyBwbGFpbiBvYmplY3RzLiBBbiBlbXB0eSBvYmplY3QgaXMgcmV0dXJuZWQgZm9yIHVuY2xvbmVhYmxlIHZhbHVlcyBzdWNoXG4gICAgICogYXMgZXJyb3Igb2JqZWN0cywgZnVuY3Rpb25zLCBET00gbm9kZXMsIGFuZCBXZWFrTWFwcy5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAwLjEuMFxuICAgICAqIEBjYXRlZ29yeSBMYW5nXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2xvbmUuXG4gICAgICogQHJldHVybnMgeyp9IFJldHVybnMgdGhlIGNsb25lZCB2YWx1ZS5cbiAgICAgKiBAc2VlIF8uY2xvbmVEZWVwXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciBvYmplY3RzID0gW3sgJ2EnOiAxIH0sIHsgJ2InOiAyIH1dO1xuICAgICAqXG4gICAgICogdmFyIHNoYWxsb3cgPSBfLmNsb25lKG9iamVjdHMpO1xuICAgICAqIGNvbnNvbGUubG9nKHNoYWxsb3dbMF0gPT09IG9iamVjdHNbMF0pO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBjbG9uZSh2YWx1ZSkge1xuICAgICAgcmV0dXJuIGJhc2VDbG9uZSh2YWx1ZSwgQ0xPTkVfU1lNQk9MU19GTEFHKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIG1ldGhvZCBpcyBsaWtlIGBfLmNsb25lYCBleGNlcHQgdGhhdCBpdCBhY2NlcHRzIGBjdXN0b21pemVyYCB3aGljaFxuICAgICAqIGlzIGludm9rZWQgdG8gcHJvZHVjZSB0aGUgY2xvbmVkIHZhbHVlLiBJZiBgY3VzdG9taXplcmAgcmV0dXJucyBgdW5kZWZpbmVkYCxcbiAgICAgKiBjbG9uaW5nIGlzIGhhbmRsZWQgYnkgdGhlIG1ldGhvZCBpbnN0ZWFkLiBUaGUgYGN1c3RvbWl6ZXJgIGlzIGludm9rZWQgd2l0aFxuICAgICAqIHVwIHRvIGZvdXIgYXJndW1lbnRzOyAodmFsdWUgWywgaW5kZXh8a2V5LCBvYmplY3QsIHN0YWNrXSkuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgTGFuZ1xuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNsb25lLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IFtjdXN0b21pemVyXSBUaGUgZnVuY3Rpb24gdG8gY3VzdG9taXplIGNsb25pbmcuXG4gICAgICogQHJldHVybnMgeyp9IFJldHVybnMgdGhlIGNsb25lZCB2YWx1ZS5cbiAgICAgKiBAc2VlIF8uY2xvbmVEZWVwV2l0aFxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBmdW5jdGlvbiBjdXN0b21pemVyKHZhbHVlKSB7XG4gICAgICogICBpZiAoXy5pc0VsZW1lbnQodmFsdWUpKSB7XG4gICAgICogICAgIHJldHVybiB2YWx1ZS5jbG9uZU5vZGUoZmFsc2UpO1xuICAgICAqICAgfVxuICAgICAqIH1cbiAgICAgKlxuICAgICAqIHZhciBlbCA9IF8uY2xvbmVXaXRoKGRvY3VtZW50LmJvZHksIGN1c3RvbWl6ZXIpO1xuICAgICAqXG4gICAgICogY29uc29sZS5sb2coZWwgPT09IGRvY3VtZW50LmJvZHkpO1xuICAgICAqIC8vID0+IGZhbHNlXG4gICAgICogY29uc29sZS5sb2coZWwubm9kZU5hbWUpO1xuICAgICAqIC8vID0+ICdCT0RZJ1xuICAgICAqIGNvbnNvbGUubG9nKGVsLmNoaWxkTm9kZXMubGVuZ3RoKTtcbiAgICAgKiAvLyA9PiAwXG4gICAgICovXG4gICAgZnVuY3Rpb24gY2xvbmVXaXRoKHZhbHVlLCBjdXN0b21pemVyKSB7XG4gICAgICBjdXN0b21pemVyID0gdHlwZW9mIGN1c3RvbWl6ZXIgPT0gJ2Z1bmN0aW9uJyA/IGN1c3RvbWl6ZXIgOiB1bmRlZmluZWQ7XG4gICAgICByZXR1cm4gYmFzZUNsb25lKHZhbHVlLCBDTE9ORV9TWU1CT0xTX0ZMQUcsIGN1c3RvbWl6ZXIpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIGlzIGxpa2UgYF8uY2xvbmVgIGV4Y2VwdCB0aGF0IGl0IHJlY3Vyc2l2ZWx5IGNsb25lcyBgdmFsdWVgLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDEuMC4wXG4gICAgICogQGNhdGVnb3J5IExhbmdcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byByZWN1cnNpdmVseSBjbG9uZS5cbiAgICAgKiBAcmV0dXJucyB7Kn0gUmV0dXJucyB0aGUgZGVlcCBjbG9uZWQgdmFsdWUuXG4gICAgICogQHNlZSBfLmNsb25lXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciBvYmplY3RzID0gW3sgJ2EnOiAxIH0sIHsgJ2InOiAyIH1dO1xuICAgICAqXG4gICAgICogdmFyIGRlZXAgPSBfLmNsb25lRGVlcChvYmplY3RzKTtcbiAgICAgKiBjb25zb2xlLmxvZyhkZWVwWzBdID09PSBvYmplY3RzWzBdKTtcbiAgICAgKiAvLyA9PiBmYWxzZVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGNsb25lRGVlcCh2YWx1ZSkge1xuICAgICAgcmV0dXJuIGJhc2VDbG9uZSh2YWx1ZSwgQ0xPTkVfREVFUF9GTEFHIHwgQ0xPTkVfU1lNQk9MU19GTEFHKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIG1ldGhvZCBpcyBsaWtlIGBfLmNsb25lV2l0aGAgZXhjZXB0IHRoYXQgaXQgcmVjdXJzaXZlbHkgY2xvbmVzIGB2YWx1ZWAuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgTGFuZ1xuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIHJlY3Vyc2l2ZWx5IGNsb25lLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IFtjdXN0b21pemVyXSBUaGUgZnVuY3Rpb24gdG8gY3VzdG9taXplIGNsb25pbmcuXG4gICAgICogQHJldHVybnMgeyp9IFJldHVybnMgdGhlIGRlZXAgY2xvbmVkIHZhbHVlLlxuICAgICAqIEBzZWUgXy5jbG9uZVdpdGhcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogZnVuY3Rpb24gY3VzdG9taXplcih2YWx1ZSkge1xuICAgICAqICAgaWYgKF8uaXNFbGVtZW50KHZhbHVlKSkge1xuICAgICAqICAgICByZXR1cm4gdmFsdWUuY2xvbmVOb2RlKHRydWUpO1xuICAgICAqICAgfVxuICAgICAqIH1cbiAgICAgKlxuICAgICAqIHZhciBlbCA9IF8uY2xvbmVEZWVwV2l0aChkb2N1bWVudC5ib2R5LCBjdXN0b21pemVyKTtcbiAgICAgKlxuICAgICAqIGNvbnNvbGUubG9nKGVsID09PSBkb2N1bWVudC5ib2R5KTtcbiAgICAgKiAvLyA9PiBmYWxzZVxuICAgICAqIGNvbnNvbGUubG9nKGVsLm5vZGVOYW1lKTtcbiAgICAgKiAvLyA9PiAnQk9EWSdcbiAgICAgKiBjb25zb2xlLmxvZyhlbC5jaGlsZE5vZGVzLmxlbmd0aCk7XG4gICAgICogLy8gPT4gMjBcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBjbG9uZURlZXBXaXRoKHZhbHVlLCBjdXN0b21pemVyKSB7XG4gICAgICBjdXN0b21pemVyID0gdHlwZW9mIGN1c3RvbWl6ZXIgPT0gJ2Z1bmN0aW9uJyA/IGN1c3RvbWl6ZXIgOiB1bmRlZmluZWQ7XG4gICAgICByZXR1cm4gYmFzZUNsb25lKHZhbHVlLCBDTE9ORV9ERUVQX0ZMQUcgfCBDTE9ORV9TWU1CT0xTX0ZMQUcsIGN1c3RvbWl6ZXIpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENoZWNrcyBpZiBgb2JqZWN0YCBjb25mb3JtcyB0byBgc291cmNlYCBieSBpbnZva2luZyB0aGUgcHJlZGljYXRlXG4gICAgICogcHJvcGVydGllcyBvZiBgc291cmNlYCB3aXRoIHRoZSBjb3JyZXNwb25kaW5nIHByb3BlcnR5IHZhbHVlcyBvZiBgb2JqZWN0YC5cbiAgICAgKlxuICAgICAqICoqTm90ZToqKiBUaGlzIG1ldGhvZCBpcyBlcXVpdmFsZW50IHRvIGBfLmNvbmZvcm1zYCB3aGVuIGBzb3VyY2VgIGlzXG4gICAgICogcGFydGlhbGx5IGFwcGxpZWQuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4xNC4wXG4gICAgICogQGNhdGVnb3J5IExhbmdcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gaW5zcGVjdC5cbiAgICAgKiBAcGFyYW0ge09iamVjdH0gc291cmNlIFRoZSBvYmplY3Qgb2YgcHJvcGVydHkgcHJlZGljYXRlcyB0byBjb25mb3JtIHRvLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgb2JqZWN0YCBjb25mb3JtcywgZWxzZSBgZmFsc2VgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgb2JqZWN0ID0geyAnYSc6IDEsICdiJzogMiB9O1xuICAgICAqXG4gICAgICogXy5jb25mb3Jtc1RvKG9iamVjdCwgeyAnYic6IGZ1bmN0aW9uKG4pIHsgcmV0dXJuIG4gPiAxOyB9IH0pO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKlxuICAgICAqIF8uY29uZm9ybXNUbyhvYmplY3QsIHsgJ2InOiBmdW5jdGlvbihuKSB7IHJldHVybiBuID4gMjsgfSB9KTtcbiAgICAgKiAvLyA9PiBmYWxzZVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGNvbmZvcm1zVG8ob2JqZWN0LCBzb3VyY2UpIHtcbiAgICAgIHJldHVybiBzb3VyY2UgPT0gbnVsbCB8fCBiYXNlQ29uZm9ybXNUbyhvYmplY3QsIHNvdXJjZSwga2V5cyhzb3VyY2UpKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBQZXJmb3JtcyBhXG4gICAgICogW2BTYW1lVmFsdWVaZXJvYF0oaHR0cDovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNy4wLyNzZWMtc2FtZXZhbHVlemVybylcbiAgICAgKiBjb21wYXJpc29uIGJldHdlZW4gdHdvIHZhbHVlcyB0byBkZXRlcm1pbmUgaWYgdGhleSBhcmUgZXF1aXZhbGVudC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjAuMFxuICAgICAqIEBjYXRlZ29yeSBMYW5nXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY29tcGFyZS5cbiAgICAgKiBAcGFyYW0geyp9IG90aGVyIFRoZSBvdGhlciB2YWx1ZSB0byBjb21wYXJlLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiB0aGUgdmFsdWVzIGFyZSBlcXVpdmFsZW50LCBlbHNlIGBmYWxzZWAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciBvYmplY3QgPSB7ICdhJzogMSB9O1xuICAgICAqIHZhciBvdGhlciA9IHsgJ2EnOiAxIH07XG4gICAgICpcbiAgICAgKiBfLmVxKG9iamVjdCwgb2JqZWN0KTtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICpcbiAgICAgKiBfLmVxKG9iamVjdCwgb3RoZXIpO1xuICAgICAqIC8vID0+IGZhbHNlXG4gICAgICpcbiAgICAgKiBfLmVxKCdhJywgJ2EnKTtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICpcbiAgICAgKiBfLmVxKCdhJywgT2JqZWN0KCdhJykpO1xuICAgICAqIC8vID0+IGZhbHNlXG4gICAgICpcbiAgICAgKiBfLmVxKE5hTiwgTmFOKTtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICovXG4gICAgZnVuY3Rpb24gZXEodmFsdWUsIG90aGVyKSB7XG4gICAgICByZXR1cm4gdmFsdWUgPT09IG90aGVyIHx8ICh2YWx1ZSAhPT0gdmFsdWUgJiYgb3RoZXIgIT09IG90aGVyKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBncmVhdGVyIHRoYW4gYG90aGVyYC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAzLjkuMFxuICAgICAqIEBjYXRlZ29yeSBMYW5nXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY29tcGFyZS5cbiAgICAgKiBAcGFyYW0geyp9IG90aGVyIFRoZSBvdGhlciB2YWx1ZSB0byBjb21wYXJlLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGdyZWF0ZXIgdGhhbiBgb3RoZXJgLFxuICAgICAqICBlbHNlIGBmYWxzZWAuXG4gICAgICogQHNlZSBfLmx0XG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uZ3QoMywgMSk7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqXG4gICAgICogXy5ndCgzLCAzKTtcbiAgICAgKiAvLyA9PiBmYWxzZVxuICAgICAqXG4gICAgICogXy5ndCgxLCAzKTtcbiAgICAgKiAvLyA9PiBmYWxzZVxuICAgICAqL1xuICAgIHZhciBndCA9IGNyZWF0ZVJlbGF0aW9uYWxPcGVyYXRpb24oYmFzZUd0KTtcblxuICAgIC8qKlxuICAgICAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byBgb3RoZXJgLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDMuOS4wXG4gICAgICogQGNhdGVnb3J5IExhbmdcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjb21wYXJlLlxuICAgICAqIEBwYXJhbSB7Kn0gb3RoZXIgVGhlIG90aGVyIHZhbHVlIHRvIGNvbXBhcmUuXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvXG4gICAgICogIGBvdGhlcmAsIGVsc2UgYGZhbHNlYC5cbiAgICAgKiBAc2VlIF8ubHRlXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uZ3RlKDMsIDEpO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKlxuICAgICAqIF8uZ3RlKDMsIDMpO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKlxuICAgICAqIF8uZ3RlKDEsIDMpO1xuICAgICAqIC8vID0+IGZhbHNlXG4gICAgICovXG4gICAgdmFyIGd0ZSA9IGNyZWF0ZVJlbGF0aW9uYWxPcGVyYXRpb24oZnVuY3Rpb24odmFsdWUsIG90aGVyKSB7XG4gICAgICByZXR1cm4gdmFsdWUgPj0gb3RoZXI7XG4gICAgfSk7XG5cbiAgICAvKipcbiAgICAgKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBsaWtlbHkgYW4gYGFyZ3VtZW50c2Agb2JqZWN0LlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDAuMS4wXG4gICAgICogQGNhdGVnb3J5IExhbmdcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhbiBgYXJndW1lbnRzYCBvYmplY3QsXG4gICAgICogIGVsc2UgYGZhbHNlYC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5pc0FyZ3VtZW50cyhmdW5jdGlvbigpIHsgcmV0dXJuIGFyZ3VtZW50czsgfSgpKTtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICpcbiAgICAgKiBfLmlzQXJndW1lbnRzKFsxLCAyLCAzXSk7XG4gICAgICogLy8gPT4gZmFsc2VcbiAgICAgKi9cbiAgICB2YXIgaXNBcmd1bWVudHMgPSBiYXNlSXNBcmd1bWVudHMoZnVuY3Rpb24oKSB7IHJldHVybiBhcmd1bWVudHM7IH0oKSkgPyBiYXNlSXNBcmd1bWVudHMgOiBmdW5jdGlvbih2YWx1ZSkge1xuICAgICAgcmV0dXJuIGlzT2JqZWN0TGlrZSh2YWx1ZSkgJiYgaGFzT3duUHJvcGVydHkuY2FsbCh2YWx1ZSwgJ2NhbGxlZScpICYmXG4gICAgICAgICFwcm9wZXJ0eUlzRW51bWVyYWJsZS5jYWxsKHZhbHVlLCAnY2FsbGVlJyk7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIGNsYXNzaWZpZWQgYXMgYW4gYEFycmF5YCBvYmplY3QuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMC4xLjBcbiAgICAgKiBAY2F0ZWdvcnkgTGFuZ1xuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGFuIGFycmF5LCBlbHNlIGBmYWxzZWAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uaXNBcnJheShbMSwgMiwgM10pO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKlxuICAgICAqIF8uaXNBcnJheShkb2N1bWVudC5ib2R5LmNoaWxkcmVuKTtcbiAgICAgKiAvLyA9PiBmYWxzZVxuICAgICAqXG4gICAgICogXy5pc0FycmF5KCdhYmMnKTtcbiAgICAgKiAvLyA9PiBmYWxzZVxuICAgICAqXG4gICAgICogXy5pc0FycmF5KF8ubm9vcCk7XG4gICAgICogLy8gPT4gZmFsc2VcbiAgICAgKi9cbiAgICB2YXIgaXNBcnJheSA9IEFycmF5LmlzQXJyYXk7XG5cbiAgICAvKipcbiAgICAgKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBjbGFzc2lmaWVkIGFzIGFuIGBBcnJheUJ1ZmZlcmAgb2JqZWN0LlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMy4wXG4gICAgICogQGNhdGVnb3J5IExhbmdcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhbiBhcnJheSBidWZmZXIsIGVsc2UgYGZhbHNlYC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5pc0FycmF5QnVmZmVyKG5ldyBBcnJheUJ1ZmZlcigyKSk7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqXG4gICAgICogXy5pc0FycmF5QnVmZmVyKG5ldyBBcnJheSgyKSk7XG4gICAgICogLy8gPT4gZmFsc2VcbiAgICAgKi9cbiAgICB2YXIgaXNBcnJheUJ1ZmZlciA9IG5vZGVJc0FycmF5QnVmZmVyID8gYmFzZVVuYXJ5KG5vZGVJc0FycmF5QnVmZmVyKSA6IGJhc2VJc0FycmF5QnVmZmVyO1xuXG4gICAgLyoqXG4gICAgICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgYXJyYXktbGlrZS4gQSB2YWx1ZSBpcyBjb25zaWRlcmVkIGFycmF5LWxpa2UgaWYgaXQnc1xuICAgICAqIG5vdCBhIGZ1bmN0aW9uIGFuZCBoYXMgYSBgdmFsdWUubGVuZ3RoYCB0aGF0J3MgYW4gaW50ZWdlciBncmVhdGVyIHRoYW4gb3JcbiAgICAgKiBlcXVhbCB0byBgMGAgYW5kIGxlc3MgdGhhbiBvciBlcXVhbCB0byBgTnVtYmVyLk1BWF9TQUZFX0lOVEVHRVJgLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMC4wXG4gICAgICogQGNhdGVnb3J5IExhbmdcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhcnJheS1saWtlLCBlbHNlIGBmYWxzZWAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uaXNBcnJheUxpa2UoWzEsIDIsIDNdKTtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICpcbiAgICAgKiBfLmlzQXJyYXlMaWtlKGRvY3VtZW50LmJvZHkuY2hpbGRyZW4pO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKlxuICAgICAqIF8uaXNBcnJheUxpa2UoJ2FiYycpO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKlxuICAgICAqIF8uaXNBcnJheUxpa2UoXy5ub29wKTtcbiAgICAgKiAvLyA9PiBmYWxzZVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGlzQXJyYXlMaWtlKHZhbHVlKSB7XG4gICAgICByZXR1cm4gdmFsdWUgIT0gbnVsbCAmJiBpc0xlbmd0aCh2YWx1ZS5sZW5ndGgpICYmICFpc0Z1bmN0aW9uKHZhbHVlKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIG1ldGhvZCBpcyBsaWtlIGBfLmlzQXJyYXlMaWtlYCBleGNlcHQgdGhhdCBpdCBhbHNvIGNoZWNrcyBpZiBgdmFsdWVgXG4gICAgICogaXMgYW4gb2JqZWN0LlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMC4wXG4gICAgICogQGNhdGVnb3J5IExhbmdcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhbiBhcnJheS1saWtlIG9iamVjdCxcbiAgICAgKiAgZWxzZSBgZmFsc2VgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLmlzQXJyYXlMaWtlT2JqZWN0KFsxLCAyLCAzXSk7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqXG4gICAgICogXy5pc0FycmF5TGlrZU9iamVjdChkb2N1bWVudC5ib2R5LmNoaWxkcmVuKTtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICpcbiAgICAgKiBfLmlzQXJyYXlMaWtlT2JqZWN0KCdhYmMnKTtcbiAgICAgKiAvLyA9PiBmYWxzZVxuICAgICAqXG4gICAgICogXy5pc0FycmF5TGlrZU9iamVjdChfLm5vb3ApO1xuICAgICAqIC8vID0+IGZhbHNlXG4gICAgICovXG4gICAgZnVuY3Rpb24gaXNBcnJheUxpa2VPYmplY3QodmFsdWUpIHtcbiAgICAgIHJldHVybiBpc09iamVjdExpa2UodmFsdWUpICYmIGlzQXJyYXlMaWtlKHZhbHVlKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBjbGFzc2lmaWVkIGFzIGEgYm9vbGVhbiBwcmltaXRpdmUgb3Igb2JqZWN0LlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDAuMS4wXG4gICAgICogQGNhdGVnb3J5IExhbmdcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhIGJvb2xlYW4sIGVsc2UgYGZhbHNlYC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5pc0Jvb2xlYW4oZmFsc2UpO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKlxuICAgICAqIF8uaXNCb29sZWFuKG51bGwpO1xuICAgICAqIC8vID0+IGZhbHNlXG4gICAgICovXG4gICAgZnVuY3Rpb24gaXNCb29sZWFuKHZhbHVlKSB7XG4gICAgICByZXR1cm4gdmFsdWUgPT09IHRydWUgfHwgdmFsdWUgPT09IGZhbHNlIHx8XG4gICAgICAgIChpc09iamVjdExpa2UodmFsdWUpICYmIGJhc2VHZXRUYWcodmFsdWUpID09IGJvb2xUYWcpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIGEgYnVmZmVyLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMy4wXG4gICAgICogQGNhdGVnb3J5IExhbmdcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhIGJ1ZmZlciwgZWxzZSBgZmFsc2VgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLmlzQnVmZmVyKG5ldyBCdWZmZXIoMikpO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKlxuICAgICAqIF8uaXNCdWZmZXIobmV3IFVpbnQ4QXJyYXkoMikpO1xuICAgICAqIC8vID0+IGZhbHNlXG4gICAgICovXG4gICAgdmFyIGlzQnVmZmVyID0gbmF0aXZlSXNCdWZmZXIgfHwgc3R1YkZhbHNlO1xuXG4gICAgLyoqXG4gICAgICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgY2xhc3NpZmllZCBhcyBhIGBEYXRlYCBvYmplY3QuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMC4xLjBcbiAgICAgKiBAY2F0ZWdvcnkgTGFuZ1xuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGEgZGF0ZSBvYmplY3QsIGVsc2UgYGZhbHNlYC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5pc0RhdGUobmV3IERhdGUpO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKlxuICAgICAqIF8uaXNEYXRlKCdNb24gQXByaWwgMjMgMjAxMicpO1xuICAgICAqIC8vID0+IGZhbHNlXG4gICAgICovXG4gICAgdmFyIGlzRGF0ZSA9IG5vZGVJc0RhdGUgPyBiYXNlVW5hcnkobm9kZUlzRGF0ZSkgOiBiYXNlSXNEYXRlO1xuXG4gICAgLyoqXG4gICAgICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgbGlrZWx5IGEgRE9NIGVsZW1lbnQuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMC4xLjBcbiAgICAgKiBAY2F0ZWdvcnkgTGFuZ1xuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGEgRE9NIGVsZW1lbnQsIGVsc2UgYGZhbHNlYC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5pc0VsZW1lbnQoZG9jdW1lbnQuYm9keSk7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqXG4gICAgICogXy5pc0VsZW1lbnQoJzxib2R5PicpO1xuICAgICAqIC8vID0+IGZhbHNlXG4gICAgICovXG4gICAgZnVuY3Rpb24gaXNFbGVtZW50KHZhbHVlKSB7XG4gICAgICByZXR1cm4gaXNPYmplY3RMaWtlKHZhbHVlKSAmJiB2YWx1ZS5ub2RlVHlwZSA9PT0gMSAmJiAhaXNQbGFpbk9iamVjdCh2YWx1ZSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgYW4gZW1wdHkgb2JqZWN0LCBjb2xsZWN0aW9uLCBtYXAsIG9yIHNldC5cbiAgICAgKlxuICAgICAqIE9iamVjdHMgYXJlIGNvbnNpZGVyZWQgZW1wdHkgaWYgdGhleSBoYXZlIG5vIG93biBlbnVtZXJhYmxlIHN0cmluZyBrZXllZFxuICAgICAqIHByb3BlcnRpZXMuXG4gICAgICpcbiAgICAgKiBBcnJheS1saWtlIHZhbHVlcyBzdWNoIGFzIGBhcmd1bWVudHNgIG9iamVjdHMsIGFycmF5cywgYnVmZmVycywgc3RyaW5ncywgb3JcbiAgICAgKiBqUXVlcnktbGlrZSBjb2xsZWN0aW9ucyBhcmUgY29uc2lkZXJlZCBlbXB0eSBpZiB0aGV5IGhhdmUgYSBgbGVuZ3RoYCBvZiBgMGAuXG4gICAgICogU2ltaWxhcmx5LCBtYXBzIGFuZCBzZXRzIGFyZSBjb25zaWRlcmVkIGVtcHR5IGlmIHRoZXkgaGF2ZSBhIGBzaXplYCBvZiBgMGAuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMC4xLjBcbiAgICAgKiBAY2F0ZWdvcnkgTGFuZ1xuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGVtcHR5LCBlbHNlIGBmYWxzZWAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uaXNFbXB0eShudWxsKTtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICpcbiAgICAgKiBfLmlzRW1wdHkodHJ1ZSk7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqXG4gICAgICogXy5pc0VtcHR5KDEpO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKlxuICAgICAqIF8uaXNFbXB0eShbMSwgMiwgM10pO1xuICAgICAqIC8vID0+IGZhbHNlXG4gICAgICpcbiAgICAgKiBfLmlzRW1wdHkoeyAnYSc6IDEgfSk7XG4gICAgICogLy8gPT4gZmFsc2VcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBpc0VtcHR5KHZhbHVlKSB7XG4gICAgICBpZiAodmFsdWUgPT0gbnVsbCkge1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIH1cbiAgICAgIGlmIChpc0FycmF5TGlrZSh2YWx1ZSkgJiZcbiAgICAgICAgICAoaXNBcnJheSh2YWx1ZSkgfHwgdHlwZW9mIHZhbHVlID09ICdzdHJpbmcnIHx8IHR5cGVvZiB2YWx1ZS5zcGxpY2UgPT0gJ2Z1bmN0aW9uJyB8fFxuICAgICAgICAgICAgaXNCdWZmZXIodmFsdWUpIHx8IGlzVHlwZWRBcnJheSh2YWx1ZSkgfHwgaXNBcmd1bWVudHModmFsdWUpKSkge1xuICAgICAgICByZXR1cm4gIXZhbHVlLmxlbmd0aDtcbiAgICAgIH1cbiAgICAgIHZhciB0YWcgPSBnZXRUYWcodmFsdWUpO1xuICAgICAgaWYgKHRhZyA9PSBtYXBUYWcgfHwgdGFnID09IHNldFRhZykge1xuICAgICAgICByZXR1cm4gIXZhbHVlLnNpemU7XG4gICAgICB9XG4gICAgICBpZiAoaXNQcm90b3R5cGUodmFsdWUpKSB7XG4gICAgICAgIHJldHVybiAhYmFzZUtleXModmFsdWUpLmxlbmd0aDtcbiAgICAgIH1cbiAgICAgIGZvciAodmFyIGtleSBpbiB2YWx1ZSkge1xuICAgICAgICBpZiAoaGFzT3duUHJvcGVydHkuY2FsbCh2YWx1ZSwga2V5KSkge1xuICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUGVyZm9ybXMgYSBkZWVwIGNvbXBhcmlzb24gYmV0d2VlbiB0d28gdmFsdWVzIHRvIGRldGVybWluZSBpZiB0aGV5IGFyZVxuICAgICAqIGVxdWl2YWxlbnQuXG4gICAgICpcbiAgICAgKiAqKk5vdGU6KiogVGhpcyBtZXRob2Qgc3VwcG9ydHMgY29tcGFyaW5nIGFycmF5cywgYXJyYXkgYnVmZmVycywgYm9vbGVhbnMsXG4gICAgICogZGF0ZSBvYmplY3RzLCBlcnJvciBvYmplY3RzLCBtYXBzLCBudW1iZXJzLCBgT2JqZWN0YCBvYmplY3RzLCByZWdleGVzLFxuICAgICAqIHNldHMsIHN0cmluZ3MsIHN5bWJvbHMsIGFuZCB0eXBlZCBhcnJheXMuIGBPYmplY3RgIG9iamVjdHMgYXJlIGNvbXBhcmVkXG4gICAgICogYnkgdGhlaXIgb3duLCBub3QgaW5oZXJpdGVkLCBlbnVtZXJhYmxlIHByb3BlcnRpZXMuIEZ1bmN0aW9ucyBhbmQgRE9NXG4gICAgICogbm9kZXMgYXJlIGNvbXBhcmVkIGJ5IHN0cmljdCBlcXVhbGl0eSwgaS5lLiBgPT09YC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAwLjEuMFxuICAgICAqIEBjYXRlZ29yeSBMYW5nXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY29tcGFyZS5cbiAgICAgKiBAcGFyYW0geyp9IG90aGVyIFRoZSBvdGhlciB2YWx1ZSB0byBjb21wYXJlLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiB0aGUgdmFsdWVzIGFyZSBlcXVpdmFsZW50LCBlbHNlIGBmYWxzZWAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciBvYmplY3QgPSB7ICdhJzogMSB9O1xuICAgICAqIHZhciBvdGhlciA9IHsgJ2EnOiAxIH07XG4gICAgICpcbiAgICAgKiBfLmlzRXF1YWwob2JqZWN0LCBvdGhlcik7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqXG4gICAgICogb2JqZWN0ID09PSBvdGhlcjtcbiAgICAgKiAvLyA9PiBmYWxzZVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGlzRXF1YWwodmFsdWUsIG90aGVyKSB7XG4gICAgICByZXR1cm4gYmFzZUlzRXF1YWwodmFsdWUsIG90aGVyKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIG1ldGhvZCBpcyBsaWtlIGBfLmlzRXF1YWxgIGV4Y2VwdCB0aGF0IGl0IGFjY2VwdHMgYGN1c3RvbWl6ZXJgIHdoaWNoXG4gICAgICogaXMgaW52b2tlZCB0byBjb21wYXJlIHZhbHVlcy4gSWYgYGN1c3RvbWl6ZXJgIHJldHVybnMgYHVuZGVmaW5lZGAsIGNvbXBhcmlzb25zXG4gICAgICogYXJlIGhhbmRsZWQgYnkgdGhlIG1ldGhvZCBpbnN0ZWFkLiBUaGUgYGN1c3RvbWl6ZXJgIGlzIGludm9rZWQgd2l0aCB1cCB0b1xuICAgICAqIHNpeCBhcmd1bWVudHM6IChvYmpWYWx1ZSwgb3RoVmFsdWUgWywgaW5kZXh8a2V5LCBvYmplY3QsIG90aGVyLCBzdGFja10pLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMC4wXG4gICAgICogQGNhdGVnb3J5IExhbmdcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjb21wYXJlLlxuICAgICAqIEBwYXJhbSB7Kn0gb3RoZXIgVGhlIG90aGVyIHZhbHVlIHRvIGNvbXBhcmUuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW2N1c3RvbWl6ZXJdIFRoZSBmdW5jdGlvbiB0byBjdXN0b21pemUgY29tcGFyaXNvbnMuXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIHRoZSB2YWx1ZXMgYXJlIGVxdWl2YWxlbnQsIGVsc2UgYGZhbHNlYC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogZnVuY3Rpb24gaXNHcmVldGluZyh2YWx1ZSkge1xuICAgICAqICAgcmV0dXJuIC9eaCg/Oml8ZWxsbykkLy50ZXN0KHZhbHVlKTtcbiAgICAgKiB9XG4gICAgICpcbiAgICAgKiBmdW5jdGlvbiBjdXN0b21pemVyKG9ialZhbHVlLCBvdGhWYWx1ZSkge1xuICAgICAqICAgaWYgKGlzR3JlZXRpbmcob2JqVmFsdWUpICYmIGlzR3JlZXRpbmcob3RoVmFsdWUpKSB7XG4gICAgICogICAgIHJldHVybiB0cnVlO1xuICAgICAqICAgfVxuICAgICAqIH1cbiAgICAgKlxuICAgICAqIHZhciBhcnJheSA9IFsnaGVsbG8nLCAnZ29vZGJ5ZSddO1xuICAgICAqIHZhciBvdGhlciA9IFsnaGknLCAnZ29vZGJ5ZSddO1xuICAgICAqXG4gICAgICogXy5pc0VxdWFsV2l0aChhcnJheSwgb3RoZXIsIGN1c3RvbWl6ZXIpO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBpc0VxdWFsV2l0aCh2YWx1ZSwgb3RoZXIsIGN1c3RvbWl6ZXIpIHtcbiAgICAgIGN1c3RvbWl6ZXIgPSB0eXBlb2YgY3VzdG9taXplciA9PSAnZnVuY3Rpb24nID8gY3VzdG9taXplciA6IHVuZGVmaW5lZDtcbiAgICAgIHZhciByZXN1bHQgPSBjdXN0b21pemVyID8gY3VzdG9taXplcih2YWx1ZSwgb3RoZXIpIDogdW5kZWZpbmVkO1xuICAgICAgcmV0dXJuIHJlc3VsdCA9PT0gdW5kZWZpbmVkID8gYmFzZUlzRXF1YWwodmFsdWUsIG90aGVyLCB1bmRlZmluZWQsIGN1c3RvbWl6ZXIpIDogISFyZXN1bHQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgYW4gYEVycm9yYCwgYEV2YWxFcnJvcmAsIGBSYW5nZUVycm9yYCwgYFJlZmVyZW5jZUVycm9yYCxcbiAgICAgKiBgU3ludGF4RXJyb3JgLCBgVHlwZUVycm9yYCwgb3IgYFVSSUVycm9yYCBvYmplY3QuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMy4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgTGFuZ1xuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGFuIGVycm9yIG9iamVjdCwgZWxzZSBgZmFsc2VgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLmlzRXJyb3IobmV3IEVycm9yKTtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICpcbiAgICAgKiBfLmlzRXJyb3IoRXJyb3IpO1xuICAgICAqIC8vID0+IGZhbHNlXG4gICAgICovXG4gICAgZnVuY3Rpb24gaXNFcnJvcih2YWx1ZSkge1xuICAgICAgaWYgKCFpc09iamVjdExpa2UodmFsdWUpKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICAgIHZhciB0YWcgPSBiYXNlR2V0VGFnKHZhbHVlKTtcbiAgICAgIHJldHVybiB0YWcgPT0gZXJyb3JUYWcgfHwgdGFnID09IGRvbUV4Y1RhZyB8fFxuICAgICAgICAodHlwZW9mIHZhbHVlLm1lc3NhZ2UgPT0gJ3N0cmluZycgJiYgdHlwZW9mIHZhbHVlLm5hbWUgPT0gJ3N0cmluZycgJiYgIWlzUGxhaW5PYmplY3QodmFsdWUpKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBhIGZpbml0ZSBwcmltaXRpdmUgbnVtYmVyLlxuICAgICAqXG4gICAgICogKipOb3RlOioqIFRoaXMgbWV0aG9kIGlzIGJhc2VkIG9uXG4gICAgICogW2BOdW1iZXIuaXNGaW5pdGVgXShodHRwczovL21kbi5pby9OdW1iZXIvaXNGaW5pdGUpLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDAuMS4wXG4gICAgICogQGNhdGVnb3J5IExhbmdcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhIGZpbml0ZSBudW1iZXIsIGVsc2UgYGZhbHNlYC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5pc0Zpbml0ZSgzKTtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICpcbiAgICAgKiBfLmlzRmluaXRlKE51bWJlci5NSU5fVkFMVUUpO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKlxuICAgICAqIF8uaXNGaW5pdGUoSW5maW5pdHkpO1xuICAgICAqIC8vID0+IGZhbHNlXG4gICAgICpcbiAgICAgKiBfLmlzRmluaXRlKCczJyk7XG4gICAgICogLy8gPT4gZmFsc2VcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBpc0Zpbml0ZSh2YWx1ZSkge1xuICAgICAgcmV0dXJuIHR5cGVvZiB2YWx1ZSA9PSAnbnVtYmVyJyAmJiBuYXRpdmVJc0Zpbml0ZSh2YWx1ZSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgY2xhc3NpZmllZCBhcyBhIGBGdW5jdGlvbmAgb2JqZWN0LlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDAuMS4wXG4gICAgICogQGNhdGVnb3J5IExhbmdcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhIGZ1bmN0aW9uLCBlbHNlIGBmYWxzZWAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uaXNGdW5jdGlvbihfKTtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICpcbiAgICAgKiBfLmlzRnVuY3Rpb24oL2FiYy8pO1xuICAgICAqIC8vID0+IGZhbHNlXG4gICAgICovXG4gICAgZnVuY3Rpb24gaXNGdW5jdGlvbih2YWx1ZSkge1xuICAgICAgaWYgKCFpc09iamVjdCh2YWx1ZSkpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgICAgLy8gVGhlIHVzZSBvZiBgT2JqZWN0I3RvU3RyaW5nYCBhdm9pZHMgaXNzdWVzIHdpdGggdGhlIGB0eXBlb2ZgIG9wZXJhdG9yXG4gICAgICAvLyBpbiBTYWZhcmkgOSB3aGljaCByZXR1cm5zICdvYmplY3QnIGZvciB0eXBlZCBhcnJheXMgYW5kIG90aGVyIGNvbnN0cnVjdG9ycy5cbiAgICAgIHZhciB0YWcgPSBiYXNlR2V0VGFnKHZhbHVlKTtcbiAgICAgIHJldHVybiB0YWcgPT0gZnVuY1RhZyB8fCB0YWcgPT0gZ2VuVGFnIHx8IHRhZyA9PSBhc3luY1RhZyB8fCB0YWcgPT0gcHJveHlUYWc7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgYW4gaW50ZWdlci5cbiAgICAgKlxuICAgICAqICoqTm90ZToqKiBUaGlzIG1ldGhvZCBpcyBiYXNlZCBvblxuICAgICAqIFtgTnVtYmVyLmlzSW50ZWdlcmBdKGh0dHBzOi8vbWRuLmlvL051bWJlci9pc0ludGVnZXIpLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMC4wXG4gICAgICogQGNhdGVnb3J5IExhbmdcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhbiBpbnRlZ2VyLCBlbHNlIGBmYWxzZWAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uaXNJbnRlZ2VyKDMpO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKlxuICAgICAqIF8uaXNJbnRlZ2VyKE51bWJlci5NSU5fVkFMVUUpO1xuICAgICAqIC8vID0+IGZhbHNlXG4gICAgICpcbiAgICAgKiBfLmlzSW50ZWdlcihJbmZpbml0eSk7XG4gICAgICogLy8gPT4gZmFsc2VcbiAgICAgKlxuICAgICAqIF8uaXNJbnRlZ2VyKCczJyk7XG4gICAgICogLy8gPT4gZmFsc2VcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBpc0ludGVnZXIodmFsdWUpIHtcbiAgICAgIHJldHVybiB0eXBlb2YgdmFsdWUgPT0gJ251bWJlcicgJiYgdmFsdWUgPT0gdG9JbnRlZ2VyKHZhbHVlKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBhIHZhbGlkIGFycmF5LWxpa2UgbGVuZ3RoLlxuICAgICAqXG4gICAgICogKipOb3RlOioqIFRoaXMgbWV0aG9kIGlzIGxvb3NlbHkgYmFzZWQgb25cbiAgICAgKiBbYFRvTGVuZ3RoYF0oaHR0cDovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNy4wLyNzZWMtdG9sZW5ndGgpLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMC4wXG4gICAgICogQGNhdGVnb3J5IExhbmdcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhIHZhbGlkIGxlbmd0aCwgZWxzZSBgZmFsc2VgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLmlzTGVuZ3RoKDMpO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKlxuICAgICAqIF8uaXNMZW5ndGgoTnVtYmVyLk1JTl9WQUxVRSk7XG4gICAgICogLy8gPT4gZmFsc2VcbiAgICAgKlxuICAgICAqIF8uaXNMZW5ndGgoSW5maW5pdHkpO1xuICAgICAqIC8vID0+IGZhbHNlXG4gICAgICpcbiAgICAgKiBfLmlzTGVuZ3RoKCczJyk7XG4gICAgICogLy8gPT4gZmFsc2VcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBpc0xlbmd0aCh2YWx1ZSkge1xuICAgICAgcmV0dXJuIHR5cGVvZiB2YWx1ZSA9PSAnbnVtYmVyJyAmJlxuICAgICAgICB2YWx1ZSA+IC0xICYmIHZhbHVlICUgMSA9PSAwICYmIHZhbHVlIDw9IE1BWF9TQUZFX0lOVEVHRVI7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgdGhlXG4gICAgICogW2xhbmd1YWdlIHR5cGVdKGh0dHA6Ly93d3cuZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi83LjAvI3NlYy1lY21hc2NyaXB0LWxhbmd1YWdlLXR5cGVzKVxuICAgICAqIG9mIGBPYmplY3RgLiAoZS5nLiBhcnJheXMsIGZ1bmN0aW9ucywgb2JqZWN0cywgcmVnZXhlcywgYG5ldyBOdW1iZXIoMClgLCBhbmQgYG5ldyBTdHJpbmcoJycpYClcbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAwLjEuMFxuICAgICAqIEBjYXRlZ29yeSBMYW5nXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgYW4gb2JqZWN0LCBlbHNlIGBmYWxzZWAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uaXNPYmplY3Qoe30pO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKlxuICAgICAqIF8uaXNPYmplY3QoWzEsIDIsIDNdKTtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICpcbiAgICAgKiBfLmlzT2JqZWN0KF8ubm9vcCk7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqXG4gICAgICogXy5pc09iamVjdChudWxsKTtcbiAgICAgKiAvLyA9PiBmYWxzZVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGlzT2JqZWN0KHZhbHVlKSB7XG4gICAgICB2YXIgdHlwZSA9IHR5cGVvZiB2YWx1ZTtcbiAgICAgIHJldHVybiB2YWx1ZSAhPSBudWxsICYmICh0eXBlID09ICdvYmplY3QnIHx8IHR5cGUgPT0gJ2Z1bmN0aW9uJyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgb2JqZWN0LWxpa2UuIEEgdmFsdWUgaXMgb2JqZWN0LWxpa2UgaWYgaXQncyBub3QgYG51bGxgXG4gICAgICogYW5kIGhhcyBhIGB0eXBlb2ZgIHJlc3VsdCBvZiBcIm9iamVjdFwiLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMC4wXG4gICAgICogQGNhdGVnb3J5IExhbmdcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBvYmplY3QtbGlrZSwgZWxzZSBgZmFsc2VgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLmlzT2JqZWN0TGlrZSh7fSk7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqXG4gICAgICogXy5pc09iamVjdExpa2UoWzEsIDIsIDNdKTtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICpcbiAgICAgKiBfLmlzT2JqZWN0TGlrZShfLm5vb3ApO1xuICAgICAqIC8vID0+IGZhbHNlXG4gICAgICpcbiAgICAgKiBfLmlzT2JqZWN0TGlrZShudWxsKTtcbiAgICAgKiAvLyA9PiBmYWxzZVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGlzT2JqZWN0TGlrZSh2YWx1ZSkge1xuICAgICAgcmV0dXJuIHZhbHVlICE9IG51bGwgJiYgdHlwZW9mIHZhbHVlID09ICdvYmplY3QnO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIGNsYXNzaWZpZWQgYXMgYSBgTWFwYCBvYmplY3QuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4zLjBcbiAgICAgKiBAY2F0ZWdvcnkgTGFuZ1xuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGEgbWFwLCBlbHNlIGBmYWxzZWAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uaXNNYXAobmV3IE1hcCk7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqXG4gICAgICogXy5pc01hcChuZXcgV2Vha01hcCk7XG4gICAgICogLy8gPT4gZmFsc2VcbiAgICAgKi9cbiAgICB2YXIgaXNNYXAgPSBub2RlSXNNYXAgPyBiYXNlVW5hcnkobm9kZUlzTWFwKSA6IGJhc2VJc01hcDtcblxuICAgIC8qKlxuICAgICAqIFBlcmZvcm1zIGEgcGFydGlhbCBkZWVwIGNvbXBhcmlzb24gYmV0d2VlbiBgb2JqZWN0YCBhbmQgYHNvdXJjZWAgdG9cbiAgICAgKiBkZXRlcm1pbmUgaWYgYG9iamVjdGAgY29udGFpbnMgZXF1aXZhbGVudCBwcm9wZXJ0eSB2YWx1ZXMuXG4gICAgICpcbiAgICAgKiAqKk5vdGU6KiogVGhpcyBtZXRob2QgaXMgZXF1aXZhbGVudCB0byBgXy5tYXRjaGVzYCB3aGVuIGBzb3VyY2VgIGlzXG4gICAgICogcGFydGlhbGx5IGFwcGxpZWQuXG4gICAgICpcbiAgICAgKiBQYXJ0aWFsIGNvbXBhcmlzb25zIHdpbGwgbWF0Y2ggZW1wdHkgYXJyYXkgYW5kIGVtcHR5IG9iamVjdCBgc291cmNlYFxuICAgICAqIHZhbHVlcyBhZ2FpbnN0IGFueSBhcnJheSBvciBvYmplY3QgdmFsdWUsIHJlc3BlY3RpdmVseS4gU2VlIGBfLmlzRXF1YWxgXG4gICAgICogZm9yIGEgbGlzdCBvZiBzdXBwb3J0ZWQgdmFsdWUgY29tcGFyaXNvbnMuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMy4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgTGFuZ1xuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBpbnNwZWN0LlxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBzb3VyY2UgVGhlIG9iamVjdCBvZiBwcm9wZXJ0eSB2YWx1ZXMgdG8gbWF0Y2guXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGBvYmplY3RgIGlzIGEgbWF0Y2gsIGVsc2UgYGZhbHNlYC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIG9iamVjdCA9IHsgJ2EnOiAxLCAnYic6IDIgfTtcbiAgICAgKlxuICAgICAqIF8uaXNNYXRjaChvYmplY3QsIHsgJ2InOiAyIH0pO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKlxuICAgICAqIF8uaXNNYXRjaChvYmplY3QsIHsgJ2InOiAxIH0pO1xuICAgICAqIC8vID0+IGZhbHNlXG4gICAgICovXG4gICAgZnVuY3Rpb24gaXNNYXRjaChvYmplY3QsIHNvdXJjZSkge1xuICAgICAgcmV0dXJuIG9iamVjdCA9PT0gc291cmNlIHx8IGJhc2VJc01hdGNoKG9iamVjdCwgc291cmNlLCBnZXRNYXRjaERhdGEoc291cmNlKSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgaXMgbGlrZSBgXy5pc01hdGNoYCBleGNlcHQgdGhhdCBpdCBhY2NlcHRzIGBjdXN0b21pemVyYCB3aGljaFxuICAgICAqIGlzIGludm9rZWQgdG8gY29tcGFyZSB2YWx1ZXMuIElmIGBjdXN0b21pemVyYCByZXR1cm5zIGB1bmRlZmluZWRgLCBjb21wYXJpc29uc1xuICAgICAqIGFyZSBoYW5kbGVkIGJ5IHRoZSBtZXRob2QgaW5zdGVhZC4gVGhlIGBjdXN0b21pemVyYCBpcyBpbnZva2VkIHdpdGggZml2ZVxuICAgICAqIGFyZ3VtZW50czogKG9ialZhbHVlLCBzcmNWYWx1ZSwgaW5kZXh8a2V5LCBvYmplY3QsIHNvdXJjZSkuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgTGFuZ1xuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBpbnNwZWN0LlxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBzb3VyY2UgVGhlIG9iamVjdCBvZiBwcm9wZXJ0eSB2YWx1ZXMgdG8gbWF0Y2guXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW2N1c3RvbWl6ZXJdIFRoZSBmdW5jdGlvbiB0byBjdXN0b21pemUgY29tcGFyaXNvbnMuXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGBvYmplY3RgIGlzIGEgbWF0Y2gsIGVsc2UgYGZhbHNlYC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogZnVuY3Rpb24gaXNHcmVldGluZyh2YWx1ZSkge1xuICAgICAqICAgcmV0dXJuIC9eaCg/Oml8ZWxsbykkLy50ZXN0KHZhbHVlKTtcbiAgICAgKiB9XG4gICAgICpcbiAgICAgKiBmdW5jdGlvbiBjdXN0b21pemVyKG9ialZhbHVlLCBzcmNWYWx1ZSkge1xuICAgICAqICAgaWYgKGlzR3JlZXRpbmcob2JqVmFsdWUpICYmIGlzR3JlZXRpbmcoc3JjVmFsdWUpKSB7XG4gICAgICogICAgIHJldHVybiB0cnVlO1xuICAgICAqICAgfVxuICAgICAqIH1cbiAgICAgKlxuICAgICAqIHZhciBvYmplY3QgPSB7ICdncmVldGluZyc6ICdoZWxsbycgfTtcbiAgICAgKiB2YXIgc291cmNlID0geyAnZ3JlZXRpbmcnOiAnaGknIH07XG4gICAgICpcbiAgICAgKiBfLmlzTWF0Y2hXaXRoKG9iamVjdCwgc291cmNlLCBjdXN0b21pemVyKTtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICovXG4gICAgZnVuY3Rpb24gaXNNYXRjaFdpdGgob2JqZWN0LCBzb3VyY2UsIGN1c3RvbWl6ZXIpIHtcbiAgICAgIGN1c3RvbWl6ZXIgPSB0eXBlb2YgY3VzdG9taXplciA9PSAnZnVuY3Rpb24nID8gY3VzdG9taXplciA6IHVuZGVmaW5lZDtcbiAgICAgIHJldHVybiBiYXNlSXNNYXRjaChvYmplY3QsIHNvdXJjZSwgZ2V0TWF0Y2hEYXRhKHNvdXJjZSksIGN1c3RvbWl6ZXIpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIGBOYU5gLlxuICAgICAqXG4gICAgICogKipOb3RlOioqIFRoaXMgbWV0aG9kIGlzIGJhc2VkIG9uXG4gICAgICogW2BOdW1iZXIuaXNOYU5gXShodHRwczovL21kbi5pby9OdW1iZXIvaXNOYU4pIGFuZCBpcyBub3QgdGhlIHNhbWUgYXNcbiAgICAgKiBnbG9iYWwgW2Bpc05hTmBdKGh0dHBzOi8vbWRuLmlvL2lzTmFOKSB3aGljaCByZXR1cm5zIGB0cnVlYCBmb3JcbiAgICAgKiBgdW5kZWZpbmVkYCBhbmQgb3RoZXIgbm9uLW51bWJlciB2YWx1ZXMuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMC4xLjBcbiAgICAgKiBAY2F0ZWdvcnkgTGFuZ1xuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGBOYU5gLCBlbHNlIGBmYWxzZWAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uaXNOYU4oTmFOKTtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICpcbiAgICAgKiBfLmlzTmFOKG5ldyBOdW1iZXIoTmFOKSk7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqXG4gICAgICogaXNOYU4odW5kZWZpbmVkKTtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICpcbiAgICAgKiBfLmlzTmFOKHVuZGVmaW5lZCk7XG4gICAgICogLy8gPT4gZmFsc2VcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBpc05hTih2YWx1ZSkge1xuICAgICAgLy8gQW4gYE5hTmAgcHJpbWl0aXZlIGlzIHRoZSBvbmx5IHZhbHVlIHRoYXQgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi5cbiAgICAgIC8vIFBlcmZvcm0gdGhlIGB0b1N0cmluZ1RhZ2AgY2hlY2sgZmlyc3QgdG8gYXZvaWQgZXJyb3JzIHdpdGggc29tZVxuICAgICAgLy8gQWN0aXZlWCBvYmplY3RzIGluIElFLlxuICAgICAgcmV0dXJuIGlzTnVtYmVyKHZhbHVlKSAmJiB2YWx1ZSAhPSArdmFsdWU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgYSBwcmlzdGluZSBuYXRpdmUgZnVuY3Rpb24uXG4gICAgICpcbiAgICAgKiAqKk5vdGU6KiogVGhpcyBtZXRob2QgY2FuJ3QgcmVsaWFibHkgZGV0ZWN0IG5hdGl2ZSBmdW5jdGlvbnMgaW4gdGhlIHByZXNlbmNlXG4gICAgICogb2YgdGhlIGNvcmUtanMgcGFja2FnZSBiZWNhdXNlIGNvcmUtanMgY2lyY3VtdmVudHMgdGhpcyBraW5kIG9mIGRldGVjdGlvbi5cbiAgICAgKiBEZXNwaXRlIG11bHRpcGxlIHJlcXVlc3RzLCB0aGUgY29yZS1qcyBtYWludGFpbmVyIGhhcyBtYWRlIGl0IGNsZWFyOiBhbnlcbiAgICAgKiBhdHRlbXB0IHRvIGZpeCB0aGUgZGV0ZWN0aW9uIHdpbGwgYmUgb2JzdHJ1Y3RlZC4gQXMgYSByZXN1bHQsIHdlJ3JlIGxlZnRcbiAgICAgKiB3aXRoIGxpdHRsZSBjaG9pY2UgYnV0IHRvIHRocm93IGFuIGVycm9yLiBVbmZvcnR1bmF0ZWx5LCB0aGlzIGFsc28gYWZmZWN0c1xuICAgICAqIHBhY2thZ2VzLCBsaWtlIFtiYWJlbC1wb2x5ZmlsbF0oaHR0cHM6Ly93d3cubnBtanMuY29tL3BhY2thZ2UvYmFiZWwtcG9seWZpbGwpLFxuICAgICAqIHdoaWNoIHJlbHkgb24gY29yZS1qcy5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAzLjAuMFxuICAgICAqIEBjYXRlZ29yeSBMYW5nXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgYSBuYXRpdmUgZnVuY3Rpb24sXG4gICAgICogIGVsc2UgYGZhbHNlYC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5pc05hdGl2ZShBcnJheS5wcm90b3R5cGUucHVzaCk7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqXG4gICAgICogXy5pc05hdGl2ZShfKTtcbiAgICAgKiAvLyA9PiBmYWxzZVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGlzTmF0aXZlKHZhbHVlKSB7XG4gICAgICBpZiAoaXNNYXNrYWJsZSh2YWx1ZSkpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKENPUkVfRVJST1JfVEVYVCk7XG4gICAgICB9XG4gICAgICByZXR1cm4gYmFzZUlzTmF0aXZlKHZhbHVlKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBgbnVsbGAuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMC4xLjBcbiAgICAgKiBAY2F0ZWdvcnkgTGFuZ1xuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGBudWxsYCwgZWxzZSBgZmFsc2VgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLmlzTnVsbChudWxsKTtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICpcbiAgICAgKiBfLmlzTnVsbCh2b2lkIDApO1xuICAgICAqIC8vID0+IGZhbHNlXG4gICAgICovXG4gICAgZnVuY3Rpb24gaXNOdWxsKHZhbHVlKSB7XG4gICAgICByZXR1cm4gdmFsdWUgPT09IG51bGw7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgYG51bGxgIG9yIGB1bmRlZmluZWRgLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMC4wXG4gICAgICogQGNhdGVnb3J5IExhbmdcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBudWxsaXNoLCBlbHNlIGBmYWxzZWAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uaXNOaWwobnVsbCk7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqXG4gICAgICogXy5pc05pbCh2b2lkIDApO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKlxuICAgICAqIF8uaXNOaWwoTmFOKTtcbiAgICAgKiAvLyA9PiBmYWxzZVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGlzTmlsKHZhbHVlKSB7XG4gICAgICByZXR1cm4gdmFsdWUgPT0gbnVsbDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBjbGFzc2lmaWVkIGFzIGEgYE51bWJlcmAgcHJpbWl0aXZlIG9yIG9iamVjdC5cbiAgICAgKlxuICAgICAqICoqTm90ZToqKiBUbyBleGNsdWRlIGBJbmZpbml0eWAsIGAtSW5maW5pdHlgLCBhbmQgYE5hTmAsIHdoaWNoIGFyZVxuICAgICAqIGNsYXNzaWZpZWQgYXMgbnVtYmVycywgdXNlIHRoZSBgXy5pc0Zpbml0ZWAgbWV0aG9kLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDAuMS4wXG4gICAgICogQGNhdGVnb3J5IExhbmdcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhIG51bWJlciwgZWxzZSBgZmFsc2VgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLmlzTnVtYmVyKDMpO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKlxuICAgICAqIF8uaXNOdW1iZXIoTnVtYmVyLk1JTl9WQUxVRSk7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqXG4gICAgICogXy5pc051bWJlcihJbmZpbml0eSk7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqXG4gICAgICogXy5pc051bWJlcignMycpO1xuICAgICAqIC8vID0+IGZhbHNlXG4gICAgICovXG4gICAgZnVuY3Rpb24gaXNOdW1iZXIodmFsdWUpIHtcbiAgICAgIHJldHVybiB0eXBlb2YgdmFsdWUgPT0gJ251bWJlcicgfHxcbiAgICAgICAgKGlzT2JqZWN0TGlrZSh2YWx1ZSkgJiYgYmFzZUdldFRhZyh2YWx1ZSkgPT0gbnVtYmVyVGFnKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBhIHBsYWluIG9iamVjdCwgdGhhdCBpcywgYW4gb2JqZWN0IGNyZWF0ZWQgYnkgdGhlXG4gICAgICogYE9iamVjdGAgY29uc3RydWN0b3Igb3Igb25lIHdpdGggYSBgW1tQcm90b3R5cGVdXWAgb2YgYG51bGxgLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDAuOC4wXG4gICAgICogQGNhdGVnb3J5IExhbmdcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhIHBsYWluIG9iamVjdCwgZWxzZSBgZmFsc2VgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBmdW5jdGlvbiBGb28oKSB7XG4gICAgICogICB0aGlzLmEgPSAxO1xuICAgICAqIH1cbiAgICAgKlxuICAgICAqIF8uaXNQbGFpbk9iamVjdChuZXcgRm9vKTtcbiAgICAgKiAvLyA9PiBmYWxzZVxuICAgICAqXG4gICAgICogXy5pc1BsYWluT2JqZWN0KFsxLCAyLCAzXSk7XG4gICAgICogLy8gPT4gZmFsc2VcbiAgICAgKlxuICAgICAqIF8uaXNQbGFpbk9iamVjdCh7ICd4JzogMCwgJ3knOiAwIH0pO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKlxuICAgICAqIF8uaXNQbGFpbk9iamVjdChPYmplY3QuY3JlYXRlKG51bGwpKTtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICovXG4gICAgZnVuY3Rpb24gaXNQbGFpbk9iamVjdCh2YWx1ZSkge1xuICAgICAgaWYgKCFpc09iamVjdExpa2UodmFsdWUpIHx8IGJhc2VHZXRUYWcodmFsdWUpICE9IG9iamVjdFRhZykge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgICB2YXIgcHJvdG8gPSBnZXRQcm90b3R5cGUodmFsdWUpO1xuICAgICAgaWYgKHByb3RvID09PSBudWxsKSB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgfVxuICAgICAgdmFyIEN0b3IgPSBoYXNPd25Qcm9wZXJ0eS5jYWxsKHByb3RvLCAnY29uc3RydWN0b3InKSAmJiBwcm90by5jb25zdHJ1Y3RvcjtcbiAgICAgIHJldHVybiB0eXBlb2YgQ3RvciA9PSAnZnVuY3Rpb24nICYmIEN0b3IgaW5zdGFuY2VvZiBDdG9yICYmXG4gICAgICAgIGZ1bmNUb1N0cmluZy5jYWxsKEN0b3IpID09IG9iamVjdEN0b3JTdHJpbmc7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgY2xhc3NpZmllZCBhcyBhIGBSZWdFeHBgIG9iamVjdC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAwLjEuMFxuICAgICAqIEBjYXRlZ29yeSBMYW5nXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgYSByZWdleHAsIGVsc2UgYGZhbHNlYC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5pc1JlZ0V4cCgvYWJjLyk7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqXG4gICAgICogXy5pc1JlZ0V4cCgnL2FiYy8nKTtcbiAgICAgKiAvLyA9PiBmYWxzZVxuICAgICAqL1xuICAgIHZhciBpc1JlZ0V4cCA9IG5vZGVJc1JlZ0V4cCA/IGJhc2VVbmFyeShub2RlSXNSZWdFeHApIDogYmFzZUlzUmVnRXhwO1xuXG4gICAgLyoqXG4gICAgICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgYSBzYWZlIGludGVnZXIuIEFuIGludGVnZXIgaXMgc2FmZSBpZiBpdCdzIGFuIElFRUUtNzU0XG4gICAgICogZG91YmxlIHByZWNpc2lvbiBudW1iZXIgd2hpY2ggaXNuJ3QgdGhlIHJlc3VsdCBvZiBhIHJvdW5kZWQgdW5zYWZlIGludGVnZXIuXG4gICAgICpcbiAgICAgKiAqKk5vdGU6KiogVGhpcyBtZXRob2QgaXMgYmFzZWQgb25cbiAgICAgKiBbYE51bWJlci5pc1NhZmVJbnRlZ2VyYF0oaHR0cHM6Ly9tZG4uaW8vTnVtYmVyL2lzU2FmZUludGVnZXIpLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMC4wXG4gICAgICogQGNhdGVnb3J5IExhbmdcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhIHNhZmUgaW50ZWdlciwgZWxzZSBgZmFsc2VgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLmlzU2FmZUludGVnZXIoMyk7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqXG4gICAgICogXy5pc1NhZmVJbnRlZ2VyKE51bWJlci5NSU5fVkFMVUUpO1xuICAgICAqIC8vID0+IGZhbHNlXG4gICAgICpcbiAgICAgKiBfLmlzU2FmZUludGVnZXIoSW5maW5pdHkpO1xuICAgICAqIC8vID0+IGZhbHNlXG4gICAgICpcbiAgICAgKiBfLmlzU2FmZUludGVnZXIoJzMnKTtcbiAgICAgKiAvLyA9PiBmYWxzZVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGlzU2FmZUludGVnZXIodmFsdWUpIHtcbiAgICAgIHJldHVybiBpc0ludGVnZXIodmFsdWUpICYmIHZhbHVlID49IC1NQVhfU0FGRV9JTlRFR0VSICYmIHZhbHVlIDw9IE1BWF9TQUZFX0lOVEVHRVI7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgY2xhc3NpZmllZCBhcyBhIGBTZXRgIG9iamVjdC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjMuMFxuICAgICAqIEBjYXRlZ29yeSBMYW5nXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgYSBzZXQsIGVsc2UgYGZhbHNlYC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5pc1NldChuZXcgU2V0KTtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICpcbiAgICAgKiBfLmlzU2V0KG5ldyBXZWFrU2V0KTtcbiAgICAgKiAvLyA9PiBmYWxzZVxuICAgICAqL1xuICAgIHZhciBpc1NldCA9IG5vZGVJc1NldCA/IGJhc2VVbmFyeShub2RlSXNTZXQpIDogYmFzZUlzU2V0O1xuXG4gICAgLyoqXG4gICAgICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgY2xhc3NpZmllZCBhcyBhIGBTdHJpbmdgIHByaW1pdGl2ZSBvciBvYmplY3QuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQHNpbmNlIDAuMS4wXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAY2F0ZWdvcnkgTGFuZ1xuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGEgc3RyaW5nLCBlbHNlIGBmYWxzZWAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uaXNTdHJpbmcoJ2FiYycpO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKlxuICAgICAqIF8uaXNTdHJpbmcoMSk7XG4gICAgICogLy8gPT4gZmFsc2VcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBpc1N0cmluZyh2YWx1ZSkge1xuICAgICAgcmV0dXJuIHR5cGVvZiB2YWx1ZSA9PSAnc3RyaW5nJyB8fFxuICAgICAgICAoIWlzQXJyYXkodmFsdWUpICYmIGlzT2JqZWN0TGlrZSh2YWx1ZSkgJiYgYmFzZUdldFRhZyh2YWx1ZSkgPT0gc3RyaW5nVGFnKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBjbGFzc2lmaWVkIGFzIGEgYFN5bWJvbGAgcHJpbWl0aXZlIG9yIG9iamVjdC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjAuMFxuICAgICAqIEBjYXRlZ29yeSBMYW5nXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgYSBzeW1ib2wsIGVsc2UgYGZhbHNlYC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5pc1N5bWJvbChTeW1ib2wuaXRlcmF0b3IpO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKlxuICAgICAqIF8uaXNTeW1ib2woJ2FiYycpO1xuICAgICAqIC8vID0+IGZhbHNlXG4gICAgICovXG4gICAgZnVuY3Rpb24gaXNTeW1ib2wodmFsdWUpIHtcbiAgICAgIHJldHVybiB0eXBlb2YgdmFsdWUgPT0gJ3N5bWJvbCcgfHxcbiAgICAgICAgKGlzT2JqZWN0TGlrZSh2YWx1ZSkgJiYgYmFzZUdldFRhZyh2YWx1ZSkgPT0gc3ltYm9sVGFnKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBjbGFzc2lmaWVkIGFzIGEgdHlwZWQgYXJyYXkuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMy4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgTGFuZ1xuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGEgdHlwZWQgYXJyYXksIGVsc2UgYGZhbHNlYC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5pc1R5cGVkQXJyYXkobmV3IFVpbnQ4QXJyYXkpO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKlxuICAgICAqIF8uaXNUeXBlZEFycmF5KFtdKTtcbiAgICAgKiAvLyA9PiBmYWxzZVxuICAgICAqL1xuICAgIHZhciBpc1R5cGVkQXJyYXkgPSBub2RlSXNUeXBlZEFycmF5ID8gYmFzZVVuYXJ5KG5vZGVJc1R5cGVkQXJyYXkpIDogYmFzZUlzVHlwZWRBcnJheTtcblxuICAgIC8qKlxuICAgICAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIGB1bmRlZmluZWRgLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBzaW5jZSAwLjEuMFxuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQGNhdGVnb3J5IExhbmdcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBgdW5kZWZpbmVkYCwgZWxzZSBgZmFsc2VgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLmlzVW5kZWZpbmVkKHZvaWQgMCk7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqXG4gICAgICogXy5pc1VuZGVmaW5lZChudWxsKTtcbiAgICAgKiAvLyA9PiBmYWxzZVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGlzVW5kZWZpbmVkKHZhbHVlKSB7XG4gICAgICByZXR1cm4gdmFsdWUgPT09IHVuZGVmaW5lZDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBjbGFzc2lmaWVkIGFzIGEgYFdlYWtNYXBgIG9iamVjdC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjMuMFxuICAgICAqIEBjYXRlZ29yeSBMYW5nXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgYSB3ZWFrIG1hcCwgZWxzZSBgZmFsc2VgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLmlzV2Vha01hcChuZXcgV2Vha01hcCk7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqXG4gICAgICogXy5pc1dlYWtNYXAobmV3IE1hcCk7XG4gICAgICogLy8gPT4gZmFsc2VcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBpc1dlYWtNYXAodmFsdWUpIHtcbiAgICAgIHJldHVybiBpc09iamVjdExpa2UodmFsdWUpICYmIGdldFRhZyh2YWx1ZSkgPT0gd2Vha01hcFRhZztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBjbGFzc2lmaWVkIGFzIGEgYFdlYWtTZXRgIG9iamVjdC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjMuMFxuICAgICAqIEBjYXRlZ29yeSBMYW5nXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgYSB3ZWFrIHNldCwgZWxzZSBgZmFsc2VgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLmlzV2Vha1NldChuZXcgV2Vha1NldCk7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqXG4gICAgICogXy5pc1dlYWtTZXQobmV3IFNldCk7XG4gICAgICogLy8gPT4gZmFsc2VcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBpc1dlYWtTZXQodmFsdWUpIHtcbiAgICAgIHJldHVybiBpc09iamVjdExpa2UodmFsdWUpICYmIGJhc2VHZXRUYWcodmFsdWUpID09IHdlYWtTZXRUYWc7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgbGVzcyB0aGFuIGBvdGhlcmAuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMy45LjBcbiAgICAgKiBAY2F0ZWdvcnkgTGFuZ1xuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNvbXBhcmUuXG4gICAgICogQHBhcmFtIHsqfSBvdGhlciBUaGUgb3RoZXIgdmFsdWUgdG8gY29tcGFyZS5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBsZXNzIHRoYW4gYG90aGVyYCxcbiAgICAgKiAgZWxzZSBgZmFsc2VgLlxuICAgICAqIEBzZWUgXy5ndFxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLmx0KDEsIDMpO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKlxuICAgICAqIF8ubHQoMywgMyk7XG4gICAgICogLy8gPT4gZmFsc2VcbiAgICAgKlxuICAgICAqIF8ubHQoMywgMSk7XG4gICAgICogLy8gPT4gZmFsc2VcbiAgICAgKi9cbiAgICB2YXIgbHQgPSBjcmVhdGVSZWxhdGlvbmFsT3BlcmF0aW9uKGJhc2VMdCk7XG5cbiAgICAvKipcbiAgICAgKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gYG90aGVyYC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAzLjkuMFxuICAgICAqIEBjYXRlZ29yeSBMYW5nXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY29tcGFyZS5cbiAgICAgKiBAcGFyYW0geyp9IG90aGVyIFRoZSBvdGhlciB2YWx1ZSB0byBjb21wYXJlLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGxlc3MgdGhhbiBvciBlcXVhbCB0b1xuICAgICAqICBgb3RoZXJgLCBlbHNlIGBmYWxzZWAuXG4gICAgICogQHNlZSBfLmd0ZVxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLmx0ZSgxLCAzKTtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICpcbiAgICAgKiBfLmx0ZSgzLCAzKTtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICpcbiAgICAgKiBfLmx0ZSgzLCAxKTtcbiAgICAgKiAvLyA9PiBmYWxzZVxuICAgICAqL1xuICAgIHZhciBsdGUgPSBjcmVhdGVSZWxhdGlvbmFsT3BlcmF0aW9uKGZ1bmN0aW9uKHZhbHVlLCBvdGhlcikge1xuICAgICAgcmV0dXJuIHZhbHVlIDw9IG90aGVyO1xuICAgIH0pO1xuXG4gICAgLyoqXG4gICAgICogQ29udmVydHMgYHZhbHVlYCB0byBhbiBhcnJheS5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAc2luY2UgMC4xLjBcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBjYXRlZ29yeSBMYW5nXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY29udmVydC5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIGNvbnZlcnRlZCBhcnJheS5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy50b0FycmF5KHsgJ2EnOiAxLCAnYic6IDIgfSk7XG4gICAgICogLy8gPT4gWzEsIDJdXG4gICAgICpcbiAgICAgKiBfLnRvQXJyYXkoJ2FiYycpO1xuICAgICAqIC8vID0+IFsnYScsICdiJywgJ2MnXVxuICAgICAqXG4gICAgICogXy50b0FycmF5KDEpO1xuICAgICAqIC8vID0+IFtdXG4gICAgICpcbiAgICAgKiBfLnRvQXJyYXkobnVsbCk7XG4gICAgICogLy8gPT4gW11cbiAgICAgKi9cbiAgICBmdW5jdGlvbiB0b0FycmF5KHZhbHVlKSB7XG4gICAgICBpZiAoIXZhbHVlKSB7XG4gICAgICAgIHJldHVybiBbXTtcbiAgICAgIH1cbiAgICAgIGlmIChpc0FycmF5TGlrZSh2YWx1ZSkpIHtcbiAgICAgICAgcmV0dXJuIGlzU3RyaW5nKHZhbHVlKSA/IHN0cmluZ1RvQXJyYXkodmFsdWUpIDogY29weUFycmF5KHZhbHVlKTtcbiAgICAgIH1cbiAgICAgIGlmIChzeW1JdGVyYXRvciAmJiB2YWx1ZVtzeW1JdGVyYXRvcl0pIHtcbiAgICAgICAgcmV0dXJuIGl0ZXJhdG9yVG9BcnJheSh2YWx1ZVtzeW1JdGVyYXRvcl0oKSk7XG4gICAgICB9XG4gICAgICB2YXIgdGFnID0gZ2V0VGFnKHZhbHVlKSxcbiAgICAgICAgICBmdW5jID0gdGFnID09IG1hcFRhZyA/IG1hcFRvQXJyYXkgOiAodGFnID09IHNldFRhZyA/IHNldFRvQXJyYXkgOiB2YWx1ZXMpO1xuXG4gICAgICByZXR1cm4gZnVuYyh2YWx1ZSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ29udmVydHMgYHZhbHVlYCB0byBhIGZpbml0ZSBudW1iZXIuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4xMi4wXG4gICAgICogQGNhdGVnb3J5IExhbmdcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjb252ZXJ0LlxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9IFJldHVybnMgdGhlIGNvbnZlcnRlZCBudW1iZXIuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8udG9GaW5pdGUoMy4yKTtcbiAgICAgKiAvLyA9PiAzLjJcbiAgICAgKlxuICAgICAqIF8udG9GaW5pdGUoTnVtYmVyLk1JTl9WQUxVRSk7XG4gICAgICogLy8gPT4gNWUtMzI0XG4gICAgICpcbiAgICAgKiBfLnRvRmluaXRlKEluZmluaXR5KTtcbiAgICAgKiAvLyA9PiAxLjc5NzY5MzEzNDg2MjMxNTdlKzMwOFxuICAgICAqXG4gICAgICogXy50b0Zpbml0ZSgnMy4yJyk7XG4gICAgICogLy8gPT4gMy4yXG4gICAgICovXG4gICAgZnVuY3Rpb24gdG9GaW5pdGUodmFsdWUpIHtcbiAgICAgIGlmICghdmFsdWUpIHtcbiAgICAgICAgcmV0dXJuIHZhbHVlID09PSAwID8gdmFsdWUgOiAwO1xuICAgICAgfVxuICAgICAgdmFsdWUgPSB0b051bWJlcih2YWx1ZSk7XG4gICAgICBpZiAodmFsdWUgPT09IElORklOSVRZIHx8IHZhbHVlID09PSAtSU5GSU5JVFkpIHtcbiAgICAgICAgdmFyIHNpZ24gPSAodmFsdWUgPCAwID8gLTEgOiAxKTtcbiAgICAgICAgcmV0dXJuIHNpZ24gKiBNQVhfSU5URUdFUjtcbiAgICAgIH1cbiAgICAgIHJldHVybiB2YWx1ZSA9PT0gdmFsdWUgPyB2YWx1ZSA6IDA7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ29udmVydHMgYHZhbHVlYCB0byBhbiBpbnRlZ2VyLlxuICAgICAqXG4gICAgICogKipOb3RlOioqIFRoaXMgbWV0aG9kIGlzIGxvb3NlbHkgYmFzZWQgb25cbiAgICAgKiBbYFRvSW50ZWdlcmBdKGh0dHA6Ly93d3cuZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi83LjAvI3NlYy10b2ludGVnZXIpLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMC4wXG4gICAgICogQGNhdGVnb3J5IExhbmdcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjb252ZXJ0LlxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9IFJldHVybnMgdGhlIGNvbnZlcnRlZCBpbnRlZ2VyLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLnRvSW50ZWdlcigzLjIpO1xuICAgICAqIC8vID0+IDNcbiAgICAgKlxuICAgICAqIF8udG9JbnRlZ2VyKE51bWJlci5NSU5fVkFMVUUpO1xuICAgICAqIC8vID0+IDBcbiAgICAgKlxuICAgICAqIF8udG9JbnRlZ2VyKEluZmluaXR5KTtcbiAgICAgKiAvLyA9PiAxLjc5NzY5MzEzNDg2MjMxNTdlKzMwOFxuICAgICAqXG4gICAgICogXy50b0ludGVnZXIoJzMuMicpO1xuICAgICAqIC8vID0+IDNcbiAgICAgKi9cbiAgICBmdW5jdGlvbiB0b0ludGVnZXIodmFsdWUpIHtcbiAgICAgIHZhciByZXN1bHQgPSB0b0Zpbml0ZSh2YWx1ZSksXG4gICAgICAgICAgcmVtYWluZGVyID0gcmVzdWx0ICUgMTtcblxuICAgICAgcmV0dXJuIHJlc3VsdCA9PT0gcmVzdWx0ID8gKHJlbWFpbmRlciA/IHJlc3VsdCAtIHJlbWFpbmRlciA6IHJlc3VsdCkgOiAwO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENvbnZlcnRzIGB2YWx1ZWAgdG8gYW4gaW50ZWdlciBzdWl0YWJsZSBmb3IgdXNlIGFzIHRoZSBsZW5ndGggb2YgYW5cbiAgICAgKiBhcnJheS1saWtlIG9iamVjdC5cbiAgICAgKlxuICAgICAqICoqTm90ZToqKiBUaGlzIG1ldGhvZCBpcyBiYXNlZCBvblxuICAgICAqIFtgVG9MZW5ndGhgXShodHRwOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi83LjAvI3NlYy10b2xlbmd0aCkuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgTGFuZ1xuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNvbnZlcnQuXG4gICAgICogQHJldHVybnMge251bWJlcn0gUmV0dXJucyB0aGUgY29udmVydGVkIGludGVnZXIuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8udG9MZW5ndGgoMy4yKTtcbiAgICAgKiAvLyA9PiAzXG4gICAgICpcbiAgICAgKiBfLnRvTGVuZ3RoKE51bWJlci5NSU5fVkFMVUUpO1xuICAgICAqIC8vID0+IDBcbiAgICAgKlxuICAgICAqIF8udG9MZW5ndGgoSW5maW5pdHkpO1xuICAgICAqIC8vID0+IDQyOTQ5NjcyOTVcbiAgICAgKlxuICAgICAqIF8udG9MZW5ndGgoJzMuMicpO1xuICAgICAqIC8vID0+IDNcbiAgICAgKi9cbiAgICBmdW5jdGlvbiB0b0xlbmd0aCh2YWx1ZSkge1xuICAgICAgcmV0dXJuIHZhbHVlID8gYmFzZUNsYW1wKHRvSW50ZWdlcih2YWx1ZSksIDAsIE1BWF9BUlJBWV9MRU5HVEgpIDogMDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDb252ZXJ0cyBgdmFsdWVgIHRvIGEgbnVtYmVyLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMC4wXG4gICAgICogQGNhdGVnb3J5IExhbmdcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBwcm9jZXNzLlxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9IFJldHVybnMgdGhlIG51bWJlci5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy50b051bWJlcigzLjIpO1xuICAgICAqIC8vID0+IDMuMlxuICAgICAqXG4gICAgICogXy50b051bWJlcihOdW1iZXIuTUlOX1ZBTFVFKTtcbiAgICAgKiAvLyA9PiA1ZS0zMjRcbiAgICAgKlxuICAgICAqIF8udG9OdW1iZXIoSW5maW5pdHkpO1xuICAgICAqIC8vID0+IEluZmluaXR5XG4gICAgICpcbiAgICAgKiBfLnRvTnVtYmVyKCczLjInKTtcbiAgICAgKiAvLyA9PiAzLjJcbiAgICAgKi9cbiAgICBmdW5jdGlvbiB0b051bWJlcih2YWx1ZSkge1xuICAgICAgaWYgKHR5cGVvZiB2YWx1ZSA9PSAnbnVtYmVyJykge1xuICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgICB9XG4gICAgICBpZiAoaXNTeW1ib2wodmFsdWUpKSB7XG4gICAgICAgIHJldHVybiBOQU47XG4gICAgICB9XG4gICAgICBpZiAoaXNPYmplY3QodmFsdWUpKSB7XG4gICAgICAgIHZhciBvdGhlciA9IHR5cGVvZiB2YWx1ZS52YWx1ZU9mID09ICdmdW5jdGlvbicgPyB2YWx1ZS52YWx1ZU9mKCkgOiB2YWx1ZTtcbiAgICAgICAgdmFsdWUgPSBpc09iamVjdChvdGhlcikgPyAob3RoZXIgKyAnJykgOiBvdGhlcjtcbiAgICAgIH1cbiAgICAgIGlmICh0eXBlb2YgdmFsdWUgIT0gJ3N0cmluZycpIHtcbiAgICAgICAgcmV0dXJuIHZhbHVlID09PSAwID8gdmFsdWUgOiArdmFsdWU7XG4gICAgICB9XG4gICAgICB2YWx1ZSA9IGJhc2VUcmltKHZhbHVlKTtcbiAgICAgIHZhciBpc0JpbmFyeSA9IHJlSXNCaW5hcnkudGVzdCh2YWx1ZSk7XG4gICAgICByZXR1cm4gKGlzQmluYXJ5IHx8IHJlSXNPY3RhbC50ZXN0KHZhbHVlKSlcbiAgICAgICAgPyBmcmVlUGFyc2VJbnQodmFsdWUuc2xpY2UoMiksIGlzQmluYXJ5ID8gMiA6IDgpXG4gICAgICAgIDogKHJlSXNCYWRIZXgudGVzdCh2YWx1ZSkgPyBOQU4gOiArdmFsdWUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENvbnZlcnRzIGB2YWx1ZWAgdG8gYSBwbGFpbiBvYmplY3QgZmxhdHRlbmluZyBpbmhlcml0ZWQgZW51bWVyYWJsZSBzdHJpbmdcbiAgICAgKiBrZXllZCBwcm9wZXJ0aWVzIG9mIGB2YWx1ZWAgdG8gb3duIHByb3BlcnRpZXMgb2YgdGhlIHBsYWluIG9iamVjdC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAzLjAuMFxuICAgICAqIEBjYXRlZ29yeSBMYW5nXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY29udmVydC5cbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIHRoZSBjb252ZXJ0ZWQgcGxhaW4gb2JqZWN0LlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBmdW5jdGlvbiBGb28oKSB7XG4gICAgICogICB0aGlzLmIgPSAyO1xuICAgICAqIH1cbiAgICAgKlxuICAgICAqIEZvby5wcm90b3R5cGUuYyA9IDM7XG4gICAgICpcbiAgICAgKiBfLmFzc2lnbih7ICdhJzogMSB9LCBuZXcgRm9vKTtcbiAgICAgKiAvLyA9PiB7ICdhJzogMSwgJ2InOiAyIH1cbiAgICAgKlxuICAgICAqIF8uYXNzaWduKHsgJ2EnOiAxIH0sIF8udG9QbGFpbk9iamVjdChuZXcgRm9vKSk7XG4gICAgICogLy8gPT4geyAnYSc6IDEsICdiJzogMiwgJ2MnOiAzIH1cbiAgICAgKi9cbiAgICBmdW5jdGlvbiB0b1BsYWluT2JqZWN0KHZhbHVlKSB7XG4gICAgICByZXR1cm4gY29weU9iamVjdCh2YWx1ZSwga2V5c0luKHZhbHVlKSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ29udmVydHMgYHZhbHVlYCB0byBhIHNhZmUgaW50ZWdlci4gQSBzYWZlIGludGVnZXIgY2FuIGJlIGNvbXBhcmVkIGFuZFxuICAgICAqIHJlcHJlc2VudGVkIGNvcnJlY3RseS5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjAuMFxuICAgICAqIEBjYXRlZ29yeSBMYW5nXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY29udmVydC5cbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBSZXR1cm5zIHRoZSBjb252ZXJ0ZWQgaW50ZWdlci5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy50b1NhZmVJbnRlZ2VyKDMuMik7XG4gICAgICogLy8gPT4gM1xuICAgICAqXG4gICAgICogXy50b1NhZmVJbnRlZ2VyKE51bWJlci5NSU5fVkFMVUUpO1xuICAgICAqIC8vID0+IDBcbiAgICAgKlxuICAgICAqIF8udG9TYWZlSW50ZWdlcihJbmZpbml0eSk7XG4gICAgICogLy8gPT4gOTAwNzE5OTI1NDc0MDk5MVxuICAgICAqXG4gICAgICogXy50b1NhZmVJbnRlZ2VyKCczLjInKTtcbiAgICAgKiAvLyA9PiAzXG4gICAgICovXG4gICAgZnVuY3Rpb24gdG9TYWZlSW50ZWdlcih2YWx1ZSkge1xuICAgICAgcmV0dXJuIHZhbHVlXG4gICAgICAgID8gYmFzZUNsYW1wKHRvSW50ZWdlcih2YWx1ZSksIC1NQVhfU0FGRV9JTlRFR0VSLCBNQVhfU0FGRV9JTlRFR0VSKVxuICAgICAgICA6ICh2YWx1ZSA9PT0gMCA/IHZhbHVlIDogMCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ29udmVydHMgYHZhbHVlYCB0byBhIHN0cmluZy4gQW4gZW1wdHkgc3RyaW5nIGlzIHJldHVybmVkIGZvciBgbnVsbGBcbiAgICAgKiBhbmQgYHVuZGVmaW5lZGAgdmFsdWVzLiBUaGUgc2lnbiBvZiBgLTBgIGlzIHByZXNlcnZlZC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjAuMFxuICAgICAqIEBjYXRlZ29yeSBMYW5nXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY29udmVydC5cbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfSBSZXR1cm5zIHRoZSBjb252ZXJ0ZWQgc3RyaW5nLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLnRvU3RyaW5nKG51bGwpO1xuICAgICAqIC8vID0+ICcnXG4gICAgICpcbiAgICAgKiBfLnRvU3RyaW5nKC0wKTtcbiAgICAgKiAvLyA9PiAnLTAnXG4gICAgICpcbiAgICAgKiBfLnRvU3RyaW5nKFsxLCAyLCAzXSk7XG4gICAgICogLy8gPT4gJzEsMiwzJ1xuICAgICAqL1xuICAgIGZ1bmN0aW9uIHRvU3RyaW5nKHZhbHVlKSB7XG4gICAgICByZXR1cm4gdmFsdWUgPT0gbnVsbCA/ICcnIDogYmFzZVRvU3RyaW5nKHZhbHVlKTtcbiAgICB9XG5cbiAgICAvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovXG5cbiAgICAvKipcbiAgICAgKiBBc3NpZ25zIG93biBlbnVtZXJhYmxlIHN0cmluZyBrZXllZCBwcm9wZXJ0aWVzIG9mIHNvdXJjZSBvYmplY3RzIHRvIHRoZVxuICAgICAqIGRlc3RpbmF0aW9uIG9iamVjdC4gU291cmNlIG9iamVjdHMgYXJlIGFwcGxpZWQgZnJvbSBsZWZ0IHRvIHJpZ2h0LlxuICAgICAqIFN1YnNlcXVlbnQgc291cmNlcyBvdmVyd3JpdGUgcHJvcGVydHkgYXNzaWdubWVudHMgb2YgcHJldmlvdXMgc291cmNlcy5cbiAgICAgKlxuICAgICAqICoqTm90ZToqKiBUaGlzIG1ldGhvZCBtdXRhdGVzIGBvYmplY3RgIGFuZCBpcyBsb29zZWx5IGJhc2VkIG9uXG4gICAgICogW2BPYmplY3QuYXNzaWduYF0oaHR0cHM6Ly9tZG4uaW8vT2JqZWN0L2Fzc2lnbikuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMC4xMC4wXG4gICAgICogQGNhdGVnb3J5IE9iamVjdFxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIGRlc3RpbmF0aW9uIG9iamVjdC5cbiAgICAgKiBAcGFyYW0gey4uLk9iamVjdH0gW3NvdXJjZXNdIFRoZSBzb3VyY2Ugb2JqZWN0cy5cbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIGBvYmplY3RgLlxuICAgICAqIEBzZWUgXy5hc3NpZ25JblxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBmdW5jdGlvbiBGb28oKSB7XG4gICAgICogICB0aGlzLmEgPSAxO1xuICAgICAqIH1cbiAgICAgKlxuICAgICAqIGZ1bmN0aW9uIEJhcigpIHtcbiAgICAgKiAgIHRoaXMuYyA9IDM7XG4gICAgICogfVxuICAgICAqXG4gICAgICogRm9vLnByb3RvdHlwZS5iID0gMjtcbiAgICAgKiBCYXIucHJvdG90eXBlLmQgPSA0O1xuICAgICAqXG4gICAgICogXy5hc3NpZ24oeyAnYSc6IDAgfSwgbmV3IEZvbywgbmV3IEJhcik7XG4gICAgICogLy8gPT4geyAnYSc6IDEsICdjJzogMyB9XG4gICAgICovXG4gICAgdmFyIGFzc2lnbiA9IGNyZWF0ZUFzc2lnbmVyKGZ1bmN0aW9uKG9iamVjdCwgc291cmNlKSB7XG4gICAgICBpZiAoaXNQcm90b3R5cGUoc291cmNlKSB8fCBpc0FycmF5TGlrZShzb3VyY2UpKSB7XG4gICAgICAgIGNvcHlPYmplY3Qoc291cmNlLCBrZXlzKHNvdXJjZSksIG9iamVjdCk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGZvciAodmFyIGtleSBpbiBzb3VyY2UpIHtcbiAgICAgICAgaWYgKGhhc093blByb3BlcnR5LmNhbGwoc291cmNlLCBrZXkpKSB7XG4gICAgICAgICAgYXNzaWduVmFsdWUob2JqZWN0LCBrZXksIHNvdXJjZVtrZXldKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0pO1xuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgaXMgbGlrZSBgXy5hc3NpZ25gIGV4Y2VwdCB0aGF0IGl0IGl0ZXJhdGVzIG92ZXIgb3duIGFuZFxuICAgICAqIGluaGVyaXRlZCBzb3VyY2UgcHJvcGVydGllcy5cbiAgICAgKlxuICAgICAqICoqTm90ZToqKiBUaGlzIG1ldGhvZCBtdXRhdGVzIGBvYmplY3RgLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMC4wXG4gICAgICogQGFsaWFzIGV4dGVuZFxuICAgICAqIEBjYXRlZ29yeSBPYmplY3RcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBkZXN0aW5hdGlvbiBvYmplY3QuXG4gICAgICogQHBhcmFtIHsuLi5PYmplY3R9IFtzb3VyY2VzXSBUaGUgc291cmNlIG9iamVjdHMuXG4gICAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyBgb2JqZWN0YC5cbiAgICAgKiBAc2VlIF8uYXNzaWduXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIGZ1bmN0aW9uIEZvbygpIHtcbiAgICAgKiAgIHRoaXMuYSA9IDE7XG4gICAgICogfVxuICAgICAqXG4gICAgICogZnVuY3Rpb24gQmFyKCkge1xuICAgICAqICAgdGhpcy5jID0gMztcbiAgICAgKiB9XG4gICAgICpcbiAgICAgKiBGb28ucHJvdG90eXBlLmIgPSAyO1xuICAgICAqIEJhci5wcm90b3R5cGUuZCA9IDQ7XG4gICAgICpcbiAgICAgKiBfLmFzc2lnbkluKHsgJ2EnOiAwIH0sIG5ldyBGb28sIG5ldyBCYXIpO1xuICAgICAqIC8vID0+IHsgJ2EnOiAxLCAnYic6IDIsICdjJzogMywgJ2QnOiA0IH1cbiAgICAgKi9cbiAgICB2YXIgYXNzaWduSW4gPSBjcmVhdGVBc3NpZ25lcihmdW5jdGlvbihvYmplY3QsIHNvdXJjZSkge1xuICAgICAgY29weU9iamVjdChzb3VyY2UsIGtleXNJbihzb3VyY2UpLCBvYmplY3QpO1xuICAgIH0pO1xuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgaXMgbGlrZSBgXy5hc3NpZ25JbmAgZXhjZXB0IHRoYXQgaXQgYWNjZXB0cyBgY3VzdG9taXplcmBcbiAgICAgKiB3aGljaCBpcyBpbnZva2VkIHRvIHByb2R1Y2UgdGhlIGFzc2lnbmVkIHZhbHVlcy4gSWYgYGN1c3RvbWl6ZXJgIHJldHVybnNcbiAgICAgKiBgdW5kZWZpbmVkYCwgYXNzaWdubWVudCBpcyBoYW5kbGVkIGJ5IHRoZSBtZXRob2QgaW5zdGVhZC4gVGhlIGBjdXN0b21pemVyYFxuICAgICAqIGlzIGludm9rZWQgd2l0aCBmaXZlIGFyZ3VtZW50czogKG9ialZhbHVlLCBzcmNWYWx1ZSwga2V5LCBvYmplY3QsIHNvdXJjZSkuXG4gICAgICpcbiAgICAgKiAqKk5vdGU6KiogVGhpcyBtZXRob2QgbXV0YXRlcyBgb2JqZWN0YC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjAuMFxuICAgICAqIEBhbGlhcyBleHRlbmRXaXRoXG4gICAgICogQGNhdGVnb3J5IE9iamVjdFxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIGRlc3RpbmF0aW9uIG9iamVjdC5cbiAgICAgKiBAcGFyYW0gey4uLk9iamVjdH0gc291cmNlcyBUaGUgc291cmNlIG9iamVjdHMuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW2N1c3RvbWl6ZXJdIFRoZSBmdW5jdGlvbiB0byBjdXN0b21pemUgYXNzaWduZWQgdmFsdWVzLlxuICAgICAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgYG9iamVjdGAuXG4gICAgICogQHNlZSBfLmFzc2lnbldpdGhcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogZnVuY3Rpb24gY3VzdG9taXplcihvYmpWYWx1ZSwgc3JjVmFsdWUpIHtcbiAgICAgKiAgIHJldHVybiBfLmlzVW5kZWZpbmVkKG9ialZhbHVlKSA/IHNyY1ZhbHVlIDogb2JqVmFsdWU7XG4gICAgICogfVxuICAgICAqXG4gICAgICogdmFyIGRlZmF1bHRzID0gXy5wYXJ0aWFsUmlnaHQoXy5hc3NpZ25JbldpdGgsIGN1c3RvbWl6ZXIpO1xuICAgICAqXG4gICAgICogZGVmYXVsdHMoeyAnYSc6IDEgfSwgeyAnYic6IDIgfSwgeyAnYSc6IDMgfSk7XG4gICAgICogLy8gPT4geyAnYSc6IDEsICdiJzogMiB9XG4gICAgICovXG4gICAgdmFyIGFzc2lnbkluV2l0aCA9IGNyZWF0ZUFzc2lnbmVyKGZ1bmN0aW9uKG9iamVjdCwgc291cmNlLCBzcmNJbmRleCwgY3VzdG9taXplcikge1xuICAgICAgY29weU9iamVjdChzb3VyY2UsIGtleXNJbihzb3VyY2UpLCBvYmplY3QsIGN1c3RvbWl6ZXIpO1xuICAgIH0pO1xuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgaXMgbGlrZSBgXy5hc3NpZ25gIGV4Y2VwdCB0aGF0IGl0IGFjY2VwdHMgYGN1c3RvbWl6ZXJgXG4gICAgICogd2hpY2ggaXMgaW52b2tlZCB0byBwcm9kdWNlIHRoZSBhc3NpZ25lZCB2YWx1ZXMuIElmIGBjdXN0b21pemVyYCByZXR1cm5zXG4gICAgICogYHVuZGVmaW5lZGAsIGFzc2lnbm1lbnQgaXMgaGFuZGxlZCBieSB0aGUgbWV0aG9kIGluc3RlYWQuIFRoZSBgY3VzdG9taXplcmBcbiAgICAgKiBpcyBpbnZva2VkIHdpdGggZml2ZSBhcmd1bWVudHM6IChvYmpWYWx1ZSwgc3JjVmFsdWUsIGtleSwgb2JqZWN0LCBzb3VyY2UpLlxuICAgICAqXG4gICAgICogKipOb3RlOioqIFRoaXMgbWV0aG9kIG11dGF0ZXMgYG9iamVjdGAuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgT2JqZWN0XG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgZGVzdGluYXRpb24gb2JqZWN0LlxuICAgICAqIEBwYXJhbSB7Li4uT2JqZWN0fSBzb3VyY2VzIFRoZSBzb3VyY2Ugb2JqZWN0cy5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbY3VzdG9taXplcl0gVGhlIGZ1bmN0aW9uIHRvIGN1c3RvbWl6ZSBhc3NpZ25lZCB2YWx1ZXMuXG4gICAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyBgb2JqZWN0YC5cbiAgICAgKiBAc2VlIF8uYXNzaWduSW5XaXRoXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIGZ1bmN0aW9uIGN1c3RvbWl6ZXIob2JqVmFsdWUsIHNyY1ZhbHVlKSB7XG4gICAgICogICByZXR1cm4gXy5pc1VuZGVmaW5lZChvYmpWYWx1ZSkgPyBzcmNWYWx1ZSA6IG9ialZhbHVlO1xuICAgICAqIH1cbiAgICAgKlxuICAgICAqIHZhciBkZWZhdWx0cyA9IF8ucGFydGlhbFJpZ2h0KF8uYXNzaWduV2l0aCwgY3VzdG9taXplcik7XG4gICAgICpcbiAgICAgKiBkZWZhdWx0cyh7ICdhJzogMSB9LCB7ICdiJzogMiB9LCB7ICdhJzogMyB9KTtcbiAgICAgKiAvLyA9PiB7ICdhJzogMSwgJ2InOiAyIH1cbiAgICAgKi9cbiAgICB2YXIgYXNzaWduV2l0aCA9IGNyZWF0ZUFzc2lnbmVyKGZ1bmN0aW9uKG9iamVjdCwgc291cmNlLCBzcmNJbmRleCwgY3VzdG9taXplcikge1xuICAgICAgY29weU9iamVjdChzb3VyY2UsIGtleXMoc291cmNlKSwgb2JqZWN0LCBjdXN0b21pemVyKTtcbiAgICB9KTtcblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYW4gYXJyYXkgb2YgdmFsdWVzIGNvcnJlc3BvbmRpbmcgdG8gYHBhdGhzYCBvZiBgb2JqZWN0YC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAxLjAuMFxuICAgICAqIEBjYXRlZ29yeSBPYmplY3RcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gaXRlcmF0ZSBvdmVyLlxuICAgICAqIEBwYXJhbSB7Li4uKHN0cmluZ3xzdHJpbmdbXSl9IFtwYXRoc10gVGhlIHByb3BlcnR5IHBhdGhzIHRvIHBpY2suXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBwaWNrZWQgdmFsdWVzLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgb2JqZWN0ID0geyAnYSc6IFt7ICdiJzogeyAnYyc6IDMgfSB9LCA0XSB9O1xuICAgICAqXG4gICAgICogXy5hdChvYmplY3QsIFsnYVswXS5iLmMnLCAnYVsxXSddKTtcbiAgICAgKiAvLyA9PiBbMywgNF1cbiAgICAgKi9cbiAgICB2YXIgYXQgPSBmbGF0UmVzdChiYXNlQXQpO1xuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhbiBvYmplY3QgdGhhdCBpbmhlcml0cyBmcm9tIHRoZSBgcHJvdG90eXBlYCBvYmplY3QuIElmIGFcbiAgICAgKiBgcHJvcGVydGllc2Agb2JqZWN0IGlzIGdpdmVuLCBpdHMgb3duIGVudW1lcmFibGUgc3RyaW5nIGtleWVkIHByb3BlcnRpZXNcbiAgICAgKiBhcmUgYXNzaWduZWQgdG8gdGhlIGNyZWF0ZWQgb2JqZWN0LlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDIuMy4wXG4gICAgICogQGNhdGVnb3J5IE9iamVjdFxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBwcm90b3R5cGUgVGhlIG9iamVjdCB0byBpbmhlcml0IGZyb20uXG4gICAgICogQHBhcmFtIHtPYmplY3R9IFtwcm9wZXJ0aWVzXSBUaGUgcHJvcGVydGllcyB0byBhc3NpZ24gdG8gdGhlIG9iamVjdC5cbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIHRoZSBuZXcgb2JqZWN0LlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBmdW5jdGlvbiBTaGFwZSgpIHtcbiAgICAgKiAgIHRoaXMueCA9IDA7XG4gICAgICogICB0aGlzLnkgPSAwO1xuICAgICAqIH1cbiAgICAgKlxuICAgICAqIGZ1bmN0aW9uIENpcmNsZSgpIHtcbiAgICAgKiAgIFNoYXBlLmNhbGwodGhpcyk7XG4gICAgICogfVxuICAgICAqXG4gICAgICogQ2lyY2xlLnByb3RvdHlwZSA9IF8uY3JlYXRlKFNoYXBlLnByb3RvdHlwZSwge1xuICAgICAqICAgJ2NvbnN0cnVjdG9yJzogQ2lyY2xlXG4gICAgICogfSk7XG4gICAgICpcbiAgICAgKiB2YXIgY2lyY2xlID0gbmV3IENpcmNsZTtcbiAgICAgKiBjaXJjbGUgaW5zdGFuY2VvZiBDaXJjbGU7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqXG4gICAgICogY2lyY2xlIGluc3RhbmNlb2YgU2hhcGU7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGNyZWF0ZShwcm90b3R5cGUsIHByb3BlcnRpZXMpIHtcbiAgICAgIHZhciByZXN1bHQgPSBiYXNlQ3JlYXRlKHByb3RvdHlwZSk7XG4gICAgICByZXR1cm4gcHJvcGVydGllcyA9PSBudWxsID8gcmVzdWx0IDogYmFzZUFzc2lnbihyZXN1bHQsIHByb3BlcnRpZXMpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEFzc2lnbnMgb3duIGFuZCBpbmhlcml0ZWQgZW51bWVyYWJsZSBzdHJpbmcga2V5ZWQgcHJvcGVydGllcyBvZiBzb3VyY2VcbiAgICAgKiBvYmplY3RzIHRvIHRoZSBkZXN0aW5hdGlvbiBvYmplY3QgZm9yIGFsbCBkZXN0aW5hdGlvbiBwcm9wZXJ0aWVzIHRoYXRcbiAgICAgKiByZXNvbHZlIHRvIGB1bmRlZmluZWRgLiBTb3VyY2Ugb2JqZWN0cyBhcmUgYXBwbGllZCBmcm9tIGxlZnQgdG8gcmlnaHQuXG4gICAgICogT25jZSBhIHByb3BlcnR5IGlzIHNldCwgYWRkaXRpb25hbCB2YWx1ZXMgb2YgdGhlIHNhbWUgcHJvcGVydHkgYXJlIGlnbm9yZWQuXG4gICAgICpcbiAgICAgKiAqKk5vdGU6KiogVGhpcyBtZXRob2QgbXV0YXRlcyBgb2JqZWN0YC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAc2luY2UgMC4xLjBcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBjYXRlZ29yeSBPYmplY3RcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBkZXN0aW5hdGlvbiBvYmplY3QuXG4gICAgICogQHBhcmFtIHsuLi5PYmplY3R9IFtzb3VyY2VzXSBUaGUgc291cmNlIG9iamVjdHMuXG4gICAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyBgb2JqZWN0YC5cbiAgICAgKiBAc2VlIF8uZGVmYXVsdHNEZWVwXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uZGVmYXVsdHMoeyAnYSc6IDEgfSwgeyAnYic6IDIgfSwgeyAnYSc6IDMgfSk7XG4gICAgICogLy8gPT4geyAnYSc6IDEsICdiJzogMiB9XG4gICAgICovXG4gICAgdmFyIGRlZmF1bHRzID0gYmFzZVJlc3QoZnVuY3Rpb24ob2JqZWN0LCBzb3VyY2VzKSB7XG4gICAgICBvYmplY3QgPSBPYmplY3Qob2JqZWN0KTtcblxuICAgICAgdmFyIGluZGV4ID0gLTE7XG4gICAgICB2YXIgbGVuZ3RoID0gc291cmNlcy5sZW5ndGg7XG4gICAgICB2YXIgZ3VhcmQgPSBsZW5ndGggPiAyID8gc291cmNlc1syXSA6IHVuZGVmaW5lZDtcblxuICAgICAgaWYgKGd1YXJkICYmIGlzSXRlcmF0ZWVDYWxsKHNvdXJjZXNbMF0sIHNvdXJjZXNbMV0sIGd1YXJkKSkge1xuICAgICAgICBsZW5ndGggPSAxO1xuICAgICAgfVxuXG4gICAgICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgICAgICB2YXIgc291cmNlID0gc291cmNlc1tpbmRleF07XG4gICAgICAgIHZhciBwcm9wcyA9IGtleXNJbihzb3VyY2UpO1xuICAgICAgICB2YXIgcHJvcHNJbmRleCA9IC0xO1xuICAgICAgICB2YXIgcHJvcHNMZW5ndGggPSBwcm9wcy5sZW5ndGg7XG5cbiAgICAgICAgd2hpbGUgKCsrcHJvcHNJbmRleCA8IHByb3BzTGVuZ3RoKSB7XG4gICAgICAgICAgdmFyIGtleSA9IHByb3BzW3Byb3BzSW5kZXhdO1xuICAgICAgICAgIHZhciB2YWx1ZSA9IG9iamVjdFtrZXldO1xuXG4gICAgICAgICAgaWYgKHZhbHVlID09PSB1bmRlZmluZWQgfHxcbiAgICAgICAgICAgICAgKGVxKHZhbHVlLCBvYmplY3RQcm90b1trZXldKSAmJiAhaGFzT3duUHJvcGVydHkuY2FsbChvYmplY3QsIGtleSkpKSB7XG4gICAgICAgICAgICBvYmplY3Rba2V5XSA9IHNvdXJjZVtrZXldO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICByZXR1cm4gb2JqZWN0O1xuICAgIH0pO1xuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgaXMgbGlrZSBgXy5kZWZhdWx0c2AgZXhjZXB0IHRoYXQgaXQgcmVjdXJzaXZlbHkgYXNzaWduc1xuICAgICAqIGRlZmF1bHQgcHJvcGVydGllcy5cbiAgICAgKlxuICAgICAqICoqTm90ZToqKiBUaGlzIG1ldGhvZCBtdXRhdGVzIGBvYmplY3RgLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDMuMTAuMFxuICAgICAqIEBjYXRlZ29yeSBPYmplY3RcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBkZXN0aW5hdGlvbiBvYmplY3QuXG4gICAgICogQHBhcmFtIHsuLi5PYmplY3R9IFtzb3VyY2VzXSBUaGUgc291cmNlIG9iamVjdHMuXG4gICAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyBgb2JqZWN0YC5cbiAgICAgKiBAc2VlIF8uZGVmYXVsdHNcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5kZWZhdWx0c0RlZXAoeyAnYSc6IHsgJ2InOiAyIH0gfSwgeyAnYSc6IHsgJ2InOiAxLCAnYyc6IDMgfSB9KTtcbiAgICAgKiAvLyA9PiB7ICdhJzogeyAnYic6IDIsICdjJzogMyB9IH1cbiAgICAgKi9cbiAgICB2YXIgZGVmYXVsdHNEZWVwID0gYmFzZVJlc3QoZnVuY3Rpb24oYXJncykge1xuICAgICAgYXJncy5wdXNoKHVuZGVmaW5lZCwgY3VzdG9tRGVmYXVsdHNNZXJnZSk7XG4gICAgICByZXR1cm4gYXBwbHkobWVyZ2VXaXRoLCB1bmRlZmluZWQsIGFyZ3MpO1xuICAgIH0pO1xuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgaXMgbGlrZSBgXy5maW5kYCBleGNlcHQgdGhhdCBpdCByZXR1cm5zIHRoZSBrZXkgb2YgdGhlIGZpcnN0XG4gICAgICogZWxlbWVudCBgcHJlZGljYXRlYCByZXR1cm5zIHRydXRoeSBmb3IgaW5zdGVhZCBvZiB0aGUgZWxlbWVudCBpdHNlbGYuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMS4xLjBcbiAgICAgKiBAY2F0ZWdvcnkgT2JqZWN0XG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIGluc3BlY3QuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW3ByZWRpY2F0ZT1fLmlkZW50aXR5XSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd8dW5kZWZpbmVkfSBSZXR1cm5zIHRoZSBrZXkgb2YgdGhlIG1hdGNoZWQgZWxlbWVudCxcbiAgICAgKiAgZWxzZSBgdW5kZWZpbmVkYC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIHVzZXJzID0ge1xuICAgICAqICAgJ2Jhcm5leSc6ICB7ICdhZ2UnOiAzNiwgJ2FjdGl2ZSc6IHRydWUgfSxcbiAgICAgKiAgICdmcmVkJzogICAgeyAnYWdlJzogNDAsICdhY3RpdmUnOiBmYWxzZSB9LFxuICAgICAqICAgJ3BlYmJsZXMnOiB7ICdhZ2UnOiAxLCAgJ2FjdGl2ZSc6IHRydWUgfVxuICAgICAqIH07XG4gICAgICpcbiAgICAgKiBfLmZpbmRLZXkodXNlcnMsIGZ1bmN0aW9uKG8pIHsgcmV0dXJuIG8uYWdlIDwgNDA7IH0pO1xuICAgICAqIC8vID0+ICdiYXJuZXknIChpdGVyYXRpb24gb3JkZXIgaXMgbm90IGd1YXJhbnRlZWQpXG4gICAgICpcbiAgICAgKiAvLyBUaGUgYF8ubWF0Y2hlc2AgaXRlcmF0ZWUgc2hvcnRoYW5kLlxuICAgICAqIF8uZmluZEtleSh1c2VycywgeyAnYWdlJzogMSwgJ2FjdGl2ZSc6IHRydWUgfSk7XG4gICAgICogLy8gPT4gJ3BlYmJsZXMnXG4gICAgICpcbiAgICAgKiAvLyBUaGUgYF8ubWF0Y2hlc1Byb3BlcnR5YCBpdGVyYXRlZSBzaG9ydGhhbmQuXG4gICAgICogXy5maW5kS2V5KHVzZXJzLCBbJ2FjdGl2ZScsIGZhbHNlXSk7XG4gICAgICogLy8gPT4gJ2ZyZWQnXG4gICAgICpcbiAgICAgKiAvLyBUaGUgYF8ucHJvcGVydHlgIGl0ZXJhdGVlIHNob3J0aGFuZC5cbiAgICAgKiBfLmZpbmRLZXkodXNlcnMsICdhY3RpdmUnKTtcbiAgICAgKiAvLyA9PiAnYmFybmV5J1xuICAgICAqL1xuICAgIGZ1bmN0aW9uIGZpbmRLZXkob2JqZWN0LCBwcmVkaWNhdGUpIHtcbiAgICAgIHJldHVybiBiYXNlRmluZEtleShvYmplY3QsIGdldEl0ZXJhdGVlKHByZWRpY2F0ZSwgMyksIGJhc2VGb3JPd24pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIGlzIGxpa2UgYF8uZmluZEtleWAgZXhjZXB0IHRoYXQgaXQgaXRlcmF0ZXMgb3ZlciBlbGVtZW50cyBvZlxuICAgICAqIGEgY29sbGVjdGlvbiBpbiB0aGUgb3Bwb3NpdGUgb3JkZXIuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMi4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgT2JqZWN0XG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIGluc3BlY3QuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW3ByZWRpY2F0ZT1fLmlkZW50aXR5XSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd8dW5kZWZpbmVkfSBSZXR1cm5zIHRoZSBrZXkgb2YgdGhlIG1hdGNoZWQgZWxlbWVudCxcbiAgICAgKiAgZWxzZSBgdW5kZWZpbmVkYC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIHVzZXJzID0ge1xuICAgICAqICAgJ2Jhcm5leSc6ICB7ICdhZ2UnOiAzNiwgJ2FjdGl2ZSc6IHRydWUgfSxcbiAgICAgKiAgICdmcmVkJzogICAgeyAnYWdlJzogNDAsICdhY3RpdmUnOiBmYWxzZSB9LFxuICAgICAqICAgJ3BlYmJsZXMnOiB7ICdhZ2UnOiAxLCAgJ2FjdGl2ZSc6IHRydWUgfVxuICAgICAqIH07XG4gICAgICpcbiAgICAgKiBfLmZpbmRMYXN0S2V5KHVzZXJzLCBmdW5jdGlvbihvKSB7IHJldHVybiBvLmFnZSA8IDQwOyB9KTtcbiAgICAgKiAvLyA9PiByZXR1cm5zICdwZWJibGVzJyBhc3N1bWluZyBgXy5maW5kS2V5YCByZXR1cm5zICdiYXJuZXknXG4gICAgICpcbiAgICAgKiAvLyBUaGUgYF8ubWF0Y2hlc2AgaXRlcmF0ZWUgc2hvcnRoYW5kLlxuICAgICAqIF8uZmluZExhc3RLZXkodXNlcnMsIHsgJ2FnZSc6IDM2LCAnYWN0aXZlJzogdHJ1ZSB9KTtcbiAgICAgKiAvLyA9PiAnYmFybmV5J1xuICAgICAqXG4gICAgICogLy8gVGhlIGBfLm1hdGNoZXNQcm9wZXJ0eWAgaXRlcmF0ZWUgc2hvcnRoYW5kLlxuICAgICAqIF8uZmluZExhc3RLZXkodXNlcnMsIFsnYWN0aXZlJywgZmFsc2VdKTtcbiAgICAgKiAvLyA9PiAnZnJlZCdcbiAgICAgKlxuICAgICAqIC8vIFRoZSBgXy5wcm9wZXJ0eWAgaXRlcmF0ZWUgc2hvcnRoYW5kLlxuICAgICAqIF8uZmluZExhc3RLZXkodXNlcnMsICdhY3RpdmUnKTtcbiAgICAgKiAvLyA9PiAncGViYmxlcydcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBmaW5kTGFzdEtleShvYmplY3QsIHByZWRpY2F0ZSkge1xuICAgICAgcmV0dXJuIGJhc2VGaW5kS2V5KG9iamVjdCwgZ2V0SXRlcmF0ZWUocHJlZGljYXRlLCAzKSwgYmFzZUZvck93blJpZ2h0KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBJdGVyYXRlcyBvdmVyIG93biBhbmQgaW5oZXJpdGVkIGVudW1lcmFibGUgc3RyaW5nIGtleWVkIHByb3BlcnRpZXMgb2YgYW5cbiAgICAgKiBvYmplY3QgYW5kIGludm9rZXMgYGl0ZXJhdGVlYCBmb3IgZWFjaCBwcm9wZXJ0eS4gVGhlIGl0ZXJhdGVlIGlzIGludm9rZWRcbiAgICAgKiB3aXRoIHRocmVlIGFyZ3VtZW50czogKHZhbHVlLCBrZXksIG9iamVjdCkuIEl0ZXJhdGVlIGZ1bmN0aW9ucyBtYXkgZXhpdFxuICAgICAqIGl0ZXJhdGlvbiBlYXJseSBieSBleHBsaWNpdGx5IHJldHVybmluZyBgZmFsc2VgLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDAuMy4wXG4gICAgICogQGNhdGVnb3J5IE9iamVjdFxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBpdGVyYXRlIG92ZXIuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW2l0ZXJhdGVlPV8uaWRlbnRpdHldIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uXG4gICAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyBgb2JqZWN0YC5cbiAgICAgKiBAc2VlIF8uZm9ySW5SaWdodFxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBmdW5jdGlvbiBGb28oKSB7XG4gICAgICogICB0aGlzLmEgPSAxO1xuICAgICAqICAgdGhpcy5iID0gMjtcbiAgICAgKiB9XG4gICAgICpcbiAgICAgKiBGb28ucHJvdG90eXBlLmMgPSAzO1xuICAgICAqXG4gICAgICogXy5mb3JJbihuZXcgRm9vLCBmdW5jdGlvbih2YWx1ZSwga2V5KSB7XG4gICAgICogICBjb25zb2xlLmxvZyhrZXkpO1xuICAgICAqIH0pO1xuICAgICAqIC8vID0+IExvZ3MgJ2EnLCAnYicsIHRoZW4gJ2MnIChpdGVyYXRpb24gb3JkZXIgaXMgbm90IGd1YXJhbnRlZWQpLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGZvckluKG9iamVjdCwgaXRlcmF0ZWUpIHtcbiAgICAgIHJldHVybiBvYmplY3QgPT0gbnVsbFxuICAgICAgICA/IG9iamVjdFxuICAgICAgICA6IGJhc2VGb3Iob2JqZWN0LCBnZXRJdGVyYXRlZShpdGVyYXRlZSwgMyksIGtleXNJbik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgaXMgbGlrZSBgXy5mb3JJbmAgZXhjZXB0IHRoYXQgaXQgaXRlcmF0ZXMgb3ZlciBwcm9wZXJ0aWVzIG9mXG4gICAgICogYG9iamVjdGAgaW4gdGhlIG9wcG9zaXRlIG9yZGVyLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDIuMC4wXG4gICAgICogQGNhdGVnb3J5IE9iamVjdFxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBpdGVyYXRlIG92ZXIuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW2l0ZXJhdGVlPV8uaWRlbnRpdHldIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uXG4gICAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyBgb2JqZWN0YC5cbiAgICAgKiBAc2VlIF8uZm9ySW5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogZnVuY3Rpb24gRm9vKCkge1xuICAgICAqICAgdGhpcy5hID0gMTtcbiAgICAgKiAgIHRoaXMuYiA9IDI7XG4gICAgICogfVxuICAgICAqXG4gICAgICogRm9vLnByb3RvdHlwZS5jID0gMztcbiAgICAgKlxuICAgICAqIF8uZm9ySW5SaWdodChuZXcgRm9vLCBmdW5jdGlvbih2YWx1ZSwga2V5KSB7XG4gICAgICogICBjb25zb2xlLmxvZyhrZXkpO1xuICAgICAqIH0pO1xuICAgICAqIC8vID0+IExvZ3MgJ2MnLCAnYicsIHRoZW4gJ2EnIGFzc3VtaW5nIGBfLmZvckluYCBsb2dzICdhJywgJ2InLCB0aGVuICdjJy5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBmb3JJblJpZ2h0KG9iamVjdCwgaXRlcmF0ZWUpIHtcbiAgICAgIHJldHVybiBvYmplY3QgPT0gbnVsbFxuICAgICAgICA/IG9iamVjdFxuICAgICAgICA6IGJhc2VGb3JSaWdodChvYmplY3QsIGdldEl0ZXJhdGVlKGl0ZXJhdGVlLCAzKSwga2V5c0luKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBJdGVyYXRlcyBvdmVyIG93biBlbnVtZXJhYmxlIHN0cmluZyBrZXllZCBwcm9wZXJ0aWVzIG9mIGFuIG9iamVjdCBhbmRcbiAgICAgKiBpbnZva2VzIGBpdGVyYXRlZWAgZm9yIGVhY2ggcHJvcGVydHkuIFRoZSBpdGVyYXRlZSBpcyBpbnZva2VkIHdpdGggdGhyZWVcbiAgICAgKiBhcmd1bWVudHM6ICh2YWx1ZSwga2V5LCBvYmplY3QpLiBJdGVyYXRlZSBmdW5jdGlvbnMgbWF5IGV4aXQgaXRlcmF0aW9uXG4gICAgICogZWFybHkgYnkgZXhwbGljaXRseSByZXR1cm5pbmcgYGZhbHNlYC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAwLjMuMFxuICAgICAqIEBjYXRlZ29yeSBPYmplY3RcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gaXRlcmF0ZSBvdmVyLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IFtpdGVyYXRlZT1fLmlkZW50aXR5XSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICAgICAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgYG9iamVjdGAuXG4gICAgICogQHNlZSBfLmZvck93blJpZ2h0XG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIGZ1bmN0aW9uIEZvbygpIHtcbiAgICAgKiAgIHRoaXMuYSA9IDE7XG4gICAgICogICB0aGlzLmIgPSAyO1xuICAgICAqIH1cbiAgICAgKlxuICAgICAqIEZvby5wcm90b3R5cGUuYyA9IDM7XG4gICAgICpcbiAgICAgKiBfLmZvck93bihuZXcgRm9vLCBmdW5jdGlvbih2YWx1ZSwga2V5KSB7XG4gICAgICogICBjb25zb2xlLmxvZyhrZXkpO1xuICAgICAqIH0pO1xuICAgICAqIC8vID0+IExvZ3MgJ2EnIHRoZW4gJ2InIChpdGVyYXRpb24gb3JkZXIgaXMgbm90IGd1YXJhbnRlZWQpLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGZvck93bihvYmplY3QsIGl0ZXJhdGVlKSB7XG4gICAgICByZXR1cm4gb2JqZWN0ICYmIGJhc2VGb3JPd24ob2JqZWN0LCBnZXRJdGVyYXRlZShpdGVyYXRlZSwgMykpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIGlzIGxpa2UgYF8uZm9yT3duYCBleGNlcHQgdGhhdCBpdCBpdGVyYXRlcyBvdmVyIHByb3BlcnRpZXMgb2ZcbiAgICAgKiBgb2JqZWN0YCBpbiB0aGUgb3Bwb3NpdGUgb3JkZXIuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMi4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgT2JqZWN0XG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIGl0ZXJhdGUgb3Zlci5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbaXRlcmF0ZWU9Xy5pZGVudGl0eV0gVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIGl0ZXJhdGlvbi5cbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIGBvYmplY3RgLlxuICAgICAqIEBzZWUgXy5mb3JPd25cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogZnVuY3Rpb24gRm9vKCkge1xuICAgICAqICAgdGhpcy5hID0gMTtcbiAgICAgKiAgIHRoaXMuYiA9IDI7XG4gICAgICogfVxuICAgICAqXG4gICAgICogRm9vLnByb3RvdHlwZS5jID0gMztcbiAgICAgKlxuICAgICAqIF8uZm9yT3duUmlnaHQobmV3IEZvbywgZnVuY3Rpb24odmFsdWUsIGtleSkge1xuICAgICAqICAgY29uc29sZS5sb2coa2V5KTtcbiAgICAgKiB9KTtcbiAgICAgKiAvLyA9PiBMb2dzICdiJyB0aGVuICdhJyBhc3N1bWluZyBgXy5mb3JPd25gIGxvZ3MgJ2EnIHRoZW4gJ2InLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGZvck93blJpZ2h0KG9iamVjdCwgaXRlcmF0ZWUpIHtcbiAgICAgIHJldHVybiBvYmplY3QgJiYgYmFzZUZvck93blJpZ2h0KG9iamVjdCwgZ2V0SXRlcmF0ZWUoaXRlcmF0ZWUsIDMpKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGFuIGFycmF5IG9mIGZ1bmN0aW9uIHByb3BlcnR5IG5hbWVzIGZyb20gb3duIGVudW1lcmFibGUgcHJvcGVydGllc1xuICAgICAqIG9mIGBvYmplY3RgLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBzaW5jZSAwLjEuMFxuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQGNhdGVnb3J5IE9iamVjdFxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBpbnNwZWN0LlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgZnVuY3Rpb24gbmFtZXMuXG4gICAgICogQHNlZSBfLmZ1bmN0aW9uc0luXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIGZ1bmN0aW9uIEZvbygpIHtcbiAgICAgKiAgIHRoaXMuYSA9IF8uY29uc3RhbnQoJ2EnKTtcbiAgICAgKiAgIHRoaXMuYiA9IF8uY29uc3RhbnQoJ2InKTtcbiAgICAgKiB9XG4gICAgICpcbiAgICAgKiBGb28ucHJvdG90eXBlLmMgPSBfLmNvbnN0YW50KCdjJyk7XG4gICAgICpcbiAgICAgKiBfLmZ1bmN0aW9ucyhuZXcgRm9vKTtcbiAgICAgKiAvLyA9PiBbJ2EnLCAnYiddXG4gICAgICovXG4gICAgZnVuY3Rpb24gZnVuY3Rpb25zKG9iamVjdCkge1xuICAgICAgcmV0dXJuIG9iamVjdCA9PSBudWxsID8gW10gOiBiYXNlRnVuY3Rpb25zKG9iamVjdCwga2V5cyhvYmplY3QpKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGFuIGFycmF5IG9mIGZ1bmN0aW9uIHByb3BlcnR5IG5hbWVzIGZyb20gb3duIGFuZCBpbmhlcml0ZWRcbiAgICAgKiBlbnVtZXJhYmxlIHByb3BlcnRpZXMgb2YgYG9iamVjdGAuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgT2JqZWN0XG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIGluc3BlY3QuXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBmdW5jdGlvbiBuYW1lcy5cbiAgICAgKiBAc2VlIF8uZnVuY3Rpb25zXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIGZ1bmN0aW9uIEZvbygpIHtcbiAgICAgKiAgIHRoaXMuYSA9IF8uY29uc3RhbnQoJ2EnKTtcbiAgICAgKiAgIHRoaXMuYiA9IF8uY29uc3RhbnQoJ2InKTtcbiAgICAgKiB9XG4gICAgICpcbiAgICAgKiBGb28ucHJvdG90eXBlLmMgPSBfLmNvbnN0YW50KCdjJyk7XG4gICAgICpcbiAgICAgKiBfLmZ1bmN0aW9uc0luKG5ldyBGb28pO1xuICAgICAqIC8vID0+IFsnYScsICdiJywgJ2MnXVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGZ1bmN0aW9uc0luKG9iamVjdCkge1xuICAgICAgcmV0dXJuIG9iamVjdCA9PSBudWxsID8gW10gOiBiYXNlRnVuY3Rpb25zKG9iamVjdCwga2V5c0luKG9iamVjdCkpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldHMgdGhlIHZhbHVlIGF0IGBwYXRoYCBvZiBgb2JqZWN0YC4gSWYgdGhlIHJlc29sdmVkIHZhbHVlIGlzXG4gICAgICogYHVuZGVmaW5lZGAsIHRoZSBgZGVmYXVsdFZhbHVlYCBpcyByZXR1cm5lZCBpbiBpdHMgcGxhY2UuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMy43LjBcbiAgICAgKiBAY2F0ZWdvcnkgT2JqZWN0XG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIHF1ZXJ5LlxuICAgICAqIEBwYXJhbSB7QXJyYXl8c3RyaW5nfSBwYXRoIFRoZSBwYXRoIG9mIHRoZSBwcm9wZXJ0eSB0byBnZXQuXG4gICAgICogQHBhcmFtIHsqfSBbZGVmYXVsdFZhbHVlXSBUaGUgdmFsdWUgcmV0dXJuZWQgZm9yIGB1bmRlZmluZWRgIHJlc29sdmVkIHZhbHVlcy5cbiAgICAgKiBAcmV0dXJucyB7Kn0gUmV0dXJucyB0aGUgcmVzb2x2ZWQgdmFsdWUuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciBvYmplY3QgPSB7ICdhJzogW3sgJ2InOiB7ICdjJzogMyB9IH1dIH07XG4gICAgICpcbiAgICAgKiBfLmdldChvYmplY3QsICdhWzBdLmIuYycpO1xuICAgICAqIC8vID0+IDNcbiAgICAgKlxuICAgICAqIF8uZ2V0KG9iamVjdCwgWydhJywgJzAnLCAnYicsICdjJ10pO1xuICAgICAqIC8vID0+IDNcbiAgICAgKlxuICAgICAqIF8uZ2V0KG9iamVjdCwgJ2EuYi5jJywgJ2RlZmF1bHQnKTtcbiAgICAgKiAvLyA9PiAnZGVmYXVsdCdcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBnZXQob2JqZWN0LCBwYXRoLCBkZWZhdWx0VmFsdWUpIHtcbiAgICAgIHZhciByZXN1bHQgPSBvYmplY3QgPT0gbnVsbCA/IHVuZGVmaW5lZCA6IGJhc2VHZXQob2JqZWN0LCBwYXRoKTtcbiAgICAgIHJldHVybiByZXN1bHQgPT09IHVuZGVmaW5lZCA/IGRlZmF1bHRWYWx1ZSA6IHJlc3VsdDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDaGVja3MgaWYgYHBhdGhgIGlzIGEgZGlyZWN0IHByb3BlcnR5IG9mIGBvYmplY3RgLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBzaW5jZSAwLjEuMFxuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQGNhdGVnb3J5IE9iamVjdFxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBxdWVyeS5cbiAgICAgKiBAcGFyYW0ge0FycmF5fHN0cmluZ30gcGF0aCBUaGUgcGF0aCB0byBjaGVjay5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHBhdGhgIGV4aXN0cywgZWxzZSBgZmFsc2VgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgb2JqZWN0ID0geyAnYSc6IHsgJ2InOiAyIH0gfTtcbiAgICAgKiB2YXIgb3RoZXIgPSBfLmNyZWF0ZSh7ICdhJzogXy5jcmVhdGUoeyAnYic6IDIgfSkgfSk7XG4gICAgICpcbiAgICAgKiBfLmhhcyhvYmplY3QsICdhJyk7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqXG4gICAgICogXy5oYXMob2JqZWN0LCAnYS5iJyk7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqXG4gICAgICogXy5oYXMob2JqZWN0LCBbJ2EnLCAnYiddKTtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICpcbiAgICAgKiBfLmhhcyhvdGhlciwgJ2EnKTtcbiAgICAgKiAvLyA9PiBmYWxzZVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGhhcyhvYmplY3QsIHBhdGgpIHtcbiAgICAgIHJldHVybiBvYmplY3QgIT0gbnVsbCAmJiBoYXNQYXRoKG9iamVjdCwgcGF0aCwgYmFzZUhhcyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2hlY2tzIGlmIGBwYXRoYCBpcyBhIGRpcmVjdCBvciBpbmhlcml0ZWQgcHJvcGVydHkgb2YgYG9iamVjdGAuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgT2JqZWN0XG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIHF1ZXJ5LlxuICAgICAqIEBwYXJhbSB7QXJyYXl8c3RyaW5nfSBwYXRoIFRoZSBwYXRoIHRvIGNoZWNrLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgcGF0aGAgZXhpc3RzLCBlbHNlIGBmYWxzZWAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciBvYmplY3QgPSBfLmNyZWF0ZSh7ICdhJzogXy5jcmVhdGUoeyAnYic6IDIgfSkgfSk7XG4gICAgICpcbiAgICAgKiBfLmhhc0luKG9iamVjdCwgJ2EnKTtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICpcbiAgICAgKiBfLmhhc0luKG9iamVjdCwgJ2EuYicpO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKlxuICAgICAqIF8uaGFzSW4ob2JqZWN0LCBbJ2EnLCAnYiddKTtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICpcbiAgICAgKiBfLmhhc0luKG9iamVjdCwgJ2InKTtcbiAgICAgKiAvLyA9PiBmYWxzZVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGhhc0luKG9iamVjdCwgcGF0aCkge1xuICAgICAgcmV0dXJuIG9iamVjdCAhPSBudWxsICYmIGhhc1BhdGgob2JqZWN0LCBwYXRoLCBiYXNlSGFzSW4pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYW4gb2JqZWN0IGNvbXBvc2VkIG9mIHRoZSBpbnZlcnRlZCBrZXlzIGFuZCB2YWx1ZXMgb2YgYG9iamVjdGAuXG4gICAgICogSWYgYG9iamVjdGAgY29udGFpbnMgZHVwbGljYXRlIHZhbHVlcywgc3Vic2VxdWVudCB2YWx1ZXMgb3ZlcndyaXRlXG4gICAgICogcHJvcGVydHkgYXNzaWdubWVudHMgb2YgcHJldmlvdXMgdmFsdWVzLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDAuNy4wXG4gICAgICogQGNhdGVnb3J5IE9iamVjdFxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBpbnZlcnQuXG4gICAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyB0aGUgbmV3IGludmVydGVkIG9iamVjdC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIG9iamVjdCA9IHsgJ2EnOiAxLCAnYic6IDIsICdjJzogMSB9O1xuICAgICAqXG4gICAgICogXy5pbnZlcnQob2JqZWN0KTtcbiAgICAgKiAvLyA9PiB7ICcxJzogJ2MnLCAnMic6ICdiJyB9XG4gICAgICovXG4gICAgdmFyIGludmVydCA9IGNyZWF0ZUludmVydGVyKGZ1bmN0aW9uKHJlc3VsdCwgdmFsdWUsIGtleSkge1xuICAgICAgaWYgKHZhbHVlICE9IG51bGwgJiZcbiAgICAgICAgICB0eXBlb2YgdmFsdWUudG9TdHJpbmcgIT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICB2YWx1ZSA9IG5hdGl2ZU9iamVjdFRvU3RyaW5nLmNhbGwodmFsdWUpO1xuICAgICAgfVxuXG4gICAgICByZXN1bHRbdmFsdWVdID0ga2V5O1xuICAgIH0sIGNvbnN0YW50KGlkZW50aXR5KSk7XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIG1ldGhvZCBpcyBsaWtlIGBfLmludmVydGAgZXhjZXB0IHRoYXQgdGhlIGludmVydGVkIG9iamVjdCBpcyBnZW5lcmF0ZWRcbiAgICAgKiBmcm9tIHRoZSByZXN1bHRzIG9mIHJ1bm5pbmcgZWFjaCBlbGVtZW50IG9mIGBvYmplY3RgIHRocnUgYGl0ZXJhdGVlYC4gVGhlXG4gICAgICogY29ycmVzcG9uZGluZyBpbnZlcnRlZCB2YWx1ZSBvZiBlYWNoIGludmVydGVkIGtleSBpcyBhbiBhcnJheSBvZiBrZXlzXG4gICAgICogcmVzcG9uc2libGUgZm9yIGdlbmVyYXRpbmcgdGhlIGludmVydGVkIHZhbHVlLiBUaGUgaXRlcmF0ZWUgaXMgaW52b2tlZFxuICAgICAqIHdpdGggb25lIGFyZ3VtZW50OiAodmFsdWUpLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMS4wXG4gICAgICogQGNhdGVnb3J5IE9iamVjdFxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBpbnZlcnQuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW2l0ZXJhdGVlPV8uaWRlbnRpdHldIFRoZSBpdGVyYXRlZSBpbnZva2VkIHBlciBlbGVtZW50LlxuICAgICAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgdGhlIG5ldyBpbnZlcnRlZCBvYmplY3QuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciBvYmplY3QgPSB7ICdhJzogMSwgJ2InOiAyLCAnYyc6IDEgfTtcbiAgICAgKlxuICAgICAqIF8uaW52ZXJ0Qnkob2JqZWN0KTtcbiAgICAgKiAvLyA9PiB7ICcxJzogWydhJywgJ2MnXSwgJzInOiBbJ2InXSB9XG4gICAgICpcbiAgICAgKiBfLmludmVydEJ5KG9iamVjdCwgZnVuY3Rpb24odmFsdWUpIHtcbiAgICAgKiAgIHJldHVybiAnZ3JvdXAnICsgdmFsdWU7XG4gICAgICogfSk7XG4gICAgICogLy8gPT4geyAnZ3JvdXAxJzogWydhJywgJ2MnXSwgJ2dyb3VwMic6IFsnYiddIH1cbiAgICAgKi9cbiAgICB2YXIgaW52ZXJ0QnkgPSBjcmVhdGVJbnZlcnRlcihmdW5jdGlvbihyZXN1bHQsIHZhbHVlLCBrZXkpIHtcbiAgICAgIGlmICh2YWx1ZSAhPSBudWxsICYmXG4gICAgICAgICAgdHlwZW9mIHZhbHVlLnRvU3RyaW5nICE9ICdmdW5jdGlvbicpIHtcbiAgICAgICAgdmFsdWUgPSBuYXRpdmVPYmplY3RUb1N0cmluZy5jYWxsKHZhbHVlKTtcbiAgICAgIH1cblxuICAgICAgaWYgKGhhc093blByb3BlcnR5LmNhbGwocmVzdWx0LCB2YWx1ZSkpIHtcbiAgICAgICAgcmVzdWx0W3ZhbHVlXS5wdXNoKGtleSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXN1bHRbdmFsdWVdID0gW2tleV07XG4gICAgICB9XG4gICAgfSwgZ2V0SXRlcmF0ZWUpO1xuXG4gICAgLyoqXG4gICAgICogSW52b2tlcyB0aGUgbWV0aG9kIGF0IGBwYXRoYCBvZiBgb2JqZWN0YC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjAuMFxuICAgICAqIEBjYXRlZ29yeSBPYmplY3RcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gcXVlcnkuXG4gICAgICogQHBhcmFtIHtBcnJheXxzdHJpbmd9IHBhdGggVGhlIHBhdGggb2YgdGhlIG1ldGhvZCB0byBpbnZva2UuXG4gICAgICogQHBhcmFtIHsuLi4qfSBbYXJnc10gVGhlIGFyZ3VtZW50cyB0byBpbnZva2UgdGhlIG1ldGhvZCB3aXRoLlxuICAgICAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSByZXN1bHQgb2YgdGhlIGludm9rZWQgbWV0aG9kLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgb2JqZWN0ID0geyAnYSc6IFt7ICdiJzogeyAnYyc6IFsxLCAyLCAzLCA0XSB9IH1dIH07XG4gICAgICpcbiAgICAgKiBfLmludm9rZShvYmplY3QsICdhWzBdLmIuYy5zbGljZScsIDEsIDMpO1xuICAgICAqIC8vID0+IFsyLCAzXVxuICAgICAqL1xuICAgIHZhciBpbnZva2UgPSBiYXNlUmVzdChiYXNlSW52b2tlKTtcblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYW4gYXJyYXkgb2YgdGhlIG93biBlbnVtZXJhYmxlIHByb3BlcnR5IG5hbWVzIG9mIGBvYmplY3RgLlxuICAgICAqXG4gICAgICogKipOb3RlOioqIE5vbi1vYmplY3QgdmFsdWVzIGFyZSBjb2VyY2VkIHRvIG9iamVjdHMuIFNlZSB0aGVcbiAgICAgKiBbRVMgc3BlY10oaHR0cDovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNy4wLyNzZWMtb2JqZWN0LmtleXMpXG4gICAgICogZm9yIG1vcmUgZGV0YWlscy5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAc2luY2UgMC4xLjBcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBjYXRlZ29yeSBPYmplY3RcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gcXVlcnkuXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBhcnJheSBvZiBwcm9wZXJ0eSBuYW1lcy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogZnVuY3Rpb24gRm9vKCkge1xuICAgICAqICAgdGhpcy5hID0gMTtcbiAgICAgKiAgIHRoaXMuYiA9IDI7XG4gICAgICogfVxuICAgICAqXG4gICAgICogRm9vLnByb3RvdHlwZS5jID0gMztcbiAgICAgKlxuICAgICAqIF8ua2V5cyhuZXcgRm9vKTtcbiAgICAgKiAvLyA9PiBbJ2EnLCAnYiddIChpdGVyYXRpb24gb3JkZXIgaXMgbm90IGd1YXJhbnRlZWQpXG4gICAgICpcbiAgICAgKiBfLmtleXMoJ2hpJyk7XG4gICAgICogLy8gPT4gWycwJywgJzEnXVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGtleXMob2JqZWN0KSB7XG4gICAgICByZXR1cm4gaXNBcnJheUxpa2Uob2JqZWN0KSA/IGFycmF5TGlrZUtleXMob2JqZWN0KSA6IGJhc2VLZXlzKG9iamVjdCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhbiBhcnJheSBvZiB0aGUgb3duIGFuZCBpbmhlcml0ZWQgZW51bWVyYWJsZSBwcm9wZXJ0eSBuYW1lcyBvZiBgb2JqZWN0YC5cbiAgICAgKlxuICAgICAqICoqTm90ZToqKiBOb24tb2JqZWN0IHZhbHVlcyBhcmUgY29lcmNlZCB0byBvYmplY3RzLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDMuMC4wXG4gICAgICogQGNhdGVnb3J5IE9iamVjdFxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBxdWVyeS5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIGFycmF5IG9mIHByb3BlcnR5IG5hbWVzLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBmdW5jdGlvbiBGb28oKSB7XG4gICAgICogICB0aGlzLmEgPSAxO1xuICAgICAqICAgdGhpcy5iID0gMjtcbiAgICAgKiB9XG4gICAgICpcbiAgICAgKiBGb28ucHJvdG90eXBlLmMgPSAzO1xuICAgICAqXG4gICAgICogXy5rZXlzSW4obmV3IEZvbyk7XG4gICAgICogLy8gPT4gWydhJywgJ2InLCAnYyddIChpdGVyYXRpb24gb3JkZXIgaXMgbm90IGd1YXJhbnRlZWQpXG4gICAgICovXG4gICAgZnVuY3Rpb24ga2V5c0luKG9iamVjdCkge1xuICAgICAgcmV0dXJuIGlzQXJyYXlMaWtlKG9iamVjdCkgPyBhcnJheUxpa2VLZXlzKG9iamVjdCwgdHJ1ZSkgOiBiYXNlS2V5c0luKG9iamVjdCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIG9wcG9zaXRlIG9mIGBfLm1hcFZhbHVlc2A7IHRoaXMgbWV0aG9kIGNyZWF0ZXMgYW4gb2JqZWN0IHdpdGggdGhlXG4gICAgICogc2FtZSB2YWx1ZXMgYXMgYG9iamVjdGAgYW5kIGtleXMgZ2VuZXJhdGVkIGJ5IHJ1bm5pbmcgZWFjaCBvd24gZW51bWVyYWJsZVxuICAgICAqIHN0cmluZyBrZXllZCBwcm9wZXJ0eSBvZiBgb2JqZWN0YCB0aHJ1IGBpdGVyYXRlZWAuIFRoZSBpdGVyYXRlZSBpcyBpbnZva2VkXG4gICAgICogd2l0aCB0aHJlZSBhcmd1bWVudHM6ICh2YWx1ZSwga2V5LCBvYmplY3QpLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDMuOC4wXG4gICAgICogQGNhdGVnb3J5IE9iamVjdFxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBpdGVyYXRlIG92ZXIuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW2l0ZXJhdGVlPV8uaWRlbnRpdHldIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uXG4gICAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyB0aGUgbmV3IG1hcHBlZCBvYmplY3QuXG4gICAgICogQHNlZSBfLm1hcFZhbHVlc1xuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLm1hcEtleXMoeyAnYSc6IDEsICdiJzogMiB9LCBmdW5jdGlvbih2YWx1ZSwga2V5KSB7XG4gICAgICogICByZXR1cm4ga2V5ICsgdmFsdWU7XG4gICAgICogfSk7XG4gICAgICogLy8gPT4geyAnYTEnOiAxLCAnYjInOiAyIH1cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBtYXBLZXlzKG9iamVjdCwgaXRlcmF0ZWUpIHtcbiAgICAgIHZhciByZXN1bHQgPSB7fTtcbiAgICAgIGl0ZXJhdGVlID0gZ2V0SXRlcmF0ZWUoaXRlcmF0ZWUsIDMpO1xuXG4gICAgICBiYXNlRm9yT3duKG9iamVjdCwgZnVuY3Rpb24odmFsdWUsIGtleSwgb2JqZWN0KSB7XG4gICAgICAgIGJhc2VBc3NpZ25WYWx1ZShyZXN1bHQsIGl0ZXJhdGVlKHZhbHVlLCBrZXksIG9iamVjdCksIHZhbHVlKTtcbiAgICAgIH0pO1xuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGFuIG9iamVjdCB3aXRoIHRoZSBzYW1lIGtleXMgYXMgYG9iamVjdGAgYW5kIHZhbHVlcyBnZW5lcmF0ZWRcbiAgICAgKiBieSBydW5uaW5nIGVhY2ggb3duIGVudW1lcmFibGUgc3RyaW5nIGtleWVkIHByb3BlcnR5IG9mIGBvYmplY3RgIHRocnVcbiAgICAgKiBgaXRlcmF0ZWVgLiBUaGUgaXRlcmF0ZWUgaXMgaW52b2tlZCB3aXRoIHRocmVlIGFyZ3VtZW50czpcbiAgICAgKiAodmFsdWUsIGtleSwgb2JqZWN0KS5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAyLjQuMFxuICAgICAqIEBjYXRlZ29yeSBPYmplY3RcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gaXRlcmF0ZSBvdmVyLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IFtpdGVyYXRlZT1fLmlkZW50aXR5XSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICAgICAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgdGhlIG5ldyBtYXBwZWQgb2JqZWN0LlxuICAgICAqIEBzZWUgXy5tYXBLZXlzXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciB1c2VycyA9IHtcbiAgICAgKiAgICdmcmVkJzogICAgeyAndXNlcic6ICdmcmVkJywgICAgJ2FnZSc6IDQwIH0sXG4gICAgICogICAncGViYmxlcyc6IHsgJ3VzZXInOiAncGViYmxlcycsICdhZ2UnOiAxIH1cbiAgICAgKiB9O1xuICAgICAqXG4gICAgICogXy5tYXBWYWx1ZXModXNlcnMsIGZ1bmN0aW9uKG8pIHsgcmV0dXJuIG8uYWdlOyB9KTtcbiAgICAgKiAvLyA9PiB7ICdmcmVkJzogNDAsICdwZWJibGVzJzogMSB9IChpdGVyYXRpb24gb3JkZXIgaXMgbm90IGd1YXJhbnRlZWQpXG4gICAgICpcbiAgICAgKiAvLyBUaGUgYF8ucHJvcGVydHlgIGl0ZXJhdGVlIHNob3J0aGFuZC5cbiAgICAgKiBfLm1hcFZhbHVlcyh1c2VycywgJ2FnZScpO1xuICAgICAqIC8vID0+IHsgJ2ZyZWQnOiA0MCwgJ3BlYmJsZXMnOiAxIH0gKGl0ZXJhdGlvbiBvcmRlciBpcyBub3QgZ3VhcmFudGVlZClcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBtYXBWYWx1ZXMob2JqZWN0LCBpdGVyYXRlZSkge1xuICAgICAgdmFyIHJlc3VsdCA9IHt9O1xuICAgICAgaXRlcmF0ZWUgPSBnZXRJdGVyYXRlZShpdGVyYXRlZSwgMyk7XG5cbiAgICAgIGJhc2VGb3JPd24ob2JqZWN0LCBmdW5jdGlvbih2YWx1ZSwga2V5LCBvYmplY3QpIHtcbiAgICAgICAgYmFzZUFzc2lnblZhbHVlKHJlc3VsdCwga2V5LCBpdGVyYXRlZSh2YWx1ZSwga2V5LCBvYmplY3QpKTtcbiAgICAgIH0pO1xuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIG1ldGhvZCBpcyBsaWtlIGBfLmFzc2lnbmAgZXhjZXB0IHRoYXQgaXQgcmVjdXJzaXZlbHkgbWVyZ2VzIG93biBhbmRcbiAgICAgKiBpbmhlcml0ZWQgZW51bWVyYWJsZSBzdHJpbmcga2V5ZWQgcHJvcGVydGllcyBvZiBzb3VyY2Ugb2JqZWN0cyBpbnRvIHRoZVxuICAgICAqIGRlc3RpbmF0aW9uIG9iamVjdC4gU291cmNlIHByb3BlcnRpZXMgdGhhdCByZXNvbHZlIHRvIGB1bmRlZmluZWRgIGFyZVxuICAgICAqIHNraXBwZWQgaWYgYSBkZXN0aW5hdGlvbiB2YWx1ZSBleGlzdHMuIEFycmF5IGFuZCBwbGFpbiBvYmplY3QgcHJvcGVydGllc1xuICAgICAqIGFyZSBtZXJnZWQgcmVjdXJzaXZlbHkuIE90aGVyIG9iamVjdHMgYW5kIHZhbHVlIHR5cGVzIGFyZSBvdmVycmlkZGVuIGJ5XG4gICAgICogYXNzaWdubWVudC4gU291cmNlIG9iamVjdHMgYXJlIGFwcGxpZWQgZnJvbSBsZWZ0IHRvIHJpZ2h0LiBTdWJzZXF1ZW50XG4gICAgICogc291cmNlcyBvdmVyd3JpdGUgcHJvcGVydHkgYXNzaWdubWVudHMgb2YgcHJldmlvdXMgc291cmNlcy5cbiAgICAgKlxuICAgICAqICoqTm90ZToqKiBUaGlzIG1ldGhvZCBtdXRhdGVzIGBvYmplY3RgLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDAuNS4wXG4gICAgICogQGNhdGVnb3J5IE9iamVjdFxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIGRlc3RpbmF0aW9uIG9iamVjdC5cbiAgICAgKiBAcGFyYW0gey4uLk9iamVjdH0gW3NvdXJjZXNdIFRoZSBzb3VyY2Ugb2JqZWN0cy5cbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIGBvYmplY3RgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgb2JqZWN0ID0ge1xuICAgICAqICAgJ2EnOiBbeyAnYic6IDIgfSwgeyAnZCc6IDQgfV1cbiAgICAgKiB9O1xuICAgICAqXG4gICAgICogdmFyIG90aGVyID0ge1xuICAgICAqICAgJ2EnOiBbeyAnYyc6IDMgfSwgeyAnZSc6IDUgfV1cbiAgICAgKiB9O1xuICAgICAqXG4gICAgICogXy5tZXJnZShvYmplY3QsIG90aGVyKTtcbiAgICAgKiAvLyA9PiB7ICdhJzogW3sgJ2InOiAyLCAnYyc6IDMgfSwgeyAnZCc6IDQsICdlJzogNSB9XSB9XG4gICAgICovXG4gICAgdmFyIG1lcmdlID0gY3JlYXRlQXNzaWduZXIoZnVuY3Rpb24ob2JqZWN0LCBzb3VyY2UsIHNyY0luZGV4KSB7XG4gICAgICBiYXNlTWVyZ2Uob2JqZWN0LCBzb3VyY2UsIHNyY0luZGV4KTtcbiAgICB9KTtcblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIGlzIGxpa2UgYF8ubWVyZ2VgIGV4Y2VwdCB0aGF0IGl0IGFjY2VwdHMgYGN1c3RvbWl6ZXJgIHdoaWNoXG4gICAgICogaXMgaW52b2tlZCB0byBwcm9kdWNlIHRoZSBtZXJnZWQgdmFsdWVzIG9mIHRoZSBkZXN0aW5hdGlvbiBhbmQgc291cmNlXG4gICAgICogcHJvcGVydGllcy4gSWYgYGN1c3RvbWl6ZXJgIHJldHVybnMgYHVuZGVmaW5lZGAsIG1lcmdpbmcgaXMgaGFuZGxlZCBieSB0aGVcbiAgICAgKiBtZXRob2QgaW5zdGVhZC4gVGhlIGBjdXN0b21pemVyYCBpcyBpbnZva2VkIHdpdGggc2l4IGFyZ3VtZW50czpcbiAgICAgKiAob2JqVmFsdWUsIHNyY1ZhbHVlLCBrZXksIG9iamVjdCwgc291cmNlLCBzdGFjaykuXG4gICAgICpcbiAgICAgKiAqKk5vdGU6KiogVGhpcyBtZXRob2QgbXV0YXRlcyBgb2JqZWN0YC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjAuMFxuICAgICAqIEBjYXRlZ29yeSBPYmplY3RcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBkZXN0aW5hdGlvbiBvYmplY3QuXG4gICAgICogQHBhcmFtIHsuLi5PYmplY3R9IHNvdXJjZXMgVGhlIHNvdXJjZSBvYmplY3RzLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGN1c3RvbWl6ZXIgVGhlIGZ1bmN0aW9uIHRvIGN1c3RvbWl6ZSBhc3NpZ25lZCB2YWx1ZXMuXG4gICAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyBgb2JqZWN0YC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogZnVuY3Rpb24gY3VzdG9taXplcihvYmpWYWx1ZSwgc3JjVmFsdWUpIHtcbiAgICAgKiAgIGlmIChfLmlzQXJyYXkob2JqVmFsdWUpKSB7XG4gICAgICogICAgIHJldHVybiBvYmpWYWx1ZS5jb25jYXQoc3JjVmFsdWUpO1xuICAgICAqICAgfVxuICAgICAqIH1cbiAgICAgKlxuICAgICAqIHZhciBvYmplY3QgPSB7ICdhJzogWzFdLCAnYic6IFsyXSB9O1xuICAgICAqIHZhciBvdGhlciA9IHsgJ2EnOiBbM10sICdiJzogWzRdIH07XG4gICAgICpcbiAgICAgKiBfLm1lcmdlV2l0aChvYmplY3QsIG90aGVyLCBjdXN0b21pemVyKTtcbiAgICAgKiAvLyA9PiB7ICdhJzogWzEsIDNdLCAnYic6IFsyLCA0XSB9XG4gICAgICovXG4gICAgdmFyIG1lcmdlV2l0aCA9IGNyZWF0ZUFzc2lnbmVyKGZ1bmN0aW9uKG9iamVjdCwgc291cmNlLCBzcmNJbmRleCwgY3VzdG9taXplcikge1xuICAgICAgYmFzZU1lcmdlKG9iamVjdCwgc291cmNlLCBzcmNJbmRleCwgY3VzdG9taXplcik7XG4gICAgfSk7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgb3Bwb3NpdGUgb2YgYF8ucGlja2A7IHRoaXMgbWV0aG9kIGNyZWF0ZXMgYW4gb2JqZWN0IGNvbXBvc2VkIG9mIHRoZVxuICAgICAqIG93biBhbmQgaW5oZXJpdGVkIGVudW1lcmFibGUgcHJvcGVydHkgcGF0aHMgb2YgYG9iamVjdGAgdGhhdCBhcmUgbm90IG9taXR0ZWQuXG4gICAgICpcbiAgICAgKiAqKk5vdGU6KiogVGhpcyBtZXRob2QgaXMgY29uc2lkZXJhYmx5IHNsb3dlciB0aGFuIGBfLnBpY2tgLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBzaW5jZSAwLjEuMFxuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQGNhdGVnb3J5IE9iamVjdFxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIHNvdXJjZSBvYmplY3QuXG4gICAgICogQHBhcmFtIHsuLi4oc3RyaW5nfHN0cmluZ1tdKX0gW3BhdGhzXSBUaGUgcHJvcGVydHkgcGF0aHMgdG8gb21pdC5cbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIHRoZSBuZXcgb2JqZWN0LlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgb2JqZWN0ID0geyAnYSc6IDEsICdiJzogJzInLCAnYyc6IDMgfTtcbiAgICAgKlxuICAgICAqIF8ub21pdChvYmplY3QsIFsnYScsICdjJ10pO1xuICAgICAqIC8vID0+IHsgJ2InOiAnMicgfVxuICAgICAqL1xuICAgIHZhciBvbWl0ID0gZmxhdFJlc3QoZnVuY3Rpb24ob2JqZWN0LCBwYXRocykge1xuICAgICAgdmFyIHJlc3VsdCA9IHt9O1xuICAgICAgaWYgKG9iamVjdCA9PSBudWxsKSB7XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICB9XG4gICAgICB2YXIgaXNEZWVwID0gZmFsc2U7XG4gICAgICBwYXRocyA9IGFycmF5TWFwKHBhdGhzLCBmdW5jdGlvbihwYXRoKSB7XG4gICAgICAgIHBhdGggPSBjYXN0UGF0aChwYXRoLCBvYmplY3QpO1xuICAgICAgICBpc0RlZXAgfHwgKGlzRGVlcCA9IHBhdGgubGVuZ3RoID4gMSk7XG4gICAgICAgIHJldHVybiBwYXRoO1xuICAgICAgfSk7XG4gICAgICBjb3B5T2JqZWN0KG9iamVjdCwgZ2V0QWxsS2V5c0luKG9iamVjdCksIHJlc3VsdCk7XG4gICAgICBpZiAoaXNEZWVwKSB7XG4gICAgICAgIHJlc3VsdCA9IGJhc2VDbG9uZShyZXN1bHQsIENMT05FX0RFRVBfRkxBRyB8IENMT05FX0ZMQVRfRkxBRyB8IENMT05FX1NZTUJPTFNfRkxBRywgY3VzdG9tT21pdENsb25lKTtcbiAgICAgIH1cbiAgICAgIHZhciBsZW5ndGggPSBwYXRocy5sZW5ndGg7XG4gICAgICB3aGlsZSAobGVuZ3RoLS0pIHtcbiAgICAgICAgYmFzZVVuc2V0KHJlc3VsdCwgcGF0aHNbbGVuZ3RoXSk7XG4gICAgICB9XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH0pO1xuXG4gICAgLyoqXG4gICAgICogVGhlIG9wcG9zaXRlIG9mIGBfLnBpY2tCeWA7IHRoaXMgbWV0aG9kIGNyZWF0ZXMgYW4gb2JqZWN0IGNvbXBvc2VkIG9mXG4gICAgICogdGhlIG93biBhbmQgaW5oZXJpdGVkIGVudW1lcmFibGUgc3RyaW5nIGtleWVkIHByb3BlcnRpZXMgb2YgYG9iamVjdGAgdGhhdFxuICAgICAqIGBwcmVkaWNhdGVgIGRvZXNuJ3QgcmV0dXJuIHRydXRoeSBmb3IuIFRoZSBwcmVkaWNhdGUgaXMgaW52b2tlZCB3aXRoIHR3b1xuICAgICAqIGFyZ3VtZW50czogKHZhbHVlLCBrZXkpLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMC4wXG4gICAgICogQGNhdGVnb3J5IE9iamVjdFxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIHNvdXJjZSBvYmplY3QuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW3ByZWRpY2F0ZT1fLmlkZW50aXR5XSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgcHJvcGVydHkuXG4gICAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyB0aGUgbmV3IG9iamVjdC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIG9iamVjdCA9IHsgJ2EnOiAxLCAnYic6ICcyJywgJ2MnOiAzIH07XG4gICAgICpcbiAgICAgKiBfLm9taXRCeShvYmplY3QsIF8uaXNOdW1iZXIpO1xuICAgICAqIC8vID0+IHsgJ2InOiAnMicgfVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIG9taXRCeShvYmplY3QsIHByZWRpY2F0ZSkge1xuICAgICAgcmV0dXJuIHBpY2tCeShvYmplY3QsIG5lZ2F0ZShnZXRJdGVyYXRlZShwcmVkaWNhdGUpKSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhbiBvYmplY3QgY29tcG9zZWQgb2YgdGhlIHBpY2tlZCBgb2JqZWN0YCBwcm9wZXJ0aWVzLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBzaW5jZSAwLjEuMFxuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQGNhdGVnb3J5IE9iamVjdFxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIHNvdXJjZSBvYmplY3QuXG4gICAgICogQHBhcmFtIHsuLi4oc3RyaW5nfHN0cmluZ1tdKX0gW3BhdGhzXSBUaGUgcHJvcGVydHkgcGF0aHMgdG8gcGljay5cbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIHRoZSBuZXcgb2JqZWN0LlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgb2JqZWN0ID0geyAnYSc6IDEsICdiJzogJzInLCAnYyc6IDMgfTtcbiAgICAgKlxuICAgICAqIF8ucGljayhvYmplY3QsIFsnYScsICdjJ10pO1xuICAgICAqIC8vID0+IHsgJ2EnOiAxLCAnYyc6IDMgfVxuICAgICAqL1xuICAgIHZhciBwaWNrID0gZmxhdFJlc3QoZnVuY3Rpb24ob2JqZWN0LCBwYXRocykge1xuICAgICAgcmV0dXJuIG9iamVjdCA9PSBudWxsID8ge30gOiBiYXNlUGljayhvYmplY3QsIHBhdGhzKTtcbiAgICB9KTtcblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYW4gb2JqZWN0IGNvbXBvc2VkIG9mIHRoZSBgb2JqZWN0YCBwcm9wZXJ0aWVzIGBwcmVkaWNhdGVgIHJldHVybnNcbiAgICAgKiB0cnV0aHkgZm9yLiBUaGUgcHJlZGljYXRlIGlzIGludm9rZWQgd2l0aCB0d28gYXJndW1lbnRzOiAodmFsdWUsIGtleSkuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgT2JqZWN0XG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgc291cmNlIG9iamVjdC5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbcHJlZGljYXRlPV8uaWRlbnRpdHldIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBwcm9wZXJ0eS5cbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIHRoZSBuZXcgb2JqZWN0LlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgb2JqZWN0ID0geyAnYSc6IDEsICdiJzogJzInLCAnYyc6IDMgfTtcbiAgICAgKlxuICAgICAqIF8ucGlja0J5KG9iamVjdCwgXy5pc051bWJlcik7XG4gICAgICogLy8gPT4geyAnYSc6IDEsICdjJzogMyB9XG4gICAgICovXG4gICAgZnVuY3Rpb24gcGlja0J5KG9iamVjdCwgcHJlZGljYXRlKSB7XG4gICAgICBpZiAob2JqZWN0ID09IG51bGwpIHtcbiAgICAgICAgcmV0dXJuIHt9O1xuICAgICAgfVxuICAgICAgdmFyIHByb3BzID0gYXJyYXlNYXAoZ2V0QWxsS2V5c0luKG9iamVjdCksIGZ1bmN0aW9uKHByb3ApIHtcbiAgICAgICAgcmV0dXJuIFtwcm9wXTtcbiAgICAgIH0pO1xuICAgICAgcHJlZGljYXRlID0gZ2V0SXRlcmF0ZWUocHJlZGljYXRlKTtcbiAgICAgIHJldHVybiBiYXNlUGlja0J5KG9iamVjdCwgcHJvcHMsIGZ1bmN0aW9uKHZhbHVlLCBwYXRoKSB7XG4gICAgICAgIHJldHVybiBwcmVkaWNhdGUodmFsdWUsIHBhdGhbMF0pO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgaXMgbGlrZSBgXy5nZXRgIGV4Y2VwdCB0aGF0IGlmIHRoZSByZXNvbHZlZCB2YWx1ZSBpcyBhXG4gICAgICogZnVuY3Rpb24gaXQncyBpbnZva2VkIHdpdGggdGhlIGB0aGlzYCBiaW5kaW5nIG9mIGl0cyBwYXJlbnQgb2JqZWN0IGFuZFxuICAgICAqIGl0cyByZXN1bHQgaXMgcmV0dXJuZWQuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQHNpbmNlIDAuMS4wXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAY2F0ZWdvcnkgT2JqZWN0XG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIHF1ZXJ5LlxuICAgICAqIEBwYXJhbSB7QXJyYXl8c3RyaW5nfSBwYXRoIFRoZSBwYXRoIG9mIHRoZSBwcm9wZXJ0eSB0byByZXNvbHZlLlxuICAgICAqIEBwYXJhbSB7Kn0gW2RlZmF1bHRWYWx1ZV0gVGhlIHZhbHVlIHJldHVybmVkIGZvciBgdW5kZWZpbmVkYCByZXNvbHZlZCB2YWx1ZXMuXG4gICAgICogQHJldHVybnMgeyp9IFJldHVybnMgdGhlIHJlc29sdmVkIHZhbHVlLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgb2JqZWN0ID0geyAnYSc6IFt7ICdiJzogeyAnYzEnOiAzLCAnYzInOiBfLmNvbnN0YW50KDQpIH0gfV0gfTtcbiAgICAgKlxuICAgICAqIF8ucmVzdWx0KG9iamVjdCwgJ2FbMF0uYi5jMScpO1xuICAgICAqIC8vID0+IDNcbiAgICAgKlxuICAgICAqIF8ucmVzdWx0KG9iamVjdCwgJ2FbMF0uYi5jMicpO1xuICAgICAqIC8vID0+IDRcbiAgICAgKlxuICAgICAqIF8ucmVzdWx0KG9iamVjdCwgJ2FbMF0uYi5jMycsICdkZWZhdWx0Jyk7XG4gICAgICogLy8gPT4gJ2RlZmF1bHQnXG4gICAgICpcbiAgICAgKiBfLnJlc3VsdChvYmplY3QsICdhWzBdLmIuYzMnLCBfLmNvbnN0YW50KCdkZWZhdWx0JykpO1xuICAgICAqIC8vID0+ICdkZWZhdWx0J1xuICAgICAqL1xuICAgIGZ1bmN0aW9uIHJlc3VsdChvYmplY3QsIHBhdGgsIGRlZmF1bHRWYWx1ZSkge1xuICAgICAgcGF0aCA9IGNhc3RQYXRoKHBhdGgsIG9iamVjdCk7XG5cbiAgICAgIHZhciBpbmRleCA9IC0xLFxuICAgICAgICAgIGxlbmd0aCA9IHBhdGgubGVuZ3RoO1xuXG4gICAgICAvLyBFbnN1cmUgdGhlIGxvb3AgaXMgZW50ZXJlZCB3aGVuIHBhdGggaXMgZW1wdHkuXG4gICAgICBpZiAoIWxlbmd0aCkge1xuICAgICAgICBsZW5ndGggPSAxO1xuICAgICAgICBvYmplY3QgPSB1bmRlZmluZWQ7XG4gICAgICB9XG4gICAgICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgICAgICB2YXIgdmFsdWUgPSBvYmplY3QgPT0gbnVsbCA/IHVuZGVmaW5lZCA6IG9iamVjdFt0b0tleShwYXRoW2luZGV4XSldO1xuICAgICAgICBpZiAodmFsdWUgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIGluZGV4ID0gbGVuZ3RoO1xuICAgICAgICAgIHZhbHVlID0gZGVmYXVsdFZhbHVlO1xuICAgICAgICB9XG4gICAgICAgIG9iamVjdCA9IGlzRnVuY3Rpb24odmFsdWUpID8gdmFsdWUuY2FsbChvYmplY3QpIDogdmFsdWU7XG4gICAgICB9XG4gICAgICByZXR1cm4gb2JqZWN0O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFNldHMgdGhlIHZhbHVlIGF0IGBwYXRoYCBvZiBgb2JqZWN0YC4gSWYgYSBwb3J0aW9uIG9mIGBwYXRoYCBkb2Vzbid0IGV4aXN0LFxuICAgICAqIGl0J3MgY3JlYXRlZC4gQXJyYXlzIGFyZSBjcmVhdGVkIGZvciBtaXNzaW5nIGluZGV4IHByb3BlcnRpZXMgd2hpbGUgb2JqZWN0c1xuICAgICAqIGFyZSBjcmVhdGVkIGZvciBhbGwgb3RoZXIgbWlzc2luZyBwcm9wZXJ0aWVzLiBVc2UgYF8uc2V0V2l0aGAgdG8gY3VzdG9taXplXG4gICAgICogYHBhdGhgIGNyZWF0aW9uLlxuICAgICAqXG4gICAgICogKipOb3RlOioqIFRoaXMgbWV0aG9kIG11dGF0ZXMgYG9iamVjdGAuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMy43LjBcbiAgICAgKiBAY2F0ZWdvcnkgT2JqZWN0XG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIG1vZGlmeS5cbiAgICAgKiBAcGFyYW0ge0FycmF5fHN0cmluZ30gcGF0aCBUaGUgcGF0aCBvZiB0aGUgcHJvcGVydHkgdG8gc2V0LlxuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIHNldC5cbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIGBvYmplY3RgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgb2JqZWN0ID0geyAnYSc6IFt7ICdiJzogeyAnYyc6IDMgfSB9XSB9O1xuICAgICAqXG4gICAgICogXy5zZXQob2JqZWN0LCAnYVswXS5iLmMnLCA0KTtcbiAgICAgKiBjb25zb2xlLmxvZyhvYmplY3QuYVswXS5iLmMpO1xuICAgICAqIC8vID0+IDRcbiAgICAgKlxuICAgICAqIF8uc2V0KG9iamVjdCwgWyd4JywgJzAnLCAneScsICd6J10sIDUpO1xuICAgICAqIGNvbnNvbGUubG9nKG9iamVjdC54WzBdLnkueik7XG4gICAgICogLy8gPT4gNVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIHNldChvYmplY3QsIHBhdGgsIHZhbHVlKSB7XG4gICAgICByZXR1cm4gb2JqZWN0ID09IG51bGwgPyBvYmplY3QgOiBiYXNlU2V0KG9iamVjdCwgcGF0aCwgdmFsdWUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIGlzIGxpa2UgYF8uc2V0YCBleGNlcHQgdGhhdCBpdCBhY2NlcHRzIGBjdXN0b21pemVyYCB3aGljaCBpc1xuICAgICAqIGludm9rZWQgdG8gcHJvZHVjZSB0aGUgb2JqZWN0cyBvZiBgcGF0aGAuICBJZiBgY3VzdG9taXplcmAgcmV0dXJucyBgdW5kZWZpbmVkYFxuICAgICAqIHBhdGggY3JlYXRpb24gaXMgaGFuZGxlZCBieSB0aGUgbWV0aG9kIGluc3RlYWQuIFRoZSBgY3VzdG9taXplcmAgaXMgaW52b2tlZFxuICAgICAqIHdpdGggdGhyZWUgYXJndW1lbnRzOiAobnNWYWx1ZSwga2V5LCBuc09iamVjdCkuXG4gICAgICpcbiAgICAgKiAqKk5vdGU6KiogVGhpcyBtZXRob2QgbXV0YXRlcyBgb2JqZWN0YC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjAuMFxuICAgICAqIEBjYXRlZ29yeSBPYmplY3RcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gbW9kaWZ5LlxuICAgICAqIEBwYXJhbSB7QXJyYXl8c3RyaW5nfSBwYXRoIFRoZSBwYXRoIG9mIHRoZSBwcm9wZXJ0eSB0byBzZXQuXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gc2V0LlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IFtjdXN0b21pemVyXSBUaGUgZnVuY3Rpb24gdG8gY3VzdG9taXplIGFzc2lnbmVkIHZhbHVlcy5cbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIGBvYmplY3RgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgb2JqZWN0ID0ge307XG4gICAgICpcbiAgICAgKiBfLnNldFdpdGgob2JqZWN0LCAnWzBdWzFdJywgJ2EnLCBPYmplY3QpO1xuICAgICAqIC8vID0+IHsgJzAnOiB7ICcxJzogJ2EnIH0gfVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIHNldFdpdGgob2JqZWN0LCBwYXRoLCB2YWx1ZSwgY3VzdG9taXplcikge1xuICAgICAgY3VzdG9taXplciA9IHR5cGVvZiBjdXN0b21pemVyID09ICdmdW5jdGlvbicgPyBjdXN0b21pemVyIDogdW5kZWZpbmVkO1xuICAgICAgcmV0dXJuIG9iamVjdCA9PSBudWxsID8gb2JqZWN0IDogYmFzZVNldChvYmplY3QsIHBhdGgsIHZhbHVlLCBjdXN0b21pemVyKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGFuIGFycmF5IG9mIG93biBlbnVtZXJhYmxlIHN0cmluZyBrZXllZC12YWx1ZSBwYWlycyBmb3IgYG9iamVjdGBcbiAgICAgKiB3aGljaCBjYW4gYmUgY29uc3VtZWQgYnkgYF8uZnJvbVBhaXJzYC4gSWYgYG9iamVjdGAgaXMgYSBtYXAgb3Igc2V0LCBpdHNcbiAgICAgKiBlbnRyaWVzIGFyZSByZXR1cm5lZC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjAuMFxuICAgICAqIEBhbGlhcyBlbnRyaWVzXG4gICAgICogQGNhdGVnb3J5IE9iamVjdFxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBxdWVyeS5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIGtleS12YWx1ZSBwYWlycy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogZnVuY3Rpb24gRm9vKCkge1xuICAgICAqICAgdGhpcy5hID0gMTtcbiAgICAgKiAgIHRoaXMuYiA9IDI7XG4gICAgICogfVxuICAgICAqXG4gICAgICogRm9vLnByb3RvdHlwZS5jID0gMztcbiAgICAgKlxuICAgICAqIF8udG9QYWlycyhuZXcgRm9vKTtcbiAgICAgKiAvLyA9PiBbWydhJywgMV0sIFsnYicsIDJdXSAoaXRlcmF0aW9uIG9yZGVyIGlzIG5vdCBndWFyYW50ZWVkKVxuICAgICAqL1xuICAgIHZhciB0b1BhaXJzID0gY3JlYXRlVG9QYWlycyhrZXlzKTtcblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYW4gYXJyYXkgb2Ygb3duIGFuZCBpbmhlcml0ZWQgZW51bWVyYWJsZSBzdHJpbmcga2V5ZWQtdmFsdWUgcGFpcnNcbiAgICAgKiBmb3IgYG9iamVjdGAgd2hpY2ggY2FuIGJlIGNvbnN1bWVkIGJ5IGBfLmZyb21QYWlyc2AuIElmIGBvYmplY3RgIGlzIGEgbWFwXG4gICAgICogb3Igc2V0LCBpdHMgZW50cmllcyBhcmUgcmV0dXJuZWQuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4wLjBcbiAgICAgKiBAYWxpYXMgZW50cmllc0luXG4gICAgICogQGNhdGVnb3J5IE9iamVjdFxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBxdWVyeS5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIGtleS12YWx1ZSBwYWlycy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogZnVuY3Rpb24gRm9vKCkge1xuICAgICAqICAgdGhpcy5hID0gMTtcbiAgICAgKiAgIHRoaXMuYiA9IDI7XG4gICAgICogfVxuICAgICAqXG4gICAgICogRm9vLnByb3RvdHlwZS5jID0gMztcbiAgICAgKlxuICAgICAqIF8udG9QYWlyc0luKG5ldyBGb28pO1xuICAgICAqIC8vID0+IFtbJ2EnLCAxXSwgWydiJywgMl0sIFsnYycsIDNdXSAoaXRlcmF0aW9uIG9yZGVyIGlzIG5vdCBndWFyYW50ZWVkKVxuICAgICAqL1xuICAgIHZhciB0b1BhaXJzSW4gPSBjcmVhdGVUb1BhaXJzKGtleXNJbik7XG5cbiAgICAvKipcbiAgICAgKiBBbiBhbHRlcm5hdGl2ZSB0byBgXy5yZWR1Y2VgOyB0aGlzIG1ldGhvZCB0cmFuc2Zvcm1zIGBvYmplY3RgIHRvIGEgbmV3XG4gICAgICogYGFjY3VtdWxhdG9yYCBvYmplY3Qgd2hpY2ggaXMgdGhlIHJlc3VsdCBvZiBydW5uaW5nIGVhY2ggb2YgaXRzIG93blxuICAgICAqIGVudW1lcmFibGUgc3RyaW5nIGtleWVkIHByb3BlcnRpZXMgdGhydSBgaXRlcmF0ZWVgLCB3aXRoIGVhY2ggaW52b2NhdGlvblxuICAgICAqIHBvdGVudGlhbGx5IG11dGF0aW5nIHRoZSBgYWNjdW11bGF0b3JgIG9iamVjdC4gSWYgYGFjY3VtdWxhdG9yYCBpcyBub3RcbiAgICAgKiBwcm92aWRlZCwgYSBuZXcgb2JqZWN0IHdpdGggdGhlIHNhbWUgYFtbUHJvdG90eXBlXV1gIHdpbGwgYmUgdXNlZC4gVGhlXG4gICAgICogaXRlcmF0ZWUgaXMgaW52b2tlZCB3aXRoIGZvdXIgYXJndW1lbnRzOiAoYWNjdW11bGF0b3IsIHZhbHVlLCBrZXksIG9iamVjdCkuXG4gICAgICogSXRlcmF0ZWUgZnVuY3Rpb25zIG1heSBleGl0IGl0ZXJhdGlvbiBlYXJseSBieSBleHBsaWNpdGx5IHJldHVybmluZyBgZmFsc2VgLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDEuMy4wXG4gICAgICogQGNhdGVnb3J5IE9iamVjdFxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBpdGVyYXRlIG92ZXIuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW2l0ZXJhdGVlPV8uaWRlbnRpdHldIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uXG4gICAgICogQHBhcmFtIHsqfSBbYWNjdW11bGF0b3JdIFRoZSBjdXN0b20gYWNjdW11bGF0b3IgdmFsdWUuXG4gICAgICogQHJldHVybnMgeyp9IFJldHVybnMgdGhlIGFjY3VtdWxhdGVkIHZhbHVlLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLnRyYW5zZm9ybShbMiwgMywgNF0sIGZ1bmN0aW9uKHJlc3VsdCwgbikge1xuICAgICAqICAgcmVzdWx0LnB1c2gobiAqPSBuKTtcbiAgICAgKiAgIHJldHVybiBuICUgMiA9PSAwO1xuICAgICAqIH0sIFtdKTtcbiAgICAgKiAvLyA9PiBbNCwgOV1cbiAgICAgKlxuICAgICAqIF8udHJhbnNmb3JtKHsgJ2EnOiAxLCAnYic6IDIsICdjJzogMSB9LCBmdW5jdGlvbihyZXN1bHQsIHZhbHVlLCBrZXkpIHtcbiAgICAgKiAgIChyZXN1bHRbdmFsdWVdIHx8IChyZXN1bHRbdmFsdWVdID0gW10pKS5wdXNoKGtleSk7XG4gICAgICogfSwge30pO1xuICAgICAqIC8vID0+IHsgJzEnOiBbJ2EnLCAnYyddLCAnMic6IFsnYiddIH1cbiAgICAgKi9cbiAgICBmdW5jdGlvbiB0cmFuc2Zvcm0ob2JqZWN0LCBpdGVyYXRlZSwgYWNjdW11bGF0b3IpIHtcbiAgICAgIHZhciBpc0FyciA9IGlzQXJyYXkob2JqZWN0KSxcbiAgICAgICAgICBpc0Fyckxpa2UgPSBpc0FyciB8fCBpc0J1ZmZlcihvYmplY3QpIHx8IGlzVHlwZWRBcnJheShvYmplY3QpO1xuXG4gICAgICBpdGVyYXRlZSA9IGdldEl0ZXJhdGVlKGl0ZXJhdGVlLCA0KTtcbiAgICAgIGlmIChhY2N1bXVsYXRvciA9PSBudWxsKSB7XG4gICAgICAgIHZhciBDdG9yID0gb2JqZWN0ICYmIG9iamVjdC5jb25zdHJ1Y3RvcjtcbiAgICAgICAgaWYgKGlzQXJyTGlrZSkge1xuICAgICAgICAgIGFjY3VtdWxhdG9yID0gaXNBcnIgPyBuZXcgQ3RvciA6IFtdO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKGlzT2JqZWN0KG9iamVjdCkpIHtcbiAgICAgICAgICBhY2N1bXVsYXRvciA9IGlzRnVuY3Rpb24oQ3RvcikgPyBiYXNlQ3JlYXRlKGdldFByb3RvdHlwZShvYmplY3QpKSA6IHt9O1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgIGFjY3VtdWxhdG9yID0ge307XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIChpc0Fyckxpa2UgPyBhcnJheUVhY2ggOiBiYXNlRm9yT3duKShvYmplY3QsIGZ1bmN0aW9uKHZhbHVlLCBpbmRleCwgb2JqZWN0KSB7XG4gICAgICAgIHJldHVybiBpdGVyYXRlZShhY2N1bXVsYXRvciwgdmFsdWUsIGluZGV4LCBvYmplY3QpO1xuICAgICAgfSk7XG4gICAgICByZXR1cm4gYWNjdW11bGF0b3I7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmVtb3ZlcyB0aGUgcHJvcGVydHkgYXQgYHBhdGhgIG9mIGBvYmplY3RgLlxuICAgICAqXG4gICAgICogKipOb3RlOioqIFRoaXMgbWV0aG9kIG11dGF0ZXMgYG9iamVjdGAuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgT2JqZWN0XG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIG1vZGlmeS5cbiAgICAgKiBAcGFyYW0ge0FycmF5fHN0cmluZ30gcGF0aCBUaGUgcGF0aCBvZiB0aGUgcHJvcGVydHkgdG8gdW5zZXQuXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIHRoZSBwcm9wZXJ0eSBpcyBkZWxldGVkLCBlbHNlIGBmYWxzZWAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciBvYmplY3QgPSB7ICdhJzogW3sgJ2InOiB7ICdjJzogNyB9IH1dIH07XG4gICAgICogXy51bnNldChvYmplY3QsICdhWzBdLmIuYycpO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKlxuICAgICAqIGNvbnNvbGUubG9nKG9iamVjdCk7XG4gICAgICogLy8gPT4geyAnYSc6IFt7ICdiJzoge30gfV0gfTtcbiAgICAgKlxuICAgICAqIF8udW5zZXQob2JqZWN0LCBbJ2EnLCAnMCcsICdiJywgJ2MnXSk7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqXG4gICAgICogY29uc29sZS5sb2cob2JqZWN0KTtcbiAgICAgKiAvLyA9PiB7ICdhJzogW3sgJ2InOiB7fSB9XSB9O1xuICAgICAqL1xuICAgIGZ1bmN0aW9uIHVuc2V0KG9iamVjdCwgcGF0aCkge1xuICAgICAgcmV0dXJuIG9iamVjdCA9PSBudWxsID8gdHJ1ZSA6IGJhc2VVbnNldChvYmplY3QsIHBhdGgpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIGlzIGxpa2UgYF8uc2V0YCBleGNlcHQgdGhhdCBhY2NlcHRzIGB1cGRhdGVyYCB0byBwcm9kdWNlIHRoZVxuICAgICAqIHZhbHVlIHRvIHNldC4gVXNlIGBfLnVwZGF0ZVdpdGhgIHRvIGN1c3RvbWl6ZSBgcGF0aGAgY3JlYXRpb24uIFRoZSBgdXBkYXRlcmBcbiAgICAgKiBpcyBpbnZva2VkIHdpdGggb25lIGFyZ3VtZW50OiAodmFsdWUpLlxuICAgICAqXG4gICAgICogKipOb3RlOioqIFRoaXMgbWV0aG9kIG11dGF0ZXMgYG9iamVjdGAuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC42LjBcbiAgICAgKiBAY2F0ZWdvcnkgT2JqZWN0XG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIG1vZGlmeS5cbiAgICAgKiBAcGFyYW0ge0FycmF5fHN0cmluZ30gcGF0aCBUaGUgcGF0aCBvZiB0aGUgcHJvcGVydHkgdG8gc2V0LlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IHVwZGF0ZXIgVGhlIGZ1bmN0aW9uIHRvIHByb2R1Y2UgdGhlIHVwZGF0ZWQgdmFsdWUuXG4gICAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyBgb2JqZWN0YC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIG9iamVjdCA9IHsgJ2EnOiBbeyAnYic6IHsgJ2MnOiAzIH0gfV0gfTtcbiAgICAgKlxuICAgICAqIF8udXBkYXRlKG9iamVjdCwgJ2FbMF0uYi5jJywgZnVuY3Rpb24obikgeyByZXR1cm4gbiAqIG47IH0pO1xuICAgICAqIGNvbnNvbGUubG9nKG9iamVjdC5hWzBdLmIuYyk7XG4gICAgICogLy8gPT4gOVxuICAgICAqXG4gICAgICogXy51cGRhdGUob2JqZWN0LCAneFswXS55LnonLCBmdW5jdGlvbihuKSB7IHJldHVybiBuID8gbiArIDEgOiAwOyB9KTtcbiAgICAgKiBjb25zb2xlLmxvZyhvYmplY3QueFswXS55LnopO1xuICAgICAqIC8vID0+IDBcbiAgICAgKi9cbiAgICBmdW5jdGlvbiB1cGRhdGUob2JqZWN0LCBwYXRoLCB1cGRhdGVyKSB7XG4gICAgICByZXR1cm4gb2JqZWN0ID09IG51bGwgPyBvYmplY3QgOiBiYXNlVXBkYXRlKG9iamVjdCwgcGF0aCwgY2FzdEZ1bmN0aW9uKHVwZGF0ZXIpKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIG1ldGhvZCBpcyBsaWtlIGBfLnVwZGF0ZWAgZXhjZXB0IHRoYXQgaXQgYWNjZXB0cyBgY3VzdG9taXplcmAgd2hpY2ggaXNcbiAgICAgKiBpbnZva2VkIHRvIHByb2R1Y2UgdGhlIG9iamVjdHMgb2YgYHBhdGhgLiAgSWYgYGN1c3RvbWl6ZXJgIHJldHVybnMgYHVuZGVmaW5lZGBcbiAgICAgKiBwYXRoIGNyZWF0aW9uIGlzIGhhbmRsZWQgYnkgdGhlIG1ldGhvZCBpbnN0ZWFkLiBUaGUgYGN1c3RvbWl6ZXJgIGlzIGludm9rZWRcbiAgICAgKiB3aXRoIHRocmVlIGFyZ3VtZW50czogKG5zVmFsdWUsIGtleSwgbnNPYmplY3QpLlxuICAgICAqXG4gICAgICogKipOb3RlOioqIFRoaXMgbWV0aG9kIG11dGF0ZXMgYG9iamVjdGAuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC42LjBcbiAgICAgKiBAY2F0ZWdvcnkgT2JqZWN0XG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIG1vZGlmeS5cbiAgICAgKiBAcGFyYW0ge0FycmF5fHN0cmluZ30gcGF0aCBUaGUgcGF0aCBvZiB0aGUgcHJvcGVydHkgdG8gc2V0LlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IHVwZGF0ZXIgVGhlIGZ1bmN0aW9uIHRvIHByb2R1Y2UgdGhlIHVwZGF0ZWQgdmFsdWUuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW2N1c3RvbWl6ZXJdIFRoZSBmdW5jdGlvbiB0byBjdXN0b21pemUgYXNzaWduZWQgdmFsdWVzLlxuICAgICAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgYG9iamVjdGAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciBvYmplY3QgPSB7fTtcbiAgICAgKlxuICAgICAqIF8udXBkYXRlV2l0aChvYmplY3QsICdbMF1bMV0nLCBfLmNvbnN0YW50KCdhJyksIE9iamVjdCk7XG4gICAgICogLy8gPT4geyAnMCc6IHsgJzEnOiAnYScgfSB9XG4gICAgICovXG4gICAgZnVuY3Rpb24gdXBkYXRlV2l0aChvYmplY3QsIHBhdGgsIHVwZGF0ZXIsIGN1c3RvbWl6ZXIpIHtcbiAgICAgIGN1c3RvbWl6ZXIgPSB0eXBlb2YgY3VzdG9taXplciA9PSAnZnVuY3Rpb24nID8gY3VzdG9taXplciA6IHVuZGVmaW5lZDtcbiAgICAgIHJldHVybiBvYmplY3QgPT0gbnVsbCA/IG9iamVjdCA6IGJhc2VVcGRhdGUob2JqZWN0LCBwYXRoLCBjYXN0RnVuY3Rpb24odXBkYXRlciksIGN1c3RvbWl6ZXIpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYW4gYXJyYXkgb2YgdGhlIG93biBlbnVtZXJhYmxlIHN0cmluZyBrZXllZCBwcm9wZXJ0eSB2YWx1ZXMgb2YgYG9iamVjdGAuXG4gICAgICpcbiAgICAgKiAqKk5vdGU6KiogTm9uLW9iamVjdCB2YWx1ZXMgYXJlIGNvZXJjZWQgdG8gb2JqZWN0cy5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAc2luY2UgMC4xLjBcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBjYXRlZ29yeSBPYmplY3RcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gcXVlcnkuXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBhcnJheSBvZiBwcm9wZXJ0eSB2YWx1ZXMuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIGZ1bmN0aW9uIEZvbygpIHtcbiAgICAgKiAgIHRoaXMuYSA9IDE7XG4gICAgICogICB0aGlzLmIgPSAyO1xuICAgICAqIH1cbiAgICAgKlxuICAgICAqIEZvby5wcm90b3R5cGUuYyA9IDM7XG4gICAgICpcbiAgICAgKiBfLnZhbHVlcyhuZXcgRm9vKTtcbiAgICAgKiAvLyA9PiBbMSwgMl0gKGl0ZXJhdGlvbiBvcmRlciBpcyBub3QgZ3VhcmFudGVlZClcbiAgICAgKlxuICAgICAqIF8udmFsdWVzKCdoaScpO1xuICAgICAqIC8vID0+IFsnaCcsICdpJ11cbiAgICAgKi9cbiAgICBmdW5jdGlvbiB2YWx1ZXMob2JqZWN0KSB7XG4gICAgICByZXR1cm4gb2JqZWN0ID09IG51bGwgPyBbXSA6IGJhc2VWYWx1ZXMob2JqZWN0LCBrZXlzKG9iamVjdCkpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYW4gYXJyYXkgb2YgdGhlIG93biBhbmQgaW5oZXJpdGVkIGVudW1lcmFibGUgc3RyaW5nIGtleWVkIHByb3BlcnR5XG4gICAgICogdmFsdWVzIG9mIGBvYmplY3RgLlxuICAgICAqXG4gICAgICogKipOb3RlOioqIE5vbi1vYmplY3QgdmFsdWVzIGFyZSBjb2VyY2VkIHRvIG9iamVjdHMuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMy4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgT2JqZWN0XG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIHF1ZXJ5LlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgYXJyYXkgb2YgcHJvcGVydHkgdmFsdWVzLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBmdW5jdGlvbiBGb28oKSB7XG4gICAgICogICB0aGlzLmEgPSAxO1xuICAgICAqICAgdGhpcy5iID0gMjtcbiAgICAgKiB9XG4gICAgICpcbiAgICAgKiBGb28ucHJvdG90eXBlLmMgPSAzO1xuICAgICAqXG4gICAgICogXy52YWx1ZXNJbihuZXcgRm9vKTtcbiAgICAgKiAvLyA9PiBbMSwgMiwgM10gKGl0ZXJhdGlvbiBvcmRlciBpcyBub3QgZ3VhcmFudGVlZClcbiAgICAgKi9cbiAgICBmdW5jdGlvbiB2YWx1ZXNJbihvYmplY3QpIHtcbiAgICAgIHJldHVybiBvYmplY3QgPT0gbnVsbCA/IFtdIDogYmFzZVZhbHVlcyhvYmplY3QsIGtleXNJbihvYmplY3QpKTtcbiAgICB9XG5cbiAgICAvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovXG5cbiAgICAvKipcbiAgICAgKiBDbGFtcHMgYG51bWJlcmAgd2l0aGluIHRoZSBpbmNsdXNpdmUgYGxvd2VyYCBhbmQgYHVwcGVyYCBib3VuZHMuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgTnVtYmVyXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IG51bWJlciBUaGUgbnVtYmVyIHRvIGNsYW1wLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbbG93ZXJdIFRoZSBsb3dlciBib3VuZC5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gdXBwZXIgVGhlIHVwcGVyIGJvdW5kLlxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9IFJldHVybnMgdGhlIGNsYW1wZWQgbnVtYmVyLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLmNsYW1wKC0xMCwgLTUsIDUpO1xuICAgICAqIC8vID0+IC01XG4gICAgICpcbiAgICAgKiBfLmNsYW1wKDEwLCAtNSwgNSk7XG4gICAgICogLy8gPT4gNVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGNsYW1wKG51bWJlciwgbG93ZXIsIHVwcGVyKSB7XG4gICAgICBpZiAodXBwZXIgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICB1cHBlciA9IGxvd2VyO1xuICAgICAgICBsb3dlciA9IHVuZGVmaW5lZDtcbiAgICAgIH1cbiAgICAgIGlmICh1cHBlciAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHVwcGVyID0gdG9OdW1iZXIodXBwZXIpO1xuICAgICAgICB1cHBlciA9IHVwcGVyID09PSB1cHBlciA/IHVwcGVyIDogMDtcbiAgICAgIH1cbiAgICAgIGlmIChsb3dlciAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGxvd2VyID0gdG9OdW1iZXIobG93ZXIpO1xuICAgICAgICBsb3dlciA9IGxvd2VyID09PSBsb3dlciA/IGxvd2VyIDogMDtcbiAgICAgIH1cbiAgICAgIHJldHVybiBiYXNlQ2xhbXAodG9OdW1iZXIobnVtYmVyKSwgbG93ZXIsIHVwcGVyKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDaGVja3MgaWYgYG5gIGlzIGJldHdlZW4gYHN0YXJ0YCBhbmQgdXAgdG8sIGJ1dCBub3QgaW5jbHVkaW5nLCBgZW5kYC4gSWZcbiAgICAgKiBgZW5kYCBpcyBub3Qgc3BlY2lmaWVkLCBpdCdzIHNldCB0byBgc3RhcnRgIHdpdGggYHN0YXJ0YCB0aGVuIHNldCB0byBgMGAuXG4gICAgICogSWYgYHN0YXJ0YCBpcyBncmVhdGVyIHRoYW4gYGVuZGAgdGhlIHBhcmFtcyBhcmUgc3dhcHBlZCB0byBzdXBwb3J0XG4gICAgICogbmVnYXRpdmUgcmFuZ2VzLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDMuMy4wXG4gICAgICogQGNhdGVnb3J5IE51bWJlclxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBudW1iZXIgVGhlIG51bWJlciB0byBjaGVjay5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW3N0YXJ0PTBdIFRoZSBzdGFydCBvZiB0aGUgcmFuZ2UuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IGVuZCBUaGUgZW5kIG9mIHRoZSByYW5nZS5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYG51bWJlcmAgaXMgaW4gdGhlIHJhbmdlLCBlbHNlIGBmYWxzZWAuXG4gICAgICogQHNlZSBfLnJhbmdlLCBfLnJhbmdlUmlnaHRcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5pblJhbmdlKDMsIDIsIDQpO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKlxuICAgICAqIF8uaW5SYW5nZSg0LCA4KTtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICpcbiAgICAgKiBfLmluUmFuZ2UoNCwgMik7XG4gICAgICogLy8gPT4gZmFsc2VcbiAgICAgKlxuICAgICAqIF8uaW5SYW5nZSgyLCAyKTtcbiAgICAgKiAvLyA9PiBmYWxzZVxuICAgICAqXG4gICAgICogXy5pblJhbmdlKDEuMiwgMik7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqXG4gICAgICogXy5pblJhbmdlKDUuMiwgNCk7XG4gICAgICogLy8gPT4gZmFsc2VcbiAgICAgKlxuICAgICAqIF8uaW5SYW5nZSgtMywgLTIsIC02KTtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICovXG4gICAgZnVuY3Rpb24gaW5SYW5nZShudW1iZXIsIHN0YXJ0LCBlbmQpIHtcbiAgICAgIHN0YXJ0ID0gdG9GaW5pdGUoc3RhcnQpO1xuICAgICAgaWYgKGVuZCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGVuZCA9IHN0YXJ0O1xuICAgICAgICBzdGFydCA9IDA7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBlbmQgPSB0b0Zpbml0ZShlbmQpO1xuICAgICAgfVxuICAgICAgbnVtYmVyID0gdG9OdW1iZXIobnVtYmVyKTtcbiAgICAgIHJldHVybiBiYXNlSW5SYW5nZShudW1iZXIsIHN0YXJ0LCBlbmQpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFByb2R1Y2VzIGEgcmFuZG9tIG51bWJlciBiZXR3ZWVuIHRoZSBpbmNsdXNpdmUgYGxvd2VyYCBhbmQgYHVwcGVyYCBib3VuZHMuXG4gICAgICogSWYgb25seSBvbmUgYXJndW1lbnQgaXMgcHJvdmlkZWQgYSBudW1iZXIgYmV0d2VlbiBgMGAgYW5kIHRoZSBnaXZlbiBudW1iZXJcbiAgICAgKiBpcyByZXR1cm5lZC4gSWYgYGZsb2F0aW5nYCBpcyBgdHJ1ZWAsIG9yIGVpdGhlciBgbG93ZXJgIG9yIGB1cHBlcmAgYXJlXG4gICAgICogZmxvYXRzLCBhIGZsb2F0aW5nLXBvaW50IG51bWJlciBpcyByZXR1cm5lZCBpbnN0ZWFkIG9mIGFuIGludGVnZXIuXG4gICAgICpcbiAgICAgKiAqKk5vdGU6KiogSmF2YVNjcmlwdCBmb2xsb3dzIHRoZSBJRUVFLTc1NCBzdGFuZGFyZCBmb3IgcmVzb2x2aW5nXG4gICAgICogZmxvYXRpbmctcG9pbnQgdmFsdWVzIHdoaWNoIGNhbiBwcm9kdWNlIHVuZXhwZWN0ZWQgcmVzdWx0cy5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAwLjcuMFxuICAgICAqIEBjYXRlZ29yeSBOdW1iZXJcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW2xvd2VyPTBdIFRoZSBsb3dlciBib3VuZC5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW3VwcGVyPTFdIFRoZSB1cHBlciBib3VuZC5cbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW59IFtmbG9hdGluZ10gU3BlY2lmeSByZXR1cm5pbmcgYSBmbG9hdGluZy1wb2ludCBudW1iZXIuXG4gICAgICogQHJldHVybnMge251bWJlcn0gUmV0dXJucyB0aGUgcmFuZG9tIG51bWJlci5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5yYW5kb20oMCwgNSk7XG4gICAgICogLy8gPT4gYW4gaW50ZWdlciBiZXR3ZWVuIDAgYW5kIDVcbiAgICAgKlxuICAgICAqIF8ucmFuZG9tKDUpO1xuICAgICAqIC8vID0+IGFsc28gYW4gaW50ZWdlciBiZXR3ZWVuIDAgYW5kIDVcbiAgICAgKlxuICAgICAqIF8ucmFuZG9tKDUsIHRydWUpO1xuICAgICAqIC8vID0+IGEgZmxvYXRpbmctcG9pbnQgbnVtYmVyIGJldHdlZW4gMCBhbmQgNVxuICAgICAqXG4gICAgICogXy5yYW5kb20oMS4yLCA1LjIpO1xuICAgICAqIC8vID0+IGEgZmxvYXRpbmctcG9pbnQgbnVtYmVyIGJldHdlZW4gMS4yIGFuZCA1LjJcbiAgICAgKi9cbiAgICBmdW5jdGlvbiByYW5kb20obG93ZXIsIHVwcGVyLCBmbG9hdGluZykge1xuICAgICAgaWYgKGZsb2F0aW5nICYmIHR5cGVvZiBmbG9hdGluZyAhPSAnYm9vbGVhbicgJiYgaXNJdGVyYXRlZUNhbGwobG93ZXIsIHVwcGVyLCBmbG9hdGluZykpIHtcbiAgICAgICAgdXBwZXIgPSBmbG9hdGluZyA9IHVuZGVmaW5lZDtcbiAgICAgIH1cbiAgICAgIGlmIChmbG9hdGluZyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGlmICh0eXBlb2YgdXBwZXIgPT0gJ2Jvb2xlYW4nKSB7XG4gICAgICAgICAgZmxvYXRpbmcgPSB1cHBlcjtcbiAgICAgICAgICB1cHBlciA9IHVuZGVmaW5lZDtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmICh0eXBlb2YgbG93ZXIgPT0gJ2Jvb2xlYW4nKSB7XG4gICAgICAgICAgZmxvYXRpbmcgPSBsb3dlcjtcbiAgICAgICAgICBsb3dlciA9IHVuZGVmaW5lZDtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKGxvd2VyID09PSB1bmRlZmluZWQgJiYgdXBwZXIgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICBsb3dlciA9IDA7XG4gICAgICAgIHVwcGVyID0gMTtcbiAgICAgIH1cbiAgICAgIGVsc2Uge1xuICAgICAgICBsb3dlciA9IHRvRmluaXRlKGxvd2VyKTtcbiAgICAgICAgaWYgKHVwcGVyID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICB1cHBlciA9IGxvd2VyO1xuICAgICAgICAgIGxvd2VyID0gMDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB1cHBlciA9IHRvRmluaXRlKHVwcGVyKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKGxvd2VyID4gdXBwZXIpIHtcbiAgICAgICAgdmFyIHRlbXAgPSBsb3dlcjtcbiAgICAgICAgbG93ZXIgPSB1cHBlcjtcbiAgICAgICAgdXBwZXIgPSB0ZW1wO1xuICAgICAgfVxuICAgICAgaWYgKGZsb2F0aW5nIHx8IGxvd2VyICUgMSB8fCB1cHBlciAlIDEpIHtcbiAgICAgICAgdmFyIHJhbmQgPSBuYXRpdmVSYW5kb20oKTtcbiAgICAgICAgcmV0dXJuIG5hdGl2ZU1pbihsb3dlciArIChyYW5kICogKHVwcGVyIC0gbG93ZXIgKyBmcmVlUGFyc2VGbG9hdCgnMWUtJyArICgocmFuZCArICcnKS5sZW5ndGggLSAxKSkpKSwgdXBwZXIpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGJhc2VSYW5kb20obG93ZXIsIHVwcGVyKTtcbiAgICB9XG5cbiAgICAvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovXG5cbiAgICAvKipcbiAgICAgKiBDb252ZXJ0cyBgc3RyaW5nYCB0byBbY2FtZWwgY2FzZV0oaHR0cHM6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvQ2FtZWxDYXNlKS5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAzLjAuMFxuICAgICAqIEBjYXRlZ29yeSBTdHJpbmdcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gW3N0cmluZz0nJ10gVGhlIHN0cmluZyB0byBjb252ZXJ0LlxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IFJldHVybnMgdGhlIGNhbWVsIGNhc2VkIHN0cmluZy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5jYW1lbENhc2UoJ0ZvbyBCYXInKTtcbiAgICAgKiAvLyA9PiAnZm9vQmFyJ1xuICAgICAqXG4gICAgICogXy5jYW1lbENhc2UoJy0tZm9vLWJhci0tJyk7XG4gICAgICogLy8gPT4gJ2Zvb0JhcidcbiAgICAgKlxuICAgICAqIF8uY2FtZWxDYXNlKCdfX0ZPT19CQVJfXycpO1xuICAgICAqIC8vID0+ICdmb29CYXInXG4gICAgICovXG4gICAgdmFyIGNhbWVsQ2FzZSA9IGNyZWF0ZUNvbXBvdW5kZXIoZnVuY3Rpb24ocmVzdWx0LCB3b3JkLCBpbmRleCkge1xuICAgICAgd29yZCA9IHdvcmQudG9Mb3dlckNhc2UoKTtcbiAgICAgIHJldHVybiByZXN1bHQgKyAoaW5kZXggPyBjYXBpdGFsaXplKHdvcmQpIDogd29yZCk7XG4gICAgfSk7XG5cbiAgICAvKipcbiAgICAgKiBDb252ZXJ0cyB0aGUgZmlyc3QgY2hhcmFjdGVyIG9mIGBzdHJpbmdgIHRvIHVwcGVyIGNhc2UgYW5kIHRoZSByZW1haW5pbmdcbiAgICAgKiB0byBsb3dlciBjYXNlLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDMuMC4wXG4gICAgICogQGNhdGVnb3J5IFN0cmluZ1xuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBbc3RyaW5nPScnXSBUaGUgc3RyaW5nIHRvIGNhcGl0YWxpemUuXG4gICAgICogQHJldHVybnMge3N0cmluZ30gUmV0dXJucyB0aGUgY2FwaXRhbGl6ZWQgc3RyaW5nLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLmNhcGl0YWxpemUoJ0ZSRUQnKTtcbiAgICAgKiAvLyA9PiAnRnJlZCdcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBjYXBpdGFsaXplKHN0cmluZykge1xuICAgICAgcmV0dXJuIHVwcGVyRmlyc3QodG9TdHJpbmcoc3RyaW5nKS50b0xvd2VyQ2FzZSgpKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBEZWJ1cnJzIGBzdHJpbmdgIGJ5IGNvbnZlcnRpbmdcbiAgICAgKiBbTGF0aW4tMSBTdXBwbGVtZW50XShodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9MYXRpbi0xX1N1cHBsZW1lbnRfKFVuaWNvZGVfYmxvY2spI0NoYXJhY3Rlcl90YWJsZSlcbiAgICAgKiBhbmQgW0xhdGluIEV4dGVuZGVkLUFdKGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL0xhdGluX0V4dGVuZGVkLUEpXG4gICAgICogbGV0dGVycyB0byBiYXNpYyBMYXRpbiBsZXR0ZXJzIGFuZCByZW1vdmluZ1xuICAgICAqIFtjb21iaW5pbmcgZGlhY3JpdGljYWwgbWFya3NdKGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL0NvbWJpbmluZ19EaWFjcml0aWNhbF9NYXJrcykuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMy4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgU3RyaW5nXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IFtzdHJpbmc9JyddIFRoZSBzdHJpbmcgdG8gZGVidXJyLlxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IFJldHVybnMgdGhlIGRlYnVycmVkIHN0cmluZy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5kZWJ1cnIoJ2TDqWrDoCB2dScpO1xuICAgICAqIC8vID0+ICdkZWphIHZ1J1xuICAgICAqL1xuICAgIGZ1bmN0aW9uIGRlYnVycihzdHJpbmcpIHtcbiAgICAgIHN0cmluZyA9IHRvU3RyaW5nKHN0cmluZyk7XG4gICAgICByZXR1cm4gc3RyaW5nICYmIHN0cmluZy5yZXBsYWNlKHJlTGF0aW4sIGRlYnVyckxldHRlcikucmVwbGFjZShyZUNvbWJvTWFyaywgJycpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENoZWNrcyBpZiBgc3RyaW5nYCBlbmRzIHdpdGggdGhlIGdpdmVuIHRhcmdldCBzdHJpbmcuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMy4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgU3RyaW5nXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IFtzdHJpbmc9JyddIFRoZSBzdHJpbmcgdG8gaW5zcGVjdC5cbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gW3RhcmdldF0gVGhlIHN0cmluZyB0byBzZWFyY2ggZm9yLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbcG9zaXRpb249c3RyaW5nLmxlbmd0aF0gVGhlIHBvc2l0aW9uIHRvIHNlYXJjaCB1cCB0by5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHN0cmluZ2AgZW5kcyB3aXRoIGB0YXJnZXRgLFxuICAgICAqICBlbHNlIGBmYWxzZWAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uZW5kc1dpdGgoJ2FiYycsICdjJyk7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqXG4gICAgICogXy5lbmRzV2l0aCgnYWJjJywgJ2InKTtcbiAgICAgKiAvLyA9PiBmYWxzZVxuICAgICAqXG4gICAgICogXy5lbmRzV2l0aCgnYWJjJywgJ2InLCAyKTtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICovXG4gICAgZnVuY3Rpb24gZW5kc1dpdGgoc3RyaW5nLCB0YXJnZXQsIHBvc2l0aW9uKSB7XG4gICAgICBzdHJpbmcgPSB0b1N0cmluZyhzdHJpbmcpO1xuICAgICAgdGFyZ2V0ID0gYmFzZVRvU3RyaW5nKHRhcmdldCk7XG5cbiAgICAgIHZhciBsZW5ndGggPSBzdHJpbmcubGVuZ3RoO1xuICAgICAgcG9zaXRpb24gPSBwb3NpdGlvbiA9PT0gdW5kZWZpbmVkXG4gICAgICAgID8gbGVuZ3RoXG4gICAgICAgIDogYmFzZUNsYW1wKHRvSW50ZWdlcihwb3NpdGlvbiksIDAsIGxlbmd0aCk7XG5cbiAgICAgIHZhciBlbmQgPSBwb3NpdGlvbjtcbiAgICAgIHBvc2l0aW9uIC09IHRhcmdldC5sZW5ndGg7XG4gICAgICByZXR1cm4gcG9zaXRpb24gPj0gMCAmJiBzdHJpbmcuc2xpY2UocG9zaXRpb24sIGVuZCkgPT0gdGFyZ2V0O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENvbnZlcnRzIHRoZSBjaGFyYWN0ZXJzIFwiJlwiLCBcIjxcIiwgXCI+XCIsICdcIicsIGFuZCBcIidcIiBpbiBgc3RyaW5nYCB0byB0aGVpclxuICAgICAqIGNvcnJlc3BvbmRpbmcgSFRNTCBlbnRpdGllcy5cbiAgICAgKlxuICAgICAqICoqTm90ZToqKiBObyBvdGhlciBjaGFyYWN0ZXJzIGFyZSBlc2NhcGVkLiBUbyBlc2NhcGUgYWRkaXRpb25hbFxuICAgICAqIGNoYXJhY3RlcnMgdXNlIGEgdGhpcmQtcGFydHkgbGlicmFyeSBsaWtlIFtfaGVfXShodHRwczovL210aHMuYmUvaGUpLlxuICAgICAqXG4gICAgICogVGhvdWdoIHRoZSBcIj5cIiBjaGFyYWN0ZXIgaXMgZXNjYXBlZCBmb3Igc3ltbWV0cnksIGNoYXJhY3RlcnMgbGlrZVxuICAgICAqIFwiPlwiIGFuZCBcIi9cIiBkb24ndCBuZWVkIGVzY2FwaW5nIGluIEhUTUwgYW5kIGhhdmUgbm8gc3BlY2lhbCBtZWFuaW5nXG4gICAgICogdW5sZXNzIHRoZXkncmUgcGFydCBvZiBhIHRhZyBvciB1bnF1b3RlZCBhdHRyaWJ1dGUgdmFsdWUuIFNlZVxuICAgICAqIFtNYXRoaWFzIEJ5bmVucydzIGFydGljbGVdKGh0dHBzOi8vbWF0aGlhc2J5bmVucy5iZS9ub3Rlcy9hbWJpZ3VvdXMtYW1wZXJzYW5kcylcbiAgICAgKiAodW5kZXIgXCJzZW1pLXJlbGF0ZWQgZnVuIGZhY3RcIikgZm9yIG1vcmUgZGV0YWlscy5cbiAgICAgKlxuICAgICAqIFdoZW4gd29ya2luZyB3aXRoIEhUTUwgeW91IHNob3VsZCBhbHdheXNcbiAgICAgKiBbcXVvdGUgYXR0cmlidXRlIHZhbHVlc10oaHR0cDovL3dvbmtvLmNvbS9wb3N0L2h0bWwtZXNjYXBpbmcpIHRvIHJlZHVjZVxuICAgICAqIFhTUyB2ZWN0b3JzLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBzaW5jZSAwLjEuMFxuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQGNhdGVnb3J5IFN0cmluZ1xuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBbc3RyaW5nPScnXSBUaGUgc3RyaW5nIHRvIGVzY2FwZS5cbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfSBSZXR1cm5zIHRoZSBlc2NhcGVkIHN0cmluZy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5lc2NhcGUoJ2ZyZWQsIGJhcm5leSwgJiBwZWJibGVzJyk7XG4gICAgICogLy8gPT4gJ2ZyZWQsIGJhcm5leSwgJmFtcDsgcGViYmxlcydcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBlc2NhcGUoc3RyaW5nKSB7XG4gICAgICBzdHJpbmcgPSB0b1N0cmluZyhzdHJpbmcpO1xuICAgICAgcmV0dXJuIChzdHJpbmcgJiYgcmVIYXNVbmVzY2FwZWRIdG1sLnRlc3Qoc3RyaW5nKSlcbiAgICAgICAgPyBzdHJpbmcucmVwbGFjZShyZVVuZXNjYXBlZEh0bWwsIGVzY2FwZUh0bWxDaGFyKVxuICAgICAgICA6IHN0cmluZztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBFc2NhcGVzIHRoZSBgUmVnRXhwYCBzcGVjaWFsIGNoYXJhY3RlcnMgXCJeXCIsIFwiJFwiLCBcIlxcXCIsIFwiLlwiLCBcIipcIiwgXCIrXCIsXG4gICAgICogXCI/XCIsIFwiKFwiLCBcIilcIiwgXCJbXCIsIFwiXVwiLCBcIntcIiwgXCJ9XCIsIGFuZCBcInxcIiBpbiBgc3RyaW5nYC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAzLjAuMFxuICAgICAqIEBjYXRlZ29yeSBTdHJpbmdcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gW3N0cmluZz0nJ10gVGhlIHN0cmluZyB0byBlc2NhcGUuXG4gICAgICogQHJldHVybnMge3N0cmluZ30gUmV0dXJucyB0aGUgZXNjYXBlZCBzdHJpbmcuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uZXNjYXBlUmVnRXhwKCdbbG9kYXNoXShodHRwczovL2xvZGFzaC5jb20vKScpO1xuICAgICAqIC8vID0+ICdcXFtsb2Rhc2hcXF1cXChodHRwczovL2xvZGFzaFxcLmNvbS9cXCknXG4gICAgICovXG4gICAgZnVuY3Rpb24gZXNjYXBlUmVnRXhwKHN0cmluZykge1xuICAgICAgc3RyaW5nID0gdG9TdHJpbmcoc3RyaW5nKTtcbiAgICAgIHJldHVybiAoc3RyaW5nICYmIHJlSGFzUmVnRXhwQ2hhci50ZXN0KHN0cmluZykpXG4gICAgICAgID8gc3RyaW5nLnJlcGxhY2UocmVSZWdFeHBDaGFyLCAnXFxcXCQmJylcbiAgICAgICAgOiBzdHJpbmc7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ29udmVydHMgYHN0cmluZ2AgdG9cbiAgICAgKiBba2ViYWIgY2FzZV0oaHR0cHM6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvTGV0dGVyX2Nhc2UjU3BlY2lhbF9jYXNlX3N0eWxlcykuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMy4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgU3RyaW5nXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IFtzdHJpbmc9JyddIFRoZSBzdHJpbmcgdG8gY29udmVydC5cbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfSBSZXR1cm5zIHRoZSBrZWJhYiBjYXNlZCBzdHJpbmcuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8ua2ViYWJDYXNlKCdGb28gQmFyJyk7XG4gICAgICogLy8gPT4gJ2Zvby1iYXInXG4gICAgICpcbiAgICAgKiBfLmtlYmFiQ2FzZSgnZm9vQmFyJyk7XG4gICAgICogLy8gPT4gJ2Zvby1iYXInXG4gICAgICpcbiAgICAgKiBfLmtlYmFiQ2FzZSgnX19GT09fQkFSX18nKTtcbiAgICAgKiAvLyA9PiAnZm9vLWJhcidcbiAgICAgKi9cbiAgICB2YXIga2ViYWJDYXNlID0gY3JlYXRlQ29tcG91bmRlcihmdW5jdGlvbihyZXN1bHQsIHdvcmQsIGluZGV4KSB7XG4gICAgICByZXR1cm4gcmVzdWx0ICsgKGluZGV4ID8gJy0nIDogJycpICsgd29yZC50b0xvd2VyQ2FzZSgpO1xuICAgIH0pO1xuXG4gICAgLyoqXG4gICAgICogQ29udmVydHMgYHN0cmluZ2AsIGFzIHNwYWNlIHNlcGFyYXRlZCB3b3JkcywgdG8gbG93ZXIgY2FzZS5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjAuMFxuICAgICAqIEBjYXRlZ29yeSBTdHJpbmdcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gW3N0cmluZz0nJ10gVGhlIHN0cmluZyB0byBjb252ZXJ0LlxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IFJldHVybnMgdGhlIGxvd2VyIGNhc2VkIHN0cmluZy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5sb3dlckNhc2UoJy0tRm9vLUJhci0tJyk7XG4gICAgICogLy8gPT4gJ2ZvbyBiYXInXG4gICAgICpcbiAgICAgKiBfLmxvd2VyQ2FzZSgnZm9vQmFyJyk7XG4gICAgICogLy8gPT4gJ2ZvbyBiYXInXG4gICAgICpcbiAgICAgKiBfLmxvd2VyQ2FzZSgnX19GT09fQkFSX18nKTtcbiAgICAgKiAvLyA9PiAnZm9vIGJhcidcbiAgICAgKi9cbiAgICB2YXIgbG93ZXJDYXNlID0gY3JlYXRlQ29tcG91bmRlcihmdW5jdGlvbihyZXN1bHQsIHdvcmQsIGluZGV4KSB7XG4gICAgICByZXR1cm4gcmVzdWx0ICsgKGluZGV4ID8gJyAnIDogJycpICsgd29yZC50b0xvd2VyQ2FzZSgpO1xuICAgIH0pO1xuXG4gICAgLyoqXG4gICAgICogQ29udmVydHMgdGhlIGZpcnN0IGNoYXJhY3RlciBvZiBgc3RyaW5nYCB0byBsb3dlciBjYXNlLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMC4wXG4gICAgICogQGNhdGVnb3J5IFN0cmluZ1xuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBbc3RyaW5nPScnXSBUaGUgc3RyaW5nIHRvIGNvbnZlcnQuXG4gICAgICogQHJldHVybnMge3N0cmluZ30gUmV0dXJucyB0aGUgY29udmVydGVkIHN0cmluZy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5sb3dlckZpcnN0KCdGcmVkJyk7XG4gICAgICogLy8gPT4gJ2ZyZWQnXG4gICAgICpcbiAgICAgKiBfLmxvd2VyRmlyc3QoJ0ZSRUQnKTtcbiAgICAgKiAvLyA9PiAnZlJFRCdcbiAgICAgKi9cbiAgICB2YXIgbG93ZXJGaXJzdCA9IGNyZWF0ZUNhc2VGaXJzdCgndG9Mb3dlckNhc2UnKTtcblxuICAgIC8qKlxuICAgICAqIFBhZHMgYHN0cmluZ2Agb24gdGhlIGxlZnQgYW5kIHJpZ2h0IHNpZGVzIGlmIGl0J3Mgc2hvcnRlciB0aGFuIGBsZW5ndGhgLlxuICAgICAqIFBhZGRpbmcgY2hhcmFjdGVycyBhcmUgdHJ1bmNhdGVkIGlmIHRoZXkgY2FuJ3QgYmUgZXZlbmx5IGRpdmlkZWQgYnkgYGxlbmd0aGAuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMy4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgU3RyaW5nXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IFtzdHJpbmc9JyddIFRoZSBzdHJpbmcgdG8gcGFkLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbbGVuZ3RoPTBdIFRoZSBwYWRkaW5nIGxlbmd0aC5cbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gW2NoYXJzPScgJ10gVGhlIHN0cmluZyB1c2VkIGFzIHBhZGRpbmcuXG4gICAgICogQHJldHVybnMge3N0cmluZ30gUmV0dXJucyB0aGUgcGFkZGVkIHN0cmluZy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5wYWQoJ2FiYycsIDgpO1xuICAgICAqIC8vID0+ICcgIGFiYyAgICdcbiAgICAgKlxuICAgICAqIF8ucGFkKCdhYmMnLCA4LCAnXy0nKTtcbiAgICAgKiAvLyA9PiAnXy1hYmNfLV8nXG4gICAgICpcbiAgICAgKiBfLnBhZCgnYWJjJywgMyk7XG4gICAgICogLy8gPT4gJ2FiYydcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBwYWQoc3RyaW5nLCBsZW5ndGgsIGNoYXJzKSB7XG4gICAgICBzdHJpbmcgPSB0b1N0cmluZyhzdHJpbmcpO1xuICAgICAgbGVuZ3RoID0gdG9JbnRlZ2VyKGxlbmd0aCk7XG5cbiAgICAgIHZhciBzdHJMZW5ndGggPSBsZW5ndGggPyBzdHJpbmdTaXplKHN0cmluZykgOiAwO1xuICAgICAgaWYgKCFsZW5ndGggfHwgc3RyTGVuZ3RoID49IGxlbmd0aCkge1xuICAgICAgICByZXR1cm4gc3RyaW5nO1xuICAgICAgfVxuICAgICAgdmFyIG1pZCA9IChsZW5ndGggLSBzdHJMZW5ndGgpIC8gMjtcbiAgICAgIHJldHVybiAoXG4gICAgICAgIGNyZWF0ZVBhZGRpbmcobmF0aXZlRmxvb3IobWlkKSwgY2hhcnMpICtcbiAgICAgICAgc3RyaW5nICtcbiAgICAgICAgY3JlYXRlUGFkZGluZyhuYXRpdmVDZWlsKG1pZCksIGNoYXJzKVxuICAgICAgKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBQYWRzIGBzdHJpbmdgIG9uIHRoZSByaWdodCBzaWRlIGlmIGl0J3Mgc2hvcnRlciB0aGFuIGBsZW5ndGhgLiBQYWRkaW5nXG4gICAgICogY2hhcmFjdGVycyBhcmUgdHJ1bmNhdGVkIGlmIHRoZXkgZXhjZWVkIGBsZW5ndGhgLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMC4wXG4gICAgICogQGNhdGVnb3J5IFN0cmluZ1xuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBbc3RyaW5nPScnXSBUaGUgc3RyaW5nIHRvIHBhZC5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW2xlbmd0aD0wXSBUaGUgcGFkZGluZyBsZW5ndGguXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IFtjaGFycz0nICddIFRoZSBzdHJpbmcgdXNlZCBhcyBwYWRkaW5nLlxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IFJldHVybnMgdGhlIHBhZGRlZCBzdHJpbmcuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8ucGFkRW5kKCdhYmMnLCA2KTtcbiAgICAgKiAvLyA9PiAnYWJjICAgJ1xuICAgICAqXG4gICAgICogXy5wYWRFbmQoJ2FiYycsIDYsICdfLScpO1xuICAgICAqIC8vID0+ICdhYmNfLV8nXG4gICAgICpcbiAgICAgKiBfLnBhZEVuZCgnYWJjJywgMyk7XG4gICAgICogLy8gPT4gJ2FiYydcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBwYWRFbmQoc3RyaW5nLCBsZW5ndGgsIGNoYXJzKSB7XG4gICAgICBzdHJpbmcgPSB0b1N0cmluZyhzdHJpbmcpO1xuICAgICAgbGVuZ3RoID0gdG9JbnRlZ2VyKGxlbmd0aCk7XG5cbiAgICAgIHZhciBzdHJMZW5ndGggPSBsZW5ndGggPyBzdHJpbmdTaXplKHN0cmluZykgOiAwO1xuICAgICAgcmV0dXJuIChsZW5ndGggJiYgc3RyTGVuZ3RoIDwgbGVuZ3RoKVxuICAgICAgICA/IChzdHJpbmcgKyBjcmVhdGVQYWRkaW5nKGxlbmd0aCAtIHN0ckxlbmd0aCwgY2hhcnMpKVxuICAgICAgICA6IHN0cmluZztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBQYWRzIGBzdHJpbmdgIG9uIHRoZSBsZWZ0IHNpZGUgaWYgaXQncyBzaG9ydGVyIHRoYW4gYGxlbmd0aGAuIFBhZGRpbmdcbiAgICAgKiBjaGFyYWN0ZXJzIGFyZSB0cnVuY2F0ZWQgaWYgdGhleSBleGNlZWQgYGxlbmd0aGAuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgU3RyaW5nXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IFtzdHJpbmc9JyddIFRoZSBzdHJpbmcgdG8gcGFkLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbbGVuZ3RoPTBdIFRoZSBwYWRkaW5nIGxlbmd0aC5cbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gW2NoYXJzPScgJ10gVGhlIHN0cmluZyB1c2VkIGFzIHBhZGRpbmcuXG4gICAgICogQHJldHVybnMge3N0cmluZ30gUmV0dXJucyB0aGUgcGFkZGVkIHN0cmluZy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5wYWRTdGFydCgnYWJjJywgNik7XG4gICAgICogLy8gPT4gJyAgIGFiYydcbiAgICAgKlxuICAgICAqIF8ucGFkU3RhcnQoJ2FiYycsIDYsICdfLScpO1xuICAgICAqIC8vID0+ICdfLV9hYmMnXG4gICAgICpcbiAgICAgKiBfLnBhZFN0YXJ0KCdhYmMnLCAzKTtcbiAgICAgKiAvLyA9PiAnYWJjJ1xuICAgICAqL1xuICAgIGZ1bmN0aW9uIHBhZFN0YXJ0KHN0cmluZywgbGVuZ3RoLCBjaGFycykge1xuICAgICAgc3RyaW5nID0gdG9TdHJpbmcoc3RyaW5nKTtcbiAgICAgIGxlbmd0aCA9IHRvSW50ZWdlcihsZW5ndGgpO1xuXG4gICAgICB2YXIgc3RyTGVuZ3RoID0gbGVuZ3RoID8gc3RyaW5nU2l6ZShzdHJpbmcpIDogMDtcbiAgICAgIHJldHVybiAobGVuZ3RoICYmIHN0ckxlbmd0aCA8IGxlbmd0aClcbiAgICAgICAgPyAoY3JlYXRlUGFkZGluZyhsZW5ndGggLSBzdHJMZW5ndGgsIGNoYXJzKSArIHN0cmluZylcbiAgICAgICAgOiBzdHJpbmc7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ29udmVydHMgYHN0cmluZ2AgdG8gYW4gaW50ZWdlciBvZiB0aGUgc3BlY2lmaWVkIHJhZGl4LiBJZiBgcmFkaXhgIGlzXG4gICAgICogYHVuZGVmaW5lZGAgb3IgYDBgLCBhIGByYWRpeGAgb2YgYDEwYCBpcyB1c2VkIHVubGVzcyBgdmFsdWVgIGlzIGFcbiAgICAgKiBoZXhhZGVjaW1hbCwgaW4gd2hpY2ggY2FzZSBhIGByYWRpeGAgb2YgYDE2YCBpcyB1c2VkLlxuICAgICAqXG4gICAgICogKipOb3RlOioqIFRoaXMgbWV0aG9kIGFsaWducyB3aXRoIHRoZVxuICAgICAqIFtFUzUgaW1wbGVtZW50YXRpb25dKGh0dHBzOi8vZXM1LmdpdGh1Yi5pby8jeDE1LjEuMi4yKSBvZiBgcGFyc2VJbnRgLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDEuMS4wXG4gICAgICogQGNhdGVnb3J5IFN0cmluZ1xuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBzdHJpbmcgVGhlIHN0cmluZyB0byBjb252ZXJ0LlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbcmFkaXg9MTBdIFRoZSByYWRpeCB0byBpbnRlcnByZXQgYHZhbHVlYCBieS5cbiAgICAgKiBAcGFyYW0tIHtPYmplY3R9IFtndWFyZF0gRW5hYmxlcyB1c2UgYXMgYW4gaXRlcmF0ZWUgZm9yIG1ldGhvZHMgbGlrZSBgXy5tYXBgLlxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9IFJldHVybnMgdGhlIGNvbnZlcnRlZCBpbnRlZ2VyLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLnBhcnNlSW50KCcwOCcpO1xuICAgICAqIC8vID0+IDhcbiAgICAgKlxuICAgICAqIF8ubWFwKFsnNicsICcwOCcsICcxMCddLCBfLnBhcnNlSW50KTtcbiAgICAgKiAvLyA9PiBbNiwgOCwgMTBdXG4gICAgICovXG4gICAgZnVuY3Rpb24gcGFyc2VJbnQoc3RyaW5nLCByYWRpeCwgZ3VhcmQpIHtcbiAgICAgIGlmIChndWFyZCB8fCByYWRpeCA9PSBudWxsKSB7XG4gICAgICAgIHJhZGl4ID0gMDtcbiAgICAgIH0gZWxzZSBpZiAocmFkaXgpIHtcbiAgICAgICAgcmFkaXggPSArcmFkaXg7XG4gICAgICB9XG4gICAgICByZXR1cm4gbmF0aXZlUGFyc2VJbnQodG9TdHJpbmcoc3RyaW5nKS5yZXBsYWNlKHJlVHJpbVN0YXJ0LCAnJyksIHJhZGl4IHx8IDApO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJlcGVhdHMgdGhlIGdpdmVuIHN0cmluZyBgbmAgdGltZXMuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMy4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgU3RyaW5nXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IFtzdHJpbmc9JyddIFRoZSBzdHJpbmcgdG8gcmVwZWF0LlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbbj0xXSBUaGUgbnVtYmVyIG9mIHRpbWVzIHRvIHJlcGVhdCB0aGUgc3RyaW5nLlxuICAgICAqIEBwYXJhbS0ge09iamVjdH0gW2d1YXJkXSBFbmFibGVzIHVzZSBhcyBhbiBpdGVyYXRlZSBmb3IgbWV0aG9kcyBsaWtlIGBfLm1hcGAuXG4gICAgICogQHJldHVybnMge3N0cmluZ30gUmV0dXJucyB0aGUgcmVwZWF0ZWQgc3RyaW5nLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLnJlcGVhdCgnKicsIDMpO1xuICAgICAqIC8vID0+ICcqKionXG4gICAgICpcbiAgICAgKiBfLnJlcGVhdCgnYWJjJywgMik7XG4gICAgICogLy8gPT4gJ2FiY2FiYydcbiAgICAgKlxuICAgICAqIF8ucmVwZWF0KCdhYmMnLCAwKTtcbiAgICAgKiAvLyA9PiAnJ1xuICAgICAqL1xuICAgIGZ1bmN0aW9uIHJlcGVhdChzdHJpbmcsIG4sIGd1YXJkKSB7XG4gICAgICBpZiAoKGd1YXJkID8gaXNJdGVyYXRlZUNhbGwoc3RyaW5nLCBuLCBndWFyZCkgOiBuID09PSB1bmRlZmluZWQpKSB7XG4gICAgICAgIG4gPSAxO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgbiA9IHRvSW50ZWdlcihuKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBiYXNlUmVwZWF0KHRvU3RyaW5nKHN0cmluZyksIG4pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJlcGxhY2VzIG1hdGNoZXMgZm9yIGBwYXR0ZXJuYCBpbiBgc3RyaW5nYCB3aXRoIGByZXBsYWNlbWVudGAuXG4gICAgICpcbiAgICAgKiAqKk5vdGU6KiogVGhpcyBtZXRob2QgaXMgYmFzZWQgb25cbiAgICAgKiBbYFN0cmluZyNyZXBsYWNlYF0oaHR0cHM6Ly9tZG4uaW8vU3RyaW5nL3JlcGxhY2UpLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMC4wXG4gICAgICogQGNhdGVnb3J5IFN0cmluZ1xuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBbc3RyaW5nPScnXSBUaGUgc3RyaW5nIHRvIG1vZGlmeS5cbiAgICAgKiBAcGFyYW0ge1JlZ0V4cHxzdHJpbmd9IHBhdHRlcm4gVGhlIHBhdHRlcm4gdG8gcmVwbGFjZS5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufHN0cmluZ30gcmVwbGFjZW1lbnQgVGhlIG1hdGNoIHJlcGxhY2VtZW50LlxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IFJldHVybnMgdGhlIG1vZGlmaWVkIHN0cmluZy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5yZXBsYWNlKCdIaSBGcmVkJywgJ0ZyZWQnLCAnQmFybmV5Jyk7XG4gICAgICogLy8gPT4gJ0hpIEJhcm5leSdcbiAgICAgKi9cbiAgICBmdW5jdGlvbiByZXBsYWNlKCkge1xuICAgICAgdmFyIGFyZ3MgPSBhcmd1bWVudHMsXG4gICAgICAgICAgc3RyaW5nID0gdG9TdHJpbmcoYXJnc1swXSk7XG5cbiAgICAgIHJldHVybiBhcmdzLmxlbmd0aCA8IDMgPyBzdHJpbmcgOiBzdHJpbmcucmVwbGFjZShhcmdzWzFdLCBhcmdzWzJdKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDb252ZXJ0cyBgc3RyaW5nYCB0b1xuICAgICAqIFtzbmFrZSBjYXNlXShodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9TbmFrZV9jYXNlKS5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAzLjAuMFxuICAgICAqIEBjYXRlZ29yeSBTdHJpbmdcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gW3N0cmluZz0nJ10gVGhlIHN0cmluZyB0byBjb252ZXJ0LlxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IFJldHVybnMgdGhlIHNuYWtlIGNhc2VkIHN0cmluZy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5zbmFrZUNhc2UoJ0ZvbyBCYXInKTtcbiAgICAgKiAvLyA9PiAnZm9vX2JhcidcbiAgICAgKlxuICAgICAqIF8uc25ha2VDYXNlKCdmb29CYXInKTtcbiAgICAgKiAvLyA9PiAnZm9vX2JhcidcbiAgICAgKlxuICAgICAqIF8uc25ha2VDYXNlKCctLUZPTy1CQVItLScpO1xuICAgICAqIC8vID0+ICdmb29fYmFyJ1xuICAgICAqL1xuICAgIHZhciBzbmFrZUNhc2UgPSBjcmVhdGVDb21wb3VuZGVyKGZ1bmN0aW9uKHJlc3VsdCwgd29yZCwgaW5kZXgpIHtcbiAgICAgIHJldHVybiByZXN1bHQgKyAoaW5kZXggPyAnXycgOiAnJykgKyB3b3JkLnRvTG93ZXJDYXNlKCk7XG4gICAgfSk7XG5cbiAgICAvKipcbiAgICAgKiBTcGxpdHMgYHN0cmluZ2AgYnkgYHNlcGFyYXRvcmAuXG4gICAgICpcbiAgICAgKiAqKk5vdGU6KiogVGhpcyBtZXRob2QgaXMgYmFzZWQgb25cbiAgICAgKiBbYFN0cmluZyNzcGxpdGBdKGh0dHBzOi8vbWRuLmlvL1N0cmluZy9zcGxpdCkuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgU3RyaW5nXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IFtzdHJpbmc9JyddIFRoZSBzdHJpbmcgdG8gc3BsaXQuXG4gICAgICogQHBhcmFtIHtSZWdFeHB8c3RyaW5nfSBzZXBhcmF0b3IgVGhlIHNlcGFyYXRvciBwYXR0ZXJuIHRvIHNwbGl0IGJ5LlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbbGltaXRdIFRoZSBsZW5ndGggdG8gdHJ1bmNhdGUgcmVzdWx0cyB0by5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIHN0cmluZyBzZWdtZW50cy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5zcGxpdCgnYS1iLWMnLCAnLScsIDIpO1xuICAgICAqIC8vID0+IFsnYScsICdiJ11cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBzcGxpdChzdHJpbmcsIHNlcGFyYXRvciwgbGltaXQpIHtcbiAgICAgIGlmIChsaW1pdCAmJiB0eXBlb2YgbGltaXQgIT0gJ251bWJlcicgJiYgaXNJdGVyYXRlZUNhbGwoc3RyaW5nLCBzZXBhcmF0b3IsIGxpbWl0KSkge1xuICAgICAgICBzZXBhcmF0b3IgPSBsaW1pdCA9IHVuZGVmaW5lZDtcbiAgICAgIH1cbiAgICAgIGxpbWl0ID0gbGltaXQgPT09IHVuZGVmaW5lZCA/IE1BWF9BUlJBWV9MRU5HVEggOiBsaW1pdCA+Pj4gMDtcbiAgICAgIGlmICghbGltaXQpIHtcbiAgICAgICAgcmV0dXJuIFtdO1xuICAgICAgfVxuICAgICAgc3RyaW5nID0gdG9TdHJpbmcoc3RyaW5nKTtcbiAgICAgIGlmIChzdHJpbmcgJiYgKFxuICAgICAgICAgICAgdHlwZW9mIHNlcGFyYXRvciA9PSAnc3RyaW5nJyB8fFxuICAgICAgICAgICAgKHNlcGFyYXRvciAhPSBudWxsICYmICFpc1JlZ0V4cChzZXBhcmF0b3IpKVxuICAgICAgICAgICkpIHtcbiAgICAgICAgc2VwYXJhdG9yID0gYmFzZVRvU3RyaW5nKHNlcGFyYXRvcik7XG4gICAgICAgIGlmICghc2VwYXJhdG9yICYmIGhhc1VuaWNvZGUoc3RyaW5nKSkge1xuICAgICAgICAgIHJldHVybiBjYXN0U2xpY2Uoc3RyaW5nVG9BcnJheShzdHJpbmcpLCAwLCBsaW1pdCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiBzdHJpbmcuc3BsaXQoc2VwYXJhdG9yLCBsaW1pdCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ29udmVydHMgYHN0cmluZ2AgdG9cbiAgICAgKiBbc3RhcnQgY2FzZV0oaHR0cHM6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvTGV0dGVyX2Nhc2UjU3R5bGlzdGljX29yX3NwZWNpYWxpc2VkX3VzYWdlKS5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAzLjEuMFxuICAgICAqIEBjYXRlZ29yeSBTdHJpbmdcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gW3N0cmluZz0nJ10gVGhlIHN0cmluZyB0byBjb252ZXJ0LlxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IFJldHVybnMgdGhlIHN0YXJ0IGNhc2VkIHN0cmluZy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5zdGFydENhc2UoJy0tZm9vLWJhci0tJyk7XG4gICAgICogLy8gPT4gJ0ZvbyBCYXInXG4gICAgICpcbiAgICAgKiBfLnN0YXJ0Q2FzZSgnZm9vQmFyJyk7XG4gICAgICogLy8gPT4gJ0ZvbyBCYXInXG4gICAgICpcbiAgICAgKiBfLnN0YXJ0Q2FzZSgnX19GT09fQkFSX18nKTtcbiAgICAgKiAvLyA9PiAnRk9PIEJBUidcbiAgICAgKi9cbiAgICB2YXIgc3RhcnRDYXNlID0gY3JlYXRlQ29tcG91bmRlcihmdW5jdGlvbihyZXN1bHQsIHdvcmQsIGluZGV4KSB7XG4gICAgICByZXR1cm4gcmVzdWx0ICsgKGluZGV4ID8gJyAnIDogJycpICsgdXBwZXJGaXJzdCh3b3JkKTtcbiAgICB9KTtcblxuICAgIC8qKlxuICAgICAqIENoZWNrcyBpZiBgc3RyaW5nYCBzdGFydHMgd2l0aCB0aGUgZ2l2ZW4gdGFyZ2V0IHN0cmluZy5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAzLjAuMFxuICAgICAqIEBjYXRlZ29yeSBTdHJpbmdcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gW3N0cmluZz0nJ10gVGhlIHN0cmluZyB0byBpbnNwZWN0LlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBbdGFyZ2V0XSBUaGUgc3RyaW5nIHRvIHNlYXJjaCBmb3IuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtwb3NpdGlvbj0wXSBUaGUgcG9zaXRpb24gdG8gc2VhcmNoIGZyb20uXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGBzdHJpbmdgIHN0YXJ0cyB3aXRoIGB0YXJnZXRgLFxuICAgICAqICBlbHNlIGBmYWxzZWAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uc3RhcnRzV2l0aCgnYWJjJywgJ2EnKTtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICpcbiAgICAgKiBfLnN0YXJ0c1dpdGgoJ2FiYycsICdiJyk7XG4gICAgICogLy8gPT4gZmFsc2VcbiAgICAgKlxuICAgICAqIF8uc3RhcnRzV2l0aCgnYWJjJywgJ2InLCAxKTtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICovXG4gICAgZnVuY3Rpb24gc3RhcnRzV2l0aChzdHJpbmcsIHRhcmdldCwgcG9zaXRpb24pIHtcbiAgICAgIHN0cmluZyA9IHRvU3RyaW5nKHN0cmluZyk7XG4gICAgICBwb3NpdGlvbiA9IHBvc2l0aW9uID09IG51bGxcbiAgICAgICAgPyAwXG4gICAgICAgIDogYmFzZUNsYW1wKHRvSW50ZWdlcihwb3NpdGlvbiksIDAsIHN0cmluZy5sZW5ndGgpO1xuXG4gICAgICB0YXJnZXQgPSBiYXNlVG9TdHJpbmcodGFyZ2V0KTtcbiAgICAgIHJldHVybiBzdHJpbmcuc2xpY2UocG9zaXRpb24sIHBvc2l0aW9uICsgdGFyZ2V0Lmxlbmd0aCkgPT0gdGFyZ2V0O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBjb21waWxlZCB0ZW1wbGF0ZSBmdW5jdGlvbiB0aGF0IGNhbiBpbnRlcnBvbGF0ZSBkYXRhIHByb3BlcnRpZXNcbiAgICAgKiBpbiBcImludGVycG9sYXRlXCIgZGVsaW1pdGVycywgSFRNTC1lc2NhcGUgaW50ZXJwb2xhdGVkIGRhdGEgcHJvcGVydGllcyBpblxuICAgICAqIFwiZXNjYXBlXCIgZGVsaW1pdGVycywgYW5kIGV4ZWN1dGUgSmF2YVNjcmlwdCBpbiBcImV2YWx1YXRlXCIgZGVsaW1pdGVycy4gRGF0YVxuICAgICAqIHByb3BlcnRpZXMgbWF5IGJlIGFjY2Vzc2VkIGFzIGZyZWUgdmFyaWFibGVzIGluIHRoZSB0ZW1wbGF0ZS4gSWYgYSBzZXR0aW5nXG4gICAgICogb2JqZWN0IGlzIGdpdmVuLCBpdCB0YWtlcyBwcmVjZWRlbmNlIG92ZXIgYF8udGVtcGxhdGVTZXR0aW5nc2AgdmFsdWVzLlxuICAgICAqXG4gICAgICogKipOb3RlOioqIEluIHRoZSBkZXZlbG9wbWVudCBidWlsZCBgXy50ZW1wbGF0ZWAgdXRpbGl6ZXNcbiAgICAgKiBbc291cmNlVVJMc10oaHR0cDovL3d3dy5odG1sNXJvY2tzLmNvbS9lbi90dXRvcmlhbHMvZGV2ZWxvcGVydG9vbHMvc291cmNlbWFwcy8jdG9jLXNvdXJjZXVybClcbiAgICAgKiBmb3IgZWFzaWVyIGRlYnVnZ2luZy5cbiAgICAgKlxuICAgICAqIEZvciBtb3JlIGluZm9ybWF0aW9uIG9uIHByZWNvbXBpbGluZyB0ZW1wbGF0ZXMgc2VlXG4gICAgICogW2xvZGFzaCdzIGN1c3RvbSBidWlsZHMgZG9jdW1lbnRhdGlvbl0oaHR0cHM6Ly9sb2Rhc2guY29tL2N1c3RvbS1idWlsZHMpLlxuICAgICAqXG4gICAgICogRm9yIG1vcmUgaW5mb3JtYXRpb24gb24gQ2hyb21lIGV4dGVuc2lvbiBzYW5kYm94ZXMgc2VlXG4gICAgICogW0Nocm9tZSdzIGV4dGVuc2lvbnMgZG9jdW1lbnRhdGlvbl0oaHR0cHM6Ly9kZXZlbG9wZXIuY2hyb21lLmNvbS9leHRlbnNpb25zL3NhbmRib3hpbmdFdmFsKS5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAc2luY2UgMC4xLjBcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBjYXRlZ29yeSBTdHJpbmdcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gW3N0cmluZz0nJ10gVGhlIHRlbXBsYXRlIHN0cmluZy5cbiAgICAgKiBAcGFyYW0ge09iamVjdH0gW29wdGlvbnM9e31dIFRoZSBvcHRpb25zIG9iamVjdC5cbiAgICAgKiBAcGFyYW0ge1JlZ0V4cH0gW29wdGlvbnMuZXNjYXBlPV8udGVtcGxhdGVTZXR0aW5ncy5lc2NhcGVdXG4gICAgICogIFRoZSBIVE1MIFwiZXNjYXBlXCIgZGVsaW1pdGVyLlxuICAgICAqIEBwYXJhbSB7UmVnRXhwfSBbb3B0aW9ucy5ldmFsdWF0ZT1fLnRlbXBsYXRlU2V0dGluZ3MuZXZhbHVhdGVdXG4gICAgICogIFRoZSBcImV2YWx1YXRlXCIgZGVsaW1pdGVyLlxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBbb3B0aW9ucy5pbXBvcnRzPV8udGVtcGxhdGVTZXR0aW5ncy5pbXBvcnRzXVxuICAgICAqICBBbiBvYmplY3QgdG8gaW1wb3J0IGludG8gdGhlIHRlbXBsYXRlIGFzIGZyZWUgdmFyaWFibGVzLlxuICAgICAqIEBwYXJhbSB7UmVnRXhwfSBbb3B0aW9ucy5pbnRlcnBvbGF0ZT1fLnRlbXBsYXRlU2V0dGluZ3MuaW50ZXJwb2xhdGVdXG4gICAgICogIFRoZSBcImludGVycG9sYXRlXCIgZGVsaW1pdGVyLlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBbb3B0aW9ucy5zb3VyY2VVUkw9J2xvZGFzaC50ZW1wbGF0ZVNvdXJjZXNbbl0nXVxuICAgICAqICBUaGUgc291cmNlVVJMIG9mIHRoZSBjb21waWxlZCB0ZW1wbGF0ZS5cbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gW29wdGlvbnMudmFyaWFibGU9J29iaiddXG4gICAgICogIFRoZSBkYXRhIG9iamVjdCB2YXJpYWJsZSBuYW1lLlxuICAgICAqIEBwYXJhbS0ge09iamVjdH0gW2d1YXJkXSBFbmFibGVzIHVzZSBhcyBhbiBpdGVyYXRlZSBmb3IgbWV0aG9kcyBsaWtlIGBfLm1hcGAuXG4gICAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBjb21waWxlZCB0ZW1wbGF0ZSBmdW5jdGlvbi5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogLy8gVXNlIHRoZSBcImludGVycG9sYXRlXCIgZGVsaW1pdGVyIHRvIGNyZWF0ZSBhIGNvbXBpbGVkIHRlbXBsYXRlLlxuICAgICAqIHZhciBjb21waWxlZCA9IF8udGVtcGxhdGUoJ2hlbGxvIDwlPSB1c2VyICU+IScpO1xuICAgICAqIGNvbXBpbGVkKHsgJ3VzZXInOiAnZnJlZCcgfSk7XG4gICAgICogLy8gPT4gJ2hlbGxvIGZyZWQhJ1xuICAgICAqXG4gICAgICogLy8gVXNlIHRoZSBIVE1MIFwiZXNjYXBlXCIgZGVsaW1pdGVyIHRvIGVzY2FwZSBkYXRhIHByb3BlcnR5IHZhbHVlcy5cbiAgICAgKiB2YXIgY29tcGlsZWQgPSBfLnRlbXBsYXRlKCc8Yj48JS0gdmFsdWUgJT48L2I+Jyk7XG4gICAgICogY29tcGlsZWQoeyAndmFsdWUnOiAnPHNjcmlwdD4nIH0pO1xuICAgICAqIC8vID0+ICc8Yj4mbHQ7c2NyaXB0Jmd0OzwvYj4nXG4gICAgICpcbiAgICAgKiAvLyBVc2UgdGhlIFwiZXZhbHVhdGVcIiBkZWxpbWl0ZXIgdG8gZXhlY3V0ZSBKYXZhU2NyaXB0IGFuZCBnZW5lcmF0ZSBIVE1MLlxuICAgICAqIHZhciBjb21waWxlZCA9IF8udGVtcGxhdGUoJzwlIF8uZm9yRWFjaCh1c2VycywgZnVuY3Rpb24odXNlcikgeyAlPjxsaT48JS0gdXNlciAlPjwvbGk+PCUgfSk7ICU+Jyk7XG4gICAgICogY29tcGlsZWQoeyAndXNlcnMnOiBbJ2ZyZWQnLCAnYmFybmV5J10gfSk7XG4gICAgICogLy8gPT4gJzxsaT5mcmVkPC9saT48bGk+YmFybmV5PC9saT4nXG4gICAgICpcbiAgICAgKiAvLyBVc2UgdGhlIGludGVybmFsIGBwcmludGAgZnVuY3Rpb24gaW4gXCJldmFsdWF0ZVwiIGRlbGltaXRlcnMuXG4gICAgICogdmFyIGNvbXBpbGVkID0gXy50ZW1wbGF0ZSgnPCUgcHJpbnQoXCJoZWxsbyBcIiArIHVzZXIpOyAlPiEnKTtcbiAgICAgKiBjb21waWxlZCh7ICd1c2VyJzogJ2Jhcm5leScgfSk7XG4gICAgICogLy8gPT4gJ2hlbGxvIGJhcm5leSEnXG4gICAgICpcbiAgICAgKiAvLyBVc2UgdGhlIEVTIHRlbXBsYXRlIGxpdGVyYWwgZGVsaW1pdGVyIGFzIGFuIFwiaW50ZXJwb2xhdGVcIiBkZWxpbWl0ZXIuXG4gICAgICogLy8gRGlzYWJsZSBzdXBwb3J0IGJ5IHJlcGxhY2luZyB0aGUgXCJpbnRlcnBvbGF0ZVwiIGRlbGltaXRlci5cbiAgICAgKiB2YXIgY29tcGlsZWQgPSBfLnRlbXBsYXRlKCdoZWxsbyAkeyB1c2VyIH0hJyk7XG4gICAgICogY29tcGlsZWQoeyAndXNlcic6ICdwZWJibGVzJyB9KTtcbiAgICAgKiAvLyA9PiAnaGVsbG8gcGViYmxlcyEnXG4gICAgICpcbiAgICAgKiAvLyBVc2UgYmFja3NsYXNoZXMgdG8gdHJlYXQgZGVsaW1pdGVycyBhcyBwbGFpbiB0ZXh0LlxuICAgICAqIHZhciBjb21waWxlZCA9IF8udGVtcGxhdGUoJzwlPSBcIlxcXFw8JS0gdmFsdWUgJVxcXFw+XCIgJT4nKTtcbiAgICAgKiBjb21waWxlZCh7ICd2YWx1ZSc6ICdpZ25vcmVkJyB9KTtcbiAgICAgKiAvLyA9PiAnPCUtIHZhbHVlICU+J1xuICAgICAqXG4gICAgICogLy8gVXNlIHRoZSBgaW1wb3J0c2Agb3B0aW9uIHRvIGltcG9ydCBgalF1ZXJ5YCBhcyBganFgLlxuICAgICAqIHZhciB0ZXh0ID0gJzwlIGpxLmVhY2godXNlcnMsIGZ1bmN0aW9uKHVzZXIpIHsgJT48bGk+PCUtIHVzZXIgJT48L2xpPjwlIH0pOyAlPic7XG4gICAgICogdmFyIGNvbXBpbGVkID0gXy50ZW1wbGF0ZSh0ZXh0LCB7ICdpbXBvcnRzJzogeyAnanEnOiBqUXVlcnkgfSB9KTtcbiAgICAgKiBjb21waWxlZCh7ICd1c2Vycyc6IFsnZnJlZCcsICdiYXJuZXknXSB9KTtcbiAgICAgKiAvLyA9PiAnPGxpPmZyZWQ8L2xpPjxsaT5iYXJuZXk8L2xpPidcbiAgICAgKlxuICAgICAqIC8vIFVzZSB0aGUgYHNvdXJjZVVSTGAgb3B0aW9uIHRvIHNwZWNpZnkgYSBjdXN0b20gc291cmNlVVJMIGZvciB0aGUgdGVtcGxhdGUuXG4gICAgICogdmFyIGNvbXBpbGVkID0gXy50ZW1wbGF0ZSgnaGVsbG8gPCU9IHVzZXIgJT4hJywgeyAnc291cmNlVVJMJzogJy9iYXNpYy9ncmVldGluZy5qc3QnIH0pO1xuICAgICAqIGNvbXBpbGVkKGRhdGEpO1xuICAgICAqIC8vID0+IEZpbmQgdGhlIHNvdXJjZSBvZiBcImdyZWV0aW5nLmpzdFwiIHVuZGVyIHRoZSBTb3VyY2VzIHRhYiBvciBSZXNvdXJjZXMgcGFuZWwgb2YgdGhlIHdlYiBpbnNwZWN0b3IuXG4gICAgICpcbiAgICAgKiAvLyBVc2UgdGhlIGB2YXJpYWJsZWAgb3B0aW9uIHRvIGVuc3VyZSBhIHdpdGgtc3RhdGVtZW50IGlzbid0IHVzZWQgaW4gdGhlIGNvbXBpbGVkIHRlbXBsYXRlLlxuICAgICAqIHZhciBjb21waWxlZCA9IF8udGVtcGxhdGUoJ2hpIDwlPSBkYXRhLnVzZXIgJT4hJywgeyAndmFyaWFibGUnOiAnZGF0YScgfSk7XG4gICAgICogY29tcGlsZWQuc291cmNlO1xuICAgICAqIC8vID0+IGZ1bmN0aW9uKGRhdGEpIHtcbiAgICAgKiAvLyAgIHZhciBfX3QsIF9fcCA9ICcnO1xuICAgICAqIC8vICAgX19wICs9ICdoaSAnICsgKChfX3QgPSAoIGRhdGEudXNlciApKSA9PSBudWxsID8gJycgOiBfX3QpICsgJyEnO1xuICAgICAqIC8vICAgcmV0dXJuIF9fcDtcbiAgICAgKiAvLyB9XG4gICAgICpcbiAgICAgKiAvLyBVc2UgY3VzdG9tIHRlbXBsYXRlIGRlbGltaXRlcnMuXG4gICAgICogXy50ZW1wbGF0ZVNldHRpbmdzLmludGVycG9sYXRlID0gL3t7KFtcXHNcXFNdKz8pfX0vZztcbiAgICAgKiB2YXIgY29tcGlsZWQgPSBfLnRlbXBsYXRlKCdoZWxsbyB7eyB1c2VyIH19IScpO1xuICAgICAqIGNvbXBpbGVkKHsgJ3VzZXInOiAnbXVzdGFjaGUnIH0pO1xuICAgICAqIC8vID0+ICdoZWxsbyBtdXN0YWNoZSEnXG4gICAgICpcbiAgICAgKiAvLyBVc2UgdGhlIGBzb3VyY2VgIHByb3BlcnR5IHRvIGlubGluZSBjb21waWxlZCB0ZW1wbGF0ZXMgZm9yIG1lYW5pbmdmdWxcbiAgICAgKiAvLyBsaW5lIG51bWJlcnMgaW4gZXJyb3IgbWVzc2FnZXMgYW5kIHN0YWNrIHRyYWNlcy5cbiAgICAgKiBmcy53cml0ZUZpbGVTeW5jKHBhdGguam9pbihwcm9jZXNzLmN3ZCgpLCAnanN0LmpzJyksICdcXFxuICAgICAqICAgdmFyIEpTVCA9IHtcXFxuICAgICAqICAgICBcIm1haW5cIjogJyArIF8udGVtcGxhdGUobWFpblRleHQpLnNvdXJjZSArICdcXFxuICAgICAqICAgfTtcXFxuICAgICAqICcpO1xuICAgICAqL1xuICAgIGZ1bmN0aW9uIHRlbXBsYXRlKHN0cmluZywgb3B0aW9ucywgZ3VhcmQpIHtcbiAgICAgIC8vIEJhc2VkIG9uIEpvaG4gUmVzaWcncyBgdG1wbGAgaW1wbGVtZW50YXRpb25cbiAgICAgIC8vIChodHRwOi8vZWpvaG4ub3JnL2Jsb2cvamF2YXNjcmlwdC1taWNyby10ZW1wbGF0aW5nLylcbiAgICAgIC8vIGFuZCBMYXVyYSBEb2t0b3JvdmEncyBkb1QuanMgKGh0dHBzOi8vZ2l0aHViLmNvbS9vbGFkby9kb1QpLlxuICAgICAgdmFyIHNldHRpbmdzID0gbG9kYXNoLnRlbXBsYXRlU2V0dGluZ3M7XG5cbiAgICAgIGlmIChndWFyZCAmJiBpc0l0ZXJhdGVlQ2FsbChzdHJpbmcsIG9wdGlvbnMsIGd1YXJkKSkge1xuICAgICAgICBvcHRpb25zID0gdW5kZWZpbmVkO1xuICAgICAgfVxuICAgICAgc3RyaW5nID0gdG9TdHJpbmcoc3RyaW5nKTtcbiAgICAgIG9wdGlvbnMgPSBhc3NpZ25JbldpdGgoe30sIG9wdGlvbnMsIHNldHRpbmdzLCBjdXN0b21EZWZhdWx0c0Fzc2lnbkluKTtcblxuICAgICAgdmFyIGltcG9ydHMgPSBhc3NpZ25JbldpdGgoe30sIG9wdGlvbnMuaW1wb3J0cywgc2V0dGluZ3MuaW1wb3J0cywgY3VzdG9tRGVmYXVsdHNBc3NpZ25JbiksXG4gICAgICAgICAgaW1wb3J0c0tleXMgPSBrZXlzKGltcG9ydHMpLFxuICAgICAgICAgIGltcG9ydHNWYWx1ZXMgPSBiYXNlVmFsdWVzKGltcG9ydHMsIGltcG9ydHNLZXlzKTtcblxuICAgICAgdmFyIGlzRXNjYXBpbmcsXG4gICAgICAgICAgaXNFdmFsdWF0aW5nLFxuICAgICAgICAgIGluZGV4ID0gMCxcbiAgICAgICAgICBpbnRlcnBvbGF0ZSA9IG9wdGlvbnMuaW50ZXJwb2xhdGUgfHwgcmVOb01hdGNoLFxuICAgICAgICAgIHNvdXJjZSA9IFwiX19wICs9ICdcIjtcblxuICAgICAgLy8gQ29tcGlsZSB0aGUgcmVnZXhwIHRvIG1hdGNoIGVhY2ggZGVsaW1pdGVyLlxuICAgICAgdmFyIHJlRGVsaW1pdGVycyA9IFJlZ0V4cChcbiAgICAgICAgKG9wdGlvbnMuZXNjYXBlIHx8IHJlTm9NYXRjaCkuc291cmNlICsgJ3wnICtcbiAgICAgICAgaW50ZXJwb2xhdGUuc291cmNlICsgJ3wnICtcbiAgICAgICAgKGludGVycG9sYXRlID09PSByZUludGVycG9sYXRlID8gcmVFc1RlbXBsYXRlIDogcmVOb01hdGNoKS5zb3VyY2UgKyAnfCcgK1xuICAgICAgICAob3B0aW9ucy5ldmFsdWF0ZSB8fCByZU5vTWF0Y2gpLnNvdXJjZSArICd8JCdcbiAgICAgICwgJ2cnKTtcblxuICAgICAgLy8gVXNlIGEgc291cmNlVVJMIGZvciBlYXNpZXIgZGVidWdnaW5nLlxuICAgICAgLy8gVGhlIHNvdXJjZVVSTCBnZXRzIGluamVjdGVkIGludG8gdGhlIHNvdXJjZSB0aGF0J3MgZXZhbC1lZCwgc28gYmUgY2FyZWZ1bFxuICAgICAgLy8gdG8gbm9ybWFsaXplIGFsbCBraW5kcyBvZiB3aGl0ZXNwYWNlLCBzbyBlLmcuIG5ld2xpbmVzIChhbmQgdW5pY29kZSB2ZXJzaW9ucyBvZiBpdCkgY2FuJ3Qgc25lYWsgaW5cbiAgICAgIC8vIGFuZCBlc2NhcGUgdGhlIGNvbW1lbnQsIHRodXMgaW5qZWN0aW5nIGNvZGUgdGhhdCBnZXRzIGV2YWxlZC5cbiAgICAgIHZhciBzb3VyY2VVUkwgPSAnLy8jIHNvdXJjZVVSTD0nICtcbiAgICAgICAgKGhhc093blByb3BlcnR5LmNhbGwob3B0aW9ucywgJ3NvdXJjZVVSTCcpXG4gICAgICAgICAgPyAob3B0aW9ucy5zb3VyY2VVUkwgKyAnJykucmVwbGFjZSgvXFxzL2csICcgJylcbiAgICAgICAgICA6ICgnbG9kYXNoLnRlbXBsYXRlU291cmNlc1snICsgKCsrdGVtcGxhdGVDb3VudGVyKSArICddJylcbiAgICAgICAgKSArICdcXG4nO1xuXG4gICAgICBzdHJpbmcucmVwbGFjZShyZURlbGltaXRlcnMsIGZ1bmN0aW9uKG1hdGNoLCBlc2NhcGVWYWx1ZSwgaW50ZXJwb2xhdGVWYWx1ZSwgZXNUZW1wbGF0ZVZhbHVlLCBldmFsdWF0ZVZhbHVlLCBvZmZzZXQpIHtcbiAgICAgICAgaW50ZXJwb2xhdGVWYWx1ZSB8fCAoaW50ZXJwb2xhdGVWYWx1ZSA9IGVzVGVtcGxhdGVWYWx1ZSk7XG5cbiAgICAgICAgLy8gRXNjYXBlIGNoYXJhY3RlcnMgdGhhdCBjYW4ndCBiZSBpbmNsdWRlZCBpbiBzdHJpbmcgbGl0ZXJhbHMuXG4gICAgICAgIHNvdXJjZSArPSBzdHJpbmcuc2xpY2UoaW5kZXgsIG9mZnNldCkucmVwbGFjZShyZVVuZXNjYXBlZFN0cmluZywgZXNjYXBlU3RyaW5nQ2hhcik7XG5cbiAgICAgICAgLy8gUmVwbGFjZSBkZWxpbWl0ZXJzIHdpdGggc25pcHBldHMuXG4gICAgICAgIGlmIChlc2NhcGVWYWx1ZSkge1xuICAgICAgICAgIGlzRXNjYXBpbmcgPSB0cnVlO1xuICAgICAgICAgIHNvdXJjZSArPSBcIicgK1xcbl9fZShcIiArIGVzY2FwZVZhbHVlICsgXCIpICtcXG4nXCI7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGV2YWx1YXRlVmFsdWUpIHtcbiAgICAgICAgICBpc0V2YWx1YXRpbmcgPSB0cnVlO1xuICAgICAgICAgIHNvdXJjZSArPSBcIic7XFxuXCIgKyBldmFsdWF0ZVZhbHVlICsgXCI7XFxuX19wICs9ICdcIjtcbiAgICAgICAgfVxuICAgICAgICBpZiAoaW50ZXJwb2xhdGVWYWx1ZSkge1xuICAgICAgICAgIHNvdXJjZSArPSBcIicgK1xcbigoX190ID0gKFwiICsgaW50ZXJwb2xhdGVWYWx1ZSArIFwiKSkgPT0gbnVsbCA/ICcnIDogX190KSArXFxuJ1wiO1xuICAgICAgICB9XG4gICAgICAgIGluZGV4ID0gb2Zmc2V0ICsgbWF0Y2gubGVuZ3RoO1xuXG4gICAgICAgIC8vIFRoZSBKUyBlbmdpbmUgZW1iZWRkZWQgaW4gQWRvYmUgcHJvZHVjdHMgbmVlZHMgYG1hdGNoYCByZXR1cm5lZCBpblxuICAgICAgICAvLyBvcmRlciB0byBwcm9kdWNlIHRoZSBjb3JyZWN0IGBvZmZzZXRgIHZhbHVlLlxuICAgICAgICByZXR1cm4gbWF0Y2g7XG4gICAgICB9KTtcblxuICAgICAgc291cmNlICs9IFwiJztcXG5cIjtcblxuICAgICAgLy8gSWYgYHZhcmlhYmxlYCBpcyBub3Qgc3BlY2lmaWVkIHdyYXAgYSB3aXRoLXN0YXRlbWVudCBhcm91bmQgdGhlIGdlbmVyYXRlZFxuICAgICAgLy8gY29kZSB0byBhZGQgdGhlIGRhdGEgb2JqZWN0IHRvIHRoZSB0b3Agb2YgdGhlIHNjb3BlIGNoYWluLlxuICAgICAgdmFyIHZhcmlhYmxlID0gaGFzT3duUHJvcGVydHkuY2FsbChvcHRpb25zLCAndmFyaWFibGUnKSAmJiBvcHRpb25zLnZhcmlhYmxlO1xuICAgICAgaWYgKCF2YXJpYWJsZSkge1xuICAgICAgICBzb3VyY2UgPSAnd2l0aCAob2JqKSB7XFxuJyArIHNvdXJjZSArICdcXG59XFxuJztcbiAgICAgIH1cbiAgICAgIC8vIFRocm93IGFuIGVycm9yIGlmIGEgZm9yYmlkZGVuIGNoYXJhY3RlciB3YXMgZm91bmQgaW4gYHZhcmlhYmxlYCwgdG8gcHJldmVudFxuICAgICAgLy8gcG90ZW50aWFsIGNvbW1hbmQgaW5qZWN0aW9uIGF0dGFja3MuXG4gICAgICBlbHNlIGlmIChyZUZvcmJpZGRlbklkZW50aWZpZXJDaGFycy50ZXN0KHZhcmlhYmxlKSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoSU5WQUxJRF9URU1QTF9WQVJfRVJST1JfVEVYVCk7XG4gICAgICB9XG5cbiAgICAgIC8vIENsZWFudXAgY29kZSBieSBzdHJpcHBpbmcgZW1wdHkgc3RyaW5ncy5cbiAgICAgIHNvdXJjZSA9IChpc0V2YWx1YXRpbmcgPyBzb3VyY2UucmVwbGFjZShyZUVtcHR5U3RyaW5nTGVhZGluZywgJycpIDogc291cmNlKVxuICAgICAgICAucmVwbGFjZShyZUVtcHR5U3RyaW5nTWlkZGxlLCAnJDEnKVxuICAgICAgICAucmVwbGFjZShyZUVtcHR5U3RyaW5nVHJhaWxpbmcsICckMTsnKTtcblxuICAgICAgLy8gRnJhbWUgY29kZSBhcyB0aGUgZnVuY3Rpb24gYm9keS5cbiAgICAgIHNvdXJjZSA9ICdmdW5jdGlvbignICsgKHZhcmlhYmxlIHx8ICdvYmonKSArICcpIHtcXG4nICtcbiAgICAgICAgKHZhcmlhYmxlXG4gICAgICAgICAgPyAnJ1xuICAgICAgICAgIDogJ29iaiB8fCAob2JqID0ge30pO1xcbidcbiAgICAgICAgKSArXG4gICAgICAgIFwidmFyIF9fdCwgX19wID0gJydcIiArXG4gICAgICAgIChpc0VzY2FwaW5nXG4gICAgICAgICAgID8gJywgX19lID0gXy5lc2NhcGUnXG4gICAgICAgICAgIDogJydcbiAgICAgICAgKSArXG4gICAgICAgIChpc0V2YWx1YXRpbmdcbiAgICAgICAgICA/ICcsIF9faiA9IEFycmF5LnByb3RvdHlwZS5qb2luO1xcbicgK1xuICAgICAgICAgICAgXCJmdW5jdGlvbiBwcmludCgpIHsgX19wICs9IF9fai5jYWxsKGFyZ3VtZW50cywgJycpIH1cXG5cIlxuICAgICAgICAgIDogJztcXG4nXG4gICAgICAgICkgK1xuICAgICAgICBzb3VyY2UgK1xuICAgICAgICAncmV0dXJuIF9fcFxcbn0nO1xuXG4gICAgICB2YXIgcmVzdWx0ID0gYXR0ZW1wdChmdW5jdGlvbigpIHtcbiAgICAgICAgcmV0dXJuIEZ1bmN0aW9uKGltcG9ydHNLZXlzLCBzb3VyY2VVUkwgKyAncmV0dXJuICcgKyBzb3VyY2UpXG4gICAgICAgICAgLmFwcGx5KHVuZGVmaW5lZCwgaW1wb3J0c1ZhbHVlcyk7XG4gICAgICB9KTtcblxuICAgICAgLy8gUHJvdmlkZSB0aGUgY29tcGlsZWQgZnVuY3Rpb24ncyBzb3VyY2UgYnkgaXRzIGB0b1N0cmluZ2AgbWV0aG9kIG9yXG4gICAgICAvLyB0aGUgYHNvdXJjZWAgcHJvcGVydHkgYXMgYSBjb252ZW5pZW5jZSBmb3IgaW5saW5pbmcgY29tcGlsZWQgdGVtcGxhdGVzLlxuICAgICAgcmVzdWx0LnNvdXJjZSA9IHNvdXJjZTtcbiAgICAgIGlmIChpc0Vycm9yKHJlc3VsdCkpIHtcbiAgICAgICAgdGhyb3cgcmVzdWx0O1xuICAgICAgfVxuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDb252ZXJ0cyBgc3RyaW5nYCwgYXMgYSB3aG9sZSwgdG8gbG93ZXIgY2FzZSBqdXN0IGxpa2VcbiAgICAgKiBbU3RyaW5nI3RvTG93ZXJDYXNlXShodHRwczovL21kbi5pby90b0xvd2VyQ2FzZSkuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgU3RyaW5nXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IFtzdHJpbmc9JyddIFRoZSBzdHJpbmcgdG8gY29udmVydC5cbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfSBSZXR1cm5zIHRoZSBsb3dlciBjYXNlZCBzdHJpbmcuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8udG9Mb3dlcignLS1Gb28tQmFyLS0nKTtcbiAgICAgKiAvLyA9PiAnLS1mb28tYmFyLS0nXG4gICAgICpcbiAgICAgKiBfLnRvTG93ZXIoJ2Zvb0JhcicpO1xuICAgICAqIC8vID0+ICdmb29iYXInXG4gICAgICpcbiAgICAgKiBfLnRvTG93ZXIoJ19fRk9PX0JBUl9fJyk7XG4gICAgICogLy8gPT4gJ19fZm9vX2Jhcl9fJ1xuICAgICAqL1xuICAgIGZ1bmN0aW9uIHRvTG93ZXIodmFsdWUpIHtcbiAgICAgIHJldHVybiB0b1N0cmluZyh2YWx1ZSkudG9Mb3dlckNhc2UoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDb252ZXJ0cyBgc3RyaW5nYCwgYXMgYSB3aG9sZSwgdG8gdXBwZXIgY2FzZSBqdXN0IGxpa2VcbiAgICAgKiBbU3RyaW5nI3RvVXBwZXJDYXNlXShodHRwczovL21kbi5pby90b1VwcGVyQ2FzZSkuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgU3RyaW5nXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IFtzdHJpbmc9JyddIFRoZSBzdHJpbmcgdG8gY29udmVydC5cbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfSBSZXR1cm5zIHRoZSB1cHBlciBjYXNlZCBzdHJpbmcuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8udG9VcHBlcignLS1mb28tYmFyLS0nKTtcbiAgICAgKiAvLyA9PiAnLS1GT08tQkFSLS0nXG4gICAgICpcbiAgICAgKiBfLnRvVXBwZXIoJ2Zvb0JhcicpO1xuICAgICAqIC8vID0+ICdGT09CQVInXG4gICAgICpcbiAgICAgKiBfLnRvVXBwZXIoJ19fZm9vX2Jhcl9fJyk7XG4gICAgICogLy8gPT4gJ19fRk9PX0JBUl9fJ1xuICAgICAqL1xuICAgIGZ1bmN0aW9uIHRvVXBwZXIodmFsdWUpIHtcbiAgICAgIHJldHVybiB0b1N0cmluZyh2YWx1ZSkudG9VcHBlckNhc2UoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZW1vdmVzIGxlYWRpbmcgYW5kIHRyYWlsaW5nIHdoaXRlc3BhY2Ugb3Igc3BlY2lmaWVkIGNoYXJhY3RlcnMgZnJvbSBgc3RyaW5nYC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAzLjAuMFxuICAgICAqIEBjYXRlZ29yeSBTdHJpbmdcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gW3N0cmluZz0nJ10gVGhlIHN0cmluZyB0byB0cmltLlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBbY2hhcnM9d2hpdGVzcGFjZV0gVGhlIGNoYXJhY3RlcnMgdG8gdHJpbS5cbiAgICAgKiBAcGFyYW0tIHtPYmplY3R9IFtndWFyZF0gRW5hYmxlcyB1c2UgYXMgYW4gaXRlcmF0ZWUgZm9yIG1ldGhvZHMgbGlrZSBgXy5tYXBgLlxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IFJldHVybnMgdGhlIHRyaW1tZWQgc3RyaW5nLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLnRyaW0oJyAgYWJjICAnKTtcbiAgICAgKiAvLyA9PiAnYWJjJ1xuICAgICAqXG4gICAgICogXy50cmltKCctXy1hYmMtXy0nLCAnXy0nKTtcbiAgICAgKiAvLyA9PiAnYWJjJ1xuICAgICAqXG4gICAgICogXy5tYXAoWycgIGZvbyAgJywgJyAgYmFyICAnXSwgXy50cmltKTtcbiAgICAgKiAvLyA9PiBbJ2ZvbycsICdiYXInXVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIHRyaW0oc3RyaW5nLCBjaGFycywgZ3VhcmQpIHtcbiAgICAgIHN0cmluZyA9IHRvU3RyaW5nKHN0cmluZyk7XG4gICAgICBpZiAoc3RyaW5nICYmIChndWFyZCB8fCBjaGFycyA9PT0gdW5kZWZpbmVkKSkge1xuICAgICAgICByZXR1cm4gYmFzZVRyaW0oc3RyaW5nKTtcbiAgICAgIH1cbiAgICAgIGlmICghc3RyaW5nIHx8ICEoY2hhcnMgPSBiYXNlVG9TdHJpbmcoY2hhcnMpKSkge1xuICAgICAgICByZXR1cm4gc3RyaW5nO1xuICAgICAgfVxuICAgICAgdmFyIHN0clN5bWJvbHMgPSBzdHJpbmdUb0FycmF5KHN0cmluZyksXG4gICAgICAgICAgY2hyU3ltYm9scyA9IHN0cmluZ1RvQXJyYXkoY2hhcnMpLFxuICAgICAgICAgIHN0YXJ0ID0gY2hhcnNTdGFydEluZGV4KHN0clN5bWJvbHMsIGNoclN5bWJvbHMpLFxuICAgICAgICAgIGVuZCA9IGNoYXJzRW5kSW5kZXgoc3RyU3ltYm9scywgY2hyU3ltYm9scykgKyAxO1xuXG4gICAgICByZXR1cm4gY2FzdFNsaWNlKHN0clN5bWJvbHMsIHN0YXJ0LCBlbmQpLmpvaW4oJycpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJlbW92ZXMgdHJhaWxpbmcgd2hpdGVzcGFjZSBvciBzcGVjaWZpZWQgY2hhcmFjdGVycyBmcm9tIGBzdHJpbmdgLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMC4wXG4gICAgICogQGNhdGVnb3J5IFN0cmluZ1xuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBbc3RyaW5nPScnXSBUaGUgc3RyaW5nIHRvIHRyaW0uXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IFtjaGFycz13aGl0ZXNwYWNlXSBUaGUgY2hhcmFjdGVycyB0byB0cmltLlxuICAgICAqIEBwYXJhbS0ge09iamVjdH0gW2d1YXJkXSBFbmFibGVzIHVzZSBhcyBhbiBpdGVyYXRlZSBmb3IgbWV0aG9kcyBsaWtlIGBfLm1hcGAuXG4gICAgICogQHJldHVybnMge3N0cmluZ30gUmV0dXJucyB0aGUgdHJpbW1lZCBzdHJpbmcuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8udHJpbUVuZCgnICBhYmMgICcpO1xuICAgICAqIC8vID0+ICcgIGFiYydcbiAgICAgKlxuICAgICAqIF8udHJpbUVuZCgnLV8tYWJjLV8tJywgJ18tJyk7XG4gICAgICogLy8gPT4gJy1fLWFiYydcbiAgICAgKi9cbiAgICBmdW5jdGlvbiB0cmltRW5kKHN0cmluZywgY2hhcnMsIGd1YXJkKSB7XG4gICAgICBzdHJpbmcgPSB0b1N0cmluZyhzdHJpbmcpO1xuICAgICAgaWYgKHN0cmluZyAmJiAoZ3VhcmQgfHwgY2hhcnMgPT09IHVuZGVmaW5lZCkpIHtcbiAgICAgICAgcmV0dXJuIHN0cmluZy5zbGljZSgwLCB0cmltbWVkRW5kSW5kZXgoc3RyaW5nKSArIDEpO1xuICAgICAgfVxuICAgICAgaWYgKCFzdHJpbmcgfHwgIShjaGFycyA9IGJhc2VUb1N0cmluZyhjaGFycykpKSB7XG4gICAgICAgIHJldHVybiBzdHJpbmc7XG4gICAgICB9XG4gICAgICB2YXIgc3RyU3ltYm9scyA9IHN0cmluZ1RvQXJyYXkoc3RyaW5nKSxcbiAgICAgICAgICBlbmQgPSBjaGFyc0VuZEluZGV4KHN0clN5bWJvbHMsIHN0cmluZ1RvQXJyYXkoY2hhcnMpKSArIDE7XG5cbiAgICAgIHJldHVybiBjYXN0U2xpY2Uoc3RyU3ltYm9scywgMCwgZW5kKS5qb2luKCcnKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZW1vdmVzIGxlYWRpbmcgd2hpdGVzcGFjZSBvciBzcGVjaWZpZWQgY2hhcmFjdGVycyBmcm9tIGBzdHJpbmdgLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMC4wXG4gICAgICogQGNhdGVnb3J5IFN0cmluZ1xuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBbc3RyaW5nPScnXSBUaGUgc3RyaW5nIHRvIHRyaW0uXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IFtjaGFycz13aGl0ZXNwYWNlXSBUaGUgY2hhcmFjdGVycyB0byB0cmltLlxuICAgICAqIEBwYXJhbS0ge09iamVjdH0gW2d1YXJkXSBFbmFibGVzIHVzZSBhcyBhbiBpdGVyYXRlZSBmb3IgbWV0aG9kcyBsaWtlIGBfLm1hcGAuXG4gICAgICogQHJldHVybnMge3N0cmluZ30gUmV0dXJucyB0aGUgdHJpbW1lZCBzdHJpbmcuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8udHJpbVN0YXJ0KCcgIGFiYyAgJyk7XG4gICAgICogLy8gPT4gJ2FiYyAgJ1xuICAgICAqXG4gICAgICogXy50cmltU3RhcnQoJy1fLWFiYy1fLScsICdfLScpO1xuICAgICAqIC8vID0+ICdhYmMtXy0nXG4gICAgICovXG4gICAgZnVuY3Rpb24gdHJpbVN0YXJ0KHN0cmluZywgY2hhcnMsIGd1YXJkKSB7XG4gICAgICBzdHJpbmcgPSB0b1N0cmluZyhzdHJpbmcpO1xuICAgICAgaWYgKHN0cmluZyAmJiAoZ3VhcmQgfHwgY2hhcnMgPT09IHVuZGVmaW5lZCkpIHtcbiAgICAgICAgcmV0dXJuIHN0cmluZy5yZXBsYWNlKHJlVHJpbVN0YXJ0LCAnJyk7XG4gICAgICB9XG4gICAgICBpZiAoIXN0cmluZyB8fCAhKGNoYXJzID0gYmFzZVRvU3RyaW5nKGNoYXJzKSkpIHtcbiAgICAgICAgcmV0dXJuIHN0cmluZztcbiAgICAgIH1cbiAgICAgIHZhciBzdHJTeW1ib2xzID0gc3RyaW5nVG9BcnJheShzdHJpbmcpLFxuICAgICAgICAgIHN0YXJ0ID0gY2hhcnNTdGFydEluZGV4KHN0clN5bWJvbHMsIHN0cmluZ1RvQXJyYXkoY2hhcnMpKTtcblxuICAgICAgcmV0dXJuIGNhc3RTbGljZShzdHJTeW1ib2xzLCBzdGFydCkuam9pbignJyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVHJ1bmNhdGVzIGBzdHJpbmdgIGlmIGl0J3MgbG9uZ2VyIHRoYW4gdGhlIGdpdmVuIG1heGltdW0gc3RyaW5nIGxlbmd0aC5cbiAgICAgKiBUaGUgbGFzdCBjaGFyYWN0ZXJzIG9mIHRoZSB0cnVuY2F0ZWQgc3RyaW5nIGFyZSByZXBsYWNlZCB3aXRoIHRoZSBvbWlzc2lvblxuICAgICAqIHN0cmluZyB3aGljaCBkZWZhdWx0cyB0byBcIi4uLlwiLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMC4wXG4gICAgICogQGNhdGVnb3J5IFN0cmluZ1xuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBbc3RyaW5nPScnXSBUaGUgc3RyaW5nIHRvIHRydW5jYXRlLlxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBbb3B0aW9ucz17fV0gVGhlIG9wdGlvbnMgb2JqZWN0LlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbb3B0aW9ucy5sZW5ndGg9MzBdIFRoZSBtYXhpbXVtIHN0cmluZyBsZW5ndGguXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IFtvcHRpb25zLm9taXNzaW9uPScuLi4nXSBUaGUgc3RyaW5nIHRvIGluZGljYXRlIHRleHQgaXMgb21pdHRlZC5cbiAgICAgKiBAcGFyYW0ge1JlZ0V4cHxzdHJpbmd9IFtvcHRpb25zLnNlcGFyYXRvcl0gVGhlIHNlcGFyYXRvciBwYXR0ZXJuIHRvIHRydW5jYXRlIHRvLlxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IFJldHVybnMgdGhlIHRydW5jYXRlZCBzdHJpbmcuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8udHJ1bmNhdGUoJ2hpLWRpZGRseS1obyB0aGVyZSwgbmVpZ2hib3Jpbm8nKTtcbiAgICAgKiAvLyA9PiAnaGktZGlkZGx5LWhvIHRoZXJlLCBuZWlnaGJvLi4uJ1xuICAgICAqXG4gICAgICogXy50cnVuY2F0ZSgnaGktZGlkZGx5LWhvIHRoZXJlLCBuZWlnaGJvcmlubycsIHtcbiAgICAgKiAgICdsZW5ndGgnOiAyNCxcbiAgICAgKiAgICdzZXBhcmF0b3InOiAnICdcbiAgICAgKiB9KTtcbiAgICAgKiAvLyA9PiAnaGktZGlkZGx5LWhvIHRoZXJlLC4uLidcbiAgICAgKlxuICAgICAqIF8udHJ1bmNhdGUoJ2hpLWRpZGRseS1obyB0aGVyZSwgbmVpZ2hib3Jpbm8nLCB7XG4gICAgICogICAnbGVuZ3RoJzogMjQsXG4gICAgICogICAnc2VwYXJhdG9yJzogLyw/ICsvXG4gICAgICogfSk7XG4gICAgICogLy8gPT4gJ2hpLWRpZGRseS1obyB0aGVyZS4uLidcbiAgICAgKlxuICAgICAqIF8udHJ1bmNhdGUoJ2hpLWRpZGRseS1obyB0aGVyZSwgbmVpZ2hib3Jpbm8nLCB7XG4gICAgICogICAnb21pc3Npb24nOiAnIFsuLi5dJ1xuICAgICAqIH0pO1xuICAgICAqIC8vID0+ICdoaS1kaWRkbHktaG8gdGhlcmUsIG5laWcgWy4uLl0nXG4gICAgICovXG4gICAgZnVuY3Rpb24gdHJ1bmNhdGUoc3RyaW5nLCBvcHRpb25zKSB7XG4gICAgICB2YXIgbGVuZ3RoID0gREVGQVVMVF9UUlVOQ19MRU5HVEgsXG4gICAgICAgICAgb21pc3Npb24gPSBERUZBVUxUX1RSVU5DX09NSVNTSU9OO1xuXG4gICAgICBpZiAoaXNPYmplY3Qob3B0aW9ucykpIHtcbiAgICAgICAgdmFyIHNlcGFyYXRvciA9ICdzZXBhcmF0b3InIGluIG9wdGlvbnMgPyBvcHRpb25zLnNlcGFyYXRvciA6IHNlcGFyYXRvcjtcbiAgICAgICAgbGVuZ3RoID0gJ2xlbmd0aCcgaW4gb3B0aW9ucyA/IHRvSW50ZWdlcihvcHRpb25zLmxlbmd0aCkgOiBsZW5ndGg7XG4gICAgICAgIG9taXNzaW9uID0gJ29taXNzaW9uJyBpbiBvcHRpb25zID8gYmFzZVRvU3RyaW5nKG9wdGlvbnMub21pc3Npb24pIDogb21pc3Npb247XG4gICAgICB9XG4gICAgICBzdHJpbmcgPSB0b1N0cmluZyhzdHJpbmcpO1xuXG4gICAgICB2YXIgc3RyTGVuZ3RoID0gc3RyaW5nLmxlbmd0aDtcbiAgICAgIGlmIChoYXNVbmljb2RlKHN0cmluZykpIHtcbiAgICAgICAgdmFyIHN0clN5bWJvbHMgPSBzdHJpbmdUb0FycmF5KHN0cmluZyk7XG4gICAgICAgIHN0ckxlbmd0aCA9IHN0clN5bWJvbHMubGVuZ3RoO1xuICAgICAgfVxuICAgICAgaWYgKGxlbmd0aCA+PSBzdHJMZW5ndGgpIHtcbiAgICAgICAgcmV0dXJuIHN0cmluZztcbiAgICAgIH1cbiAgICAgIHZhciBlbmQgPSBsZW5ndGggLSBzdHJpbmdTaXplKG9taXNzaW9uKTtcbiAgICAgIGlmIChlbmQgPCAxKSB7XG4gICAgICAgIHJldHVybiBvbWlzc2lvbjtcbiAgICAgIH1cbiAgICAgIHZhciByZXN1bHQgPSBzdHJTeW1ib2xzXG4gICAgICAgID8gY2FzdFNsaWNlKHN0clN5bWJvbHMsIDAsIGVuZCkuam9pbignJylcbiAgICAgICAgOiBzdHJpbmcuc2xpY2UoMCwgZW5kKTtcblxuICAgICAgaWYgKHNlcGFyYXRvciA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHJldHVybiByZXN1bHQgKyBvbWlzc2lvbjtcbiAgICAgIH1cbiAgICAgIGlmIChzdHJTeW1ib2xzKSB7XG4gICAgICAgIGVuZCArPSAocmVzdWx0Lmxlbmd0aCAtIGVuZCk7XG4gICAgICB9XG4gICAgICBpZiAoaXNSZWdFeHAoc2VwYXJhdG9yKSkge1xuICAgICAgICBpZiAoc3RyaW5nLnNsaWNlKGVuZCkuc2VhcmNoKHNlcGFyYXRvcikpIHtcbiAgICAgICAgICB2YXIgbWF0Y2gsXG4gICAgICAgICAgICAgIHN1YnN0cmluZyA9IHJlc3VsdDtcblxuICAgICAgICAgIGlmICghc2VwYXJhdG9yLmdsb2JhbCkge1xuICAgICAgICAgICAgc2VwYXJhdG9yID0gUmVnRXhwKHNlcGFyYXRvci5zb3VyY2UsIHRvU3RyaW5nKHJlRmxhZ3MuZXhlYyhzZXBhcmF0b3IpKSArICdnJyk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHNlcGFyYXRvci5sYXN0SW5kZXggPSAwO1xuICAgICAgICAgIHdoaWxlICgobWF0Y2ggPSBzZXBhcmF0b3IuZXhlYyhzdWJzdHJpbmcpKSkge1xuICAgICAgICAgICAgdmFyIG5ld0VuZCA9IG1hdGNoLmluZGV4O1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXN1bHQgPSByZXN1bHQuc2xpY2UoMCwgbmV3RW5kID09PSB1bmRlZmluZWQgPyBlbmQgOiBuZXdFbmQpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKHN0cmluZy5pbmRleE9mKGJhc2VUb1N0cmluZyhzZXBhcmF0b3IpLCBlbmQpICE9IGVuZCkge1xuICAgICAgICB2YXIgaW5kZXggPSByZXN1bHQubGFzdEluZGV4T2Yoc2VwYXJhdG9yKTtcbiAgICAgICAgaWYgKGluZGV4ID4gLTEpIHtcbiAgICAgICAgICByZXN1bHQgPSByZXN1bHQuc2xpY2UoMCwgaW5kZXgpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gcmVzdWx0ICsgb21pc3Npb247XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIGludmVyc2Ugb2YgYF8uZXNjYXBlYDsgdGhpcyBtZXRob2QgY29udmVydHMgdGhlIEhUTUwgZW50aXRpZXNcbiAgICAgKiBgJmFtcDtgLCBgJmx0O2AsIGAmZ3Q7YCwgYCZxdW90O2AsIGFuZCBgJiMzOTtgIGluIGBzdHJpbmdgIHRvXG4gICAgICogdGhlaXIgY29ycmVzcG9uZGluZyBjaGFyYWN0ZXJzLlxuICAgICAqXG4gICAgICogKipOb3RlOioqIE5vIG90aGVyIEhUTUwgZW50aXRpZXMgYXJlIHVuZXNjYXBlZC4gVG8gdW5lc2NhcGUgYWRkaXRpb25hbFxuICAgICAqIEhUTUwgZW50aXRpZXMgdXNlIGEgdGhpcmQtcGFydHkgbGlicmFyeSBsaWtlIFtfaGVfXShodHRwczovL210aHMuYmUvaGUpLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDAuNi4wXG4gICAgICogQGNhdGVnb3J5IFN0cmluZ1xuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBbc3RyaW5nPScnXSBUaGUgc3RyaW5nIHRvIHVuZXNjYXBlLlxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IFJldHVybnMgdGhlIHVuZXNjYXBlZCBzdHJpbmcuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8udW5lc2NhcGUoJ2ZyZWQsIGJhcm5leSwgJmFtcDsgcGViYmxlcycpO1xuICAgICAqIC8vID0+ICdmcmVkLCBiYXJuZXksICYgcGViYmxlcydcbiAgICAgKi9cbiAgICBmdW5jdGlvbiB1bmVzY2FwZShzdHJpbmcpIHtcbiAgICAgIHN0cmluZyA9IHRvU3RyaW5nKHN0cmluZyk7XG4gICAgICByZXR1cm4gKHN0cmluZyAmJiByZUhhc0VzY2FwZWRIdG1sLnRlc3Qoc3RyaW5nKSlcbiAgICAgICAgPyBzdHJpbmcucmVwbGFjZShyZUVzY2FwZWRIdG1sLCB1bmVzY2FwZUh0bWxDaGFyKVxuICAgICAgICA6IHN0cmluZztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDb252ZXJ0cyBgc3RyaW5nYCwgYXMgc3BhY2Ugc2VwYXJhdGVkIHdvcmRzLCB0byB1cHBlciBjYXNlLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMC4wXG4gICAgICogQGNhdGVnb3J5IFN0cmluZ1xuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBbc3RyaW5nPScnXSBUaGUgc3RyaW5nIHRvIGNvbnZlcnQuXG4gICAgICogQHJldHVybnMge3N0cmluZ30gUmV0dXJucyB0aGUgdXBwZXIgY2FzZWQgc3RyaW5nLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLnVwcGVyQ2FzZSgnLS1mb28tYmFyJyk7XG4gICAgICogLy8gPT4gJ0ZPTyBCQVInXG4gICAgICpcbiAgICAgKiBfLnVwcGVyQ2FzZSgnZm9vQmFyJyk7XG4gICAgICogLy8gPT4gJ0ZPTyBCQVInXG4gICAgICpcbiAgICAgKiBfLnVwcGVyQ2FzZSgnX19mb29fYmFyX18nKTtcbiAgICAgKiAvLyA9PiAnRk9PIEJBUidcbiAgICAgKi9cbiAgICB2YXIgdXBwZXJDYXNlID0gY3JlYXRlQ29tcG91bmRlcihmdW5jdGlvbihyZXN1bHQsIHdvcmQsIGluZGV4KSB7XG4gICAgICByZXR1cm4gcmVzdWx0ICsgKGluZGV4ID8gJyAnIDogJycpICsgd29yZC50b1VwcGVyQ2FzZSgpO1xuICAgIH0pO1xuXG4gICAgLyoqXG4gICAgICogQ29udmVydHMgdGhlIGZpcnN0IGNoYXJhY3RlciBvZiBgc3RyaW5nYCB0byB1cHBlciBjYXNlLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMC4wXG4gICAgICogQGNhdGVnb3J5IFN0cmluZ1xuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBbc3RyaW5nPScnXSBUaGUgc3RyaW5nIHRvIGNvbnZlcnQuXG4gICAgICogQHJldHVybnMge3N0cmluZ30gUmV0dXJucyB0aGUgY29udmVydGVkIHN0cmluZy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy51cHBlckZpcnN0KCdmcmVkJyk7XG4gICAgICogLy8gPT4gJ0ZyZWQnXG4gICAgICpcbiAgICAgKiBfLnVwcGVyRmlyc3QoJ0ZSRUQnKTtcbiAgICAgKiAvLyA9PiAnRlJFRCdcbiAgICAgKi9cbiAgICB2YXIgdXBwZXJGaXJzdCA9IGNyZWF0ZUNhc2VGaXJzdCgndG9VcHBlckNhc2UnKTtcblxuICAgIC8qKlxuICAgICAqIFNwbGl0cyBgc3RyaW5nYCBpbnRvIGFuIGFycmF5IG9mIGl0cyB3b3Jkcy5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAzLjAuMFxuICAgICAqIEBjYXRlZ29yeSBTdHJpbmdcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gW3N0cmluZz0nJ10gVGhlIHN0cmluZyB0byBpbnNwZWN0LlxuICAgICAqIEBwYXJhbSB7UmVnRXhwfHN0cmluZ30gW3BhdHRlcm5dIFRoZSBwYXR0ZXJuIHRvIG1hdGNoIHdvcmRzLlxuICAgICAqIEBwYXJhbS0ge09iamVjdH0gW2d1YXJkXSBFbmFibGVzIHVzZSBhcyBhbiBpdGVyYXRlZSBmb3IgbWV0aG9kcyBsaWtlIGBfLm1hcGAuXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSB3b3JkcyBvZiBgc3RyaW5nYC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy53b3JkcygnZnJlZCwgYmFybmV5LCAmIHBlYmJsZXMnKTtcbiAgICAgKiAvLyA9PiBbJ2ZyZWQnLCAnYmFybmV5JywgJ3BlYmJsZXMnXVxuICAgICAqXG4gICAgICogXy53b3JkcygnZnJlZCwgYmFybmV5LCAmIHBlYmJsZXMnLCAvW14sIF0rL2cpO1xuICAgICAqIC8vID0+IFsnZnJlZCcsICdiYXJuZXknLCAnJicsICdwZWJibGVzJ11cbiAgICAgKi9cbiAgICBmdW5jdGlvbiB3b3JkcyhzdHJpbmcsIHBhdHRlcm4sIGd1YXJkKSB7XG4gICAgICBzdHJpbmcgPSB0b1N0cmluZyhzdHJpbmcpO1xuICAgICAgcGF0dGVybiA9IGd1YXJkID8gdW5kZWZpbmVkIDogcGF0dGVybjtcblxuICAgICAgaWYgKHBhdHRlcm4gPT09IHVuZGVmaW5lZCkge1xuICAgICAgICByZXR1cm4gaGFzVW5pY29kZVdvcmQoc3RyaW5nKSA/IHVuaWNvZGVXb3JkcyhzdHJpbmcpIDogYXNjaWlXb3JkcyhzdHJpbmcpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHN0cmluZy5tYXRjaChwYXR0ZXJuKSB8fCBbXTtcbiAgICB9XG5cbiAgICAvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovXG5cbiAgICAvKipcbiAgICAgKiBBdHRlbXB0cyB0byBpbnZva2UgYGZ1bmNgLCByZXR1cm5pbmcgZWl0aGVyIHRoZSByZXN1bHQgb3IgdGhlIGNhdWdodCBlcnJvclxuICAgICAqIG9iamVjdC4gQW55IGFkZGl0aW9uYWwgYXJndW1lbnRzIGFyZSBwcm92aWRlZCB0byBgZnVuY2Agd2hlbiBpdCdzIGludm9rZWQuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMy4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgVXRpbFxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIGF0dGVtcHQuXG4gICAgICogQHBhcmFtIHsuLi4qfSBbYXJnc10gVGhlIGFyZ3VtZW50cyB0byBpbnZva2UgYGZ1bmNgIHdpdGguXG4gICAgICogQHJldHVybnMgeyp9IFJldHVybnMgdGhlIGBmdW5jYCByZXN1bHQgb3IgZXJyb3Igb2JqZWN0LlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiAvLyBBdm9pZCB0aHJvd2luZyBlcnJvcnMgZm9yIGludmFsaWQgc2VsZWN0b3JzLlxuICAgICAqIHZhciBlbGVtZW50cyA9IF8uYXR0ZW1wdChmdW5jdGlvbihzZWxlY3Rvcikge1xuICAgICAqICAgcmV0dXJuIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoc2VsZWN0b3IpO1xuICAgICAqIH0sICc+Xz4nKTtcbiAgICAgKlxuICAgICAqIGlmIChfLmlzRXJyb3IoZWxlbWVudHMpKSB7XG4gICAgICogICBlbGVtZW50cyA9IFtdO1xuICAgICAqIH1cbiAgICAgKi9cbiAgICB2YXIgYXR0ZW1wdCA9IGJhc2VSZXN0KGZ1bmN0aW9uKGZ1bmMsIGFyZ3MpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIHJldHVybiBhcHBseShmdW5jLCB1bmRlZmluZWQsIGFyZ3MpO1xuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICByZXR1cm4gaXNFcnJvcihlKSA/IGUgOiBuZXcgRXJyb3IoZSk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICAvKipcbiAgICAgKiBCaW5kcyBtZXRob2RzIG9mIGFuIG9iamVjdCB0byB0aGUgb2JqZWN0IGl0c2VsZiwgb3ZlcndyaXRpbmcgdGhlIGV4aXN0aW5nXG4gICAgICogbWV0aG9kLlxuICAgICAqXG4gICAgICogKipOb3RlOioqIFRoaXMgbWV0aG9kIGRvZXNuJ3Qgc2V0IHRoZSBcImxlbmd0aFwiIHByb3BlcnR5IG9mIGJvdW5kIGZ1bmN0aW9ucy5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAc2luY2UgMC4xLjBcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBjYXRlZ29yeSBVdGlsXG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIGJpbmQgYW5kIGFzc2lnbiB0aGUgYm91bmQgbWV0aG9kcyB0by5cbiAgICAgKiBAcGFyYW0gey4uLihzdHJpbmd8c3RyaW5nW10pfSBtZXRob2ROYW1lcyBUaGUgb2JqZWN0IG1ldGhvZCBuYW1lcyB0byBiaW5kLlxuICAgICAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgYG9iamVjdGAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciB2aWV3ID0ge1xuICAgICAqICAgJ2xhYmVsJzogJ2RvY3MnLFxuICAgICAqICAgJ2NsaWNrJzogZnVuY3Rpb24oKSB7XG4gICAgICogICAgIGNvbnNvbGUubG9nKCdjbGlja2VkICcgKyB0aGlzLmxhYmVsKTtcbiAgICAgKiAgIH1cbiAgICAgKiB9O1xuICAgICAqXG4gICAgICogXy5iaW5kQWxsKHZpZXcsIFsnY2xpY2snXSk7XG4gICAgICogalF1ZXJ5KGVsZW1lbnQpLm9uKCdjbGljaycsIHZpZXcuY2xpY2spO1xuICAgICAqIC8vID0+IExvZ3MgJ2NsaWNrZWQgZG9jcycgd2hlbiBjbGlja2VkLlxuICAgICAqL1xuICAgIHZhciBiaW5kQWxsID0gZmxhdFJlc3QoZnVuY3Rpb24ob2JqZWN0LCBtZXRob2ROYW1lcykge1xuICAgICAgYXJyYXlFYWNoKG1ldGhvZE5hbWVzLCBmdW5jdGlvbihrZXkpIHtcbiAgICAgICAga2V5ID0gdG9LZXkoa2V5KTtcbiAgICAgICAgYmFzZUFzc2lnblZhbHVlKG9iamVjdCwga2V5LCBiaW5kKG9iamVjdFtrZXldLCBvYmplY3QpKTtcbiAgICAgIH0pO1xuICAgICAgcmV0dXJuIG9iamVjdDtcbiAgICB9KTtcblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBmdW5jdGlvbiB0aGF0IGl0ZXJhdGVzIG92ZXIgYHBhaXJzYCBhbmQgaW52b2tlcyB0aGUgY29ycmVzcG9uZGluZ1xuICAgICAqIGZ1bmN0aW9uIG9mIHRoZSBmaXJzdCBwcmVkaWNhdGUgdG8gcmV0dXJuIHRydXRoeS4gVGhlIHByZWRpY2F0ZS1mdW5jdGlvblxuICAgICAqIHBhaXJzIGFyZSBpbnZva2VkIHdpdGggdGhlIGB0aGlzYCBiaW5kaW5nIGFuZCBhcmd1bWVudHMgb2YgdGhlIGNyZWF0ZWRcbiAgICAgKiBmdW5jdGlvbi5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjAuMFxuICAgICAqIEBjYXRlZ29yeSBVdGlsXG4gICAgICogQHBhcmFtIHtBcnJheX0gcGFpcnMgVGhlIHByZWRpY2F0ZS1mdW5jdGlvbiBwYWlycy5cbiAgICAgKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBjb21wb3NpdGUgZnVuY3Rpb24uXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciBmdW5jID0gXy5jb25kKFtcbiAgICAgKiAgIFtfLm1hdGNoZXMoeyAnYSc6IDEgfSksICAgICAgICAgICBfLmNvbnN0YW50KCdtYXRjaGVzIEEnKV0sXG4gICAgICogICBbXy5jb25mb3Jtcyh7ICdiJzogXy5pc051bWJlciB9KSwgXy5jb25zdGFudCgnbWF0Y2hlcyBCJyldLFxuICAgICAqICAgW18uc3R1YlRydWUsICAgICAgICAgICAgICAgICAgICAgIF8uY29uc3RhbnQoJ25vIG1hdGNoJyldXG4gICAgICogXSk7XG4gICAgICpcbiAgICAgKiBmdW5jKHsgJ2EnOiAxLCAnYic6IDIgfSk7XG4gICAgICogLy8gPT4gJ21hdGNoZXMgQSdcbiAgICAgKlxuICAgICAqIGZ1bmMoeyAnYSc6IDAsICdiJzogMSB9KTtcbiAgICAgKiAvLyA9PiAnbWF0Y2hlcyBCJ1xuICAgICAqXG4gICAgICogZnVuYyh7ICdhJzogJzEnLCAnYic6ICcyJyB9KTtcbiAgICAgKiAvLyA9PiAnbm8gbWF0Y2gnXG4gICAgICovXG4gICAgZnVuY3Rpb24gY29uZChwYWlycykge1xuICAgICAgdmFyIGxlbmd0aCA9IHBhaXJzID09IG51bGwgPyAwIDogcGFpcnMubGVuZ3RoLFxuICAgICAgICAgIHRvSXRlcmF0ZWUgPSBnZXRJdGVyYXRlZSgpO1xuXG4gICAgICBwYWlycyA9ICFsZW5ndGggPyBbXSA6IGFycmF5TWFwKHBhaXJzLCBmdW5jdGlvbihwYWlyKSB7XG4gICAgICAgIGlmICh0eXBlb2YgcGFpclsxXSAhPSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihGVU5DX0VSUk9SX1RFWFQpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBbdG9JdGVyYXRlZShwYWlyWzBdKSwgcGFpclsxXV07XG4gICAgICB9KTtcblxuICAgICAgcmV0dXJuIGJhc2VSZXN0KGZ1bmN0aW9uKGFyZ3MpIHtcbiAgICAgICAgdmFyIGluZGV4ID0gLTE7XG4gICAgICAgIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XG4gICAgICAgICAgdmFyIHBhaXIgPSBwYWlyc1tpbmRleF07XG4gICAgICAgICAgaWYgKGFwcGx5KHBhaXJbMF0sIHRoaXMsIGFyZ3MpKSB7XG4gICAgICAgICAgICByZXR1cm4gYXBwbHkocGFpclsxXSwgdGhpcywgYXJncyk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgZnVuY3Rpb24gdGhhdCBpbnZva2VzIHRoZSBwcmVkaWNhdGUgcHJvcGVydGllcyBvZiBgc291cmNlYCB3aXRoXG4gICAgICogdGhlIGNvcnJlc3BvbmRpbmcgcHJvcGVydHkgdmFsdWVzIG9mIGEgZ2l2ZW4gb2JqZWN0LCByZXR1cm5pbmcgYHRydWVgIGlmXG4gICAgICogYWxsIHByZWRpY2F0ZXMgcmV0dXJuIHRydXRoeSwgZWxzZSBgZmFsc2VgLlxuICAgICAqXG4gICAgICogKipOb3RlOioqIFRoZSBjcmVhdGVkIGZ1bmN0aW9uIGlzIGVxdWl2YWxlbnQgdG8gYF8uY29uZm9ybXNUb2Agd2l0aFxuICAgICAqIGBzb3VyY2VgIHBhcnRpYWxseSBhcHBsaWVkLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMC4wXG4gICAgICogQGNhdGVnb3J5IFV0aWxcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gc291cmNlIFRoZSBvYmplY3Qgb2YgcHJvcGVydHkgcHJlZGljYXRlcyB0byBjb25mb3JtIHRvLlxuICAgICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IHNwZWMgZnVuY3Rpb24uXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciBvYmplY3RzID0gW1xuICAgICAqICAgeyAnYSc6IDIsICdiJzogMSB9LFxuICAgICAqICAgeyAnYSc6IDEsICdiJzogMiB9XG4gICAgICogXTtcbiAgICAgKlxuICAgICAqIF8uZmlsdGVyKG9iamVjdHMsIF8uY29uZm9ybXMoeyAnYic6IGZ1bmN0aW9uKG4pIHsgcmV0dXJuIG4gPiAxOyB9IH0pKTtcbiAgICAgKiAvLyA9PiBbeyAnYSc6IDEsICdiJzogMiB9XVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGNvbmZvcm1zKHNvdXJjZSkge1xuICAgICAgcmV0dXJuIGJhc2VDb25mb3JtcyhiYXNlQ2xvbmUoc291cmNlLCBDTE9ORV9ERUVQX0ZMQUcpKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgZnVuY3Rpb24gdGhhdCByZXR1cm5zIGB2YWx1ZWAuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMi40LjBcbiAgICAgKiBAY2F0ZWdvcnkgVXRpbFxuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIHJldHVybiBmcm9tIHRoZSBuZXcgZnVuY3Rpb24uXG4gICAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgY29uc3RhbnQgZnVuY3Rpb24uXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciBvYmplY3RzID0gXy50aW1lcygyLCBfLmNvbnN0YW50KHsgJ2EnOiAxIH0pKTtcbiAgICAgKlxuICAgICAqIGNvbnNvbGUubG9nKG9iamVjdHMpO1xuICAgICAqIC8vID0+IFt7ICdhJzogMSB9LCB7ICdhJzogMSB9XVxuICAgICAqXG4gICAgICogY29uc29sZS5sb2cob2JqZWN0c1swXSA9PT0gb2JqZWN0c1sxXSk7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGNvbnN0YW50KHZhbHVlKSB7XG4gICAgICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICAgIH07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2hlY2tzIGB2YWx1ZWAgdG8gZGV0ZXJtaW5lIHdoZXRoZXIgYSBkZWZhdWx0IHZhbHVlIHNob3VsZCBiZSByZXR1cm5lZCBpblxuICAgICAqIGl0cyBwbGFjZS4gVGhlIGBkZWZhdWx0VmFsdWVgIGlzIHJldHVybmVkIGlmIGB2YWx1ZWAgaXMgYE5hTmAsIGBudWxsYCxcbiAgICAgKiBvciBgdW5kZWZpbmVkYC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjE0LjBcbiAgICAgKiBAY2F0ZWdvcnkgVXRpbFxuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICAgICAqIEBwYXJhbSB7Kn0gZGVmYXVsdFZhbHVlIFRoZSBkZWZhdWx0IHZhbHVlLlxuICAgICAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSByZXNvbHZlZCB2YWx1ZS5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5kZWZhdWx0VG8oMSwgMTApO1xuICAgICAqIC8vID0+IDFcbiAgICAgKlxuICAgICAqIF8uZGVmYXVsdFRvKHVuZGVmaW5lZCwgMTApO1xuICAgICAqIC8vID0+IDEwXG4gICAgICovXG4gICAgZnVuY3Rpb24gZGVmYXVsdFRvKHZhbHVlLCBkZWZhdWx0VmFsdWUpIHtcbiAgICAgIHJldHVybiAodmFsdWUgPT0gbnVsbCB8fCB2YWx1ZSAhPT0gdmFsdWUpID8gZGVmYXVsdFZhbHVlIDogdmFsdWU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIGZ1bmN0aW9uIHRoYXQgcmV0dXJucyB0aGUgcmVzdWx0IG9mIGludm9raW5nIHRoZSBnaXZlbiBmdW5jdGlvbnNcbiAgICAgKiB3aXRoIHRoZSBgdGhpc2AgYmluZGluZyBvZiB0aGUgY3JlYXRlZCBmdW5jdGlvbiwgd2hlcmUgZWFjaCBzdWNjZXNzaXZlXG4gICAgICogaW52b2NhdGlvbiBpcyBzdXBwbGllZCB0aGUgcmV0dXJuIHZhbHVlIG9mIHRoZSBwcmV2aW91cy5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAzLjAuMFxuICAgICAqIEBjYXRlZ29yeSBVdGlsXG4gICAgICogQHBhcmFtIHsuLi4oRnVuY3Rpb258RnVuY3Rpb25bXSl9IFtmdW5jc10gVGhlIGZ1bmN0aW9ucyB0byBpbnZva2UuXG4gICAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgY29tcG9zaXRlIGZ1bmN0aW9uLlxuICAgICAqIEBzZWUgXy5mbG93UmlnaHRcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogZnVuY3Rpb24gc3F1YXJlKG4pIHtcbiAgICAgKiAgIHJldHVybiBuICogbjtcbiAgICAgKiB9XG4gICAgICpcbiAgICAgKiB2YXIgYWRkU3F1YXJlID0gXy5mbG93KFtfLmFkZCwgc3F1YXJlXSk7XG4gICAgICogYWRkU3F1YXJlKDEsIDIpO1xuICAgICAqIC8vID0+IDlcbiAgICAgKi9cbiAgICB2YXIgZmxvdyA9IGNyZWF0ZUZsb3coKTtcblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIGlzIGxpa2UgYF8uZmxvd2AgZXhjZXB0IHRoYXQgaXQgY3JlYXRlcyBhIGZ1bmN0aW9uIHRoYXRcbiAgICAgKiBpbnZva2VzIHRoZSBnaXZlbiBmdW5jdGlvbnMgZnJvbSByaWdodCB0byBsZWZ0LlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBzaW5jZSAzLjAuMFxuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQGNhdGVnb3J5IFV0aWxcbiAgICAgKiBAcGFyYW0gey4uLihGdW5jdGlvbnxGdW5jdGlvbltdKX0gW2Z1bmNzXSBUaGUgZnVuY3Rpb25zIHRvIGludm9rZS5cbiAgICAgKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBjb21wb3NpdGUgZnVuY3Rpb24uXG4gICAgICogQHNlZSBfLmZsb3dcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogZnVuY3Rpb24gc3F1YXJlKG4pIHtcbiAgICAgKiAgIHJldHVybiBuICogbjtcbiAgICAgKiB9XG4gICAgICpcbiAgICAgKiB2YXIgYWRkU3F1YXJlID0gXy5mbG93UmlnaHQoW3NxdWFyZSwgXy5hZGRdKTtcbiAgICAgKiBhZGRTcXVhcmUoMSwgMik7XG4gICAgICogLy8gPT4gOVxuICAgICAqL1xuICAgIHZhciBmbG93UmlnaHQgPSBjcmVhdGVGbG93KHRydWUpO1xuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgcmV0dXJucyB0aGUgZmlyc3QgYXJndW1lbnQgaXQgcmVjZWl2ZXMuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQHNpbmNlIDAuMS4wXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAY2F0ZWdvcnkgVXRpbFxuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgQW55IHZhbHVlLlxuICAgICAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIGB2YWx1ZWAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciBvYmplY3QgPSB7ICdhJzogMSB9O1xuICAgICAqXG4gICAgICogY29uc29sZS5sb2coXy5pZGVudGl0eShvYmplY3QpID09PSBvYmplY3QpO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBpZGVudGl0eSh2YWx1ZSkge1xuICAgICAgcmV0dXJuIHZhbHVlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBmdW5jdGlvbiB0aGF0IGludm9rZXMgYGZ1bmNgIHdpdGggdGhlIGFyZ3VtZW50cyBvZiB0aGUgY3JlYXRlZFxuICAgICAqIGZ1bmN0aW9uLiBJZiBgZnVuY2AgaXMgYSBwcm9wZXJ0eSBuYW1lLCB0aGUgY3JlYXRlZCBmdW5jdGlvbiByZXR1cm5zIHRoZVxuICAgICAqIHByb3BlcnR5IHZhbHVlIGZvciBhIGdpdmVuIGVsZW1lbnQuIElmIGBmdW5jYCBpcyBhbiBhcnJheSBvciBvYmplY3QsIHRoZVxuICAgICAqIGNyZWF0ZWQgZnVuY3Rpb24gcmV0dXJucyBgdHJ1ZWAgZm9yIGVsZW1lbnRzIHRoYXQgY29udGFpbiB0aGUgZXF1aXZhbGVudFxuICAgICAqIHNvdXJjZSBwcm9wZXJ0aWVzLCBvdGhlcndpc2UgaXQgcmV0dXJucyBgZmFsc2VgLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBzaW5jZSA0LjAuMFxuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQGNhdGVnb3J5IFV0aWxcbiAgICAgKiBAcGFyYW0geyp9IFtmdW5jPV8uaWRlbnRpdHldIFRoZSB2YWx1ZSB0byBjb252ZXJ0IHRvIGEgY2FsbGJhY2suXG4gICAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBjYWxsYmFjay5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIHVzZXJzID0gW1xuICAgICAqICAgeyAndXNlcic6ICdiYXJuZXknLCAnYWdlJzogMzYsICdhY3RpdmUnOiB0cnVlIH0sXG4gICAgICogICB7ICd1c2VyJzogJ2ZyZWQnLCAgICdhZ2UnOiA0MCwgJ2FjdGl2ZSc6IGZhbHNlIH1cbiAgICAgKiBdO1xuICAgICAqXG4gICAgICogLy8gVGhlIGBfLm1hdGNoZXNgIGl0ZXJhdGVlIHNob3J0aGFuZC5cbiAgICAgKiBfLmZpbHRlcih1c2VycywgXy5pdGVyYXRlZSh7ICd1c2VyJzogJ2Jhcm5leScsICdhY3RpdmUnOiB0cnVlIH0pKTtcbiAgICAgKiAvLyA9PiBbeyAndXNlcic6ICdiYXJuZXknLCAnYWdlJzogMzYsICdhY3RpdmUnOiB0cnVlIH1dXG4gICAgICpcbiAgICAgKiAvLyBUaGUgYF8ubWF0Y2hlc1Byb3BlcnR5YCBpdGVyYXRlZSBzaG9ydGhhbmQuXG4gICAgICogXy5maWx0ZXIodXNlcnMsIF8uaXRlcmF0ZWUoWyd1c2VyJywgJ2ZyZWQnXSkpO1xuICAgICAqIC8vID0+IFt7ICd1c2VyJzogJ2ZyZWQnLCAnYWdlJzogNDAgfV1cbiAgICAgKlxuICAgICAqIC8vIFRoZSBgXy5wcm9wZXJ0eWAgaXRlcmF0ZWUgc2hvcnRoYW5kLlxuICAgICAqIF8ubWFwKHVzZXJzLCBfLml0ZXJhdGVlKCd1c2VyJykpO1xuICAgICAqIC8vID0+IFsnYmFybmV5JywgJ2ZyZWQnXVxuICAgICAqXG4gICAgICogLy8gQ3JlYXRlIGN1c3RvbSBpdGVyYXRlZSBzaG9ydGhhbmRzLlxuICAgICAqIF8uaXRlcmF0ZWUgPSBfLndyYXAoXy5pdGVyYXRlZSwgZnVuY3Rpb24oaXRlcmF0ZWUsIGZ1bmMpIHtcbiAgICAgKiAgIHJldHVybiAhXy5pc1JlZ0V4cChmdW5jKSA/IGl0ZXJhdGVlKGZ1bmMpIDogZnVuY3Rpb24oc3RyaW5nKSB7XG4gICAgICogICAgIHJldHVybiBmdW5jLnRlc3Qoc3RyaW5nKTtcbiAgICAgKiAgIH07XG4gICAgICogfSk7XG4gICAgICpcbiAgICAgKiBfLmZpbHRlcihbJ2FiYycsICdkZWYnXSwgL2VmLyk7XG4gICAgICogLy8gPT4gWydkZWYnXVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGl0ZXJhdGVlKGZ1bmMpIHtcbiAgICAgIHJldHVybiBiYXNlSXRlcmF0ZWUodHlwZW9mIGZ1bmMgPT0gJ2Z1bmN0aW9uJyA/IGZ1bmMgOiBiYXNlQ2xvbmUoZnVuYywgQ0xPTkVfREVFUF9GTEFHKSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIGZ1bmN0aW9uIHRoYXQgcGVyZm9ybXMgYSBwYXJ0aWFsIGRlZXAgY29tcGFyaXNvbiBiZXR3ZWVuIGEgZ2l2ZW5cbiAgICAgKiBvYmplY3QgYW5kIGBzb3VyY2VgLCByZXR1cm5pbmcgYHRydWVgIGlmIHRoZSBnaXZlbiBvYmplY3QgaGFzIGVxdWl2YWxlbnRcbiAgICAgKiBwcm9wZXJ0eSB2YWx1ZXMsIGVsc2UgYGZhbHNlYC5cbiAgICAgKlxuICAgICAqICoqTm90ZToqKiBUaGUgY3JlYXRlZCBmdW5jdGlvbiBpcyBlcXVpdmFsZW50IHRvIGBfLmlzTWF0Y2hgIHdpdGggYHNvdXJjZWBcbiAgICAgKiBwYXJ0aWFsbHkgYXBwbGllZC5cbiAgICAgKlxuICAgICAqIFBhcnRpYWwgY29tcGFyaXNvbnMgd2lsbCBtYXRjaCBlbXB0eSBhcnJheSBhbmQgZW1wdHkgb2JqZWN0IGBzb3VyY2VgXG4gICAgICogdmFsdWVzIGFnYWluc3QgYW55IGFycmF5IG9yIG9iamVjdCB2YWx1ZSwgcmVzcGVjdGl2ZWx5LiBTZWUgYF8uaXNFcXVhbGBcbiAgICAgKiBmb3IgYSBsaXN0IG9mIHN1cHBvcnRlZCB2YWx1ZSBjb21wYXJpc29ucy5cbiAgICAgKlxuICAgICAqICoqTm90ZToqKiBNdWx0aXBsZSB2YWx1ZXMgY2FuIGJlIGNoZWNrZWQgYnkgY29tYmluaW5nIHNldmVyYWwgbWF0Y2hlcnNcbiAgICAgKiB1c2luZyBgXy5vdmVyU29tZWBcbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAzLjAuMFxuICAgICAqIEBjYXRlZ29yeSBVdGlsXG4gICAgICogQHBhcmFtIHtPYmplY3R9IHNvdXJjZSBUaGUgb2JqZWN0IG9mIHByb3BlcnR5IHZhbHVlcyB0byBtYXRjaC5cbiAgICAgKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBzcGVjIGZ1bmN0aW9uLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgb2JqZWN0cyA9IFtcbiAgICAgKiAgIHsgJ2EnOiAxLCAnYic6IDIsICdjJzogMyB9LFxuICAgICAqICAgeyAnYSc6IDQsICdiJzogNSwgJ2MnOiA2IH1cbiAgICAgKiBdO1xuICAgICAqXG4gICAgICogXy5maWx0ZXIob2JqZWN0cywgXy5tYXRjaGVzKHsgJ2EnOiA0LCAnYyc6IDYgfSkpO1xuICAgICAqIC8vID0+IFt7ICdhJzogNCwgJ2InOiA1LCAnYyc6IDYgfV1cbiAgICAgKlxuICAgICAqIC8vIENoZWNraW5nIGZvciBzZXZlcmFsIHBvc3NpYmxlIHZhbHVlc1xuICAgICAqIF8uZmlsdGVyKG9iamVjdHMsIF8ub3ZlclNvbWUoW18ubWF0Y2hlcyh7ICdhJzogMSB9KSwgXy5tYXRjaGVzKHsgJ2EnOiA0IH0pXSkpO1xuICAgICAqIC8vID0+IFt7ICdhJzogMSwgJ2InOiAyLCAnYyc6IDMgfSwgeyAnYSc6IDQsICdiJzogNSwgJ2MnOiA2IH1dXG4gICAgICovXG4gICAgZnVuY3Rpb24gbWF0Y2hlcyhzb3VyY2UpIHtcbiAgICAgIHJldHVybiBiYXNlTWF0Y2hlcyhiYXNlQ2xvbmUoc291cmNlLCBDTE9ORV9ERUVQX0ZMQUcpKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgZnVuY3Rpb24gdGhhdCBwZXJmb3JtcyBhIHBhcnRpYWwgZGVlcCBjb21wYXJpc29uIGJldHdlZW4gdGhlXG4gICAgICogdmFsdWUgYXQgYHBhdGhgIG9mIGEgZ2l2ZW4gb2JqZWN0IHRvIGBzcmNWYWx1ZWAsIHJldHVybmluZyBgdHJ1ZWAgaWYgdGhlXG4gICAgICogb2JqZWN0IHZhbHVlIGlzIGVxdWl2YWxlbnQsIGVsc2UgYGZhbHNlYC5cbiAgICAgKlxuICAgICAqICoqTm90ZToqKiBQYXJ0aWFsIGNvbXBhcmlzb25zIHdpbGwgbWF0Y2ggZW1wdHkgYXJyYXkgYW5kIGVtcHR5IG9iamVjdFxuICAgICAqIGBzcmNWYWx1ZWAgdmFsdWVzIGFnYWluc3QgYW55IGFycmF5IG9yIG9iamVjdCB2YWx1ZSwgcmVzcGVjdGl2ZWx5LiBTZWVcbiAgICAgKiBgXy5pc0VxdWFsYCBmb3IgYSBsaXN0IG9mIHN1cHBvcnRlZCB2YWx1ZSBjb21wYXJpc29ucy5cbiAgICAgKlxuICAgICAqICoqTm90ZToqKiBNdWx0aXBsZSB2YWx1ZXMgY2FuIGJlIGNoZWNrZWQgYnkgY29tYmluaW5nIHNldmVyYWwgbWF0Y2hlcnNcbiAgICAgKiB1c2luZyBgXy5vdmVyU29tZWBcbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAzLjIuMFxuICAgICAqIEBjYXRlZ29yeSBVdGlsXG4gICAgICogQHBhcmFtIHtBcnJheXxzdHJpbmd9IHBhdGggVGhlIHBhdGggb2YgdGhlIHByb3BlcnR5IHRvIGdldC5cbiAgICAgKiBAcGFyYW0geyp9IHNyY1ZhbHVlIFRoZSB2YWx1ZSB0byBtYXRjaC5cbiAgICAgKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBzcGVjIGZ1bmN0aW9uLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgb2JqZWN0cyA9IFtcbiAgICAgKiAgIHsgJ2EnOiAxLCAnYic6IDIsICdjJzogMyB9LFxuICAgICAqICAgeyAnYSc6IDQsICdiJzogNSwgJ2MnOiA2IH1cbiAgICAgKiBdO1xuICAgICAqXG4gICAgICogXy5maW5kKG9iamVjdHMsIF8ubWF0Y2hlc1Byb3BlcnR5KCdhJywgNCkpO1xuICAgICAqIC8vID0+IHsgJ2EnOiA0LCAnYic6IDUsICdjJzogNiB9XG4gICAgICpcbiAgICAgKiAvLyBDaGVja2luZyBmb3Igc2V2ZXJhbCBwb3NzaWJsZSB2YWx1ZXNcbiAgICAgKiBfLmZpbHRlcihvYmplY3RzLCBfLm92ZXJTb21lKFtfLm1hdGNoZXNQcm9wZXJ0eSgnYScsIDEpLCBfLm1hdGNoZXNQcm9wZXJ0eSgnYScsIDQpXSkpO1xuICAgICAqIC8vID0+IFt7ICdhJzogMSwgJ2InOiAyLCAnYyc6IDMgfSwgeyAnYSc6IDQsICdiJzogNSwgJ2MnOiA2IH1dXG4gICAgICovXG4gICAgZnVuY3Rpb24gbWF0Y2hlc1Byb3BlcnR5KHBhdGgsIHNyY1ZhbHVlKSB7XG4gICAgICByZXR1cm4gYmFzZU1hdGNoZXNQcm9wZXJ0eShwYXRoLCBiYXNlQ2xvbmUoc3JjVmFsdWUsIENMT05FX0RFRVBfRkxBRykpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBmdW5jdGlvbiB0aGF0IGludm9rZXMgdGhlIG1ldGhvZCBhdCBgcGF0aGAgb2YgYSBnaXZlbiBvYmplY3QuXG4gICAgICogQW55IGFkZGl0aW9uYWwgYXJndW1lbnRzIGFyZSBwcm92aWRlZCB0byB0aGUgaW52b2tlZCBtZXRob2QuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMy43LjBcbiAgICAgKiBAY2F0ZWdvcnkgVXRpbFxuICAgICAqIEBwYXJhbSB7QXJyYXl8c3RyaW5nfSBwYXRoIFRoZSBwYXRoIG9mIHRoZSBtZXRob2QgdG8gaW52b2tlLlxuICAgICAqIEBwYXJhbSB7Li4uKn0gW2FyZ3NdIFRoZSBhcmd1bWVudHMgdG8gaW52b2tlIHRoZSBtZXRob2Qgd2l0aC5cbiAgICAgKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBpbnZva2VyIGZ1bmN0aW9uLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgb2JqZWN0cyA9IFtcbiAgICAgKiAgIHsgJ2EnOiB7ICdiJzogXy5jb25zdGFudCgyKSB9IH0sXG4gICAgICogICB7ICdhJzogeyAnYic6IF8uY29uc3RhbnQoMSkgfSB9XG4gICAgICogXTtcbiAgICAgKlxuICAgICAqIF8ubWFwKG9iamVjdHMsIF8ubWV0aG9kKCdhLmInKSk7XG4gICAgICogLy8gPT4gWzIsIDFdXG4gICAgICpcbiAgICAgKiBfLm1hcChvYmplY3RzLCBfLm1ldGhvZChbJ2EnLCAnYiddKSk7XG4gICAgICogLy8gPT4gWzIsIDFdXG4gICAgICovXG4gICAgdmFyIG1ldGhvZCA9IGJhc2VSZXN0KGZ1bmN0aW9uKHBhdGgsIGFyZ3MpIHtcbiAgICAgIHJldHVybiBmdW5jdGlvbihvYmplY3QpIHtcbiAgICAgICAgcmV0dXJuIGJhc2VJbnZva2Uob2JqZWN0LCBwYXRoLCBhcmdzKTtcbiAgICAgIH07XG4gICAgfSk7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgb3Bwb3NpdGUgb2YgYF8ubWV0aG9kYDsgdGhpcyBtZXRob2QgY3JlYXRlcyBhIGZ1bmN0aW9uIHRoYXQgaW52b2tlc1xuICAgICAqIHRoZSBtZXRob2QgYXQgYSBnaXZlbiBwYXRoIG9mIGBvYmplY3RgLiBBbnkgYWRkaXRpb25hbCBhcmd1bWVudHMgYXJlXG4gICAgICogcHJvdmlkZWQgdG8gdGhlIGludm9rZWQgbWV0aG9kLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDMuNy4wXG4gICAgICogQGNhdGVnb3J5IFV0aWxcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gcXVlcnkuXG4gICAgICogQHBhcmFtIHsuLi4qfSBbYXJnc10gVGhlIGFyZ3VtZW50cyB0byBpbnZva2UgdGhlIG1ldGhvZCB3aXRoLlxuICAgICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IGludm9rZXIgZnVuY3Rpb24uXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciBhcnJheSA9IF8udGltZXMoMywgXy5jb25zdGFudCksXG4gICAgICogICAgIG9iamVjdCA9IHsgJ2EnOiBhcnJheSwgJ2InOiBhcnJheSwgJ2MnOiBhcnJheSB9O1xuICAgICAqXG4gICAgICogXy5tYXAoWydhWzJdJywgJ2NbMF0nXSwgXy5tZXRob2RPZihvYmplY3QpKTtcbiAgICAgKiAvLyA9PiBbMiwgMF1cbiAgICAgKlxuICAgICAqIF8ubWFwKFtbJ2EnLCAnMiddLCBbJ2MnLCAnMCddXSwgXy5tZXRob2RPZihvYmplY3QpKTtcbiAgICAgKiAvLyA9PiBbMiwgMF1cbiAgICAgKi9cbiAgICB2YXIgbWV0aG9kT2YgPSBiYXNlUmVzdChmdW5jdGlvbihvYmplY3QsIGFyZ3MpIHtcbiAgICAgIHJldHVybiBmdW5jdGlvbihwYXRoKSB7XG4gICAgICAgIHJldHVybiBiYXNlSW52b2tlKG9iamVjdCwgcGF0aCwgYXJncyk7XG4gICAgICB9O1xuICAgIH0pO1xuXG4gICAgLyoqXG4gICAgICogQWRkcyBhbGwgb3duIGVudW1lcmFibGUgc3RyaW5nIGtleWVkIGZ1bmN0aW9uIHByb3BlcnRpZXMgb2YgYSBzb3VyY2VcbiAgICAgKiBvYmplY3QgdG8gdGhlIGRlc3RpbmF0aW9uIG9iamVjdC4gSWYgYG9iamVjdGAgaXMgYSBmdW5jdGlvbiwgdGhlbiBtZXRob2RzXG4gICAgICogYXJlIGFkZGVkIHRvIGl0cyBwcm90b3R5cGUgYXMgd2VsbC5cbiAgICAgKlxuICAgICAqICoqTm90ZToqKiBVc2UgYF8ucnVuSW5Db250ZXh0YCB0byBjcmVhdGUgYSBwcmlzdGluZSBgbG9kYXNoYCBmdW5jdGlvbiB0b1xuICAgICAqIGF2b2lkIGNvbmZsaWN0cyBjYXVzZWQgYnkgbW9kaWZ5aW5nIHRoZSBvcmlnaW5hbC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAc2luY2UgMC4xLjBcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBjYXRlZ29yeSBVdGlsXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbnxPYmplY3R9IFtvYmplY3Q9bG9kYXNoXSBUaGUgZGVzdGluYXRpb24gb2JqZWN0LlxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBzb3VyY2UgVGhlIG9iamVjdCBvZiBmdW5jdGlvbnMgdG8gYWRkLlxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBbb3B0aW9ucz17fV0gVGhlIG9wdGlvbnMgb2JqZWN0LlxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbn0gW29wdGlvbnMuY2hhaW49dHJ1ZV0gU3BlY2lmeSB3aGV0aGVyIG1peGlucyBhcmUgY2hhaW5hYmxlLlxuICAgICAqIEByZXR1cm5zIHtGdW5jdGlvbnxPYmplY3R9IFJldHVybnMgYG9iamVjdGAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIGZ1bmN0aW9uIHZvd2VscyhzdHJpbmcpIHtcbiAgICAgKiAgIHJldHVybiBfLmZpbHRlcihzdHJpbmcsIGZ1bmN0aW9uKHYpIHtcbiAgICAgKiAgICAgcmV0dXJuIC9bYWVpb3VdL2kudGVzdCh2KTtcbiAgICAgKiAgIH0pO1xuICAgICAqIH1cbiAgICAgKlxuICAgICAqIF8ubWl4aW4oeyAndm93ZWxzJzogdm93ZWxzIH0pO1xuICAgICAqIF8udm93ZWxzKCdmcmVkJyk7XG4gICAgICogLy8gPT4gWydlJ11cbiAgICAgKlxuICAgICAqIF8oJ2ZyZWQnKS52b3dlbHMoKS52YWx1ZSgpO1xuICAgICAqIC8vID0+IFsnZSddXG4gICAgICpcbiAgICAgKiBfLm1peGluKHsgJ3Zvd2Vscyc6IHZvd2VscyB9LCB7ICdjaGFpbic6IGZhbHNlIH0pO1xuICAgICAqIF8oJ2ZyZWQnKS52b3dlbHMoKTtcbiAgICAgKiAvLyA9PiBbJ2UnXVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIG1peGluKG9iamVjdCwgc291cmNlLCBvcHRpb25zKSB7XG4gICAgICB2YXIgcHJvcHMgPSBrZXlzKHNvdXJjZSksXG4gICAgICAgICAgbWV0aG9kTmFtZXMgPSBiYXNlRnVuY3Rpb25zKHNvdXJjZSwgcHJvcHMpO1xuXG4gICAgICBpZiAob3B0aW9ucyA9PSBudWxsICYmXG4gICAgICAgICAgIShpc09iamVjdChzb3VyY2UpICYmIChtZXRob2ROYW1lcy5sZW5ndGggfHwgIXByb3BzLmxlbmd0aCkpKSB7XG4gICAgICAgIG9wdGlvbnMgPSBzb3VyY2U7XG4gICAgICAgIHNvdXJjZSA9IG9iamVjdDtcbiAgICAgICAgb2JqZWN0ID0gdGhpcztcbiAgICAgICAgbWV0aG9kTmFtZXMgPSBiYXNlRnVuY3Rpb25zKHNvdXJjZSwga2V5cyhzb3VyY2UpKTtcbiAgICAgIH1cbiAgICAgIHZhciBjaGFpbiA9ICEoaXNPYmplY3Qob3B0aW9ucykgJiYgJ2NoYWluJyBpbiBvcHRpb25zKSB8fCAhIW9wdGlvbnMuY2hhaW4sXG4gICAgICAgICAgaXNGdW5jID0gaXNGdW5jdGlvbihvYmplY3QpO1xuXG4gICAgICBhcnJheUVhY2gobWV0aG9kTmFtZXMsIGZ1bmN0aW9uKG1ldGhvZE5hbWUpIHtcbiAgICAgICAgdmFyIGZ1bmMgPSBzb3VyY2VbbWV0aG9kTmFtZV07XG4gICAgICAgIG9iamVjdFttZXRob2ROYW1lXSA9IGZ1bmM7XG4gICAgICAgIGlmIChpc0Z1bmMpIHtcbiAgICAgICAgICBvYmplY3QucHJvdG90eXBlW21ldGhvZE5hbWVdID0gZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICB2YXIgY2hhaW5BbGwgPSB0aGlzLl9fY2hhaW5fXztcbiAgICAgICAgICAgIGlmIChjaGFpbiB8fCBjaGFpbkFsbCkge1xuICAgICAgICAgICAgICB2YXIgcmVzdWx0ID0gb2JqZWN0KHRoaXMuX193cmFwcGVkX18pLFxuICAgICAgICAgICAgICAgICAgYWN0aW9ucyA9IHJlc3VsdC5fX2FjdGlvbnNfXyA9IGNvcHlBcnJheSh0aGlzLl9fYWN0aW9uc19fKTtcblxuICAgICAgICAgICAgICBhY3Rpb25zLnB1c2goeyAnZnVuYyc6IGZ1bmMsICdhcmdzJzogYXJndW1lbnRzLCAndGhpc0FyZyc6IG9iamVjdCB9KTtcbiAgICAgICAgICAgICAgcmVzdWx0Ll9fY2hhaW5fXyA9IGNoYWluQWxsO1xuICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIGZ1bmMuYXBwbHkob2JqZWN0LCBhcnJheVB1c2goW3RoaXMudmFsdWUoKV0sIGFyZ3VtZW50cykpO1xuICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICAgIH0pO1xuXG4gICAgICByZXR1cm4gb2JqZWN0O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJldmVydHMgdGhlIGBfYCB2YXJpYWJsZSB0byBpdHMgcHJldmlvdXMgdmFsdWUgYW5kIHJldHVybnMgYSByZWZlcmVuY2UgdG9cbiAgICAgKiB0aGUgYGxvZGFzaGAgZnVuY3Rpb24uXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQHNpbmNlIDAuMS4wXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAY2F0ZWdvcnkgVXRpbFxuICAgICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgYGxvZGFzaGAgZnVuY3Rpb24uXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciBsb2Rhc2ggPSBfLm5vQ29uZmxpY3QoKTtcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBub0NvbmZsaWN0KCkge1xuICAgICAgaWYgKHJvb3QuXyA9PT0gdGhpcykge1xuICAgICAgICByb290Ll8gPSBvbGREYXNoO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgcmV0dXJucyBgdW5kZWZpbmVkYC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAyLjMuMFxuICAgICAqIEBjYXRlZ29yeSBVdGlsXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8udGltZXMoMiwgXy5ub29wKTtcbiAgICAgKiAvLyA9PiBbdW5kZWZpbmVkLCB1bmRlZmluZWRdXG4gICAgICovXG4gICAgZnVuY3Rpb24gbm9vcCgpIHtcbiAgICAgIC8vIE5vIG9wZXJhdGlvbiBwZXJmb3JtZWQuXG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIGZ1bmN0aW9uIHRoYXQgZ2V0cyB0aGUgYXJndW1lbnQgYXQgaW5kZXggYG5gLiBJZiBgbmAgaXMgbmVnYXRpdmUsXG4gICAgICogdGhlIG50aCBhcmd1bWVudCBmcm9tIHRoZSBlbmQgaXMgcmV0dXJuZWQuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgVXRpbFxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbbj0wXSBUaGUgaW5kZXggb2YgdGhlIGFyZ3VtZW50IHRvIHJldHVybi5cbiAgICAgKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBwYXNzLXRocnUgZnVuY3Rpb24uXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciBmdW5jID0gXy5udGhBcmcoMSk7XG4gICAgICogZnVuYygnYScsICdiJywgJ2MnLCAnZCcpO1xuICAgICAqIC8vID0+ICdiJ1xuICAgICAqXG4gICAgICogdmFyIGZ1bmMgPSBfLm50aEFyZygtMik7XG4gICAgICogZnVuYygnYScsICdiJywgJ2MnLCAnZCcpO1xuICAgICAqIC8vID0+ICdjJ1xuICAgICAqL1xuICAgIGZ1bmN0aW9uIG50aEFyZyhuKSB7XG4gICAgICBuID0gdG9JbnRlZ2VyKG4pO1xuICAgICAgcmV0dXJuIGJhc2VSZXN0KGZ1bmN0aW9uKGFyZ3MpIHtcbiAgICAgICAgcmV0dXJuIGJhc2VOdGgoYXJncywgbik7XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgZnVuY3Rpb24gdGhhdCBpbnZva2VzIGBpdGVyYXRlZXNgIHdpdGggdGhlIGFyZ3VtZW50cyBpdCByZWNlaXZlc1xuICAgICAqIGFuZCByZXR1cm5zIHRoZWlyIHJlc3VsdHMuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgVXRpbFxuICAgICAqIEBwYXJhbSB7Li4uKEZ1bmN0aW9ufEZ1bmN0aW9uW10pfSBbaXRlcmF0ZWVzPVtfLmlkZW50aXR5XV1cbiAgICAgKiAgVGhlIGl0ZXJhdGVlcyB0byBpbnZva2UuXG4gICAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgZnVuY3Rpb24uXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciBmdW5jID0gXy5vdmVyKFtNYXRoLm1heCwgTWF0aC5taW5dKTtcbiAgICAgKlxuICAgICAqIGZ1bmMoMSwgMiwgMywgNCk7XG4gICAgICogLy8gPT4gWzQsIDFdXG4gICAgICovXG4gICAgdmFyIG92ZXIgPSBjcmVhdGVPdmVyKGFycmF5TWFwKTtcblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBmdW5jdGlvbiB0aGF0IGNoZWNrcyBpZiAqKmFsbCoqIG9mIHRoZSBgcHJlZGljYXRlc2AgcmV0dXJuXG4gICAgICogdHJ1dGh5IHdoZW4gaW52b2tlZCB3aXRoIHRoZSBhcmd1bWVudHMgaXQgcmVjZWl2ZXMuXG4gICAgICpcbiAgICAgKiBGb2xsb3dpbmcgc2hvcnRoYW5kcyBhcmUgcG9zc2libGUgZm9yIHByb3ZpZGluZyBwcmVkaWNhdGVzLlxuICAgICAqIFBhc3MgYW4gYE9iamVjdGAgYW5kIGl0IHdpbGwgYmUgdXNlZCBhcyBhbiBwYXJhbWV0ZXIgZm9yIGBfLm1hdGNoZXNgIHRvIGNyZWF0ZSB0aGUgcHJlZGljYXRlLlxuICAgICAqIFBhc3MgYW4gYEFycmF5YCBvZiBwYXJhbWV0ZXJzIGZvciBgXy5tYXRjaGVzUHJvcGVydHlgIGFuZCB0aGUgcHJlZGljYXRlIHdpbGwgYmUgY3JlYXRlZCB1c2luZyB0aGVtLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMC4wXG4gICAgICogQGNhdGVnb3J5IFV0aWxcbiAgICAgKiBAcGFyYW0gey4uLihGdW5jdGlvbnxGdW5jdGlvbltdKX0gW3ByZWRpY2F0ZXM9W18uaWRlbnRpdHldXVxuICAgICAqICBUaGUgcHJlZGljYXRlcyB0byBjaGVjay5cbiAgICAgKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBmdW5jdGlvbi5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIGZ1bmMgPSBfLm92ZXJFdmVyeShbQm9vbGVhbiwgaXNGaW5pdGVdKTtcbiAgICAgKlxuICAgICAqIGZ1bmMoJzEnKTtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICpcbiAgICAgKiBmdW5jKG51bGwpO1xuICAgICAqIC8vID0+IGZhbHNlXG4gICAgICpcbiAgICAgKiBmdW5jKE5hTik7XG4gICAgICogLy8gPT4gZmFsc2VcbiAgICAgKi9cbiAgICB2YXIgb3ZlckV2ZXJ5ID0gY3JlYXRlT3ZlcihhcnJheUV2ZXJ5KTtcblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBmdW5jdGlvbiB0aGF0IGNoZWNrcyBpZiAqKmFueSoqIG9mIHRoZSBgcHJlZGljYXRlc2AgcmV0dXJuXG4gICAgICogdHJ1dGh5IHdoZW4gaW52b2tlZCB3aXRoIHRoZSBhcmd1bWVudHMgaXQgcmVjZWl2ZXMuXG4gICAgICpcbiAgICAgKiBGb2xsb3dpbmcgc2hvcnRoYW5kcyBhcmUgcG9zc2libGUgZm9yIHByb3ZpZGluZyBwcmVkaWNhdGVzLlxuICAgICAqIFBhc3MgYW4gYE9iamVjdGAgYW5kIGl0IHdpbGwgYmUgdXNlZCBhcyBhbiBwYXJhbWV0ZXIgZm9yIGBfLm1hdGNoZXNgIHRvIGNyZWF0ZSB0aGUgcHJlZGljYXRlLlxuICAgICAqIFBhc3MgYW4gYEFycmF5YCBvZiBwYXJhbWV0ZXJzIGZvciBgXy5tYXRjaGVzUHJvcGVydHlgIGFuZCB0aGUgcHJlZGljYXRlIHdpbGwgYmUgY3JlYXRlZCB1c2luZyB0aGVtLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMC4wXG4gICAgICogQGNhdGVnb3J5IFV0aWxcbiAgICAgKiBAcGFyYW0gey4uLihGdW5jdGlvbnxGdW5jdGlvbltdKX0gW3ByZWRpY2F0ZXM9W18uaWRlbnRpdHldXVxuICAgICAqICBUaGUgcHJlZGljYXRlcyB0byBjaGVjay5cbiAgICAgKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBmdW5jdGlvbi5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIGZ1bmMgPSBfLm92ZXJTb21lKFtCb29sZWFuLCBpc0Zpbml0ZV0pO1xuICAgICAqXG4gICAgICogZnVuYygnMScpO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKlxuICAgICAqIGZ1bmMobnVsbCk7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqXG4gICAgICogZnVuYyhOYU4pO1xuICAgICAqIC8vID0+IGZhbHNlXG4gICAgICpcbiAgICAgKiB2YXIgbWF0Y2hlc0Z1bmMgPSBfLm92ZXJTb21lKFt7ICdhJzogMSB9LCB7ICdhJzogMiB9XSlcbiAgICAgKiB2YXIgbWF0Y2hlc1Byb3BlcnR5RnVuYyA9IF8ub3ZlclNvbWUoW1snYScsIDFdLCBbJ2EnLCAyXV0pXG4gICAgICovXG4gICAgdmFyIG92ZXJTb21lID0gY3JlYXRlT3ZlcihhcnJheVNvbWUpO1xuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIGZ1bmN0aW9uIHRoYXQgcmV0dXJucyB0aGUgdmFsdWUgYXQgYHBhdGhgIG9mIGEgZ2l2ZW4gb2JqZWN0LlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDIuNC4wXG4gICAgICogQGNhdGVnb3J5IFV0aWxcbiAgICAgKiBAcGFyYW0ge0FycmF5fHN0cmluZ30gcGF0aCBUaGUgcGF0aCBvZiB0aGUgcHJvcGVydHkgdG8gZ2V0LlxuICAgICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IGFjY2Vzc29yIGZ1bmN0aW9uLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgb2JqZWN0cyA9IFtcbiAgICAgKiAgIHsgJ2EnOiB7ICdiJzogMiB9IH0sXG4gICAgICogICB7ICdhJzogeyAnYic6IDEgfSB9XG4gICAgICogXTtcbiAgICAgKlxuICAgICAqIF8ubWFwKG9iamVjdHMsIF8ucHJvcGVydHkoJ2EuYicpKTtcbiAgICAgKiAvLyA9PiBbMiwgMV1cbiAgICAgKlxuICAgICAqIF8ubWFwKF8uc29ydEJ5KG9iamVjdHMsIF8ucHJvcGVydHkoWydhJywgJ2InXSkpLCAnYS5iJyk7XG4gICAgICogLy8gPT4gWzEsIDJdXG4gICAgICovXG4gICAgZnVuY3Rpb24gcHJvcGVydHkocGF0aCkge1xuICAgICAgcmV0dXJuIGlzS2V5KHBhdGgpID8gYmFzZVByb3BlcnR5KHRvS2V5KHBhdGgpKSA6IGJhc2VQcm9wZXJ0eURlZXAocGF0aCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIG9wcG9zaXRlIG9mIGBfLnByb3BlcnR5YDsgdGhpcyBtZXRob2QgY3JlYXRlcyBhIGZ1bmN0aW9uIHRoYXQgcmV0dXJuc1xuICAgICAqIHRoZSB2YWx1ZSBhdCBhIGdpdmVuIHBhdGggb2YgYG9iamVjdGAuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMy4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgVXRpbFxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBxdWVyeS5cbiAgICAgKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBhY2Nlc3NvciBmdW5jdGlvbi5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIGFycmF5ID0gWzAsIDEsIDJdLFxuICAgICAqICAgICBvYmplY3QgPSB7ICdhJzogYXJyYXksICdiJzogYXJyYXksICdjJzogYXJyYXkgfTtcbiAgICAgKlxuICAgICAqIF8ubWFwKFsnYVsyXScsICdjWzBdJ10sIF8ucHJvcGVydHlPZihvYmplY3QpKTtcbiAgICAgKiAvLyA9PiBbMiwgMF1cbiAgICAgKlxuICAgICAqIF8ubWFwKFtbJ2EnLCAnMiddLCBbJ2MnLCAnMCddXSwgXy5wcm9wZXJ0eU9mKG9iamVjdCkpO1xuICAgICAqIC8vID0+IFsyLCAwXVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIHByb3BlcnR5T2Yob2JqZWN0KSB7XG4gICAgICByZXR1cm4gZnVuY3Rpb24ocGF0aCkge1xuICAgICAgICByZXR1cm4gb2JqZWN0ID09IG51bGwgPyB1bmRlZmluZWQgOiBiYXNlR2V0KG9iamVjdCwgcGF0aCk7XG4gICAgICB9O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYW4gYXJyYXkgb2YgbnVtYmVycyAocG9zaXRpdmUgYW5kL29yIG5lZ2F0aXZlKSBwcm9ncmVzc2luZyBmcm9tXG4gICAgICogYHN0YXJ0YCB1cCB0bywgYnV0IG5vdCBpbmNsdWRpbmcsIGBlbmRgLiBBIHN0ZXAgb2YgYC0xYCBpcyB1c2VkIGlmIGEgbmVnYXRpdmVcbiAgICAgKiBgc3RhcnRgIGlzIHNwZWNpZmllZCB3aXRob3V0IGFuIGBlbmRgIG9yIGBzdGVwYC4gSWYgYGVuZGAgaXMgbm90IHNwZWNpZmllZCxcbiAgICAgKiBpdCdzIHNldCB0byBgc3RhcnRgIHdpdGggYHN0YXJ0YCB0aGVuIHNldCB0byBgMGAuXG4gICAgICpcbiAgICAgKiAqKk5vdGU6KiogSmF2YVNjcmlwdCBmb2xsb3dzIHRoZSBJRUVFLTc1NCBzdGFuZGFyZCBmb3IgcmVzb2x2aW5nXG4gICAgICogZmxvYXRpbmctcG9pbnQgdmFsdWVzIHdoaWNoIGNhbiBwcm9kdWNlIHVuZXhwZWN0ZWQgcmVzdWx0cy5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAc2luY2UgMC4xLjBcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBjYXRlZ29yeSBVdGlsXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtzdGFydD0wXSBUaGUgc3RhcnQgb2YgdGhlIHJhbmdlLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBlbmQgVGhlIGVuZCBvZiB0aGUgcmFuZ2UuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtzdGVwPTFdIFRoZSB2YWx1ZSB0byBpbmNyZW1lbnQgb3IgZGVjcmVtZW50IGJ5LlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgcmFuZ2Ugb2YgbnVtYmVycy5cbiAgICAgKiBAc2VlIF8uaW5SYW5nZSwgXy5yYW5nZVJpZ2h0XG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8ucmFuZ2UoNCk7XG4gICAgICogLy8gPT4gWzAsIDEsIDIsIDNdXG4gICAgICpcbiAgICAgKiBfLnJhbmdlKC00KTtcbiAgICAgKiAvLyA9PiBbMCwgLTEsIC0yLCAtM11cbiAgICAgKlxuICAgICAqIF8ucmFuZ2UoMSwgNSk7XG4gICAgICogLy8gPT4gWzEsIDIsIDMsIDRdXG4gICAgICpcbiAgICAgKiBfLnJhbmdlKDAsIDIwLCA1KTtcbiAgICAgKiAvLyA9PiBbMCwgNSwgMTAsIDE1XVxuICAgICAqXG4gICAgICogXy5yYW5nZSgwLCAtNCwgLTEpO1xuICAgICAqIC8vID0+IFswLCAtMSwgLTIsIC0zXVxuICAgICAqXG4gICAgICogXy5yYW5nZSgxLCA0LCAwKTtcbiAgICAgKiAvLyA9PiBbMSwgMSwgMV1cbiAgICAgKlxuICAgICAqIF8ucmFuZ2UoMCk7XG4gICAgICogLy8gPT4gW11cbiAgICAgKi9cbiAgICB2YXIgcmFuZ2UgPSBjcmVhdGVSYW5nZSgpO1xuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgaXMgbGlrZSBgXy5yYW5nZWAgZXhjZXB0IHRoYXQgaXQgcG9wdWxhdGVzIHZhbHVlcyBpblxuICAgICAqIGRlc2NlbmRpbmcgb3JkZXIuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgVXRpbFxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbc3RhcnQ9MF0gVGhlIHN0YXJ0IG9mIHRoZSByYW5nZS5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gZW5kIFRoZSBlbmQgb2YgdGhlIHJhbmdlLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbc3RlcD0xXSBUaGUgdmFsdWUgdG8gaW5jcmVtZW50IG9yIGRlY3JlbWVudCBieS5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIHJhbmdlIG9mIG51bWJlcnMuXG4gICAgICogQHNlZSBfLmluUmFuZ2UsIF8ucmFuZ2VcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5yYW5nZVJpZ2h0KDQpO1xuICAgICAqIC8vID0+IFszLCAyLCAxLCAwXVxuICAgICAqXG4gICAgICogXy5yYW5nZVJpZ2h0KC00KTtcbiAgICAgKiAvLyA9PiBbLTMsIC0yLCAtMSwgMF1cbiAgICAgKlxuICAgICAqIF8ucmFuZ2VSaWdodCgxLCA1KTtcbiAgICAgKiAvLyA9PiBbNCwgMywgMiwgMV1cbiAgICAgKlxuICAgICAqIF8ucmFuZ2VSaWdodCgwLCAyMCwgNSk7XG4gICAgICogLy8gPT4gWzE1LCAxMCwgNSwgMF1cbiAgICAgKlxuICAgICAqIF8ucmFuZ2VSaWdodCgwLCAtNCwgLTEpO1xuICAgICAqIC8vID0+IFstMywgLTIsIC0xLCAwXVxuICAgICAqXG4gICAgICogXy5yYW5nZVJpZ2h0KDEsIDQsIDApO1xuICAgICAqIC8vID0+IFsxLCAxLCAxXVxuICAgICAqXG4gICAgICogXy5yYW5nZVJpZ2h0KDApO1xuICAgICAqIC8vID0+IFtdXG4gICAgICovXG4gICAgdmFyIHJhbmdlUmlnaHQgPSBjcmVhdGVSYW5nZSh0cnVlKTtcblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIHJldHVybnMgYSBuZXcgZW1wdHkgYXJyYXkuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4xMy4wXG4gICAgICogQGNhdGVnb3J5IFV0aWxcbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIG5ldyBlbXB0eSBhcnJheS5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIGFycmF5cyA9IF8udGltZXMoMiwgXy5zdHViQXJyYXkpO1xuICAgICAqXG4gICAgICogY29uc29sZS5sb2coYXJyYXlzKTtcbiAgICAgKiAvLyA9PiBbW10sIFtdXVxuICAgICAqXG4gICAgICogY29uc29sZS5sb2coYXJyYXlzWzBdID09PSBhcnJheXNbMV0pO1xuICAgICAqIC8vID0+IGZhbHNlXG4gICAgICovXG4gICAgZnVuY3Rpb24gc3R1YkFycmF5KCkge1xuICAgICAgcmV0dXJuIFtdO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIHJldHVybnMgYGZhbHNlYC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjEzLjBcbiAgICAgKiBAY2F0ZWdvcnkgVXRpbFxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGBmYWxzZWAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8udGltZXMoMiwgXy5zdHViRmFsc2UpO1xuICAgICAqIC8vID0+IFtmYWxzZSwgZmFsc2VdXG4gICAgICovXG4gICAgZnVuY3Rpb24gc3R1YkZhbHNlKCkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIHJldHVybnMgYSBuZXcgZW1wdHkgb2JqZWN0LlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMTMuMFxuICAgICAqIEBjYXRlZ29yeSBVdGlsXG4gICAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyB0aGUgbmV3IGVtcHR5IG9iamVjdC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIG9iamVjdHMgPSBfLnRpbWVzKDIsIF8uc3R1Yk9iamVjdCk7XG4gICAgICpcbiAgICAgKiBjb25zb2xlLmxvZyhvYmplY3RzKTtcbiAgICAgKiAvLyA9PiBbe30sIHt9XVxuICAgICAqXG4gICAgICogY29uc29sZS5sb2cob2JqZWN0c1swXSA9PT0gb2JqZWN0c1sxXSk7XG4gICAgICogLy8gPT4gZmFsc2VcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBzdHViT2JqZWN0KCkge1xuICAgICAgcmV0dXJuIHt9O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIHJldHVybnMgYW4gZW1wdHkgc3RyaW5nLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMTMuMFxuICAgICAqIEBjYXRlZ29yeSBVdGlsXG4gICAgICogQHJldHVybnMge3N0cmluZ30gUmV0dXJucyB0aGUgZW1wdHkgc3RyaW5nLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLnRpbWVzKDIsIF8uc3R1YlN0cmluZyk7XG4gICAgICogLy8gPT4gWycnLCAnJ11cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBzdHViU3RyaW5nKCkge1xuICAgICAgcmV0dXJuICcnO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIHJldHVybnMgYHRydWVgLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMTMuMFxuICAgICAqIEBjYXRlZ29yeSBVdGlsXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLnRpbWVzKDIsIF8uc3R1YlRydWUpO1xuICAgICAqIC8vID0+IFt0cnVlLCB0cnVlXVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIHN0dWJUcnVlKCkge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogSW52b2tlcyB0aGUgaXRlcmF0ZWUgYG5gIHRpbWVzLCByZXR1cm5pbmcgYW4gYXJyYXkgb2YgdGhlIHJlc3VsdHMgb2ZcbiAgICAgKiBlYWNoIGludm9jYXRpb24uIFRoZSBpdGVyYXRlZSBpcyBpbnZva2VkIHdpdGggb25lIGFyZ3VtZW50OyAoaW5kZXgpLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBzaW5jZSAwLjEuMFxuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQGNhdGVnb3J5IFV0aWxcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gbiBUaGUgbnVtYmVyIG9mIHRpbWVzIHRvIGludm9rZSBgaXRlcmF0ZWVgLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IFtpdGVyYXRlZT1fLmlkZW50aXR5XSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgYXJyYXkgb2YgcmVzdWx0cy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy50aW1lcygzLCBTdHJpbmcpO1xuICAgICAqIC8vID0+IFsnMCcsICcxJywgJzInXVxuICAgICAqXG4gICAgICogIF8udGltZXMoNCwgXy5jb25zdGFudCgwKSk7XG4gICAgICogLy8gPT4gWzAsIDAsIDAsIDBdXG4gICAgICovXG4gICAgZnVuY3Rpb24gdGltZXMobiwgaXRlcmF0ZWUpIHtcbiAgICAgIG4gPSB0b0ludGVnZXIobik7XG4gICAgICBpZiAobiA8IDEgfHwgbiA+IE1BWF9TQUZFX0lOVEVHRVIpIHtcbiAgICAgICAgcmV0dXJuIFtdO1xuICAgICAgfVxuICAgICAgdmFyIGluZGV4ID0gTUFYX0FSUkFZX0xFTkdUSCxcbiAgICAgICAgICBsZW5ndGggPSBuYXRpdmVNaW4obiwgTUFYX0FSUkFZX0xFTkdUSCk7XG5cbiAgICAgIGl0ZXJhdGVlID0gZ2V0SXRlcmF0ZWUoaXRlcmF0ZWUpO1xuICAgICAgbiAtPSBNQVhfQVJSQVlfTEVOR1RIO1xuXG4gICAgICB2YXIgcmVzdWx0ID0gYmFzZVRpbWVzKGxlbmd0aCwgaXRlcmF0ZWUpO1xuICAgICAgd2hpbGUgKCsraW5kZXggPCBuKSB7XG4gICAgICAgIGl0ZXJhdGVlKGluZGV4KTtcbiAgICAgIH1cbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ29udmVydHMgYHZhbHVlYCB0byBhIHByb3BlcnR5IHBhdGggYXJyYXkuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgVXRpbFxuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNvbnZlcnQuXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBuZXcgcHJvcGVydHkgcGF0aCBhcnJheS5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy50b1BhdGgoJ2EuYi5jJyk7XG4gICAgICogLy8gPT4gWydhJywgJ2InLCAnYyddXG4gICAgICpcbiAgICAgKiBfLnRvUGF0aCgnYVswXS5iLmMnKTtcbiAgICAgKiAvLyA9PiBbJ2EnLCAnMCcsICdiJywgJ2MnXVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIHRvUGF0aCh2YWx1ZSkge1xuICAgICAgaWYgKGlzQXJyYXkodmFsdWUpKSB7XG4gICAgICAgIHJldHVybiBhcnJheU1hcCh2YWx1ZSwgdG9LZXkpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGlzU3ltYm9sKHZhbHVlKSA/IFt2YWx1ZV0gOiBjb3B5QXJyYXkoc3RyaW5nVG9QYXRoKHRvU3RyaW5nKHZhbHVlKSkpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdlbmVyYXRlcyBhIHVuaXF1ZSBJRC4gSWYgYHByZWZpeGAgaXMgZ2l2ZW4sIHRoZSBJRCBpcyBhcHBlbmRlZCB0byBpdC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAc2luY2UgMC4xLjBcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBjYXRlZ29yeSBVdGlsXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IFtwcmVmaXg9JyddIFRoZSB2YWx1ZSB0byBwcmVmaXggdGhlIElEIHdpdGguXG4gICAgICogQHJldHVybnMge3N0cmluZ30gUmV0dXJucyB0aGUgdW5pcXVlIElELlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLnVuaXF1ZUlkKCdjb250YWN0XycpO1xuICAgICAqIC8vID0+ICdjb250YWN0XzEwNCdcbiAgICAgKlxuICAgICAqIF8udW5pcXVlSWQoKTtcbiAgICAgKiAvLyA9PiAnMTA1J1xuICAgICAqL1xuICAgIGZ1bmN0aW9uIHVuaXF1ZUlkKHByZWZpeCkge1xuICAgICAgdmFyIGlkID0gKytpZENvdW50ZXI7XG4gICAgICByZXR1cm4gdG9TdHJpbmcocHJlZml4KSArIGlkO1xuICAgIH1cblxuICAgIC8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi9cblxuICAgIC8qKlxuICAgICAqIEFkZHMgdHdvIG51bWJlcnMuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMy40LjBcbiAgICAgKiBAY2F0ZWdvcnkgTWF0aFxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBhdWdlbmQgVGhlIGZpcnN0IG51bWJlciBpbiBhbiBhZGRpdGlvbi5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gYWRkZW5kIFRoZSBzZWNvbmQgbnVtYmVyIGluIGFuIGFkZGl0aW9uLlxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9IFJldHVybnMgdGhlIHRvdGFsLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLmFkZCg2LCA0KTtcbiAgICAgKiAvLyA9PiAxMFxuICAgICAqL1xuICAgIHZhciBhZGQgPSBjcmVhdGVNYXRoT3BlcmF0aW9uKGZ1bmN0aW9uKGF1Z2VuZCwgYWRkZW5kKSB7XG4gICAgICByZXR1cm4gYXVnZW5kICsgYWRkZW5kO1xuICAgIH0sIDApO1xuXG4gICAgLyoqXG4gICAgICogQ29tcHV0ZXMgYG51bWJlcmAgcm91bmRlZCB1cCB0byBgcHJlY2lzaW9uYC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAzLjEwLjBcbiAgICAgKiBAY2F0ZWdvcnkgTWF0aFxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBudW1iZXIgVGhlIG51bWJlciB0byByb3VuZCB1cC5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW3ByZWNpc2lvbj0wXSBUaGUgcHJlY2lzaW9uIHRvIHJvdW5kIHVwIHRvLlxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9IFJldHVybnMgdGhlIHJvdW5kZWQgdXAgbnVtYmVyLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLmNlaWwoNC4wMDYpO1xuICAgICAqIC8vID0+IDVcbiAgICAgKlxuICAgICAqIF8uY2VpbCg2LjAwNCwgMik7XG4gICAgICogLy8gPT4gNi4wMVxuICAgICAqXG4gICAgICogXy5jZWlsKDYwNDAsIC0yKTtcbiAgICAgKiAvLyA9PiA2MTAwXG4gICAgICovXG4gICAgdmFyIGNlaWwgPSBjcmVhdGVSb3VuZCgnY2VpbCcpO1xuXG4gICAgLyoqXG4gICAgICogRGl2aWRlIHR3byBudW1iZXJzLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuNy4wXG4gICAgICogQGNhdGVnb3J5IE1hdGhcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gZGl2aWRlbmQgVGhlIGZpcnN0IG51bWJlciBpbiBhIGRpdmlzaW9uLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBkaXZpc29yIFRoZSBzZWNvbmQgbnVtYmVyIGluIGEgZGl2aXNpb24uXG4gICAgICogQHJldHVybnMge251bWJlcn0gUmV0dXJucyB0aGUgcXVvdGllbnQuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uZGl2aWRlKDYsIDQpO1xuICAgICAqIC8vID0+IDEuNVxuICAgICAqL1xuICAgIHZhciBkaXZpZGUgPSBjcmVhdGVNYXRoT3BlcmF0aW9uKGZ1bmN0aW9uKGRpdmlkZW5kLCBkaXZpc29yKSB7XG4gICAgICByZXR1cm4gZGl2aWRlbmQgLyBkaXZpc29yO1xuICAgIH0sIDEpO1xuXG4gICAgLyoqXG4gICAgICogQ29tcHV0ZXMgYG51bWJlcmAgcm91bmRlZCBkb3duIHRvIGBwcmVjaXNpb25gLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDMuMTAuMFxuICAgICAqIEBjYXRlZ29yeSBNYXRoXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IG51bWJlciBUaGUgbnVtYmVyIHRvIHJvdW5kIGRvd24uXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtwcmVjaXNpb249MF0gVGhlIHByZWNpc2lvbiB0byByb3VuZCBkb3duIHRvLlxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9IFJldHVybnMgdGhlIHJvdW5kZWQgZG93biBudW1iZXIuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uZmxvb3IoNC4wMDYpO1xuICAgICAqIC8vID0+IDRcbiAgICAgKlxuICAgICAqIF8uZmxvb3IoMC4wNDYsIDIpO1xuICAgICAqIC8vID0+IDAuMDRcbiAgICAgKlxuICAgICAqIF8uZmxvb3IoNDA2MCwgLTIpO1xuICAgICAqIC8vID0+IDQwMDBcbiAgICAgKi9cbiAgICB2YXIgZmxvb3IgPSBjcmVhdGVSb3VuZCgnZmxvb3InKTtcblxuICAgIC8qKlxuICAgICAqIENvbXB1dGVzIHRoZSBtYXhpbXVtIHZhbHVlIG9mIGBhcnJheWAuIElmIGBhcnJheWAgaXMgZW1wdHkgb3IgZmFsc2V5LFxuICAgICAqIGB1bmRlZmluZWRgIGlzIHJldHVybmVkLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBzaW5jZSAwLjEuMFxuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQGNhdGVnb3J5IE1hdGhcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gaXRlcmF0ZSBvdmVyLlxuICAgICAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSBtYXhpbXVtIHZhbHVlLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLm1heChbNCwgMiwgOCwgNl0pO1xuICAgICAqIC8vID0+IDhcbiAgICAgKlxuICAgICAqIF8ubWF4KFtdKTtcbiAgICAgKiAvLyA9PiB1bmRlZmluZWRcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBtYXgoYXJyYXkpIHtcbiAgICAgIHJldHVybiAoYXJyYXkgJiYgYXJyYXkubGVuZ3RoKVxuICAgICAgICA/IGJhc2VFeHRyZW11bShhcnJheSwgaWRlbnRpdHksIGJhc2VHdClcbiAgICAgICAgOiB1bmRlZmluZWQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgaXMgbGlrZSBgXy5tYXhgIGV4Y2VwdCB0aGF0IGl0IGFjY2VwdHMgYGl0ZXJhdGVlYCB3aGljaCBpc1xuICAgICAqIGludm9rZWQgZm9yIGVhY2ggZWxlbWVudCBpbiBgYXJyYXlgIHRvIGdlbmVyYXRlIHRoZSBjcml0ZXJpb24gYnkgd2hpY2hcbiAgICAgKiB0aGUgdmFsdWUgaXMgcmFua2VkLiBUaGUgaXRlcmF0ZWUgaXMgaW52b2tlZCB3aXRoIG9uZSBhcmd1bWVudDogKHZhbHVlKS5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjAuMFxuICAgICAqIEBjYXRlZ29yeSBNYXRoXG4gICAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIGl0ZXJhdGUgb3Zlci5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbaXRlcmF0ZWU9Xy5pZGVudGl0eV0gVGhlIGl0ZXJhdGVlIGludm9rZWQgcGVyIGVsZW1lbnQuXG4gICAgICogQHJldHVybnMgeyp9IFJldHVybnMgdGhlIG1heGltdW0gdmFsdWUuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciBvYmplY3RzID0gW3sgJ24nOiAxIH0sIHsgJ24nOiAyIH1dO1xuICAgICAqXG4gICAgICogXy5tYXhCeShvYmplY3RzLCBmdW5jdGlvbihvKSB7IHJldHVybiBvLm47IH0pO1xuICAgICAqIC8vID0+IHsgJ24nOiAyIH1cbiAgICAgKlxuICAgICAqIC8vIFRoZSBgXy5wcm9wZXJ0eWAgaXRlcmF0ZWUgc2hvcnRoYW5kLlxuICAgICAqIF8ubWF4Qnkob2JqZWN0cywgJ24nKTtcbiAgICAgKiAvLyA9PiB7ICduJzogMiB9XG4gICAgICovXG4gICAgZnVuY3Rpb24gbWF4QnkoYXJyYXksIGl0ZXJhdGVlKSB7XG4gICAgICByZXR1cm4gKGFycmF5ICYmIGFycmF5Lmxlbmd0aClcbiAgICAgICAgPyBiYXNlRXh0cmVtdW0oYXJyYXksIGdldEl0ZXJhdGVlKGl0ZXJhdGVlLCAyKSwgYmFzZUd0KVxuICAgICAgICA6IHVuZGVmaW5lZDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDb21wdXRlcyB0aGUgbWVhbiBvZiB0aGUgdmFsdWVzIGluIGBhcnJheWAuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgTWF0aFxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBpdGVyYXRlIG92ZXIuXG4gICAgICogQHJldHVybnMge251bWJlcn0gUmV0dXJucyB0aGUgbWVhbi5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5tZWFuKFs0LCAyLCA4LCA2XSk7XG4gICAgICogLy8gPT4gNVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIG1lYW4oYXJyYXkpIHtcbiAgICAgIHJldHVybiBiYXNlTWVhbihhcnJheSwgaWRlbnRpdHkpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIGlzIGxpa2UgYF8ubWVhbmAgZXhjZXB0IHRoYXQgaXQgYWNjZXB0cyBgaXRlcmF0ZWVgIHdoaWNoIGlzXG4gICAgICogaW52b2tlZCBmb3IgZWFjaCBlbGVtZW50IGluIGBhcnJheWAgdG8gZ2VuZXJhdGUgdGhlIHZhbHVlIHRvIGJlIGF2ZXJhZ2VkLlxuICAgICAqIFRoZSBpdGVyYXRlZSBpcyBpbnZva2VkIHdpdGggb25lIGFyZ3VtZW50OiAodmFsdWUpLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuNy4wXG4gICAgICogQGNhdGVnb3J5IE1hdGhcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gaXRlcmF0ZSBvdmVyLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IFtpdGVyYXRlZT1fLmlkZW50aXR5XSBUaGUgaXRlcmF0ZWUgaW52b2tlZCBwZXIgZWxlbWVudC5cbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBSZXR1cm5zIHRoZSBtZWFuLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgb2JqZWN0cyA9IFt7ICduJzogNCB9LCB7ICduJzogMiB9LCB7ICduJzogOCB9LCB7ICduJzogNiB9XTtcbiAgICAgKlxuICAgICAqIF8ubWVhbkJ5KG9iamVjdHMsIGZ1bmN0aW9uKG8pIHsgcmV0dXJuIG8ubjsgfSk7XG4gICAgICogLy8gPT4gNVxuICAgICAqXG4gICAgICogLy8gVGhlIGBfLnByb3BlcnR5YCBpdGVyYXRlZSBzaG9ydGhhbmQuXG4gICAgICogXy5tZWFuQnkob2JqZWN0cywgJ24nKTtcbiAgICAgKiAvLyA9PiA1XG4gICAgICovXG4gICAgZnVuY3Rpb24gbWVhbkJ5KGFycmF5LCBpdGVyYXRlZSkge1xuICAgICAgcmV0dXJuIGJhc2VNZWFuKGFycmF5LCBnZXRJdGVyYXRlZShpdGVyYXRlZSwgMikpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENvbXB1dGVzIHRoZSBtaW5pbXVtIHZhbHVlIG9mIGBhcnJheWAuIElmIGBhcnJheWAgaXMgZW1wdHkgb3IgZmFsc2V5LFxuICAgICAqIGB1bmRlZmluZWRgIGlzIHJldHVybmVkLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBzaW5jZSAwLjEuMFxuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQGNhdGVnb3J5IE1hdGhcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gaXRlcmF0ZSBvdmVyLlxuICAgICAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSBtaW5pbXVtIHZhbHVlLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLm1pbihbNCwgMiwgOCwgNl0pO1xuICAgICAqIC8vID0+IDJcbiAgICAgKlxuICAgICAqIF8ubWluKFtdKTtcbiAgICAgKiAvLyA9PiB1bmRlZmluZWRcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBtaW4oYXJyYXkpIHtcbiAgICAgIHJldHVybiAoYXJyYXkgJiYgYXJyYXkubGVuZ3RoKVxuICAgICAgICA/IGJhc2VFeHRyZW11bShhcnJheSwgaWRlbnRpdHksIGJhc2VMdClcbiAgICAgICAgOiB1bmRlZmluZWQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgaXMgbGlrZSBgXy5taW5gIGV4Y2VwdCB0aGF0IGl0IGFjY2VwdHMgYGl0ZXJhdGVlYCB3aGljaCBpc1xuICAgICAqIGludm9rZWQgZm9yIGVhY2ggZWxlbWVudCBpbiBgYXJyYXlgIHRvIGdlbmVyYXRlIHRoZSBjcml0ZXJpb24gYnkgd2hpY2hcbiAgICAgKiB0aGUgdmFsdWUgaXMgcmFua2VkLiBUaGUgaXRlcmF0ZWUgaXMgaW52b2tlZCB3aXRoIG9uZSBhcmd1bWVudDogKHZhbHVlKS5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjAuMFxuICAgICAqIEBjYXRlZ29yeSBNYXRoXG4gICAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIGl0ZXJhdGUgb3Zlci5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbaXRlcmF0ZWU9Xy5pZGVudGl0eV0gVGhlIGl0ZXJhdGVlIGludm9rZWQgcGVyIGVsZW1lbnQuXG4gICAgICogQHJldHVybnMgeyp9IFJldHVybnMgdGhlIG1pbmltdW0gdmFsdWUuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciBvYmplY3RzID0gW3sgJ24nOiAxIH0sIHsgJ24nOiAyIH1dO1xuICAgICAqXG4gICAgICogXy5taW5CeShvYmplY3RzLCBmdW5jdGlvbihvKSB7IHJldHVybiBvLm47IH0pO1xuICAgICAqIC8vID0+IHsgJ24nOiAxIH1cbiAgICAgKlxuICAgICAqIC8vIFRoZSBgXy5wcm9wZXJ0eWAgaXRlcmF0ZWUgc2hvcnRoYW5kLlxuICAgICAqIF8ubWluQnkob2JqZWN0cywgJ24nKTtcbiAgICAgKiAvLyA9PiB7ICduJzogMSB9XG4gICAgICovXG4gICAgZnVuY3Rpb24gbWluQnkoYXJyYXksIGl0ZXJhdGVlKSB7XG4gICAgICByZXR1cm4gKGFycmF5ICYmIGFycmF5Lmxlbmd0aClcbiAgICAgICAgPyBiYXNlRXh0cmVtdW0oYXJyYXksIGdldEl0ZXJhdGVlKGl0ZXJhdGVlLCAyKSwgYmFzZUx0KVxuICAgICAgICA6IHVuZGVmaW5lZDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBNdWx0aXBseSB0d28gbnVtYmVycy5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjcuMFxuICAgICAqIEBjYXRlZ29yeSBNYXRoXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IG11bHRpcGxpZXIgVGhlIGZpcnN0IG51bWJlciBpbiBhIG11bHRpcGxpY2F0aW9uLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBtdWx0aXBsaWNhbmQgVGhlIHNlY29uZCBudW1iZXIgaW4gYSBtdWx0aXBsaWNhdGlvbi5cbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBSZXR1cm5zIHRoZSBwcm9kdWN0LlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLm11bHRpcGx5KDYsIDQpO1xuICAgICAqIC8vID0+IDI0XG4gICAgICovXG4gICAgdmFyIG11bHRpcGx5ID0gY3JlYXRlTWF0aE9wZXJhdGlvbihmdW5jdGlvbihtdWx0aXBsaWVyLCBtdWx0aXBsaWNhbmQpIHtcbiAgICAgIHJldHVybiBtdWx0aXBsaWVyICogbXVsdGlwbGljYW5kO1xuICAgIH0sIDEpO1xuXG4gICAgLyoqXG4gICAgICogQ29tcHV0ZXMgYG51bWJlcmAgcm91bmRlZCB0byBgcHJlY2lzaW9uYC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAzLjEwLjBcbiAgICAgKiBAY2F0ZWdvcnkgTWF0aFxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBudW1iZXIgVGhlIG51bWJlciB0byByb3VuZC5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW3ByZWNpc2lvbj0wXSBUaGUgcHJlY2lzaW9uIHRvIHJvdW5kIHRvLlxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9IFJldHVybnMgdGhlIHJvdW5kZWQgbnVtYmVyLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLnJvdW5kKDQuMDA2KTtcbiAgICAgKiAvLyA9PiA0XG4gICAgICpcbiAgICAgKiBfLnJvdW5kKDQuMDA2LCAyKTtcbiAgICAgKiAvLyA9PiA0LjAxXG4gICAgICpcbiAgICAgKiBfLnJvdW5kKDQwNjAsIC0yKTtcbiAgICAgKiAvLyA9PiA0MTAwXG4gICAgICovXG4gICAgdmFyIHJvdW5kID0gY3JlYXRlUm91bmQoJ3JvdW5kJyk7XG5cbiAgICAvKipcbiAgICAgKiBTdWJ0cmFjdCB0d28gbnVtYmVycy5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjAuMFxuICAgICAqIEBjYXRlZ29yeSBNYXRoXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IG1pbnVlbmQgVGhlIGZpcnN0IG51bWJlciBpbiBhIHN1YnRyYWN0aW9uLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBzdWJ0cmFoZW5kIFRoZSBzZWNvbmQgbnVtYmVyIGluIGEgc3VidHJhY3Rpb24uXG4gICAgICogQHJldHVybnMge251bWJlcn0gUmV0dXJucyB0aGUgZGlmZmVyZW5jZS5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5zdWJ0cmFjdCg2LCA0KTtcbiAgICAgKiAvLyA9PiAyXG4gICAgICovXG4gICAgdmFyIHN1YnRyYWN0ID0gY3JlYXRlTWF0aE9wZXJhdGlvbihmdW5jdGlvbihtaW51ZW5kLCBzdWJ0cmFoZW5kKSB7XG4gICAgICByZXR1cm4gbWludWVuZCAtIHN1YnRyYWhlbmQ7XG4gICAgfSwgMCk7XG5cbiAgICAvKipcbiAgICAgKiBDb21wdXRlcyB0aGUgc3VtIG9mIHRoZSB2YWx1ZXMgaW4gYGFycmF5YC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAzLjQuMFxuICAgICAqIEBjYXRlZ29yeSBNYXRoXG4gICAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIGl0ZXJhdGUgb3Zlci5cbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBSZXR1cm5zIHRoZSBzdW0uXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uc3VtKFs0LCAyLCA4LCA2XSk7XG4gICAgICogLy8gPT4gMjBcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBzdW0oYXJyYXkpIHtcbiAgICAgIHJldHVybiAoYXJyYXkgJiYgYXJyYXkubGVuZ3RoKVxuICAgICAgICA/IGJhc2VTdW0oYXJyYXksIGlkZW50aXR5KVxuICAgICAgICA6IDA7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgaXMgbGlrZSBgXy5zdW1gIGV4Y2VwdCB0aGF0IGl0IGFjY2VwdHMgYGl0ZXJhdGVlYCB3aGljaCBpc1xuICAgICAqIGludm9rZWQgZm9yIGVhY2ggZWxlbWVudCBpbiBgYXJyYXlgIHRvIGdlbmVyYXRlIHRoZSB2YWx1ZSB0byBiZSBzdW1tZWQuXG4gICAgICogVGhlIGl0ZXJhdGVlIGlzIGludm9rZWQgd2l0aCBvbmUgYXJndW1lbnQ6ICh2YWx1ZSkuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgTWF0aFxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBpdGVyYXRlIG92ZXIuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW2l0ZXJhdGVlPV8uaWRlbnRpdHldIFRoZSBpdGVyYXRlZSBpbnZva2VkIHBlciBlbGVtZW50LlxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9IFJldHVybnMgdGhlIHN1bS5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIG9iamVjdHMgPSBbeyAnbic6IDQgfSwgeyAnbic6IDIgfSwgeyAnbic6IDggfSwgeyAnbic6IDYgfV07XG4gICAgICpcbiAgICAgKiBfLnN1bUJ5KG9iamVjdHMsIGZ1bmN0aW9uKG8pIHsgcmV0dXJuIG8ubjsgfSk7XG4gICAgICogLy8gPT4gMjBcbiAgICAgKlxuICAgICAqIC8vIFRoZSBgXy5wcm9wZXJ0eWAgaXRlcmF0ZWUgc2hvcnRoYW5kLlxuICAgICAqIF8uc3VtQnkob2JqZWN0cywgJ24nKTtcbiAgICAgKiAvLyA9PiAyMFxuICAgICAqL1xuICAgIGZ1bmN0aW9uIHN1bUJ5KGFycmF5LCBpdGVyYXRlZSkge1xuICAgICAgcmV0dXJuIChhcnJheSAmJiBhcnJheS5sZW5ndGgpXG4gICAgICAgID8gYmFzZVN1bShhcnJheSwgZ2V0SXRlcmF0ZWUoaXRlcmF0ZWUsIDIpKVxuICAgICAgICA6IDA7XG4gICAgfVxuXG4gICAgLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuXG4gICAgLy8gQWRkIG1ldGhvZHMgdGhhdCByZXR1cm4gd3JhcHBlZCB2YWx1ZXMgaW4gY2hhaW4gc2VxdWVuY2VzLlxuICAgIGxvZGFzaC5hZnRlciA9IGFmdGVyO1xuICAgIGxvZGFzaC5hcnkgPSBhcnk7XG4gICAgbG9kYXNoLmFzc2lnbiA9IGFzc2lnbjtcbiAgICBsb2Rhc2guYXNzaWduSW4gPSBhc3NpZ25JbjtcbiAgICBsb2Rhc2guYXNzaWduSW5XaXRoID0gYXNzaWduSW5XaXRoO1xuICAgIGxvZGFzaC5hc3NpZ25XaXRoID0gYXNzaWduV2l0aDtcbiAgICBsb2Rhc2guYXQgPSBhdDtcbiAgICBsb2Rhc2guYmVmb3JlID0gYmVmb3JlO1xuICAgIGxvZGFzaC5iaW5kID0gYmluZDtcbiAgICBsb2Rhc2guYmluZEFsbCA9IGJpbmRBbGw7XG4gICAgbG9kYXNoLmJpbmRLZXkgPSBiaW5kS2V5O1xuICAgIGxvZGFzaC5jYXN0QXJyYXkgPSBjYXN0QXJyYXk7XG4gICAgbG9kYXNoLmNoYWluID0gY2hhaW47XG4gICAgbG9kYXNoLmNodW5rID0gY2h1bms7XG4gICAgbG9kYXNoLmNvbXBhY3QgPSBjb21wYWN0O1xuICAgIGxvZGFzaC5jb25jYXQgPSBjb25jYXQ7XG4gICAgbG9kYXNoLmNvbmQgPSBjb25kO1xuICAgIGxvZGFzaC5jb25mb3JtcyA9IGNvbmZvcm1zO1xuICAgIGxvZGFzaC5jb25zdGFudCA9IGNvbnN0YW50O1xuICAgIGxvZGFzaC5jb3VudEJ5ID0gY291bnRCeTtcbiAgICBsb2Rhc2guY3JlYXRlID0gY3JlYXRlO1xuICAgIGxvZGFzaC5jdXJyeSA9IGN1cnJ5O1xuICAgIGxvZGFzaC5jdXJyeVJpZ2h0ID0gY3VycnlSaWdodDtcbiAgICBsb2Rhc2guZGVib3VuY2UgPSBkZWJvdW5jZTtcbiAgICBsb2Rhc2guZGVmYXVsdHMgPSBkZWZhdWx0cztcbiAgICBsb2Rhc2guZGVmYXVsdHNEZWVwID0gZGVmYXVsdHNEZWVwO1xuICAgIGxvZGFzaC5kZWZlciA9IGRlZmVyO1xuICAgIGxvZGFzaC5kZWxheSA9IGRlbGF5O1xuICAgIGxvZGFzaC5kaWZmZXJlbmNlID0gZGlmZmVyZW5jZTtcbiAgICBsb2Rhc2guZGlmZmVyZW5jZUJ5ID0gZGlmZmVyZW5jZUJ5O1xuICAgIGxvZGFzaC5kaWZmZXJlbmNlV2l0aCA9IGRpZmZlcmVuY2VXaXRoO1xuICAgIGxvZGFzaC5kcm9wID0gZHJvcDtcbiAgICBsb2Rhc2guZHJvcFJpZ2h0ID0gZHJvcFJpZ2h0O1xuICAgIGxvZGFzaC5kcm9wUmlnaHRXaGlsZSA9IGRyb3BSaWdodFdoaWxlO1xuICAgIGxvZGFzaC5kcm9wV2hpbGUgPSBkcm9wV2hpbGU7XG4gICAgbG9kYXNoLmZpbGwgPSBmaWxsO1xuICAgIGxvZGFzaC5maWx0ZXIgPSBmaWx0ZXI7XG4gICAgbG9kYXNoLmZsYXRNYXAgPSBmbGF0TWFwO1xuICAgIGxvZGFzaC5mbGF0TWFwRGVlcCA9IGZsYXRNYXBEZWVwO1xuICAgIGxvZGFzaC5mbGF0TWFwRGVwdGggPSBmbGF0TWFwRGVwdGg7XG4gICAgbG9kYXNoLmZsYXR0ZW4gPSBmbGF0dGVuO1xuICAgIGxvZGFzaC5mbGF0dGVuRGVlcCA9IGZsYXR0ZW5EZWVwO1xuICAgIGxvZGFzaC5mbGF0dGVuRGVwdGggPSBmbGF0dGVuRGVwdGg7XG4gICAgbG9kYXNoLmZsaXAgPSBmbGlwO1xuICAgIGxvZGFzaC5mbG93ID0gZmxvdztcbiAgICBsb2Rhc2guZmxvd1JpZ2h0ID0gZmxvd1JpZ2h0O1xuICAgIGxvZGFzaC5mcm9tUGFpcnMgPSBmcm9tUGFpcnM7XG4gICAgbG9kYXNoLmZ1bmN0aW9ucyA9IGZ1bmN0aW9ucztcbiAgICBsb2Rhc2guZnVuY3Rpb25zSW4gPSBmdW5jdGlvbnNJbjtcbiAgICBsb2Rhc2guZ3JvdXBCeSA9IGdyb3VwQnk7XG4gICAgbG9kYXNoLmluaXRpYWwgPSBpbml0aWFsO1xuICAgIGxvZGFzaC5pbnRlcnNlY3Rpb24gPSBpbnRlcnNlY3Rpb247XG4gICAgbG9kYXNoLmludGVyc2VjdGlvbkJ5ID0gaW50ZXJzZWN0aW9uQnk7XG4gICAgbG9kYXNoLmludGVyc2VjdGlvbldpdGggPSBpbnRlcnNlY3Rpb25XaXRoO1xuICAgIGxvZGFzaC5pbnZlcnQgPSBpbnZlcnQ7XG4gICAgbG9kYXNoLmludmVydEJ5ID0gaW52ZXJ0Qnk7XG4gICAgbG9kYXNoLmludm9rZU1hcCA9IGludm9rZU1hcDtcbiAgICBsb2Rhc2guaXRlcmF0ZWUgPSBpdGVyYXRlZTtcbiAgICBsb2Rhc2gua2V5QnkgPSBrZXlCeTtcbiAgICBsb2Rhc2gua2V5cyA9IGtleXM7XG4gICAgbG9kYXNoLmtleXNJbiA9IGtleXNJbjtcbiAgICBsb2Rhc2gubWFwID0gbWFwO1xuICAgIGxvZGFzaC5tYXBLZXlzID0gbWFwS2V5cztcbiAgICBsb2Rhc2gubWFwVmFsdWVzID0gbWFwVmFsdWVzO1xuICAgIGxvZGFzaC5tYXRjaGVzID0gbWF0Y2hlcztcbiAgICBsb2Rhc2gubWF0Y2hlc1Byb3BlcnR5ID0gbWF0Y2hlc1Byb3BlcnR5O1xuICAgIGxvZGFzaC5tZW1vaXplID0gbWVtb2l6ZTtcbiAgICBsb2Rhc2gubWVyZ2UgPSBtZXJnZTtcbiAgICBsb2Rhc2gubWVyZ2VXaXRoID0gbWVyZ2VXaXRoO1xuICAgIGxvZGFzaC5tZXRob2QgPSBtZXRob2Q7XG4gICAgbG9kYXNoLm1ldGhvZE9mID0gbWV0aG9kT2Y7XG4gICAgbG9kYXNoLm1peGluID0gbWl4aW47XG4gICAgbG9kYXNoLm5lZ2F0ZSA9IG5lZ2F0ZTtcbiAgICBsb2Rhc2gubnRoQXJnID0gbnRoQXJnO1xuICAgIGxvZGFzaC5vbWl0ID0gb21pdDtcbiAgICBsb2Rhc2gub21pdEJ5ID0gb21pdEJ5O1xuICAgIGxvZGFzaC5vbmNlID0gb25jZTtcbiAgICBsb2Rhc2gub3JkZXJCeSA9IG9yZGVyQnk7XG4gICAgbG9kYXNoLm92ZXIgPSBvdmVyO1xuICAgIGxvZGFzaC5vdmVyQXJncyA9IG92ZXJBcmdzO1xuICAgIGxvZGFzaC5vdmVyRXZlcnkgPSBvdmVyRXZlcnk7XG4gICAgbG9kYXNoLm92ZXJTb21lID0gb3ZlclNvbWU7XG4gICAgbG9kYXNoLnBhcnRpYWwgPSBwYXJ0aWFsO1xuICAgIGxvZGFzaC5wYXJ0aWFsUmlnaHQgPSBwYXJ0aWFsUmlnaHQ7XG4gICAgbG9kYXNoLnBhcnRpdGlvbiA9IHBhcnRpdGlvbjtcbiAgICBsb2Rhc2gucGljayA9IHBpY2s7XG4gICAgbG9kYXNoLnBpY2tCeSA9IHBpY2tCeTtcbiAgICBsb2Rhc2gucHJvcGVydHkgPSBwcm9wZXJ0eTtcbiAgICBsb2Rhc2gucHJvcGVydHlPZiA9IHByb3BlcnR5T2Y7XG4gICAgbG9kYXNoLnB1bGwgPSBwdWxsO1xuICAgIGxvZGFzaC5wdWxsQWxsID0gcHVsbEFsbDtcbiAgICBsb2Rhc2gucHVsbEFsbEJ5ID0gcHVsbEFsbEJ5O1xuICAgIGxvZGFzaC5wdWxsQWxsV2l0aCA9IHB1bGxBbGxXaXRoO1xuICAgIGxvZGFzaC5wdWxsQXQgPSBwdWxsQXQ7XG4gICAgbG9kYXNoLnJhbmdlID0gcmFuZ2U7XG4gICAgbG9kYXNoLnJhbmdlUmlnaHQgPSByYW5nZVJpZ2h0O1xuICAgIGxvZGFzaC5yZWFyZyA9IHJlYXJnO1xuICAgIGxvZGFzaC5yZWplY3QgPSByZWplY3Q7XG4gICAgbG9kYXNoLnJlbW92ZSA9IHJlbW92ZTtcbiAgICBsb2Rhc2gucmVzdCA9IHJlc3Q7XG4gICAgbG9kYXNoLnJldmVyc2UgPSByZXZlcnNlO1xuICAgIGxvZGFzaC5zYW1wbGVTaXplID0gc2FtcGxlU2l6ZTtcbiAgICBsb2Rhc2guc2V0ID0gc2V0O1xuICAgIGxvZGFzaC5zZXRXaXRoID0gc2V0V2l0aDtcbiAgICBsb2Rhc2guc2h1ZmZsZSA9IHNodWZmbGU7XG4gICAgbG9kYXNoLnNsaWNlID0gc2xpY2U7XG4gICAgbG9kYXNoLnNvcnRCeSA9IHNvcnRCeTtcbiAgICBsb2Rhc2guc29ydGVkVW5pcSA9IHNvcnRlZFVuaXE7XG4gICAgbG9kYXNoLnNvcnRlZFVuaXFCeSA9IHNvcnRlZFVuaXFCeTtcbiAgICBsb2Rhc2guc3BsaXQgPSBzcGxpdDtcbiAgICBsb2Rhc2guc3ByZWFkID0gc3ByZWFkO1xuICAgIGxvZGFzaC50YWlsID0gdGFpbDtcbiAgICBsb2Rhc2gudGFrZSA9IHRha2U7XG4gICAgbG9kYXNoLnRha2VSaWdodCA9IHRha2VSaWdodDtcbiAgICBsb2Rhc2gudGFrZVJpZ2h0V2hpbGUgPSB0YWtlUmlnaHRXaGlsZTtcbiAgICBsb2Rhc2gudGFrZVdoaWxlID0gdGFrZVdoaWxlO1xuICAgIGxvZGFzaC50YXAgPSB0YXA7XG4gICAgbG9kYXNoLnRocm90dGxlID0gdGhyb3R0bGU7XG4gICAgbG9kYXNoLnRocnUgPSB0aHJ1O1xuICAgIGxvZGFzaC50b0FycmF5ID0gdG9BcnJheTtcbiAgICBsb2Rhc2gudG9QYWlycyA9IHRvUGFpcnM7XG4gICAgbG9kYXNoLnRvUGFpcnNJbiA9IHRvUGFpcnNJbjtcbiAgICBsb2Rhc2gudG9QYXRoID0gdG9QYXRoO1xuICAgIGxvZGFzaC50b1BsYWluT2JqZWN0ID0gdG9QbGFpbk9iamVjdDtcbiAgICBsb2Rhc2gudHJhbnNmb3JtID0gdHJhbnNmb3JtO1xuICAgIGxvZGFzaC51bmFyeSA9IHVuYXJ5O1xuICAgIGxvZGFzaC51bmlvbiA9IHVuaW9uO1xuICAgIGxvZGFzaC51bmlvbkJ5ID0gdW5pb25CeTtcbiAgICBsb2Rhc2gudW5pb25XaXRoID0gdW5pb25XaXRoO1xuICAgIGxvZGFzaC51bmlxID0gdW5pcTtcbiAgICBsb2Rhc2gudW5pcUJ5ID0gdW5pcUJ5O1xuICAgIGxvZGFzaC51bmlxV2l0aCA9IHVuaXFXaXRoO1xuICAgIGxvZGFzaC51bnNldCA9IHVuc2V0O1xuICAgIGxvZGFzaC51bnppcCA9IHVuemlwO1xuICAgIGxvZGFzaC51bnppcFdpdGggPSB1bnppcFdpdGg7XG4gICAgbG9kYXNoLnVwZGF0ZSA9IHVwZGF0ZTtcbiAgICBsb2Rhc2gudXBkYXRlV2l0aCA9IHVwZGF0ZVdpdGg7XG4gICAgbG9kYXNoLnZhbHVlcyA9IHZhbHVlcztcbiAgICBsb2Rhc2gudmFsdWVzSW4gPSB2YWx1ZXNJbjtcbiAgICBsb2Rhc2gud2l0aG91dCA9IHdpdGhvdXQ7XG4gICAgbG9kYXNoLndvcmRzID0gd29yZHM7XG4gICAgbG9kYXNoLndyYXAgPSB3cmFwO1xuICAgIGxvZGFzaC54b3IgPSB4b3I7XG4gICAgbG9kYXNoLnhvckJ5ID0geG9yQnk7XG4gICAgbG9kYXNoLnhvcldpdGggPSB4b3JXaXRoO1xuICAgIGxvZGFzaC56aXAgPSB6aXA7XG4gICAgbG9kYXNoLnppcE9iamVjdCA9IHppcE9iamVjdDtcbiAgICBsb2Rhc2guemlwT2JqZWN0RGVlcCA9IHppcE9iamVjdERlZXA7XG4gICAgbG9kYXNoLnppcFdpdGggPSB6aXBXaXRoO1xuXG4gICAgLy8gQWRkIGFsaWFzZXMuXG4gICAgbG9kYXNoLmVudHJpZXMgPSB0b1BhaXJzO1xuICAgIGxvZGFzaC5lbnRyaWVzSW4gPSB0b1BhaXJzSW47XG4gICAgbG9kYXNoLmV4dGVuZCA9IGFzc2lnbkluO1xuICAgIGxvZGFzaC5leHRlbmRXaXRoID0gYXNzaWduSW5XaXRoO1xuXG4gICAgLy8gQWRkIG1ldGhvZHMgdG8gYGxvZGFzaC5wcm90b3R5cGVgLlxuICAgIG1peGluKGxvZGFzaCwgbG9kYXNoKTtcblxuICAgIC8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi9cblxuICAgIC8vIEFkZCBtZXRob2RzIHRoYXQgcmV0dXJuIHVud3JhcHBlZCB2YWx1ZXMgaW4gY2hhaW4gc2VxdWVuY2VzLlxuICAgIGxvZGFzaC5hZGQgPSBhZGQ7XG4gICAgbG9kYXNoLmF0dGVtcHQgPSBhdHRlbXB0O1xuICAgIGxvZGFzaC5jYW1lbENhc2UgPSBjYW1lbENhc2U7XG4gICAgbG9kYXNoLmNhcGl0YWxpemUgPSBjYXBpdGFsaXplO1xuICAgIGxvZGFzaC5jZWlsID0gY2VpbDtcbiAgICBsb2Rhc2guY2xhbXAgPSBjbGFtcDtcbiAgICBsb2Rhc2guY2xvbmUgPSBjbG9uZTtcbiAgICBsb2Rhc2guY2xvbmVEZWVwID0gY2xvbmVEZWVwO1xuICAgIGxvZGFzaC5jbG9uZURlZXBXaXRoID0gY2xvbmVEZWVwV2l0aDtcbiAgICBsb2Rhc2guY2xvbmVXaXRoID0gY2xvbmVXaXRoO1xuICAgIGxvZGFzaC5jb25mb3Jtc1RvID0gY29uZm9ybXNUbztcbiAgICBsb2Rhc2guZGVidXJyID0gZGVidXJyO1xuICAgIGxvZGFzaC5kZWZhdWx0VG8gPSBkZWZhdWx0VG87XG4gICAgbG9kYXNoLmRpdmlkZSA9IGRpdmlkZTtcbiAgICBsb2Rhc2guZW5kc1dpdGggPSBlbmRzV2l0aDtcbiAgICBsb2Rhc2guZXEgPSBlcTtcbiAgICBsb2Rhc2guZXNjYXBlID0gZXNjYXBlO1xuICAgIGxvZGFzaC5lc2NhcGVSZWdFeHAgPSBlc2NhcGVSZWdFeHA7XG4gICAgbG9kYXNoLmV2ZXJ5ID0gZXZlcnk7XG4gICAgbG9kYXNoLmZpbmQgPSBmaW5kO1xuICAgIGxvZGFzaC5maW5kSW5kZXggPSBmaW5kSW5kZXg7XG4gICAgbG9kYXNoLmZpbmRLZXkgPSBmaW5kS2V5O1xuICAgIGxvZGFzaC5maW5kTGFzdCA9IGZpbmRMYXN0O1xuICAgIGxvZGFzaC5maW5kTGFzdEluZGV4ID0gZmluZExhc3RJbmRleDtcbiAgICBsb2Rhc2guZmluZExhc3RLZXkgPSBmaW5kTGFzdEtleTtcbiAgICBsb2Rhc2guZmxvb3IgPSBmbG9vcjtcbiAgICBsb2Rhc2guZm9yRWFjaCA9IGZvckVhY2g7XG4gICAgbG9kYXNoLmZvckVhY2hSaWdodCA9IGZvckVhY2hSaWdodDtcbiAgICBsb2Rhc2guZm9ySW4gPSBmb3JJbjtcbiAgICBsb2Rhc2guZm9ySW5SaWdodCA9IGZvckluUmlnaHQ7XG4gICAgbG9kYXNoLmZvck93biA9IGZvck93bjtcbiAgICBsb2Rhc2guZm9yT3duUmlnaHQgPSBmb3JPd25SaWdodDtcbiAgICBsb2Rhc2guZ2V0ID0gZ2V0O1xuICAgIGxvZGFzaC5ndCA9IGd0O1xuICAgIGxvZGFzaC5ndGUgPSBndGU7XG4gICAgbG9kYXNoLmhhcyA9IGhhcztcbiAgICBsb2Rhc2guaGFzSW4gPSBoYXNJbjtcbiAgICBsb2Rhc2guaGVhZCA9IGhlYWQ7XG4gICAgbG9kYXNoLmlkZW50aXR5ID0gaWRlbnRpdHk7XG4gICAgbG9kYXNoLmluY2x1ZGVzID0gaW5jbHVkZXM7XG4gICAgbG9kYXNoLmluZGV4T2YgPSBpbmRleE9mO1xuICAgIGxvZGFzaC5pblJhbmdlID0gaW5SYW5nZTtcbiAgICBsb2Rhc2guaW52b2tlID0gaW52b2tlO1xuICAgIGxvZGFzaC5pc0FyZ3VtZW50cyA9IGlzQXJndW1lbnRzO1xuICAgIGxvZGFzaC5pc0FycmF5ID0gaXNBcnJheTtcbiAgICBsb2Rhc2guaXNBcnJheUJ1ZmZlciA9IGlzQXJyYXlCdWZmZXI7XG4gICAgbG9kYXNoLmlzQXJyYXlMaWtlID0gaXNBcnJheUxpa2U7XG4gICAgbG9kYXNoLmlzQXJyYXlMaWtlT2JqZWN0ID0gaXNBcnJheUxpa2VPYmplY3Q7XG4gICAgbG9kYXNoLmlzQm9vbGVhbiA9IGlzQm9vbGVhbjtcbiAgICBsb2Rhc2guaXNCdWZmZXIgPSBpc0J1ZmZlcjtcbiAgICBsb2Rhc2guaXNEYXRlID0gaXNEYXRlO1xuICAgIGxvZGFzaC5pc0VsZW1lbnQgPSBpc0VsZW1lbnQ7XG4gICAgbG9kYXNoLmlzRW1wdHkgPSBpc0VtcHR5O1xuICAgIGxvZGFzaC5pc0VxdWFsID0gaXNFcXVhbDtcbiAgICBsb2Rhc2guaXNFcXVhbFdpdGggPSBpc0VxdWFsV2l0aDtcbiAgICBsb2Rhc2guaXNFcnJvciA9IGlzRXJyb3I7XG4gICAgbG9kYXNoLmlzRmluaXRlID0gaXNGaW5pdGU7XG4gICAgbG9kYXNoLmlzRnVuY3Rpb24gPSBpc0Z1bmN0aW9uO1xuICAgIGxvZGFzaC5pc0ludGVnZXIgPSBpc0ludGVnZXI7XG4gICAgbG9kYXNoLmlzTGVuZ3RoID0gaXNMZW5ndGg7XG4gICAgbG9kYXNoLmlzTWFwID0gaXNNYXA7XG4gICAgbG9kYXNoLmlzTWF0Y2ggPSBpc01hdGNoO1xuICAgIGxvZGFzaC5pc01hdGNoV2l0aCA9IGlzTWF0Y2hXaXRoO1xuICAgIGxvZGFzaC5pc05hTiA9IGlzTmFOO1xuICAgIGxvZGFzaC5pc05hdGl2ZSA9IGlzTmF0aXZlO1xuICAgIGxvZGFzaC5pc05pbCA9IGlzTmlsO1xuICAgIGxvZGFzaC5pc051bGwgPSBpc051bGw7XG4gICAgbG9kYXNoLmlzTnVtYmVyID0gaXNOdW1iZXI7XG4gICAgbG9kYXNoLmlzT2JqZWN0ID0gaXNPYmplY3Q7XG4gICAgbG9kYXNoLmlzT2JqZWN0TGlrZSA9IGlzT2JqZWN0TGlrZTtcbiAgICBsb2Rhc2guaXNQbGFpbk9iamVjdCA9IGlzUGxhaW5PYmplY3Q7XG4gICAgbG9kYXNoLmlzUmVnRXhwID0gaXNSZWdFeHA7XG4gICAgbG9kYXNoLmlzU2FmZUludGVnZXIgPSBpc1NhZmVJbnRlZ2VyO1xuICAgIGxvZGFzaC5pc1NldCA9IGlzU2V0O1xuICAgIGxvZGFzaC5pc1N0cmluZyA9IGlzU3RyaW5nO1xuICAgIGxvZGFzaC5pc1N5bWJvbCA9IGlzU3ltYm9sO1xuICAgIGxvZGFzaC5pc1R5cGVkQXJyYXkgPSBpc1R5cGVkQXJyYXk7XG4gICAgbG9kYXNoLmlzVW5kZWZpbmVkID0gaXNVbmRlZmluZWQ7XG4gICAgbG9kYXNoLmlzV2Vha01hcCA9IGlzV2Vha01hcDtcbiAgICBsb2Rhc2guaXNXZWFrU2V0ID0gaXNXZWFrU2V0O1xuICAgIGxvZGFzaC5qb2luID0gam9pbjtcbiAgICBsb2Rhc2gua2ViYWJDYXNlID0ga2ViYWJDYXNlO1xuICAgIGxvZGFzaC5sYXN0ID0gbGFzdDtcbiAgICBsb2Rhc2gubGFzdEluZGV4T2YgPSBsYXN0SW5kZXhPZjtcbiAgICBsb2Rhc2gubG93ZXJDYXNlID0gbG93ZXJDYXNlO1xuICAgIGxvZGFzaC5sb3dlckZpcnN0ID0gbG93ZXJGaXJzdDtcbiAgICBsb2Rhc2gubHQgPSBsdDtcbiAgICBsb2Rhc2gubHRlID0gbHRlO1xuICAgIGxvZGFzaC5tYXggPSBtYXg7XG4gICAgbG9kYXNoLm1heEJ5ID0gbWF4Qnk7XG4gICAgbG9kYXNoLm1lYW4gPSBtZWFuO1xuICAgIGxvZGFzaC5tZWFuQnkgPSBtZWFuQnk7XG4gICAgbG9kYXNoLm1pbiA9IG1pbjtcbiAgICBsb2Rhc2gubWluQnkgPSBtaW5CeTtcbiAgICBsb2Rhc2guc3R1YkFycmF5ID0gc3R1YkFycmF5O1xuICAgIGxvZGFzaC5zdHViRmFsc2UgPSBzdHViRmFsc2U7XG4gICAgbG9kYXNoLnN0dWJPYmplY3QgPSBzdHViT2JqZWN0O1xuICAgIGxvZGFzaC5zdHViU3RyaW5nID0gc3R1YlN0cmluZztcbiAgICBsb2Rhc2guc3R1YlRydWUgPSBzdHViVHJ1ZTtcbiAgICBsb2Rhc2gubXVsdGlwbHkgPSBtdWx0aXBseTtcbiAgICBsb2Rhc2gubnRoID0gbnRoO1xuICAgIGxvZGFzaC5ub0NvbmZsaWN0ID0gbm9Db25mbGljdDtcbiAgICBsb2Rhc2gubm9vcCA9IG5vb3A7XG4gICAgbG9kYXNoLm5vdyA9IG5vdztcbiAgICBsb2Rhc2gucGFkID0gcGFkO1xuICAgIGxvZGFzaC5wYWRFbmQgPSBwYWRFbmQ7XG4gICAgbG9kYXNoLnBhZFN0YXJ0ID0gcGFkU3RhcnQ7XG4gICAgbG9kYXNoLnBhcnNlSW50ID0gcGFyc2VJbnQ7XG4gICAgbG9kYXNoLnJhbmRvbSA9IHJhbmRvbTtcbiAgICBsb2Rhc2gucmVkdWNlID0gcmVkdWNlO1xuICAgIGxvZGFzaC5yZWR1Y2VSaWdodCA9IHJlZHVjZVJpZ2h0O1xuICAgIGxvZGFzaC5yZXBlYXQgPSByZXBlYXQ7XG4gICAgbG9kYXNoLnJlcGxhY2UgPSByZXBsYWNlO1xuICAgIGxvZGFzaC5yZXN1bHQgPSByZXN1bHQ7XG4gICAgbG9kYXNoLnJvdW5kID0gcm91bmQ7XG4gICAgbG9kYXNoLnJ1bkluQ29udGV4dCA9IHJ1bkluQ29udGV4dDtcbiAgICBsb2Rhc2guc2FtcGxlID0gc2FtcGxlO1xuICAgIGxvZGFzaC5zaXplID0gc2l6ZTtcbiAgICBsb2Rhc2guc25ha2VDYXNlID0gc25ha2VDYXNlO1xuICAgIGxvZGFzaC5zb21lID0gc29tZTtcbiAgICBsb2Rhc2guc29ydGVkSW5kZXggPSBzb3J0ZWRJbmRleDtcbiAgICBsb2Rhc2guc29ydGVkSW5kZXhCeSA9IHNvcnRlZEluZGV4Qnk7XG4gICAgbG9kYXNoLnNvcnRlZEluZGV4T2YgPSBzb3J0ZWRJbmRleE9mO1xuICAgIGxvZGFzaC5zb3J0ZWRMYXN0SW5kZXggPSBzb3J0ZWRMYXN0SW5kZXg7XG4gICAgbG9kYXNoLnNvcnRlZExhc3RJbmRleEJ5ID0gc29ydGVkTGFzdEluZGV4Qnk7XG4gICAgbG9kYXNoLnNvcnRlZExhc3RJbmRleE9mID0gc29ydGVkTGFzdEluZGV4T2Y7XG4gICAgbG9kYXNoLnN0YXJ0Q2FzZSA9IHN0YXJ0Q2FzZTtcbiAgICBsb2Rhc2guc3RhcnRzV2l0aCA9IHN0YXJ0c1dpdGg7XG4gICAgbG9kYXNoLnN1YnRyYWN0ID0gc3VidHJhY3Q7XG4gICAgbG9kYXNoLnN1bSA9IHN1bTtcbiAgICBsb2Rhc2guc3VtQnkgPSBzdW1CeTtcbiAgICBsb2Rhc2gudGVtcGxhdGUgPSB0ZW1wbGF0ZTtcbiAgICBsb2Rhc2gudGltZXMgPSB0aW1lcztcbiAgICBsb2Rhc2gudG9GaW5pdGUgPSB0b0Zpbml0ZTtcbiAgICBsb2Rhc2gudG9JbnRlZ2VyID0gdG9JbnRlZ2VyO1xuICAgIGxvZGFzaC50b0xlbmd0aCA9IHRvTGVuZ3RoO1xuICAgIGxvZGFzaC50b0xvd2VyID0gdG9Mb3dlcjtcbiAgICBsb2Rhc2gudG9OdW1iZXIgPSB0b051bWJlcjtcbiAgICBsb2Rhc2gudG9TYWZlSW50ZWdlciA9IHRvU2FmZUludGVnZXI7XG4gICAgbG9kYXNoLnRvU3RyaW5nID0gdG9TdHJpbmc7XG4gICAgbG9kYXNoLnRvVXBwZXIgPSB0b1VwcGVyO1xuICAgIGxvZGFzaC50cmltID0gdHJpbTtcbiAgICBsb2Rhc2gudHJpbUVuZCA9IHRyaW1FbmQ7XG4gICAgbG9kYXNoLnRyaW1TdGFydCA9IHRyaW1TdGFydDtcbiAgICBsb2Rhc2gudHJ1bmNhdGUgPSB0cnVuY2F0ZTtcbiAgICBsb2Rhc2gudW5lc2NhcGUgPSB1bmVzY2FwZTtcbiAgICBsb2Rhc2gudW5pcXVlSWQgPSB1bmlxdWVJZDtcbiAgICBsb2Rhc2gudXBwZXJDYXNlID0gdXBwZXJDYXNlO1xuICAgIGxvZGFzaC51cHBlckZpcnN0ID0gdXBwZXJGaXJzdDtcblxuICAgIC8vIEFkZCBhbGlhc2VzLlxuICAgIGxvZGFzaC5lYWNoID0gZm9yRWFjaDtcbiAgICBsb2Rhc2guZWFjaFJpZ2h0ID0gZm9yRWFjaFJpZ2h0O1xuICAgIGxvZGFzaC5maXJzdCA9IGhlYWQ7XG5cbiAgICBtaXhpbihsb2Rhc2gsIChmdW5jdGlvbigpIHtcbiAgICAgIHZhciBzb3VyY2UgPSB7fTtcbiAgICAgIGJhc2VGb3JPd24obG9kYXNoLCBmdW5jdGlvbihmdW5jLCBtZXRob2ROYW1lKSB7XG4gICAgICAgIGlmICghaGFzT3duUHJvcGVydHkuY2FsbChsb2Rhc2gucHJvdG90eXBlLCBtZXRob2ROYW1lKSkge1xuICAgICAgICAgIHNvdXJjZVttZXRob2ROYW1lXSA9IGZ1bmM7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgICAgcmV0dXJuIHNvdXJjZTtcbiAgICB9KCkpLCB7ICdjaGFpbic6IGZhbHNlIH0pO1xuXG4gICAgLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuXG4gICAgLyoqXG4gICAgICogVGhlIHNlbWFudGljIHZlcnNpb24gbnVtYmVyLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHR5cGUge3N0cmluZ31cbiAgICAgKi9cbiAgICBsb2Rhc2guVkVSU0lPTiA9IFZFUlNJT047XG5cbiAgICAvLyBBc3NpZ24gZGVmYXVsdCBwbGFjZWhvbGRlcnMuXG4gICAgYXJyYXlFYWNoKFsnYmluZCcsICdiaW5kS2V5JywgJ2N1cnJ5JywgJ2N1cnJ5UmlnaHQnLCAncGFydGlhbCcsICdwYXJ0aWFsUmlnaHQnXSwgZnVuY3Rpb24obWV0aG9kTmFtZSkge1xuICAgICAgbG9kYXNoW21ldGhvZE5hbWVdLnBsYWNlaG9sZGVyID0gbG9kYXNoO1xuICAgIH0pO1xuXG4gICAgLy8gQWRkIGBMYXp5V3JhcHBlcmAgbWV0aG9kcyBmb3IgYF8uZHJvcGAgYW5kIGBfLnRha2VgIHZhcmlhbnRzLlxuICAgIGFycmF5RWFjaChbJ2Ryb3AnLCAndGFrZSddLCBmdW5jdGlvbihtZXRob2ROYW1lLCBpbmRleCkge1xuICAgICAgTGF6eVdyYXBwZXIucHJvdG90eXBlW21ldGhvZE5hbWVdID0gZnVuY3Rpb24obikge1xuICAgICAgICBuID0gbiA9PT0gdW5kZWZpbmVkID8gMSA6IG5hdGl2ZU1heCh0b0ludGVnZXIobiksIDApO1xuXG4gICAgICAgIHZhciByZXN1bHQgPSAodGhpcy5fX2ZpbHRlcmVkX18gJiYgIWluZGV4KVxuICAgICAgICAgID8gbmV3IExhenlXcmFwcGVyKHRoaXMpXG4gICAgICAgICAgOiB0aGlzLmNsb25lKCk7XG5cbiAgICAgICAgaWYgKHJlc3VsdC5fX2ZpbHRlcmVkX18pIHtcbiAgICAgICAgICByZXN1bHQuX190YWtlQ291bnRfXyA9IG5hdGl2ZU1pbihuLCByZXN1bHQuX190YWtlQ291bnRfXyk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmVzdWx0Ll9fdmlld3NfXy5wdXNoKHtcbiAgICAgICAgICAgICdzaXplJzogbmF0aXZlTWluKG4sIE1BWF9BUlJBWV9MRU5HVEgpLFxuICAgICAgICAgICAgJ3R5cGUnOiBtZXRob2ROYW1lICsgKHJlc3VsdC5fX2Rpcl9fIDwgMCA/ICdSaWdodCcgOiAnJylcbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgfTtcblxuICAgICAgTGF6eVdyYXBwZXIucHJvdG90eXBlW21ldGhvZE5hbWUgKyAnUmlnaHQnXSA9IGZ1bmN0aW9uKG4pIHtcbiAgICAgICAgcmV0dXJuIHRoaXMucmV2ZXJzZSgpW21ldGhvZE5hbWVdKG4pLnJldmVyc2UoKTtcbiAgICAgIH07XG4gICAgfSk7XG5cbiAgICAvLyBBZGQgYExhenlXcmFwcGVyYCBtZXRob2RzIHRoYXQgYWNjZXB0IGFuIGBpdGVyYXRlZWAgdmFsdWUuXG4gICAgYXJyYXlFYWNoKFsnZmlsdGVyJywgJ21hcCcsICd0YWtlV2hpbGUnXSwgZnVuY3Rpb24obWV0aG9kTmFtZSwgaW5kZXgpIHtcbiAgICAgIHZhciB0eXBlID0gaW5kZXggKyAxLFxuICAgICAgICAgIGlzRmlsdGVyID0gdHlwZSA9PSBMQVpZX0ZJTFRFUl9GTEFHIHx8IHR5cGUgPT0gTEFaWV9XSElMRV9GTEFHO1xuXG4gICAgICBMYXp5V3JhcHBlci5wcm90b3R5cGVbbWV0aG9kTmFtZV0gPSBmdW5jdGlvbihpdGVyYXRlZSkge1xuICAgICAgICB2YXIgcmVzdWx0ID0gdGhpcy5jbG9uZSgpO1xuICAgICAgICByZXN1bHQuX19pdGVyYXRlZXNfXy5wdXNoKHtcbiAgICAgICAgICAnaXRlcmF0ZWUnOiBnZXRJdGVyYXRlZShpdGVyYXRlZSwgMyksXG4gICAgICAgICAgJ3R5cGUnOiB0eXBlXG4gICAgICAgIH0pO1xuICAgICAgICByZXN1bHQuX19maWx0ZXJlZF9fID0gcmVzdWx0Ll9fZmlsdGVyZWRfXyB8fCBpc0ZpbHRlcjtcbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgIH07XG4gICAgfSk7XG5cbiAgICAvLyBBZGQgYExhenlXcmFwcGVyYCBtZXRob2RzIGZvciBgXy5oZWFkYCBhbmQgYF8ubGFzdGAuXG4gICAgYXJyYXlFYWNoKFsnaGVhZCcsICdsYXN0J10sIGZ1bmN0aW9uKG1ldGhvZE5hbWUsIGluZGV4KSB7XG4gICAgICB2YXIgdGFrZU5hbWUgPSAndGFrZScgKyAoaW5kZXggPyAnUmlnaHQnIDogJycpO1xuXG4gICAgICBMYXp5V3JhcHBlci5wcm90b3R5cGVbbWV0aG9kTmFtZV0gPSBmdW5jdGlvbigpIHtcbiAgICAgICAgcmV0dXJuIHRoaXNbdGFrZU5hbWVdKDEpLnZhbHVlKClbMF07XG4gICAgICB9O1xuICAgIH0pO1xuXG4gICAgLy8gQWRkIGBMYXp5V3JhcHBlcmAgbWV0aG9kcyBmb3IgYF8uaW5pdGlhbGAgYW5kIGBfLnRhaWxgLlxuICAgIGFycmF5RWFjaChbJ2luaXRpYWwnLCAndGFpbCddLCBmdW5jdGlvbihtZXRob2ROYW1lLCBpbmRleCkge1xuICAgICAgdmFyIGRyb3BOYW1lID0gJ2Ryb3AnICsgKGluZGV4ID8gJycgOiAnUmlnaHQnKTtcblxuICAgICAgTGF6eVdyYXBwZXIucHJvdG90eXBlW21ldGhvZE5hbWVdID0gZnVuY3Rpb24oKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9fZmlsdGVyZWRfXyA/IG5ldyBMYXp5V3JhcHBlcih0aGlzKSA6IHRoaXNbZHJvcE5hbWVdKDEpO1xuICAgICAgfTtcbiAgICB9KTtcblxuICAgIExhenlXcmFwcGVyLnByb3RvdHlwZS5jb21wYWN0ID0gZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gdGhpcy5maWx0ZXIoaWRlbnRpdHkpO1xuICAgIH07XG5cbiAgICBMYXp5V3JhcHBlci5wcm90b3R5cGUuZmluZCA9IGZ1bmN0aW9uKHByZWRpY2F0ZSkge1xuICAgICAgcmV0dXJuIHRoaXMuZmlsdGVyKHByZWRpY2F0ZSkuaGVhZCgpO1xuICAgIH07XG5cbiAgICBMYXp5V3JhcHBlci5wcm90b3R5cGUuZmluZExhc3QgPSBmdW5jdGlvbihwcmVkaWNhdGUpIHtcbiAgICAgIHJldHVybiB0aGlzLnJldmVyc2UoKS5maW5kKHByZWRpY2F0ZSk7XG4gICAgfTtcblxuICAgIExhenlXcmFwcGVyLnByb3RvdHlwZS5pbnZva2VNYXAgPSBiYXNlUmVzdChmdW5jdGlvbihwYXRoLCBhcmdzKSB7XG4gICAgICBpZiAodHlwZW9mIHBhdGggPT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICByZXR1cm4gbmV3IExhenlXcmFwcGVyKHRoaXMpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHRoaXMubWFwKGZ1bmN0aW9uKHZhbHVlKSB7XG4gICAgICAgIHJldHVybiBiYXNlSW52b2tlKHZhbHVlLCBwYXRoLCBhcmdzKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgTGF6eVdyYXBwZXIucHJvdG90eXBlLnJlamVjdCA9IGZ1bmN0aW9uKHByZWRpY2F0ZSkge1xuICAgICAgcmV0dXJuIHRoaXMuZmlsdGVyKG5lZ2F0ZShnZXRJdGVyYXRlZShwcmVkaWNhdGUpKSk7XG4gICAgfTtcblxuICAgIExhenlXcmFwcGVyLnByb3RvdHlwZS5zbGljZSA9IGZ1bmN0aW9uKHN0YXJ0LCBlbmQpIHtcbiAgICAgIHN0YXJ0ID0gdG9JbnRlZ2VyKHN0YXJ0KTtcblxuICAgICAgdmFyIHJlc3VsdCA9IHRoaXM7XG4gICAgICBpZiAocmVzdWx0Ll9fZmlsdGVyZWRfXyAmJiAoc3RhcnQgPiAwIHx8IGVuZCA8IDApKSB7XG4gICAgICAgIHJldHVybiBuZXcgTGF6eVdyYXBwZXIocmVzdWx0KTtcbiAgICAgIH1cbiAgICAgIGlmIChzdGFydCA8IDApIHtcbiAgICAgICAgcmVzdWx0ID0gcmVzdWx0LnRha2VSaWdodCgtc3RhcnQpO1xuICAgICAgfSBlbHNlIGlmIChzdGFydCkge1xuICAgICAgICByZXN1bHQgPSByZXN1bHQuZHJvcChzdGFydCk7XG4gICAgICB9XG4gICAgICBpZiAoZW5kICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgZW5kID0gdG9JbnRlZ2VyKGVuZCk7XG4gICAgICAgIHJlc3VsdCA9IGVuZCA8IDAgPyByZXN1bHQuZHJvcFJpZ2h0KC1lbmQpIDogcmVzdWx0LnRha2UoZW5kIC0gc3RhcnQpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9O1xuXG4gICAgTGF6eVdyYXBwZXIucHJvdG90eXBlLnRha2VSaWdodFdoaWxlID0gZnVuY3Rpb24ocHJlZGljYXRlKSB7XG4gICAgICByZXR1cm4gdGhpcy5yZXZlcnNlKCkudGFrZVdoaWxlKHByZWRpY2F0ZSkucmV2ZXJzZSgpO1xuICAgIH07XG5cbiAgICBMYXp5V3JhcHBlci5wcm90b3R5cGUudG9BcnJheSA9IGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIHRoaXMudGFrZShNQVhfQVJSQVlfTEVOR1RIKTtcbiAgICB9O1xuXG4gICAgLy8gQWRkIGBMYXp5V3JhcHBlcmAgbWV0aG9kcyB0byBgbG9kYXNoLnByb3RvdHlwZWAuXG4gICAgYmFzZUZvck93bihMYXp5V3JhcHBlci5wcm90b3R5cGUsIGZ1bmN0aW9uKGZ1bmMsIG1ldGhvZE5hbWUpIHtcbiAgICAgIHZhciBjaGVja0l0ZXJhdGVlID0gL14oPzpmaWx0ZXJ8ZmluZHxtYXB8cmVqZWN0KXxXaGlsZSQvLnRlc3QobWV0aG9kTmFtZSksXG4gICAgICAgICAgaXNUYWtlciA9IC9eKD86aGVhZHxsYXN0KSQvLnRlc3QobWV0aG9kTmFtZSksXG4gICAgICAgICAgbG9kYXNoRnVuYyA9IGxvZGFzaFtpc1Rha2VyID8gKCd0YWtlJyArIChtZXRob2ROYW1lID09ICdsYXN0JyA/ICdSaWdodCcgOiAnJykpIDogbWV0aG9kTmFtZV0sXG4gICAgICAgICAgcmV0VW53cmFwcGVkID0gaXNUYWtlciB8fCAvXmZpbmQvLnRlc3QobWV0aG9kTmFtZSk7XG5cbiAgICAgIGlmICghbG9kYXNoRnVuYykge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBsb2Rhc2gucHJvdG90eXBlW21ldGhvZE5hbWVdID0gZnVuY3Rpb24oKSB7XG4gICAgICAgIHZhciB2YWx1ZSA9IHRoaXMuX193cmFwcGVkX18sXG4gICAgICAgICAgICBhcmdzID0gaXNUYWtlciA/IFsxXSA6IGFyZ3VtZW50cyxcbiAgICAgICAgICAgIGlzTGF6eSA9IHZhbHVlIGluc3RhbmNlb2YgTGF6eVdyYXBwZXIsXG4gICAgICAgICAgICBpdGVyYXRlZSA9IGFyZ3NbMF0sXG4gICAgICAgICAgICB1c2VMYXp5ID0gaXNMYXp5IHx8IGlzQXJyYXkodmFsdWUpO1xuXG4gICAgICAgIHZhciBpbnRlcmNlcHRvciA9IGZ1bmN0aW9uKHZhbHVlKSB7XG4gICAgICAgICAgdmFyIHJlc3VsdCA9IGxvZGFzaEZ1bmMuYXBwbHkobG9kYXNoLCBhcnJheVB1c2goW3ZhbHVlXSwgYXJncykpO1xuICAgICAgICAgIHJldHVybiAoaXNUYWtlciAmJiBjaGFpbkFsbCkgPyByZXN1bHRbMF0gOiByZXN1bHQ7XG4gICAgICAgIH07XG5cbiAgICAgICAgaWYgKHVzZUxhenkgJiYgY2hlY2tJdGVyYXRlZSAmJiB0eXBlb2YgaXRlcmF0ZWUgPT0gJ2Z1bmN0aW9uJyAmJiBpdGVyYXRlZS5sZW5ndGggIT0gMSkge1xuICAgICAgICAgIC8vIEF2b2lkIGxhenkgdXNlIGlmIHRoZSBpdGVyYXRlZSBoYXMgYSBcImxlbmd0aFwiIHZhbHVlIG90aGVyIHRoYW4gYDFgLlxuICAgICAgICAgIGlzTGF6eSA9IHVzZUxhenkgPSBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICB2YXIgY2hhaW5BbGwgPSB0aGlzLl9fY2hhaW5fXyxcbiAgICAgICAgICAgIGlzSHlicmlkID0gISF0aGlzLl9fYWN0aW9uc19fLmxlbmd0aCxcbiAgICAgICAgICAgIGlzVW53cmFwcGVkID0gcmV0VW53cmFwcGVkICYmICFjaGFpbkFsbCxcbiAgICAgICAgICAgIG9ubHlMYXp5ID0gaXNMYXp5ICYmICFpc0h5YnJpZDtcblxuICAgICAgICBpZiAoIXJldFVud3JhcHBlZCAmJiB1c2VMYXp5KSB7XG4gICAgICAgICAgdmFsdWUgPSBvbmx5TGF6eSA/IHZhbHVlIDogbmV3IExhenlXcmFwcGVyKHRoaXMpO1xuICAgICAgICAgIHZhciByZXN1bHQgPSBmdW5jLmFwcGx5KHZhbHVlLCBhcmdzKTtcbiAgICAgICAgICByZXN1bHQuX19hY3Rpb25zX18ucHVzaCh7ICdmdW5jJzogdGhydSwgJ2FyZ3MnOiBbaW50ZXJjZXB0b3JdLCAndGhpc0FyZyc6IHVuZGVmaW5lZCB9KTtcbiAgICAgICAgICByZXR1cm4gbmV3IExvZGFzaFdyYXBwZXIocmVzdWx0LCBjaGFpbkFsbCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGlzVW53cmFwcGVkICYmIG9ubHlMYXp5KSB7XG4gICAgICAgICAgcmV0dXJuIGZ1bmMuYXBwbHkodGhpcywgYXJncyk7XG4gICAgICAgIH1cbiAgICAgICAgcmVzdWx0ID0gdGhpcy50aHJ1KGludGVyY2VwdG9yKTtcbiAgICAgICAgcmV0dXJuIGlzVW53cmFwcGVkID8gKGlzVGFrZXIgPyByZXN1bHQudmFsdWUoKVswXSA6IHJlc3VsdC52YWx1ZSgpKSA6IHJlc3VsdDtcbiAgICAgIH07XG4gICAgfSk7XG5cbiAgICAvLyBBZGQgYEFycmF5YCBtZXRob2RzIHRvIGBsb2Rhc2gucHJvdG90eXBlYC5cbiAgICBhcnJheUVhY2goWydwb3AnLCAncHVzaCcsICdzaGlmdCcsICdzb3J0JywgJ3NwbGljZScsICd1bnNoaWZ0J10sIGZ1bmN0aW9uKG1ldGhvZE5hbWUpIHtcbiAgICAgIHZhciBmdW5jID0gYXJyYXlQcm90b1ttZXRob2ROYW1lXSxcbiAgICAgICAgICBjaGFpbk5hbWUgPSAvXig/OnB1c2h8c29ydHx1bnNoaWZ0KSQvLnRlc3QobWV0aG9kTmFtZSkgPyAndGFwJyA6ICd0aHJ1JyxcbiAgICAgICAgICByZXRVbndyYXBwZWQgPSAvXig/OnBvcHxzaGlmdCkkLy50ZXN0KG1ldGhvZE5hbWUpO1xuXG4gICAgICBsb2Rhc2gucHJvdG90eXBlW21ldGhvZE5hbWVdID0gZnVuY3Rpb24oKSB7XG4gICAgICAgIHZhciBhcmdzID0gYXJndW1lbnRzO1xuICAgICAgICBpZiAocmV0VW53cmFwcGVkICYmICF0aGlzLl9fY2hhaW5fXykge1xuICAgICAgICAgIHZhciB2YWx1ZSA9IHRoaXMudmFsdWUoKTtcbiAgICAgICAgICByZXR1cm4gZnVuYy5hcHBseShpc0FycmF5KHZhbHVlKSA/IHZhbHVlIDogW10sIGFyZ3MpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzW2NoYWluTmFtZV0oZnVuY3Rpb24odmFsdWUpIHtcbiAgICAgICAgICByZXR1cm4gZnVuYy5hcHBseShpc0FycmF5KHZhbHVlKSA/IHZhbHVlIDogW10sIGFyZ3MpO1xuICAgICAgICB9KTtcbiAgICAgIH07XG4gICAgfSk7XG5cbiAgICAvLyBNYXAgbWluaWZpZWQgbWV0aG9kIG5hbWVzIHRvIHRoZWlyIHJlYWwgbmFtZXMuXG4gICAgYmFzZUZvck93bihMYXp5V3JhcHBlci5wcm90b3R5cGUsIGZ1bmN0aW9uKGZ1bmMsIG1ldGhvZE5hbWUpIHtcbiAgICAgIHZhciBsb2Rhc2hGdW5jID0gbG9kYXNoW21ldGhvZE5hbWVdO1xuICAgICAgaWYgKGxvZGFzaEZ1bmMpIHtcbiAgICAgICAgdmFyIGtleSA9IGxvZGFzaEZ1bmMubmFtZSArICcnO1xuICAgICAgICBpZiAoIWhhc093blByb3BlcnR5LmNhbGwocmVhbE5hbWVzLCBrZXkpKSB7XG4gICAgICAgICAgcmVhbE5hbWVzW2tleV0gPSBbXTtcbiAgICAgICAgfVxuICAgICAgICByZWFsTmFtZXNba2V5XS5wdXNoKHsgJ25hbWUnOiBtZXRob2ROYW1lLCAnZnVuYyc6IGxvZGFzaEZ1bmMgfSk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICByZWFsTmFtZXNbY3JlYXRlSHlicmlkKHVuZGVmaW5lZCwgV1JBUF9CSU5EX0tFWV9GTEFHKS5uYW1lXSA9IFt7XG4gICAgICAnbmFtZSc6ICd3cmFwcGVyJyxcbiAgICAgICdmdW5jJzogdW5kZWZpbmVkXG4gICAgfV07XG5cbiAgICAvLyBBZGQgbWV0aG9kcyB0byBgTGF6eVdyYXBwZXJgLlxuICAgIExhenlXcmFwcGVyLnByb3RvdHlwZS5jbG9uZSA9IGxhenlDbG9uZTtcbiAgICBMYXp5V3JhcHBlci5wcm90b3R5cGUucmV2ZXJzZSA9IGxhenlSZXZlcnNlO1xuICAgIExhenlXcmFwcGVyLnByb3RvdHlwZS52YWx1ZSA9IGxhenlWYWx1ZTtcblxuICAgIC8vIEFkZCBjaGFpbiBzZXF1ZW5jZSBtZXRob2RzIHRvIHRoZSBgbG9kYXNoYCB3cmFwcGVyLlxuICAgIGxvZGFzaC5wcm90b3R5cGUuYXQgPSB3cmFwcGVyQXQ7XG4gICAgbG9kYXNoLnByb3RvdHlwZS5jaGFpbiA9IHdyYXBwZXJDaGFpbjtcbiAgICBsb2Rhc2gucHJvdG90eXBlLmNvbW1pdCA9IHdyYXBwZXJDb21taXQ7XG4gICAgbG9kYXNoLnByb3RvdHlwZS5uZXh0ID0gd3JhcHBlck5leHQ7XG4gICAgbG9kYXNoLnByb3RvdHlwZS5wbGFudCA9IHdyYXBwZXJQbGFudDtcbiAgICBsb2Rhc2gucHJvdG90eXBlLnJldmVyc2UgPSB3cmFwcGVyUmV2ZXJzZTtcbiAgICBsb2Rhc2gucHJvdG90eXBlLnRvSlNPTiA9IGxvZGFzaC5wcm90b3R5cGUudmFsdWVPZiA9IGxvZGFzaC5wcm90b3R5cGUudmFsdWUgPSB3cmFwcGVyVmFsdWU7XG5cbiAgICAvLyBBZGQgbGF6eSBhbGlhc2VzLlxuICAgIGxvZGFzaC5wcm90b3R5cGUuZmlyc3QgPSBsb2Rhc2gucHJvdG90eXBlLmhlYWQ7XG5cbiAgICBpZiAoc3ltSXRlcmF0b3IpIHtcbiAgICAgIGxvZGFzaC5wcm90b3R5cGVbc3ltSXRlcmF0b3JdID0gd3JhcHBlclRvSXRlcmF0b3I7XG4gICAgfVxuICAgIHJldHVybiBsb2Rhc2g7XG4gIH0pO1xuXG4gIC8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuXG4gIC8vIEV4cG9ydCBsb2Rhc2guXG4gIHZhciBfID0gcnVuSW5Db250ZXh0KCk7XG5cbiAgLy8gU29tZSBBTUQgYnVpbGQgb3B0aW1pemVycywgbGlrZSByLmpzLCBjaGVjayBmb3IgY29uZGl0aW9uIHBhdHRlcm5zIGxpa2U6XG4gIGlmICh0eXBlb2YgZGVmaW5lID09ICdmdW5jdGlvbicgJiYgdHlwZW9mIGRlZmluZS5hbWQgPT0gJ29iamVjdCcgJiYgZGVmaW5lLmFtZCkge1xuICAgIC8vIEV4cG9zZSBMb2Rhc2ggb24gdGhlIGdsb2JhbCBvYmplY3QgdG8gcHJldmVudCBlcnJvcnMgd2hlbiBMb2Rhc2ggaXNcbiAgICAvLyBsb2FkZWQgYnkgYSBzY3JpcHQgdGFnIGluIHRoZSBwcmVzZW5jZSBvZiBhbiBBTUQgbG9hZGVyLlxuICAgIC8vIFNlZSBodHRwOi8vcmVxdWlyZWpzLm9yZy9kb2NzL2Vycm9ycy5odG1sI21pc21hdGNoIGZvciBtb3JlIGRldGFpbHMuXG4gICAgLy8gVXNlIGBfLm5vQ29uZmxpY3RgIHRvIHJlbW92ZSBMb2Rhc2ggZnJvbSB0aGUgZ2xvYmFsIG9iamVjdC5cbiAgICByb290Ll8gPSBfO1xuXG4gICAgLy8gRGVmaW5lIGFzIGFuIGFub255bW91cyBtb2R1bGUgc28sIHRocm91Z2ggcGF0aCBtYXBwaW5nLCBpdCBjYW4gYmVcbiAgICAvLyByZWZlcmVuY2VkIGFzIHRoZSBcInVuZGVyc2NvcmVcIiBtb2R1bGUuXG4gICAgZGVmaW5lKGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIF87XG4gICAgfSk7XG4gIH1cbiAgLy8gQ2hlY2sgZm9yIGBleHBvcnRzYCBhZnRlciBgZGVmaW5lYCBpbiBjYXNlIGEgYnVpbGQgb3B0aW1pemVyIGFkZHMgaXQuXG4gIGVsc2UgaWYgKGZyZWVNb2R1bGUpIHtcbiAgICAvLyBFeHBvcnQgZm9yIE5vZGUuanMuXG4gICAgKGZyZWVNb2R1bGUuZXhwb3J0cyA9IF8pLl8gPSBfO1xuICAgIC8vIEV4cG9ydCBmb3IgQ29tbW9uSlMgc3VwcG9ydC5cbiAgICBmcmVlRXhwb3J0cy5fID0gXztcbiAgfVxuICBlbHNlIHtcbiAgICAvLyBFeHBvcnQgdG8gdGhlIGdsb2JhbCBvYmplY3QuXG4gICAgcm9vdC5fID0gXztcbiAgfVxufS5jYWxsKHRoaXMpKTtcbiIsImltcG9ydCB7IE91dGxpbmUsIFJhd091dGxpbmUgfSBmcm9tICcuL291dGxpbmUnO1xuaW1wb3J0IHsgQ3Vyc29yIH0gZnJvbSAnLi9jdXJzb3InO1xuaW1wb3J0IGtleWJvYXJkSlMgZnJvbSAna2V5Ym9hcmRqcyc7XG5pbXBvcnQgKiBhcyByYXdPdXRsaW5lIGZyb20gJy4vdGVzdC1kYXRhLmpzb24nO1xuaW1wb3J0IHtzaG93SGVscH0gZnJvbSAnaGVscCc7XG5cbmxldCBvdXRsaW5lRGF0YSA9IHJhd091dGxpbmU7XG5pZihsb2NhbFN0b3JhZ2UuZ2V0SXRlbSgnYWN0aXZlT3V0bGluZScpKSB7XG4gIGNvbnN0IG91dGxpbmVJZCA9IGxvY2FsU3RvcmFnZS5nZXRJdGVtKCdhY3RpdmVPdXRsaW5lJyk7XG4gIG91dGxpbmVEYXRhID0gSlNPTi5wYXJzZShsb2NhbFN0b3JhZ2UuZ2V0SXRlbShvdXRsaW5lSWQpKTtcbn1cblxuY29uc3Qgc3RhdGUgPSBuZXcgTWFwPHN0cmluZywgYW55PigpO1xuY29uc3Qgb3V0bGluZSA9IG5ldyBPdXRsaW5lKG91dGxpbmVEYXRhIGFzIHVua25vd24gYXMgUmF3T3V0bGluZSk7XG5vdXRsaW5lcigpLmlubmVySFRNTCA9IG91dGxpbmUucmVuZGVyKCk7XG5cbmNvbnN0IGN1cnNvciA9IG5ldyBDdXJzb3IoKTtcbi8vIHBsYWNlIHRoZSBjdXJzb3IgYXQgdGhlIHRvcCFcbmN1cnNvci5zZXQoJy5ub2RlJyk7XG5cbmZ1bmN0aW9uIG91dGxpbmVyKCkge1xuICByZXR1cm4gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI291dGxpbmVyJyk7XG59XG5cbmRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdkaXNwbGF5LWhlbHAnKS5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIGUgPT4ge1xuICBlLnByZXZlbnREZWZhdWx0KCk7XG4gIGUuc3RvcFByb3BhZ2F0aW9uKCk7XG5cbiAgc2hvd0hlbHAoKTtcbn0pO1xuXG4vLyBtb3ZlIGRvd25cbmtleWJvYXJkSlMud2l0aENvbnRleHQoJ25hdmlnYXRpb24nLCAoKSA9PiB7XG4gIGtleWJvYXJkSlMuYmluZCgnaicsIGUgPT4ge1xuICAgIC8vIG1vdmUgY3Vyc29yIGRvd25cbiAgICAvLyBpZiBzaGlmdCBrZXkgaXMgaGVsZCwgc3dhcCB0aGUgbm9kZSB3aXRoIGl0cyBuZXh0IHNpYmxpbmdcbiAgICBjb25zdCBzaWJsaW5nID0gY3Vyc29yLmdldCgpLm5leHRFbGVtZW50U2libGluZztcblxuICAgIGlmKHNpYmxpbmcpIHtcbiAgICAgIGlmKGUuc2hpZnRLZXkpIHtcbiAgICAgICAgLy8gc3dhcCB0aGlzIG5vZGUgd2l0aCBpdHMgcHJldmlvdXMgc2libGluZ1xuICAgICAgICBjb25zdCByZXMgPSBvdXRsaW5lLnN3YXBOb2RlV2l0aE5leHRTaWJsaW5nKGN1cnNvci5nZXRJZE9mTm9kZSgpKTtcbiAgICAgICAgY29uc3QgaHRtbCA9IG91dGxpbmUucmVuZGVyTm9kZShyZXMucGFyZW50Tm9kZSk7XG5cbiAgICAgICAgaWYocmVzLnBhcmVudE5vZGUuaWQgPT09ICcwMDAwMDAnKSB7XG4gICAgICAgICAgY3Vyc29yLmdldCgpLnBhcmVudEVsZW1lbnQuaW5uZXJIVE1MID0gaHRtbDtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICBjdXJzb3IuZ2V0KCkucGFyZW50RWxlbWVudC5vdXRlckhUTUwgPSBodG1sO1xuICAgICAgICB9XG5cbiAgICAgICAgY3Vyc29yLnNldChgI2lkLSR7cmVzLnRhcmdldE5vZGUuaWR9YCk7XG4gICAgICAgIHNhdmUoKTtcbiAgICAgIH1cbiAgICAgIGVsc2Uge1xuICAgICAgICBjdXJzb3Iuc2V0KGAjaWQtJHtzaWJsaW5nLmdldEF0dHJpYnV0ZSgnZGF0YS1pZCcpfWApO1xuICAgICAgfVxuICAgIH1cbiAgfSk7XG5cblxuICBrZXlib2FyZEpTLmJpbmQoJ3NoaWZ0ICsgLycsIGUgPT4ge1xuICAgIHNob3dIZWxwKCk7XG4gIH0pO1xuXG4gIGtleWJvYXJkSlMuYmluZCgnaycsIGUgPT4ge1xuICAgIC8vIG1vdmUgY3Vyc29yIHVwXG4gICAgLy8gaWYgc2hpZnQga2V5IGlzIGhlbGQsIHN3YXAgdGhlIG5vZGUgd2l0aCBpdHMgcHJldmlvdXMgc2libGluZ1xuICAgIGNvbnN0IHNpYmxpbmcgPSBjdXJzb3IuZ2V0KCkucHJldmlvdXNFbGVtZW50U2libGluZztcblxuICAgIGlmKHNpYmxpbmcgJiYgIXNpYmxpbmcuY2xhc3NMaXN0LmNvbnRhaW5zKCdub2RlQ29udGVudCcpKSB7XG4gICAgICBpZihlLnNoaWZ0S2V5KSB7XG4gICAgICAgIC8vIHN3YXAgdGhpcyBub2RlIHdpdGggaXRzIHByZXZpb3VzIHNpYmxpbmdcbiAgICAgICAgY29uc3QgcmVzID0gb3V0bGluZS5zd2FwTm9kZVdpdGhQcmV2aW91c1NpYmxpbmcoY3Vyc29yLmdldElkT2ZOb2RlKCkpO1xuICAgICAgICAvLyByZS1yZW5kZXIgdGhlIHBhcmVudCBub2RlIGFuZCBkaXNwbGF5IHRoYXQhXG4gICAgICAgIGNvbnN0IGh0bWwgPSBvdXRsaW5lLnJlbmRlck5vZGUocmVzLnBhcmVudE5vZGUpO1xuXG4gICAgICAgIGlmKHJlcy5wYXJlbnROb2RlLmlkID09PSAnMDAwMDAwJykge1xuICAgICAgICAgIGN1cnNvci5nZXQoKS5wYXJlbnRFbGVtZW50LmlubmVySFRNTCA9IGh0bWw7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgY3Vyc29yLmdldCgpLnBhcmVudEVsZW1lbnQub3V0ZXJIVE1MID0gaHRtbDtcbiAgICAgICAgfVxuXG4gICAgICAgIGN1cnNvci5zZXQoYCNpZC0ke3Jlcy50YXJnZXROb2RlLmlkfWApO1xuICAgICAgICBzYXZlKCk7XG4gICAgICB9XG4gICAgICBlbHNlIHtcbiAgICAgICAgY3Vyc29yLnNldChgI2lkLSR7c2libGluZy5nZXRBdHRyaWJ1dGUoJ2RhdGEtaWQnKX1gKTtcbiAgICAgIH1cbiAgICB9XG4gIH0pO1xuXG4gIGtleWJvYXJkSlMuYmluZCgnbCcsIGUgPT4ge1xuICAgIC8vIGlmIHRoZSBub2RlIGlzIGNvbGxhcHNlZCwgd2UgY2FuJ3QgZ28gaW50byBpdHMgY2hpbGRyZW5cbiAgICBpZihjdXJzb3IuaXNOb2RlQ29sbGFwc2VkKCkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaWYoZS5zaGlmdEtleSkge1xuICAgICAgY29uc3QgcmVzID0gb3V0bGluZS5sb3dlck5vZGVUb0NoaWxkKGN1cnNvci5nZXRJZE9mTm9kZSgpKTtcbiAgICAgIGNvbnN0IGh0bWwgPSBvdXRsaW5lLnJlbmRlck5vZGUocmVzLm9sZFBhcmVudE5vZGUpO1xuXG4gICAgICBpZihyZXMub2xkUGFyZW50Tm9kZS5pZCA9PT0gJzAwMDAwMCcpIHtcbiAgICAgICAgY3Vyc29yLmdldCgpLnBhcmVudEVsZW1lbnQuaW5uZXJIVE1MID0gaHRtbDtcbiAgICAgIH1cbiAgICAgIGVsc2Uge1xuICAgICAgICBjdXJzb3IuZ2V0KCkucGFyZW50RWxlbWVudC5vdXRlckhUTUwgPSBodG1sO1xuICAgICAgfVxuICAgICAgY3Vyc29yLnNldChgI2lkLSR7cmVzLnRhcmdldE5vZGUuaWR9YCk7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgY29uc3QgY2hpbGRyZW4gPSBjdXJzb3IuZ2V0KCkucXVlcnlTZWxlY3RvcignLm5vZGUnKTtcbiAgICAgIGlmKGNoaWxkcmVuKSB7XG4gICAgICAgIGN1cnNvci5zZXQoYCNpZC0ke2NoaWxkcmVuLmdldEF0dHJpYnV0ZSgnZGF0YS1pZCcpfWApO1xuICAgICAgfVxuICAgIH1cbiAgfSk7XG5cbiAga2V5Ym9hcmRKUy5iaW5kKCdoJywgZSA9PiB7XG4gICAgY29uc3QgcGFyZW50ID0gY3Vyc29yLmdldCgpLnBhcmVudEVsZW1lbnQ7XG4gICAgaWYocGFyZW50ICYmIHBhcmVudC5jbGFzc0xpc3QuY29udGFpbnMoJ25vZGUnKSkge1xuICAgICAgaWYoZS5zaGlmdEtleSkge1xuICAgICAgICBpZihvdXRsaW5lLmRhdGEudHJlZS5jaGlsZHJlbi5tYXAobiA9PiBuLmlkKS5pbmNsdWRlcyhjdXJzb3IuZ2V0SWRPZk5vZGUoKSkpIHtcbiAgICAgICAgICAvLyBpZiB0aGlzIGlzIGEgdG9wIGxldmVsIGl0ZW0sIHdlIGNhbid0IGVsZXZhdGUgYW55IGZ1cnRoZXJcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgcmVzID0gb3V0bGluZS5saWZ0Tm9kZVRvUGFyZW50KGN1cnNvci5nZXRJZE9mTm9kZSgpKTtcblxuICAgICAgICBjb25zdCBodG1sID0gb3V0bGluZS5yZW5kZXJOb2RlKHJlcy5wYXJlbnROb2RlKTtcblxuICAgICAgICBpZihyZXMucGFyZW50Tm9kZS5pZCA9PT0gJzAwMDAwMCcpIHtcbiAgICAgICAgICBjdXJzb3IuZ2V0KCkucGFyZW50RWxlbWVudC5wYXJlbnRFbGVtZW50LmlubmVySFRNTCA9IGh0bWw7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgY3Vyc29yLmdldCgpLnBhcmVudEVsZW1lbnQucGFyZW50RWxlbWVudC5vdXRlckhUTUwgPSBodG1sO1xuICAgICAgICB9XG5cbiAgICAgICAgY3Vyc29yLnNldChgI2lkLSR7cmVzLnRhcmdldE5vZGUuaWR9YCk7XG4gICAgICAgIHNhdmUoKTtcbiAgICAgIH1cbiAgICAgIGVsc2Uge1xuICAgICAgICBjdXJzb3Iuc2V0KGAjaWQtJHtwYXJlbnQuZ2V0QXR0cmlidXRlKCdkYXRhLWlkJyl9YCk7XG4gICAgICB9XG4gICAgfVxuICB9KTtcblxuICBrZXlib2FyZEpTLmJpbmQoJ3onLCBlID0+IHtcbiAgICAvLyB0b2dnbGUgY29sbGFwc2VcbiAgICBpZihjdXJzb3IuaXNOb2RlRXhwYW5kZWQoKSkge1xuICAgICAgY3Vyc29yLmNvbGxhcHNlKCk7XG4gICAgICBvdXRsaW5lLmZvbGQoY3Vyc29yLmdldElkT2ZOb2RlKCkpO1xuICAgIH1cbiAgICBlbHNlIGlmKGN1cnNvci5pc05vZGVDb2xsYXBzZWQoKSkge1xuICAgICAgY3Vyc29yLmV4cGFuZCgpO1xuICAgICAgb3V0bGluZS51bmZvbGQoY3Vyc29yLmdldElkT2ZOb2RlKCkpO1xuICAgIH1cbiAgICBzYXZlKCk7XG4gIH0pO1xuXG4gIGtleWJvYXJkSlMuYmluZCgnc2hpZnQgKyA0JywgZSA9PiB7XG4gICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgIC8vIHN3aXRjaCB0byBlZGl0aW5nIG1vZGVcbiAgICBjdXJzb3IuZ2V0KCkuY2xhc3NMaXN0LmFkZCgnaGlkZGVuLWN1cnNvcicpO1xuICAgIGNvbnN0IGNvbnRlbnROb2RlID0gY3Vyc29yLmdldCgpLnF1ZXJ5U2VsZWN0b3IoJy5ub2RlQ29udGVudCcpIGFzIEhUTUxFbGVtZW50O1xuXG4gICAgLy8gc3dhcCB0aGUgY29udGVudCB0byB0aGUgZGVmYXVsdCFcbiAgICBjb250ZW50Tm9kZS5pbm5lckhUTUwgPSBvdXRsaW5lLmRhdGEuY29udGVudE5vZGVzW2N1cnNvci5nZXRJZE9mTm9kZSgpXS5jb250ZW50O1xuICAgIGNvbnRlbnROb2RlLmNvbnRlbnRFZGl0YWJsZSA9IFwidHJ1ZVwiO1xuXG4gICAgY29uc3QgcmFuZ2UgPSBkb2N1bWVudC5jcmVhdGVSYW5nZSgpO1xuICAgIHJhbmdlLnNlbGVjdE5vZGVDb250ZW50cyhjb250ZW50Tm9kZSk7XG4gICAgcmFuZ2UuY29sbGFwc2UoZmFsc2UpO1xuXG4gICAgY29uc3Qgc2VsZWN0aW9uID0gd2luZG93LmdldFNlbGVjdGlvbigpO1xuICAgIHNlbGVjdGlvbi5yZW1vdmVBbGxSYW5nZXMoKTtcbiAgICBzZWxlY3Rpb24uYWRkUmFuZ2UocmFuZ2UpO1xuXG4gICAgY29udGVudE5vZGUuZm9jdXMoKTtcbiAgICBrZXlib2FyZEpTLnNldENvbnRleHQoJ2VkaXRpbmcnKTtcbiAgfSk7XG5cbiAga2V5Ym9hcmRKUy5iaW5kKCdpJywgZSA9PiB7XG4gICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgIC8vIHN3aXRjaCB0byBlZGl0aW5nIG1vZGVcbiAgICBjdXJzb3IuZ2V0KCkuY2xhc3NMaXN0LmFkZCgnaGlkZGVuLWN1cnNvcicpO1xuICAgIGNvbnN0IGNvbnRlbnROb2RlID0gY3Vyc29yLmdldCgpLnF1ZXJ5U2VsZWN0b3IoJy5ub2RlQ29udGVudCcpIGFzIEhUTUxFbGVtZW50O1xuXG4gICAgLy8gc3dhcCB0aGUgY29udGVudCB0byB0aGUgZGVmYXVsdCFcbiAgICBjb250ZW50Tm9kZS5pbm5lckhUTUwgPSBvdXRsaW5lLmRhdGEuY29udGVudE5vZGVzW2N1cnNvci5nZXRJZE9mTm9kZSgpXS5jb250ZW50O1xuICAgIGNvbnRlbnROb2RlLmNvbnRlbnRFZGl0YWJsZSA9IFwidHJ1ZVwiO1xuICAgIGNvbnRlbnROb2RlLmZvY3VzKCk7XG4gICAga2V5Ym9hcmRKUy5zZXRDb250ZXh0KCdlZGl0aW5nJyk7XG4gIH0pO1xuXG4gIGtleWJvYXJkSlMuYmluZCgndGFiJywgZSA9PiB7XG4gICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuXG4gICAgY29uc3QgcmVzID0gb3V0bGluZS5jcmVhdGVDaGlsZE5vZGUoY3Vyc29yLmdldElkT2ZOb2RlKCkpO1xuICAgIGNvbnN0IGh0bWwgPSBvdXRsaW5lLnJlbmRlck5vZGUocmVzLnBhcmVudE5vZGUpO1xuXG4gICAgY3Vyc29yLmdldCgpLm91dGVySFRNTCA9IGh0bWw7XG5cbiAgICBjdXJzb3Iuc2V0KGAjaWQtJHtyZXMubm9kZS5pZH1gKTtcbiAgICBzYXZlKCk7XG4gIH0pO1xuICBcbiAga2V5Ym9hcmRKUy5iaW5kKCdlbnRlcicsIGUgPT4ge1xuICAgIC8vIGNyZWF0ZSBhIG5ldyBub2RlIGFzIGEgc2libGluZyBvZiB0aGUgc2VsZWN0ZWQgbm9kZVxuICAgIGlmKGUuc2hpZnRLZXkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgIGUucHJldmVudFJlcGVhdCgpO1xuXG4gICAgY29uc3QgcmVzID0gb3V0bGluZS5jcmVhdGVTaWJsaW5nTm9kZShjdXJzb3IuZ2V0SWRPZk5vZGUoKSk7XG5cbiAgICBjb25zdCBodG1sID0gb3V0bGluZS5yZW5kZXJOb2RlKHJlcy5wYXJlbnROb2RlKTtcbiAgICBpZihyZXMucGFyZW50Tm9kZS5pZCA9PT0gJzAwMDAwMCcpIHtcbiAgICAgIGN1cnNvci5nZXQoKS5wYXJlbnRFbGVtZW50LmlubmVySFRNTCA9IGh0bWw7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgY3Vyc29yLmdldCgpLnBhcmVudEVsZW1lbnQub3V0ZXJIVE1MID0gaHRtbDtcbiAgICB9XG5cbiAgICBjdXJzb3Iuc2V0KGAjaWQtJHtyZXMubm9kZS5pZH1gKTtcbiAgICBzYXZlKCk7XG4gIH0pO1xuXG4gIGtleWJvYXJkSlMuYmluZCgnZCcsIGUgPT4ge1xuICAgIC8vIGRlbGV0aW5nIGEgbm9kZSByZXF1aXJlcyBkICsgc2hpZnRcbiAgICBpZighZS5zaGlmdEtleSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IHJlcyA9IG91dGxpbmUucmVtb3ZlTm9kZShjdXJzb3IuZ2V0SWRPZk5vZGUoKSk7XG4gICAgY29uc3QgaHRtbCA9IG91dGxpbmUucmVuZGVyTm9kZShyZXMucGFyZW50Tm9kZSk7XG4gICAgLy8gdGhlIHByZXZpb3VzIHNpYmxpbmchXG4gICAgY29uc3QgcHJldlNpYmxpbmcgPSBjdXJzb3IuZ2V0KCkucHJldmlvdXNFbGVtZW50U2libGluZztcbiAgICBjb25zdCBuZXh0U2libGluZyA9IGN1cnNvci5nZXQoKS5uZXh0RWxlbWVudFNpYmxpbmc7XG4gICAgaWYocmVzLnBhcmVudE5vZGUuaWQgPT09ICcwMDAwMDAnKSB7XG4gICAgICBjdXJzb3IuZ2V0KCkucGFyZW50RWxlbWVudC5pbm5lckhUTUwgPSBodG1sO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgIGN1cnNvci5nZXQoKS5wYXJlbnRFbGVtZW50Lm91dGVySFRNTCA9IGh0bWw7XG4gICAgfVxuXG4gICAgaWYocHJldlNpYmxpbmcuZ2V0QXR0cmlidXRlKCdkYXRhLWlkJykpIHtcbiAgICAgIGN1cnNvci5zZXQoYCNpZC0ke3ByZXZTaWJsaW5nLmdldEF0dHJpYnV0ZSgnZGF0YS1pZCcpfWApO1xuICAgIH1cbiAgICBlbHNlIGlmKG5leHRTaWJsaW5nLmdldEF0dHJpYnV0ZSgnZGF0YS1pZCcpKSB7XG4gICAgICBjdXJzb3Iuc2V0KGAjaWQtJHtuZXh0U2libGluZy5nZXRBdHRyaWJ1dGUoJ2RhdGEtaWQnKX1gKTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICBjb25zb2xlLmxvZyhyZXMucGFyZW50Tm9kZS5pZCk7XG4gICAgICBjdXJzb3Iuc2V0KGAjaWQtJHtyZXMucGFyZW50Tm9kZS5pZH1gKTtcbiAgICB9XG5cbiAgICBzYXZlKCk7XG4gIH0pO1xufSk7XG5cbmtleWJvYXJkSlMud2l0aENvbnRleHQoJ2VkaXRpbmcnLCAoKSA9PiB7XG4gIGtleWJvYXJkSlMuYmluZChbJ2VzYycsICdlbnRlciddLCBlID0+IHtcbiAgICBjdXJzb3IuZ2V0KCkuY2xhc3NMaXN0LnJlbW92ZSgnaGlkZGVuLWN1cnNvcicpO1xuXG4gICAgY29uc3QgY29udGVudE5vZGUgPSBjdXJzb3IuZ2V0KCkucXVlcnlTZWxlY3RvcignLm5vZGVDb250ZW50JykgYXMgSFRNTEVsZW1lbnQ7XG5cbiAgICBjb250ZW50Tm9kZS5jb250ZW50RWRpdGFibGUgPSBcImZhbHNlXCI7XG4gICAgY29udGVudE5vZGUuYmx1cigpO1xuICAgIGtleWJvYXJkSlMuc2V0Q29udGV4dCgnbmF2aWdhdGlvbicpO1xuXG4gICAgb3V0bGluZS51cGRhdGVDb250ZW50KGN1cnNvci5nZXRJZE9mTm9kZSgpLCBjb250ZW50Tm9kZS5pbm5lckhUTUwudHJpbSgpKTtcbiAgICAvLyByZS1yZW5kZXIgdGhpcyBub2RlIVxuICAgIGNvbnRlbnROb2RlLmlubmVySFRNTCA9IG91dGxpbmUucmVuZGVyQ29udGVudChjdXJzb3IuZ2V0SWRPZk5vZGUoKSk7XG4gICAgc2F2ZSgpO1xuICB9KTtcbn0pO1xuXG5rZXlib2FyZEpTLnNldENvbnRleHQoJ25hdmlnYXRpb24nKTtcblxuZnVuY3Rpb24gc2F2ZUltbWVkaWF0ZSgpIHtcbiAgbG9jYWxTdG9yYWdlLnNldEl0ZW0ob3V0bGluZS5kYXRhLmlkLCBKU09OLnN0cmluZ2lmeShvdXRsaW5lLmRhdGEpKTtcbiAgbG9jYWxTdG9yYWdlLnNldEl0ZW0oJ2FjdGl2ZU91dGxpbmUnLCBvdXRsaW5lLmRhdGEuaWQpO1xuICBjb25zb2xlLmxvZygnc2F2ZWQuLi4nLCBvdXRsaW5lLmRhdGEpO1xuICBzdGF0ZS5kZWxldGUoJ3NhdmVUaW1lb3V0Jyk7XG59XG5cbmZ1bmN0aW9uIHNhdmUoKSB7XG4gIGlmKCFzdGF0ZS5oYXMoJ3NhdmVUaW1lb3V0JykpIHtcbiAgICBzdGF0ZS5zZXQoJ3NhdmVUaW1lb3V0Jywgc2V0VGltZW91dChzYXZlSW1tZWRpYXRlLCAyMDAwKSk7XG4gIH1cbn1cblxuXG5zYXZlKCk7XG4iLCJleHBvcnQgY2xhc3MgQ3Vyc29yIHtcbiAgY29uc3RydWN0b3IoKSB7XG5cbiAgfVxuXG4gIGdldCgpIHtcbiAgICByZXR1cm4gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignLmN1cnNvcicpO1xuICB9XG5cbiAgZ2V0SWRPZk5vZGUoKTogc3RyaW5nIHtcbiAgICByZXR1cm4gdGhpcy5nZXQoKS5nZXRBdHRyaWJ1dGUoJ2RhdGEtaWQnKTtcbiAgfVxuXG4gIHVuc2V0KCkge1xuICAgIGNvbnN0IGVsID0gdGhpcy5nZXQoKTtcbiAgICBpZihlbCkge1xuICAgICAgZWwuY2xhc3NMaXN0LnJlbW92ZSgnY3Vyc29yJyk7XG4gICAgfVxuICB9XG5cbiAgc2V0KGVsZW1lbnRJZDogc3RyaW5nKSB7XG4gICAgdGhpcy51bnNldCgpO1xuICAgIGNvbnN0IGVsID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcihlbGVtZW50SWQpO1xuXG4gICAgaWYoZWwpIHtcbiAgICAgIGVsLmNsYXNzTGlzdC5hZGQoJ2N1cnNvcicpO1xuICAgICAgaWYoIXRoaXMuaXNWaXNpYmxlKGVsZW1lbnRJZCkpIHtcbiAgICAgICAgZWwuc2Nyb2xsSW50b1ZpZXcodHJ1ZSk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgY29sbGFwc2UoKSB7XG4gICAgdGhpcy5nZXQoKS5jbGFzc0xpc3QucmVtb3ZlKCdleHBhbmRlZCcpO1xuICAgIHRoaXMuZ2V0KCkuY2xhc3NMaXN0LmFkZCgnY29sbGFwc2VkJyk7XG4gIH1cblxuICBleHBhbmQoKSB7XG4gICAgdGhpcy5nZXQoKS5jbGFzc0xpc3QucmVtb3ZlKCdjb2xsYXBzZWQnKTtcbiAgICB0aGlzLmdldCgpLmNsYXNzTGlzdC5hZGQoJ2V4cGFuZGVkJyk7XG4gIH1cblxuICBpc05vZGVDb2xsYXBzZWQoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuZ2V0KCkuY2xhc3NMaXN0LmNvbnRhaW5zKCdjb2xsYXBzZWQnKTtcbiAgfVxuICBcbiAgaXNOb2RlRXhwYW5kZWQoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuZ2V0KCkuY2xhc3NMaXN0LmNvbnRhaW5zKCdleHBhbmRlZCcpO1xuICB9XG5cbiAgaXNWaXNpYmxlKGVsZW1lbnRJZDogc3RyaW5nKSB7XG4gICAgY29uc3QgZWwgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKGVsZW1lbnRJZCkgYXMgSFRNTEVsZW1lbnQ7XG4gICAgdmFyIHJlY3QgPSBlbC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgICByZXR1cm4gKFxuICAgICAgICByZWN0LnRvcCA+PSAwICYmXG4gICAgICAgIHJlY3QubGVmdCA+PSAwICYmXG4gICAgICAgIHJlY3QuYm90dG9tIDw9ICh3aW5kb3cuaW5uZXJIZWlnaHQgfHwgZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LmNsaWVudEhlaWdodCkgJiYgICAgIFxuICAgICAgICByZWN0LnJpZ2h0IDw9ICh3aW5kb3cuaW5uZXJXaWR0aCB8fCBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuY2xpZW50V2lkdGgpXG4gICAgKTtcbiAgfVxufVxuIiwiaW1wb3J0IGtleWJvYXJkSlMgZnJvbSAna2V5Ym9hcmRqcyc7XG5pbXBvcnQgeyBtYXAgfSBmcm9tICdsb2Rhc2gnO1xuXG5jb25zdCBrZXlib2FyZENvbW1hbmRzID0ge1xuICAnaCc6ICdNb3ZlIHRoZSBjdXJzb3IgdG8gdGhlIFBhcmVudCBFbGVtZW50IG9mIHRoZSBjdXJyZW50IG5vZGUnLFxuICAnbCc6ICdNb3ZlIHRoZSBjdXJzb3IgdG8gdGhlIGZpcnN0IENoaWxkIEVsZW1lbnQgb2YgdGhlIGN1cnJlbnQgbm9kZScsXG4gICdqJzogJ01vdmUgdGhlIGN1cnNvciB0byB0aGUgbmV4dCBzaWJsaW5nIG9mIHRoZSBjdXJyZW50IG5vZGUnLFxuICAnayc6ICdNb3ZlIHRoZSBjdXJzb3IgdG8gdGhlIHByZXZpb3VzIHNpYmxpbmcgb2YgdGhlIGN1cnJlbnQgbm9kZScsXG4gICdlbnRlcic6ICdBZGQgYSBuZXcgbm9kZSBhcyBhIHNpYmxpbmcgdG8gdGhlIGN1cnJlbnQgbm9kZScsXG4gICd0YWInOiAnQWRkIGEgbmV3IG5vZGUgYXMgdGhlIGNoaWxkIG9mIHRoZSBjdXJyZW50IG5vZGUnLFxuICAnc2hpZnQgKyBqJzogJ1N3YXAgdGhlIGN1cnJlbnQgbm9kZSB3aXRoIG5leHQgc2libGluZyBub2RlJyxcbiAgJ3NoaWZ0ICsgayc6ICdTd2FwIHRoZSBjdXJyZW50IG5vZGUgd2l0aCB0aGUgcHJldmlvdXMgc2libGluZyBub2RlJyxcbiAgJ3NoaWZ0ICsgaCc6ICdMaWZ0IHRoZSBjdXJyZW50IG5vZGUgdG8gYmUgYSBzaWJsaW5nIG9mIHRoZSBwYXJlbnQgbm9kZScsXG4gICdzaGlmdCArIGwnOiAnTG93ZXIgdGhlIGN1cnJlbnQgbm9kZSB0byBiZSBhIGNoaWxkIG9mIHRoZSBwcmV2aW91cyBzaWJsaW5nIG5vZGUnLFxuICAnc2hpZnQgKyBkJzogJ0RlbGV0ZSB0aGUgY3VycmVudCBub2RlJyxcbiAgJ2knOiAnRW50ZXIgXCJlZGl0XCIgbW9kZSwgYW5kIHBsYWNlIHRoZSBjdXJzb3IgYXQgdGhlIHN0YXJ0IG9mIHRoZSBlZGl0YWJsZSBjb250ZW50JyxcbiAgJyQnOiAnRW50ZXIgXCJlZGl0XCIgbW9kZSwgYW5kIHBsYWNlIHRoZSBjdXJzb3IgYXQgdGhlIGVuZCBvZiB0aGUgZWRpdGFibGUgY29udGVudCcsXG4gICdlc2NhcGUnOiAnRXhpdCB0aGUgY3VycmVudCBtb2RlIGFuZCByZXR1cm4gdG8gXCJuYXZpZ2F0aW9uXCIgbW9kZScsXG4gICc/JzogJ0Rpc3BsYXkgdGhpcyBoZWxwIGRpYWxvZ3VlJ1xufTtcblxuY29uc3QgbW9kYWxIVE1MID0gYFxuICA8ZGl2IGNsYXNzPVwibW9kYWxcIj5cbiAgPGRpdiBjbGFzcz1cIm1vZGFsLWNvbnRlbnRcIj5cbiAgICA8aDE+SGVscDwvaDE+XG4gICAgPHRhYmxlPlxuICAgIDx0aGVhZD5cbiAgICA8dHI+XG4gICAgPHRoPktleTwvdGg+XG4gICAgPHRoPkFjdGlvbjwvdGg+XG4gICAgPC90cj5cbiAgICA8L3RoZWFkPlxuICAgIDx0Ym9keT5cbiAgICAke21hcChrZXlib2FyZENvbW1hbmRzLCAodGV4dCwga2V5KSA9PiB7XG4gICAgICByZXR1cm4gYFxuICAgICAgPHRyPlxuICAgICAgICA8dGQ+XG4gICAgICAgICAgPGtiZD4ke2tleX08L2tiZD5cbiAgICAgICAgPC90ZD5cbiAgICAgICAgPHRkPlxuICAgICAgICAgICR7dGV4dH1cbiAgICAgICAgPC90ZD5cbiAgICAgIDwvdHI+XG4gICAgICBgXG4gICAgfSkuam9pbihcIlxcblwiKX1cbiAgICA8L3Rib2R5PlxuICAgIDwvdGFibGU+XG4gIDwvZGl2PlxuICA8L2Rpdj5cbmBcblxuZXhwb3J0IGZ1bmN0aW9uIHNob3dIZWxwKCkge1xuICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCdib2R5JykuaW5uZXJIVE1MICs9IG1vZGFsSFRNTDtcbiAga2V5Ym9hcmRKUy5zZXRDb250ZXh0KCdoZWxwJyk7XG59XG5cbmtleWJvYXJkSlMud2l0aENvbnRleHQoJ2hlbHAnLCAoKSA9PiB7XG4gIGtleWJvYXJkSlMuYmluZCgnZXNjYXBlJywgZSA9PiB7XG4gICAgZG9jdW1lbnQucXVlcnlTZWxlY3RvcignLm1vZGFsJykucmVtb3ZlKCk7XG4gICAga2V5Ym9hcmRKUy5zZXRDb250ZXh0KCduYXZpZ2F0aW9uJyk7XG4gIH0pO1xufSk7XG4iLCJpbXBvcnQgKiBhcyBfIGZyb20gJ2xvZGFzaCc7XG5pbXBvcnQgeyB2NCBhcyB1dWlkIH0gZnJvbSAndXVpZCc7XG5pbXBvcnQgeyBtYXJrZWQgfSBmcm9tICdtYXJrZWQnO1xuXG5leHBvcnQgaW50ZXJmYWNlIFJhd091dGxpbmUge1xuICBpZDogc3RyaW5nO1xuICBjcmVhdGVkOiBudW1iZXI7XG4gIG5hbWU6IHN0cmluZztcbiAgdHJlZTogT3V0bGluZVRyZWU7XG4gIGNvbnRlbnROb2RlczogUmVjb3JkPHN0cmluZywgT3V0bGluZU5vZGU+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